datastore-api 4.0.0 → 4.0.3

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.
@@ -9,13 +9,13 @@
9
9
  * Copyright (c) 2021, 2022, 2023 Dr. Maximillian Dornseif
10
10
  */
11
11
 
12
- import { AsyncLocalStorage } from 'async_hooks'
13
- import { setImmediate } from 'timers/promises'
12
+ import { AsyncLocalStorage } from 'async_hooks';
13
+ import { setImmediate } from 'timers/promises';
14
14
 
15
- import { Datastore, Key, PathType, Query, Transaction } from '@google-cloud/datastore'
16
- import { Entity, entity } from '@google-cloud/datastore/build/src/entity'
17
- import { Operator, RunQueryInfo, RunQueryResponse } from '@google-cloud/datastore/build/src/query'
18
- import { CommitResponse } from '@google-cloud/datastore/build/src/request'
15
+ import { Datastore, Key, PathType, Query, Transaction, PropertyFilter } from '@google-cloud/datastore';
16
+ import { Entity, entity } from '@google-cloud/datastore/build/src/entity';
17
+ import { Operator, RunQueryInfo, RunQueryResponse } from '@google-cloud/datastore/build/src/query';
18
+ import { CommitResponse } from '@google-cloud/datastore/build/src/request';
19
19
  import {
20
20
  assert,
21
21
  assertIsArray,
@@ -23,44 +23,44 @@ import {
23
23
  assertIsNumber,
24
24
  assertIsObject,
25
25
  assertIsString,
26
- } from 'assertate-debug'
27
- import Debug from 'debug'
28
- import promClient from 'prom-client'
29
- import { Writable } from 'ts-essentials'
26
+ } from 'assertate-debug';
27
+ import Debug from 'debug';
28
+ import promClient from 'prom-client';
29
+ import { Writable } from 'ts-essentials';
30
30
 
31
31
  /** @ignore */
32
- export { Datastore, Key, PathType, Query, Transaction } from '@google-cloud/datastore'
32
+ export { Datastore, Key, PathType, Query, Transaction } from '@google-cloud/datastore';
33
33
 
34
34
  /** @ignore */
35
- const debug = Debug('ds:api')
35
+ const debug = Debug('ds:api');
36
36
 
37
37
  /** @ignore */
38
- const transactionAsyncLocalStorage = new AsyncLocalStorage()
38
+ const transactionAsyncLocalStorage = new AsyncLocalStorage();
39
39
 
40
40
  /** @ignore */
41
41
  const metricHistogram = new promClient.Histogram({
42
42
  name: 'dstore_requests_seconds',
43
43
  help: 'How long did Datastore operations take?',
44
44
  labelNames: ['operation'],
45
- })
45
+ });
46
46
  const metricFailureCounter = new promClient.Counter({
47
47
  name: 'dstore_failures_total',
48
48
  help: 'How many Datastore operations failed?',
49
49
  labelNames: ['operation'],
50
- })
50
+ });
51
51
 
52
52
  /** Use instead of Datastore.KEY
53
53
  *
54
54
  * Even better: use `_key` instead.
55
55
  */
56
- export const KEYSYM = Datastore.KEY
56
+ export const KEYSYM = Datastore.KEY;
57
57
 
58
- export type IGqlFilterTypes = boolean | string | number
58
+ export type IGqlFilterTypes = boolean | string | number;
59
59
 
60
60
  export type IGqlFilterSpec = {
61
- readonly eq: IGqlFilterTypes
62
- }
63
- export type TGqlFilterList = Array<[string, Operator, DstorePropertyValues]>
61
+ readonly eq: IGqlFilterTypes;
62
+ };
63
+ export type TGqlFilterList = Array<[string, Operator, DstorePropertyValues]>;
64
64
 
65
65
  /** Define what can be written into the Datastore */
66
66
  export type DstorePropertyValues =
@@ -73,11 +73,11 @@ export type DstorePropertyValues =
73
73
  | Buffer
74
74
  | Key
75
75
  | DstorePropertyValues[]
76
- | { [key: string]: DstorePropertyValues }
76
+ | { [key: string]: DstorePropertyValues };
77
77
 
