gatsby-core-theme 44.15.2 → 44.16.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/CHANGELOG.md CHANGED
@@ -1,3 +1,39 @@
1
+ # [44.16.0](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/compare/v44.15.3...v44.16.0) (2026-02-26)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * guard toplists access in processTopListModule to prevent crash on undefined ([0fd53b3](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/0fd53b3f96cede6120838777707ae0a993284b43))
7
+ * include operators on game toplist ([fcaae16](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/fcaae16634f3dc8879f2818eb8e50fb14451a495))
8
+ * pass single operator for game toplist item ([181f031](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/181f031276fa7b16d3d58b8b240f754901f6270f))
9
+ * process game top list ([c7f494a](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/c7f494aefc29bb82c6c98dc013bdfe58a9befa9d))
10
+
11
+
12
+ ### Code Refactoring
13
+
14
+ * extract toplist helpers from modules.mjs into helpers/toplist.mjs ([3727ed8](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/3727ed863baa2cfaccdfecba8750ebc3dbbc19d8))
15
+ * process top list ([e2c4589](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/e2c45898b74b1412125464b4c230aa1be060ed32))
16
+
17
+
18
+ * Merge branch 'en-379-game-toplist' into 'master' ([5f8672c](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/5f8672cbcba7853bee36fa6aab68e0a41d2152f0))
19
+ * Merge remote-tracking branch 'origin' into en-379-game-toplist ([f6b2f05](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/f6b2f05c9c598f687af74c420d6ccee96eec3582))
20
+
21
+
22
+ ### Features
23
+
24
+ * process game toplist ([2f7944f](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/2f7944f612dd3e970726c0a5e82e5027e9360922))
25
+
26
+ ## [44.15.3](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/compare/v44.15.2...v44.15.3) (2026-02-26)
27
+
28
+
29
+ ### Bug Fixes
30
+
31
+ * add also meutimao ([cbe7293](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/cbe729308e6a84760e7f3b93213600f1a8c83968))
32
+ * improve the tracker type and make possible to edit for specific sites ([a3f2e17](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/a3f2e1776c8c1ce14a05fba06f375ad51117bdce))
33
+
34
+
35
+ * Merge branch 'tracker-type-built' into 'master' ([790c754](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/commit/790c7543bbd2532f5ab1cac6fd8d6f34b38f8461))
36
+
1
37
  ## [44.15.2](https://gitlab.com/g2m-gentoo/team-floyd/themes/gatsby-themes/compare/v44.15.1...v44.15.2) (2026-02-26)
2
38
 
3
39
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gatsby-core-theme",
3
- "version": "44.15.2",
3
+ "version": "44.16.0",
4
4
  "description": "Gatsby Theme NPM Package",
5
5
  "author": "",
6
6
  "license": "ISC",
@@ -0,0 +1,13 @@
1
+ export default {
2
+ 'odia.ig.com.br': {
3
+ 'casino': ['type', "[cassino]"],
4
+ 'sportsbook': ['type', "[esportes]"],
5
+ },
6
+ 'meutimao.com.br': {
7
+ 'casino': ['type', "[cassino]"],
8
+ 'sportsbook': ['type', "[esportes]"],
9
+ },
10
+ default: {
11
+ casino: ['type,', ''],
12
+ },
13
+ };
@@ -1,4 +1,5 @@
1
1
  import generatorsConstant from "../constants/generators.mjs";
2
+ import trackerTypePerSite from "../constants/trackerTypePerSite.mjs";
2
3
 
