tantan-typeorm-gs 1.0.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.
Files changed (53) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +31 -0
  3. package/bun.lock +300 -0
  4. package/docs/authentication.md +118 -0
  5. package/docs/configuration.md +680 -0
  6. package/docs/contributing.md +177 -0
  7. package/docs/crud.md +351 -0
  8. package/docs/custom-client.md +165 -0
  9. package/docs/development.md +243 -0
  10. package/docs/entities.md +502 -0
  11. package/docs/find-options.md +296 -0
  12. package/docs/google-cloud.md +101 -0
  13. package/docs/installation.md +51 -0
  14. package/docs/integration-testing.md +178 -0
  15. package/docs/limitations.md +223 -0
  16. package/docs/pagination.md +384 -0
  17. package/docs/performance.md +171 -0
  18. package/docs/security.md +153 -0
  19. package/docs/sorting.md +0 -0
  20. package/docs/supported-features.md +310 -0
  21. package/docs/synchronization.md +203 -0
  22. package/package.json +43 -0
  23. package/src/client/index.ts +589 -0
  24. package/src/core/data-source.ts +47 -0
  25. package/src/core/driver.ts +290 -0
  26. package/src/core/error.ts +144 -0
  27. package/src/core/memory.ts +152 -0
  28. package/src/core/query/interpreter.ts +949 -0
  29. package/src/core/query/runner.ts +1297 -0
  30. package/src/core/query/types.ts +155 -0
  31. package/src/core/schema-builder.ts +64 -0
  32. package/src/core/types.ts +113 -0
  33. package/src/core/utils.ts +13 -0
  34. package/src/index.ts +3 -0
  35. package/tantan-typeorm-gs.code-workspace +8 -0
  36. package/test/base/0001-data-source.test.ts +252 -0
  37. package/test/base/0002-operator.test.ts +616 -0
  38. package/test/base/0003-select.test.ts +281 -0
  39. package/test/base/0004-aggregate.test.ts +213 -0
  40. package/test/base/0005-transcation.test.ts +1566 -0
  41. package/test/base/0006-relation.test.ts +1611 -0
  42. package/test/base/0007-logging.test.ts +182 -0
  43. package/test/base/0008-soft-delete.test.ts +649 -0
  44. package/test/google-sheets/0001-client.test.ts +1705 -0
  45. package/test/google-sheets/0002-worksheet-management.test.ts +408 -0
  46. package/test/google-sheets/0003-data-source.test.ts +1935 -0
  47. package/test/google-sheets/0004-transactions.test.ts +952 -0
  48. package/test/google-sheets/0005-operator.test.ts +1124 -0
  49. package/test/google-sheets/0006-object-criteria.test.ts +283 -0
  50. package/test/google-sheets/0007-performance.test.ts +532 -0
  51. package/test/public-api.test.ts +34 -0
  52. package/tsconfig.build.json +21 -0
  53. package/tsconfig.json +34 -0
