@carddb/core 0.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.
package/dist/index.cjs ADDED
@@ -0,0 +1,1177 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ AuthenticationError: () => AuthenticationError,
24
+ CardDBError: () => CardDBError,
25
+ Collection: () => Collection,
26
+ ConnectionError: () => ConnectionError,
27
+ FilterBuilder: () => FilterBuilder,
28
+ GraphQLError: () => GraphQLError,
29
+ LinkResolutionError: () => LinkResolutionError,
30
+ NotFoundError: () => NotFoundError,
31
+ QueryBuilder: () => QueryBuilder,
32
+ RateLimitError: () => RateLimitError,
33
+ RestrictedError: () => RestrictedError,
34
+ ServerError: () => ServerError,
35
+ TimeoutError: () => TimeoutError,
36
+ ValidationError: () => ValidationError,
37
+ contains: () => contains,
38
+ eq: () => eq,
39
+ gt: () => gt,
40
+ gte: () => gte,
41
+ ilike: () => ilike,
42
+ isNotNull: () => isNotNull,
43
+ isNull: () => isNull,
44
+ like: () => like,
45
+ lt: () => lt,
46
+ lte: () => lte,
47
+ neq: () => neq,
48
+ notWithin: () => notWithin,
49
+ resolveFilter: () => resolveFilter,
50
+ within: () => within
51
+ });
52
+ module.exports = __toCommonJS(index_exports);
53
+
54
+ // src/errors.ts
55
+ var CardDBError = class _CardDBError extends Error {
56
+ /** The full response body if available */
57
+ response;
58
+ constructor(message, response) {
59
+ super(message);
60
+ this.name = "CardDBError";
61
+ this.response = response;
62
+ if (Error.captureStackTrace) {
63
+ Error.captureStackTrace(this, _CardDBError);
64
+ }
65
+ }
66
+ };
67
+ var AuthenticationError = class extends CardDBError {
68
+ constructor(message = "Invalid or missing API key", response) {
69
+ super(message, response);
70
+ this.name = "AuthenticationError";
71
+ }
72
+ };
73
+ var RateLimitError = class extends CardDBError {
74
+ /** Seconds until rate limit resets */
75
+ retryAfter;
76
+ /** Maximum requests allowed */
77
+ limit;
78
+ /** Remaining requests in window */
79
+ remaining;
80
+ /** Time when the rate limit resets */
81
+ resetAt;
82
+ constructor(message = "Rate limit exceeded", options = {}) {
83
+ super(message, options.response);
84
+ this.name = "RateLimitError";
85
+ this.retryAfter = options.retryAfter ?? null;
86
+ this.limit = options.limit ?? null;
87
+ this.remaining = options.remaining ?? null;
88
+ this.resetAt = options.resetAt ?? null;
89
+ }
90
+ };
91
+ var NotFoundError = class extends CardDBError {
92
+ constructor(message = "Resource not found", response) {
93
+ super(message, response);
94
+ this.name = "NotFoundError";
95
+ }
96
+ };
97
+ var ValidationError = class extends CardDBError {
98
+ /** List of validation errors */
99
+ errors;
100
+ constructor(message = "Validation error", options = {}) {
101
+ super(message, options.response);
102
+ this.name = "ValidationError";
103
+ this.errors = options.errors ?? [];
104
+ }
105
+ };
106
+ var RestrictedError = class extends CardDBError {
107
+ constructor(message, response) {
108
+ super(message, response);
109
+ this.name = "RestrictedError";
110
+ }
111
+ };
112
+ var GraphQLError = class extends CardDBError {
113
+ /** List of GraphQL errors */
114
+ errors;
115
+ constructor(message = "GraphQL error", options = {}) {
116
+ super(message, options.response);
117
+ this.name = "GraphQLError";
118
+ this.errors = options.errors ?? [];
119
+ }
120
+ };
121
+ var ConnectionError = class extends CardDBError {
122
+ constructor(message = "Connection error", response) {
123
+ super(message, response);
124
+ this.name = "ConnectionError";
125
+ }
126
+ };
127
+ var TimeoutError = class extends ConnectionError {
128
+ constructor(message = "Request timed out", response) {
129
+ super(message, response);
130
+ this.name = "TimeoutError";
131
+ }
132
+ };
133
+ var ServerError = class extends CardDBError {
134
+ /** HTTP status code */
135
+ status;
136
+ constructor(message = "Server error", options = {}) {
137
+ super(message, options.response);
138
+ this.name = "ServerError";
139
+ this.status = options.status ?? null;
140
+ }
141
+ };
142
+ var LinkResolutionError = class extends CardDBError {
143
+ /** List of link resolution failures */
144
+ failures;
145
+ /** Partial results that were successfully resolved */
146
+ partialResults;
147
+ constructor(message = "Some links could not be resolved", options = {}) {
148
+ super(message, options.response);
149
+ this.name = "LinkResolutionError";
150
+ this.failures = options.failures ?? [];
151
+ this.partialResults = options.partialResults;
152
+ }
153
+ /**
154
+ * Get failures for a specific field
155
+ */
156
+ getFailuresForField(field) {
157
+ return this.failures.filter((f) => f.field === field);
158
+ }
159
+ /**
160
+ * Check if a specific field had resolution failures
161
+ */
162
+ hasFailuresForField(field) {
163
+ return this.failures.some((f) => f.field === field);
164
+ }
165
+ };
166
+
167
+ // src/operators.ts
168
+ function eq(value) {
169
+ return { eq: value };
170
+ }
171
+ function neq(value) {
172
+ return { neq: value };
173
+ }
174
+ function gt(value) {
175
+ return { gt: value };
176
+ }
177
+ function gte(value) {
178
+ return { gte: value };
179
+ }
180
+ function lt(value) {
181
+ return { lt: value };
182
+ }
183
+ function lte(value) {
184
+ return { lte: value };
185
+ }
186
+ function within(values) {
187
+ return { in: values };
188
+ }
189
+ function notWithin(values) {
190
+ return { nin: values };
191
+ }
192
+ function contains(value) {
193
+ return { contains: value };
194
+ }
195
+ function like(pattern) {
196
+ return { like: pattern };
197
+ }
198
+ function ilike(pattern) {
199
+ return { ilike: pattern };
200
+ }
201
+ function isNull() {
202
+ return { is_null: true };
203
+ }
204
+ function isNotNull() {
205
+ return { is_null: false };
206
+ }
207
+
208
+ // src/filter-builder.ts
209
+ var FilterBuilder = class _FilterBuilder {
210
+ conditions = [];
211
+ orGroups = [];
212
+ where(fieldOrConditions, value) {
213
+ if (typeof fieldOrConditions === "string") {
214
+ this.conditions.push({ [fieldOrConditions]: value });
215
+ } else {
216
+ for (const [field, val] of Object.entries(fieldOrConditions)) {
217
+ this.conditions.push({ [field]: val });
218
+ }
219
+ }
220
+ return this;
221
+ }
222
+ /**
223
+ * Add an OR group (any of the conditions must match)
224
+ *
225
+ * @example
226
+ * .where('type', 'creature')
227
+ * .any(or => or
228
+ * .where('color', 'red')
229
+ * .where('color', 'blue')
230
+ * )
231
+ */
232
+ any(callback) {
233
+ const orBuilder = new _FilterBuilder();
234
+ callback(orBuilder);
235
+ const orConditions = orBuilder.getConditions();
236
+ if (orConditions.length > 0) {
237
+ this.orGroups.push({ $or: orConditions });
238
+ }
239
+ return this;
240
+ }
241
+ /**
242
+ * Add a link filter condition (filter on linked records)
243
+ *
244
+ * @example
245
+ * .whereLink('set_id', { code: 'DMU' })
246
+ * .whereLink('set_id', { name: ilike('%dominaria%') })
247
+ */
248
+ whereLink(field, conditions) {
249
+ const linkFilter = {};
250
+ for (const [key, val] of Object.entries(conditions)) {
251
+ linkFilter[key] = val;
252
+ }
253
+ this.conditions.push({ [`${field}._link`]: linkFilter });
254
+ return this;
255
+ }
256
+ /**
257
+ * Add an array element filter (for ARRAY of HASH fields)
258
+ * Matches if any element in the array matches all conditions
259
+ *
260
+ * @example
261
+ * .whereAny('attacks', { damage: gte(50) })
262
+ * .whereAny('attacks', { name: ilike('%thunder%') })
263
+ */
264
+ whereAny(field, conditions) {
265
+ const anyFilter = {};
266
+ for (const [key, val] of Object.entries(conditions)) {
267
+ anyFilter[key] = val;
268
+ }
269
+ this.conditions.push({ [`${field}._any`]: anyFilter });
270
+ return this;
271
+ }
272
+ /**
273
+ * Get the conditions array (used internally for OR groups)
274
+ */
275
+ getConditions() {
276
+ return this.conditions;
277
+ }
278
+ /**
279
+ * Build the final filter object
280
+ */
281
+ build() {
282
+ const allConditions = [...this.conditions, ...this.orGroups];
283
+ if (allConditions.length === 0) {
284
+ return {};
285
+ }
286
+ if (allConditions.length === 1) {
287
+ return allConditions[0];
288
+ }
289
+ return { $and: allConditions };
290
+ }
291
+ };
292
+ function resolveFilter(input) {
293
+ if (input === void 0) {
294
+ return void 0;
295
+ }
296
+ if (typeof input === "function") {
297
+ const builder = new FilterBuilder();
298
+ input(builder);
299
+ const result = builder.build();
300
+ return Object.keys(result).length > 0 ? result : void 0;
301
+ }
302
+ return Object.keys(input).length > 0 ? input : void 0;
303
+ }
304
+
305
+ // src/query-builder.ts
306
+ var PUBLISHER_FIELDS = `
307
+ id
308
+ name
309
+ slug
310
+ status
311
+ description
312
+ website
313
+ createdAt
314
+ updatedAt
315
+ logoFile {
316
+ id
317
+ url
318
+ }
319
+ bannerFile {
320
+ id
321
+ url
322
+ }
323
+ `;
324
+ var GAME_FIELDS = `
325
+ id
326
+ publisherId
327
+ key
328
+ name
329
+ description
330
+ website
331
+ visibility
332
+ isArchived
333
+ createdAt
334
+ updatedAt
335
+ publisher {
336
+ id
337
+ name
338
+ slug
339
+ }
340
+ logoFile {
341
+ id
342
+ url
343
+ }
344
+ coverFile {
345
+ id
346
+ url
347
+ }
348
+ `;
349
+ var DATASET_FIELDS = `
350
+ id
351
+ publisherId
352
+ gameId
353
+ key
354
+ name
355
+ description
356
+ purpose
357
+ visibility
358
+ isArchived
359
+ createdAt
360
+ updatedAt
361
+ publisher {
362
+ id
363
+ name
364
+ slug
365
+ }
366
+ game {
367
+ id
368
+ key
369
+ name
370
+ }
371
+ `;
372
+ var SCHEMA_FIELDS = `
373
+ schema {
374
+ fields {
375
+ key
376
+ label
377
+ description
378
+ type
379
+ isRequired
380
+ filterable
381
+ searchable
382
+ isIdentifier
383
+ itemType
384
+ displayFormat
385
+ allowedValues
386
+ nestedFields {
387
+ key
388
+ label
389
+ description
390
+ type
391
+ isRequired
392
+ filterable
393
+ searchable
394
+ itemType
395
+ }
396
+ }
397
+ filterableFields
398
+ searchableFields
399
+ linkFields {
400
+ key
401
+ label
402
+ targetDatasetKey
403
+ targetDatasetName
404
+ targetDatasetId
405
+ }
406
+ }
407
+ `;
408
+ var RECORD_FIELDS = `
409
+ id
410
+ datasetId
411
+ data
412
+ createdAt
413
+ updatedAt
414
+ dataset {
415
+ id
416
+ key
417
+ name
418
+ gameId
419
+ publisherId
420
+ }
421
+ `;
422
+ var DECK_FIELDS = `
423
+ id
424
+ accountId
425
+ apiApplicationId
426
+ gameId
427
+ title
428
+ description
429
+ formatKey
430
+ visibility
431
+ externalRef
432
+ sourceUrl
433
+ metadata
434
+ createdAt
435
+ updatedAt
436
+ game {
437
+ ${GAME_FIELDS}
438
+ }
439
+ entries {
440
+ id
441
+ datasetId
442
+ recordId
443
+ identifier
444
+ quantity
445
+ section
446
+ sortOrder
447
+ annotations
448
+ record {
449
+ ${RECORD_FIELDS}
450
+ }
451
+ }
452
+ `;
453
+ var RESOLVED_LINKS_FIELDS = `
454
+ resolvedLinks {
455
+ field
456
+ linkFieldKey
457
+ values
458
+ records {
459
+ id
460
+ datasetId
461
+ data
462
+ }
463
+ }
464
+ `;
465
+ function connectionFields(nodeFields) {
466
+ return `
467
+ totalCount
468
+ pageInfo {
469
+ hasNextPage
470
+ hasPreviousPage
471
+ startCursor
472
+ endCursor
473
+ }
474
+ edges {
475
+ cursor
476
+ node {
477
+ ${nodeFields}
478
+ }
479
+ }
480
+ `;
481
+ }
482
+ var QueryBuilder = {
483
+ // Publishers
484
+ searchPublishers(params = {}) {
485
+ const variables = {};
486
+ const args = [];
487
+ const defs = [];
488
+ if (params.search !== void 0) {
489
+ defs.push("$search: String");
490
+ args.push("search: $search");
491
+ variables["search"] = params.search;
492
+ }
493
+ if (params.first !== void 0) {
494
+ defs.push("$first: Int");
495
+ args.push("first: $first");
496
+ variables["first"] = params.first;
497
+ }
498
+ if (params.after !== void 0) {
499
+ defs.push("$after: String");
500
+ args.push("after: $after");
501
+ variables["after"] = params.after;
502
+ }
503
+ const defStr = defs.length > 0 ? `(${defs.join(", ")})` : "";
504
+ const argStr = args.length > 0 ? `(${args.join(", ")})` : "";
505
+ return {
506
+ query: `
507
+ query SearchPublishers${defStr} {
508
+ searchPublishers${argStr} {
509
+ ${connectionFields(PUBLISHER_FIELDS)}
510
+ }
511
+ }
512
+ `,
513
+ variables
514
+ };
515
+ },
516
+ fetchPublisherById() {
517
+ return {
518
+ query: `
519
+ query FetchPublisher($id: UUID!) {
520
+ fetchPublisher(id: $id) {
521
+ ${PUBLISHER_FIELDS}
522
+ }
523
+ }
524
+ `
525
+ };
526
+ },
527
+ fetchPublisherBySlug() {
528
+ return {
529
+ query: `
530
+ query FetchPublisher($slug: String!) {
531
+ fetchPublisher(slug: $slug) {
532
+ ${PUBLISHER_FIELDS}
533
+ }
534
+ }
535
+ `
536
+ };
537
+ },
538
+ fetchPublishers() {
539
+ return {
540
+ query: `
541
+ query FetchPublishers($slugs: [String!]!) {
542
+ fetchPublishers(slugs: $slugs) {
543
+ ${PUBLISHER_FIELDS}
544
+ }
545
+ }
546
+ `
547
+ };
548
+ },
549
+ // Games
550
+ searchGames(params = {}) {
551
+ const variables = {};
552
+ const args = [];
553
+ const defs = [];
554
+ if (params.publisherSlug !== void 0) {
555
+ defs.push("$publisherSlug: String");
556
+ args.push("publisherSlug: $publisherSlug");
557
+ variables["publisherSlug"] = params.publisherSlug;
558
+ }
559
+ if (params.search !== void 0) {
560
+ defs.push("$search: String");
561
+ args.push("search: $search");
562
+ variables["search"] = params.search;
563
+ }
564
+ if (params.first !== void 0) {
565
+ defs.push("$first: Int");
566
+ args.push("first: $first");
567
+ variables["first"] = params.first;
568
+ }
569
+ if (params.after !== void 0) {
570
+ defs.push("$after: String");
571
+ args.push("after: $after");
572
+ variables["after"] = params.after;
573
+ }
574
+ const defStr = defs.length > 0 ? `(${defs.join(", ")})` : "";
575
+ const argStr = args.length > 0 ? `(${args.join(", ")})` : "";
576
+ return {
577
+ query: `
578
+ query SearchGames${defStr} {
579
+ searchGames${argStr} {
580
+ ${connectionFields(GAME_FIELDS)}
581
+ }
582
+ }
583
+ `,
584
+ variables
585
+ };
586
+ },
587
+ fetchGameById() {
588
+ return {
589
+ query: `
590
+ query FetchGame($id: UUID!) {
591
+ fetchGame(id: $id) {
592
+ ${GAME_FIELDS}
593
+ }
594
+ }
595
+ `
596
+ };
597
+ },
598
+ fetchGameByKeys() {
599
+ return {
600
+ query: `
601
+ query FetchGame($publisherSlug: String!, $gameKey: String!) {
602
+ fetchGame(publisherSlug: $publisherSlug, gameKey: $gameKey) {
603
+ ${GAME_FIELDS}
604
+ }
605
+ }
606
+ `
607
+ };
608
+ },
609
+ fetchGames() {
610
+ return {
611
+ query: `
612
+ query FetchGames($ids: [UUID!]!) {
613
+ fetchGames(ids: $ids) {
614
+ ${GAME_FIELDS}
615
+ }
616
+ }
617
+ `
618
+ };
619
+ },
620
+ // Datasets
621
+ searchDatasets(params = {}) {
622
+ const variables = {};
623
+ const args = [];
624
+ const defs = [];
625
+ if (params.publisherSlug !== void 0) {
626
+ defs.push("$publisherSlug: String");
627
+ args.push("publisherSlug: $publisherSlug");
628
+ variables["publisherSlug"] = params.publisherSlug;
629
+ }
630
+ if (params.gameKey !== void 0) {
631
+ defs.push("$gameKey: String");
632
+ args.push("gameKey: $gameKey");
633
+ variables["gameKey"] = params.gameKey;
634
+ }
635
+ if (params.search !== void 0) {
636
+ defs.push("$search: String");
637
+ args.push("search: $search");
638
+ variables["search"] = params.search;
639
+ }
640
+ if (params.purpose !== void 0) {
641
+ defs.push("$purpose: DatasetPurpose");
642
+ args.push("purpose: $purpose");
643
+ variables["purpose"] = params.purpose;
644
+ }
645
+ if (params.first !== void 0) {
646
+ defs.push("$first: Int");
647
+ args.push("first: $first");
648
+ variables["first"] = params.first;
649
+ }
650
+ if (params.after !== void 0) {
651
+ defs.push("$after: String");
652
+ args.push("after: $after");
653
+ variables["after"] = params.after;
654
+ }
655
+ const defStr = defs.length > 0 ? `(${defs.join(", ")})` : "";
656
+ const argStr = args.length > 0 ? `(${args.join(", ")})` : "";
657
+ return {
658
+ query: `
659
+ query SearchDatasets${defStr} {
660
+ searchDatasets${argStr} {
661
+ ${connectionFields(DATASET_FIELDS)}
662
+ }
663
+ }
664
+ `,
665
+ variables
666
+ };
667
+ },
668
+ fetchDatasetById() {
669
+ return {
670
+ query: `
671
+ query FetchDataset($id: UUID!) {
672
+ fetchDataset(id: $id) {
673
+ ${DATASET_FIELDS}
674
+ ${SCHEMA_FIELDS}
675
+ }
676
+ }
677
+ `
678
+ };
679
+ },
680
+ fetchDatasetByKeys() {
681
+ return {
682
+ query: `
683
+ query FetchDataset($publisherSlug: String!, $gameKey: String!, $datasetKey: String!) {
684
+ fetchDataset(publisherSlug: $publisherSlug, gameKey: $gameKey, datasetKey: $datasetKey) {
685
+ ${DATASET_FIELDS}
686
+ ${SCHEMA_FIELDS}
687
+ }
688
+ }
689
+ `
690
+ };
691
+ },
692
+ fetchDatasets() {
693
+ return {
694
+ query: `
695
+ query FetchDatasets($ids: [UUID!]!) {
696
+ fetchDatasets(ids: $ids) {
697
+ ${DATASET_FIELDS}
698
+ }
699
+ }
700
+ `
701
+ };
702
+ },
703
+ // Records
704
+ searchRecords(params) {
705
+ const variables = {
706
+ publisherSlug: params.publisherSlug,
707
+ gameKey: params.gameKey,
708
+ datasetKey: params.datasetKey
709
+ };
710
+ const args = [
711
+ "publisherSlug: $publisherSlug",
712
+ "gameKey: $gameKey",
713
+ "datasetKey: $datasetKey"
714
+ ];
715
+ const defs = ["$publisherSlug: String!", "$gameKey: String!", "$datasetKey: String!"];
716
+ if (params.filter !== void 0) {
717
+ defs.push("$filter: JSON");
718
+ args.push("filter: $filter");
719
+ variables["filter"] = params.filter;
720
+ }
721
+ if (params.search !== void 0) {
722
+ defs.push("$search: String");
723
+ args.push("search: $search");
724
+ variables["search"] = params.search;
725
+ }
726
+ if (params.orderBy !== void 0) {
727
+ defs.push("$orderBy: String");
728
+ args.push("orderBy: $orderBy");
729
+ variables["orderBy"] = params.orderBy;
730
+ }
731
+ if (params.resolveLinks !== void 0) {
732
+ defs.push("$resolveLinks: [String!]");
733
+ args.push("resolveLinks: $resolveLinks");
734
+ variables["resolveLinks"] = params.resolveLinks;
735
+ }
736
+ if (params.first !== void 0) {
737
+ defs.push("$first: Int");
738
+ args.push("first: $first");
739
+ variables["first"] = params.first;
740
+ }
741
+ if (params.after !== void 0) {
742
+ defs.push("$after: String");
743
+ args.push("after: $after");
744
+ variables["after"] = params.after;
745
+ }
746
+ if (params.validateSchema !== void 0) {
747
+ defs.push("$validateSchema: Boolean");
748
+ args.push("validateSchema: $validateSchema");
749
+ variables["validateSchema"] = params.validateSchema;
750
+ }
751
+ const includeResolvedLinks = params.resolveLinks && params.resolveLinks.length > 0;
752
+ const nodeFields = includeResolvedLinks ? `${RECORD_FIELDS}
753
+ ${RESOLVED_LINKS_FIELDS}` : RECORD_FIELDS;
754
+ return {
755
+ query: `
756
+ query SearchRecords(${defs.join(", ")}) {
757
+ searchRecords(${args.join(", ")}) {
758
+ ${connectionFields(nodeFields)}
759
+ }
760
+ }
761
+ `,
762
+ variables
763
+ };
764
+ },
765
+ fetchRecordById() {
766
+ return {
767
+ query: `
768
+ query FetchRecord($id: UUID!) {
769
+ fetchRecord(id: $id) {
770
+ ${RECORD_FIELDS}
771
+ }
772
+ }
773
+ `
774
+ };
775
+ },
776
+ fetchRecordByIdentifier() {
777
+ return {
778
+ query: `
779
+ query FetchRecordByIdentifier($publisherSlug: String!, $gameKey: String!, $datasetKey: String!, $identifier: String!) {
780
+ fetchRecordByIdentifier(publisherSlug: $publisherSlug, gameKey: $gameKey, datasetKey: $datasetKey, identifier: $identifier) {
781
+ ${RECORD_FIELDS}
782
+ }
783
+ }
784
+ `
785
+ };
786
+ },
787
+ fetchRecordsByIdentifier() {
788
+ return {
789
+ query: `
790
+ query FetchRecordsByIdentifier($publisherSlug: String!, $gameKey: String!, $datasetKey: String!, $identifiers: [String!]!) {
791
+ fetchRecordsByIdentifier(publisherSlug: $publisherSlug, gameKey: $gameKey, datasetKey: $datasetKey, identifiers: $identifiers) {
792
+ ${RECORD_FIELDS}
793
+ }
794
+ }
795
+ `
796
+ };
797
+ },
798
+ fetchRecords() {
799
+ return {
800
+ query: `
801
+ query FetchRecords($ids: [UUID!]!) {
802
+ fetchRecords(ids: $ids) {
803
+ ${RECORD_FIELDS}
804
+ }
805
+ }
806
+ `
807
+ };
808
+ },
809
+ // Decks
810
+ listMyDecks(params = {}) {
811
+ const variables = {};
812
+ const args = [];
813
+ const defs = [];
814
+ if (params.first !== void 0) {
815
+ defs.push("$first: Int");
816
+ args.push("first: $first");
817
+ variables["first"] = params.first;
818
+ }
819
+ if (params.after !== void 0) {
820
+ defs.push("$after: String");
821
+ args.push("after: $after");
822
+ variables["after"] = params.after;
823
+ }
824
+ const defStr = defs.length > 0 ? `(${defs.join(", ")})` : "";
825
+ const argStr = args.length > 0 ? `(${args.join(", ")})` : "";
826
+ return {
827
+ query: `
828
+ query MyDecks${defStr} {
829
+ myDecks${argStr} {
830
+ ${connectionFields(DECK_FIELDS)}
831
+ }
832
+ }
833
+ `,
834
+ variables
835
+ };
836
+ },
837
+ fetchDeckById() {
838
+ return {
839
+ query: `
840
+ query FetchDeck($id: UUID!) {
841
+ fetchDeck(id: $id) {
842
+ ${DECK_FIELDS}
843
+ }
844
+ }
845
+ `
846
+ };
847
+ },
848
+ fetchDeckByExternalRef() {
849
+ return {
850
+ query: `
851
+ query FetchDeckByExternalRef($externalRef: String!) {
852
+ fetchDeckByExternalRef(externalRef: $externalRef) {
853
+ ${DECK_FIELDS}
854
+ }
855
+ }
856
+ `
857
+ };
858
+ },
859
+ createDeck() {
860
+ return {
861
+ query: `
862
+ mutation DeckCreate($input: DeckCreateInput!) {
863
+ deckCreate(input: $input) {
864
+ ${DECK_FIELDS}
865
+ }
866
+ }
867
+ `
868
+ };
869
+ },
870
+ updateDeck() {
871
+ return {
872
+ query: `
873
+ mutation DeckUpdate($id: UUID!, $input: DeckUpdateInput!) {
874
+ deckUpdate(id: $id, input: $input) {
875
+ ${DECK_FIELDS}
876
+ }
877
+ }
878
+ `
879
+ };
880
+ },
881
+ deleteDeck() {
882
+ return {
883
+ query: `
884
+ mutation DeckDelete($id: UUID!) {
885
+ deckDelete(id: $id)
886
+ }
887
+ `
888
+ };
889
+ },
890
+ deckCreateVariables(input) {
891
+ return { input };
892
+ },
893
+ deckUpdateVariables(id, input) {
894
+ return { id, input };
895
+ },
896
+ // API Key Info
897
+ fetchMe() {
898
+ return {
899
+ query: `
900
+ query FetchMe {
901
+ fetchMe {
902
+ application {
903
+ id
904
+ name
905
+ description
906
+ environment
907
+ apiKeyPrefix
908
+ allowedOrigins
909
+ allowedIps
910
+ createdAt
911
+ updatedAt
912
+ lastUsedAt
913
+ }
914
+ account {
915
+ id
916
+ displayName
917
+ createdAt
918
+ }
919
+ }
920
+ }
921
+ `
922
+ };
923
+ }
924
+ };
925
+
926
+ // src/collection.ts
927
+ var Collection = class {
928
+ /** Total count of matching records across all pages */
929
+ totalCount;
930
+ /** Pagination info */
931
+ pageInfo;
932
+ /** Items in the current page */
933
+ items;
934
+ /** Function to load the next page */
935
+ nextPageLoader;
936
+ constructor(data, options = {}) {
937
+ this.totalCount = data.totalCount;
938
+ this.pageInfo = data.pageInfo;
939
+ this.items = data.edges.map(
940
+ (edge) => options.itemTransformer ? options.itemTransformer(edge.node) : edge.node
941
+ );
942
+ this.nextPageLoader = options.nextPageLoader;
943
+ }
944
+ /** Check if there are more pages */
945
+ get hasNextPage() {
946
+ return this.pageInfo.hasNextPage;
947
+ }
948
+ /** Check if there are previous pages */
949
+ get hasPreviousPage() {
950
+ return this.pageInfo.hasPreviousPage;
951
+ }
952
+ /** Get the cursor for the next page */
953
+ get endCursor() {
954
+ return this.pageInfo.endCursor;
955
+ }
956
+ /** Get the cursor for the previous page */
957
+ get startCursor() {
958
+ return this.pageInfo.startCursor;
959
+ }
960
+ /** Number of items in the current page */
961
+ get length() {
962
+ return this.items.length;
963
+ }
964
+ /** Check if the current page is empty */
965
+ get isEmpty() {
966
+ return this.items.length === 0;
967
+ }
968
+ /** Get the first item */
969
+ get first() {
970
+ return this.items[0];
971
+ }
972
+ /** Get the last item */
973
+ get last() {
974
+ return this.items[this.items.length - 1];
975
+ }
976
+ /**
977
+ * Fetch the next page of results
978
+ *
979
+ * @returns The next page collection, or null if no more pages
980
+ * @throws Error if no next page loader is configured
981
+ */
982
+ async nextPage() {
983
+ if (!this.hasNextPage) {
984
+ return null;
985
+ }
986
+ if (!this.nextPageLoader) {
987
+ throw new Error("No next page loader configured");
988
+ }
989
+ if (!this.endCursor) {
990
+ return null;
991
+ }
992
+ return this.nextPageLoader(this.endCursor);
993
+ }
994
+ /**
995
+ * Async iterator that automatically paginates through all results
996
+ *
997
+ * @example
998
+ * for await (const record of collection) {
999
+ * console.log(record.name)
1000
+ * }
1001
+ *
1002
+ * @example
1003
+ * const allRecords = []
1004
+ * for await (const record of collection) {
1005
+ * allRecords.push(record)
1006
+ * }
1007
+ */
1008
+ async *[Symbol.asyncIterator]() {
1009
+ let current = this;
1010
+ while (current) {
1011
+ for (const item of current.items) {
1012
+ yield item;
1013
+ }
1014
+ if (!current.hasNextPage) {
1015
+ break;
1016
+ }
1017
+ current = await current.nextPage();
1018
+ }
1019
+ }
1020
+ /**
1021
+ * Iterate through all results, calling a callback for each item
1022
+ * Similar to Array.forEach but async and auto-paginating
1023
+ *
1024
+ * @example
1025
+ * await collection.forEach(async (record) => {
1026
+ * await processRecord(record)
1027
+ * })
1028
+ */
1029
+ async forEach(callback) {
1030
+ let index = 0;
1031
+ for await (const item of this) {
1032
+ await callback(item, index++);
1033
+ }
1034
+ }
1035
+ /**
1036
+ * Map over all results, returning a new array
1037
+ * Auto-paginates through all pages
1038
+ *
1039
+ * @example
1040
+ * const names = await collection.map(record => record.name)
1041
+ */
1042
+ async map(callback) {
1043
+ const results = [];
1044
+ let index = 0;
1045
+ for await (const item of this) {
1046
+ results.push(await callback(item, index++));
1047
+ }
1048
+ return results;
1049
+ }
1050
+ /**
1051
+ * Filter results, returning items that match the predicate
1052
+ * Auto-paginates through all pages
1053
+ *
1054
+ * @example
1055
+ * const rareCards = await collection.filter(card => card.rarity === 'rare')
1056
+ */
1057
+ async filter(predicate) {
1058
+ const results = [];
1059
+ let index = 0;
1060
+ for await (const item of this) {
1061
+ if (await predicate(item, index++)) {
1062
+ results.push(item);
1063
+ }
1064
+ }
1065
+ return results;
1066
+ }
1067
+ /**
1068
+ * Find the first item matching a predicate
1069
+ * Stops iterating once found
1070
+ *
1071
+ * @example
1072
+ * const pikachu = await collection.find(card => card.name === 'Pikachu')
1073
+ */
1074
+ async find(predicate) {
1075
+ let index = 0;
1076
+ for await (const item of this) {
1077
+ if (await predicate(item, index++)) {
1078
+ return item;
1079
+ }
1080
+ }
1081
+ return void 0;
1082
+ }
1083
+ /**
1084
+ * Take the first n items
1085
+ * Stops fetching pages once n items are collected
1086
+ *
1087
+ * @example
1088
+ * const first100 = await collection.take(100)
1089
+ */
1090
+ async take(n) {
1091
+ const results = [];
1092
+ for await (const item of this) {
1093
+ if (results.length >= n) {
1094
+ break;
1095
+ }
1096
+ results.push(item);
1097
+ }
1098
+ return results;
1099
+ }
1100
+ /**
1101
+ * Collect all items into an array
1102
+ * Auto-paginates through all pages
1103
+ *
1104
+ * @example
1105
+ * const allRecords = await collection.toArray()
1106
+ */
1107
+ async toArray() {
1108
+ const results = [];
1109
+ for await (const item of this) {
1110
+ results.push(item);
1111
+ }
1112
+ return results;
1113
+ }
1114
+ /**
1115
+ * Iterate in batches (similar to Rails find_in_batches)
1116
+ *
1117
+ * @example
1118
+ * for await (const batch of collection.batches()) {
1119
+ * await processBatch(batch)
1120
+ * }
1121
+ */
1122
+ async *batches() {
1123
+ let current = this;
1124
+ while (current) {
1125
+ if (current.items.length > 0) {
1126
+ yield current.items;
1127
+ }
1128
+ if (!current.hasNextPage) {
1129
+ break;
1130
+ }
1131
+ current = await current.nextPage();
1132
+ }
1133
+ }
1134
+ /**
1135
+ * Iterate one item at a time with batched fetching (similar to Rails find_each)
1136
+ *
1137
+ * @example
1138
+ * for await (const item of collection.each()) {
1139
+ * await processItem(item)
1140
+ * }
1141
+ */
1142
+ each() {
1143
+ return this;
1144
+ }
1145
+ };
1146
+ // Annotate the CommonJS export names for ESM import in node:
1147
+ 0 && (module.exports = {
1148
+ AuthenticationError,
1149
+ CardDBError,
1150
+ Collection,
1151
+ ConnectionError,
1152
+ FilterBuilder,
1153
+ GraphQLError,
1154
+ LinkResolutionError,
1155
+ NotFoundError,
1156
+ QueryBuilder,
1157
+ RateLimitError,
1158
+ RestrictedError,
1159
+ ServerError,
1160
+ TimeoutError,
1161
+ ValidationError,
1162
+ contains,
1163
+ eq,
1164
+ gt,
1165
+ gte,
1166
+ ilike,
1167
+ isNotNull,
1168
+ isNull,
1169
+ like,
1170
+ lt,
1171
+ lte,
1172
+ neq,
1173
+ notWithin,
1174
+ resolveFilter,
1175
+ within
1176
+ });
1177
+ //# sourceMappingURL=index.cjs.map