scryfall-api 4.0.0-beta.0 → 4.0.0-beta.1
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/scryfall-api.cjs +488 -0
- package/dist/scryfall-api.d.ts +424 -0
- package/dist/scryfall-api.js +452 -0
- package/dist/scryfall-api.min.cjs +1 -0
- package/dist/scryfall-api.min.js +1 -0
- package/package.json +2 -1
|
@@ -0,0 +1,488 @@
|
|
|
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/scryfall-api.ts
|
|
21
|
+
var scryfall_api_exports = {};
|
|
22
|
+
__export(scryfall_api_exports, {
|
|
23
|
+
CardIdentifierBuilder: () => card_identifier_default,
|
|
24
|
+
Cards: () => card_default,
|
|
25
|
+
Catalogs: () => catalog_default,
|
|
26
|
+
InvalidScryfallArgumentError: () => InvalidScryfallArgumentError,
|
|
27
|
+
MagicPageResult: () => MagicPageResult,
|
|
28
|
+
Rulings: () => ruling_default,
|
|
29
|
+
ScryfallError: () => ScryfallError,
|
|
30
|
+
Sets: () => set_default,
|
|
31
|
+
SymbologyApi: () => symbology_default,
|
|
32
|
+
UnknownScryfallError: () => UnknownScryfallError
|
|
33
|
+
});
|
|
34
|
+
module.exports = __toCommonJS(scryfall_api_exports);
|
|
35
|
+
|
|
36
|
+
// src/error/invalid.error.ts
|
|
37
|
+
var InvalidScryfallArgumentError = class extends Error {
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
// src/error/scryfall.error.ts
|
|
41
|
+
var ScryfallError = class extends Error {
|
|
42
|
+
constructor(code, details, status, type, warnings) {
|
|
43
|
+
super(details);
|
|
44
|
+
this.code = code;
|
|
45
|
+
this.status = status;
|
|
46
|
+
this.type = type;
|
|
47
|
+
this.warnings = warnings;
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
// src/error/unknown.error.ts
|
|
52
|
+
var UnknownScryfallError = class extends Error {
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
// src/fetcher/debounce.fetcher.ts
|
|
56
|
+
var lastQuery = 100;
|
|
57
|
+
var rateLimit = 100;
|
|
58
|
+
async function sleep(ms = 0) {
|
|
59
|
+
return new Promise((resolve) => {
|
|
60
|
+
setTimeout(resolve, ms);
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
async function debounce() {
|
|
64
|
+
const now = Date.now();
|
|
65
|
+
const timeSinceLastQuery = now - lastQuery;
|
|
66
|
+
if (timeSinceLastQuery >= rateLimit) {
|
|
67
|
+
lastQuery = now;
|
|
68
|
+
} else {
|
|
69
|
+
const timeUntilNextQuery = rateLimit - timeSinceLastQuery;
|
|
70
|
+
lastQuery += timeUntilNextQuery;
|
|
71
|
+
await sleep(timeUntilNextQuery);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
function createDebounceFetcher(fetcher2 = fetch) {
|
|
75
|
+
return async function debounceFetcher(...args) {
|
|
76
|
+
await debounce();
|
|
77
|
+
return fetcher2(...args);
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// src/fetcher/page.result.ts
|
|
82
|
+
var MagicPageResult = class {
|
|
83
|
+
constructor(apiPath, query) {
|
|
84
|
+
this.apiPath = apiPath;
|
|
85
|
+
this.query = query;
|
|
86
|
+
this.#hasMore = true;
|
|
87
|
+
this.#count = 0;
|
|
88
|
+
}
|
|
89
|
+
#count;
|
|
90
|
+
#hasMore;
|
|
91
|
+
get count() {
|
|
92
|
+
return this.#count;
|
|
93
|
+
}
|
|
94
|
+
get hasMore() {
|
|
95
|
+
return this.#hasMore;
|
|
96
|
+
}
|
|
97
|
+
async all() {
|
|
98
|
+
const r = [];
|
|
99
|
+
while (this.#hasMore) {
|
|
100
|
+
const result = await this.next();
|
|
101
|
+
r.push(...result);
|
|
102
|
+
}
|
|
103
|
+
return r;
|
|
104
|
+
}
|
|
105
|
+
async get(limit) {
|
|
106
|
+
const r = [];
|
|
107
|
+
while (this.#hasMore) {
|
|
108
|
+
const result = await this.next();
|
|
109
|
+
r.push(...result);
|
|
110
|
+
if (r.length === limit) {
|
|
111
|
+
return r;
|
|
112
|
+
}
|
|
113
|
+
if (r.length > limit) {
|
|
114
|
+
return r.slice(0, limit);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return r;
|
|
118
|
+
}
|
|
119
|
+
async next() {
|
|
120
|
+
const results = await fetcher(this.apiPath, this.query);
|
|
121
|
+
this.#hasMore = results?.has_more ?? false;
|
|
122
|
+
this.#count = Number.parseInt(`${results?.total_cards ?? 0}`, 10);
|
|
123
|
+
if (this.#hasMore) {
|
|
124
|
+
this.setNextPage();
|
|
125
|
+
}
|
|
126
|
+
return results?.data ?? [];
|
|
127
|
+
}
|
|
128
|
+
async page(page) {
|
|
129
|
+
this.query.page = page;
|
|
130
|
+
return this.next();
|
|
131
|
+
}
|
|
132
|
+
setNextPage() {
|
|
133
|
+
this.query.page += 1;
|
|
134
|
+
}
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
// src/fetcher/retry.fetcher.ts
|
|
138
|
+
var defaultCanRetry = async (response) => {
|
|
139
|
+
const object = await response.json();
|
|
140
|
+
const status = "status" in object ? Number(object.status) : void 0;
|
|
141
|
+
if (status && status >= 500) {
|
|
142
|
+
return true;
|
|
143
|
+
}
|
|
144
|
+
const code = "code" in object && typeof object.code === "string" ? object.code : void 0;
|
|
145
|
+
return code !== "not_found" && code !== "bad_request";
|
|
146
|
+
};
|
|
147
|
+
function createRetryFetcher({ maxAttempts = 3, canRetry = defaultCanRetry } = {}, fetcher2 = fetch) {
|
|
148
|
+
let retries = 0;
|
|
149
|
+
return async function retryFetcher(...args) {
|
|
150
|
+
retries++;
|
|
151
|
+
const response = await fetcher2(...args);
|
|
152
|
+
if (response.ok) {
|
|
153
|
+
return response;
|
|
154
|
+
}
|
|
155
|
+
const object = await response.json();
|
|
156
|
+
const code = "code" in object && typeof object.code === "string" ? object.code : void 0;
|
|
157
|
+
const status = "status" in object ? Number(object.status) : void 0;
|
|
158
|
+
const details = "details" in object && typeof object.details === "string" ? object.details : void 0;
|
|
159
|
+
const type = "type" in object && typeof object.type === "string" ? object.type : void 0;
|
|
160
|
+
const warnings = "warnings" in object && Array.isArray(object.warnings) ? object.warnings : void 0;
|
|
161
|
+
if (retries >= maxAttempts) {
|
|
162
|
+
if (code && details && status) {
|
|
163
|
+
throw new ScryfallError(code, details, status, type, warnings);
|
|
164
|
+
}
|
|
165
|
+
throw new UnknownScryfallError(`Request failed with status ${response.status}`);
|
|
166
|
+
}
|
|
167
|
+
if (canRetry(response)) {
|
|
168
|
+
return retryFetcher(...args);
|
|
169
|
+
}
|
|
170
|
+
if (code && details && status) {
|
|
171
|
+
throw new ScryfallError(code, details, status, type, warnings);
|
|
172
|
+
}
|
|
173
|
+
throw new UnknownScryfallError(`Request failed with status ${response.status}`);
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// src/fetcher/index.ts
|
|
178
|
+
var simpleFetcher = createDebounceFetcher(createRetryFetcher());
|
|
179
|
+
var endpoint = "https://api.scryfall.com";
|
|
180
|
+
var DATE_REGEXP = /^\d{4}-\d{2}-\d{2}?$/;
|
|
181
|
+
var dateParser = (_key, value) => {
|
|
182
|
+
if (typeof value === "string") {
|
|
183
|
+
if (DATE_REGEXP.test(value)) {
|
|
184
|
+
return new Date(value);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
return value;
|
|
188
|
+
};
|
|
189
|
+
async function fetcher(apiPath, params, body) {
|
|
190
|
+
let path = "";
|
|
191
|
+
if (typeof apiPath === "number" || typeof apiPath === "string") {
|
|
192
|
+
path = apiPath;
|
|
193
|
+
} else if (apiPath) {
|
|
194
|
+
path = apiPath.join("/");
|
|
195
|
+
}
|
|
196
|
+
const url = new URL(`${endpoint}/${path}`);
|
|
197
|
+
if (params) {
|
|
198
|
+
Object.entries(params).forEach(([key, value]) => {
|
|
199
|
+
if (value !== void 0) {
|
|
200
|
+
url.searchParams.append(key, `${value}`);
|
|
201
|
+
}
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
try {
|
|
205
|
+
const init = {
|
|
206
|
+
method: body ? "POST" : "GET"
|
|
207
|
+
};
|
|
208
|
+
if (body) {
|
|
209
|
+
init.body = JSON.stringify(body);
|
|
210
|
+
init.headers = {
|
|
211
|
+
"Content-Type": "application/json"
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
const response = await simpleFetcher(url, init);
|
|
215
|
+
const content = await response.text();
|
|
216
|
+
return JSON.parse(content, dateParser);
|
|
217
|
+
} catch (e) {
|
|
218
|
+
if (e instanceof ScryfallError) {
|
|
219
|
+
if (e.warnings) {
|
|
220
|
+
console.warn(e.warnings);
|
|
221
|
+
}
|
|
222
|
+
if (e.code === "not_found" || e.code === "bad_request") {
|
|
223
|
+
return void 0;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
throw e;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// src/api/card/card.api.ts
|
|
231
|
+
var CardApi = class {
|
|
232
|
+
/*
|
|
233
|
+
* Returns up to 20 full English card names that could be autocompletions of the given string parameter.
|
|
234
|
+
* @param {string} name
|
|
235
|
+
* The string to search for
|
|
236
|
+
* @returns {Promise<string[]>}
|
|
237
|
+
* A list of up to 20 full English card names.
|
|
238
|
+
*/
|
|
239
|
+
async autoCompleteName(name) {
|
|
240
|
+
const result = await fetcher("cards/autocomplete", {
|
|
241
|
+
q: name
|
|
242
|
+
});
|
|
243
|
+
return result?.data ?? [];
|
|
244
|
+
}
|
|
245
|
+
/*
|
|
246
|
+
* Returns a single card with the given Magic: The Gathering Arena ID.
|
|
247
|
+
* @param {number} id
|
|
248
|
+
* The Magic: The Gathering Arena ID of the card to retrieve.
|
|
249
|
+
* @returns {Promise<Card | undefined>}
|
|
250
|
+
* Returns a single card or undefined if no card is found.
|
|
251
|
+
*/
|
|
252
|
+
async byArenaId(id) {
|
|
253
|
+
return fetcher(["cards/arena", id]);
|
|
254
|
+
}
|
|
255
|
+
/*
|
|
256
|
+
* Returns a single card with the given Scryfall ID.
|
|
257
|
+
* @param {number} id
|
|
258
|
+
* The Scryfall ID.
|
|
259
|
+
* @returns {Promise<Card | undefined>}
|
|
260
|
+
* Returns a single card or undefined if no card is found.
|
|
261
|
+
*/
|
|
262
|
+
async byId(id) {
|
|
263
|
+
return fetcher(["cards", id]);
|
|
264
|
+
}
|
|
265
|
+
async byMtgoId(id) {
|
|
266
|
+
return fetcher(["cards/mtgo", id]);
|
|
267
|
+
}
|
|
268
|
+
async byMultiverseId(id) {
|
|
269
|
+
return fetcher(["cards/multiverse", id]);
|
|
270
|
+
}
|
|
271
|
+
async byName(name, set2, fuzzy = false) {
|
|
272
|
+
let f = fuzzy;
|
|
273
|
+
let s = set2;
|
|
274
|
+
if (typeof set2 === "boolean") {
|
|
275
|
+
f = set2;
|
|
276
|
+
s = void 0;
|
|
277
|
+
}
|
|
278
|
+
return fetcher("cards/named", {
|
|
279
|
+
[f ? "fuzzy" : "exact"]: name,
|
|
280
|
+
set: s
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
async bySet(setCode, collectorNumber, lang) {
|
|
284
|
+
const path = ["cards", setCode, collectorNumber];
|
|
285
|
+
if (lang) {
|
|
286
|
+
path.push(lang);
|
|
287
|
+
}
|
|
288
|
+
return fetcher(path);
|
|
289
|
+
}
|
|
290
|
+
async byTcgPlayerId(id) {
|
|
291
|
+
return fetcher(["cards/tcgplayer", id]);
|
|
292
|
+
}
|
|
293
|
+
async collection(...identifiers) {
|
|
294
|
+
const cards2 = [];
|
|
295
|
+
for (let i = 0; i < identifiers.length; i += 75) {
|
|
296
|
+
const collectionSection = { identifiers: identifiers.slice(i, i + 75) };
|
|
297
|
+
const result = await fetcher(
|
|
298
|
+
"cards/collection",
|
|
299
|
+
void 0,
|
|
300
|
+
collectionSection
|
|
301
|
+
);
|
|
302
|
+
cards2.push(...result?.data ?? []);
|
|
303
|
+
}
|
|
304
|
+
return cards2;
|
|
305
|
+
}
|
|
306
|
+
async random() {
|
|
307
|
+
return fetcher("cards/random");
|
|
308
|
+
}
|
|
309
|
+
search(query, options) {
|
|
310
|
+
return new MagicPageResult("cards/search", {
|
|
311
|
+
q: query,
|
|
312
|
+
...typeof options === "number" ? { page: options } : { ...options, page: options?.page ?? 1 }
|
|
313
|
+
});
|
|
314
|
+
}
|
|
315
|
+
};
|
|
316
|
+
var cards = new CardApi();
|
|
317
|
+
var card_api_default = cards;
|
|
318
|
+
|
|
319
|
+
// src/api/card/index.ts
|
|
320
|
+
var card_default = card_api_default;
|
|
321
|
+
|
|
322
|
+
// src/api/card-identifier/card-identifier.api.ts
|
|
323
|
+
var CardIdentifierApi = class {
|
|
324
|
+
static byId(id) {
|
|
325
|
+
return { id };
|
|
326
|
+
}
|
|
327
|
+
static byIllustrationId(id) {
|
|
328
|
+
return { illustration_id: id };
|
|
329
|
+
}
|
|
330
|
+
static byMtgoId(id) {
|
|
331
|
+
return { mtgo_id: id };
|
|
332
|
+
}
|
|
333
|
+
static byMultiverseId(id) {
|
|
334
|
+
return { multiverse_id: id };
|
|
335
|
+
}
|
|
336
|
+
static byName(name, set2) {
|
|
337
|
+
if (set2) {
|
|
338
|
+
return { name, set: set2 };
|
|
339
|
+
}
|
|
340
|
+
return { name };
|
|
341
|
+
}
|
|
342
|
+
static byOracleId(id) {
|
|
343
|
+
return { oracle_id: id };
|
|
344
|
+
}
|
|
345
|
+
static bySet(set2, collectorNumber) {
|
|
346
|
+
return { collector_number: `${collectorNumber}`, set: set2 };
|
|
347
|
+
}
|
|
348
|
+
};
|
|
349
|
+
|
|
350
|
+
// src/api/card-identifier/index.ts
|
|
351
|
+
var card_identifier_default = CardIdentifierApi;
|
|
352
|
+
|
|
353
|
+
// src/api/catalog/catalog.api.ts
|
|
354
|
+
var CatalogApi = class {
|
|
355
|
+
async artifactTypes() {
|
|
356
|
+
return (await fetcher("catalog/artifact-types"))?.data ?? [];
|
|
357
|
+
}
|
|
358
|
+
async artistNames() {
|
|
359
|
+
return (await fetcher("catalog/artist-names"))?.data ?? [];
|
|
360
|
+
}
|
|
361
|
+
async cardNames() {
|
|
362
|
+
return (await fetcher("catalog/card-names"))?.data ?? [];
|
|
363
|
+
}
|
|
364
|
+
async creatureTypes() {
|
|
365
|
+
return (await fetcher("catalog/creature-types"))?.data ?? [];
|
|
366
|
+
}
|
|
367
|
+
async enchantmentTypes() {
|
|
368
|
+
return (await fetcher("catalog/enchantment-types"))?.data ?? [];
|
|
369
|
+
}
|
|
370
|
+
async landTypes() {
|
|
371
|
+
return (await fetcher("catalog/land-types"))?.data ?? [];
|
|
372
|
+
}
|
|
373
|
+
async loyalties() {
|
|
374
|
+
return (await fetcher("catalog/loyalties"))?.data ?? [];
|
|
375
|
+
}
|
|
376
|
+
async planeswalkerTypes() {
|
|
377
|
+
return (await fetcher("catalog/planeswalker-types"))?.data ?? [];
|
|
378
|
+
}
|
|
379
|
+
async powers() {
|
|
380
|
+
return (await fetcher("catalog/powers"))?.data ?? [];
|
|
381
|
+
}
|
|
382
|
+
async spellTypes() {
|
|
383
|
+
return (await fetcher("catalog/spell-types"))?.data ?? [];
|
|
384
|
+
}
|
|
385
|
+
async toughnesses() {
|
|
386
|
+
return (await fetcher("catalog/toughnesses"))?.data ?? [];
|
|
387
|
+
}
|
|
388
|
+
async watermarks() {
|
|
389
|
+
return (await fetcher("catalog/watermarks"))?.data ?? [];
|
|
390
|
+
}
|
|
391
|
+
async wordBank() {
|
|
392
|
+
return (await fetcher("catalog/word-bank"))?.data ?? [];
|
|
393
|
+
}
|
|
394
|
+
};
|
|
395
|
+
var catalog = new CatalogApi();
|
|
396
|
+
var catalog_api_default = catalog;
|
|
397
|
+
|
|
398
|
+
// src/api/catalog/index.ts
|
|
399
|
+
var catalog_default = catalog_api_default;
|
|
400
|
+
|
|
401
|
+
// src/api/ruling/ruling.api.ts
|
|
402
|
+
var RulingApi = class {
|
|
403
|
+
async byArenaId(id) {
|
|
404
|
+
return (await fetcher(["cards/arena", id, "rulings"]))?.data ?? [];
|
|
405
|
+
}
|
|
406
|
+
async byId(id) {
|
|
407
|
+
return (await fetcher(["cards", id, "rulings"]))?.data ?? [];
|
|
408
|
+
}
|
|
409
|
+
async byMtgoId(id) {
|
|
410
|
+
return (await fetcher(["cards/mtgo", id, "rulings"]))?.data ?? [];
|
|
411
|
+
}
|
|
412
|
+
async byMultiverseId(id) {
|
|
413
|
+
return (await fetcher(["cards/multiverse", id, "rulings"]))?.data ?? [];
|
|
414
|
+
}
|
|
415
|
+
async bySet(setCode, collectorNumber) {
|
|
416
|
+
return (await fetcher(["cards", setCode, `${collectorNumber}`, "rulings"]))?.data ?? [];
|
|
417
|
+
}
|
|
418
|
+
};
|
|
419
|
+
var rulings = new RulingApi();
|
|
420
|
+
var ruling_api_default = rulings;
|
|
421
|
+
|
|
422
|
+
// src/api/ruling/index.ts
|
|
423
|
+
var ruling_default = ruling_api_default;
|
|
424
|
+
|
|
425
|
+
// src/api/set/set.api.ts
|
|
426
|
+
var SetApi = class {
|
|
427
|
+
async all() {
|
|
428
|
+
const result = await fetcher("sets");
|
|
429
|
+
return result?.data ?? [];
|
|
430
|
+
}
|
|
431
|
+
async byCode(code) {
|
|
432
|
+
return await fetcher(["sets", code]);
|
|
433
|
+
}
|
|
434
|
+
async byId(id) {
|
|
435
|
+
return fetcher(["sets", id]);
|
|
436
|
+
}
|
|
437
|
+
async byTcgPlayerId(id) {
|
|
438
|
+
return fetcher(["sets/tcgplayer", id]);
|
|
439
|
+
}
|
|
440
|
+
};
|
|
441
|
+
var set = new SetApi();
|
|
442
|
+
var set_api_default = set;
|
|
443
|
+
|
|
444
|
+
// src/api/set/index.ts
|
|
445
|
+
var set_default = set_api_default;
|
|
446
|
+
|
|
447
|
+
// src/api/symbology/symbology.api.ts
|
|
448
|
+
var SymbologyApi = class {
|
|
449
|
+
async all() {
|
|
450
|
+
const list = await fetcher("symbology");
|
|
451
|
+
return list?.data ?? [];
|
|
452
|
+
}
|
|
453
|
+
async parseMana(shorthand) {
|
|
454
|
+
if (!shorthand || typeof shorthand !== "string") {
|
|
455
|
+
throw new InvalidScryfallArgumentError("shorthand must be a string");
|
|
456
|
+
}
|
|
457
|
+
const cost = await fetcher("symbology/parse-mana", {
|
|
458
|
+
cost: shorthand
|
|
459
|
+
});
|
|
460
|
+
return cost ?? {
|
|
461
|
+
cost: "",
|
|
462
|
+
colors: [],
|
|
463
|
+
cmc: 0,
|
|
464
|
+
colorless: false,
|
|
465
|
+
monocolored: false,
|
|
466
|
+
multicolored: false,
|
|
467
|
+
object: "mana_cost"
|
|
468
|
+
};
|
|
469
|
+
}
|
|
470
|
+
};
|
|
471
|
+
var symbology = new SymbologyApi();
|
|
472
|
+
var symbology_api_default = symbology;
|
|
473
|
+
|
|
474
|
+
// src/api/symbology/index.ts
|
|
475
|
+
var symbology_default = symbology_api_default;
|
|
476
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
477
|
+
0 && (module.exports = {
|
|
478
|
+
CardIdentifierBuilder,
|
|
479
|
+
Cards,
|
|
480
|
+
Catalogs,
|
|
481
|
+
InvalidScryfallArgumentError,
|
|
482
|
+
MagicPageResult,
|
|
483
|
+
Rulings,
|
|
484
|
+
ScryfallError,
|
|
485
|
+
Sets,
|
|
486
|
+
SymbologyApi,
|
|
487
|
+
UnknownScryfallError
|
|
488
|
+
});
|
|
@@ -0,0 +1,424 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type definition for Nullable.
|
|
3
|
+
* @type {T | null | undefined} The type can be T, null, or undefined.
|
|
4
|
+
* @template T The type of the value that can be null or undefined.
|
|
5
|
+
*/
|
|
6
|
+
type Nullable<T> = T | null | undefined;
|
|
7
|
+
|
|
8
|
+
type QueryValue = boolean | number | string | undefined;
|
|
9
|
+
interface PageQuery {
|
|
10
|
+
[key: string]: QueryValue;
|
|
11
|
+
page: number;
|
|
12
|
+
}
|
|
13
|
+
declare class MagicPageResult<T> {
|
|
14
|
+
#private;
|
|
15
|
+
private readonly apiPath;
|
|
16
|
+
private readonly query;
|
|
17
|
+
constructor(apiPath: string, query: PageQuery);
|
|
18
|
+
get count(): number;
|
|
19
|
+
get hasMore(): boolean;
|
|
20
|
+
all(): Promise<T[]>;
|
|
21
|
+
get(limit: number): Promise<T[]>;
|
|
22
|
+
next(): Promise<T[]>;
|
|
23
|
+
page(page: number): Promise<T[]>;
|
|
24
|
+
private setNextPage;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
interface CardIdentifierId {
|
|
28
|
+
id: string;
|
|
29
|
+
}
|
|
30
|
+
interface CardIdentifierIllustrationId {
|
|
31
|
+
illustration_id: string;
|
|
32
|
+
}
|
|
33
|
+
interface CardIdentifierMtgGoId {
|
|
34
|
+
mtgo_id: number;
|
|
35
|
+
}
|
|
36
|
+
interface CardIdentifierMultiverseId {
|
|
37
|
+
multiverse_id: number;
|
|
38
|
+
}
|
|
39
|
+
interface CardIdentifierNameSet {
|
|
40
|
+
name: string;
|
|
41
|
+
set?: string;
|
|
42
|
+
}
|
|
43
|
+
interface CardIdentifierOracleId {
|
|
44
|
+
oracle_id: string;
|
|
45
|
+
}
|
|
46
|
+
interface CardIdentifierCollectorSet {
|
|
47
|
+
collector_number: string;
|
|
48
|
+
set: string;
|
|
49
|
+
}
|
|
50
|
+
type CardIdentifier = CardIdentifierId | CardIdentifierIllustrationId | CardIdentifierMtgGoId | CardIdentifierMultiverseId | CardIdentifierNameSet | CardIdentifierOracleId | CardIdentifierCollectorSet;
|
|
51
|
+
|
|
52
|
+
declare class CardIdentifierApi {
|
|
53
|
+
static byId(id: string): CardIdentifier;
|
|
54
|
+
static byIllustrationId(id: string): CardIdentifier;
|
|
55
|
+
static byMtgoId(id: number): CardIdentifier;
|
|
56
|
+
static byMultiverseId(id: number): CardIdentifier;
|
|
57
|
+
static byName(name: string, set?: string): CardIdentifier;
|
|
58
|
+
static byOracleId(id: string): CardIdentifier;
|
|
59
|
+
static bySet(set: string, collectorNumber: number | string): CardIdentifier;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
type CardLanguage = 'en' | 'es' | 'fr' | 'de' | 'it' | 'pt' | 'ja' | 'ko' | 'ru' | 'zhs' | 'zht' | 'he' | 'la' | 'grc' | 'ar' | 'sa' | 'ph';
|
|
63
|
+
type CardLayout = 'normal' | 'split' | 'flip' | 'transform' | 'modal_dfc' | 'meld' | 'leveler' | 'class' | 'case' | 'saga' | 'adventure' | 'mutate' | 'prototype' | 'battle' | 'planar' | 'scheme' | 'vanguard' | 'token' | 'double_faced_token' | 'emblem' | 'augment' | 'host' | 'art_series' | 'reversible_card';
|
|
64
|
+
interface CardCore {
|
|
65
|
+
arena_id?: Nullable<string>;
|
|
66
|
+
cardmarket_id?: Nullable<number>;
|
|
67
|
+
id: string;
|
|
68
|
+
lang: CardLanguage;
|
|
69
|
+
layout: CardLayout;
|
|
70
|
+
mtgo_foil_id?: Nullable<number>;
|
|
71
|
+
mtgo_id?: Nullable<number>;
|
|
72
|
+
multiverse_ids?: Nullable<number[]>;
|
|
73
|
+
object: 'card';
|
|
74
|
+
oracle_id?: Nullable<string>;
|
|
75
|
+
prints_search_uri: string;
|
|
76
|
+
rulings_uri: string;
|
|
77
|
+
scryfall_uri: string;
|
|
78
|
+
tcgplayer_etched_id?: Nullable<number>;
|
|
79
|
+
tcgplayer_id?: Nullable<number>;
|
|
80
|
+
uri: string;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
type Color = 'W' | 'B' | 'R' | 'U' | 'G';
|
|
84
|
+
interface ManaCost {
|
|
85
|
+
cmc: number;
|
|
86
|
+
colorless: boolean;
|
|
87
|
+
colors: Color[];
|
|
88
|
+
cost: string;
|
|
89
|
+
monocolored: boolean;
|
|
90
|
+
multicolored: boolean;
|
|
91
|
+
object: 'mana_cost';
|
|
92
|
+
}
|
|
93
|
+
interface Symbology {
|
|
94
|
+
appears_in_mana_costs: boolean;
|
|
95
|
+
colors: Color[];
|
|
96
|
+
english: string;
|
|
97
|
+
funny: boolean;
|
|
98
|
+
gatherer_alternates?: Nullable<string[]>;
|
|
99
|
+
hybrid: boolean;
|
|
100
|
+
loose_variant?: Nullable<string>;
|
|
101
|
+
mana_value?: Nullable<number>;
|
|
102
|
+
object: 'card_symbol';
|
|
103
|
+
phyrexian: boolean;
|
|
104
|
+
represents_mana: boolean;
|
|
105
|
+
svg_uri?: Nullable<string>;
|
|
106
|
+
symbol: string;
|
|
107
|
+
transposable: boolean;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
declare class SymbologyApi {
|
|
111
|
+
all(): Promise<Symbology[]>;
|
|
112
|
+
parseMana(shorthand: string): Promise<ManaCost>;
|
|
113
|
+
}
|
|
114
|
+
declare const symbology: SymbologyApi;
|
|
115
|
+
|
|
116
|
+
type CardComponent = 'token' | 'meld_part' | 'meld_result' | 'combo_piece';
|
|
117
|
+
type Legality = 'legal' | 'not_legal' | 'restricted' | 'banned';
|
|
118
|
+
interface ImageUris$1 {
|
|
119
|
+
art_crop: string;
|
|
120
|
+
border_crop: string;
|
|
121
|
+
large: string;
|
|
122
|
+
normal: string;
|
|
123
|
+
png: string;
|
|
124
|
+
small: string;
|
|
125
|
+
}
|
|
126
|
+
interface CardFace {
|
|
127
|
+
artist?: Nullable<string>;
|
|
128
|
+
artist_id?: Nullable<string>;
|
|
129
|
+
cmc?: Nullable<number>;
|
|
130
|
+
color_indicator?: Nullable<Color[]>;
|
|
131
|
+
colors?: Nullable<Color[]>;
|
|
132
|
+
defense?: Nullable<string>;
|
|
133
|
+
flavor_text?: Nullable<string>;
|
|
134
|
+
illustration_id?: Nullable<string>;
|
|
135
|
+
image_uris?: Nullable<ImageUris$1>;
|
|
136
|
+
layout?: Nullable<string>;
|
|
137
|
+
loyalty?: Nullable<string>;
|
|
138
|
+
mana_cost: string;
|
|
139
|
+
name: string;
|
|
140
|
+
object: 'card_face';
|
|
141
|
+
oracle_id?: Nullable<string>;
|
|
142
|
+
oracle_text?: Nullable<string>;
|
|
143
|
+
power?: Nullable<string>;
|
|
144
|
+
printed_name?: Nullable<string>;
|
|
145
|
+
printed_text?: Nullable<string>;
|
|
146
|
+
printed_type_line?: Nullable<string>;
|
|
147
|
+
toughness?: Nullable<string>;
|
|
148
|
+
type_line?: Nullable<string>;
|
|
149
|
+
watermark?: Nullable<string>;
|
|
150
|
+
}
|
|
151
|
+
interface RelatedCard {
|
|
152
|
+
component: CardComponent;
|
|
153
|
+
id: string;
|
|
154
|
+
name: string;
|
|
155
|
+
object: 'related_card';
|
|
156
|
+
type_line: string;
|
|
157
|
+
uri: string;
|
|
158
|
+
}
|
|
159
|
+
interface Legalities {
|
|
160
|
+
alchemy: Legality;
|
|
161
|
+
brawl: Legality;
|
|
162
|
+
commander: Legality;
|
|
163
|
+
duel: Legality;
|
|
164
|
+
explorer: Legality;
|
|
165
|
+
future: Legality;
|
|
166
|
+
gladiator: Legality;
|
|
167
|
+
historic: Legality;
|
|
168
|
+
legacy: Legality;
|
|
169
|
+
modern: Legality;
|
|
170
|
+
oathbreaker: Legality;
|
|
171
|
+
oldschool: Legality;
|
|
172
|
+
pauper: Legality;
|
|
173
|
+
paupercommander: Legality;
|
|
174
|
+
penny: Legality;
|
|
175
|
+
pioneer: Legality;
|
|
176
|
+
predh: Legality;
|
|
177
|
+
premodern: Legality;
|
|
178
|
+
standard: Legality;
|
|
179
|
+
standardbrawl: Legality;
|
|
180
|
+
timeless: Legality;
|
|
181
|
+
vintage: Legality;
|
|
182
|
+
}
|
|
183
|
+
interface GameplayCard {
|
|
184
|
+
all_parts?: Nullable<RelatedCard[]>;
|
|
185
|
+
card_faces?: Nullable<CardFace[]>;
|
|
186
|
+
cmc: number;
|
|
187
|
+
color_identity: Color[];
|
|
188
|
+
color_indicator?: Nullable<Color[]>;
|
|
189
|
+
colors?: Nullable<Color[]>;
|
|
190
|
+
defense?: Nullable<string>;
|
|
191
|
+
edhrec_rank?: Nullable<number>;
|
|
192
|
+
hand_modifier?: Nullable<string>;
|
|
193
|
+
keywords: string[];
|
|
194
|
+
legalities: Legalities;
|
|
195
|
+
life_modifier?: Nullable<string>;
|
|
196
|
+
loyalty?: Nullable<string>;
|
|
197
|
+
mana_cost?: Nullable<string>;
|
|
198
|
+
name: string;
|
|
199
|
+
oracle_text?: Nullable<string>;
|
|
200
|
+
penny_rank?: Nullable<number>;
|
|
201
|
+
power?: Nullable<string>;
|
|
202
|
+
produced_mana?: Nullable<Color[]>;
|
|
203
|
+
reserved: boolean;
|
|
204
|
+
toughness?: Nullable<string>;
|
|
205
|
+
type_line: string;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
type SetType = 'core' | 'expansion' | 'masters' | 'alchemy' | 'masterpiece' | 'arsenal' | 'from_the_vault' | 'spellbook' | 'premium_deck' | 'duel_deck' | 'draft_innovation' | 'treasure_chest' | 'commander' | 'planechase' | 'archenemy' | 'vanguard' | 'funny' | 'starter' | 'box' | 'promo' | 'token' | 'memorabilia' | 'minigame';
|
|
209
|
+
interface Set {
|
|
210
|
+
arena_code?: Nullable<string>;
|
|
211
|
+
block?: Nullable<string>;
|
|
212
|
+
block_code?: Nullable<string>;
|
|
213
|
+
card_count: number;
|
|
214
|
+
code: string;
|
|
215
|
+
digital: boolean;
|
|
216
|
+
foil_only: boolean;
|
|
217
|
+
icon_svg_uri: string;
|
|
218
|
+
id: string;
|
|
219
|
+
mtgo_code?: Nullable<string>;
|
|
220
|
+
name: string;
|
|
221
|
+
nonfoil_only: boolean;
|
|
222
|
+
object: 'set';
|
|
223
|
+
parent_set_code?: Nullable<string>;
|
|
224
|
+
printed_size?: Nullable<number>;
|
|
225
|
+
released_at?: Nullable<Date>;
|
|
226
|
+
scryfall_uri: string;
|
|
227
|
+
search_uri: string;
|
|
228
|
+
set_type: SetType;
|
|
229
|
+
tcgplayer_id?: Nullable<number>;
|
|
230
|
+
uri: string;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
declare class SetApi {
|
|
234
|
+
all(): Promise<Set[]>;
|
|
235
|
+
byCode(code: string): Promise<Set | undefined>;
|
|
236
|
+
byId(id: string): Promise<Set | undefined>;
|
|
237
|
+
byTcgPlayerId(id: number): Promise<Set | undefined>;
|
|
238
|
+
}
|
|
239
|
+
declare const set: SetApi;
|
|
240
|
+
|
|
241
|
+
type BorderColor = 'black' | 'borderless' | 'gold' | 'silver' | 'white';
|
|
242
|
+
type Finish = 'foil' | 'nonfoil' | 'etched';
|
|
243
|
+
type Frame = '1993' | '1997' | '2003' | '2015' | 'future';
|
|
244
|
+
type FrameEffect = 'legendary' | 'miracle' | 'nyxtouched' | 'draft' | 'devoid' | 'tombstone' | 'colorshifted' | 'inverted' | 'sunmoondfc' | 'compasslanddfc' | 'originpwdfc' | 'mooneldrazidfc' | 'waxingandwaningmoondfc' | 'showcase' | 'extendedart' | 'companion' | 'etched' | 'snow' | 'lesson' | 'shatteredglass' | 'convertdfc' | 'fandfc' | 'upsidedowndfc';
|
|
245
|
+
type Game = 'paper' | 'arena' | 'mtgo';
|
|
246
|
+
type ImageStatus = 'missing' | 'placeholder' | 'lowres' | 'highres_scan';
|
|
247
|
+
interface ImageUris {
|
|
248
|
+
art_crop: string;
|
|
249
|
+
border_crop: string;
|
|
250
|
+
large: string;
|
|
251
|
+
normal: string;
|
|
252
|
+
png: string;
|
|
253
|
+
small: string;
|
|
254
|
+
}
|
|
255
|
+
interface Preview {
|
|
256
|
+
previewed_at: Date;
|
|
257
|
+
source: string;
|
|
258
|
+
source_uri: string;
|
|
259
|
+
}
|
|
260
|
+
interface Prices {
|
|
261
|
+
eur?: Nullable<string>;
|
|
262
|
+
eur_foil?: Nullable<string>;
|
|
263
|
+
tix?: Nullable<string>;
|
|
264
|
+
usd?: Nullable<string>;
|
|
265
|
+
usd_etched?: Nullable<string>;
|
|
266
|
+
usd_foil?: Nullable<string>;
|
|
267
|
+
}
|
|
268
|
+
type PromoType = 'ourney' | 'prerelease' | 'datestamped' | 'planeswalkerdeck' | 'buyabox' | 'judgegift' | 'event' | 'convention' | 'starterdeck' | 'instore' | 'setpromo' | 'fnm' | 'openhouse' | 'league' | 'draftweekend' | 'gameday' | 'release' | 'intropack' | 'giftbox' | 'duels' | 'wizardsplaynetwork' | 'premiereshop' | 'playerrewards' | 'gateway' | 'arenaleague';
|
|
269
|
+
interface PurchaseUris {
|
|
270
|
+
[key: string]: Nullable<string>;
|
|
271
|
+
cardhoarder?: Nullable<string>;
|
|
272
|
+
cardmarket?: Nullable<string>;
|
|
273
|
+
tcgplayer?: Nullable<string>;
|
|
274
|
+
}
|
|
275
|
+
type Rarity = 'common' | 'uncommon' | 'rare' | 'special' | 'mythic' | 'bonus';
|
|
276
|
+
interface RelatedUris {
|
|
277
|
+
[key: string]: Nullable<string>;
|
|
278
|
+
edhrec?: Nullable<string>;
|
|
279
|
+
gatherer?: Nullable<string>;
|
|
280
|
+
mtgtop8?: Nullable<string>;
|
|
281
|
+
tcgplayer_decks?: Nullable<string>;
|
|
282
|
+
tcgplayer_infinite_articles?: Nullable<string>;
|
|
283
|
+
tcgplayer_infinite_decks?: Nullable<string>;
|
|
284
|
+
}
|
|
285
|
+
type SecurityStamp = 'oval' | 'triangle' | 'acorn' | 'circle' | 'arena' | 'heart';
|
|
286
|
+
interface CardPrint {
|
|
287
|
+
artist?: Nullable<string>;
|
|
288
|
+
artist_ids?: Nullable<string[]>;
|
|
289
|
+
attraction_lights?: Nullable<number[]>;
|
|
290
|
+
booster: boolean;
|
|
291
|
+
border_color: BorderColor;
|
|
292
|
+
card_back_id: string;
|
|
293
|
+
collector_number: string;
|
|
294
|
+
content_warning?: Nullable<boolean>;
|
|
295
|
+
digital: boolean;
|
|
296
|
+
finishes: Finish[];
|
|
297
|
+
flavor_name?: Nullable<string>;
|
|
298
|
+
flavor_text?: Nullable<string>;
|
|
299
|
+
frame: Frame;
|
|
300
|
+
frame_effects?: Nullable<FrameEffect[]>;
|
|
301
|
+
full_art: boolean;
|
|
302
|
+
games: Game[];
|
|
303
|
+
highres_image: boolean;
|
|
304
|
+
illustration_id?: Nullable<string>;
|
|
305
|
+
image_status: ImageStatus;
|
|
306
|
+
image_uris?: Nullable<ImageUris>;
|
|
307
|
+
oversized: boolean;
|
|
308
|
+
preview: Preview;
|
|
309
|
+
prices: Prices;
|
|
310
|
+
printed_name?: Nullable<string>;
|
|
311
|
+
printed_text?: Nullable<string>;
|
|
312
|
+
printed_type_line?: Nullable<string>;
|
|
313
|
+
promo: boolean;
|
|
314
|
+
promo_types?: Nullable<PromoType[]>;
|
|
315
|
+
purchase_uris?: Nullable<PurchaseUris>;
|
|
316
|
+
rarity: Rarity;
|
|
317
|
+
related_uris: RelatedUris;
|
|
318
|
+
released_at: Date;
|
|
319
|
+
reprint: boolean;
|
|
320
|
+
scryfall_set_uri: string;
|
|
321
|
+
security_stamp?: Nullable<SecurityStamp>;
|
|
322
|
+
set: string;
|
|
323
|
+
set_id: string;
|
|
324
|
+
set_name: string;
|
|
325
|
+
set_search_uri: string;
|
|
326
|
+
set_type: SetType;
|
|
327
|
+
set_uri: string;
|
|
328
|
+
story_spotlight: boolean;
|
|
329
|
+
textless: boolean;
|
|
330
|
+
variation: boolean;
|
|
331
|
+
variation_of?: Nullable<string>;
|
|
332
|
+
watermark?: Nullable<string>;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
type Card = CardCore & GameplayCard & CardPrint;
|
|
336
|
+
|
|
337
|
+
type CardSearchUnique = 'cards' | 'art' | 'prints';
|
|
338
|
+
type CardSearchOrder = 'name' | 'set' | 'released' | 'rarity' | 'color' | 'usd' | 'tix' | 'eur' | 'cmc' | 'power' | 'toughness' | 'edhrec' | 'penny' | 'artist' | 'review';
|
|
339
|
+
type CardSearchDir = 'auto' | 'asc' | 'desc';
|
|
340
|
+
type CardSearchFormat = 'json' | 'csv';
|
|
341
|
+
interface CardSearch {
|
|
342
|
+
dir?: CardSearchDir;
|
|
343
|
+
format?: CardSearchFormat;
|
|
344
|
+
include_extras?: boolean;
|
|
345
|
+
include_multilingual?: boolean;
|
|
346
|
+
include_variations?: boolean;
|
|
347
|
+
order?: CardSearchOrder;
|
|
348
|
+
page?: number;
|
|
349
|
+
pretty?: boolean;
|
|
350
|
+
unique?: CardSearchUnique;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
declare class CardApi {
|
|
354
|
+
autoCompleteName(name: string): Promise<string[]>;
|
|
355
|
+
byArenaId(id: number): Promise<Card | undefined>;
|
|
356
|
+
byId(id: string): Promise<Card | undefined>;
|
|
357
|
+
byMtgoId(id: number): Promise<Card | undefined>;
|
|
358
|
+
byMultiverseId(id: number): Promise<Card | undefined>;
|
|
359
|
+
byName(name: string, fuzzy?: boolean): Promise<Card | undefined>;
|
|
360
|
+
byName(name: string, set?: string, fuzzy?: boolean): Promise<Card | undefined>;
|
|
361
|
+
bySet(setCode: string, collectorNumber: number, lang?: string): Promise<Card | undefined>;
|
|
362
|
+
byTcgPlayerId(id: number): Promise<Card | undefined>;
|
|
363
|
+
collection(...identifiers: CardIdentifier[]): Promise<Card[]>;
|
|
364
|
+
random(): Promise<Card | undefined>;
|
|
365
|
+
search(query: string, options?: CardSearch | number): MagicPageResult<Card>;
|
|
366
|
+
}
|
|
367
|
+
declare const cards: CardApi;
|
|
368
|
+
|
|
369
|
+
declare class CatalogApi {
|
|
370
|
+
artifactTypes(): Promise<string[]>;
|
|
371
|
+
artistNames(): Promise<string[]>;
|
|
372
|
+
cardNames(): Promise<string[]>;
|
|
373
|
+
creatureTypes(): Promise<string[]>;
|
|
374
|
+
enchantmentTypes(): Promise<string[]>;
|
|
375
|
+
landTypes(): Promise<string[]>;
|
|
376
|
+
loyalties(): Promise<string[]>;
|
|
377
|
+
planeswalkerTypes(): Promise<string[]>;
|
|
378
|
+
powers(): Promise<string[]>;
|
|
379
|
+
spellTypes(): Promise<string[]>;
|
|
380
|
+
toughnesses(): Promise<string[]>;
|
|
381
|
+
watermarks(): Promise<string[]>;
|
|
382
|
+
wordBank(): Promise<string[]>;
|
|
383
|
+
}
|
|
384
|
+
declare const catalog: CatalogApi;
|
|
385
|
+
|
|
386
|
+
interface Catalog {
|
|
387
|
+
data: string[];
|
|
388
|
+
object: 'catalog';
|
|
389
|
+
total_values: number;
|
|
390
|
+
uri: string;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
interface Ruling {
|
|
394
|
+
comment: string;
|
|
395
|
+
object: 'ruling';
|
|
396
|
+
oracle_id: string;
|
|
397
|
+
published_at: Date;
|
|
398
|
+
source: string;
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
declare class RulingApi {
|
|
402
|
+
byArenaId(id: number): Promise<Ruling[]>;
|
|
403
|
+
byId(id: string): Promise<Ruling[]>;
|
|
404
|
+
byMtgoId(id: number): Promise<Ruling[]>;
|
|
405
|
+
byMultiverseId(id: number): Promise<Ruling[]>;
|
|
406
|
+
bySet(setCode: string, collectorNumber: number | string): Promise<Ruling[]>;
|
|
407
|
+
}
|
|
408
|
+
declare const rulings: RulingApi;
|
|
409
|
+
|
|
410
|
+
declare class InvalidScryfallArgumentError extends Error {
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
declare class ScryfallError extends Error {
|
|
414
|
+
readonly code: string;
|
|
415
|
+
readonly status: number;
|
|
416
|
+
readonly type?: string | null | undefined;
|
|
417
|
+
readonly warnings?: string[] | null | undefined;
|
|
418
|
+
constructor(code: string, details: string, status: number, type?: string | null | undefined, warnings?: string[] | null | undefined);
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
declare class UnknownScryfallError extends Error {
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
export { type Card, type CardIdentifier, CardIdentifierApi as CardIdentifierBuilder, type CardIdentifierCollectorSet, type CardIdentifierId, type CardIdentifierIllustrationId, type CardIdentifierMtgGoId, type CardIdentifierMultiverseId, type CardIdentifierNameSet, type CardIdentifierOracleId, type CardSearch, type CardSearchDir, type CardSearchFormat, type CardSearchOrder, type CardSearchUnique, cards as Cards, type Catalog, catalog as Catalogs, type Color, InvalidScryfallArgumentError, MagicPageResult, type ManaCost, type Ruling, rulings as Rulings, ScryfallError, type Set, type SetType, set as Sets, type Symbology, symbology as SymbologyApi, UnknownScryfallError };
|
|
@@ -0,0 +1,452 @@
|
|
|
1
|
+
// src/error/invalid.error.ts
|
|
2
|
+
var InvalidScryfallArgumentError = class extends Error {
|
|
3
|
+
};
|
|
4
|
+
|
|
5
|
+
// src/error/scryfall.error.ts
|
|
6
|
+
var ScryfallError = class extends Error {
|
|
7
|
+
constructor(code, details, status, type, warnings) {
|
|
8
|
+
super(details);
|
|
9
|
+
this.code = code;
|
|
10
|
+
this.status = status;
|
|
11
|
+
this.type = type;
|
|
12
|
+
this.warnings = warnings;
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
// src/error/unknown.error.ts
|
|
17
|
+
var UnknownScryfallError = class extends Error {
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
// src/fetcher/debounce.fetcher.ts
|
|
21
|
+
var lastQuery = 100;
|
|
22
|
+
var rateLimit = 100;
|
|
23
|
+
async function sleep(ms = 0) {
|
|
24
|
+
return new Promise((resolve) => {
|
|
25
|
+
setTimeout(resolve, ms);
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
async function debounce() {
|
|
29
|
+
const now = Date.now();
|
|
30
|
+
const timeSinceLastQuery = now - lastQuery;
|
|
31
|
+
if (timeSinceLastQuery >= rateLimit) {
|
|
32
|
+
lastQuery = now;
|
|
33
|
+
} else {
|
|
34
|
+
const timeUntilNextQuery = rateLimit - timeSinceLastQuery;
|
|
35
|
+
lastQuery += timeUntilNextQuery;
|
|
36
|
+
await sleep(timeUntilNextQuery);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
function createDebounceFetcher(fetcher2 = fetch) {
|
|
40
|
+
return async function debounceFetcher(...args) {
|
|
41
|
+
await debounce();
|
|
42
|
+
return fetcher2(...args);
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// src/fetcher/page.result.ts
|
|
47
|
+
var MagicPageResult = class {
|
|
48
|
+
constructor(apiPath, query) {
|
|
49
|
+
this.apiPath = apiPath;
|
|
50
|
+
this.query = query;
|
|
51
|
+
this.#hasMore = true;
|
|
52
|
+
this.#count = 0;
|
|
53
|
+
}
|
|
54
|
+
#count;
|
|
55
|
+
#hasMore;
|
|
56
|
+
get count() {
|
|
57
|
+
return this.#count;
|
|
58
|
+
}
|
|
59
|
+
get hasMore() {
|
|
60
|
+
return this.#hasMore;
|
|
61
|
+
}
|
|
62
|
+
async all() {
|
|
63
|
+
const r = [];
|
|
64
|
+
while (this.#hasMore) {
|
|
65
|
+
const result = await this.next();
|
|
66
|
+
r.push(...result);
|
|
67
|
+
}
|
|
68
|
+
return r;
|
|
69
|
+
}
|
|
70
|
+
async get(limit) {
|
|
71
|
+
const r = [];
|
|
72
|
+
while (this.#hasMore) {
|
|
73
|
+
const result = await this.next();
|
|
74
|
+
r.push(...result);
|
|
75
|
+
if (r.length === limit) {
|
|
76
|
+
return r;
|
|
77
|
+
}
|
|
78
|
+
if (r.length > limit) {
|
|
79
|
+
return r.slice(0, limit);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return r;
|
|
83
|
+
}
|
|
84
|
+
async next() {
|
|
85
|
+
const results = await fetcher(this.apiPath, this.query);
|
|
86
|
+
this.#hasMore = results?.has_more ?? false;
|
|
87
|
+
this.#count = Number.parseInt(`${results?.total_cards ?? 0}`, 10);
|
|
88
|
+
if (this.#hasMore) {
|
|
89
|
+
this.setNextPage();
|
|
90
|
+
}
|
|
91
|
+
return results?.data ?? [];
|
|
92
|
+
}
|
|
93
|
+
async page(page) {
|
|
94
|
+
this.query.page = page;
|
|
95
|
+
return this.next();
|
|
96
|
+
}
|
|
97
|
+
setNextPage() {
|
|
98
|
+
this.query.page += 1;
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
// src/fetcher/retry.fetcher.ts
|
|
103
|
+
var defaultCanRetry = async (response) => {
|
|
104
|
+
const object = await response.json();
|
|
105
|
+
const status = "status" in object ? Number(object.status) : void 0;
|
|
106
|
+
if (status && status >= 500) {
|
|
107
|
+
return true;
|
|
108
|
+
}
|
|
109
|
+
const code = "code" in object && typeof object.code === "string" ? object.code : void 0;
|
|
110
|
+
return code !== "not_found" && code !== "bad_request";
|
|
111
|
+
};
|
|
112
|
+
function createRetryFetcher({ maxAttempts = 3, canRetry = defaultCanRetry } = {}, fetcher2 = fetch) {
|
|
113
|
+
let retries = 0;
|
|
114
|
+
return async function retryFetcher(...args) {
|
|
115
|
+
retries++;
|
|
116
|
+
const response = await fetcher2(...args);
|
|
117
|
+
if (response.ok) {
|
|
118
|
+
return response;
|
|
119
|
+
}
|
|
120
|
+
const object = await response.json();
|
|
121
|
+
const code = "code" in object && typeof object.code === "string" ? object.code : void 0;
|
|
122
|
+
const status = "status" in object ? Number(object.status) : void 0;
|
|
123
|
+
const details = "details" in object && typeof object.details === "string" ? object.details : void 0;
|
|
124
|
+
const type = "type" in object && typeof object.type === "string" ? object.type : void 0;
|
|
125
|
+
const warnings = "warnings" in object && Array.isArray(object.warnings) ? object.warnings : void 0;
|
|
126
|
+
if (retries >= maxAttempts) {
|
|
127
|
+
if (code && details && status) {
|
|
128
|
+
throw new ScryfallError(code, details, status, type, warnings);
|
|
129
|
+
}
|
|
130
|
+
throw new UnknownScryfallError(`Request failed with status ${response.status}`);
|
|
131
|
+
}
|
|
132
|
+
if (canRetry(response)) {
|
|
133
|
+
return retryFetcher(...args);
|
|
134
|
+
}
|
|
135
|
+
if (code && details && status) {
|
|
136
|
+
throw new ScryfallError(code, details, status, type, warnings);
|
|
137
|
+
}
|
|
138
|
+
throw new UnknownScryfallError(`Request failed with status ${response.status}`);
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// src/fetcher/index.ts
|
|
143
|
+
var simpleFetcher = createDebounceFetcher(createRetryFetcher());
|
|
144
|
+
var endpoint = "https://api.scryfall.com";
|
|
145
|
+
var DATE_REGEXP = /^\d{4}-\d{2}-\d{2}?$/;
|
|
146
|
+
var dateParser = (_key, value) => {
|
|
147
|
+
if (typeof value === "string") {
|
|
148
|
+
if (DATE_REGEXP.test(value)) {
|
|
149
|
+
return new Date(value);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return value;
|
|
153
|
+
};
|
|
154
|
+
async function fetcher(apiPath, params, body) {
|
|
155
|
+
let path = "";
|
|
156
|
+
if (typeof apiPath === "number" || typeof apiPath === "string") {
|
|
157
|
+
path = apiPath;
|
|
158
|
+
} else if (apiPath) {
|
|
159
|
+
path = apiPath.join("/");
|
|
160
|
+
}
|
|
161
|
+
const url = new URL(`${endpoint}/${path}`);
|
|
162
|
+
if (params) {
|
|
163
|
+
Object.entries(params).forEach(([key, value]) => {
|
|
164
|
+
if (value !== void 0) {
|
|
165
|
+
url.searchParams.append(key, `${value}`);
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
try {
|
|
170
|
+
const init = {
|
|
171
|
+
method: body ? "POST" : "GET"
|
|
172
|
+
};
|
|
173
|
+
if (body) {
|
|
174
|
+
init.body = JSON.stringify(body);
|
|
175
|
+
init.headers = {
|
|
176
|
+
"Content-Type": "application/json"
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
const response = await simpleFetcher(url, init);
|
|
180
|
+
const content = await response.text();
|
|
181
|
+
return JSON.parse(content, dateParser);
|
|
182
|
+
} catch (e) {
|
|
183
|
+
if (e instanceof ScryfallError) {
|
|
184
|
+
if (e.warnings) {
|
|
185
|
+
console.warn(e.warnings);
|
|
186
|
+
}
|
|
187
|
+
if (e.code === "not_found" || e.code === "bad_request") {
|
|
188
|
+
return void 0;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
throw e;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// src/api/card/card.api.ts
|
|
196
|
+
var CardApi = class {
|
|
197
|
+
/*
|
|
198
|
+
* Returns up to 20 full English card names that could be autocompletions of the given string parameter.
|
|
199
|
+
* @param {string} name
|
|
200
|
+
* The string to search for
|
|
201
|
+
* @returns {Promise<string[]>}
|
|
202
|
+
* A list of up to 20 full English card names.
|
|
203
|
+
*/
|
|
204
|
+
async autoCompleteName(name) {
|
|
205
|
+
const result = await fetcher("cards/autocomplete", {
|
|
206
|
+
q: name
|
|
207
|
+
});
|
|
208
|
+
return result?.data ?? [];
|
|
209
|
+
}
|
|
210
|
+
/*
|
|
211
|
+
* Returns a single card with the given Magic: The Gathering Arena ID.
|
|
212
|
+
* @param {number} id
|
|
213
|
+
* The Magic: The Gathering Arena ID of the card to retrieve.
|
|
214
|
+
* @returns {Promise<Card | undefined>}
|
|
215
|
+
* Returns a single card or undefined if no card is found.
|
|
216
|
+
*/
|
|
217
|
+
async byArenaId(id) {
|
|
218
|
+
return fetcher(["cards/arena", id]);
|
|
219
|
+
}
|
|
220
|
+
/*
|
|
221
|
+
* Returns a single card with the given Scryfall ID.
|
|
222
|
+
* @param {number} id
|
|
223
|
+
* The Scryfall ID.
|
|
224
|
+
* @returns {Promise<Card | undefined>}
|
|
225
|
+
* Returns a single card or undefined if no card is found.
|
|
226
|
+
*/
|
|
227
|
+
async byId(id) {
|
|
228
|
+
return fetcher(["cards", id]);
|
|
229
|
+
}
|
|
230
|
+
async byMtgoId(id) {
|
|
231
|
+
return fetcher(["cards/mtgo", id]);
|
|
232
|
+
}
|
|
233
|
+
async byMultiverseId(id) {
|
|
234
|
+
return fetcher(["cards/multiverse", id]);
|
|
235
|
+
}
|
|
236
|
+
async byName(name, set2, fuzzy = false) {
|
|
237
|
+
let f = fuzzy;
|
|
238
|
+
let s = set2;
|
|
239
|
+
if (typeof set2 === "boolean") {
|
|
240
|
+
f = set2;
|
|
241
|
+
s = void 0;
|
|
242
|
+
}
|
|
243
|
+
return fetcher("cards/named", {
|
|
244
|
+
[f ? "fuzzy" : "exact"]: name,
|
|
245
|
+
set: s
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
async bySet(setCode, collectorNumber, lang) {
|
|
249
|
+
const path = ["cards", setCode, collectorNumber];
|
|
250
|
+
if (lang) {
|
|
251
|
+
path.push(lang);
|
|
252
|
+
}
|
|
253
|
+
return fetcher(path);
|
|
254
|
+
}
|
|
255
|
+
async byTcgPlayerId(id) {
|
|
256
|
+
return fetcher(["cards/tcgplayer", id]);
|
|
257
|
+
}
|
|
258
|
+
async collection(...identifiers) {
|
|
259
|
+
const cards2 = [];
|
|
260
|
+
for (let i = 0; i < identifiers.length; i += 75) {
|
|
261
|
+
const collectionSection = { identifiers: identifiers.slice(i, i + 75) };
|
|
262
|
+
const result = await fetcher(
|
|
263
|
+
"cards/collection",
|
|
264
|
+
void 0,
|
|
265
|
+
collectionSection
|
|
266
|
+
);
|
|
267
|
+
cards2.push(...result?.data ?? []);
|
|
268
|
+
}
|
|
269
|
+
return cards2;
|
|
270
|
+
}
|
|
271
|
+
async random() {
|
|
272
|
+
return fetcher("cards/random");
|
|
273
|
+
}
|
|
274
|
+
search(query, options) {
|
|
275
|
+
return new MagicPageResult("cards/search", {
|
|
276
|
+
q: query,
|
|
277
|
+
...typeof options === "number" ? { page: options } : { ...options, page: options?.page ?? 1 }
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
};
|
|
281
|
+
var cards = new CardApi();
|
|
282
|
+
var card_api_default = cards;
|
|
283
|
+
|
|
284
|
+
// src/api/card/index.ts
|
|
285
|
+
var card_default = card_api_default;
|
|
286
|
+
|
|
287
|
+
// src/api/card-identifier/card-identifier.api.ts
|
|
288
|
+
var CardIdentifierApi = class {
|
|
289
|
+
static byId(id) {
|
|
290
|
+
return { id };
|
|
291
|
+
}
|
|
292
|
+
static byIllustrationId(id) {
|
|
293
|
+
return { illustration_id: id };
|
|
294
|
+
}
|
|
295
|
+
static byMtgoId(id) {
|
|
296
|
+
return { mtgo_id: id };
|
|
297
|
+
}
|
|
298
|
+
static byMultiverseId(id) {
|
|
299
|
+
return { multiverse_id: id };
|
|
300
|
+
}
|
|
301
|
+
static byName(name, set2) {
|
|
302
|
+
if (set2) {
|
|
303
|
+
return { name, set: set2 };
|
|
304
|
+
}
|
|
305
|
+
return { name };
|
|
306
|
+
}
|
|
307
|
+
static byOracleId(id) {
|
|
308
|
+
return { oracle_id: id };
|
|
309
|
+
}
|
|
310
|
+
static bySet(set2, collectorNumber) {
|
|
311
|
+
return { collector_number: `${collectorNumber}`, set: set2 };
|
|
312
|
+
}
|
|
313
|
+
};
|
|
314
|
+
|
|
315
|
+
// src/api/card-identifier/index.ts
|
|
316
|
+
var card_identifier_default = CardIdentifierApi;
|
|
317
|
+
|
|
318
|
+
// src/api/catalog/catalog.api.ts
|
|
319
|
+
var CatalogApi = class {
|
|
320
|
+
async artifactTypes() {
|
|
321
|
+
return (await fetcher("catalog/artifact-types"))?.data ?? [];
|
|
322
|
+
}
|
|
323
|
+
async artistNames() {
|
|
324
|
+
return (await fetcher("catalog/artist-names"))?.data ?? [];
|
|
325
|
+
}
|
|
326
|
+
async cardNames() {
|
|
327
|
+
return (await fetcher("catalog/card-names"))?.data ?? [];
|
|
328
|
+
}
|
|
329
|
+
async creatureTypes() {
|
|
330
|
+
return (await fetcher("catalog/creature-types"))?.data ?? [];
|
|
331
|
+
}
|
|
332
|
+
async enchantmentTypes() {
|
|
333
|
+
return (await fetcher("catalog/enchantment-types"))?.data ?? [];
|
|
334
|
+
}
|
|
335
|
+
async landTypes() {
|
|
336
|
+
return (await fetcher("catalog/land-types"))?.data ?? [];
|
|
337
|
+
}
|
|
338
|
+
async loyalties() {
|
|
339
|
+
return (await fetcher("catalog/loyalties"))?.data ?? [];
|
|
340
|
+
}
|
|
341
|
+
async planeswalkerTypes() {
|
|
342
|
+
return (await fetcher("catalog/planeswalker-types"))?.data ?? [];
|
|
343
|
+
}
|
|
344
|
+
async powers() {
|
|
345
|
+
return (await fetcher("catalog/powers"))?.data ?? [];
|
|
346
|
+
}
|
|
347
|
+
async spellTypes() {
|
|
348
|
+
return (await fetcher("catalog/spell-types"))?.data ?? [];
|
|
349
|
+
}
|
|
350
|
+
async toughnesses() {
|
|
351
|
+
return (await fetcher("catalog/toughnesses"))?.data ?? [];
|
|
352
|
+
}
|
|
353
|
+
async watermarks() {
|
|
354
|
+
return (await fetcher("catalog/watermarks"))?.data ?? [];
|
|
355
|
+
}
|
|
356
|
+
async wordBank() {
|
|
357
|
+
return (await fetcher("catalog/word-bank"))?.data ?? [];
|
|
358
|
+
}
|
|
359
|
+
};
|
|
360
|
+
var catalog = new CatalogApi();
|
|
361
|
+
var catalog_api_default = catalog;
|
|
362
|
+
|
|
363
|
+
// src/api/catalog/index.ts
|
|
364
|
+
var catalog_default = catalog_api_default;
|
|
365
|
+
|
|
366
|
+
// src/api/ruling/ruling.api.ts
|
|
367
|
+
var RulingApi = class {
|
|
368
|
+
async byArenaId(id) {
|
|
369
|
+
return (await fetcher(["cards/arena", id, "rulings"]))?.data ?? [];
|
|
370
|
+
}
|
|
371
|
+
async byId(id) {
|
|
372
|
+
return (await fetcher(["cards", id, "rulings"]))?.data ?? [];
|
|
373
|
+
}
|
|
374
|
+
async byMtgoId(id) {
|
|
375
|
+
return (await fetcher(["cards/mtgo", id, "rulings"]))?.data ?? [];
|
|
376
|
+
}
|
|
377
|
+
async byMultiverseId(id) {
|
|
378
|
+
return (await fetcher(["cards/multiverse", id, "rulings"]))?.data ?? [];
|
|
379
|
+
}
|
|
380
|
+
async bySet(setCode, collectorNumber) {
|
|
381
|
+
return (await fetcher(["cards", setCode, `${collectorNumber}`, "rulings"]))?.data ?? [];
|
|
382
|
+
}
|
|
383
|
+
};
|
|
384
|
+
var rulings = new RulingApi();
|
|
385
|
+
var ruling_api_default = rulings;
|
|
386
|
+
|
|
387
|
+
// src/api/ruling/index.ts
|
|
388
|
+
var ruling_default = ruling_api_default;
|
|
389
|
+
|
|
390
|
+
// src/api/set/set.api.ts
|
|
391
|
+
var SetApi = class {
|
|
392
|
+
async all() {
|
|
393
|
+
const result = await fetcher("sets");
|
|
394
|
+
return result?.data ?? [];
|
|
395
|
+
}
|
|
396
|
+
async byCode(code) {
|
|
397
|
+
return await fetcher(["sets", code]);
|
|
398
|
+
}
|
|
399
|
+
async byId(id) {
|
|
400
|
+
return fetcher(["sets", id]);
|
|
401
|
+
}
|
|
402
|
+
async byTcgPlayerId(id) {
|
|
403
|
+
return fetcher(["sets/tcgplayer", id]);
|
|
404
|
+
}
|
|
405
|
+
};
|
|
406
|
+
var set = new SetApi();
|
|
407
|
+
var set_api_default = set;
|
|
408
|
+
|
|
409
|
+
// src/api/set/index.ts
|
|
410
|
+
var set_default = set_api_default;
|
|
411
|
+
|
|
412
|
+
// src/api/symbology/symbology.api.ts
|
|
413
|
+
var SymbologyApi = class {
|
|
414
|
+
async all() {
|
|
415
|
+
const list = await fetcher("symbology");
|
|
416
|
+
return list?.data ?? [];
|
|
417
|
+
}
|
|
418
|
+
async parseMana(shorthand) {
|
|
419
|
+
if (!shorthand || typeof shorthand !== "string") {
|
|
420
|
+
throw new InvalidScryfallArgumentError("shorthand must be a string");
|
|
421
|
+
}
|
|
422
|
+
const cost = await fetcher("symbology/parse-mana", {
|
|
423
|
+
cost: shorthand
|
|
424
|
+
});
|
|
425
|
+
return cost ?? {
|
|
426
|
+
cost: "",
|
|
427
|
+
colors: [],
|
|
428
|
+
cmc: 0,
|
|
429
|
+
colorless: false,
|
|
430
|
+
monocolored: false,
|
|
431
|
+
multicolored: false,
|
|
432
|
+
object: "mana_cost"
|
|
433
|
+
};
|
|
434
|
+
}
|
|
435
|
+
};
|
|
436
|
+
var symbology = new SymbologyApi();
|
|
437
|
+
var symbology_api_default = symbology;
|
|
438
|
+
|
|
439
|
+
// src/api/symbology/index.ts
|
|
440
|
+
var symbology_default = symbology_api_default;
|
|
441
|
+
export {
|
|
442
|
+
card_identifier_default as CardIdentifierBuilder,
|
|
443
|
+
card_default as Cards,
|
|
444
|
+
catalog_default as Catalogs,
|
|
445
|
+
InvalidScryfallArgumentError,
|
|
446
|
+
MagicPageResult,
|
|
447
|
+
ruling_default as Rulings,
|
|
448
|
+
ScryfallError,
|
|
449
|
+
set_default as Sets,
|
|
450
|
+
symbology_default as SymbologyApi,
|
|
451
|
+
UnknownScryfallError
|
|
452
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";var b=Object.defineProperty;var Q=Object.getOwnPropertyDescriptor;var z=Object.getOwnPropertyNames;var A=Object.prototype.hasOwnProperty;var U=(a,e)=>{for(var t in e)b(a,t,{get:e[t],enumerable:!0})},B=(a,e,t,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of z(e))!A.call(a,o)&&o!==t&&b(a,o,{get:()=>e[o],enumerable:!(s=Q(e,o))||s.enumerable});return a};var G=a=>B(b({},"__esModule",{value:!0}),a);var se={};U(se,{CardIdentifierBuilder:()=>_,Cards:()=>N,Catalogs:()=>j,InvalidScryfallArgumentError:()=>p,MagicPageResult:()=>d,Rulings:()=>q,ScryfallError:()=>u,Sets:()=>$,SymbologyApi:()=>D,UnknownScryfallError:()=>l});module.exports=G(se);var p=class extends Error{};var u=class extends Error{constructor(t,s,o,n,c){super(s);this.code=t;this.status=o;this.type=n;this.warnings=c}};var l=class extends Error{};var h=100,L=100;async function J(a=0){return new Promise(e=>{setTimeout(e,a)})}async function V(){let a=Date.now(),e=a-h;if(e>=L)h=a;else{let t=L-e;h+=t,await J(t)}}function w(a=fetch){return async function(...t){return await V(),a(...t)}}var d=class{constructor(e,t){this.apiPath=e;this.query=t;this.#e=!0,this.#t=0}#t;#e;get count(){return this.#t}get hasMore(){return this.#e}async all(){let e=[];for(;this.#e;){let t=await this.next();e.push(...t)}return e}async get(e){let t=[];for(;this.#e;){let s=await this.next();if(t.push(...s),t.length===e)return t;if(t.length>e)return t.slice(0,e)}return t}async next(){let e=await r(this.apiPath,this.query);return this.#e=e?.has_more??!1,this.#t=Number.parseInt(`${e?.total_cards??0}`,10),this.#e&&this.setNextPage(),e?.data??[]}async page(e){return this.query.page=e,this.next()}setNextPage(){this.query.page+=1}};var X=async a=>{let e=await a.json(),t="status"in e?Number(e.status):void 0;if(t&&t>=500)return!0;let s="code"in e&&typeof e.code=="string"?e.code:void 0;return s!=="not_found"&&s!=="bad_request"};function x({maxAttempts:a=3,canRetry:e=X}={},t=fetch){let s=0;return async function o(...n){s++;let c=await t(...n);if(c.ok)return c;let i=await c.json(),f="code"in i&&typeof i.code=="string"?i.code:void 0,y="status"in i?Number(i.status):void 0,g="details"in i&&typeof i.details=="string"?i.details:void 0,S="type"in i&&typeof i.type=="string"?i.type:void 0,F="warnings"in i&&Array.isArray(i.warnings)?i.warnings:void 0;if(s>=a)throw f&&g&&y?new u(f,g,y,S,F):new l(`Request failed with status ${c.status}`);if(e(c))return o(...n);throw f&&g&&y?new u(f,g,y,S,F):new l(`Request failed with status ${c.status}`)}}var H=w(x()),K="https://api.scryfall.com",W=/^\d{4}-\d{2}-\d{2}?$/,Y=(a,e)=>typeof e=="string"&&W.test(e)?new Date(e):e;async function r(a,e,t){let s="";typeof a=="number"||typeof a=="string"?s=a:a&&(s=a.join("/"));let o=new URL(`${K}/${s}`);e&&Object.entries(e).forEach(([n,c])=>{c!==void 0&&o.searchParams.append(n,`${c}`)});try{let n={method:t?"POST":"GET"};t&&(n.body=JSON.stringify(t),n.headers={"Content-Type":"application/json"});let i=await(await H(o,n)).text();return JSON.parse(i,Y)}catch(n){if(n instanceof u&&(n.warnings&&console.warn(n.warnings),n.code==="not_found"||n.code==="bad_request"))return;throw n}}var C=class{async autoCompleteName(e){return(await r("cards/autocomplete",{q:e}))?.data??[]}async byArenaId(e){return r(["cards/arena",e])}async byId(e){return r(["cards",e])}async byMtgoId(e){return r(["cards/mtgo",e])}async byMultiverseId(e){return r(["cards/multiverse",e])}async byName(e,t,s=!1){let o=s,n=t;return typeof t=="boolean"&&(o=t,n=void 0),r("cards/named",{[o?"fuzzy":"exact"]:e,set:n})}async bySet(e,t,s){let o=["cards",e,t];return s&&o.push(s),r(o)}async byTcgPlayerId(e){return r(["cards/tcgplayer",e])}async collection(...e){let t=[];for(let s=0;s<e.length;s+=75){let o={identifiers:e.slice(s,s+75)},n=await r("cards/collection",void 0,o);t.push(...n?.data??[])}return t}async random(){return r("cards/random")}search(e,t){return new d("cards/search",{q:e,...typeof t=="number"?{page:t}:{...t,page:t?.page??1}})}},Z=new C,M=Z;var N=M;var m=class{static byId(e){return{id:e}}static byIllustrationId(e){return{illustration_id:e}}static byMtgoId(e){return{mtgo_id:e}}static byMultiverseId(e){return{multiverse_id:e}}static byName(e,t){return t?{name:e,set:t}:{name:e}}static byOracleId(e){return{oracle_id:e}}static bySet(e,t){return{collector_number:`${t}`,set:e}}};var _=m;var P=class{async artifactTypes(){return(await r("catalog/artifact-types"))?.data??[]}async artistNames(){return(await r("catalog/artist-names"))?.data??[]}async cardNames(){return(await r("catalog/card-names"))?.data??[]}async creatureTypes(){return(await r("catalog/creature-types"))?.data??[]}async enchantmentTypes(){return(await r("catalog/enchantment-types"))?.data??[]}async landTypes(){return(await r("catalog/land-types"))?.data??[]}async loyalties(){return(await r("catalog/loyalties"))?.data??[]}async planeswalkerTypes(){return(await r("catalog/planeswalker-types"))?.data??[]}async powers(){return(await r("catalog/powers"))?.data??[]}async spellTypes(){return(await r("catalog/spell-types"))?.data??[]}async toughnesses(){return(await r("catalog/toughnesses"))?.data??[]}async watermarks(){return(await r("catalog/watermarks"))?.data??[]}async wordBank(){return(await r("catalog/word-bank"))?.data??[]}},ee=new P,E=ee;var j=E;var R=class{async byArenaId(e){return(await r(["cards/arena",e,"rulings"]))?.data??[]}async byId(e){return(await r(["cards",e,"rulings"]))?.data??[]}async byMtgoId(e){return(await r(["cards/mtgo",e,"rulings"]))?.data??[]}async byMultiverseId(e){return(await r(["cards/multiverse",e,"rulings"]))?.data??[]}async bySet(e,t){return(await r(["cards",e,`${t}`,"rulings"]))?.data??[]}},te=new R,k=te;var q=k;var T=class{async all(){return(await r("sets"))?.data??[]}async byCode(e){return await r(["sets",e])}async byId(e){return r(["sets",e])}async byTcgPlayerId(e){return r(["sets/tcgplayer",e])}},re=new T,O=re;var $=O;var I=class{async all(){return(await r("symbology"))?.data??[]}async parseMana(e){if(!e||typeof e!="string")throw new p("shorthand must be a string");return await r("symbology/parse-mana",{cost:e})??{cost:"",colors:[],cmc:0,colorless:!1,monocolored:!1,multicolored:!1,object:"mana_cost"}}},ae=new I,v=ae;var D=v;0&&(module.exports={CardIdentifierBuilder,Cards,Catalogs,InvalidScryfallArgumentError,MagicPageResult,Rulings,ScryfallError,Sets,SymbologyApi,UnknownScryfallError});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var p=class extends Error{};var u=class extends Error{constructor(t,s,i,n,c){super(s);this.code=t;this.status=i;this.type=n;this.warnings=c}};var l=class extends Error{};var b=100,F=100;async function j(a=0){return new Promise(e=>{setTimeout(e,a)})}async function k(){let a=Date.now(),e=a-b;if(e>=F)b=a;else{let t=F-e;b+=t,await j(t)}}function h(a=fetch){return async function(...t){return await k(),a(...t)}}var d=class{constructor(e,t){this.apiPath=e;this.query=t;this.#e=!0,this.#t=0}#t;#e;get count(){return this.#t}get hasMore(){return this.#e}async all(){let e=[];for(;this.#e;){let t=await this.next();e.push(...t)}return e}async get(e){let t=[];for(;this.#e;){let s=await this.next();if(t.push(...s),t.length===e)return t;if(t.length>e)return t.slice(0,e)}return t}async next(){let e=await r(this.apiPath,this.query);return this.#e=e?.has_more??!1,this.#t=Number.parseInt(`${e?.total_cards??0}`,10),this.#e&&this.setNextPage(),e?.data??[]}async page(e){return this.query.page=e,this.next()}setNextPage(){this.query.page+=1}};var q=async a=>{let e=await a.json(),t="status"in e?Number(e.status):void 0;if(t&&t>=500)return!0;let s="code"in e&&typeof e.code=="string"?e.code:void 0;return s!=="not_found"&&s!=="bad_request"};function w({maxAttempts:a=3,canRetry:e=q}={},t=fetch){let s=0;return async function i(...n){s++;let c=await t(...n);if(c.ok)return c;let o=await c.json(),f="code"in o&&typeof o.code=="string"?o.code:void 0,y="status"in o?Number(o.status):void 0,g="details"in o&&typeof o.details=="string"?o.details:void 0,I="type"in o&&typeof o.type=="string"?o.type:void 0,S="warnings"in o&&Array.isArray(o.warnings)?o.warnings:void 0;if(s>=a)throw f&&g&&y?new u(f,g,y,I,S):new l(`Request failed with status ${c.status}`);if(e(c))return i(...n);throw f&&g&&y?new u(f,g,y,I,S):new l(`Request failed with status ${c.status}`)}}var O=h(w()),$="https://api.scryfall.com",v=/^\d{4}-\d{2}-\d{2}?$/,D=(a,e)=>typeof e=="string"&&v.test(e)?new Date(e):e;async function r(a,e,t){let s="";typeof a=="number"||typeof a=="string"?s=a:a&&(s=a.join("/"));let i=new URL(`${$}/${s}`);e&&Object.entries(e).forEach(([n,c])=>{c!==void 0&&i.searchParams.append(n,`${c}`)});try{let n={method:t?"POST":"GET"};t&&(n.body=JSON.stringify(t),n.headers={"Content-Type":"application/json"});let o=await(await O(i,n)).text();return JSON.parse(o,D)}catch(n){if(n instanceof u&&(n.warnings&&console.warn(n.warnings),n.code==="not_found"||n.code==="bad_request"))return;throw n}}var x=class{async autoCompleteName(e){return(await r("cards/autocomplete",{q:e}))?.data??[]}async byArenaId(e){return r(["cards/arena",e])}async byId(e){return r(["cards",e])}async byMtgoId(e){return r(["cards/mtgo",e])}async byMultiverseId(e){return r(["cards/multiverse",e])}async byName(e,t,s=!1){let i=s,n=t;return typeof t=="boolean"&&(i=t,n=void 0),r("cards/named",{[i?"fuzzy":"exact"]:e,set:n})}async bySet(e,t,s){let i=["cards",e,t];return s&&i.push(s),r(i)}async byTcgPlayerId(e){return r(["cards/tcgplayer",e])}async collection(...e){let t=[];for(let s=0;s<e.length;s+=75){let i={identifiers:e.slice(s,s+75)},n=await r("cards/collection",void 0,i);t.push(...n?.data??[])}return t}async random(){return r("cards/random")}search(e,t){return new d("cards/search",{q:e,...typeof t=="number"?{page:t}:{...t,page:t?.page??1}})}},Q=new x,L=Q;var z=L;var m=class{static byId(e){return{id:e}}static byIllustrationId(e){return{illustration_id:e}}static byMtgoId(e){return{mtgo_id:e}}static byMultiverseId(e){return{multiverse_id:e}}static byName(e,t){return t?{name:e,set:t}:{name:e}}static byOracleId(e){return{oracle_id:e}}static bySet(e,t){return{collector_number:`${t}`,set:e}}};var A=m;var C=class{async artifactTypes(){return(await r("catalog/artifact-types"))?.data??[]}async artistNames(){return(await r("catalog/artist-names"))?.data??[]}async cardNames(){return(await r("catalog/card-names"))?.data??[]}async creatureTypes(){return(await r("catalog/creature-types"))?.data??[]}async enchantmentTypes(){return(await r("catalog/enchantment-types"))?.data??[]}async landTypes(){return(await r("catalog/land-types"))?.data??[]}async loyalties(){return(await r("catalog/loyalties"))?.data??[]}async planeswalkerTypes(){return(await r("catalog/planeswalker-types"))?.data??[]}async powers(){return(await r("catalog/powers"))?.data??[]}async spellTypes(){return(await r("catalog/spell-types"))?.data??[]}async toughnesses(){return(await r("catalog/toughnesses"))?.data??[]}async watermarks(){return(await r("catalog/watermarks"))?.data??[]}async wordBank(){return(await r("catalog/word-bank"))?.data??[]}},U=new C,M=U;var B=M;var P=class{async byArenaId(e){return(await r(["cards/arena",e,"rulings"]))?.data??[]}async byId(e){return(await r(["cards",e,"rulings"]))?.data??[]}async byMtgoId(e){return(await r(["cards/mtgo",e,"rulings"]))?.data??[]}async byMultiverseId(e){return(await r(["cards/multiverse",e,"rulings"]))?.data??[]}async bySet(e,t){return(await r(["cards",e,`${t}`,"rulings"]))?.data??[]}},G=new P,N=G;var J=N;var R=class{async all(){return(await r("sets"))?.data??[]}async byCode(e){return await r(["sets",e])}async byId(e){return r(["sets",e])}async byTcgPlayerId(e){return r(["sets/tcgplayer",e])}},V=new R,_=V;var X=_;var T=class{async all(){return(await r("symbology"))?.data??[]}async parseMana(e){if(!e||typeof e!="string")throw new p("shorthand must be a string");return await r("symbology/parse-mana",{cost:e})??{cost:"",colors:[],cmc:0,colorless:!1,monocolored:!1,multicolored:!1,object:"mana_cost"}}},H=new T,E=H;var K=E;export{A as CardIdentifierBuilder,z as Cards,B as Catalogs,p as InvalidScryfallArgumentError,d as MagicPageResult,J as Rulings,u as ScryfallError,X as Sets,K as SymbologyApi,l as UnknownScryfallError};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "scryfall-api",
|
|
3
|
-
"version": "4.0.0-beta.
|
|
3
|
+
"version": "4.0.0-beta.1",
|
|
4
4
|
"description": "A Javascript library for https://scryfall.com/docs/api written in Typescript.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"magic",
|
|
@@ -42,6 +42,7 @@
|
|
|
42
42
|
"build": "tsup",
|
|
43
43
|
"lint": "eslint .",
|
|
44
44
|
"lint:fix": "eslint --fix .",
|
|
45
|
+
"prepublishOnly": "tsup",
|
|
45
46
|
"test": "bun test",
|
|
46
47
|
"typecheck": "tsc --noEmit"
|
|
47
48
|
},
|