78
78
  export interface IDstoreEntryWithoutKey {
79
79
  /** All User Data stored in the Datastore */
80
- [key: string]: DstorePropertyValues
80
+ [key: string]: DstorePropertyValues;
81
81
  }
82
82
 
83
83
  /** Represents what is actually stored inside the Datastore, called "Entity" by Google
@@ -85,41 +85,41 @@ export interface IDstoreEntryWithoutKey {
85
85
  */
86
86
  export interface IDstoreEntry extends IDstoreEntryWithoutKey {
87
87
  /* Datastore key provided by [@google-cloud/datastore](https://github.com/googleapis/nodejs-datastore#readme) */
88
- readonly [Datastore.KEY]?: Key
88
+ readonly [Datastore.KEY]?: Key;
89
89
  /** [Datastore.KEY] key */
90
- _keyStr: string
90
+ _keyStr: string;
91
91
  /** All User Data stored in the Datastore */
92
- [key: string]: DstorePropertyValues
92
+ [key: string]: DstorePropertyValues;
93
93
  }
94
94
 
95
95
  /** Represents the thing you pass to the save method. Also called "Entity" by Google */
96
96
  export type DstoreSaveEntity = {
97
- key: Key
97
+ key: Key;
98
98
  data: Omit<IDstoreEntry, '_keyStr' | Datastore['KEY']> &
99
99
  Partial<{
100
- _keyStr: string
101
- [Datastore.KEY]: Key
102
- }>
103
- method?: 'insert' | 'update' | 'upsert'
104
- excludeLargeProperties?: boolean
105
- excludeFromIndexes?: readonly string[]
106
- }
100
+ _keyStr: string;
101
+ [Datastore.KEY]: Key;
102
+ }>;
103
+ method?: 'insert' | 'update' | 'upsert';
104
+ excludeLargeProperties?: boolean;
105
+ excludeFromIndexes?: readonly string[];
106
+ };
107
107
 
108
108
  type IDstore = {
109
109
  /** Accessible by Users of the library. Keep in mind that you will access outside transactions created by [[runInTransaction]]. */
110
- readonly datastore: Datastore
111
- key: (path: ReadonlyArray<PathType>) => Key
112
- keyFromSerialized: (text: string) => Key
113
- keySerialize: (key: Key) => string
114
- readKey: (entry: IDstoreEntry) => Key
115
- get: (key: Key) => Promise<IDstoreEntry | null>
116
- getMulti: (keys: ReadonlyArray<Key>) => Promise<ReadonlyArray<IDstoreEntry | null>>
117
- set: (key: Key, entry: IDstoreEntry) => Promise<Key>
118
- save: (entities: readonly DstoreSaveEntity[]) => Promise<CommitResponse | undefined>
119
- insert: (entities: readonly DstoreSaveEntity[]) => Promise<CommitResponse | undefined>
120
- update: (entities: readonly DstoreSaveEntity[]) => Promise<CommitResponse | undefined>
121
- delete: (keys: readonly Key[]) => Promise<CommitResponse | undefined>
122
- createQuery: (kind: string) => Query
110
+ readonly datastore: Datastore;
111
+ key: (path: ReadonlyArray<PathType>) => Key;
112
+ keyFromSerialized: (text: string) => Key;
113
+ keySerialize: (key: Key) => string;
114
+ readKey: (entry: IDstoreEntry) => Key;
115
+ get: (key: Key) => Promise<IDstoreEntry | null>;
116
+ getMulti: (keys: ReadonlyArray<Key>) => Promise<ReadonlyArray<IDstoreEntry | null>>;
117
+ set: (key: Key, entry: IDstoreEntry) => Promise<Key>;
118
+ save: (entities: readonly DstoreSaveEntity[]) => Promise<CommitResponse | undefined>;
119
+ insert: (entities: readonly DstoreSaveEntity[]) => Promise<CommitResponse | undefined>;
120
+ update: (entities: readonly DstoreSaveEntity[]) => Promise<CommitResponse | undefined>;
121
+ delete: (keys: readonly Key[]) => Promise<CommitResponse | undefined>;
122
+ createQuery: (kind: string) => Query;
123
123
  query: (
124
124
  kind: string,
125
125
  filters?: TGqlFilterList,
@@ -127,11 +127,11 @@ type IDstore = {
127
127
  ordering?: readonly string[],
128
128
  selection?: readonly string[],
129
129
  cursor?: string
130
- ) => Promise<RunQueryResponse>
131
- runQuery: (query: Query | Omit<Query, 'run'>) => Promise<RunQueryResponse>
132
- allocateOneId: (kindName: string) => Promise<string>
133
- runInTransaction: <T>(func: { (): Promise<T>; (): T }) => Promise<T>
134
- }
130
+ ) => Promise<RunQueryResponse>;
131
+ runQuery: (query: Query | Omit<Query, 'run'>) => Promise<RunQueryResponse>;
132
+ allocateOneId: (kindName: string) => Promise<string>;
133
+ runInTransaction: <T>(func: { (): Promise<T>; (): T }) => Promise<T>;
134
+ };
135
135
 
