@flesh-and-blood/search 3.9.13 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -5
- package/dist/abbreviations.js +385 -0
- package/dist/constants.js +4 -0
- package/dist/filters.js +695 -0
- package/dist/helpers.js +15 -0
- package/dist/index.cjs +1 -0
- package/dist/index.js +12 -2
- package/dist/memes.js +52 -0
- package/dist/metaFilters.js +395 -0
- package/dist/related.js +135 -0
- package/dist/search.js +422 -0
- package/dist/shorthands.js +174 -0
- package/package.json +33 -6
package/dist/filters.js
ADDED
|
@@ -0,0 +1,695 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Foiling,
|
|
3
|
+
Meta,
|
|
4
|
+
Rarity,
|
|
5
|
+
Release,
|
|
6
|
+
Treatment,
|
|
7
|
+
Type,
|
|
8
|
+
setIdentifierToSetMappings,
|
|
9
|
+
setToSetIdentifierMappings
|
|
10
|
+
} from "@flesh-and-blood/types";
|
|
11
|
+
import { getAbbreviation } from "./abbreviations";
|
|
12
|
+
import { getExcludedMetaFilters, getMetaFilters } from "./metaFilters";
|
|
13
|
+
import { multiWordShorthands, singleWordShorthands } from "./shorthands";
|
|
14
|
+
import { PUNCTUATION } from "./constants";
|
|
15
|
+
import { getCardByName, getRelatedCardsByName } from ".";
|
|
16
|
+
const availableModifiers = [">=", ">", "<=", "<"];
|
|
17
|
+
const availableExclusions = ["!", "-"];
|
|
18
|
+
const arcaneFilter = {
|
|
19
|
+
property: "arcane",
|
|
20
|
+
specialProperty: "specialArcane",
|
|
21
|
+
isNumber: true,
|
|
22
|
+
partialMatch: true
|
|
23
|
+
};
|
|
24
|
+
const artistFilter = {
|
|
25
|
+
property: "artists",
|
|
26
|
+
isArray: true,
|
|
27
|
+
partialMatch: true
|
|
28
|
+
};
|
|
29
|
+
const bannedFilter = {
|
|
30
|
+
property: "n/a",
|
|
31
|
+
isMeta: true
|
|
32
|
+
};
|
|
33
|
+
const bondFilter = {
|
|
34
|
+
property: "bonds",
|
|
35
|
+
isArray: true
|
|
36
|
+
};
|
|
37
|
+
const chainFilter = {
|
|
38
|
+
property: "n/a"
|
|
39
|
+
};
|
|
40
|
+
const classFilter = {
|
|
41
|
+
property: "classes",
|
|
42
|
+
isArray: true,
|
|
43
|
+
partialMatch: true
|
|
44
|
+
};
|
|
45
|
+
const costFilter = {
|
|
46
|
+
property: "cost",
|
|
47
|
+
specialProperty: "specialCost",
|
|
48
|
+
isNumber: true,
|
|
49
|
+
partialMatch: true
|
|
50
|
+
};
|
|
51
|
+
const defenseFilter = {
|
|
52
|
+
property: "defense",
|
|
53
|
+
specialProperty: "specialDefense",
|
|
54
|
+
isNumber: true
|
|
55
|
+
};
|
|
56
|
+
const flowFilter = {
|
|
57
|
+
property: "flows",
|
|
58
|
+
isArray: true
|
|
59
|
+
};
|
|
60
|
+
const foilFilter = {
|
|
61
|
+
nestedProperty: "foiling",
|
|
62
|
+
property: "printings",
|
|
63
|
+
isArray: true
|
|
64
|
+
};
|
|
65
|
+
const fuseFilter = {
|
|
66
|
+
property: "fusions",
|
|
67
|
+
isArray: true
|
|
68
|
+
};
|
|
69
|
+
const intellectFilter = {
|
|
70
|
+
property: "intellect",
|
|
71
|
+
isNumber: true
|
|
72
|
+
};
|
|
73
|
+
const keywordFilter = {
|
|
74
|
+
property: "keywords",
|
|
75
|
+
isArray: true
|
|
76
|
+
// partialMatch: true,
|
|
77
|
+
};
|
|
78
|
+
const legalFilter = {
|
|
79
|
+
property: "n/a",
|
|
80
|
+
isMeta: true
|
|
81
|
+
};
|
|
82
|
+
const lifeFilter = {
|
|
83
|
+
property: "life",
|
|
84
|
+
specialProperty: "specialLife",
|
|
85
|
+
isNumber: true
|
|
86
|
+
};
|
|
87
|
+
const metaFilter = {
|
|
88
|
+
property: "meta",
|
|
89
|
+
isArray: true
|
|
90
|
+
};
|
|
91
|
+
const nameFilter = {
|
|
92
|
+
property: "name",
|
|
93
|
+
isString: true,
|
|
94
|
+
partialMatch: true
|
|
95
|
+
};
|
|
96
|
+
const pitchFilter = {
|
|
97
|
+
property: "pitch",
|
|
98
|
+
isNumber: true
|
|
99
|
+
};
|
|
100
|
+
const powerFilter = {
|
|
101
|
+
property: "power",
|
|
102
|
+
specialProperty: "specialPower",
|
|
103
|
+
isNumber: true
|
|
104
|
+
};
|
|
105
|
+
const setIdentifiersFilter = {
|
|
106
|
+
property: "setIdentifiers",
|
|
107
|
+
isArray: true,
|
|
108
|
+
partialMatch: true
|
|
109
|
+
};
|
|
110
|
+
const rarityFilter = {
|
|
111
|
+
property: "n/a",
|
|
112
|
+
isMeta: true
|
|
113
|
+
};
|
|
114
|
+
const referencedByFilter = {
|
|
115
|
+
property: "n/a"
|
|
116
|
+
};
|
|
117
|
+
const referencesFilter = {
|
|
118
|
+
property: "n/a"
|
|
119
|
+
};
|
|
120
|
+
const setFilter = {
|
|
121
|
+
property: "sets",
|
|
122
|
+
isArray: true,
|
|
123
|
+
partialMatch: true
|
|
124
|
+
};
|
|
125
|
+
const shorthandsFilter = {
|
|
126
|
+
property: "shorthands",
|
|
127
|
+
isArray: true,
|
|
128
|
+
partialMatch: true
|
|
129
|
+
};
|
|
130
|
+
const specializationsFilter = {
|
|
131
|
+
property: "specializations",
|
|
132
|
+
isArray: true,
|
|
133
|
+
partialMatch: true
|
|
134
|
+
};
|
|
135
|
+
const subtypeFilter = {
|
|
136
|
+
property: "subtypes",
|
|
137
|
+
isArray: true
|
|
138
|
+
};
|
|
139
|
+
const typeFilter = {
|
|
140
|
+
property: "types",
|
|
141
|
+
isArray: true
|
|
142
|
+
};
|
|
143
|
+
const talentFilter = {
|
|
144
|
+
property: "talents",
|
|
145
|
+
isArray: true
|
|
146
|
+
};
|
|
147
|
+
const textFilter = {
|
|
148
|
+
property: "functionalText",
|
|
149
|
+
isString: true,
|
|
150
|
+
partialMatch: true
|
|
151
|
+
};
|
|
152
|
+
const traitFilter = {
|
|
153
|
+
property: "traits",
|
|
154
|
+
isArray: true,
|
|
155
|
+
partialMatch: true
|
|
156
|
+
};
|
|
157
|
+
const typeTextFilter = {
|
|
158
|
+
property: "typeText",
|
|
159
|
+
isString: true,
|
|
160
|
+
partialMatch: true
|
|
161
|
+
};
|
|
162
|
+
const treatmentFilter = {
|
|
163
|
+
nestedProperty: "treatments",
|
|
164
|
+
property: "printings",
|
|
165
|
+
isArray: true,
|
|
166
|
+
isNestedPropertyArray: true
|
|
167
|
+
};
|
|
168
|
+
const filtersToCardPropertyMappings = {
|
|
169
|
+
arcane: arcaneFilter,
|
|
170
|
+
a: artistFilter,
|
|
171
|
+
artist: artistFilter,
|
|
172
|
+
art: artistFilter,
|
|
173
|
+
attack: powerFilter,
|
|
174
|
+
b: defenseFilter,
|
|
175
|
+
block: defenseFilter,
|
|
176
|
+
banned: bannedFilter,
|
|
177
|
+
bond: bondFilter,
|
|
178
|
+
bonds: bondFilter,
|
|
179
|
+
c: classFilter,
|
|
180
|
+
class: classFilter,
|
|
181
|
+
chain: chainFilter,
|
|
182
|
+
co: costFilter,
|
|
183
|
+
cost: costFilter,
|
|
184
|
+
color: pitchFilter,
|
|
185
|
+
d: defenseFilter,
|
|
186
|
+
def: defenseFilter,
|
|
187
|
+
defense: defenseFilter,
|
|
188
|
+
flow: flowFilter,
|
|
189
|
+
flows: flowFilter,
|
|
190
|
+
f: fuseFilter,
|
|
191
|
+
fusion: fuseFilter,
|
|
192
|
+
foil: foilFilter,
|
|
193
|
+
foiling: foilFilter,
|
|
194
|
+
i: intellectFilter,
|
|
195
|
+
intellect: intellectFilter,
|
|
196
|
+
is: metaFilter,
|
|
197
|
+
k: keywordFilter,
|
|
198
|
+
keyword: keywordFilter,
|
|
199
|
+
l: legalFilter,
|
|
200
|
+
legal: legalFilter,
|
|
201
|
+
hero: legalFilter,
|
|
202
|
+
li: lifeFilter,
|
|
203
|
+
life: lifeFilter,
|
|
204
|
+
meta: metaFilter,
|
|
205
|
+
n: nameFilter,
|
|
206
|
+
name: nameFilter,
|
|
207
|
+
p: pitchFilter,
|
|
208
|
+
pitch: pitchFilter,
|
|
209
|
+
pwr: powerFilter,
|
|
210
|
+
pow: powerFilter,
|
|
211
|
+
power: powerFilter,
|
|
212
|
+
print: setIdentifiersFilter,
|
|
213
|
+
r: rarityFilter,
|
|
214
|
+
rarity: rarityFilter,
|
|
215
|
+
referencedby: referencedByFilter,
|
|
216
|
+
references: referencesFilter,
|
|
217
|
+
rf: bannedFilter,
|
|
218
|
+
s: setFilter,
|
|
219
|
+
set: setFilter,
|
|
220
|
+
short: shorthandsFilter,
|
|
221
|
+
shorthand: shorthandsFilter,
|
|
222
|
+
shorthands: shorthandsFilter,
|
|
223
|
+
sp: specializationsFilter,
|
|
224
|
+
spec: specializationsFilter,
|
|
225
|
+
specialization: specializationsFilter,
|
|
226
|
+
specializations: specializationsFilter,
|
|
227
|
+
st: subtypeFilter,
|
|
228
|
+
subtype: subtypeFilter,
|
|
229
|
+
t: typeFilter,
|
|
230
|
+
type: typeFilter,
|
|
231
|
+
tal: talentFilter,
|
|
232
|
+
talent: talentFilter,
|
|
233
|
+
text: textFilter,
|
|
234
|
+
trait: traitFilter,
|
|
235
|
+
treat: treatmentFilter,
|
|
236
|
+
treatment: treatmentFilter,
|
|
237
|
+
var: treatmentFilter,
|
|
238
|
+
variation: treatmentFilter,
|
|
239
|
+
x: typeTextFilter
|
|
240
|
+
};
|
|
241
|
+
const punctuationOverrides = [
|
|
242
|
+
{
|
|
243
|
+
text: Release.ClassicBattlesRhinarDorinthea.toLowerCase(),
|
|
244
|
+
override: Release.ClassicBattlesRhinarDorinthea.toLowerCase().replaceAll(
|
|
245
|
+
PUNCTUATION,
|
|
246
|
+
""
|
|
247
|
+
)
|
|
248
|
+
}
|
|
249
|
+
];
|
|
250
|
+
const getSearchCriteria = (text) => {
|
|
251
|
+
const searchCriteria = [];
|
|
252
|
+
let rawSearchCriteria = text.replaceAll("\u201D", '"');
|
|
253
|
+
for (const { text: text2, override } of punctuationOverrides) {
|
|
254
|
+
if (rawSearchCriteria.includes(text2)) {
|
|
255
|
+
rawSearchCriteria = rawSearchCriteria.replace(text2, override);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
const matchingAbbreviation = getAbbreviation(rawSearchCriteria)?.card;
|
|
259
|
+
if (matchingAbbreviation) {
|
|
260
|
+
searchCriteria.push(rawSearchCriteria);
|
|
261
|
+
} else {
|
|
262
|
+
const splitSearchCriteria = rawSearchCriteria.split(/[ ]+/);
|
|
263
|
+
let combinedSearchCriteria = "";
|
|
264
|
+
let combinedQuoteCount = 0;
|
|
265
|
+
for (const criteria of splitSearchCriteria) {
|
|
266
|
+
if (combinedQuoteCount === 2) {
|
|
267
|
+
searchCriteria.push(combinedSearchCriteria.trim().replaceAll('"', ""));
|
|
268
|
+
combinedSearchCriteria = "";
|
|
269
|
+
combinedQuoteCount = 0;
|
|
270
|
+
}
|
|
271
|
+
if (combinedQuoteCount < 2 && criteria.split('"').length === 2) {
|
|
272
|
+
combinedSearchCriteria += " " + criteria;
|
|
273
|
+
combinedQuoteCount++;
|
|
274
|
+
} else if (combinedQuoteCount === 0 && combinedSearchCriteria === "") {
|
|
275
|
+
searchCriteria.push(criteria);
|
|
276
|
+
} else if (combinedQuoteCount === 1) {
|
|
277
|
+
combinedSearchCriteria += " " + criteria;
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
if (combinedQuoteCount === 2) {
|
|
281
|
+
searchCriteria.push(combinedSearchCriteria.trim().replaceAll('"', ""));
|
|
282
|
+
combinedSearchCriteria = "";
|
|
283
|
+
combinedQuoteCount = 0;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
return searchCriteria;
|
|
287
|
+
};
|
|
288
|
+
const getKeywordsAndAppliedFiltersFromText = (text, cards, additionalHeroes = [], additionalSets = []) => {
|
|
289
|
+
let expandedText = text.trim().toLowerCase();
|
|
290
|
+
for (const { expanded: filters, shorthands } of multiWordShorthands) {
|
|
291
|
+
for (const shorthand of shorthands) {
|
|
292
|
+
if (expandedText.includes(shorthand)) {
|
|
293
|
+
expandedText = expandedText.replace(shorthand, filters.join(" "));
|
|
294
|
+
break;
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
for (const [set, setIdentifiers] of Object.entries(
|
|
299
|
+
setToSetIdentifierMappings
|
|
300
|
+
)) {
|
|
301
|
+
if (expandedText.includes(set.toLowerCase())) {
|
|
302
|
+
expandedText = expandedText.replace(set.toLowerCase(), setIdentifiers[0]);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
const rawSearchCriteria = getSearchCriteria(expandedText);
|
|
306
|
+
const searchCriteria = [];
|
|
307
|
+
for (const criteria of rawSearchCriteria) {
|
|
308
|
+
const expanded = singleWordShorthands.find(
|
|
309
|
+
({ shorthands }) => shorthands.includes(criteria)
|
|
310
|
+
);
|
|
311
|
+
if (expanded && !expanded.isCardProperty) {
|
|
312
|
+
searchCriteria.push(...expanded.expanded);
|
|
313
|
+
} else {
|
|
314
|
+
searchCriteria.push(criteria);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
let appliedFilters = [];
|
|
318
|
+
let artists = [];
|
|
319
|
+
let keywords = [];
|
|
320
|
+
let foilings = [];
|
|
321
|
+
let isExpansionSlot = false;
|
|
322
|
+
let prints = [];
|
|
323
|
+
let rarities = [];
|
|
324
|
+
let releases = [];
|
|
325
|
+
let treatments = [];
|
|
326
|
+
for (const criteria of searchCriteria) {
|
|
327
|
+
if (hasFilter(criteria)) {
|
|
328
|
+
const [unparsedFilterKey, unparsedFilterValue] = criteria.split(":");
|
|
329
|
+
let { modifier, values, isAnd, isOr } = getFilterValuesAndModifier(unparsedFilterValue);
|
|
330
|
+
let { filterKey, isExcluded, isOptional, isMeta } = getFilterKeyAndExcludedOrOptional(unparsedFilterKey);
|
|
331
|
+
if (isMeta) {
|
|
332
|
+
if (["rarity", "r"].includes(filterKey)) {
|
|
333
|
+
const rarityValues = getRarityValuesFromText(values);
|
|
334
|
+
if (!isExcluded) {
|
|
335
|
+
rarities = [...rarityValues];
|
|
336
|
+
}
|
|
337
|
+
values = rarityValues.map((s) => s.toLowerCase());
|
|
338
|
+
}
|
|
339
|
+
if (["legal", "l", "hero"].includes(filterKey)) {
|
|
340
|
+
}
|
|
341
|
+
appliedFilters.push(
|
|
342
|
+
...getMetaFilters(
|
|
343
|
+
isExcluded,
|
|
344
|
+
isOptional,
|
|
345
|
+
filterKey,
|
|
346
|
+
values,
|
|
347
|
+
modifier,
|
|
348
|
+
additionalHeroes
|
|
349
|
+
)
|
|
350
|
+
);
|
|
351
|
+
} else {
|
|
352
|
+
if (["chain"].includes(filterKey)) {
|
|
353
|
+
const getName = (card) => card.name.toLowerCase().replaceAll(PUNCTUATION, "");
|
|
354
|
+
const relatedCardNames = values.map((name) => getCardByName(name, cards)).filter((card) => !!card).map(getName);
|
|
355
|
+
const names = new Set(relatedCardNames);
|
|
356
|
+
filterKey = "name";
|
|
357
|
+
isOr = true;
|
|
358
|
+
let limit = 20;
|
|
359
|
+
let counter = 0;
|
|
360
|
+
const addToSetAndRelated = (card) => {
|
|
361
|
+
if (!card.types.includes(Type.Hero)) {
|
|
362
|
+
const name = getName(card);
|
|
363
|
+
names.add(name);
|
|
364
|
+
if (!relatedCardNames.includes(name)) {
|
|
365
|
+
relatedCardNames.push(name);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
};
|
|
369
|
+
for (const relatedCardName of relatedCardNames) {
|
|
370
|
+
if (counter > limit) {
|
|
371
|
+
break;
|
|
372
|
+
}
|
|
373
|
+
const { referencedBy, references } = getRelatedCardsByName(
|
|
374
|
+
relatedCardName,
|
|
375
|
+
cards
|
|
376
|
+
);
|
|
377
|
+
references.forEach(addToSetAndRelated);
|
|
378
|
+
if (counter === 0) {
|
|
379
|
+
referencedBy.forEach(addToSetAndRelated);
|
|
380
|
+
}
|
|
381
|
+
counter++;
|
|
382
|
+
}
|
|
383
|
+
values = Array.from(names);
|
|
384
|
+
} else if (["referencedby", "references"].includes(filterKey)) {
|
|
385
|
+
const originalKey = filterKey;
|
|
386
|
+
const relatedCardNames = [...values].filter((value) => !!value);
|
|
387
|
+
values = [];
|
|
388
|
+
filterKey = "name";
|
|
389
|
+
isOr = true;
|
|
390
|
+
for (const relatedCardName of relatedCardNames) {
|
|
391
|
+
const { referencedBy, references } = getRelatedCardsByName(
|
|
392
|
+
relatedCardName,
|
|
393
|
+
cards
|
|
394
|
+
);
|
|
395
|
+
if (["referencedby"].includes(originalKey)) {
|
|
396
|
+
values.push(
|
|
397
|
+
...references.map(
|
|
398
|
+
({ name }) => name.toLowerCase().replaceAll(PUNCTUATION, "")
|
|
399
|
+
)
|
|
400
|
+
);
|
|
401
|
+
} else if (["references"].includes(originalKey)) {
|
|
402
|
+
values.push(
|
|
403
|
+
...referencedBy.map(
|
|
404
|
+
({ name }) => name.toLowerCase().replaceAll(PUNCTUATION, "")
|
|
405
|
+
)
|
|
406
|
+
);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
} else if (["art", "artist"].includes(filterKey)) {
|
|
410
|
+
artists = values;
|
|
411
|
+
} else if (["print", "prints", "printing", "printings"].includes(filterKey)) {
|
|
412
|
+
prints = values;
|
|
413
|
+
} else if (["is", "meta"].includes(filterKey)) {
|
|
414
|
+
const metaValues = getMetaValuesFromText(values);
|
|
415
|
+
values = metaValues.map(
|
|
416
|
+
(v) => v.toLowerCase().replaceAll(PUNCTUATION, "")
|
|
417
|
+
);
|
|
418
|
+
if (metaValues.includes(Meta.Expansion) && !isExcluded) {
|
|
419
|
+
isExpansionSlot = true;
|
|
420
|
+
}
|
|
421
|
+
} else if (["foiling", "foil"].includes(filterKey)) {
|
|
422
|
+
foilings = getFoilingValuesFromText(values);
|
|
423
|
+
values = foilings.map((f) => f.toLowerCase());
|
|
424
|
+
} else if (["treat", "treatment", "var", "variation"].includes(filterKey)) {
|
|
425
|
+
treatments = getTreatmentValuesFromText(values);
|
|
426
|
+
values = treatments.map((t) => t.toLowerCase());
|
|
427
|
+
} else if (["set", "s"].includes(filterKey)) {
|
|
428
|
+
releases = getReleasesFromRawValues(values, additionalSets);
|
|
429
|
+
values = releases.map(
|
|
430
|
+
(s) => s.toLowerCase().replaceAll(PUNCTUATION, "")
|
|
431
|
+
);
|
|
432
|
+
} else if (["pitch", "p", "color"].includes(filterKey)) {
|
|
433
|
+
values = getPitchValuesFromText(values);
|
|
434
|
+
}
|
|
435
|
+
if (filtersToCardPropertyMappings[filterKey]) {
|
|
436
|
+
appliedFilters.push({
|
|
437
|
+
filterToPropertyMapping: filtersToCardPropertyMappings[filterKey],
|
|
438
|
+
values,
|
|
439
|
+
isAnd,
|
|
440
|
+
isOr,
|
|
441
|
+
modifier,
|
|
442
|
+
isExcluded,
|
|
443
|
+
isOptional
|
|
444
|
+
});
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
} else if (criteria) {
|
|
448
|
+
const expanded = getAbbreviation(criteria)?.card;
|
|
449
|
+
const metaFilters = getExcludedMetaFilters(criteria);
|
|
450
|
+
if (expanded) {
|
|
451
|
+
keywords.push(`"${expanded.toLowerCase().replace(PUNCTUATION, "")}"`);
|
|
452
|
+
} else if (metaFilters && metaFilters.length > 0) {
|
|
453
|
+
appliedFilters.push(...metaFilters);
|
|
454
|
+
} else {
|
|
455
|
+
keywords.push(criteria.replace(PUNCTUATION, ""));
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
return {
|
|
460
|
+
appliedFilters,
|
|
461
|
+
attributes: {
|
|
462
|
+
artists,
|
|
463
|
+
foilings,
|
|
464
|
+
isExpansionSlot,
|
|
465
|
+
prints,
|
|
466
|
+
rarities,
|
|
467
|
+
releases,
|
|
468
|
+
treatments
|
|
469
|
+
},
|
|
470
|
+
keywords
|
|
471
|
+
};
|
|
472
|
+
};
|
|
473
|
+
const getReleasesFromRawValues = (rawValues, additionalSets = []) => {
|
|
474
|
+
const releases = [];
|
|
475
|
+
for (const rawValue of rawValues) {
|
|
476
|
+
releases.push(...getMatchingReleasesFromRawValue(rawValue, additionalSets));
|
|
477
|
+
}
|
|
478
|
+
return releases;
|
|
479
|
+
};
|
|
480
|
+
const getMatchingReleasesFromRawValue = (rawValue, additionalSets = []) => {
|
|
481
|
+
const releases = [];
|
|
482
|
+
const setFromValue = Object.values(Release).find(
|
|
483
|
+
(release) => release.toLowerCase().replaceAll(PUNCTUATION, "") === rawValue
|
|
484
|
+
);
|
|
485
|
+
if (setFromValue) {
|
|
486
|
+
releases.push(setFromValue);
|
|
487
|
+
}
|
|
488
|
+
if (releases.length === 0) {
|
|
489
|
+
const setFromSetIdentifier = setIdentifierToSetMappings[rawValue];
|
|
490
|
+
if (setFromSetIdentifier) {
|
|
491
|
+
releases.push(setFromSetIdentifier);
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
if (releases.length === 0) {
|
|
495
|
+
const setsFromPartialValue = Object.values(Release).filter(
|
|
496
|
+
(release) => release.toLowerCase().includes(rawValue)
|
|
497
|
+
);
|
|
498
|
+
if (setsFromPartialValue.length > 0) {
|
|
499
|
+
releases.push(...setsFromPartialValue);
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
if (releases.length === 0) {
|
|
503
|
+
const additionalSetFromValue = additionalSets.find(
|
|
504
|
+
(additionalSet) => additionalSet.toLowerCase().replaceAll(PUNCTUATION, "") === rawValue
|
|
505
|
+
);
|
|
506
|
+
if (additionalSetFromValue) {
|
|
507
|
+
releases.push(additionalSetFromValue);
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
return releases;
|
|
511
|
+
};
|
|
512
|
+
const pitchValuesMapping = {
|
|
513
|
+
blue: 3,
|
|
514
|
+
yellow: 2,
|
|
515
|
+
red: 1,
|
|
516
|
+
white: 0
|
|
517
|
+
};
|
|
518
|
+
const getPitchValuesFromText = (rawValues) => {
|
|
519
|
+
const values = [];
|
|
520
|
+
for (const rawValue of rawValues) {
|
|
521
|
+
if (pitchValuesMapping[rawValue] || pitchValuesMapping[rawValue] === 0) {
|
|
522
|
+
values.push(pitchValuesMapping[rawValue].toString());
|
|
523
|
+
} else {
|
|
524
|
+
values.push(rawValue);
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
return values;
|
|
528
|
+
};
|
|
529
|
+
const metaValuesMapping = {
|
|
530
|
+
exp: Meta.Expansion,
|
|
531
|
+
expansion: Meta.Expansion,
|
|
532
|
+
expansionSlot: Meta.Expansion,
|
|
533
|
+
rainbow: Meta.Rainbow
|
|
534
|
+
};
|
|
535
|
+
const getMetaValuesFromText = (rawValues) => {
|
|
536
|
+
const values = [];
|
|
537
|
+
for (const rawValue of rawValues) {
|
|
538
|
+
if (metaValuesMapping[rawValue]) {
|
|
539
|
+
values.push(metaValuesMapping[rawValue]);
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
return values;
|
|
543
|
+
};
|
|
544
|
+
const foilingValuesMapping = {
|
|
545
|
+
r: Foiling.Rainbow,
|
|
546
|
+
rf: Foiling.Rainbow,
|
|
547
|
+
rainbow: Foiling.Rainbow,
|
|
548
|
+
c: Foiling.Cold,
|
|
549
|
+
cf: Foiling.Cold,
|
|
550
|
+
cold: Foiling.Cold,
|
|
551
|
+
g: Foiling.Gold,
|
|
552
|
+
gf: Foiling.Gold,
|
|
553
|
+
gold: Foiling.Gold
|
|
554
|
+
};
|
|
555
|
+
const getFoilingValuesFromText = (rawValues) => {
|
|
556
|
+
const values = [];
|
|
557
|
+
for (const rawValue of rawValues) {
|
|
558
|
+
if (foilingValuesMapping[rawValue]) {
|
|
559
|
+
values.push(foilingValuesMapping[rawValue]);
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
return values;
|
|
563
|
+
};
|
|
564
|
+
const treatmentValuesMapping = {
|
|
565
|
+
...Object.values(Treatment).reduce((obj, treatment) => {
|
|
566
|
+
obj[treatment.toLowerCase()] = treatment;
|
|
567
|
+
return obj;
|
|
568
|
+
}, {}),
|
|
569
|
+
...{
|
|
570
|
+
aa: Treatment.AA,
|
|
571
|
+
alt: Treatment.AA,
|
|
572
|
+
"alt art": Treatment.AA,
|
|
573
|
+
ab: Treatment.AB,
|
|
574
|
+
"alt border": Treatment.AB,
|
|
575
|
+
at: Treatment.AT,
|
|
576
|
+
"alt text": Treatment.AT,
|
|
577
|
+
// ds: Treatment.DS,
|
|
578
|
+
// "double sided": Treatment.DS,
|
|
579
|
+
ea: Treatment.EA,
|
|
580
|
+
extended: Treatment.EA,
|
|
581
|
+
"extended art": Treatment.EA,
|
|
582
|
+
fa: Treatment.FA,
|
|
583
|
+
full: Treatment.FA,
|
|
584
|
+
"full art": Treatment.FA
|
|
585
|
+
}
|
|
586
|
+
};
|
|
587
|
+
const getTreatmentValuesFromText = (rawValues) => {
|
|
588
|
+
const values = [];
|
|
589
|
+
for (const rawValue of rawValues) {
|
|
590
|
+
if (treatmentValuesMapping[rawValue]) {
|
|
591
|
+
values.push(treatmentValuesMapping[rawValue]);
|
|
592
|
+
} else if (!!Treatment[rawValue.toUpperCase()]) {
|
|
593
|
+
values.push(Treatment[rawValue.toUpperCase()]);
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
return values;
|
|
597
|
+
};
|
|
598
|
+
const RARITY_VALUES_MAPPING = {
|
|
599
|
+
b: Rarity.Basic,
|
|
600
|
+
c: Rarity.Common,
|
|
601
|
+
f: Rarity.Fabled,
|
|
602
|
+
l: Rarity.Legendary,
|
|
603
|
+
m: Rarity.Majestic,
|
|
604
|
+
p: Rarity.Promo,
|
|
605
|
+
r: Rarity.Rare,
|
|
606
|
+
s: Rarity.SuperRare,
|
|
607
|
+
t: Rarity.Token,
|
|
608
|
+
v: Rarity.Marvel
|
|
609
|
+
};
|
|
610
|
+
const getRarityValuesFromText = (rawValues) => {
|
|
611
|
+
const values = [];
|
|
612
|
+
for (const rawValue of rawValues) {
|
|
613
|
+
if (RARITY_VALUES_MAPPING[rawValue]) {
|
|
614
|
+
values.push(RARITY_VALUES_MAPPING[rawValue]);
|
|
615
|
+
} else {
|
|
616
|
+
values.push(rawValue);
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
return values;
|
|
620
|
+
};
|
|
621
|
+
const getFilterValuesAndModifier = (unparsedFilterValue) => {
|
|
622
|
+
const values = [];
|
|
623
|
+
let isAnd, isOr;
|
|
624
|
+
const modifier = availableModifiers.find(
|
|
625
|
+
(modifier2) => unparsedFilterValue.includes(modifier2)
|
|
626
|
+
);
|
|
627
|
+
if (modifier) {
|
|
628
|
+
const [, rawValue] = unparsedFilterValue.split(modifier);
|
|
629
|
+
if (filterIsAnd(rawValue)) {
|
|
630
|
+
isAnd = true;
|
|
631
|
+
values.push(
|
|
632
|
+
...rawValue.trim().split("+").map((value) => value.replace(PUNCTUATION, ""))
|
|
633
|
+
);
|
|
634
|
+
} else if (filterIsOr(rawValue)) {
|
|
635
|
+
isOr = true;
|
|
636
|
+
values.push(
|
|
637
|
+
...rawValue.trim().split(",").map((value) => value.replace(PUNCTUATION, ""))
|
|
638
|
+
);
|
|
639
|
+
} else {
|
|
640
|
+
values.push(rawValue.trim().replace(PUNCTUATION, ""));
|
|
641
|
+
}
|
|
642
|
+
} else {
|
|
643
|
+
if (filterIsAnd(unparsedFilterValue)) {
|
|
644
|
+
isAnd = true;
|
|
645
|
+
values.push(
|
|
646
|
+
...unparsedFilterValue.trim().split("+").map((value) => value.replace(PUNCTUATION, ""))
|
|
647
|
+
);
|
|
648
|
+
} else if (filterIsOr(unparsedFilterValue)) {
|
|
649
|
+
isOr = true;
|
|
650
|
+
values.push(
|
|
651
|
+
...unparsedFilterValue.trim().split(",").map((value) => value.replace(PUNCTUATION, ""))
|
|
652
|
+
);
|
|
653
|
+
} else {
|
|
654
|
+
if (unparsedFilterValue.startsWith('"') && unparsedFilterValue.endsWith('"')) {
|
|
655
|
+
values.push(
|
|
656
|
+
unparsedFilterValue.trim().replaceAll('"', "").replace(PUNCTUATION, "")
|
|
657
|
+
);
|
|
658
|
+
} else {
|
|
659
|
+
values.push(unparsedFilterValue.trim().replace(PUNCTUATION, ""));
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
return { modifier, values, isAnd, isOr };
|
|
664
|
+
};
|
|
665
|
+
const getFilterKeyAndExcludedOrOptional = (unparsedFilterKey) => {
|
|
666
|
+
const exclusion = getExclusion(unparsedFilterKey);
|
|
667
|
+
if (exclusion) {
|
|
668
|
+
const [, filterKey] = unparsedFilterKey.split(exclusion);
|
|
669
|
+
return {
|
|
670
|
+
filterKey,
|
|
671
|
+
isExcluded: true,
|
|
672
|
+
isOptional: false,
|
|
673
|
+
isMeta: filterIsMeta(filterKey)
|
|
674
|
+
};
|
|
675
|
+
} else {
|
|
676
|
+
return {
|
|
677
|
+
filterKey: unparsedFilterKey,
|
|
678
|
+
isExcluded: false,
|
|
679
|
+
isOptional: false,
|
|
680
|
+
isMeta: filterIsMeta(unparsedFilterKey)
|
|
681
|
+
};
|
|
682
|
+
}
|
|
683
|
+
};
|
|
684
|
+
const hasFilter = (text) => text.indexOf(":") >= 0;
|
|
685
|
+
const filterIsAnd = (text) => text.indexOf("+") >= 0;
|
|
686
|
+
const filterIsOr = (text) => text.indexOf(",") >= 0;
|
|
687
|
+
const filterIsMeta = (filterKey) => !!filtersToCardPropertyMappings[filterKey]?.isMeta;
|
|
688
|
+
const getExclusion = (text) => availableExclusions.find((exclusion) => text.includes(exclusion))?.slice(0, 1);
|
|
689
|
+
export {
|
|
690
|
+
RARITY_VALUES_MAPPING,
|
|
691
|
+
availableExclusions,
|
|
692
|
+
availableModifiers,
|
|
693
|
+
filtersToCardPropertyMappings,
|
|
694
|
+
getKeywordsAndAppliedFiltersFromText
|
|
695
|
+
};
|
package/dist/helpers.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { PUNCTUATION } from "./constants";
|
|
2
|
+
const getCardByName = (name, cards) => {
|
|
3
|
+
let card = cards.find((card2) => getCleanText(card2.name) === name);
|
|
4
|
+
if (!card) {
|
|
5
|
+
card = cards.find((card2) => getCleanText(card2.name).includes(name));
|
|
6
|
+
}
|
|
7
|
+
return card;
|
|
8
|
+
};
|
|
9
|
+
const getCleanText = (text) => getNormalizedText(text.toLowerCase().trim().replace(PUNCTUATION, ""));
|
|
10
|
+
const getNormalizedText = (text) => text.normalize("NFD").replace(/\p{Diacritic}/gu, "");
|
|
11
|
+
export {
|
|
12
|
+
getCardByName,
|
|
13
|
+
getCleanText,
|
|
14
|
+
getNormalizedText
|
|
15
|
+
};
|