@@ -0,0 +1,616 @@
1
+ import { describe, expect, test } from 'bun:test';
2
+ import
3
+ {
4
+ Column,
5
+ Entity,
6
+ In,
7
+ IsNull,
8
+ LessThan,
9
+ LessThanOrEqual,
10
+ MoreThan,
11
+ MoreThanOrEqual,
12
+ Not,
13
+ PrimaryGeneratedColumn,
14
+ } from 'typeorm';
15
+ import { Memory } from '../../src/core/memory';
16
+ import { createGoogleSheetsDataSource } from '../../src/core/data-source';
17
+
18
+ describe('GoogleSheetsDataSource - Operators', () =>
19
+ {
20
+ @Entity()
21
+ class User
22
+ {
23
+ @PrimaryGeneratedColumn()
24
+ id!: number;
25
+
26
+ @Column({ nullable: true })
27
+ name!: string | null;
28
+ }
29
+
30
+ test('finds entities with equal condition', async () =>
31
+ {
32
+ const dataSource = createGoogleSheetsDataSource({
33
+ type: 'google-sheets',
34
+ client: new Memory({
35
+ user: [
36
+ { id: 1, name: 'Basuni' },
37
+ { id: 2, name: 'Budi' },
38
+ { id: 3, name: 'Andi' },
39
+ ],
40
+ }),
41
+ entities: [User],
42
+ });
43
+
44
+ await dataSource.initialize();
45
+
46
+ const repository = dataSource.getRepository(User);
47
+
48
+ const users = await repository.find({
49
+ where: {
50
+ name: 'Basuni',
51
+ },
52
+ });
53
+
54
+ expect(users).toHaveLength(1);
55
+ expect(users[0]).toMatchObject({
56
+ id: 1,
57
+ name: 'Basuni',
58
+ });
59
+
60
+ await dataSource.destroy();
61
+ });
62
+
63
+ test('finds entities with Not equal condition', async () =>
64
+ {
65
+ const dataSource = createGoogleSheetsDataSource({
66
+ type: 'google-sheets',
67
+ client: new Memory({
68
+ user: [
69
+ { id: 1, name: 'Basuni' },
70
+ { id: 2, name: 'Budi' },
71
+ { id: 3, name: 'Andi' },
72
+ ],
73
+ }),
74
+ entities: [User],
75
+ });
76
+
77
+ await dataSource.initialize();
78
+
79
+ const repository = dataSource.getRepository(User);
80
+
81
+ const users = await repository.find({
82
+ where: {
83
+ name: Not('Basuni'),
84
+ },
85
+ });
86
+
87
+ expect(users.map((user) => user.id)).toEqual([2, 3]);
88
+
89
+ await dataSource.destroy();
90
+ });
91
+
92
+ test('finds entities with Not equal operator <>', async () =>
93
+ {
94
+ const dataSource = createGoogleSheetsDataSource({
95
+ type: 'google-sheets',
96
+ client: new Memory({
97
+ user: [
98
+ { id: 1, name: 'Basuni' },
99
+ { id: 2, name: 'Budi' },
100
+ { id: 3, name: 'Andi' },
101
+ ],
102
+ }),
103
+ entities: [User],
104
+ });
105
+
106
+ await dataSource.initialize();
107
+
108
+ const repository = dataSource.getRepository(User);
109
+
110
+ const users = await repository
111
+ .createQueryBuilder('user')
112
+ .where('"user"."name" <> :name', {
113
+ name: 'Basuni',
114
+ })
115
+ .getMany();
116
+
117
+ expect(users.map((user) => user.id)).toEqual([2, 3]);
118
+
119
+ await dataSource.destroy();
120
+ });
121
+
122
+ test('finds entities with MoreThan condition', async () =>
123
+ {
124
+ const dataSource = createGoogleSheetsDataSource({
125
+ type: 'google-sheets',
126
+ client: new Memory({
127
+ user: [
128
+ { id: 1, name: 'Basuni' },
129
+ { id: 2, name: 'Budi' },
130
+ { id: 3, name: 'Andi' },
131
+ ],
132
+ }),
133
+ entities: [User],
134
+ });
135
+
136
+ await dataSource.initialize();
137
+
138
+ const repository = dataSource.getRepository(User);
139
+
140
+ const users = await repository.find({
141
+ where: {
142
+ id: MoreThan(1),
143
+ },
144
+ });
145
+
146
+ expect(users.map((user) => user.id)).toEqual([2, 3]);
147
+
148
+ await dataSource.destroy();
149
+ });
150
+
151
+ test('finds entities with MoreThanOrEqual condition', async () =>
152
+ {
153
+ const dataSource = createGoogleSheetsDataSource({
154
+ type: 'google-sheets',
155
+ client: new Memory({
156
+ user: [
157
+ { id: 1, name: 'Basuni' },
158
+ { id: 2, name: 'Budi' },
159
+ { id: 3, name: 'Andi' },
160
+ ],
161
+ }),
162
+ entities: [User],
163
+ });
164
+
165
+ await dataSource.initialize();
166
+
167
+ const repository = dataSource.getRepository(User);
168
+
169
+ const users = await repository.find({
170
+ where: {
171
+ id: MoreThanOrEqual(2),
172
+ },
173
+ });
174
+
175
+ expect(users.map((user) => user.id)).toEqual([2, 3]);
176
+
177
+ await dataSource.destroy();
178
+ });
179
+
180
+ test('finds entities with LessThan condition', async () =>
181
+ {
182
+ const dataSource = createGoogleSheetsDataSource({
183
+ type: 'google-sheets',
184
+ client: new Memory({
185
+ user: [
186
+ { id: 1, name: 'Basuni' },
187
+ { id: 2, name: 'Budi' },
188
+ { id: 3, name: 'Andi' },
189
+ ],
190
+ }),
191
+ entities: [User],
192
+ });
193
+
194
+ await dataSource.initialize();
195
+
196
+ const repository = dataSource.getRepository(User);
197
+
198
+ const users = await repository.find({
199
+ where: {
200
+ id: LessThan(3),
201
+ },
202
+ });
203
+
204
+ expect(users.map((user) => user.id)).toEqual([1, 2]);
205
+
206
+ await dataSource.destroy();
207
+ });
208
+
209
+ test('finds entities with LessThanOrEqual condition', async () =>
210
+ {
211
+ const dataSource = createGoogleSheetsDataSource({
212
+ type: 'google-sheets',
213
+ client: new Memory({
214
+ user: [
215
+ { id: 1, name: 'Basuni' },
216
+ { id: 2, name: 'Budi' },
217
+ { id: 3, name: 'Andi' },
218
+ ],
219
+ }),
220
+ entities: [User],
221
+ });
222
+
223
+ await dataSource.initialize();
224
+
225
+ const repository = dataSource.getRepository(User);
226
+
227
+ const users = await repository.find({
228
+ where: {
229
+ id: LessThanOrEqual(2),
230
+ },
231
+ });
232
+
233
+ expect(users.map((user) => user.id)).toEqual([1, 2]);
234
+
235
+ await dataSource.destroy();
236
+ });
237
+
238
+ test('finds entities with IsNull condition', async () =>
239
+ {
240
+ const dataSource = createGoogleSheetsDataSource({
241
+ type: 'google-sheets',
242
+ client: new Memory({
243
+ user: [
244
+ { id: 1, name: 'Basuni' },
245
+ { id: 2, name: null },
246
+ { id: 3, name: 'Budi' },
247
+ ],
248
+ }),
249
+ entities: [User],
250
+ });
251
+
252
+ await dataSource.initialize();
253
+
254
+ const repository = dataSource.getRepository(User);
255
+
256
+ const users = await repository.find({
257
+ where: {
258
+ name: IsNull(),
259
+ },
260
+ });
261
+
262
+ expect(users).toHaveLength(1);
263
+ expect(users[0]).toMatchObject({
264
+ id: 2,
265
+ name: null,
266
+ });
267
+
268
+ await dataSource.destroy();
269
+ });
270
+
271
+ test('finds entities with IsNotNull condition', async () =>
272
+ {
273
+ const dataSource = createGoogleSheetsDataSource({
274
+ type: 'google-sheets',
275
+ client: new Memory({
276
+ user: [
277
+ { id: 1, name: 'Basuni' },
278
+ { id: 2, name: null },
279
+ { id: 3, name: 'Budi' },
280
+ ],
281
+ }),
282
+ entities: [User],
283
+ });
284
+
285
+ await dataSource.initialize();
286
+
287
+ const repository = dataSource.getRepository(User);
288
+
289
+ const users = await repository.find({
290
+ where: {
291
+ name: Not(IsNull()),
292
+ },
293
+ });
294
+
295
+ expect(users.map((user) => user.id)).toEqual([1, 3]);
296
+
297
+ await dataSource.destroy();
298
+ });
299
+
300
+ test('finds entities with In condition', async () =>
301
+ {
302
+ const dataSource = createGoogleSheetsDataSource({
303
+ type: 'google-sheets',
304
+ client: new Memory({
305
+ user: [
306
+ { id: 1, name: 'Basuni' },
307
+ { id: 2, name: 'Budi' },
308
+ { id: 3, name: 'Andi' },
309
+ ],
310
+ }),
311
+ entities: [User],
312
+ });
313
+
314
+ await dataSource.initialize();
315
+
316
+ const repository = dataSource.getRepository(User);
317
+
318
+ const users = await repository.find({
319
+ where: {
320
+ id: In([1, 3]),
321
+ },
322
+ });
323
+
324
+ expect(users.map((user) => user.id)).toEqual([1, 3]);
325
+
326
+ await dataSource.destroy();
327
+ });
328
+
329
+ test('finds entities with Not In condition', async () =>
330
+ {
331
+ const dataSource = createGoogleSheetsDataSource({
332
+ type: 'google-sheets',
333
+ client: new Memory({
334
+ user: [
335
+ { id: 1, name: 'Basuni' },
336
+ { id: 2, name: 'Budi' },
337
+ { id: 3, name: 'Andi' },
338
+ ],
339
+ }),
340
+ entities: [User],
341
+ });
342
+
343
+ await dataSource.initialize();
344
+
345
+ const repository = dataSource.getRepository(User);
346
+
347
+ const users = await repository.find({
348
+ where: {
349
+ id: Not(In([1, 3])),
350
+ },
351
+ });
352
+
353
+ expect(users.map((user) => user.id)).toEqual([2]);
354
+
355
+ await dataSource.destroy();
356
+ });
357
+
358
+ test('finds entities with LIKE condition', async () =>
359
+ {
360
+ const dataSource = createGoogleSheetsDataSource({
361
+ type: 'google-sheets',
362
+ client: new Memory({
363
+ user: [
364
+ { id: 1, name: 'Basuni' },
365
+ { id: 2, name: 'Budi' },
366
+ { id: 3, name: 'Andi' },
367
+ { id: 4, name: 'Basuki' },
368
+ ],
369
+ }),
370
+ entities: [User],
371
+ });
372
+
373
+ await dataSource.initialize();
374
+
375
+ const repository = dataSource.getRepository(User);
376
+
377
+ const users = await repository
378
+ .createQueryBuilder('user')
379
+ .where('"user"."name" LIKE :name', {
380
+ name: 'Basu%',
381
+ })
382
+ .getMany();
383
+
384
+ expect(users.map((user) => user.id)).toEqual([1, 4]);
385
+
386
+ await dataSource.destroy();
387
+ });
388
+
389
+ test('finds entities with NOT LIKE condition', async () =>
390
+ {
391
+ const dataSource = createGoogleSheetsDataSource({
392
+ type: 'google-sheets',
393
+ client: new Memory({
394
+ user: [
395
+ { id: 1, name: 'Basuni' },
396
+ { id: 2, name: 'Budi' },
397
+ { id: 3, name: 'Andi' },
398
+ { id: 4, name: 'Basuki' },
399
+ ],
400
+ }),
401
+ entities: [User],
402
+ });
403
+
404
+ await dataSource.initialize();
405
+
406
+ const repository = dataSource.getRepository(User);
407
+
408
+ const users = await repository
409
+ .createQueryBuilder('user')
410
+ .where('"user"."name" NOT LIKE :name', {
411
+ name: 'Basu%',
412
+ })
413
+ .getMany();
414
+
415
+ expect(users.map((user) => user.id)).toEqual([2, 3]);
416
+
417
+ await dataSource.destroy();
418
+ });
419
+
420
+ test('finds entities with ILIKE condition', async () =>
421
+ {
422
+ const dataSource = createGoogleSheetsDataSource({
423
+ type: 'google-sheets',
424
+ client: new Memory({
425
+ user: [
426
+ { id: 1, name: 'Basuni' },
427
+ { id: 2, name: 'Budi' },
428
+ { id: 3, name: 'ANDI' },
429
+ { id: 4, name: 'Basuki' },
430
+ ],
431
+ }),
432
+ entities: [User],
433
+ });
434
+
435
+ await dataSource.initialize();
436
+
437
+ const repository = dataSource.getRepository(User);
438
+
439
+ const users = await repository
440
+ .createQueryBuilder('user')
441
+ .where('"user"."name" ILIKE :name', {
442
+ name: 'andi',
443
+ })
444
+ .getMany();
445
+
446
+ expect(users.map((user) => user.id)).toEqual([3]);
447
+
448
+ await dataSource.destroy();
449
+ });
450
+
451
+ test('finds entities with NOT ILIKE condition', async () =>
452
+ {
453
+ const dataSource = createGoogleSheetsDataSource({
454
+ type: 'google-sheets',
455
+ client: new Memory({
456
+ user: [
457
+ { id: 1, name: 'Basuni' },
458
+ { id: 2, name: 'Budi' },
459
+ { id: 3, name: 'ANDI' },
460
+ { id: 4, name: 'Basuki' },
461
+ ],
462
+ }),
463
+ entities: [User],
464
+ });
465
+
466
+ await dataSource.initialize();
467
+
468
+ const repository = dataSource.getRepository(User);
469
+
470
+ const users = await repository
471
+ .createQueryBuilder('user')
472
+ .where('"user"."name" NOT ILIKE :name', {
473
+ name: 'andi',
474
+ })
475
+ .getMany();
476
+
477
+ expect(users.map((user) => user.id)).toEqual([1, 2, 4]);
478
+
479
+ await dataSource.destroy();
480
+ });
481
+
482
+ test('finds entities with BETWEEN condition', async () =>
483
+ {
484
+ const dataSource = createGoogleSheetsDataSource({
485
+ type: 'google-sheets',
486
+ client: new Memory({
487
+ user: [
488
+ { id: 1, name: 'Basuni' },
489
+ { id: 2, name: 'Budi' },
490
+ { id: 3, name: 'Andi' },
491
+ { id: 4, name: 'Caca' },
492
+ { id: 5, name: 'Deni' },
493
+ ],
494
+ }),
495
+ entities: [User],
496
+ });
497
+
498
+ await dataSource.initialize();
499
+
500
+ const repository = dataSource.getRepository(User);
501
+
502
+ const users = await repository
503
+ .createQueryBuilder('user')
504
+ .where(
505
+ '"user"."id" BETWEEN :min AND :max',
506
+ {
507
+ min: 2,
508
+ max: 4,
509
+ },
510
+ )
511
+ .getMany();
512
+
513
+ expect(users.map((user) => user.id)).toEqual([2, 3, 4]);
514
+
515
+ await dataSource.destroy();
516
+ });
517
+
518
+ test('finds entities with AND condition', async () =>
519
+ {
520
+ const dataSource = createGoogleSheetsDataSource({
521
+ type: 'google-sheets',
522
+ client: new Memory({
523
+ user: [
524
+ { id: 1, name: 'Basuni' },
525
+ { id: 2, name: 'Budi' },
526
+ { id: 3, name: 'Andi' },
527
+ { id: 4, name: 'Caca' },
528
+ ],
529
+ }),
530
+ entities: [User],
531
+ });
532
+
533
+ await dataSource.initialize();
534
+
535
+ const repository = dataSource.getRepository(User);
536
+
537
+ const users = await repository.find({
538
+ where: {
539
+ id: MoreThan(1),
540
+ name: 'Andi',
541
+ },
542
+ });
543
+
544
+ expect(users.map((user) => user.id)).toEqual([3]);
545
+
546
+ await dataSource.destroy();
547
+ });
548
+
549
+ test('finds entities with OR condition', async () =>
550
+ {
551
+ const dataSource = createGoogleSheetsDataSource({
552
+ type: 'google-sheets',
553
+ client: new Memory({
554
+ user: [
555
+ { id: 1, name: 'Basuni' },
556
+ { id: 2, name: 'Budi' },
557
+ { id: 3, name: 'Andi' },
558
+ { id: 4, name: 'Caca' },
559
+ ],
560
+ }),
561
+ entities: [User],
562
+ });
563
+
564
+ await dataSource.initialize();
565
+
566
+ const repository = dataSource.getRepository(User);
567
+
568
+ const users = await repository.find({
569
+ where: [
570
+ { id: 1 },
571
+ { id: 4 },
572
+ ],
573
+ });
574
+
575
+ expect(users.map((user) => user.id)).toEqual([1, 4]);
576
+
577
+ await dataSource.destroy();
578
+ });
579
+
580
+ test('finds entities with combined AND and OR conditions', async () =>
581
+ {
582
+ const dataSource = createGoogleSheetsDataSource({
583
+ type: 'google-sheets',
584
+ client: new Memory({
585
+ user: [
586
+ { id: 1, name: 'Basuni' },
587
+ { id: 2, name: 'Budi' },
588
+ { id: 3, name: 'Andi' },
589
+ { id: 4, name: 'Andi' },
590
+ { id: 5, name: 'Caca' },
591
+ ],
592
+ }),
593
+ entities: [User],
594
+ });
595
+
596
+ await dataSource.initialize();
597
+
598
+ const repository = dataSource.getRepository(User);
599
+
600
+ const users = await repository
601
+ .createQueryBuilder('user')
602
+ .where(
603
+ '(("user"."id" > :min AND "user"."name" = :name) OR "user"."id" = :id)',
604
+ {
605
+ min: 2,
606
+ name: 'Andi',
607
+ id: 1,
608
+ },
609
+ )
610
+ .getMany();
611
+
612
+ expect(users.map((user) => user.id)).toEqual([1, 3, 4]);
613
+
614
+ await dataSource.destroy();
615
+ });
616
+ });