136
136
  /** Dstore implements a slightly more accessible version of the [Google Cloud Datastore: Node.js Client](https://cloud.google.com/nodejs/docs/reference/datastore/latest)
137
137
 
@@ -157,9 +157,9 @@ Main differences:
157
157
  This documentation also tries to document the little known idiosyncrasies of the [@google-cloud/datastore](https://github.com/googleapis/nodejs-datastore) library. See the corresponding functions.
158
158
  */
159
159
  export class Dstore implements IDstore {
160
- engine = 'Dstore'
161
- engines: string[] = []
162
- private readonly urlSaveKey = new entity.URLSafeKey()
160
+ engine = 'Dstore';
161
+ engines: string[] = [];
162
+ private readonly urlSaveKey = new entity.URLSafeKey();
163
163
 
164
164
  /** Generate a Dstore instance for a specific [[Datastore]] instance.
165
165
 
@@ -177,13 +177,13 @@ export class Dstore implements IDstore {
177
177
  ```
178
178
  */
179
179
  constructor(readonly datastore: Datastore, readonly projectId?: string, readonly logger?: string) {
180
- assertIsObject(datastore)
181
- this.engines.push(this.engine)
180
+ assertIsObject(datastore);
181
+ this.engines.push(this.engine);
182
182
  }
183
183
 
184
184
  /** Gets the Datastore or the current Transaction. */
185
185
  private getDoT(): Transaction | Datastore {
186
- return (transactionAsyncLocalStorage.getStore() as Transaction) || this.datastore
186
+ return (transactionAsyncLocalStorage.getStore() as Transaction) || this.datastore;
187
187
  }
188
188
 
189
189
  /** `key()` creates a [[Key]] Object from a path.
@@ -195,7 +195,7 @@ export class Dstore implements IDstore {
195
195
  * @category Datastore Drop-In
196
196
  */
197
197
  key(path: readonly PathType[]): Key {
198
- return this.datastore.key(path as Writable<typeof path>)
198
+ return this.datastore.key(path as Writable<typeof path>);
199
199
  }
200
200
 
201
201
  /** `keyFromSerialized()` serializes [[Key]] to a string.
@@ -207,7 +207,7 @@ export class Dstore implements IDstore {
207
207
  * @category Datastore Drop-In
208
208
  */
209
209
  keySerialize(key: Key): string {
210
- return key ? this.urlSaveKey.legacyEncode(this.projectId ?? '', key) : ''
210
+ return key ? this.urlSaveKey.legacyEncode(this.projectId ?? '', key) : '';
211
211
  }
212
212
 
213
213
  /** `keyFromSerialized()` deserializes a string created with [[keySerialize]] to a [[Key]].
@@ -217,7 +217,7 @@ export class Dstore implements IDstore {
217
217
  * @category Datastore Drop-In
218
218
  */
219
219
  keyFromSerialized(text: string): Key {
220
- return this.urlSaveKey.legacyDecode(text)
220
+ return this.urlSaveKey.legacyDecode(text);
221
221
  }
222
222
 
223
223
  /** `readKey()` extracts the [[Key]] from an [[IDstoreEntry]].
@@ -228,17 +228,17 @@ export class Dstore implements IDstore {
228
228
  * @category Additional
229
229
  */
230
230
  readKey(ent: IDstoreEntry): Key {
231
- assertIsObject(ent)
232
- let ret = ent[Datastore.KEY]
231
+ assertIsObject(ent);
232
+ let ret = ent[Datastore.KEY];
233
233
  if (ent._keyStr && !ret) {
234
- ret = this.keyFromSerialized(ent._keyStr)
234
+ ret = this.keyFromSerialized(ent._keyStr);
235
235
  }
236
236
  assertIsObject(
237
237
  ret,
238
238
  'entity[Datastore.KEY]/entity._keyStr',
239
239
  `Entity is missing the datastore Key: ${JSON.stringify(ent)}`
240
- )
241
- return ret
240
+ );
241
+ return ret;
242
242
  }
