crazy-odds-bet-shared 1.0.45 → 1.0.47
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/bookmakers/specifiers/superbetSpecifiers.js +3 -0
- package/models/fixture.js +26 -2
- package/models/index.js +2 -0
- package/models/player.js +1 -1
- package/models/sport.js +6 -0
- package/models/tournament.js +187 -0
- package/package.json +1 -1
|
@@ -107,6 +107,9 @@ class SuperbetSpecifiersHelper extends SpecifiersHelperBase {
|
|
|
107
107
|
|
|
108
108
|
getQuarter(externalRef) {
|
|
109
109
|
const s = String(externalRef?.value ?? '').trim();
|
|
110
|
+
if (['1', '2', '3', '4'].includes(s)) {
|
|
111
|
+
return { value: String(s) };
|
|
112
|
+
}
|
|
110
113
|
const m = s.match(/Sfertul\s*([0-9])/i);
|
|
111
114
|
if (!m) return { value: null };
|
|
112
115
|
const n = Number(m[1]);
|
package/models/fixture.js
CHANGED
|
@@ -23,8 +23,10 @@ const fixtureSchema = new Schema(
|
|
|
23
23
|
...createBaseSchema(),
|
|
24
24
|
sportId: { type: String, required: true, ref: 'Sport' },
|
|
25
25
|
competitionId: { type: String, required: true, ref: 'Competition' },
|
|
26
|
-
homeTeamId: { type: String, required:
|
|
27
|
-
awayTeamId: { type: String, required:
|
|
26
|
+
homeTeamId: { type: String, required: false, ref: 'Team' },
|
|
27
|
+
awayTeamId: { type: String, required: false, ref: 'Team' },
|
|
28
|
+
firstPlayerId: { type: String, required: false, ref: 'Player' },
|
|
29
|
+
secondPlayerId: { type: String, required: false, ref: 'Player' },
|
|
28
30
|
name: { type: String, required: true },
|
|
29
31
|
slug: { type: String, unique: true, sparse: true },
|
|
30
32
|
scheduledAt: { type: Date, required: true },
|
|
@@ -45,6 +47,8 @@ fixtureSchema.index({ sportId: 1 });
|
|
|
45
47
|
fixtureSchema.index({ competitionId: 1 });
|
|
46
48
|
fixtureSchema.index({ homeTeamId: 1 });
|
|
47
49
|
fixtureSchema.index({ awayTeamId: 1 });
|
|
50
|
+
fixtureSchema.index({ firstPlayerId: 1 });
|
|
51
|
+
fixtureSchema.index({ secondPlayerId: 1 });
|
|
48
52
|
fixtureSchema.index({ scheduledAt: 1 });
|
|
49
53
|
fixtureSchema.index({ status: 1 });
|
|
50
54
|
fixtureSchema.index({ scheduledAt: 1, status: 1 });
|
|
@@ -78,6 +82,20 @@ fixtureSchema.virtual('awayTeam', {
|
|
|
78
82
|
justOne: true
|
|
79
83
|
});
|
|
80
84
|
|
|
85
|
+
fixtureSchema.virtual('firstPlayer', {
|
|
86
|
+
ref: 'Player',
|
|
87
|
+
localField: 'firstPlayerId',
|
|
88
|
+
foreignField: '_id',
|
|
89
|
+
justOne: true
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
fixtureSchema.virtual('secondPlayer', {
|
|
93
|
+
ref: 'Player',
|
|
94
|
+
localField: 'secondPlayerId',
|
|
95
|
+
foreignField: '_id',
|
|
96
|
+
justOne: true
|
|
97
|
+
});
|
|
98
|
+
|
|
81
99
|
// Static methods
|
|
82
100
|
fixtureSchema.static('findBySlug', function (slug) {
|
|
83
101
|
return this.findOne({ slug });
|
|
@@ -123,6 +141,12 @@ fixtureSchema.static('findByTeam', function (teamId) {
|
|
|
123
141
|
}).sort({ scheduledAt: 1 });
|
|
124
142
|
});
|
|
125
143
|
|
|
144
|
+
fixtureSchema.static('findByPlayer', function (playerId) {
|
|
145
|
+
return this.find({
|
|
146
|
+
$or: [{ firstPlayerId: playerId }, { secondPlayerId: playerId }]
|
|
147
|
+
}).sort({ scheduledAt: 1 });
|
|
148
|
+
});
|
|
149
|
+
|
|
126
150
|
fixtureSchema.static('findUpcoming', function (limit = 20) {
|
|
127
151
|
return this.find({
|
|
128
152
|
scheduledAt: { $gte: new Date() },
|
package/models/index.js
CHANGED
|
@@ -2,6 +2,7 @@ const { Bookmaker } = require('./bookmaker');
|
|
|
2
2
|
const { Provider } = require('./provider');
|
|
3
3
|
const { Sport } = require('./sport');
|
|
4
4
|
const { Competition } = require('./competition');
|
|
5
|
+
const { Tournament } = require('./tournament');
|
|
5
6
|
const { Team } = require('./team');
|
|
6
7
|
const { Player } = require('./player');
|
|
7
8
|
const { Fixture, FixtureStatus } = require('./fixture');
|
|
@@ -20,6 +21,7 @@ module.exports = {
|
|
|
20
21
|
Provider,
|
|
21
22
|
Sport,
|
|
22
23
|
Competition,
|
|
24
|
+
Tournament,
|
|
23
25
|
Team,
|
|
24
26
|
Player,
|
|
25
27
|
Fixture,
|
package/models/player.js
CHANGED
|
@@ -11,7 +11,7 @@ const playerSchema = new Schema(
|
|
|
11
11
|
{
|
|
12
12
|
...createBaseSchema(),
|
|
13
13
|
sportId: { type: String, required: true, ref: 'Sport' },
|
|
14
|
-
teamId: { type: String, required:
|
|
14
|
+
teamId: { type: String, required: false, ref: 'Team' },
|
|
15
15
|
fullName: { type: String, required: true },
|
|
16
16
|
firstName: { type: String },
|
|
17
17
|
lastName: { type: String },
|
package/models/sport.js
CHANGED
|
@@ -13,6 +13,12 @@ const sportSchema = new Schema(
|
|
|
13
13
|
name: { type: String, required: true },
|
|
14
14
|
slug: { type: String, unique: true, sparse: true },
|
|
15
15
|
displayName: { type: String, required: true },
|
|
16
|
+
category: {
|
|
17
|
+
type: String,
|
|
18
|
+
required: true,
|
|
19
|
+
enum: ['team', 'individual'],
|
|
20
|
+
default: 'team'
|
|
21
|
+
},
|
|
16
22
|
isActive: { type: Boolean, default: true },
|
|
17
23
|
externalRefs: { type: Schema.Types.Mixed, default: {} }
|
|
18
24
|
},
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
const { Schema, model } = require('mongoose');
|
|
2
|
+
const {
|
|
3
|
+
createBaseSchema,
|
|
4
|
+
baseSchemaOptions
|
|
5
|
+
} = require('./base');
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Tournament schema
|
|
9
|
+
*/
|
|
10
|
+
const tournamentSchema = new Schema(
|
|
11
|
+
{
|
|
12
|
+
...createBaseSchema(),
|
|
13
|
+
sportId: { type: String, required: true, ref: 'Sport' },
|
|
14
|
+
competitionId: { type: String, required: true, ref: 'Competition' },
|
|
15
|
+
name: { type: String, required: true },
|
|
16
|
+
slug: { type: String, sparse: true },
|
|
17
|
+
location: { type: String, required: false, sparse: true },
|
|
18
|
+
startDate: { type: Date, required: false, sparse: true },
|
|
19
|
+
endDate: { type: Date, required: false, sparse: true },
|
|
20
|
+
isActive: { type: Boolean, default: true },
|
|
21
|
+
externalRefs: { type: Schema.Types.Mixed, default: {} },
|
|
22
|
+
providerRefs: { type: Schema.Types.Mixed, default: {} },
|
|
23
|
+
metadata: { type: Schema.Types.Mixed, default: {} }
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
...baseSchemaOptions,
|
|
27
|
+
autoIndex: process.env.NODE_ENV !== 'production'
|
|
28
|
+
}
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
// Indexes (slug unique per sport via compound)
|
|
32
|
+
tournamentSchema.index({ slug: 1, sportId: 1 }, { unique: true, sparse: true });
|
|
33
|
+
tournamentSchema.index({ sportId: 1 });
|
|
34
|
+
tournamentSchema.index({ competitionId: 1 });
|
|
35
|
+
tournamentSchema.index({ isActive: 1 });
|
|
36
|
+
tournamentSchema.index({ name: 'text' });
|
|
37
|
+
|
|
38
|
+
// Virtuals
|
|
39
|
+
tournamentSchema.virtual('sport', {
|
|
40
|
+
ref: 'Sport',
|
|
41
|
+
localField: 'sportId',
|
|
42
|
+
foreignField: '_id',
|
|
43
|
+
justOne: true
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
tournamentSchema.virtual('competition', {
|
|
47
|
+
ref: 'Competition',
|
|
48
|
+
localField: 'competitionId',
|
|
49
|
+
foreignField: '_id',
|
|
50
|
+
justOne: true
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
// Migration hook: convert array externalRefs to object
|
|
54
|
+
tournamentSchema.pre('save', function (next) {
|
|
55
|
+
if (this.externalRefs && Array.isArray(this.externalRefs)) {
|
|
56
|
+
// Migrate from array to object format
|
|
57
|
+
const converted = {};
|
|
58
|
+
this.externalRefs.forEach((ref) => {
|
|
59
|
+
if (ref && ref.bookmaker) {
|
|
60
|
+
// If array has bookmaker property, use it as key
|
|
61
|
+
const { bookmaker, ...refData } = ref;
|
|
62
|
+
converted[bookmaker] = refData;
|
|
63
|
+
} else if (ref && ref.slug) {
|
|
64
|
+
// Fallback to slug as key
|
|
65
|
+
converted[ref.slug] = ref;
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
this.externalRefs = converted;
|
|
69
|
+
}
|
|
70
|
+
next();
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
// Static methods
|
|
74
|
+
tournamentSchema.static('findBySlug', function (slug, sport, season) {
|
|
75
|
+
const query = { slug };
|
|
76
|
+
if (sport) query.sportId = sport;
|
|
77
|
+
if (season) query.season = season;
|
|
78
|
+
return this.findOne(query);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
tournamentSchema.static('getActive', function () {
|
|
82
|
+
return this.find({ isActive: true }).sort({ name: 1 });
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
tournamentSchema.static('findByExternalRef', function (bookmakerSlug, sportId, externalId) {
|
|
86
|
+
const query = {};
|
|
87
|
+
query[`externalRefs.${bookmakerSlug}.id`] = externalId;
|
|
88
|
+
query['sportId'] = sportId;
|
|
89
|
+
return this.findOne(query);
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
tournamentSchema.static('findBySport', function (sportId) {
|
|
93
|
+
return this.find({ sportId, isActive: true }).sort({ name: 1 });
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
tournamentSchema.static('findByCompetition', function (competitionId) {
|
|
97
|
+
return this.find({ competitionId, isActive: true }).sort({ name: 1 });
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
tournamentSchema.static('searchByName', function (query) {
|
|
101
|
+
return this.find({
|
|
102
|
+
name: { $regex: query, $options: 'i' }
|
|
103
|
+
}).sort({ name: 1 });
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
// Instance methods
|
|
107
|
+
tournamentSchema.method('activate', async function () {
|
|
108
|
+
this.isActive = true;
|
|
109
|
+
return this.save();
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
tournamentSchema.method('deactivate', async function () {
|
|
113
|
+
this.isActive = false;
|
|
114
|
+
return this.save();
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
tournamentSchema.method('addExternalRef', async function (key, ref) {
|
|
118
|
+
if (!this.externalRefs || typeof this.externalRefs !== 'object') {
|
|
119
|
+
this.externalRefs = {};
|
|
120
|
+
}
|
|
121
|
+
const refs = this.externalRefs;
|
|
122
|
+
refs[key] = ref;
|
|
123
|
+
this.markModified('externalRefs');
|
|
124
|
+
return this.save();
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
tournamentSchema.method('removeExternalRef', async function (key) {
|
|
128
|
+
if (this.externalRefs && typeof this.externalRefs === 'object') {
|
|
129
|
+
const refs = this.externalRefs;
|
|
130
|
+
delete refs[key];
|
|
131
|
+
this.markModified('externalRefs');
|
|
132
|
+
}
|
|
133
|
+
return this.save();
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
tournamentSchema.method('activateExternalRef', async function (key) {
|
|
137
|
+
if (this.externalRefs && typeof this.externalRefs === 'object') {
|
|
138
|
+
const refs = this.externalRefs;
|
|
139
|
+
const ref = refs[key];
|
|
140
|
+
if (ref) {
|
|
141
|
+
ref.isActive = true;
|
|
142
|
+
refs[key] = ref;
|
|
143
|
+
this.markModified('externalRefs');
|
|
144
|
+
return this.save();
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return this;
|
|
148
|
+
});
|
|
149
|
+
|
|
150
|
+
tournamentSchema.method('deactivateExternalRef', async function (key) {
|
|
151
|
+
if (this.externalRefs && typeof this.externalRefs === 'object') {
|
|
152
|
+
const refs = this.externalRefs;
|
|
153
|
+
const ref = refs[key];
|
|
154
|
+
if (ref) {
|
|
155
|
+
ref.isActive = false;
|
|
156
|
+
refs[key] = ref;
|
|
157
|
+
this.markModified('externalRefs');
|
|
158
|
+
return this.save();
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return this;
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
tournamentSchema.method('addProviderRef', async function (key, ref) {
|
|
165
|
+
if (!this.providerRefs || typeof this.providerRefs !== 'object') {
|
|
166
|
+
this.providerRefs = {};
|
|
167
|
+
}
|
|
168
|
+
this.providerRefs[key] = ref;
|
|
169
|
+
this.markModified('providerRefs');
|
|
170
|
+
return this.save();
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
tournamentSchema.method('removeProviderRef', async function (key) {
|
|
174
|
+
if (this.providerRefs && typeof this.providerRefs === 'object') {
|
|
175
|
+
delete this.providerRefs[key];
|
|
176
|
+
this.markModified('providerRefs');
|
|
177
|
+
}
|
|
178
|
+
return this.save();
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
tournamentSchema.method('getProviderRef', function (key) {
|
|
182
|
+
return this.providerRefs?.[key] || null;
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
const Tournament = model('Tournament', tournamentSchema);
|
|
186
|
+
|
|
187
|
+
module.exports = { Tournament };
|