3
4
  export function generateTrackerLink(operator, trackerType, provider = false) {
4
5
  let defaultTrackerFormat = provider
@@ -8,11 +9,14 @@ export function generateTrackerLink(operator, trackerType, provider = false) {
8
9
  ? process.env.PROVIDER_TRACKER_LINK_FORMAT_NON_MAIN
9
10
  : process.env.TRACKER_LINK_FORMAT_NON_MAIN;
10
11
 
12
+ const replaceTrackerFormat = trackerTypePerSite[process.env.GATSBY_SITE_NAME] || trackerTypePerSite.default;
13
+
11
14
  if (defaultTrackerFormat && trackerFormat) {
12
- if (operator.type === "casino") {
13
- defaultTrackerFormat = defaultTrackerFormat.replace("type,", "");
14
- trackerFormat = trackerFormat.replace("type,", "");
15
+ if(replaceTrackerFormat?.[operator?.type]){
16
+ defaultTrackerFormat = defaultTrackerFormat.replace(replaceTrackerFormat[operator.type][0], replaceTrackerFormat[operator.type][1]);
17
+ trackerFormat = trackerFormat.replace(replaceTrackerFormat[operator.type][0], replaceTrackerFormat[operator.type][1]);
15
18
  }
19
+
16
20
  const linkFormatArray =
17
21
  trackerType === "main"
18
22
  ? defaultTrackerFormat.split(",")
@@ -31,6 +31,48 @@ describe("Generate Tracker Link Helper", () => {
31
31
  );
32
32
  expect(trackerLink).toEqual("/no/visit/bet365");
33
33
  });
34
+ test("sportsbook type is shown as-is for default site (non_main)", () => {
35
+ const trackerLink = generateTrackerLink(
36
+ { type: "sportsbook", short_name: "bet365" },
37
+ "non_main"
38
+ );
39
+ expect(trackerLink).toEqual("/no/visit/bet365/sportsbook/non_main");
40
+ });
41
+ });
42
+
43
+ describe("Generate Tracker Link Helper - Site Type Translations", () => {
44
+ const originalSiteName = process.env.GATSBY_SITE_NAME;
45
+
46
+ afterEach(() => {
47
+ process.env.GATSBY_SITE_NAME = originalSiteName;
48
+ });
49
+
50
+ test("casino type is translated for translated site (non_main)", () => {
51
+ process.env.GATSBY_SITE_NAME = "odia.ig.com.br";
52
+ const trackerLink = generateTrackerLink(
53
+ { type: "casino", short_name: "bet365" },
54
+ "non_main"
55
+ );
56
+ expect(trackerLink).toEqual("/no/visit/bet365/cassino/non_main");
57
+ });
58
+
59
+ test("sportsbook type is translated for translated site (non_main)", () => {
60
+ process.env.GATSBY_SITE_NAME = "odia.ig.com.br";
61
+ const trackerLink = generateTrackerLink(
62
+ { type: "sportsbook", short_name: "bet365" },
63
+ "non_main"
64
+ );
65
+ expect(trackerLink).toEqual("/no/visit/bet365/esportes/non_main");
66
+ });
67
+
68
+ test("main tracker link is unaffected by type translation", () => {
69
+ process.env.GATSBY_SITE_NAME = "odia.ig.com.br";
70
+ const trackerLink = generateTrackerLink(
71
+ { type: "casino", short_name: "bet365" },
72
+ "main"
73
+ );
74
+ expect(trackerLink).toEqual("/no/visit/bet365");
75
+ });
34
76
  });
35
77
 
36
78
  describe("Generate Placeholders String", () => {
@@ -0,0 +1,142 @@
1
+ /* eslint-disable camelcase */
2
+ /* eslint-disable import/no-extraneous-dependencies */
3
+ import loadash from "lodash/index.js";
4
+ import { stripDomainAndLeadingSlash } from "./path.mjs";
5
+ import { sanitizeOperatorData } from "../resolver/operators.mjs";
6
+ import { sanitizegameData } from "../resolver/games.mjs";
7
+ import buildToplistFilter from "../resolver/build-toplist-filter.mjs";
8
+
9
+ const { cloneDeep } = loadash;
10
+
11
+ /**
12
+ * @param {Object} item - Raw toplist item from DMS (operator or game)
13
+ * @param {Object|null} itemRelation - Resolved relation data for the item
14
+ * @param {Array<Object>} itemPages - Pages matching this relation
15
+ * @param {Object} ctx - Shared processing context
16
+ * @param {boolean} ctx.filterEnabled - Whether filter mode is active
17
+ * @param {Object} ctx.filters - Filter accumulator object
18
+ * @param {Object} ctx.data - Full relations data (payment methods, etc.)
19
+ * @param {Object|null} ctx.toplists - Toplists lookup map
20
+ * @param {string|undefined} ctx.toplistLabel - Label from the parent toplist item
21
+ * @returns {Object|null} Sanitized toplist item or null if no relation
22
+ */
23
+ export function processToplistItem(item, itemRelation, itemPages, ctx) {
24
+ if (!itemRelation) {
25
+ return null;
26
+ }
27
+
28
+ itemRelation.ribbons =
29
+ item.ribbon_ids && item.ribbon_ids.length === 0
30
+ ? itemRelation.ribbons
31
+ : item.ribbon_ids;
32
+
33
+ itemRelation.selling_points =
34
+ item.selling_points && item.selling_points.length === 0
35
+ ? itemRelation.selling_points
36
+ : item.selling_points;
37
+
38
+ itemRelation.updated_at = item.updated_at;
39
+ itemRelation.toplist_bonus = item.bonus_name;
40
+ itemRelation.toplist_item_tracker_name = item.tracker_name;
41
+
42
+ const reviewLink =
43
+ process.env.DMS_REVIEW_LINKS_ENABLED === "true"
44
+ ? stripDomainAndLeadingSlash(itemRelation?.review_link)
45
+ : itemPages[0]?.path;
46
+
47
+ const authorTitle = itemPages[0]?.author?.author_title;
48
+ const clone = item.game_id
49
+ ? sanitizegameData(cloneDeep(itemRelation), itemPages, ["operators"])
50
+ : sanitizeOperatorData(
51
+ cloneDeep(itemRelation),
52
+ itemPages,
53
+ ctx.data,
54
+ ctx.toplistLabel
55
+ );
56
+ const socialAuthorLinks = [
57
+ "facebook_profile",
58
+ "twitter_profile",
59
+ "instagram_profile",
60
+ "linkedin_profile",
61
+ ];
62
+
63
+ if (ctx.filterEnabled) {
64
+ buildToplistFilter(ctx.filters, clone);
65
+ }
66
+
67
+ return Object.assign(clone, {
68
+ review_link: reviewLink,
69
+ author_title: authorTitle,
70
+ author_same_as:
71
+ itemPages[0]?.author &&
72
+ socialAuthorLinks
73
+ .map((socialLink) => itemPages[0]?.author?.[socialLink])
74
+ .filter((socialLink) => socialLink),
75
+ });
76
+ }
77
+
78
+ /**
79
+ * @param {Object} item - Raw operator toplist item with operator_id
80
+ * @param {Object} ctx - Shared processing context
81
+ * @param {Object} ctx.relations - All relations keyed by type (operator, game, etc.)
82
+ * @param {Object} ctx.pages - Pages grouped by type
83
+ * @param {string|undefined} ctx.type - Operator type filter (e.g. "casino")
84
+ * @param {string} ctx.market - Market short code
85
+ * @param {boolean} ctx.filterEnabled
86
+ * @param {Object} ctx.filters
87
+ * @param {Object} ctx.data
88
+ * @param {Object|null} ctx.toplists
89
+ * @param {string|undefined} ctx.toplistLabel
90
+ * @returns {Object|null} Sanitized operator item or null
91
+ */
92
+ export function processOperatorToplist(item, ctx) {
93
+ const operatorRelation = cloneDeep(
94
+ Object.values(ctx.relations.operator).find(
95
+ (operator) =>
96
+ operator.operator_id === (item.operator_id || item.id) &&
97
+ operator.market === ctx.market &&
98
+ (ctx.type ? ctx.type === operator.type : true)
99
+ )
100
+ );
101
+
102
+ const operatorPage =
103
+ ctx.pages?.operator && operatorRelation
104
+ ? ctx.pages.operator.filter(
105
+ (page) =>
106
+ page.relation?.operator_id === operatorRelation.operator_id &&
107
+ page.relation?.type === operatorRelation.type
108
+ )
109
+ : [];
110
+
111
+ return processToplistItem(item, operatorRelation, operatorPage, ctx);
112
+ }
113
+
114
+ /**
115
+ * @param {Object} item - Raw game toplist item with game_id and operators array
116
+ * @param {Object} ctx - Same context as processOperatorToplist
117
+ * @returns {Object|null} Sanitized game item or null
118
+ */
119
+ export function processGameToplist(item, ctx) {
120
+ const relation = cloneDeep(
121
+ Object.values(ctx.relations.game).find(
122
+ (game) => game.game_id === item.game_id
123
+ )
124
+ );
125
+ const gameOperators = (item.operators ?? [])
126
+ .map((operator) => processOperatorToplist(operator, ctx))
127
+ .filter(Boolean);
128
+ const gamePage = ctx.pages?.game
129
+ ? ctx.pages.game.filter(
130
+ (page) =>
131
+ page.relation?.game_id === relation?.game_id &&
132
+ page.relation?.market === ctx.market
133
+ )
134
+ : [];
135
+
136
+ return processToplistItem(
137
+ item,
138
+ { ...relation, operators: gameOperators?.[0] },
139
+ gamePage,
140
+ ctx
141
+ );
142
+ }
@@ -0,0 +1,288 @@
1
+ import loadash from "lodash/index.js";
2
+ import {
3
+ processToplistItem,
4
+ processOperatorToplist,
5
+ processGameToplist,
6
+ } from "./toplist.mjs";
7
+ import { relationData } from "~tests/factories/modules/toplist.factory";
8
+
9
+ const { cloneDeep } = loadash;
10
+
11
+ jest.mock("../resolver/build-toplist-filter.mjs", () => ({
12
+ __esModule: true,
13
+ default: jest.fn(),
14
+ }));
15
+ // eslint-disable-next-line import/first
16
+ import buildToplistFilter from "../resolver/build-toplist-filter.mjs";
17
+
18
+ describe("processToplistItem", () => {
19
+ const baseCtx = {
20
+ filterEnabled: false,
21
+ filters: {},
22
+ data: relationData,
23
+ toplists: null,
24
+ toplistLabel: undefined,
25
+ };
26
+
27
+ test("returns null when itemRelation is null", () => {
28
+ const result = processToplistItem({ operator_id: 1 }, null, [], baseCtx);
29
+ expect(result).toBeNull();
30
+ });
31
+
32
+ test("returns null when itemRelation is undefined", () => {
33
+ const result = processToplistItem(
34
+ { operator_id: 1 },
35
+ undefined,
36
+ [],
37
+ baseCtx
38
+ );
39
+ expect(result).toBeNull();
40
+ });
41
+
42
+ test("returns sanitized operator item with correct fields", () => {
43
+ const item = {
44
+ operator_id: 6342,
45
+ selling_points: ["classicslots", "bitcoin", "bingo"],
46
+ updated_at: "2025-01-14 11:04:49",
47
+ bonus_name: "Welcome Bonus",
48
+ tracker_name: "main_tracker",
49
+ };
50
+ const itemRelation = cloneDeep(relationData.operator[6342]);
51
+ const pages = [{ path: "en/slotum", author: { author_title: "John" } }];
52
+
53
+ const result = processToplistItem(item, itemRelation, pages, baseCtx);
54
+
55
+ expect(result).not.toBeNull();
56
+ expect(result.review_link).toBe("en/slotum");
57
+ expect(result.author_title).toBe("John");
58
+ expect(result.short_name).toBe("slotum");
59
+ });
60
+
61
+ test("preserves original ribbons when ribbon_ids is empty array", () => {
62
+ const originalRibbons = [1, 2, 3];
63
+ const item = {
64
+ operator_id: 6342,
65
+ ribbon_ids: [],
66
+ updated_at: "2025-01-14",
67
+ };
68
+ const itemRelation = cloneDeep(relationData.operator[6342]);
69
+ itemRelation.ribbons = originalRibbons;
70
+
71
+ processToplistItem(item, itemRelation, [], baseCtx);
72
+
73
+ expect(itemRelation.ribbons).toEqual(originalRibbons);
74
+ });
75
+
76
+ test("overrides ribbons when ribbon_ids has values", () => {
77
+ const item = {
78
+ operator_id: 6342,
79
+ ribbon_ids: [10, 20],
80
+ updated_at: "2025-01-14",
81
+ };
82
+ const itemRelation = cloneDeep(relationData.operator[6342]);
83
+ itemRelation.ribbons = [1, 2, 3];
84
+
85
+ processToplistItem(item, itemRelation, [], baseCtx);
86
+
87
+ expect(itemRelation.ribbons).toEqual([10, 20]);
88
+ });
89
+
90
+ test("preserves original selling_points when selling_points is empty array", () => {
91
+ const originalSP = ["point1", "point2"];
92
+ const item = {
93
+ operator_id: 6342,
94
+ selling_points: [],
95
+ updated_at: "2025-01-14",
96
+ };
97
+ const itemRelation = cloneDeep(relationData.operator[6342]);
98
+ itemRelation.selling_points = originalSP;
99
+
100
+ processToplistItem(item, itemRelation, [], baseCtx);
101
+
102
+ expect(itemRelation.selling_points).toEqual(originalSP);
103
+ });
104
+
105
+ test("calls buildToplistFilter when filterEnabled is true", () => {
106
+ buildToplistFilter.mockClear();
107
+ const ctx = { ...baseCtx, filterEnabled: true, filters: { test: true } };
108
+ const item = {
109
+ operator_id: 6342,
110
+ selling_points: ["a"],
111
+ updated_at: "2025-01-14",
112
+ };
113
+ const itemRelation = cloneDeep(relationData.operator[6342]);
114
+
115
+ processToplistItem(item, itemRelation, [], ctx);
116
+
117
+ expect(buildToplistFilter).toHaveBeenCalledTimes(1);
118
+ expect(buildToplistFilter).toHaveBeenCalledWith(
119
+ ctx.filters,
120
+ expect.any(Object)
121
+ );
122
+ });
123
+
124
+ test("does not call buildToplistFilter when filterEnabled is false", () => {
125
+ buildToplistFilter.mockClear();
126
+ const item = {
127
+ operator_id: 6342,
128
+ selling_points: ["a"],
129
+ updated_at: "2025-01-14",
130
+ };
131
+ const itemRelation = cloneDeep(relationData.operator[6342]);
132
+
133
+ processToplistItem(item, itemRelation, [], baseCtx);
134
+
135
+ expect(buildToplistFilter).not.toHaveBeenCalled();
136
+ });
137
+ });
138
+
139
+ describe("processOperatorToplist", () => {
140
+ const baseCtx = {
141
+ relations: relationData,
142
+ pages: undefined,
143
+ type: "casino",
144
+ market: undefined,
145
+ filterEnabled: false,
146
+ filters: {},
147
+ data: relationData,
148
+ toplists: null,
149
+ toplistLabel: undefined,
150
+ };
151
+
152
+ test("finds correct operator relation by operator_id and type", () => {
153
+ const item = {
154
+ operator_id: 6342,
155
+ selling_points: ["a", "b", "c"],
156
+ updated_at: "2025-01-14",
157
+ };
158
+
159
+ const result = processOperatorToplist(item, baseCtx);
160
+
161
+ expect(result).not.toBeNull();
162
+ expect(result.short_name).toBe("slotum");
163
+ });
164
+
165
+ test("returns null when no matching operator relation exists", () => {
166
+ const item = {
167
+ operator_id: 99999,
168
+ updated_at: "2025-01-14",
169
+ };
170
+
171
+ const result = processOperatorToplist(item, baseCtx);
172
+
173
+ expect(result).toBeNull();
174
+ });
175
+
176
+ test("falls back to item.id when item.operator_id is missing", () => {
177
+ const item = {
178
+ id: 6342,
179
+ selling_points: ["a"],
180
+ updated_at: "2025-01-14",
181
+ };
182
+
183
+ const result = processOperatorToplist(item, baseCtx);
184
+
185
+ expect(result).not.toBeNull();
186
+ expect(result.short_name).toBe("slotum");
187
+ });
188
+
189
+ test("matches operator pages by operator_id and type", () => {
190
+ const ctx = {
191
+ ...baseCtx,
192
+ pages: {
193
+ operator: [
194
+ {
195
+ relation_id: 6342,
196
+ path: "en/slotum",
197
+ relation: { operator_id: 6342, type: "casino" },
198
+ author: { author_title: "Editor" },
199
+ },
200
+ ],
201
+ },
202
+ };
203
+ const item = {
204
+ operator_id: 6342,
205
+ selling_points: ["a"],
206
+ updated_at: "2025-01-14",
207
+ };
208
+
209
+ const result = processOperatorToplist(item, ctx);
210
+
211
+ expect(result.review_link).toBe("en/slotum");
212
+ expect(result.author_title).toBe("Editor");
213
+ });
214
+ });
215
+
216
+ describe("processGameToplist", () => {
217
+ const gameRelations = {
218
+ ...relationData,
219
+ game: {
220
+ 100: {
221
+ game_id: 100,
222
+ name: "Test Slot",
223
+ short_name: "test-slot",
224
+ market: "en_za",
225
+ },
226
+ },
227
+ };
228
+
229
+ const baseCtx = {
230
+ relations: gameRelations,
231
+ pages: undefined,
232
+ type: "casino",
233
+ market: "en_za",
234
+ filterEnabled: false,
235
+ filters: {},
236
+ data: gameRelations,
237
+ toplists: null,
238
+ toplistLabel: undefined,
239
+ };
240
+
241
+ test("processes game operators through processOperatorToplist", () => {
242
+ const item = {
243
+ game_id: 100,
244
+ operators: [
245
+ { operator_id: 6342, selling_points: ["a"], updated_at: "2025-01-14" },
246
+ ],
247
+ updated_at: "2025-01-14",
248
+ };
249
+
250
+ const result = processGameToplist(item, baseCtx);
251
+
252
+ expect(result).not.toBeNull();
253
+ });
254
+
255
+ test("returns object with undefined fields when game relation not found", () => {
256
+ const item = {
257
+ game_id: 99999,
258
+ operators: [],
259
+ updated_at: "2025-01-14",
260
+ };
261
+
262
+ const result = processGameToplist(item, baseCtx);
263
+
264
+ // When relation is not found, the spread of undefined still creates an object
265
+ // so processToplistItem receives a non-null itemRelation
266
+ expect(result).toBeDefined();
267
+ expect(result.operators).toBeUndefined();
268
+ });
269
+
270
+ test("attaches first processed operator to the game relation", () => {
271
+ const item = {
272
+ game_id: 100,
273
+ operators: [
274
+ { operator_id: 6342, selling_points: ["a"], updated_at: "2025-01-14" },
275
+ { operator_id: 6343, selling_points: ["b"], updated_at: "2025-01-14" },
276
+ ],
277
+ updated_at: "2025-01-14",
278
+ };
279
+
280
+ const result = processGameToplist(item, baseCtx);
281
+
282
+ expect(result).not.toBeNull();
283
+ // The first processed operator should be attached as the operators field
284
+ if (result.operators) {
285
+ expect(result.operators.short_name).toBeDefined();
286
+ }
287
+ });
288
+ });
@@ -2,7 +2,7 @@
2
2
  /* eslint-disable no-underscore-dangle */
3
3
  import { generateTrackerLink } from "./generators.mjs";
4
4
  import { stripSuffixSlash } from "./strings.mjs";
5
- import { getCookie } from "./cookies.js";
5
+ import { getCookie } from "./cookies.mjs";
6
6
 
7
7
  export function getTrackerName(operator, page, path) {
8
8
  const trackerLinks = operator ? Object.keys(operator.links) : [];
@@ -4,7 +4,7 @@
4
4
  /* eslint-disable import/no-extraneous-dependencies */
5
5
  import loadash from "lodash/index.js";
6
6
  import { generatePlaceholderString } from "../helpers/generators.mjs";
7
- import { stripDomainAndLeadingSlash } from "../helpers/path.mjs";
7
+ import { processOperatorToplist, processGameToplist } from "../helpers/toplist.mjs";
8
8
  import {
9
9
  clonePageForCards,
10
10
  groupBy,
@@ -19,7 +19,6 @@ import {
19
19
  getModuleTitle,
20
20
  trailingSlash,
21
21
  } from "../helpers/getters.mjs";
22
- import buildToplistFilter from "./build-toplist-filter.mjs";
23
22
 
24
23
  const pagesGroupedByTemplateId = [];
25
24
  const cardItems = {};
@@ -375,100 +374,56 @@ export function processTopListModule(
375
374
  payout_rate: {},
376
375
  licenses: {},
377
376
  };
378
-
379
377
  module.items = module.items.map((listItem) => {
380
378
  const { type } = listItem;
381
379
  const showLoadMore = +listItem.show_load_more;
382
380
  const itemsCount = +listItem.num_items_initial_load;
383
- if (listItem.id && toplists && toplists[listItem.id.toString()]) {
384
- listItem.market = toplists[listItem.id].market?.short_code;
385
- listItem.items = toplists[listItem.id].items;
386
- listItem.one_liner = toplists[listItem.id].one_liner;
387
- listItem.tracker = toplists[listItem.id].tracker;
381
+ const toplistItem = toplists && listItem.id
382
+ ? toplists[listItem.id.toString()] ||
383
+ toplists[`g_${listItem.id.toString()}`]
384
+ : undefined;
385
+ if (toplistItem) {
386
+ listItem.market = toplistItem.market?.short_code;
387
+ listItem.items = toplistItem.items;
388
+ listItem.one_liner = toplistItem.one_liner;
389
+ listItem.tracker = toplistItem.tracker;
388
390
  }
389
-
390
391
  if (!showLoadMore && itemsCount) {
391
392
  listItem.items = listItem.items?.slice(0, itemsCount);
392
393
  }
394
+ const ctx = {
395
+ relations,
396
+ pages,
397
+ type,
398
+ market: listItem.market,
399
+ filterEnabled,
400
+ filters,
401
+ data,
402
+ toplists,
403
+ toplistLabel: toplists && toplistItem?.label,
404
+ };
393
405
 
406
+ // build top list
394
407
  listItem.items = listItem.items
395
408
  ? listItem.items
396
- .map((item) => {
397
- const operatorRelation = cloneDeep(
409
+ .filter(
410
+ (item) =>
398
411
  Object.values(relations.operator).find(
399
412
  (operator) =>
400
413
  operator.operator_id === item.operator_id &&
401
414
  operator.market === listItem.market &&
402
415
  type === operator.type
416
+ ) ||
417
+ Object.values(relations.game).find(
418
+ (game) => game.game_id === item.game_id
403
419
  )
404
- );
405
-
406
- // If we can't find a matching operator relation, skip this toplist item
407
- if (!operatorRelation) {
408
- return null;
409
- }
410
-
411
- operatorRelation.ribbons =
412
- item.ribbon_ids && item.ribbon_ids.length === 0
413
- ? operatorRelation.ribbons
414
- : item.ribbon_ids;
415
-
416
- operatorRelation.selling_points =
417
- item.selling_points && item.selling_points.length === 0
418
- ? operatorRelation.selling_points
419
- : item.selling_points;
420
-
421
- operatorRelation.updated_at = item.updated_at;
422
- operatorRelation.toplist_bonus = item.bonus_name;
423
- operatorRelation.toplist_item_tracker_name = item.tracker_name;
424
-
425
- const operatorPage =
426
- pages && pages.operator && operatorRelation
427
- ? pages.operator.filter(
428
- (page) =>
429
- page.relation &&
430
- page.relation.operator_id ===
431
- operatorRelation.operator_id &&
432
- page.relation.type === operatorRelation.type
433
- )
434
- : [];
435
-
436
- const reviewLink =
437
- process.env.DMS_REVIEW_LINKS_ENABLED === "true"
438
- ? stripDomainAndLeadingSlash(operatorRelation?.review_link)
439
- : operatorPage[0]?.path;
440
-
441
- const authorTitle =
442
- operatorPage[0] && operatorPage[0]?.author?.author_title;
443
-
444
- const clone = sanitizeOperatorData(
445
- cloneDeep(operatorRelation),
446
- operatorPage,
447
- data,
448
- toplists && toplists[listItem.id].label
449
- );
450
-
451
- const socialAuthorLinks = [
452
- "facebook_profile",
453
- "twitter_profile",
454
- "instagram_profile",
455
- "linkedin_profile",
456
- ];
457
- if (filterEnabled) {
458
- buildToplistFilter(filters, clone);
459
- }
460
- return Object.assign(clone, {
461
- review_link: reviewLink,
462
- author_title: authorTitle,
463
- author_same_as:
464
- operatorPage[0] &&
465
- operatorPage[0]?.author &&
466
- socialAuthorLinks
467
- .map((socialLink) => operatorPage[0]?.author?.[socialLink])
468
- .filter((socialLink) => socialLink),
469
- });
420
+ )
421
+ .map((item) => {
422
+ if (item.operator_id) return processOperatorToplist(item, ctx);
423
+ if (item.game_id) return processGameToplist(item, ctx);
424
+ return null;
470
425
  })
471
- .filter((item) => item)
426
+ .filter(Boolean)
472
427
  : [];
473
428
  const latestItems = listItem.items
474
429
  .map((toplist) => ({
@@ -477,7 +432,6 @@ export function processTopListModule(
477
432
  }))
478
433
  .sort((a, b) => b.updated_at - a.updated_at)
479
434
  .slice(0, 3);
480
-
481
435
  const formattedLatestItems = latestItems
482
436
  .map((item) => item.name)
483
437
  .reduce((acc, curr, index, array) => {
@@ -626,9 +580,13 @@ export function processAnchor(module = {}, relationData, translations) {
626
580
  relationData
627
581
  );
628
582
  anchor.label = generatedLabel;
629
- anchor.slug = generatePlaceholderString(anchor?.slug?.trim(), translations, relationData);
583
+ anchor.slug = generatePlaceholderString(
584
+ anchor?.slug?.trim(),
585
+ translations,
586
+ relationData
587
+ );
630
588
  });
631
-
589
+
632
590
  return module;
633
591
  }
634
592
 
File without changes