243
243
 
244
244
  /** `fixKeys()` is called for all [[IDstoreEntry]]sa returned from [[Dstore]].
@@ -252,13 +252,13 @@ export class Dstore implements IDstore {
252
252
  ): Array<IDstoreEntry | undefined> {
253
253
  entities.forEach((x) => {
254
254
  if (!!x?.[Datastore.KEY] && x[Datastore.KEY]) {
255
- assertIsDefined(x[Datastore.KEY])
256
- assertIsObject(x[Datastore.KEY])
255
+ assertIsDefined(x[Datastore.KEY]);
256
+ assertIsObject(x[Datastore.KEY]);
257
257
  // Old TypesScript has problems with symbols as a property
258
- x._keyStr = this.keySerialize(x[Datastore.KEY] as Key)
258
+ x._keyStr = this.keySerialize(x[Datastore.KEY] as Key);
259
259
  }
260
- })
261
- return entities as Array<IDstoreEntry | undefined>
260
+ });
261
+ return entities as Array<IDstoreEntry | undefined>;
262
262
  }
263
263
 
264
264
  /** `get()` reads a [[IDstoreEntry]] from the Datastore.
@@ -277,11 +277,11 @@ export class Dstore implements IDstore {
277
277
  * @category Datastore Drop-In
278
278
  */
279
279
  async get(key: Key): Promise<IDstoreEntry | null> {
280
- assertIsObject(key)
281
- assert(!Array.isArray(key))
282
- assert(key.path.length % 2 == 0, `key.path must be complete: ${JSON.stringify(key.path)}`)
283
- const result = await this.getMulti([key])
284
- return result?.[0] || null
280
+ assertIsObject(key);
281
+ assert(!Array.isArray(key));
282
+ assert(key.path.length % 2 == 0, `key.path must be complete: ${JSON.stringify(key.path)}`);
283
+ const result = await this.getMulti([key]);
284
+ return result?.[0] || null;
285
285
  }
286
286
 
287
287
  /** `getMulti()` reads several [[IDstoreEntry]]s from the Datastore.
@@ -303,28 +303,28 @@ export class Dstore implements IDstore {
303
303
  */
304
304
  async getMulti(keys: readonly Key[]): Promise<Array<IDstoreEntry | null>> {
305
305
  // assertIsArray(keys);
306
- let results: (IDstoreEntry | null | undefined)[]
307
- const metricEnd = metricHistogram.startTimer()
306
+ let results: (IDstoreEntry | null | undefined)[];
307
+ const metricEnd = metricHistogram.startTimer();
308
308
  try {
309
309
  results = this.fixKeys(
310
310
  keys.length > 0 ? (await this.getDoT().get(keys as Writable<typeof keys>))?.[0] : []
311
- )
311
+ );
312
312
  } catch (error) {
313
- metricFailureCounter.inc({ operation: 'get' })
314
- await setImmediate()
315
- throw new DstoreError('datastore.getMulti error', error as Error, { keys })
313
+ metricFailureCounter.inc({ operation: 'get' });
314
+ await setImmediate();
315
+ throw new DstoreError('datastore.getMulti error', error as Error, { keys });
316
316
  } finally {
317
- metricEnd({ operation: 'get' })
317
+ metricEnd({ operation: 'get' });
318
318
  }
319
319
 
320
320
  // Sort resulting entities by the keys they were requested with.
