@flesh-and-blood/search 3.9.13 → 4.0.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/search.js ADDED
@@ -0,0 +1,422 @@
1
+ import {
2
+ setIdentifierToSetMappings,
3
+ setToSetIdentifierMappings
4
+ } from "@flesh-and-blood/types";
5
+ import Fuse from "fuse.js";
6
+ import { PUNCTUATION } from "./constants";
7
+ import { getKeywordsAndAppliedFiltersFromText } from "./filters";
8
+ import { memes } from "./memes";
9
+ import { getNormalizedText } from "./helpers";
10
+ import { FilterProperty } from "./metaFilters";
11
+ class Search {
12
+ constructor(cards, additionalHeroes = [], additionalSets = [], debug = false) {
13
+ this.log = (message, ...optionalParams) => {
14
+ if (this.debug) {
15
+ console.log(message, ...optionalParams);
16
+ }
17
+ };
18
+ this.search = (text, includeMemes) => {
19
+ let results;
20
+ const { appliedFilters, attributes, keywords } = getKeywordsAndAppliedFiltersFromText(
21
+ text,
22
+ this.cards,
23
+ this.additionalHeroes,
24
+ this.additionalSets
25
+ );
26
+ const keyword = keywords.join(" ");
27
+ const matchingMemes = includeMemes ? memes.filter((meme) => meme.keyword === keyword) : [];
28
+ if (matchingMemes.length > 0) {
29
+ results = matchingMemes.map(({ card }) => card);
30
+ } else if (keywords.length) {
31
+ results = this.fuse.search(keyword).map((result) => result.item);
32
+ } else {
33
+ results = [...this.cards];
34
+ }
35
+ if (appliedFilters.length) {
36
+ results = results.filter(
37
+ (card) => card && filterCard(card, appliedFilters)
38
+ );
39
+ }
40
+ if (keywords.length === 0) {
41
+ let setIdentifieToSortBy = "";
42
+ const shouldSortByRelease = attributes.releases.length === 1;
43
+ if (shouldSortByRelease) {
44
+ try {
45
+ const setToSort = attributes.releases[0];
46
+ const matchingSetIdentifiers = setToSetIdentifierMappings[setToSort];
47
+ setIdentifieToSortBy = matchingSetIdentifiers[0].toUpperCase();
48
+ } catch (e) {
49
+ console.error(`Error getting set identifier from search`, e);
50
+ }
51
+ }
52
+ const shouldSortByPrint = !setIdentifieToSortBy && attributes.prints.length === 1;
53
+ if (shouldSortByPrint) {
54
+ try {
55
+ const setToSort = attributes.prints[0];
56
+ const matchingSetIdentifiers = setIdentifierToSetMappings[setToSort];
57
+ if (matchingSetIdentifiers) {
58
+ setIdentifieToSortBy = setToSort.toUpperCase();
59
+ }
60
+ } catch (e) {
61
+ console.error(`Error getting set identifier from search`, e);
62
+ }
63
+ }
64
+ if (setIdentifieToSortBy) {
65
+ results.sort((c1, c2) => {
66
+ const c1SetNumber = c1.setIdentifiers.find((identifier) => identifier.includes(setIdentifieToSortBy))?.replace(setIdentifieToSortBy, "");
67
+ const c2SetNumber = c2.setIdentifiers.find((identifier) => identifier.includes(setIdentifieToSortBy))?.replace(setIdentifieToSortBy, "");
68
+ return c1SetNumber && c2SetNumber ? c1SetNumber.localeCompare(c2SetNumber) : -1;
69
+ });
70
+ } else {
71
+ results.sort(
72
+ (c1, c2) => c1.name === c2.name ? `${c1.pitch}`.localeCompare(`${c2.pitch}`) : c1.name.localeCompare(c2.name)
73
+ );
74
+ }
75
+ } else {
76
+ const nameMatches = [];
77
+ const nonMatches = [];
78
+ const potentialCardName = keywords.map((keyword2) => keyword2.toLowerCase().replace(PUNCTUATION, "")).join(" ");
79
+ for (const card of results) {
80
+ if (card.name.toLowerCase().replace(PUNCTUATION, "") === potentialCardName) {
81
+ nameMatches.push(card);
82
+ } else {
83
+ nonMatches.push(card);
84
+ }
85
+ }
86
+ results = [...nameMatches, ...nonMatches];
87
+ }
88
+ let searchResultsWithMatchingPrinting;
89
+ const {
90
+ artists,
91
+ isExpansionSlot,
92
+ foilings,
93
+ prints,
94
+ rarities,
95
+ releases,
96
+ treatments
97
+ } = attributes;
98
+ const shouldFindMatchingPrintings = artists.length > 0 || isExpansionSlot || foilings.length > 0 || prints.length > 0 || rarities.length > 0 || releases.length > 0 || treatments.length > 0;
99
+ if (shouldFindMatchingPrintings) {
100
+ searchResultsWithMatchingPrinting = results.map((card) => {
101
+ const matchingPrintings = card.printings.filter((printing) => {
102
+ const hasImage = !!printing.image;
103
+ const matchesArtist = artists.length === 0 || artists.some(
104
+ (attributeArtist) => printing.artists.find(
105
+ (artist) => artist.replace(PUNCTUATION, "").toLowerCase().includes(attributeArtist)
106
+ )
107
+ );
108
+ const matchesExpansionSlot = !isExpansionSlot || isExpansionSlot === printing.isExpansionSlot;
109
+ const matchesFoiling = foilings.length === 0 || foilings.includes(printing.foiling);
110
+ const matchesPrint = prints.length === 0 || prints.some(
111
+ (print) => printing.identifier.includes(print.toUpperCase())
112
+ );
113
+ const matchesRarity = rarities.length === 0 || rarities.includes(printing.rarity);
114
+ const matchesReleases = releases.length === 0 || releases.includes(printing.set);
115
+ const matchesTreatment = treatments.length === 0 || printing.treatments?.some(
116
+ (treatment) => treatments.includes(treatment)
117
+ );
118
+ const printMatches = hasImage && matchesArtist && matchesExpansionSlot && matchesFoiling && matchesPrint && matchesRarity && matchesReleases && matchesTreatment;
119
+ return printMatches;
120
+ });
121
+ return {
122
+ ...card,
123
+ matchingPrintings
124
+ };
125
+ });
126
+ }
127
+ const searchResults = searchResultsWithMatchingPrinting?.length > 0 ? searchResultsWithMatchingPrinting : results;
128
+ return {
129
+ appliedFilters,
130
+ attributes,
131
+ keywords,
132
+ searchResults
133
+ };
134
+ };
135
+ const searchOptions = {
136
+ getFn: (obj, path) => {
137
+ const value = Fuse.config.getFn(obj, path);
138
+ if (!value) {
139
+ return value;
140
+ } else if (Array.isArray(value)) {
141
+ return value.map(
142
+ (val) => getNormalizedText(val.replace(PUNCTUATION, ""))
143
+ );
144
+ } else {
145
+ return getNormalizedText(value).replace(PUNCTUATION, "");
146
+ }
147
+ },
148
+ ignoreLocation: true,
149
+ includeScore: true,
150
+ keys: [
151
+ { name: "name", weight: 10 },
152
+ { name: "functionalText", weight: 6 },
153
+ { name: "shorthands", weight: 4 },
154
+ { name: "setIdentifiers", weight: 2 },
155
+ { name: "traits", weight: 4 },
156
+ { name: "typeText", weight: 6 }
157
+ ],
158
+ threshold: 0.15,
159
+ useExtendedSearch: true
160
+ };
161
+ this.additionalHeroes = additionalHeroes;
162
+ this.additionalSets = additionalSets;
163
+ this.cards = [...cards];
164
+ this.debug = debug;
165
+ this.fuse = new Fuse([...cards], searchOptions);
166
+ }
167
+ }
168
+ var search_default = Search;
169
+ const filterCard = (card, appliedFilters) => {
170
+ let doesCardMatchAllRequiredFilters = true;
171
+ let doesCardMatchAnyOptionalFilters = false;
172
+ for (const appliedFilter of appliedFilters) {
173
+ const isOptional = appliedFilter.isOptional;
174
+ const { isNumber, isString, isArray, isBoolean } = appliedFilter.filterToPropertyMapping;
175
+ if (isNumber) {
176
+ const cardMatchesNumericFilter = getDoesCardMatchNumericFilter(
177
+ card,
178
+ appliedFilter
179
+ );
180
+ if (isOptional) {
181
+ if (cardMatchesNumericFilter) {
182
+ doesCardMatchAnyOptionalFilters = true;
183
+ }
184
+ } else {
185
+ doesCardMatchAllRequiredFilters = doesCardMatchAllRequiredFilters && cardMatchesNumericFilter;
186
+ }
187
+ } else if (isString) {
188
+ const cardMatchesStringFilter = getDoesCardMatchStringFilter(
189
+ card,
190
+ appliedFilter
191
+ );
192
+ if (isOptional) {
193
+ if (cardMatchesStringFilter) {
194
+ doesCardMatchAnyOptionalFilters = true;
195
+ }
196
+ } else {
197
+ doesCardMatchAllRequiredFilters = doesCardMatchAllRequiredFilters && cardMatchesStringFilter;
198
+ }
199
+ } else if (isArray) {
200
+ const cardMatchesArrayFilter = getDoesCardMatchArrayFilter(
201
+ card,
202
+ appliedFilter,
203
+ appliedFilters
204
+ );
205
+ if (isOptional) {
206
+ if (cardMatchesArrayFilter) {
207
+ doesCardMatchAnyOptionalFilters = true;
208
+ }
209
+ } else {
210
+ doesCardMatchAllRequiredFilters = doesCardMatchAllRequiredFilters && cardMatchesArrayFilter;
211
+ }
212
+ } else if (isBoolean) {
213
+ const cardMatchesBooleanFilter = getDoesCardMatchBooleanFilter(
214
+ card,
215
+ appliedFilter
216
+ );
217
+ if (isOptional) {
218
+ if (cardMatchesBooleanFilter) {
219
+ doesCardMatchAnyOptionalFilters = true;
220
+ }
221
+ } else {
222
+ doesCardMatchAllRequiredFilters = doesCardMatchAllRequiredFilters && cardMatchesBooleanFilter;
223
+ }
224
+ }
225
+ }
226
+ return doesCardMatchAllRequiredFilters;
227
+ };
228
+ const getDoesCardMatchNumericFilter = (card, filter) => {
229
+ if (!doesFilterMatchCardType(filter, card)) {
230
+ return true;
231
+ } else {
232
+ const {
233
+ values,
234
+ modifier,
235
+ isExcluded: excluded,
236
+ filterToPropertyMapping: { partialMatch }
237
+ } = filter;
238
+ let cardValue = getCardValue(card, filter);
239
+ if (cardValue != null && !isNaN(cardValue)) {
240
+ cardValue = parseInt(cardValue);
241
+ if (modifier) {
242
+ switch (modifier) {
243
+ case ">=":
244
+ const isGreatherThanOrEqualTo = values?.some(
245
+ (filterValue) => cardValue >= parseInt(filterValue)
246
+ );
247
+ return excluded ? !isGreatherThanOrEqualTo : isGreatherThanOrEqualTo;
248
+ case ">":
249
+ const isGreatherThan = values?.some(
250
+ (filterValue) => cardValue > parseInt(filterValue)
251
+ );
252
+ return excluded ? !isGreatherThan : isGreatherThan;
253
+ case "<=":
254
+ const isLessThanOrEqualTo = values?.some(
255
+ (filterValue) => cardValue <= parseInt(filterValue)
256
+ );
257
+ return excluded ? !isLessThanOrEqualTo : isLessThanOrEqualTo;
258
+ case "<":
259
+ const isLessThan = values?.some(
260
+ (filterValue) => cardValue < parseInt(filterValue)
261
+ );
262
+ return excluded ? !isLessThan : isLessThan;
263
+ default:
264
+ return false;
265
+ }
266
+ } else {
267
+ const isEqualTo = values?.some(
268
+ (filterValue) => cardValue === parseInt(filterValue)
269
+ );
270
+ return excluded ? !isEqualTo : isEqualTo;
271
+ }
272
+ } else {
273
+ const cardSpecialValue = getCardSpecialValue(card, filter)?.toLowerCase();
274
+ const isMatch = partialMatch ? values?.some((filterValue) => cardSpecialValue?.includes(filterValue)) : values?.some((filterValue) => cardSpecialValue === filterValue);
275
+ return excluded ? !isMatch : isMatch;
276
+ }
277
+ }
278
+ };
279
+ const getDoesCardMatchStringFilter = (card, filter) => {
280
+ if (!doesFilterMatchCardType(filter, card)) {
281
+ return true;
282
+ } else {
283
+ const {
284
+ values,
285
+ isAnd,
286
+ isExcluded: excluded,
287
+ filterToPropertyMapping: { partialMatch }
288
+ } = filter;
289
+ const cardValue = getCardValue(card, filter)?.replaceAll(
290
+ PUNCTUATION,
291
+ ""
292
+ );
293
+ if (partialMatch) {
294
+ const isPartialMatch = isAnd ? values?.every(
295
+ (filterValue) => cardValue?.toLowerCase().includes(filterValue)
296
+ ) : values?.some(
297
+ (filterValue) => cardValue?.toLowerCase().includes(filterValue)
298
+ );
299
+ return excluded ? !isPartialMatch : isPartialMatch;
300
+ } else {
301
+ const isFullMatch = isAnd ? values?.every(
302
+ (filterValue) => cardValue?.toLowerCase() === filterValue
303
+ ) : values?.some(
304
+ (filterValue) => cardValue?.toLowerCase() === filterValue
305
+ );
306
+ return excluded ? !isFullMatch : isFullMatch;
307
+ }
308
+ }
309
+ };
310
+ const getDoesCardMatchArrayFilter = (card, filter, filters) => {
311
+ if (!doesFilterMatchCardType(filter, card)) {
312
+ return true;
313
+ } else {
314
+ const {
315
+ values,
316
+ isAnd,
317
+ isExcluded,
318
+ filterToPropertyMapping: { partialMatch }
319
+ } = filter;
320
+ const cardValues = getCardValues(card, filter, filters).map(
321
+ (value) => value?.replaceAll(PUNCTUATION, "")
322
+ );
323
+ if (partialMatch) {
324
+ const isPartialMatch = isAnd ? values.every(
325
+ (filterValue) => cardValues?.some(
326
+ (cardValue) => cardValue?.toLowerCase().includes(filterValue)
327
+ )
328
+ ) : values.some(
329
+ (filterValue) => cardValues?.some(
330
+ (cardValue) => cardValue?.toLowerCase().includes(filterValue)
331
+ )
332
+ );
333
+ const noValues = cardValues.length === 0;
334
+ return isExcluded ? !isPartialMatch || noValues : isPartialMatch;
335
+ } else {
336
+ const isFullMatch = isAnd ? values.every(
337
+ (filterValue) => cardValues?.some(
338
+ (cardValue) => cardValue?.toLowerCase() === filterValue
339
+ )
340
+ ) : values.some(
341
+ (filterValue) => cardValues?.some(
342
+ (cardValue) => cardValue?.toLowerCase() === filterValue
343
+ )
344
+ );
345
+ return isExcluded ? !isFullMatch : isFullMatch;
346
+ }
347
+ }
348
+ };
349
+ const getDoesCardMatchBooleanFilter = (card, filter) => {
350
+ if (!doesFilterMatchCardType(filter, card)) {
351
+ return true;
352
+ } else {
353
+ const { isExcluded } = filter;
354
+ const cardValue = getCardValue(card, filter);
355
+ return isExcluded ? !cardValue : cardValue;
356
+ }
357
+ };
358
+ const getCardValue = (card, appliedFilter) => {
359
+ const { filterToPropertyMapping } = appliedFilter;
360
+ return card[filterToPropertyMapping.property];
361
+ };
362
+ const getCardValues = (card, filter, filters) => {
363
+ const {
364
+ filterToPropertyMapping: {
365
+ isNestedPropertyArray,
366
+ nestedProperty,
367
+ property
368
+ }
369
+ } = filter;
370
+ const propertyValues = card[property] || [];
371
+ let values = [];
372
+ const cardHasLegalOverrides = Object.keys(card.legalOverrides || {}).length > 0;
373
+ const isCheckingForLegalHeroes = filter.filterToPropertyMapping.property === FilterProperty.LegalHeroes;
374
+ const anotherFilterForLegalFormat = filters.find(
375
+ ({ filterToPropertyMapping }) => filterToPropertyMapping.property === FilterProperty.LegalFormats
376
+ );
377
+ const shouldCheckForLegalOverrides = cardHasLegalOverrides && isCheckingForLegalHeroes && !!anotherFilterForLegalFormat;
378
+ if (shouldCheckForLegalOverrides) {
379
+ const valuesSet = /* @__PURE__ */ new Set();
380
+ for (const { format, heroes } of card.legalOverrides || []) {
381
+ if (anotherFilterForLegalFormat.values.includes(format.toLowerCase())) {
382
+ for (const hero of heroes) {
383
+ valuesSet.add(hero);
384
+ }
385
+ }
386
+ }
387
+ values = Array.from(valuesSet);
388
+ }
389
+ if (values.length === 0) {
390
+ if (nestedProperty) {
391
+ const valuesSet = /* @__PURE__ */ new Set();
392
+ for (const rawValue of propertyValues) {
393
+ if (isNestedPropertyArray) {
394
+ const rawValues = rawValue[nestedProperty] || [];
395
+ for (const value of rawValues) {
396
+ valuesSet.add(value);
397
+ }
398
+ } else {
399
+ const value = rawValue[nestedProperty];
400
+ if (value) {
401
+ valuesSet.add(value);
402
+ }
403
+ }
404
+ }
405
+ values = Array.from(valuesSet);
406
+ } else {
407
+ values = propertyValues;
408
+ }
409
+ }
410
+ return values;
411
+ };
412
+ const getCardSpecialValue = (card, appliedFilter) => {
413
+ const { filterToPropertyMapping } = appliedFilter;
414
+ return card[filterToPropertyMapping.specialProperty];
415
+ };
416
+ const doesFilterMatchCardType = ({ cardTypes }, { types, subtypes }) => !cardTypes || cardTypes?.some(
417
+ (cardType) => types.map((type) => type.toLowerCase()).includes(cardType.toLowerCase()) || subtypes.map((subtype) => subtype.toLowerCase()).includes(cardType.toLowerCase())
418
+ );
419
+ export {
420
+ search_default as default,
421
+ filterCard
422
+ };
@@ -0,0 +1,174 @@
1
+ import { Keyword, Subtype, Type } from "@flesh-and-blood/types";
2
+ const shorthands = [
3
+ {
4
+ description: "Attack actions",
5
+ expanded: ["st:attack"],
6
+ filters: {
7
+ subtypes: [Subtype.Attack]
8
+ },
9
+ isCardProperty: false,
10
+ shorthands: ["AA"]
11
+ },
12
+ {
13
+ description: "Arcane barrier",
14
+ expanded: ['k:"arcane barrier"'],
15
+ filters: {
16
+ keywords: [Keyword.ArcaneBarrier]
17
+ },
18
+ isCardProperty: false,
19
+ shorthands: ["AB"]
20
+ },
21
+ {
22
+ description: "Attack reactions",
23
+ expanded: ['t:"attack reaction"'],
24
+ filters: {
25
+ types: [Type.AttackReaction]
26
+ },
27
+ isCardProperty: false,
28
+ shorthands: ["AR"]
29
+ },
30
+ {
31
+ description: "Defense reactions",
32
+ expanded: ['t:"defense reaction"'],
33
+ filters: {
34
+ types: [Type.DefenseReaction]
35
+ },
36
+ isCardProperty: false,
37
+ shorthands: ["DR"]
38
+ },
39
+ // {
40
+ // description: "Flick daggers",
41
+ // expanded: ["dagger you control deal 1 damage"],
42
+ // filters: {
43
+ // functionalText: "dagger you control deal 1 damage",
44
+ // },
45
+ // isCardProperty: true,
46
+ // shorthands: ["Flick", "Hurl", "Throw"],
47
+ // },
48
+ {
49
+ description: "Gain life",
50
+ expanded: ["gain {h}"],
51
+ filters: {
52
+ functionalText: "gain {h}"
53
+ },
54
+ isCardProperty: false,
55
+ shorthands: ["Gain life", "Gains life"]
56
+ },
57
+ {
58
+ description: "Go again",
59
+ expanded: ['k:"go again"'],
60
+ filters: {
61
+ keywords: [Keyword.GoAgain]
62
+ },
63
+ isCardProperty: false,
64
+ shorthands: ["GA"]
65
+ },
66
+ {
67
+ description: "Non-attack actions",
68
+ expanded: ["t:action", "st:non-attack"],
69
+ filters: {
70
+ subtypes: [Subtype.NonAttack],
71
+ types: [Type.Action]
72
+ },
73
+ isCardProperty: false,
74
+ shorthands: ["NAA"]
75
+ },
76
+ {
77
+ description: "Plus defense",
78
+ expanded: ["+ {d}"],
79
+ filters: {
80
+ functionalText: "+ {d}"
81
+ },
82
+ isCardProperty: false,
83
+ shorthands: [
84
+ "Pump defense",
85
+ "Pumps defense",
86
+ "Buff defense",
87
+ "Buffs defense"
88
+ ]
89
+ },
90
+ // {
91
+ // description: "Plus power",
92
+ // expanded: ["+ {p}"],
93
+ // filters: {
94
+ // functionalText: "+ {p}",
95
+ // },
96
+ // isCardProperty: false,
97
+ // shorthands: [
98
+ // "Pumps",
99
+ // "Pump",
100
+ // "Buff",
101
+ // "Buffs",
102
+ // "Pump attack",
103
+ // "Pump attacks",
104
+ // "Pumps attack",
105
+ // "Pumps attacks",
106
+ // "Buff attack",
107
+ // "Buff attacks",
108
+ // "Buffs attack",
109
+ // "Buffs attacks",
110
+ // "Pump power",
111
+ // "Pumps power",
112
+ // "Buff power",
113
+ // "Buffs power",
114
+ // ],
115
+ // },
116
+ // {
117
+ // description: "Poppers",
118
+ // expanded: ["!c:illusionist", "st:attack", "pwr:>=6", "def:>=0"],
119
+ // filters: {
120
+ // defenseGreaterThanOrEqualTo: 0,
121
+ // notClass: [Class.Illusionist],
122
+ // powerGreaterThanOrEqualTo: 6,
123
+ // subtypes: [Subtype.Attack],
124
+ // },
125
+ // isCardProperty: false,
126
+ // helper:
127
+ // '6+ power non-Illusionist attacks that can "pop" phantasm attacks when defending',
128
+ // shorthands: ["Poppers", "Popper"],
129
+ // },
130
+ {
131
+ description: "Spellvoid",
132
+ expanded: ['k:"spellvoid"'],
133
+ filters: {
134
+ keywords: [Keyword.Spellvoid]
135
+ },
136
+ isCardProperty: false,
137
+ shorthands: ["SV"]
138
+ }
139
+ // {
140
+ // description: "Tap",
141
+ // expanded: ["{t}"],
142
+ // filters: {
143
+ // functionalText: "{t}",
144
+ // },
145
+ // isCardProperty: true,
146
+ // shorthands: ["Tap"],
147
+ // },
148
+ // {
149
+ // description: "Untap",
150
+ // expanded: ["{u}"],
151
+ // filters: {
152
+ // functionalText: "{u}",
153
+ // },
154
+ // isCardProperty: true,
155
+ // shorthands: ["Untap"],
156
+ // },
157
+ ];
158
+ const multiWordShorthands = shorthands.filter(
159
+ ({ shorthands: shorthands2 }) => shorthands2.some((shorthand) => shorthand.includes(" "))
160
+ ).map((shorthand) => ({
161
+ ...shorthand,
162
+ shorthands: shorthand.shorthands.filter((shorthand2) => shorthand2.includes(" ")).map((shorthand2) => shorthand2.toLowerCase()).sort((s1, s2) => s2.length - s1.length)
163
+ }));
164
+ const singleWordShorthands = shorthands.filter(
165
+ ({ shorthands: shorthands2 }) => shorthands2.some((shorthand) => !shorthand.includes(" "))
166
+ ).map((shorthand) => ({
167
+ ...shorthand,
168
+ shorthands: shorthand.shorthands.filter((shorthand2) => !shorthand2.includes(" ")).map((shorthand2) => shorthand2.toLowerCase()).sort((s1, s2) => s2.length - s1.length)
169
+ }));
170
+ export {
171
+ multiWordShorthands,
172
+ shorthands,
173
+ singleWordShorthands
174
+ };
package/package.json CHANGED
@@ -1,23 +1,50 @@
1
1
  {
2
2
  "name": "@flesh-and-blood/search",
3
3
  "description": "TypeScript search engine for Flesh and Blood cards",
4
- "version": "3.9.13",
5
- "main": "dist/index.js",
4
+ "version": "4.0.1",
5
+ "type": "module",
6
+ "sideEffects": false,
7
+ "main": "dist/index.cjs",
8
+ "module": "dist/index.js",
6
9
  "types": "dist/index.d.ts",
10
+ "exports": {
11
+ ".": {
12
+ "types": "./dist/index.d.ts",
13
+ "import": "./dist/index.js",
14
+ "require": "./dist/index.cjs"
15
+ },
16
+ "./abbreviations": {
17
+ "types": "./dist/abbreviations.d.ts",
18
+ "import": "./dist/abbreviations.js"
19
+ },
20
+ "./shorthands": {
21
+ "types": "./dist/shorthands.d.ts",
22
+ "import": "./dist/shorthands.js"
23
+ },
24
+ "./memes": {
25
+ "types": "./dist/memes.d.ts",
26
+ "import": "./dist/memes.js"
27
+ }
28
+ },
7
29
  "scripts": {
8
30
  "prebuild": "rm -rf dist",
9
- "build": "esbuild src/index.ts --outdir=dist --external:*.test.ts --external:fab-cards --bundle --minify --platform=node --target=es6",
31
+ "build": "npm run build:esm && npm run build:cjs",
32
+ "build:esm": "esbuild src/*.ts --outdir=dist --format=esm --platform=neutral --target=es2020",
33
+ "build:cjs": "esbuild src/index.ts --outfile=dist/index.cjs --bundle --minify --format=cjs --platform=node --target=es2020 --external:@flesh-and-blood/types --external:fuse.js",
10
34
  "postbuild": "tsc --declaration && npm test",
11
35
  "test": "jest",
12
36
  "test:specific": "jest -t 'Matching printing from treatment'",
13
37
  "full": "npm i && npm run build"
14
38
  },
15
39
  "dependencies": {
16
- "@flesh-and-blood/types": "^3.9.7",
17
40
  "fuse.js": "^6.6.2"
18
41
  },
42
+ "peerDependencies": {
43
+ "@flesh-and-blood/types": "^4.0.0"
44
+ },
19
45
  "devDependencies": {
20
- "@flesh-and-blood/cards": "^3.9.13",
46
+ "@flesh-and-blood/cards": "^4.0.1",
47
+ "@flesh-and-blood/types": "^4.0.0",
21
48
  "@types/jest": "^29.5.11",
22
49
  "@types/node": "^20.10.5",
23
50
  "esbuild": "^0.19.10",
@@ -47,5 +74,5 @@
47
74
  "FAB",
48
75
  "FABTCG"
49
76
  ],
50
- "gitHead": "8511fb800f6a8284cc2b30fc0e2a36a57a87774a"
77
+ "gitHead": "6e26d78311495343773e20505fe804e509d255bc"
51
78
  }