@opexa/portal-sdk 0.59.88 → 0.59.90
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/{chunk-AOATA4DJ.js → chunk-HJSVCLHQ.js} +141 -2
- package/dist/chunk-HJSVCLHQ.js.map +1 -0
- package/dist/index.cjs +264 -30
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +53 -3
- package/dist/index.d.ts +53 -3
- package/dist/index.js +126 -31
- package/dist/index.js.map +1 -1
- package/dist/services/index.cjs +139 -0
- package/dist/services/index.cjs.map +1 -1
- package/dist/services/index.d.cts +7 -3
- package/dist/services/index.d.ts +7 -3
- package/dist/services/index.js +1 -1
- package/dist/{types-CHjedE6P.d.cts → types-CPRTXKkO.d.cts} +111 -2
- package/dist/{types-yuha_bQI.d.ts → types-DZdI2ruq.d.ts} +111 -2
- package/package.json +1 -1
- package/dist/chunk-AOATA4DJ.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -3838,6 +3838,79 @@ var MEMBER_FREE_BET_DROPS_QUERY = gql`
|
|
|
3838
3838
|
}
|
|
3839
3839
|
}
|
|
3840
3840
|
`;
|
|
3841
|
+
var _GAMES_QUERY = gql`
|
|
3842
|
+
query _Games($first: Int, $after: Cursor, $filter: GameFilterInput) {
|
|
3843
|
+
games(first: $first, after: $after, filter: $filter) {
|
|
3844
|
+
edges {
|
|
3845
|
+
cursor
|
|
3846
|
+
node {
|
|
3847
|
+
... on Game {
|
|
3848
|
+
id
|
|
3849
|
+
name
|
|
3850
|
+
displayName
|
|
3851
|
+
type
|
|
3852
|
+
provider
|
|
3853
|
+
reference
|
|
3854
|
+
hidden
|
|
3855
|
+
image
|
|
3856
|
+
}
|
|
3857
|
+
}
|
|
3858
|
+
}
|
|
3859
|
+
pageInfo {
|
|
3860
|
+
hasNextPage
|
|
3861
|
+
endCursor
|
|
3862
|
+
}
|
|
3863
|
+
}
|
|
3864
|
+
}
|
|
3865
|
+
`;
|
|
3866
|
+
var _GAME_GROUPS_QUERY = gql`
|
|
3867
|
+
query _GameGroups {
|
|
3868
|
+
gameGroups {
|
|
3869
|
+
id
|
|
3870
|
+
name
|
|
3871
|
+
}
|
|
3872
|
+
}
|
|
3873
|
+
`;
|
|
3874
|
+
var _GAME_GROUP_NODE_QUERY = gql`
|
|
3875
|
+
query _GameGroupNode($id: ObjectId!, $limit: Int, $offset: Int) {
|
|
3876
|
+
node(id: $id) {
|
|
3877
|
+
... on GameGroup {
|
|
3878
|
+
id
|
|
3879
|
+
name
|
|
3880
|
+
games(limit: $limit, offset: $offset) {
|
|
3881
|
+
id
|
|
3882
|
+
name
|
|
3883
|
+
displayName
|
|
3884
|
+
type
|
|
3885
|
+
provider
|
|
3886
|
+
reference
|
|
3887
|
+
hidden
|
|
3888
|
+
image
|
|
3889
|
+
}
|
|
3890
|
+
}
|
|
3891
|
+
}
|
|
3892
|
+
}
|
|
3893
|
+
`;
|
|
3894
|
+
var _GAME_NODE_QUERY = gql`
|
|
3895
|
+
query _GameNode($id: ObjectId!) {
|
|
3896
|
+
node(id: $id) {
|
|
3897
|
+
... on Game {
|
|
3898
|
+
id
|
|
3899
|
+
name
|
|
3900
|
+
displayName
|
|
3901
|
+
type
|
|
3902
|
+
provider
|
|
3903
|
+
reference
|
|
3904
|
+
hidden
|
|
3905
|
+
image
|
|
3906
|
+
groups {
|
|
3907
|
+
id
|
|
3908
|
+
name
|
|
3909
|
+
}
|
|
3910
|
+
}
|
|
3911
|
+
}
|
|
3912
|
+
}
|
|
3913
|
+
`;
|
|
3841
3914
|
|
|
3842
3915
|
// src/services/utils.ts
|
|
3843
3916
|
function createOperationError(code) {
|
|
@@ -4765,6 +4838,12 @@ var AuthService = class {
|
|
|
4765
4838
|
error: createOperationError("AccountSuspendedError")
|
|
4766
4839
|
};
|
|
4767
4840
|
}
|
|
4841
|
+
if (body.code === "REFRESH_TOKEN_EXPIRED") {
|
|
4842
|
+
return {
|
|
4843
|
+
ok: false,
|
|
4844
|
+
error: createOperationError("SessionExpiredError")
|
|
4845
|
+
};
|
|
4846
|
+
}
|
|
4768
4847
|
if (res.status === 403 || res.status === 401) {
|
|
4769
4848
|
return {
|
|
4770
4849
|
ok: false,
|
|
@@ -5242,6 +5321,66 @@ var PortalService = class {
|
|
|
5242
5321
|
data: res.data
|
|
5243
5322
|
};
|
|
5244
5323
|
}
|
|
5324
|
+
async _games(variables) {
|
|
5325
|
+
const res = await this.client.request(
|
|
5326
|
+
_GAMES_QUERY,
|
|
5327
|
+
variables
|
|
5328
|
+
);
|
|
5329
|
+
if (!res.ok) return res;
|
|
5330
|
+
if (!res.data.games) {
|
|
5331
|
+
return {
|
|
5332
|
+
ok: false,
|
|
5333
|
+
error: {
|
|
5334
|
+
name: "UnknownError",
|
|
5335
|
+
message: "Something went wrong."
|
|
5336
|
+
}
|
|
5337
|
+
};
|
|
5338
|
+
}
|
|
5339
|
+
return {
|
|
5340
|
+
ok: true,
|
|
5341
|
+
data: res.data.games
|
|
5342
|
+
};
|
|
5343
|
+
}
|
|
5344
|
+
async _gameGroups() {
|
|
5345
|
+
const res = await this.client.request(
|
|
5346
|
+
_GAME_GROUPS_QUERY
|
|
5347
|
+
);
|
|
5348
|
+
if (!res.ok) return res;
|
|
5349
|
+
if (!res.data.gameGroups) {
|
|
5350
|
+
return {
|
|
5351
|
+
ok: false,
|
|
5352
|
+
error: {
|
|
5353
|
+
name: "UnknownError",
|
|
5354
|
+
message: "Something went wrong."
|
|
5355
|
+
}
|
|
5356
|
+
};
|
|
5357
|
+
}
|
|
5358
|
+
return {
|
|
5359
|
+
ok: true,
|
|
5360
|
+
data: res.data.gameGroups
|
|
5361
|
+
};
|
|
5362
|
+
}
|
|
5363
|
+
async _gameGroupNode(id, limit, offset) {
|
|
5364
|
+
const res = await this.client.request(
|
|
5365
|
+
_GAME_GROUP_NODE_QUERY,
|
|
5366
|
+
{ id, limit, offset }
|
|
5367
|
+
);
|
|
5368
|
+
if (!res.ok) return res;
|
|
5369
|
+
return {
|
|
5370
|
+
ok: true,
|
|
5371
|
+
data: res.data.node
|
|
5372
|
+
};
|
|
5373
|
+
}
|
|
5374
|
+
async _gameNode(id) {
|
|
5375
|
+
const res = await this.client.request(_GAME_NODE_QUERY, {
|
|
5376
|
+
id
|
|
5377
|
+
});
|
|
5378
|
+
if (!res.ok) return res;
|
|
5379
|
+
return {
|
|
5380
|
+
ok: true,
|
|
5381
|
+
data: res.data.node
|
|
5382
|
+
};
|
|
5383
|
+
}
|
|
5245
5384
|
async recommendedGames() {
|
|
5246
5385
|
const res = await this.client.request(
|
|
5247
5386
|
RECOMMENDED_GAMES_QUERY
|
|
@@ -7351,7 +7490,8 @@ var SessionManager = class {
|
|
|
7351
7490
|
if (input.type === "MOBILE_NUMBER") {
|
|
7352
7491
|
const res2 = await this.authService.createSession(input, version);
|
|
7353
7492
|
if (res2.ok) {
|
|
7354
|
-
if (!this.persist(res2.data, version))
|
|
7493
|
+
if (!this.persist(res2.data, version))
|
|
7494
|
+
return this.malformedResponseError();
|
|
7355
7495
|
return {
|
|
7356
7496
|
ok: true,
|
|
7357
7497
|
data: null
|
|
@@ -7369,7 +7509,8 @@ var SessionManager = class {
|
|
|
7369
7509
|
version
|
|
7370
7510
|
);
|
|
7371
7511
|
if (res2.ok) {
|
|
7372
|
-
if (!this.persist(res2.data, version))
|
|
7512
|
+
if (!this.persist(res2.data, version))
|
|
7513
|
+
return this.malformedResponseError();
|
|
7373
7514
|
return {
|
|
7374
7515
|
ok: true,
|
|
7375
7516
|
data: null
|
|
@@ -7381,7 +7522,8 @@ var SessionManager = class {
|
|
|
7381
7522
|
localStorage.setItem(this.platformStorageKey, "CABINET");
|
|
7382
7523
|
const res2 = await this.authService.createSession(input, version);
|
|
7383
7524
|
if (res2.ok) {
|
|
7384
|
-
if (!this.persist(res2.data, version))
|
|
7525
|
+
if (!this.persist(res2.data, version))
|
|
7526
|
+
return this.malformedResponseError();
|
|
7385
7527
|
return {
|
|
7386
7528
|
ok: true,
|
|
7387
7529
|
data: null
|
|
@@ -7605,7 +7747,7 @@ var SessionManager = class {
|
|
|
7605
7747
|
this.refreshing = false;
|
|
7606
7748
|
if (!res.ok) {
|
|
7607
7749
|
this.logger.error(`Failed to refresh session: ${res.error.message}`);
|
|
7608
|
-
if (res.error.name === "InvalidTokenError" || res.error.name === "AccountBlacklistedError" || res.error.name === "VerificationLockedError") {
|
|
7750
|
+
if (res.error.name === "InvalidTokenError" || res.error.name === "AccountBlacklistedError" || res.error.name === "VerificationLockedError" || res.error.name === "SessionExpiredError") {
|
|
7609
7751
|
this.v4AccessToken = null;
|
|
7610
7752
|
this.v4AccessTokenExpiresAt = null;
|
|
7611
7753
|
}
|
|
@@ -7652,35 +7794,38 @@ var SessionManager = class {
|
|
|
7652
7794
|
async verify() {
|
|
7653
7795
|
if (this.isServer) {
|
|
7654
7796
|
this.logger.warn("'localStorage' is not available on the server.");
|
|
7655
|
-
return true;
|
|
7797
|
+
return { valid: true };
|
|
7656
7798
|
}
|
|
7657
7799
|
const val = localStorage.getItem(this.storageKey);
|
|
7658
7800
|
if (val) {
|
|
7659
7801
|
try {
|
|
7660
7802
|
const stored = JSON.parse(val);
|
|
7661
7803
|
if (stored.version === 4) {
|
|
7662
|
-
const
|
|
7663
|
-
if (!valid) localStorage.removeItem(this.storageKey);
|
|
7664
|
-
return
|
|
7804
|
+
const res = await this.verifyV4(stored.session);
|
|
7805
|
+
if (!res.valid) localStorage.removeItem(this.storageKey);
|
|
7806
|
+
return res;
|
|
7665
7807
|
}
|
|
7666
7808
|
} catch {
|
|
7667
7809
|
}
|
|
7668
7810
|
}
|
|
7669
7811
|
const s = await this.get();
|
|
7670
|
-
if (s.error?.name === "InvalidTokenError")
|
|
7671
|
-
|
|
7672
|
-
|
|
7673
|
-
if (!s.data) return true;
|
|
7812
|
+
if (s.error?.name === "InvalidTokenError" || s.error?.name === "SessionExpiredError" || s.error?.name === "AccountBlacklistedError") {
|
|
7813
|
+
return { valid: false, reason: "INVALID_SESSION" };
|
|
7814
|
+
}
|
|
7815
|
+
if (!s.data) return { valid: true };
|
|
7674
7816
|
const v = await this.authService.verifySession(s.data.accessToken);
|
|
7675
7817
|
if (!v) {
|
|
7676
7818
|
localStorage.removeItem(this.storageKey);
|
|
7677
7819
|
}
|
|
7678
|
-
return v;
|
|
7820
|
+
return v ? { valid: true } : { valid: false, reason: "INVALID_SESSION" };
|
|
7679
7821
|
}
|
|
7680
7822
|
async verifyV4(session) {
|
|
7681
7823
|
if (!this.v4AccessToken || !this.v4AccessTokenExpiresAt || isAfter(/* @__PURE__ */ new Date(), new Date(this.v4AccessTokenExpiresAt))) {
|
|
7682
7824
|
const res = await this.refreshV4(session);
|
|
7683
|
-
return res.ok
|
|
7825
|
+
return res.ok ? { valid: true } : {
|
|
7826
|
+
valid: false,
|
|
7827
|
+
reason: res.error.name === "SessionExpiredError" ? "REFRESH_TOKEN_EXPIRED" : "INVALID_SESSION"
|
|
7828
|
+
};
|
|
7684
7829
|
}
|
|
7685
7830
|
const v = await this.authService.verifySession(this.v4AccessToken);
|
|
7686
7831
|
if (!v) {
|
|
@@ -7688,7 +7833,7 @@ var SessionManager = class {
|
|
|
7688
7833
|
this.v4AccessToken = null;
|
|
7689
7834
|
this.v4AccessTokenExpiresAt = null;
|
|
7690
7835
|
}
|
|
7691
|
-
return v;
|
|
7836
|
+
return v ? { valid: true } : { valid: false, reason: "INVALID_SESSION" };
|
|
7692
7837
|
}
|
|
7693
7838
|
get onMaya() {
|
|
7694
7839
|
if (this.isServer) {
|
|
@@ -8039,7 +8184,7 @@ var SessionManagerCookie = class {
|
|
|
8039
8184
|
this.refreshing = false;
|
|
8040
8185
|
if (!res.ok) {
|
|
8041
8186
|
this.logger.error(`Failed to refresh session: ${res.error.message}`);
|
|
8042
|
-
if (res.error.name === "InvalidTokenError" || res.error.name === "AccountBlacklistedError" || res.error.name === "VerificationLockedError") {
|
|
8187
|
+
if (res.error.name === "InvalidTokenError" || res.error.name === "AccountBlacklistedError" || res.error.name === "VerificationLockedError" || res.error.name === "SessionExpiredError") {
|
|
8043
8188
|
this.v4AccessToken = null;
|
|
8044
8189
|
this.v4AccessTokenExpiresAt = null;
|
|
8045
8190
|
}
|
|
@@ -8086,35 +8231,38 @@ var SessionManagerCookie = class {
|
|
|
8086
8231
|
async verify() {
|
|
8087
8232
|
if (this.isServer) {
|
|
8088
8233
|
this.logger.warn("'client cookies' is not available on the server.");
|
|
8089
|
-
return true;
|
|
8234
|
+
return { valid: true };
|
|
8090
8235
|
}
|
|
8091
8236
|
const val = cookies__default.default.get(this.storageKey);
|
|
8092
8237
|
if (val) {
|
|
8093
8238
|
try {
|
|
8094
8239
|
const stored = JSON.parse(val);
|
|
8095
8240
|
if (stored.version === 4) {
|
|
8096
|
-
const
|
|
8097
|
-
if (!valid) cookies__default.default.remove(this.storageKey);
|
|
8098
|
-
return
|
|
8241
|
+
const res = await this.verifyV4(stored.session);
|
|
8242
|
+
if (!res.valid) cookies__default.default.remove(this.storageKey);
|
|
8243
|
+
return res;
|
|
8099
8244
|
}
|
|
8100
8245
|
} catch {
|
|
8101
8246
|
}
|
|
8102
8247
|
}
|
|
8103
8248
|
const s = await this.get();
|
|
8104
|
-
if (s.error?.name === "InvalidTokenError")
|
|
8105
|
-
|
|
8106
|
-
|
|
8107
|
-
if (!s.data) return true;
|
|
8249
|
+
if (s.error?.name === "InvalidTokenError" || s.error?.name === "SessionExpiredError" || s.error?.name === "AccountBlacklistedError") {
|
|
8250
|
+
return { valid: false, reason: "INVALID_SESSION" };
|
|
8251
|
+
}
|
|
8252
|
+
if (!s.data) return { valid: true };
|
|
8108
8253
|
const v = await this.authService.verifySession(s.data.accessToken);
|
|
8109
8254
|
if (!v) {
|
|
8110
8255
|
cookies__default.default.remove(this.storageKey);
|
|
8111
8256
|
}
|
|
8112
|
-
return v;
|
|
8257
|
+
return v ? { valid: true } : { valid: false, reason: "INVALID_SESSION" };
|
|
8113
8258
|
}
|
|
8114
8259
|
async verifyV4(session) {
|
|
8115
8260
|
if (!this.v4AccessToken || !this.v4AccessTokenExpiresAt || isAfter(/* @__PURE__ */ new Date(), new Date(this.v4AccessTokenExpiresAt))) {
|
|
8116
8261
|
const res = await this.refreshV4(session);
|
|
8117
|
-
return res.ok
|
|
8262
|
+
return res.ok ? { valid: true } : {
|
|
8263
|
+
valid: false,
|
|
8264
|
+
reason: res.error.name === "SessionExpiredError" ? "REFRESH_TOKEN_EXPIRED" : "INVALID_SESSION"
|
|
8265
|
+
};
|
|
8118
8266
|
}
|
|
8119
8267
|
const v = await this.authService.verifySession(this.v4AccessToken);
|
|
8120
8268
|
if (!v) {
|
|
@@ -8122,7 +8270,7 @@ var SessionManagerCookie = class {
|
|
|
8122
8270
|
this.v4AccessToken = null;
|
|
8123
8271
|
this.v4AccessTokenExpiresAt = null;
|
|
8124
8272
|
}
|
|
8125
|
-
return v;
|
|
8273
|
+
return v ? { valid: true } : { valid: false, reason: "INVALID_SESSION" };
|
|
8126
8274
|
}
|
|
8127
8275
|
get onMaya() {
|
|
8128
8276
|
if (this.isServer) {
|
|
@@ -10433,10 +10581,10 @@ var Sdk = class {
|
|
|
10433
10581
|
try {
|
|
10434
10582
|
res = await this.sessionManager.verify();
|
|
10435
10583
|
} catch {
|
|
10436
|
-
res = false;
|
|
10584
|
+
res = { valid: false, reason: "INVALID_SESSION" };
|
|
10437
10585
|
}
|
|
10438
|
-
if (!res) {
|
|
10439
|
-
await input.onInvalid();
|
|
10586
|
+
if (!res.valid) {
|
|
10587
|
+
await input.onInvalid(res.reason ?? "INVALID_SESSION");
|
|
10440
10588
|
}
|
|
10441
10589
|
}
|
|
10442
10590
|
timeout = assignTimeout();
|
|
@@ -11811,6 +11959,92 @@ var Sdk = class {
|
|
|
11811
11959
|
data: res.data ?? null
|
|
11812
11960
|
};
|
|
11813
11961
|
}
|
|
11962
|
+
/**
|
|
11963
|
+
* Fetches platform-scoped games from the Portal GraphQL API.
|
|
11964
|
+
*
|
|
11965
|
+
* Portal `Game.id` values are platform-game IDs, distinct from Wallet
|
|
11966
|
+
* global-game IDs. Never pass them to Wallet game-management mutations.
|
|
11967
|
+
*
|
|
11968
|
+
* The Portal `games` resolver does not supply `totalCount`, so the
|
|
11969
|
+
* result does not include it. Use `hasNextPage` and `endCursor` for
|
|
11970
|
+
* cursor pagination.
|
|
11971
|
+
*
|
|
11972
|
+
* For player-facing catalogs, pass `filter: { hidden: { equal: false } }`.
|
|
11973
|
+
*
|
|
11974
|
+
* Portal is eventually consistent — refetch or poll after Wallet writes.
|
|
11975
|
+
*/
|
|
11976
|
+
async _games(input) {
|
|
11977
|
+
const res = await this.portalService._games(input);
|
|
11978
|
+
if (!res.ok) return res;
|
|
11979
|
+
return {
|
|
11980
|
+
ok: true,
|
|
11981
|
+
data: {
|
|
11982
|
+
_games: res.data.edges.map(({ cursor, node }) => ({
|
|
11983
|
+
...node,
|
|
11984
|
+
cursor
|
|
11985
|
+
})),
|
|
11986
|
+
hasNextPage: res.data.pageInfo.hasNextPage,
|
|
11987
|
+
endCursor: res.data.pageInfo.endCursor ?? void 0
|
|
11988
|
+
}
|
|
11989
|
+
};
|
|
11990
|
+
}
|
|
11991
|
+
/**
|
|
11992
|
+
* Fetches all game groups for the current platform.
|
|
11993
|
+
*
|
|
11994
|
+
* Portal sorts the result by name ascending. There is no pagination.
|
|
11995
|
+
* An empty array is a valid result (platform with no configured groups).
|
|
11996
|
+
*/
|
|
11997
|
+
async _gameGroups() {
|
|
11998
|
+
const res = await this.portalService._gameGroups();
|
|
11999
|
+
if (!res.ok) return res;
|
|
12000
|
+
return {
|
|
12001
|
+
ok: true,
|
|
12002
|
+
data: res.data
|
|
12003
|
+
};
|
|
12004
|
+
}
|
|
12005
|
+
/**
|
|
12006
|
+
* Fetches a single game group and its ordered games via `node(id)`.
|
|
12007
|
+
*
|
|
12008
|
+
* The returned `games` array preserves the Wallet-managed group order.
|
|
12009
|
+
* Missing projected platform games are filtered out by the resolver.
|
|
12010
|
+
* Omit `limit` and `offset` to load the whole group (Wallet caps at 100).
|
|
12011
|
+
*
|
|
12012
|
+
* Returns `{ ok: true, data: null }` when the group is missing, belongs
|
|
12013
|
+
* to another platform, or the platform context is invalid.
|
|
12014
|
+
*/
|
|
12015
|
+
async _gameGroup(id, opts) {
|
|
12016
|
+
const res = await this.portalService._gameGroupNode(
|
|
12017
|
+
id,
|
|
12018
|
+
opts?.limit,
|
|
12019
|
+
opts?.offset
|
|
12020
|
+
);
|
|
12021
|
+
if (!res.ok) return res;
|
|
12022
|
+
return {
|
|
12023
|
+
ok: true,
|
|
12024
|
+
data: res.data
|
|
12025
|
+
};
|
|
12026
|
+
}
|
|
12027
|
+
/**
|
|
12028
|
+
* Fetches a single game by Portal platform-game ID via `node(id)`.
|
|
12029
|
+
*
|
|
12030
|
+
* Requires a Portal `Game.id` (platform-game ID). Passing a Wallet
|
|
12031
|
+
* global-game ID returns `null`.
|
|
12032
|
+
*
|
|
12033
|
+
* Includes reverse group membership via `Game.groups`. Legacy Portal
|
|
12034
|
+
* game rows may return an empty `groups` array — treat this as no
|
|
12035
|
+
* known memberships, not a request failure.
|
|
12036
|
+
*
|
|
12037
|
+
* Returns `{ ok: true, data: null }` when the game is missing, belongs
|
|
12038
|
+
* to another platform, or the platform context is invalid.
|
|
12039
|
+
*/
|
|
12040
|
+
async _game(id) {
|
|
12041
|
+
const res = await this.portalService._gameNode(id);
|
|
12042
|
+
if (!res.ok) return res;
|
|
12043
|
+
return {
|
|
12044
|
+
ok: true,
|
|
12045
|
+
data: res.data
|
|
12046
|
+
};
|
|
12047
|
+
}
|
|
11814
12048
|
async games__next(input) {
|
|
11815
12049
|
const res = await this.cmsPortalService.games__next(input);
|
|
11816
12050
|
if (!res.ok) return res;
|