321
- assertIsArray(results)
322
- const entities = results as IDstoreEntry[]
323
- const entitiesByKey: Record<string, IDstoreEntry> = {}
321
+ assertIsArray(results);
322
+ const entities = results as IDstoreEntry[];
323
+ const entitiesByKey: Record<string, IDstoreEntry> = {};
324
324
  entities.forEach((entity) => {
325
- entitiesByKey[JSON.stringify(entity[Datastore.KEY])] = entity
326
- })
327
- return keys.map((key) => entitiesByKey[JSON.stringify(key)] || null)
325
+ entitiesByKey[JSON.stringify(entity[Datastore.KEY])] = entity;
326
+ });
327
+ return keys.map((key) => entitiesByKey[JSON.stringify(key)] || null);
328
328
  }
329
329
 
330
330
  /** `set()` is addition to [[Datastore]]. It provides a classic Key-value Interface.
@@ -344,11 +344,11 @@ export class Dstore implements IDstore {
344
344
  * @category Additional
345
345
  */
346
346
  async set(key: Key, data: IDstoreEntryWithoutKey): Promise<Key> {
347
- assertIsObject(key)
348
- assertIsObject(data)
349
- const saveEntity = { key, data }
350
- await this.save([saveEntity])
351
- return saveEntity.key
347
+ assertIsObject(key);
348
+ assertIsObject(data);
349
+ const saveEntity = { key, data };
350
+ await this.save([saveEntity]);
351
+ return saveEntity.key;
352
352
  }
353
353
 
354
354
  /** `save()` is compatible to [Datastore.save()](https://cloud.google.com/nodejs/docs/reference/datastore/latest/datastore/datastore#_google_cloud_datastore_Datastore_save_member_1_).
@@ -385,32 +385,32 @@ export class Dstore implements IDstore {
385
385
  * @category Datastore Drop-In
386
386
  */
387
387
  async save(entities: readonly DstoreSaveEntity[]): Promise<CommitResponse | undefined> {
388
- assertIsArray(entities)
389
- let ret: CommitResponse | undefined
390
- const metricEnd = metricHistogram.startTimer()
388
+ assertIsArray(entities);
389
+ let ret: CommitResponse | undefined;
390
+ const metricEnd = metricHistogram.startTimer();
391
391
  try {
392
392
  // Within Transaction we don't get any answer here!
393
393
  // [ { mutationResults: [ [Object], [Object] ], indexUpdates: 51 } ]
394
394
  for (const e of entities) {
395
- assertIsObject(e.key)
396
- assertIsObject(e.data)
397
- this.fixKeys([e.data])
398
- e.excludeLargeProperties = e.excludeLargeProperties === undefined ? true : e.excludeLargeProperties
399
- e.data = { ...e.data, _keyStr: undefined }
395
+ assertIsObject(e.key);
396
+ assertIsObject(e.data);
397
+ this.fixKeys([e.data]);
398
+ e.excludeLargeProperties = e.excludeLargeProperties === undefined ? true : e.excludeLargeProperties;
399
+ e.data = { ...e.data, _keyStr: undefined };
400
400
  }
401
- ret = (await this.getDoT().save(entities)) || undefined
401
+ ret = (await this.getDoT().save(entities)) || undefined;
402
402
  for (const e of entities) {
403
- e.data[Datastore.KEY] = e.key
404
- this.fixKeys([e.data])
403
+ e.data[Datastore.KEY] = e.key;
404
+ this.fixKeys([e.data]);
405
405
  }
406
406
  } catch (error) {
407
- metricFailureCounter.inc({ operation: 'save' })
408
- await setImmediate()
409
- throw new DstoreError('datastore.save error', error as Error)
407
+ metricFailureCounter.inc({ operation: 'save' });
408
+ await setImmediate();
409
+ throw new DstoreError('datastore.save error', error as Error);
410
410
  } finally {
411
- metricEnd({ operation: 'save' })
411
+ metricEnd({ operation: 'save' });
412
412
  }
413
- return ret
413
+ return ret;
414
414
  }
415
415
 
416
416
  /** `insert()` is compatible to [Datastore.insert()](https://cloud.google.com/nodejs/docs/reference/datastore/latest/datastore/datastore#_google_cloud_datastore_Datastore_insert_member_1_).
@@ -432,20 +432,20 @@ export class Dstore implements IDstore {
432
432
  * @category Datastore Drop-In
433
433
  */
