datastore-api 2.0.0 → 2.1.0

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.
@@ -0,0 +1,639 @@
1
+ /*
2
+ * datastore-simulator.ts
3
+ *
4
+ * Created by Dr. Maximillian Dornseif 2023-05-11 in huwawi3backend 18.16.3
5
+ * Copyright (c) 2023 HUDORA GmbH
6
+ */
7
+
8
+ /* eslint-disable @typescript-eslint/explicit-function-return-type */
9
+ /* eslint-disable @typescript-eslint/no-non-null-assertion */
10
+ /*
11
+ * index.ts
12
+ *
13
+ * Created by Dr. Maximillian Dornseif 2023-04-20 in huwawi3backend 18.13.0
14
+ * based on https://github.com/KoryNunn/datastore-mock 1.1.0 by korynunn
15
+ */
16
+
17
+ import {
18
+ DatastoreOptions,
19
+ DatastoreRequest,
20
+ Entity,
21
+ InsertCallback,
22
+ InsertResponse,
23
+ Key,
24
+ KeyToLegacyUrlSafeCallback,
25
+ Datastore as OrigDatastore,
26
+ TransactionOptions,
27
+ UpdateCallback,
28
+ UpdateResponse,
29
+ UpsertCallback,
30
+ UpsertResponse,
31
+ Query,
32
+ PathType,
33
+ } from '@google-cloud/datastore'
34
+ import { google } from '@google-cloud/datastore/build/protos/protos'
35
+ import { AggregateQuery } from '@google-cloud/datastore/build/src/aggregate'
36
+ import { Entities, entity } from '@google-cloud/datastore/build/src/entity'
37
+ import { RunQueryOptions, RunQueryResponse, RunQueryCallback } from '@google-cloud/datastore/build/src/query'
38
+ import {
39
+ AllocateIdsCallback,
40
+ AllocateIdsOptions,
41
+ AllocateIdsResponse,
42
+ CommitCallback,
43
+ CommitResponse,
44
+ CreateReadStreamOptions,
45
+ DeleteCallback,
46
+ DeleteResponse,
47
+ GetCallback,
48
+ GetResponse,
49
+ PrepareEntityObjectResponse,
50
+ RequestOptions,
51
+ SaveCallback,
52
+ SaveResponse,
53
+ } from '@google-cloud/datastore/build/src/request'
54
+ import { promisifyAll } from '@google-cloud/promisify'
55
+ import { assert } from 'assertate-debug'
56
+ import { CallOptions } from 'google-gax'
57
+ import * as is from 'is'
58
+
59
+ const urlSafeKey = new entity.URLSafeKey()
60
+
61
+ const KEY_SELECT = '__key__'
62
+
63
+ function filter(query: { filters: any[][] }, field: any, operator: any, value: any): any {
64
+ query.filters.push([field, operator, value])
65
+ return createQuery(query)
66
+ }
67
+
68
+ function limit(query: { limit: any }, limit: any): any {
69
+ query.limit = limit
70
+ return createQuery(query)
71
+ }
72
+
73
+ function select(query: { select: string | string[] }, fields: ConcatArray<never>) {
74
+ query.select = [].concat(fields)
75
+
76
+ if (query.select.length > 1 && query.select.includes(KEY_SELECT)) {
77
+ throw new Error('Cannot mix __key__ select with other fields')
78
+ }
79
+
80
+ return createQuery(query)
81
+ }
82
+
83
+ function createQuery(query: any): any {
84
+ return {
85
+ filter: filter.bind(null, query),
86
+ limit: limit.bind(null, query),
87
+ select: select.bind(null, query),
88
+ query,
89
+ }
90
+ }
91
+
92
+ export class Datastore extends OrigDatastore {
93
+ db: Map<string, any>
94
+ rnd = 0
95
+ constructor(options?: DatastoreOptions) {
96
+ super()
97
+ options = options || {}
98
+ this.clients_ = new Map()
99
+ // this.datastore = this as unknown as Datastore;
100
+ this.namespace = options.namespace
101
+ this.db = new Map()
102
+
103
+ options.projectId = options.projectId || process.env.DATASTORE_PROJECT_ID
104
+ }
105
+ _keySerializer(key: entity.Key) {
106
+ const newKey =
107
+ key.id === undefined
108
+ ? this.key(key.path)
109
+ : this.key([...key.path.slice(0, -1), this.int(key.path.slice(-1)[0])])
110
+ return JSON.stringify(newKey)
111
+ }
112
+
113
+ // export
114
+ // getIndexes getIndexes
115
+ // getProjectId
116
+ // index(id: string): Index {
117
+ // return new Index(this, id);
118
+ // }
119
+
120
+ allocateIds(key: entity.Key, options: AllocateIdsOptions | number): Promise<AllocateIdsResponse>
121
+ allocateIds(key: entity.Key, options: AllocateIdsOptions | number, callback: AllocateIdsCallback): void
122
+ allocateIds(
123
+ key: entity.Key,
124
+ options: AllocateIdsOptions | number,
125
+ callback?: AllocateIdsCallback
126
+ ): void | Promise<AllocateIdsResponse> {
127
+ options = typeof options === 'number' ? { allocations: options } : options
128
+ const allocations = options.allocations || 1
129
+ const result: entity.Key[] = []
130
+ const info = { keys: [] as any[] }
131
+
132
+ do {
133
+ const id = 5000000000000000 + this.rnd++
134
+ const newKey = this.key([...key.path.slice(0, -1), this.int(id)])
135
+ result.push(newKey)
136
+ info.keys.push({
137
+ partitionId: {
138
+ databaseId: '',
139
+ namespaceId: 'test',
140
+ projectId: 'huwawi3',
141
+ },
142
+ path: [
143
+ {
144
+ id: newKey.id,
145
+ idType: 'id',
146
+ kind: newKey.kind,
147
+ },
148
+ ],
149
+ })
150
+ } while (result.length < allocations)
151
+ callback!(null, result, info)
152
+ }
153
+
154
+ delete(keys: Entities, gaxOptions?: CallOptions): Promise<DeleteResponse>
155
+ delete(keys: Entities, callback: DeleteCallback): void
156
+ delete(keys: Entities, gaxOptions: CallOptions, callback: DeleteCallback): void
157
+ delete(
158
+ keys: entity.Key | entity.Key[],
159
+ gaxOptionsOrCallback?: CallOptions | DeleteCallback,
160
+ cb?: DeleteCallback
161
+ ): void | Promise<DeleteResponse> {
162
+ const gaxOptions = typeof gaxOptionsOrCallback === 'object' ? gaxOptionsOrCallback : {}
163
+ const callback = typeof gaxOptionsOrCallback === 'function' ? gaxOptionsOrCallback : cb!
164
+
165
+ const result: CommitResponse[] = []
166
+
167
+ for (const key of [keys].flat()) {
168
+ this.db.delete(this._keySerializer(key))
169
+ result.push({
170
+ mutationResults: [
171
+ {
172
+ key: null,
173
+ version: 1,
174
+ conflictDetected: false, // (boolean|null);
175
+ },
176
+ ],
177
+ indexUpdates: 1, // number|null);
178
+ } as unknown as CommitResponse)
179
+ }
180
+ setImmediate(() => callback(null, result.length === 1 ? result[0] : (result as any)))
181
+ }
182
+ get(keys: entity.Key | entity.Key[], options?: CreateReadStreamOptions): Promise<GetResponse>
183
+ get(keys: entity.Key | entity.Key[], callback: GetCallback): void
184
+ get(keys: entity.Key | entity.Key[], options: CreateReadStreamOptions, callback: GetCallback): void
185
+ get(
186
+ keys: entity.Key | entity.Key[],
187
+ optionsOrCallback?: CreateReadStreamOptions | GetCallback,
188
+ cb?: GetCallback
189
+ ): void | Promise<GetResponse> {
190
+ const options = typeof optionsOrCallback === 'object' && optionsOrCallback ? optionsOrCallback : {}
191
+ const callback = typeof optionsOrCallback === 'function' ? optionsOrCallback : cb!
192
+
193
+ if ([keys].flat().length === 0) {
194
+ throw Error('At least one Key object is required.')
195
+ }
196
+
197
+ const result: any[] = []
198
+ let lastK
199
+ for (let key of [keys].flat()) {
200
+ // dedupe
201
+ const k = this._keySerializer(key)
202
+ if (k !== lastK && this.db.has(k)) {
203
+ result.push(this.db.get(k))
204
+ }
205
+ lastK = k
206
+ }
207
+
208
+ setImmediate(() => callback(null, Array.isArray(keys) ? result : (result[0] as any)))
209
+ }
210
+
211
+ runQuery(query: Query, options?: RunQueryOptions): Promise<RunQueryResponse>
212
+ runQuery(query: Query, options: RunQueryOptions, callback: RunQueryCallback): void
213
+ runQuery(query: Query, callback: RunQueryCallback): void
214
+ runQuery(
215
+ query: Query,
216
+ optionsOrCallback?: RunQueryOptions | RunQueryCallback,
217
+ cb?: RunQueryCallback
218
+ ): void | Promise<RunQueryResponse> {
219
+ const options = typeof optionsOrCallback === 'object' ? optionsOrCallback : {}
220
+ const callback = typeof optionsOrCallback === 'function' ? optionsOrCallback : cb!
221
+ assert(query.kinds.length === 1)
222
+ const kind = query.kinds[0]
223
+
224
+ const reply: any[] = []
225
+ const filtered = Array.from(this.db.entries()).filter(([ks, v]) => {
226
+ const k = JSON.parse(ks)
227
+ return k.kind === kind && k.namespace === query.namespace
228
+ })
229
+
230
+ for (let filter of query.filters) {
231
+ if (filter.name === '__key__' && filter.op === 'HAS_ANCESTOR') {
232
+ const parent = filter.val.path.join('⭕️')
233
+ for (let [ks, entity] of filtered) {
234
+ const k = JSON.parse(ks)
235
+ if (k.path.join('⭕️').startsWith(parent)) {
236
+ reply.push(entity)
237
+ }
238
+ }
239
+ } else if (filter.op === '=') {
240
+ for (let [ks, entity] of filtered) {
241
+ if (entity[filter.name] == filter.val) {
242
+ reply.push(entity)
243
+ }
244
+ }
245
+ } else if (filter.op === '>=') {
246
+ for (let [ks, entity] of filtered) {
247
+ if (entity[filter.name] >= filter.val) {
248
+ reply.push(entity)
249
+ }
250
+ }
251
+ } else if (filter.op === '<') {
252
+ for (let [ks, entity] of filtered) {
253
+ if (entity[filter.name] >= filter.val) {
254
+ reply.push(entity)
255
+ }
256
+ }
257
+ } else {
258
+ console.log('unknown filter', filter)
259
+ }
260
+ }
261
+
262
+ setImmediate(() => callback(null, reply, {}))
263
+ }
264
+
265
+ merge(entities: Entities): Promise<CommitResponse>
266
+ merge(entities: Entities, callback: SaveCallback): void
267
+ merge(entities: Entities, callback?: SaveCallback): void | Promise<CommitResponse> {
268
+ throw Error('not implemented')
269
+ }
270
+
271
+ insert(entities: Entities): Promise<InsertResponse>
272
+ insert(entities: Entities, callback: InsertCallback): void
273
+ insert(entities: Entities, callback?: InsertCallback): void | Promise<InsertResponse> {
274
+ entities = [entities]
275
+ .flat()
276
+ .map(DatastoreRequest.prepareEntityObject_)
277
+ .map((x: PrepareEntityObjectResponse) => {
278
+ x.method = 'insert'
279
+ return x
280
+ })
281
+
282
+ this.save(entities, callback!)
283
+ }
284
+
285
+ update(entities: Entities): Promise<UpdateResponse>
286
+ update(entities: Entities, callback: UpdateCallback): void
287
+ update(entities: Entities, callback?: UpdateCallback): void | Promise<UpdateResponse> {
288
+ entities = [entities]
289
+ .flat()
290
+ .map(DatastoreRequest.prepareEntityObject_)
291
+ .map((x: PrepareEntityObjectResponse) => {
292
+ x.method = 'update'
293
+ return x
294
+ })
295
+
296
+ this.save(entities, callback!)
297
+ }
298
+
299
+ upsert(entities: Entities): Promise<UpsertResponse>
300
+ upsert(entities: Entities, callback: UpsertCallback): void
301
+ upsert(entities: Entities, callback?: UpsertCallback): void | Promise<UpsertResponse> {
302
+ entities = [entities]
303
+ .flat()
304
+ .map(DatastoreRequest.prepareEntityObject_)
305
+ .map((x: PrepareEntityObjectResponse) => {
306
+ x.method = 'upsert'
307
+ return x
308
+ })
309
+
310
+ this.save(entities, callback!)
311
+ }
312
+
313
+ save(entities: Entities, gaxOptions?: CallOptions): Promise<SaveResponse>
314
+ save(entities: Entities, gaxOptions: CallOptions, callback: SaveCallback): void
315
+ save(entities: Entities, callback: SaveCallback): void
316
+ save(
317
+ entities: Entities,
318
+ gaxOptionsOrCallback?: CallOptions | SaveCallback,
319
+ cb?: SaveCallback
320
+ ): void | Promise<SaveResponse> {
321
+ const gaxOptions = typeof gaxOptionsOrCallback === 'object' ? gaxOptionsOrCallback : {}
322
+ const callback = typeof gaxOptionsOrCallback === 'function' ? gaxOptionsOrCallback : cb!
323
+
324
+ const methods: Record<string, boolean> = {
325
+ insert: true,
326
+ update: true,
327
+ upsert: true,
328
+ }
329
+ entities = [entities].flat()
330
+ // Iterate over the entity objects, build a proto from all keys and values,
331
+ // then place in the correct mutation array (insert, update, etc).
332
+ const result: CommitResponse[] = []
333
+ ;[entities]
334
+ .flat()
335
+ .map(DatastoreRequest.prepareEntityObject_)
336
+ .forEach((entityObject: Entity, index: number) => {
337
+ let method = 'upsert'
338
+ if (entityObject.method) {
339
+ if (methods[entityObject.method]) {
340
+ method = entityObject.method
341
+ } else {
342
+ throw new Error('Method ' + entityObject.method + ' not recognized.')
343
+ }
344
+ }
345
+ // TODO: generate key
346
+
347
+ // Numerical IDs are always encoded as string in the datastore
348
+ const newKey =
349
+ entityObject.key.id === undefined
350
+ ? this.key(entityObject.key.path)
351
+ : this.key([...entityObject.key.path.slice(0, -1), this.int(entityObject.key.path.slice(-1)[0])])
352
+
353
+ this.db.set(this._keySerializer(newKey), {
354
+ [Datastore.KEY]: newKey,
355
+ ...entityObject.data,
356
+ })
357
+
358
+ result.push({
359
+ mutationResults: [
360
+ {
361
+ key: null,
362
+ version: 1,
363
+ conflictDetected: false, // (boolean|null);
364
+ createTime: { nanos: 1, seconds: 2 },
365
+ updateTime: { nanos: 3, seconds: 4 },
366
+ },
367
+ ],
368
+ indexUpdates: 1, // number|null);
369
+ } as unknown as CommitResponse)
370
+ })
371
+ setImmediate(() => callback(null, result[0] as any))
372
+ }
373
+
374
+ static KEY: typeof entity.KEY_SYMBOL = entity.KEY_SYMBOL
375
+ KEY: typeof entity.KEY_SYMBOL = Datastore.KEY
376
+ static MORE_RESULTS_AFTER_CURSOR = 'MORE_RESULTS_AFTER_CURSOR'
377
+ MORE_RESULTS_AFTER_CURSOR = Datastore.MORE_RESULTS_AFTER_CURSOR
378
+ static MORE_RESULTS_AFTER_LIMIT = 'MORE_RESULTS_AFTER_LIMIT'
379
+ MORE_RESULTS_AFTER_LIMIT = Datastore.MORE_RESULTS_AFTER_LIMIT
380
+ static NO_MORE_RESULTS = 'NO_MORE_RESULTS'
381
+ NO_MORE_RESULTS = Datastore.NO_MORE_RESULTS
382
+
383
+ createQuery(kind?: string): Query
384
+ createQuery(kind?: string[]): Query
385
+ createQuery(namespace: string, kind: string): Query
386
+ createQuery(namespace: string, kind: string[]): Query
387
+ createQuery(namespaceOrKind?: string | string[], kind?: string | string[]): Query {
388
+ let namespace = namespaceOrKind as string
389
+ if (!kind) {
390
+ kind = namespaceOrKind
391
+ namespace = this.namespace!
392
+ }
393
+ return new Query(this as any, namespace, [kind].flat() as string[])
394
+ }
395
+ key(options: entity.KeyOptions): entity.Key
396
+ key(path: PathType[]): entity.Key
397
+ key(path: string): entity.Key
398
+ key(options: string | entity.KeyOptions | PathType[]): entity.Key {
399
+ const keyOptions = is.object(options)
400
+ ? (options as entity.KeyOptions)
401
+ : {
402
+ namespace: this.namespace,
403
+ path: [options].flat() as PathType[],
404
+ }
405
+ return new entity.Key(keyOptions)
406
+ }
407
+ static isKey(value?: unknown) {
408
+ return entity.isDsKey(value as any)
409
+ }
410
+ isKey(value?: unknown) {
411
+ return Datastore.isKey(value)
412
+ }
413
+
414
+ keyToLegacyUrlSafe(key: entity.Key, locationPrefix?: string): Promise<string>
415
+ keyToLegacyUrlSafe(key: entity.Key, callback: KeyToLegacyUrlSafeCallback): void
416
+ keyToLegacyUrlSafe(key: entity.Key, locationPrefix: string, callback: KeyToLegacyUrlSafeCallback): void
417
+ keyToLegacyUrlSafe(
418
+ key: entity.Key,
419
+ locationPrefixOrCallback?: string | KeyToLegacyUrlSafeCallback,
420
+ callback?: KeyToLegacyUrlSafeCallback
421
+ ): Promise<string> | void {
422
+ const locationPrefix = typeof locationPrefixOrCallback === 'string' ? locationPrefixOrCallback : ''
423
+ callback = typeof locationPrefixOrCallback === 'function' ? locationPrefixOrCallback : callback
424
+ this.auth.getProjectId((err: any, projectId: any) => {
425
+ if (err) {
426
+ setImmediate(() => callback!(err))
427
+ return
428
+ }
429
+ setImmediate(() => callback!(null, urlSafeKey.legacyEncode(projectId!, key, locationPrefix)))
430
+ })
431
+ }
432
+
433
+ keyFromLegacyUrlsafe(key: string): entity.Key {
434
+ return urlSafeKey.legacyDecode(key)
435
+ }
436
+ transaction(options?: TransactionOptions) {
437
+ return new Transaction(this as any, options)
438
+ }
439
+ }
440
+
441
+ promisifyAll(Datastore, {
442
+ exclude: [
443
+ 'createAggregationQuery',
444
+ 'double',
445
+ 'isDouble',
446
+ 'geoPoint',
447
+ 'getProjectId',
448
+ 'getSharedQueryOptions',
449
+ 'isGeoPoint',
450
+ 'index',
451
+ 'int',
452
+ 'isInt',
453
+ 'createQuery',
454
+ 'key',
455
+ 'isKey',
456
+ 'keyFromLegacyUrlsafe',
457
+ 'transaction',
458
+ ],
459
+ })
460
+
461
+ export default Datastore
462
+
463
+ class Transaction extends DatastoreRequest {
464
+ namespace?: string
465
+ readOnly: boolean
466
+ request: any // Function
467
+ modifiedEntities_: ModifiedEntities
468
+ skipCommit?: boolean
469
+ constructor(datastore: Datastore, options?: TransactionOptions) {
470
+ super()
471
+ /**
472
+ * @name Transaction#datastore
473
+ * @type {Datastore}
474
+ */
475
+ this.datastore = datastore
476
+
477
+ /**
478
+ * @name Transaction#namespace
479
+ * @type {string}
480
+ */
481
+ this.namespace = datastore.namespace
482
+
483
+ options = options || {}
484
+
485
+ this.id = options.id
486
+ this.readOnly = options.readOnly === true
487
+
488
+ // A queue for entity modifications made during the transaction.
489
+ this.modifiedEntities_ = []
490
+
491
+ // Queue the callbacks that process the API responses.
492
+ this.requestCallbacks_ = []
493
+
494
+ // Queue the requests to make when we send the transactional commit.
495
+ this.requests_ = []
496
+ }
497
+ commit(gaxOptions?: CallOptions): Promise<CommitResponse>
498
+ commit(callback: CommitCallback): void
499
+ commit(gaxOptions: CallOptions, callback: CommitCallback): void
500
+ commit(
501
+ gaxOptionsOrCallback?: CallOptions | CommitCallback,
502
+ cb?: CommitCallback
503
+ ): void | Promise<CommitResponse> {
504
+ const callback =
505
+ typeof gaxOptionsOrCallback === 'function'
506
+ ? gaxOptionsOrCallback
507
+ : typeof cb === 'function'
508
+ ? cb
509
+ : () => {}
510
+ const gaxOptions = typeof gaxOptionsOrCallback === 'object' ? gaxOptionsOrCallback : {}
511
+
512
+ if (this.skipCommit) {
513
+ setImmediate(callback)
514
+ return
515
+ }
516
+
517
+ const keys: Entities = {}
518
+
519
+ callback(null, undefined)
520
+ }
521
+
522
+ createQuery(kind?: string): Query
523
+ createQuery(kind?: string[]): Query
524
+ createQuery(namespace: string, kind: string): Query
525
+ createQuery(namespace: string, kind: string[]): Query
526
+ createQuery(namespaceOrKind?: string | string[], kind?: string | string[]): Query {
527
+ return this.datastore.createQuery.call(this, namespaceOrKind as string, kind as string[])
528
+ }
529
+
530
+ createAggregationQuery(query: Query): AggregateQuery {
531
+ return this.datastore.createAggregationQuery.call(this, query)
532
+ }
533
+ delete(entities?: Entities): any {
534
+ this.datastore.delete(entities)
535
+ }
536
+ insert(entities: Entities): void {
537
+ this.save(entities)
538
+ }
539
+
540
+ rollback(callback: RollbackCallback): void
541
+ rollback(gaxOptions?: CallOptions): Promise<RollbackResponse>
542
+ rollback(gaxOptions: CallOptions, callback: RollbackCallback): void
543
+ rollback(
544
+ gaxOptionsOrCallback?: CallOptions | RollbackCallback,
545
+ cb?: RollbackCallback
546
+ ): void | Promise<RollbackResponse> {
547
+ const gaxOptions = typeof gaxOptionsOrCallback === 'object' ? gaxOptionsOrCallback : {}
548
+ const callback = typeof gaxOptionsOrCallback === 'function' ? gaxOptionsOrCallback : cb!
549
+
550
+ callback(null, undefined)
551
+ }
552
+
553
+ run(options?: RunOptions): Promise<RunResponse>
554
+ run(callback: RunCallback): void
555
+ run(options: RunOptions, callback: RunCallback): void
556
+ run(optionsOrCallback?: RunOptions | RunCallback, cb?: RunCallback): void | Promise<RunResponse> {
557
+ const options = typeof optionsOrCallback === 'object' ? optionsOrCallback : {}
558
+ const callback = typeof optionsOrCallback === 'function' ? optionsOrCallback : cb!
559
+
560
+ const reqOpts = {
561
+ transactionOptions: {},
562
+ } as RequestOptions
563
+
564
+ if (options.readOnly || this.readOnly) {
565
+ reqOpts.transactionOptions!.readOnly = {}
566
+ }
567
+
568
+ if (options.transactionId || this.id) {
569
+ reqOpts.transactionOptions!.readWrite = {
570
+ previousTransaction: options.transactionId || this.id,
571
+ }
572
+ }
573
+
574
+ if (options.transactionOptions) {
575
+ reqOpts.transactionOptions = options.transactionOptions
576
+ }
577
+
578
+ callback(null, this, undefined)
579
+ }
580
+ save(entities: Entities): void {
581
+ this.datastore.save(entities)
582
+ }
583
+
584
+ update(entities: Entities): void {
585
+ entities = [entities]
586
+ .flat()
587
+ .map(DatastoreRequest.prepareEntityObject_)
588
+ .map((x: PrepareEntityObjectResponse) => {
589
+ x.method = 'update'
590
+ return x
591
+ })
592
+
593
+ this.save(entities)
594
+ }
595
+
596
+ upsert(entities: Entities): void {
597
+ entities = [entities]
598
+ .flat()
599
+ .map(DatastoreRequest.prepareEntityObject_)
600
+ .map((x: PrepareEntityObjectResponse) => {
601
+ x.method = 'upsert'
602
+ return x
603
+ })
604
+
605
+ this.save(entities)
606
+ }
607
+ }
608
+
609
+ export type ModifiedEntities = Array<{
610
+ entity: { key: Entity }
611
+ method: string
612
+ args: Entity[]
613
+ }>
614
+ export type RunResponse = [Transaction, google.datastore.v1.IBeginTransactionResponse]
615
+ export interface RunCallback {
616
+ (
617
+ error: Error | null,
618
+ transaction: Transaction | null,
619
+ response?: google.datastore.v1.IBeginTransactionResponse
620
+ ): void
621
+ }
622
+ export interface RollbackCallback {
623
+ (error: Error | null, response?: google.datastore.v1.IRollbackResponse): void
624
+ }
625
+ export type RollbackResponse = [google.datastore.v1.IRollbackResponse]
626
+ export interface RunOptions {
627
+ readOnly?: boolean
628
+ transactionId?: string
629
+ transactionOptions?: TransactionOptions
630
+ gaxOptions?: CallOptions
631
+ }
632
+ /*! Developer Documentation
633
+ *
634
+ * All async methods (except for streams) will return a Promise in the event
635
+ * that a callback is omitted.
636
+ */
637
+ promisifyAll(Transaction, {
638
+ exclude: ['createAggregationQuery', 'createQuery', 'delete', 'insert', 'save', 'update', 'upsert'],
639
+ })
@@ -0,0 +1,20 @@
1
+ /*
2
+ * operators.ts
3
+ *
4
+ * Created by Dr. Maximillian Dornseif 2023-04-20 in huwawi3backend 18.13.0
5
+ * based on https://github.com/KoryNunn/datastore-mock 1.1.0 by korynunn
6
+ */
7
+
8
+ export default {
9
+ // @ts-ignore
10
+
11
+ '>': (a, b) => a > b,
12
+ // @ts-ignore
13
+ '<': (a, b) => a < b,
14
+ // @ts-ignore
15
+ '>=': (a, b) => a <= b,
16
+ // @ts-ignore
17
+ '<=': (a, b) => a >= b,
18
+ // @ts-ignore
19
+ '=': (a, b) => a === b,
20
+ }