434
434
  async insert(entities: readonly DstoreSaveEntity[]): Promise<CommitResponse | undefined> {
435
- assertIsArray(entities)
436
- let ret: CommitResponse | undefined
437
- const metricEnd = metricHistogram.startTimer()
435
+ assertIsArray(entities);
436
+ let ret: CommitResponse | undefined;
437
+ const metricEnd = metricHistogram.startTimer();
438
438
  try {
439
- ret = (await this.getDoT().insert(entities)) || undefined
439
+ ret = (await this.getDoT().insert(entities)) || undefined;
440
440
  } catch (error) {
441
441
  // console.error(error)
442
- metricFailureCounter.inc({ operation: 'insert' })
443
- await setImmediate()
444
- throw new DstoreError('datastore.insert error', error as Error)
442
+ metricFailureCounter.inc({ operation: 'insert' });
443
+ await setImmediate();
444
+ throw new DstoreError('datastore.insert error', error as Error);
445
445
  } finally {
446
- metricEnd({ operation: 'insert' })
446
+ metricEnd({ operation: 'insert' });
447
447
  }
448
- return ret
448
+ return ret;
449
449
  }
450
450
 
451
451
  /** `update()` is compatible to [Datastore.update()](https://cloud.google.com/nodejs/docs/reference/datastore/latest/datastore/datastore#_google_cloud_datastore_Datastore_update_member_1_).
@@ -467,29 +467,29 @@ export class Dstore implements IDstore {
467
467
  * @category Datastore Drop-In
468
468
  */
469
469
  async update(entities: readonly DstoreSaveEntity[]): Promise<CommitResponse | undefined> {
470
- assertIsArray(entities)
470
+ assertIsArray(entities);
471
471
 
472
- entities.forEach((entity) => assertIsObject(entity.key))
472
+ entities.forEach((entity) => assertIsObject(entity.key));
473
473
  entities.forEach((entity) =>
474
474
  assert(
475
475
  entity.key.path.length % 2 == 0,
476
476
  `entity.key.path must be complete: ${JSON.stringify([entity.key.path, entity])}`
477
477
  )
478
- )
479
- let ret: CommitResponse | undefined
480
- const metricEnd = metricHistogram.startTimer()
478
+ );
479
+ let ret: CommitResponse | undefined;
480
+ const metricEnd = metricHistogram.startTimer();
481
481
 
482
482
  try {
483
- ret = (await this.getDoT().update(entities)) || undefined
483
+ ret = (await this.getDoT().update(entities)) || undefined;
484
484
  } catch (error) {
485
485
  // console.error(error)
486
- metricFailureCounter.inc({ operation: 'update' })
487
- await setImmediate()
488
- throw new DstoreError('datastore.update error', error as Error)
486
+ metricFailureCounter.inc({ operation: 'update' });
487
+ await setImmediate();
488
+ throw new DstoreError('datastore.update error', error as Error);
489
489
  } finally {
490
- metricEnd({ operation: 'update' })
490
+ metricEnd({ operation: 'update' });
491
491
  }
492
- return ret
492
+ return ret;
493
493
  }
494
494
 
495
495
  /** `delete()` is compatible to [Datastore.delete()].
@@ -506,23 +506,23 @@ export class Dstore implements IDstore {
506
506
  * @category Datastore Drop-In
507
507
  */
508
508
  async delete(keys: readonly Key[]): Promise<CommitResponse | undefined> {
509
- assertIsArray(keys)
510
- keys.forEach((key) => assertIsObject(key))
509
+ assertIsArray(keys);
510
+ keys.forEach((key) => assertIsObject(key));
511
511
  keys.forEach((key) =>
512
512
  assert(key.path.length % 2 == 0, `key.path must be complete: ${JSON.stringify(key.path)}`)
513
- )
514
- let ret
515
- const metricEnd = metricHistogram.startTimer()
513
+ );
514
+ let ret;
515
+ const metricEnd = metricHistogram.startTimer();
516
516
  try {
517
- ret = (await this.getDoT().delete(keys)) || undefined
517
+ ret = (await this.getDoT().delete(keys)) || undefined;
518
518
  } catch (error) {
519
- metricFailureCounter.inc({ operation: 'delete' })
520
- await setImmediate()
521
- throw new DstoreError('datastore.delete error', error as Error)
519
+ metricFailureCounter.inc({ operation: 'delete' });
520
+ await setImmediate();
521
+ throw new DstoreError('datastore.delete error', error as Error);
522
522
  } finally {
523
- metricEnd({ operation: 'delete' })
523
+ metricEnd({ operation: 'delete' });
524
524
  }
525
- return ret
525
+ return ret;
526
526
  }
527
527
 
528
528
  /** `createQuery()` creates an "empty" [[Query]] Object.
@@ -535,25 +535,25 @@ export class Dstore implements IDstore {
535
535
  */
536
536
  createQuery(kindName: string): Query {
537
537
  try {
538
- return this.getDoT().createQuery(kindName)
538
+ return this.getDoT().createQuery(kindName);
539
539
  } catch (error) {
540
- throw new DstoreError('datastore.createQuery error', error as Error)
540
+ throw new DstoreError('datastore.createQuery error', error as Error);
541
541
  }
542
542
  }
543
543
 
544
544
  async runQuery(query: Query | Omit<Query, 'run'>): Promise<RunQueryResponse> {
545
- let ret
546
- const metricEnd = metricHistogram.startTimer()
545
+ let ret;
546
+ const metricEnd = metricHistogram.startTimer();
547
547
  try {
548
- const [entities, info]: [Entity[], RunQueryInfo] = await this.getDoT().runQuery(query as Query)
549
- ret = [this.fixKeys(entities), info]
548
+ const [entities, info]: [Entity[], RunQueryInfo] = await this.getDoT().runQuery(query as Query);
549
+ ret = [this.fixKeys(entities), info];
550
550
  } catch (error) {
551
- await setImmediate()
552
- throw new DstoreError('datastore.runQuery error', error as Error)
551
+ await setImmediate();
552
+ throw new DstoreError('datastore.runQuery error', error as Error);
553
553
  } finally {
554
- metricEnd({ operation: 'query' })
554
+ metricEnd({ operation: 'query' });
555
555
  }
556
- return ret as RunQueryResponse
556
+ return ret as RunQueryResponse;
557
557
  }
558
558
 
559
559
  /** `query()` combined [[createQuery]] and [[runQuery]] in a single call.
@@ -576,34 +576,34 @@ export class Dstore implements IDstore {
576
576
  selection: readonly string[] = [],
577
577
  cursor?: string
578
578
  ): Promise<RunQueryResponse> {
579
- assertIsString(kindName)
580
- assertIsArray(filters)
581
- assertIsNumber(limit)
579
+ assertIsString(kindName);
580
+ assertIsArray(filters);
581
+ assertIsNumber(limit);
582
582
  try {
583
- const q = this.createQuery(kindName)
583
+ const q = this.createQuery(kindName);
584
584
  for (const filterSpec of filters) {
585
- assertIsObject(filterSpec)
585
+ assertIsObject(filterSpec);
586
586
  // @ts-ignore
587
- q.filter(...filterSpec)
587
+ q.filter(new PropertyFilter(...filterSpec));
588
588
  }
589
589
  for (const orderField of ordering) {
590
- q.order(orderField)
590
+ q.order(orderField);
591
591
  }
592
592
  if (limit > 0) {
593
- q.limit(limit)
593
+ q.limit(limit);
594
594
  }
595
595
  if (selection.length > 0) {
596
- q.select(selection as any)
596
+ q.select(selection as any);
597
597
  }
598
- return await this.runQuery(q)
598
+ return await this.runQuery(q);
599
599
  } catch (error) {
600
- await setImmediate()
600
+ await setImmediate();
601
601
  throw new DstoreError('datastore.query error', error as Error, {
602
602
  kindName,
603
603
  filters,
604
604
  limit,
605
605
  ordering,
606
- })
606
+ });
607
607
  }
608
608
  }
609
609
 
@@ -619,10 +619,10 @@ export class Dstore implements IDstore {
619
619
  * In fact the generated ID is namespaced via an incomplete [[Key]] of the given Kind.
620
620
  */
621
621
  async allocateOneId(kindName = 'Numbering'): Promise<string> {
622
- assertIsString(kindName)
623
- const ret = (await this.datastore.allocateIds(this.key([kindName]), 1))[0][0].id
624
- assertIsString(ret)
625
- return ret
622
+ assertIsString(kindName);
623
+ const ret = (await this.datastore.allocateIds(this.key([kindName]), 1))[0][0].id;
624
+ assertIsString(ret);
625
+ return ret;
626
626
  }
627
627
 
628
628
  /** This tries to give high level access to transactions.
@@ -640,27 +640,27 @@ export class Dstore implements IDstore {
640
640
  Most Applications today are running on "Firestore in Datastore Mode". Beware that the Datastore-Emulator fails with `error: 3 INVALID_ARGUMENT: Only ancestor queries are allowed inside transactions.` during [[runQuery]] while the Datastore on Google Infrastructure does not have such an restriction anymore as of 2022.
641
641
  */
642
642
  async runInTransaction<T>(func: () => Promise<T>): Promise<T> {
643
- let ret
644
- const transaction: Transaction = this.datastore.transaction()
643
+ let ret;
644
+ const transaction: Transaction = this.datastore.transaction();
645
645
  await transactionAsyncLocalStorage.run(transaction, async () => {
646
- const [transactionInfo, transactionRunApiResponse] = await transaction.run()
647
- let commitApiResponse
646
+ const [transactionInfo, transactionRunApiResponse] = await transaction.run();
647
+ let commitApiResponse;
648
648
  try {
649
- ret = await func()
649
+ ret = await func();
650
650
  } catch (error) {
651
- const rollbackInfo = await transaction.rollback()
651
+ const rollbackInfo = await transaction.rollback();
652
652
  debug(
653
653
  'Transaction failed, rollback initiated: %O %O %O %O',
654
654
  transactionInfo,
655
655
  transactionRunApiResponse,
656
656
  rollbackInfo,
657
657
  error
658
- )
659
- await setImmediate()
660
- throw new DstoreError('datastore.transaction execution error', error as Error)
658
+ );
659
+ await setImmediate();
660
+ throw new DstoreError('datastore.transaction execution error', error as Error);
661
661
  }
662
662
  try {
663
- commitApiResponse = (await transaction.commit())[0]
663
+ commitApiResponse = (await transaction.commit())[0];
664
664
  } catch (error) {
665
665
  debug(
666
666
  'Transaction commit failed: %O %O %O %O ret: %O',
@@ -669,36 +669,36 @@ export class Dstore implements IDstore {
669
669
  commitApiResponse,
670
670
  error,
671
671
  ret
672
- )
673
- await setImmediate()
674
- throw new DstoreError('datastore.transaction execution error', error as Error)
672
+ );
673
+ await setImmediate();
674
+ throw new DstoreError('datastore.transaction execution error', error as Error);
675
675
  }
676
- })
677
- return ret as T
676
+ });
677
+ return ret as T;
678
678
  }
679
679
  }
680
680
 
681
681
  export class DstoreError extends Error {
682
- public readonly extensions: Record<string, unknown>
682
+ public readonly extensions: Record<string, unknown>;
683
683
  public readonly originalError: Error | undefined;
684
- readonly [key: string]: unknown
684
+ readonly [key: string]: unknown;
685
685
 
686
686
  constructor(message: string, originalError: Error | undefined, extensions?: Record<string, unknown>) {
687
- super(`${message}: ${originalError?.message}`)
687
+ super(`${message}: ${originalError?.message}`);
688
688
 
689
689
  // if no name provided, use the default. defineProperty ensures that it stays non-enumerable
690
690
  if (!this.name) {
691
- Object.defineProperty(this, 'name', { value: 'DstoreError' })
691
+ Object.defineProperty(this, 'name', { value: 'DstoreError' });
692
692
  }
693
693
  // metadata: Metadata { internalRepr: Map(0) {}, options: {} },
694
- this.originalError = originalError
695
- this.extensions = { ...extensions }
694
+ this.originalError = originalError;
695
+ this.extensions = { ...extensions };
696
696
  this.stack =
697
697
  (this.stack?.split('\n')[0] || '') +
698
698
  '\n' +
699
699
  (originalError?.stack?.split('\n')?.slice(1)?.join('\n') || '') +
700
700
  '\n' +
701
- (this.stack?.split('\n')?.slice(1)?.join('\n') || '')
701
+ (this.stack?.split('\n')?.slice(1)?.join('\n') || '');
702
702
 
703
703
  // These are usually present on Datastore Errors
704
704
  // logger.error({ err: originalError, extensions }, message);