diff --git a/api/appUser.js b/api/appUser.js
index 133d054..60964b3 100644
--- a/api/appUser.js
+++ b/api/appUser.js
@@ -292,3 +292,34 @@ export function getMatchingGameCards(game_id) {
data: { game_id }
})
}
+
+// ============================================
+// 次数卡 (Game Pass) 接口
+// ============================================
+
+/**
+ * 获取用户可用的次数卡
+ * @param {number} activity_id - 活动ID,不传返回所有
+ */
+export function getGamePasses(activity_id) {
+ const data = activity_id ? { activity_id } : {}
+ return authRequest({ url: '/api/app/game-passes/available', method: 'GET', data })
+}
+
+/**
+ * 获取可购买的次数卡套餐
+ * @param {number} activity_id - 活动ID,不传返回全局套餐
+ */
+export function getGamePassPackages(activity_id) {
+ const data = activity_id ? { activity_id } : {}
+ return authRequest({ url: '/api/app/game-passes/packages', method: 'GET', data })
+}
+
+/**
+ * 购买次数卡套餐
+ * @param {number} package_id - 套餐ID
+ */
+export function purchaseGamePass(package_id) {
+ return authRequest({ url: '/api/app/game-passes/purchase', method: 'POST', data: { package_id } })
+}
+
diff --git a/components/GamePassPurchasePopup.vue b/components/GamePassPurchasePopup.vue
new file mode 100644
index 0000000..ed544f0
--- /dev/null
+++ b/components/GamePassPurchasePopup.vue
@@ -0,0 +1,303 @@
+
+
+
+
+
+
+
+
+
diff --git a/components/PaymentPopup.vue b/components/PaymentPopup.vue
index 518ab75..81a4521 100644
--- a/components/PaymentPopup.vue
+++ b/components/PaymentPopup.vue
@@ -32,7 +32,30 @@
-
+
+
+ 0 ? toggleGamePass() : null"
+ >
+
+ ✓
+
+
+
+ 🎮 使用次数卡
+ 剩余 {{ gamePassRemaining }} 次
+ 暂无可用次数卡
+
+ 免费畅玩
+
+
+ 或选择其他支付方式
+
+
+
+
支付金额
¥{{ finalPayAmount }}
¥{{ amount }}
@@ -87,7 +110,8 @@
@@ -102,7 +126,8 @@ const props = defineProps({
amount: { type: [Number, String], default: 0 },
coupons: { type: Array, default: () => [] },
propCards: { type: Array, default: () => [] },
- showCards: { type: Boolean, default: true }
+ showCards: { type: Boolean, default: true },
+ gamePasses: { type: Object, default: () => null } // { total_remaining, passes }
})
const emit = defineEmits(['update:visible', 'confirm', 'cancel'])
@@ -174,6 +199,24 @@ watch(() => props.visible, (newVal) => {
const couponIndex = ref(-1)
const cardIndex = ref(-1)
+const useGamePass = ref(false)
+
+// 次数卡余额
+const gamePassRemaining = computed(() => {
+ return props.gamePasses?.total_remaining || 0
+})
+
+// 监听弹窗打开,若有次数卡则默认选中
+watch(() => props.visible, (newVal) => {
+ if (newVal) {
+ // 若有次数卡,默认选中
+ useGamePass.value = gamePassRemaining.value > 0
+ }
+})
+
+function toggleGamePass() {
+ useGamePass.value = !useGamePass.value
+}
const selectedCoupon = computed(() => {
if (couponIndex.value >= 0 && props.coupons[couponIndex.value]) {
@@ -254,8 +297,9 @@ function handleClose() {
function handleConfirm() {
emit('confirm', {
- coupon: selectedCoupon.value,
- card: props.showCards ? selectedCard.value : null
+ coupon: useGamePass.value ? null : selectedCoupon.value,
+ card: (props.showCards && !useGamePass.value) ? selectedCard.value : null,
+ useGamePass: useGamePass.value
})
}
@@ -765,4 +809,129 @@ function handleConfirm() {
transform: scale(0.97);
box-shadow: $shadow-md;
}
+
+/* 次数卡使用按钮特殊样式 */
+.btn-game-pass {
+ background: linear-gradient(135deg, #10B981, #059669);
+}
+
+/* ============================================
+ 次数卡选项样式
+ ============================================ */
+.game-pass-section {
+ margin-bottom: $spacing-md;
+}
+
+.game-pass-option {
+ display: flex;
+ align-items: center;
+ padding: $spacing-md;
+ background: linear-gradient(135deg, #ECFDF5, #D1FAE5);
+ border: 2rpx solid #10B981;
+ border-radius: $radius-lg;
+ transition: all 0.2s ease;
+
+ &.active {
+ background: linear-gradient(135deg, #10B981, #059669);
+ border-color: #059669;
+
+ .game-pass-label, .game-pass-count, .game-pass-free {
+ color: #FFFFFF;
+ }
+
+ .game-pass-radio {
+ background: #FFFFFF;
+ border-color: #FFFFFF;
+ }
+
+ .radio-checked {
+ color: #10B981;
+ }
+ }
+
+ &.disabled {
+ background: #F9FAFB;
+ border-color: #E5E7EB;
+
+ .game-pass-radio {
+ border-color: #D1D5DB;
+ background: #F3F4F6;
+ }
+ }
+}
+
+.game-pass-radio {
+ width: 40rpx;
+ height: 40rpx;
+ border-radius: 50%;
+ border: 3rpx solid #10B981;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ margin-right: $spacing-sm;
+}
+
+.radio-checked {
+ font-size: 24rpx;
+ font-weight: bold;
+ color: #10B981;
+}
+
+.game-pass-info {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+}
+
+.game-pass-label {
+ font-size: $font-md;
+ font-weight: 600;
+ color: #059669;
+}
+
+.game-pass-count {
+ font-size: $font-sm;
+ color: #10B981;
+ margin-top: 4rpx;
+}
+
+.game-pass-free {
+ font-size: $font-sm;
+ font-weight: 600;
+ color: #10B981;
+ padding: 6rpx 16rpx;
+ background: rgba(16, 185, 129, 0.1);
+ border-radius: $radius-md;
+}
+
+.divider-line {
+ display: flex;
+ align-items: center;
+ margin-top: $spacing-md;
+
+ &::before, &::after {
+ content: '';
+ flex: 1;
+ height: 1rpx;
+ background: $border-color-light;
+ }
+}
+
+.divider-text {
+ font-size: $font-xs;
+ color: $text-placeholder;
+ padding: 0 $spacing-sm;
+}
+
+.radio-disabled {
+ width: 24rpx;
+ height: 24rpx;
+ background: #D1D5DB;
+ border-radius: 50%;
+}
+
+.text-disabled {
+ color: #9CA3AF !important;
+}
+
diff --git a/pages-activity/activity/duiduipeng/index.vue b/pages-activity/activity/duiduipeng/index.vue
index e6ad4c2..9371c2a 100644
--- a/pages-activity/activity/duiduipeng/index.vue
+++ b/pages-activity/activity/duiduipeng/index.vue
@@ -68,6 +68,17 @@
{{ (Number(detail.price_draw || 0) / 100).toFixed(2) }}
/次
+
+
+
+ 🎮
+ {{ gamePassRemaining }}
+
+
+
+ 充值特惠
+
+
继续游戏
@@ -163,8 +174,16 @@
:coupons="coupons"
:propCards="propCards"
:showCards="true"
+ :gamePasses="gamePasses"
@confirm="onPaymentConfirm"
/>
+
+
+
gamePasses.value?.total_remaining || 0)
+const useGamePassFlag = ref(false) // 是否使用次数卡支付
+const purchasePopupVisible = ref(false)
const resumeGame = ref(null)
const resumeIssueId = ref('')
const hasResumeGame = computed(() => {
@@ -1317,6 +1341,7 @@ async function fetchCardTypes() {
async function onPaymentConfirm(data) {
selectedCoupon.value = data?.coupon || null
selectedCard.value = data?.card || null
+ useGamePassFlag.value = data?.useGamePass || false
paymentVisible.value = false
await doDraw()
}
@@ -1336,12 +1361,13 @@ async function doDraw() {
return
}
- // 1. 调用 createMatchingPreorder 创建对对碰订单(不再返回游戏数据)
+ // 1. 调用 createMatchingPreorder 创建对对碰订单
const preRes = await createMatchingPreorder({
issue_id: Number(iid),
position: String(selectedCardType.value.code || ''),
- coupon_id: selectedCoupon.value?.id ? Number(selectedCoupon.value.id) : 0,
- item_card_id: selectedCard.value?.id ? Number(selectedCard.value.id) : 0
+ coupon_id: useGamePassFlag.value ? 0 : (selectedCoupon.value?.id ? Number(selectedCoupon.value.id) : 0),
+ item_card_id: useGamePassFlag.value ? 0 : (selectedCard.value?.id ? Number(selectedCard.value.id) : 0),
+ use_game_pass: useGamePassFlag.value
})
if (!preRes) throw new Error('创建订单失败')
@@ -1352,24 +1378,33 @@ async function doDraw() {
const gameId = preRes.game_id || preRes.data?.game_id || preRes.result?.game_id || preRes.gameId
if (!gameId) throw new Error('未获取到游戏ID')
- // 3. 用对对碰订单号调用微信支付
- uni.showLoading({ title: '拉起支付...' })
- const payRes = await createWechatOrder({ openid, order_no: orderNo })
- await new Promise((resolve, reject) => {
- uni.requestPayment({
- provider: 'wxpay',
- timeStamp: payRes.timeStamp || payRes.timestamp,
- nonceStr: payRes.nonceStr || payRes.noncestr,
- package: payRes.package,
- signType: payRes.signType || 'RSA',
- paySign: payRes.paySign,
- success: resolve,
- fail: reject
+ // 3. 判断支付方式:次数卡已直接支付,微信需要拉起支付
+ const payStatus = preRes.pay_status || preRes.data?.pay_status || 1
+ if (useGamePassFlag.value || payStatus === 2) {
+ // 次数卡支付:订单已经是已支付状态,直接获取游戏数据
+ uni.showLoading({ title: '加载游戏...' })
+ // 刷新次数卡余额
+ await fetchGamePasses()
+ } else {
+ // 微信支付流程
+ uni.showLoading({ title: '拉起支付...' })
+ const payRes = await createWechatOrder({ openid, order_no: orderNo })
+ await new Promise((resolve, reject) => {
+ uni.requestPayment({
+ provider: 'wxpay',
+ timeStamp: payRes.timeStamp || payRes.timestamp,
+ nonceStr: payRes.nonceStr || payRes.noncestr,
+ package: payRes.package,
+ signType: payRes.signType || 'RSA',
+ paySign: payRes.paySign,
+ success: resolve,
+ fail: reject
+ })
})
- })
+ uni.showLoading({ title: '加载游戏...' })
+ }
- // 4. 【关键】支付成功后,调用新接口获取游戏数据
- uni.showLoading({ title: '加载游戏...' })
+ // 4. 获取游戏数据
const cardsRes = await getMatchingGameCards(gameId)
if (!cardsRes) throw new Error('获取游戏数据失败')
@@ -1385,7 +1420,7 @@ async function doDraw() {
})
uni.hideLoading()
- uni.showToast({ title: '支付成功', icon: 'success' })
+ uni.showToast({ title: useGamePassFlag.value ? '开始游戏' : '支付成功', icon: 'success' })
// 6. 自动打开游戏
syncResumeGame(aid)
@@ -1426,6 +1461,26 @@ async function fetchCoupons() {
}
}
+async function fetchGamePasses() {
+ const aid = activityId.value || ''
+ if (!aid) return
+ try {
+ const res = await getGamePasses(Number(aid))
+ gamePasses.value = res || null
+ } catch (e) {
+ gamePasses.value = null
+ }
+}
+
+function openPurchasePopup() {
+ purchasePopupVisible.value = true
+}
+
+function onPurchaseSuccess() {
+ // 购买成功,刷新次数卡余额
+ fetchGamePasses()
+}
+
async function fetchPropCards() {
const user_id = uni.getStorageSync('user_id')
if (!user_id) return
@@ -1478,6 +1533,8 @@ onLoad((opts) => {
syncResumeGame(id)
fetchDetail(id)
fetchIssues(id)
+ // 获取次数卡
+ fetchGamePasses()
}
fetchCardTypes()
})
@@ -2470,3 +2527,53 @@ onLoad((opts) => {
}
}
+
+
diff --git a/pages-game/game/minesweeper/index.vue b/pages-game/game/minesweeper/index.vue
index 4ce851a..55bd0f3 100644
--- a/pages-game/game/minesweeper/index.vue
+++ b/pages-game/game/minesweeper/index.vue
@@ -1,32 +1,32 @@
-
-
+
+
-
- 💣
+
+ 💣
-
+
多人对战扫雷
和好友一起挑战,获胜赢取精美奖品!
-
+
我的游戏资格
@@ -34,7 +34,8 @@
次
- 完成任务可获得游戏资格哦~
+
+ {{ ticketCount > 0 ? '每次进入消耗1次资格' : '完成任务可获得游戏资格哦~' }}
@@ -46,13 +47,12 @@
@@ -81,20 +81,14 @@ export default {
try {
const userInfo = uni.getStorageSync('user_info') || {}
const userId = userInfo.id || userInfo.user_id
- console.log('===== 调试游戏资格 =====')
- console.log('userId:', userId)
if (!userId) {
- console.log('未获取到用户ID,返回0')
this.ticketCount = 0
return
}
const res = await authRequest({
url: `/api/app/users/${userId}/game_tickets`
})
- console.log('API返回:', res)
- // res 格式: { minesweeper: 3, poker: 0, ... }
this.ticketCount = res[this.gameCode] || 0
- console.log('gameCode:', this.gameCode, 'ticketCount:', this.ticketCount)
} catch (e) {
console.error('加载游戏资格失败', e)
this.ticketCount = 0
@@ -115,16 +109,12 @@ export default {
}
})
- // 构建游戏URL,传递安全认证参数
- const gameBaseUrl = res.client_url || 'https://game.1024tool.vip'
const gameToken = encodeURIComponent(res.game_token)
const nakamaServer = encodeURIComponent(res.nakama_server)
const nakamaKey = encodeURIComponent(res.nakama_key)
- const gameUrl = `${gameBaseUrl}?game_token=${gameToken}&nakama_server=${nakamaServer}&nakama_key=${nakamaKey}`
- // 跳转到webview
uni.navigateTo({
- url: `/pages-game/game/webview?url=${encodeURIComponent(gameUrl)}`
+ url: `/pages-game/game/minesweeper/play?game_token=${gameToken}&nakama_server=${nakamaServer}&nakama_key=${nakamaKey}`
})
} catch (e) {
uni.showToast({
@@ -133,7 +123,6 @@ export default {
})
} finally {
this.entering = false
- // 刷新资格数
this.loadTickets()
}
}
@@ -142,47 +131,44 @@ export default {
diff --git a/pages-game/game/minesweeper/play.scss b/pages-game/game/minesweeper/play.scss
new file mode 100644
index 0000000..e24be9c
--- /dev/null
+++ b/pages-game/game/minesweeper/play.scss
@@ -0,0 +1,1024 @@
+@import '@/uni.scss';
+
+// =====================================
+// 扫雷游戏 - 暗色毛玻璃风格
+// 与项目整体设计语言保持一致
+// =====================================
+
+.container {
+ min-height: 100vh;
+ background: $bg-dark;
+ color: $text-dark-main;
+ font-size: $font-md;
+ position: relative;
+ overflow: hidden;
+}
+
+// 背景装饰 - 使用项目统一的光球效果
+.bg-dark-grid {
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ z-index: 0;
+ pointer-events: none;
+
+ &::before {
+ content: '';
+ position: absolute;
+ top: -100rpx;
+ right: -100rpx;
+ width: 600rpx;
+ height: 600rpx;
+ background: radial-gradient(circle, rgba($brand-primary, 0.2) 0%, transparent 70%);
+ filter: blur(60rpx);
+ border-radius: 50%;
+ animation: float 10s ease-in-out infinite;
+ }
+
+ &::after {
+ content: '';
+ position: absolute;
+ bottom: 100rpx;
+ left: -150rpx;
+ width: 500rpx;
+ height: 500rpx;
+ background: radial-gradient(circle, rgba($brand-secondary, 0.15) 0%, transparent 70%);
+ filter: blur(50rpx);
+ border-radius: 50%;
+ animation: float 15s ease-in-out infinite reverse;
+ }
+}
+
+@keyframes float {
+
+ 0%,
+ 100% {
+ transform: translateY(0) scale(1);
+ }
+
+ 50% {
+ transform: translateY(-30rpx) scale(1.05);
+ }
+}
+
+// =====================================
+// 暗色毛玻璃卡片 - 项目统一风格
+// =====================================
+.glass-card {
+ background: $bg-dark-card;
+ backdrop-filter: blur(20rpx);
+ border: 1px solid $border-dark;
+ box-shadow: $shadow-card;
+ border-radius: $radius-lg;
+ position: relative;
+ z-index: 1;
+}
+
+// =====================================
+// 加载屏幕
+// =====================================
+.loading-screen {
+ position: fixed;
+ inset: 0;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ z-index: 100;
+ background: rgba(0, 0, 0, 0.9);
+}
+
+.loading-content {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: $spacing-lg;
+}
+
+.loading-spinner {
+ font-size: 80rpx;
+ animation: pulse 1.5s ease-in-out infinite;
+}
+
+.loading-text {
+ color: $text-dark-sub;
+ font-size: $font-md;
+ letter-spacing: 4rpx;
+}
+
+// =====================================
+// 匹配大厅
+// =====================================
+.lobby-screen {
+ position: relative;
+ width: 100%;
+ min-height: 100vh;
+ display: flex;
+ flex-direction: column;
+ z-index: 5;
+}
+
+.bg-decoration {
+ position: absolute;
+ top: 0;
+ left: 0;
+ right: 0;
+ height: 50vh;
+ background: linear-gradient(180deg, rgba($brand-primary, 0.1) 0%, transparent 100%);
+ z-index: -1;
+}
+
+.lobby-content {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ padding: $spacing-xl $spacing-lg;
+ padding-top: calc(80rpx + env(safe-area-inset-top));
+ z-index: 10;
+}
+
+.game-title {
+ font-size: $font-xxl + 8rpx;
+ font-weight: 900;
+ color: $text-dark-main;
+ text-shadow: 0 4rpx 20rpx rgba($brand-primary, 0.4);
+ margin-bottom: $spacing-xxl;
+ letter-spacing: 6rpx;
+}
+
+// =====================================
+// 匹配卡片
+// =====================================
+.match-box {
+ width: 100%;
+ padding: $spacing-xxl $spacing-lg;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ margin-bottom: $spacing-lg;
+}
+
+// 扫描器动画
+.scanner-box {
+ position: relative;
+ width: 200rpx;
+ height: 200rpx;
+ margin-bottom: $spacing-xl;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+
+ // 外圈脉冲
+ &::before {
+ content: '';
+ position: absolute;
+ inset: 0;
+ border: 2rpx solid rgba($brand-primary, 0.4);
+ border-radius: 50%;
+ animation: pulse-ring 2s ease-out infinite;
+ }
+
+ // 内圈旋转
+ &::after {
+ content: '';
+ position: absolute;
+ inset: 20rpx;
+ border: 3rpx dashed rgba($brand-primary, 0.6);
+ border-radius: 50%;
+ animation: rotate 6s linear infinite;
+ }
+}
+
+@keyframes pulse-ring {
+ 0% {
+ transform: scale(1);
+ opacity: 1;
+ }
+
+ 100% {
+ transform: scale(1.4);
+ opacity: 0;
+ }
+}
+
+@keyframes rotate {
+ from {
+ transform: rotate(0deg);
+ }
+
+ to {
+ transform: rotate(360deg);
+ }
+}
+
+// 扫描线
+.scanner-line {
+ position: absolute;
+ width: 100%;
+ height: 3rpx;
+ background: linear-gradient(90deg, transparent, $brand-primary, transparent);
+ animation: scan 2s linear infinite;
+ top: 0;
+}
+
+@keyframes scan {
+ 0% {
+ top: 0%;
+ opacity: 0;
+ }
+
+ 50% {
+ opacity: 1;
+ }
+
+ 100% {
+ top: 100%;
+ opacity: 0;
+ }
+}
+
+.match-spinner {
+ font-size: 90rpx;
+ z-index: 10;
+ filter: drop-shadow(0 0 20rpx rgba($brand-primary, 0.4));
+ animation: bounce 2s ease-in-out infinite;
+}
+
+@keyframes bounce {
+
+ 0%,
+ 100% {
+ transform: translateY(0);
+ }
+
+ 50% {
+ transform: translateY(-15rpx);
+ }
+}
+
+.match-status {
+ font-size: $font-lg;
+ font-weight: 700;
+ color: $brand-primary;
+ margin-bottom: $spacing-xl;
+}
+
+.match-info {
+ width: 100%;
+}
+
+.timer-row {
+ display: flex;
+ justify-content: center;
+ align-items: baseline;
+ gap: $spacing-md;
+ margin-bottom: $spacing-lg;
+}
+
+.timer-label {
+ font-size: $font-sm;
+ color: $text-dark-sub;
+}
+
+.timer-value {
+ font-size: 56rpx;
+ font-weight: 900;
+ color: $text-dark-main;
+}
+
+.status-tip {
+ text-align: center;
+ margin-bottom: $spacing-xl;
+ height: 40rpx;
+
+ text {
+ font-size: $font-sm;
+ }
+}
+
+.tip-normal {
+ color: $color-success;
+}
+
+.tip-warning {
+ color: $color-warning;
+}
+
+.tip-error {
+ color: $color-error;
+ animation: blink 1s ease-in-out infinite;
+}
+
+@keyframes blink {
+
+ 0%,
+ 100% {
+ opacity: 1;
+ }
+
+ 50% {
+ opacity: 0.5;
+ }
+}
+
+.cancel-btn {
+ height: 88rpx;
+ font-size: $font-md;
+ background: transparent;
+ border: 1px solid $border-dark;
+ border-radius: $radius-round;
+ color: $text-dark-sub;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ transition: all $transition-normal $ease-out;
+
+ &:active {
+ background: rgba(255, 255, 255, 0.05);
+ }
+}
+
+// =====================================
+// 开始匹配区域
+// =====================================
+.start-box {
+ width: 100%;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+}
+
+.game-intro-card {
+ width: 100%;
+ padding: $spacing-xl;
+ margin-bottom: $spacing-xxl;
+ display: flex;
+ flex-direction: column;
+ gap: $spacing-lg;
+}
+
+.intro-item {
+ display: flex;
+ align-items: center;
+ gap: $spacing-lg;
+}
+
+.intro-icon {
+ font-size: 40rpx;
+}
+
+.intro-text {
+ font-size: $font-md;
+ color: $text-dark-main;
+ font-weight: 500;
+}
+
+// 按钮使用全局定义
+.start-btn {
+ width: 380rpx;
+ height: 100rpx;
+ font-size: $font-lg;
+ margin-bottom: $spacing-xxl;
+}
+
+.btn-text {
+ color: $text-inverse;
+}
+
+// =====================================
+// 日志区域 - 终端风格
+// =====================================
+.log-section {
+ width: 100%;
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ min-height: 200rpx;
+}
+
+.log-header {
+ padding: $spacing-md $spacing-lg;
+ border-bottom: 1px solid $border-dark;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+}
+
+.log-title {
+ font-size: $font-xxs;
+ color: $text-dark-sub;
+ text-transform: uppercase;
+ letter-spacing: 4rpx;
+}
+
+.online-indicator {
+ width: 12rpx;
+ height: 12rpx;
+ background: $color-success;
+ border-radius: 50%;
+ box-shadow: 0 0 10rpx $color-success;
+}
+
+.mini-logs {
+ flex: 1;
+ padding: $spacing-md;
+}
+
+.log-item {
+ font-size: $font-xs;
+ line-height: 1.8;
+ margin-bottom: $spacing-xs;
+ display: flex;
+ gap: $spacing-sm;
+}
+
+.log-time {
+ color: rgba(255, 255, 255, 0.3);
+ flex-shrink: 0;
+}
+
+.log-content {
+ word-break: break-all;
+}
+
+.log-system .log-content {
+ color: $accent-cyan;
+}
+
+.log-effect .log-content {
+ color: $brand-primary;
+}
+
+.log-empty {
+ height: 100%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ color: rgba(255, 255, 255, 0.2);
+ font-size: $font-sm;
+ font-style: italic;
+}
+
+// =====================================
+// 游戏主界面
+// =====================================
+.game-screen {
+ min-height: 100vh;
+ display: flex;
+ flex-direction: column;
+}
+
+.game-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: $spacing-md $spacing-lg;
+ background: $bg-dark-card;
+ backdrop-filter: blur(20rpx);
+ padding-top: calc($spacing-md + env(safe-area-inset-top));
+ border-bottom: 1px solid $border-dark;
+}
+
+.header-actions {
+ display: flex;
+ gap: $spacing-md;
+}
+
+.header-title {
+ font-size: $font-lg;
+ font-weight: 800;
+ color: $text-dark-main;
+}
+
+.round-badge {
+ background: rgba($brand-primary, 0.2);
+ color: $brand-primary;
+ padding: $spacing-xs $spacing-md;
+ border-radius: $radius-round;
+ font-size: $font-xs;
+ font-weight: bold;
+}
+
+.game-layout {
+ display: flex;
+ flex-direction: column;
+ flex: 1;
+}
+
+.btn-icon {
+ width: 56rpx;
+ height: 56rpx;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ font-size: $font-lg;
+ background: rgba(255, 255, 255, 0.05);
+ border-radius: $radius-md;
+
+ &.active {
+ background: rgba($brand-primary, 0.2);
+ }
+}
+
+// =====================================
+// 对手栏
+// =====================================
+.opponents-bar {
+ height: 140rpx;
+ background: rgba(0, 0, 0, 0.2);
+ border-bottom: 1px solid $border-dark;
+}
+
+.opponents-list {
+ display: flex;
+ padding: $spacing-md;
+ gap: $spacing-md;
+}
+
+.player-card {
+ min-width: 200rpx;
+ height: 100rpx;
+ background: $bg-dark-card;
+ border: 1px solid $border-dark;
+ border-radius: $radius-md;
+ padding: $spacing-sm $spacing-md;
+ display: flex;
+ align-items: center;
+ position: relative;
+ transition: all $transition-normal;
+
+ &.me {
+ background: rgba($brand-primary, 0.1);
+ border-color: rgba($brand-primary, 0.3);
+ }
+
+ &.active-turn {
+ border-color: $brand-primary;
+ box-shadow: 0 0 20rpx rgba($brand-primary, 0.3);
+ }
+
+ &.damaged {
+ animation: shake 0.5s ease-in-out;
+ }
+}
+
+@keyframes shake {
+
+ 0%,
+ 100% {
+ transform: translateX(0);
+ }
+
+ 25% {
+ transform: translateX(-5rpx);
+ }
+
+ 75% {
+ transform: translateX(5rpx);
+ }
+}
+
+.avatar {
+ font-size: 44rpx;
+ margin-right: $spacing-sm;
+
+ &.lg {
+ font-size: 56rpx;
+ }
+}
+
+.player-info {
+ display: flex;
+ flex-direction: column;
+ gap: 4rpx;
+}
+
+.username {
+ font-size: $font-sm;
+ color: $text-dark-main;
+ font-weight: 600;
+}
+
+.hp-bar {
+ display: flex;
+ gap: 2rpx;
+}
+
+.heart {
+ font-size: 18rpx;
+}
+
+.status-icons {
+ display: flex;
+ gap: 4rpx;
+
+ .icon {
+ font-size: 16rpx;
+ }
+}
+
+// =====================================
+// 棋盘区域
+// =====================================
+.board-area {
+ flex: 1;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ padding: $spacing-lg;
+}
+
+.turn-indicator {
+ display: flex;
+ gap: $spacing-md;
+ margin-bottom: $spacing-md;
+}
+
+.turn-badge {
+ padding: $spacing-sm $spacing-lg;
+ background: $bg-dark-card;
+ border: 1px solid $border-dark;
+ border-radius: $radius-round;
+ font-size: $font-md;
+ font-weight: 600;
+ color: $text-dark-sub;
+
+ &.my-turn {
+ background: rgba($brand-primary, 0.15);
+ border-color: $brand-primary;
+ color: $brand-primary;
+ }
+}
+
+.timer-badge {
+ padding: $spacing-sm $spacing-md;
+ background: $bg-dark-card;
+ border-radius: $radius-round;
+ font-size: $font-md;
+ font-weight: 700;
+ color: $text-dark-main;
+
+ &.urgent {
+ color: $color-error;
+ animation: blink 0.5s ease-in-out infinite;
+ }
+}
+
+.timer-progress-bg {
+ width: 660rpx;
+ height: 6rpx;
+ background: rgba(255, 255, 255, 0.1);
+ border-radius: 3rpx;
+ margin-bottom: $spacing-md;
+ overflow: hidden;
+}
+
+.timer-progress-fill {
+ height: 100%;
+ border-radius: 3rpx;
+ transition: width 1s linear;
+
+ &.bg-green {
+ background: $color-success;
+ }
+
+ &.bg-yellow {
+ background: $color-warning;
+ }
+
+ &.bg-red {
+ background: $color-error;
+ }
+}
+
+.grid-board {
+ display: grid;
+ gap: 6rpx;
+ width: 660rpx;
+ height: 660rpx;
+ padding: $spacing-sm;
+ background: $bg-dark-card;
+ border-radius: $radius-lg;
+ border: 1px solid $border-dark;
+}
+
+.grid-cell {
+ background: rgba(255, 255, 255, 0.08);
+ border-radius: $radius-sm;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ transition: all $transition-fast;
+ position: relative;
+
+ &:active {
+ transform: scale(0.95);
+ }
+
+ &.revealed {
+ background: rgba(0, 0, 0, 0.3);
+ }
+
+ &.type-bomb {
+ background: rgba($color-error, 0.2);
+ }
+
+ &.has-magnifier {
+ border: 2rpx dashed rgba($accent-cyan, 0.5);
+ }
+}
+
+.cell-icon {
+ font-size: 32rpx;
+}
+
+.cell-num {
+ font-size: $font-lg;
+ font-weight: 900;
+}
+
+.magnifier-mark {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ position: relative;
+
+ .magnifier-content {
+ font-size: 28rpx;
+ opacity: 0.8;
+ }
+
+ .magnifier-badge {
+ position: absolute;
+ top: 2rpx;
+ right: 2rpx;
+ font-size: 16rpx;
+ }
+}
+
+// =====================================
+// 底部面板
+// =====================================
+.bottom-panel {
+ padding: $spacing-md;
+ padding-bottom: calc($spacing-md + env(safe-area-inset-bottom));
+ background: rgba(0, 0, 0, 0.4);
+ display: flex;
+ gap: $spacing-md;
+ border-top: 1px solid $border-dark;
+}
+
+.game-logs {
+ flex: 1;
+ max-height: 140rpx;
+ padding: $spacing-sm;
+ background: rgba(0, 0, 0, 0.3);
+ border-radius: $radius-md;
+}
+
+.log-line {
+ font-size: $font-xxs;
+ line-height: 1.6;
+ color: $text-dark-sub;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+
+ &.log-system {
+ color: $accent-cyan;
+ }
+
+ &.log-effect {
+ color: $brand-primary;
+ }
+}
+
+// =====================================
+// 弹窗
+// =====================================
+.modal-overlay {
+ position: fixed;
+ inset: 0;
+ background: rgba(0, 0, 0, 0.8);
+ backdrop-filter: blur(10rpx);
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ z-index: 1000;
+}
+
+.modal-content {
+ width: 520rpx;
+ padding: $spacing-xxl $spacing-xl;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: $spacing-lg;
+}
+
+.modal-emoji {
+ font-size: 100rpx;
+}
+
+.modal-title {
+ font-size: 40rpx;
+ font-weight: 900;
+ color: $text-dark-main;
+}
+
+// =====================================
+// 玩法说明弹窗
+// =====================================
+.guide-modal {
+ width: 90%;
+ max-width: 640rpx;
+ max-height: 80vh;
+ display: flex;
+ flex-direction: column;
+}
+
+.guide-header {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: $spacing-lg;
+ border-bottom: 1px solid $border-dark;
+}
+
+.guide-title {
+ font-size: $font-lg;
+ font-weight: 800;
+ color: $text-dark-main;
+}
+
+.close-btn {
+ width: 56rpx;
+ height: 56rpx;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ font-size: $font-lg;
+ color: $text-dark-sub;
+ background: rgba(255, 255, 255, 0.05);
+ border-radius: 50%;
+}
+
+.guide-body {
+ padding: $spacing-lg;
+ max-height: 60vh;
+}
+
+.section-title {
+ display: block;
+ font-size: $font-md;
+ font-weight: 700;
+ color: $brand-primary;
+ margin-bottom: $spacing-md;
+}
+
+.guide-grid {
+ display: flex;
+ flex-direction: column;
+ gap: $spacing-md;
+}
+
+.guide-item {
+ display: flex;
+ align-items: flex-start;
+ gap: $spacing-md;
+ padding: $spacing-sm;
+ background: rgba(255, 255, 255, 0.03);
+ border-radius: $radius-md;
+
+ .icon {
+ font-size: 32rpx;
+ flex-shrink: 0;
+ }
+
+ .desc {
+ display: flex;
+ flex-direction: column;
+ gap: 4rpx;
+ }
+
+ .name {
+ font-size: $font-sm;
+ font-weight: 600;
+ color: $text-dark-main;
+ }
+
+ .detail {
+ font-size: $font-xs;
+ color: $text-dark-sub;
+ line-height: 1.5;
+ }
+}
+
+// =====================================
+// 飘字动画
+// =====================================
+.float-label {
+ position: absolute;
+ font-size: $font-md;
+ font-weight: 900;
+ pointer-events: none;
+ animation: floatUp 1s ease-out forwards;
+ z-index: 100;
+ text-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.8);
+
+ &.global {
+ position: fixed;
+ }
+
+ &.text-damage {
+ color: $color-error;
+ }
+
+ &.text-heal {
+ color: $color-success;
+ }
+
+ &.text-effect {
+ color: $accent-cyan;
+ }
+}
+
+@keyframes floatUp {
+ 0% {
+ opacity: 1;
+ transform: translateY(0) scale(1);
+ }
+
+ 100% {
+ opacity: 0;
+ transform: translateY(-60rpx) scale(0.8);
+ }
+}
+
+// =====================================
+// 屏幕震动 & 通用动画
+// =====================================
+.screen-shake {
+ animation: screenShake 0.4s ease-in-out;
+}
+
+@keyframes screenShake {
+
+ 0%,
+ 100% {
+ transform: translateX(0);
+ }
+
+ 20% {
+ transform: translateX(-8rpx);
+ }
+
+ 40% {
+ transform: translateX(8rpx);
+ }
+
+ 60% {
+ transform: translateX(-4rpx);
+ }
+
+ 80% {
+ transform: translateX(4rpx);
+ }
+}
+
+.fadeInUp {
+ animation: fadeInUp 0.5s ease-out both;
+}
+
+@keyframes fadeInUp {
+ from {
+ opacity: 0;
+ transform: translateY(40rpx);
+ }
+
+ to {
+ opacity: 1;
+ transform: translateY(0);
+ }
+}
+
+.pulse {
+ animation: pulse 2s ease-in-out infinite;
+}
+
+@keyframes pulse {
+
+ 0%,
+ 100% {
+ transform: scale(1);
+ opacity: 0.9;
+ }
+
+ 50% {
+ transform: scale(1.03);
+ opacity: 1;
+ }
+}
\ No newline at end of file
diff --git a/pages-game/game/minesweeper/play.vue b/pages-game/game/minesweeper/play.vue
new file mode 100644
index 0000000..44795c4
--- /dev/null
+++ b/pages-game/game/minesweeper/play.vue
@@ -0,0 +1,596 @@
+
+
+
+
+
+
+
+
+ 📡
+ 正在寻找基站...
+
+
+
+
+
+
+
+
+ 动物扫雷大作战
+
+
+
+
+ 🦁
+
+ 正在匹配全球玩家...
+
+
+
+ 等待时长
+ {{ matchingTimer }}s
+
+
+
+ ⚡ 正在接入星际网道
+ ⏳ 搜索频率增强中...
+ ⚠️ 信号微弱,请重试
+
+
+
+ 取消匹配
+
+
+
+
+
+
+
+ 🎮
+ {{ matchPlayerCount }}人经典竞技模式
+
+
+ 🏆
+ 胜者赢取全额奖励
+
+
+
+
+ 🚀 开始匹配
+
+
+
+
+
+
+
+
+ [{{ log.time }}]
+ {{ log.content }}
+
+ 等待操作指令...
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ p.avatar }}
+
+ {{ p.username || '对手' }}
+
+ {{ i < p.hp ? '❤️' : '🤍' }}
+
+
+ 🛡️
+ ☠️
+ 👻
+ 💖
+ ⏰{{p.timeBombTurns}}
+ ⏭️
+
+
+
+
+
+ {{ l.text }}
+
+
+
+
+
+
+
+
+
+ {{ isMyTurn ? '您的回合' : '等待对手...' }}
+
+
+ ⏱️ {{ turnTimer }}s
+
+
+
+
+
+
+
+
+
+
+ 💣
+
+ {{ cell.neighborBombs > 0 ? cell.neighborBombs : '' }}
+
+ {{ getItemIcon(cell.itemId) }}
+
+
+ {{ getContentIcon(myPlayer.revealedCells[i]) }}
+ 🔍
+
+
+
+
+ {{ l.text }}
+
+
+
+
+
+
+
+
+ {{ myPlayer.avatar }}
+
+ 我
+
+ {{ i < myPlayer.hp ? '❤️' : '🤍' }}
+
+
+ 🛡️
+ ☠️
+ 👻
+ 💖
+ ⏰{{myPlayer.timeBombTurns}}
+ ⏭️
+
+
+
+
+
+ {{ l.text }}
+
+
+
+
+
+
+ {{ log.content }}
+
+
+
+
+
+
+
+
+
+ {{ gameState.winnerId === myUserId ? '🏆' : '💀' }}
+ {{ gameState.winnerId === myUserId ? '胜利!' : '很遗憾失败了' }}
+
+ 🚀 再来一局
+
+
+
+
+
+
+
+
+
+ 🛡️ 道具百科
+
+
+ {{ item.i }}
+
+ {{ item.n }}
+ {{ item.d }}
+
+
+
+
+ 🐾 角色天赋
+
+
+ {{ item.i }}
+
+ {{ item.n }}
+ {{ item.d }}
+
+
+
+
+
+
+
+
+
+ {{ l.text }}
+
+
+
+
+
+
+
+
diff --git a/pages-game/game/webview.vue b/pages-game/game/webview.vue
index 8d0e6b5..a1e797b 100644
--- a/pages-game/game/webview.vue
+++ b/pages-game/game/webview.vue
@@ -43,6 +43,16 @@ function onMessage(e) {
data.forEach(msg => {
if (msg.action === 'close') {
uni.navigateBack()
+ } else if (msg.action === 'playAgain') {
+ // 再来一局: 返回上一页,上一页会自动刷新重新获取token进入游戏
+ console.log('PlayAgain: 返回游戏入口页面')
+ uni.navigateBack({
+ delta: 1,
+ success: () => {
+ // 可选: 发送事件通知上一页刷新
+ uni.$emit('refreshGame')
+ }
+ })
} else if (msg.action === 'game_over') {
// Optional: Refresh user balance or state
}
diff --git a/pages-user/tasks/index.vue b/pages-user/tasks/index.vue
index a547ff4..683f984 100644
--- a/pages-user/tasks/index.vue
+++ b/pages-user/tasks/index.vue
@@ -139,6 +139,7 @@ const claiming = reactive({})
// 用户进度 (汇总)
const userProgress = reactive({
orderCount: 0,
+ orderAmount: 0,
inviteCount: 0,
firstOrder: false,
claimedTiers: {} // { taskId: [tierId1, tierId2] }
@@ -224,6 +225,7 @@ function getTierBadge(tier) {
const metric = tier.metric || ''
if (metric === 'first_order') return '首'
if (metric === 'order_count') return `${tier.threshold}单`
+ if (metric === 'order_amount') return `¥${tier.threshold / 100}`
if (metric === 'invite_count') return `${tier.threshold}人`
return tier.threshold || ''
}
@@ -233,6 +235,7 @@ function getTierConditionText(tier) {
const metric = tier.metric || ''
if (metric === 'first_order') return '完成首笔订单'
if (metric === 'order_count') return `累计下单 ${tier.threshold} 笔`
+ if (metric === 'order_amount') return `累计消费 ¥${tier.threshold / 100}`
if (metric === 'invite_count') return `邀请 ${tier.threshold} 位好友`
return `达成 ${tier.threshold}`
}
@@ -285,6 +288,8 @@ function isTierClaimable(task, tier) {
return userProgress.firstOrder
} else if (metric === 'order_count') {
current = userProgress.orderCount || 0
+ } else if (metric === 'order_amount') {
+ current = userProgress.orderAmount || 0
} else if (metric === 'invite_count') {
current = userProgress.inviteCount || 0
}
@@ -305,6 +310,9 @@ function getTierProgressText(task, tier) {
return userProgress.firstOrder ? '已完成' : '未完成'
} else if (metric === 'order_count') {
current = userProgress.orderCount || 0
+ } else if (metric === 'order_amount') {
+ current = userProgress.orderAmount || 0
+ return `¥${current / 100}/¥${threshold / 100}`
} else if (metric === 'invite_count') {
current = userProgress.inviteCount || 0
}
@@ -368,6 +376,7 @@ async function fetchData() {
try {
const progressRes = await getTaskProgress(list[0].id, userId)
userProgress.orderCount = progressRes.order_count || 0
+ userProgress.orderAmount = progressRes.order_amount || 0
userProgress.inviteCount = progressRes.invite_count || 0
userProgress.firstOrder = progressRes.first_order || false
diff --git a/pages.json b/pages.json
index 0d6562c..2508c37 100644
--- a/pages.json
+++ b/pages.json
@@ -3,7 +3,8 @@
{
"path": "pages/index/index",
"style": {
- "navigationBarTitleText": "柯大鸭"
+ "navigationBarTitleText": "柯大鸭",
+ "enablePullDownRefresh": true
}
},
{
@@ -177,6 +178,17 @@
"navigationBarTitleText": "扫雷 game"
}
},
+ {
+ "path": "game/minesweeper/play",
+ "style": {
+ "navigationStyle": "custom",
+ "navigationBarTitleText": "扫雷对战",
+ "disableScroll": true,
+ "app-plus": {
+ "bounce": "none"
+ }
+ }
+ },
{
"path": "game/webview",
"style": {
diff --git a/pages/index/index.vue b/pages/index/index.vue
index cd34723..f9f3c65 100644
--- a/pages/index/index.vue
+++ b/pages/index/index.vue
@@ -179,7 +179,14 @@ export default {
}
},
onLoad() {
- this.loadHomeData()
+ // 延迟 200ms 首次加载,让 Token/Session 有机会就绪
+ // 同时避免页面动画卡顿
+ setTimeout(() => {
+ this.loadHomeData()
+ }, 200)
+ },
+ onPullDownRefresh() {
+ this.loadHomeData(true)
},
onShow() {
// 只有非首次进入或数据为空时才触发刷新,避免 onLoad/onShow 双重触发
@@ -255,24 +262,55 @@ export default {
const parts = [cat, price].filter(Boolean)
return parts.join(' · ')
},
- async loadHomeData() {
- if (this.isHomeLoading) return
+ async loadHomeData(isRefresh = false) {
+ if (this.isHomeLoading && !isRefresh) return
this.isHomeLoading = true
+
+ // 定义重试函数
+ const fetchWithRetry = async (url, retries = 3) => {
+ for (let i = 0; i < retries; i++) {
+ try {
+ const res = await this.apiGet(url)
+ if (res) return res
+ // 如果返回空,认为是失败,尝试重试
+ if (i < retries - 1) await new Promise(r => setTimeout(r, 1000))
+ } catch (e) {
+ console.error(`Fetch ${url} failed, attempt ${i + 1}`, e)
+ if (i < retries - 1) await new Promise(r => setTimeout(r, 1000))
+ }
+ }
+ return null
+ }
+
// 同时发起请求,大幅提升首屏加载速度
try {
const [nData, bData, acData] = await Promise.all([
- this.apiGet('/api/app/notices').catch(() => null),
- this.apiGet('/api/app/banners').catch(() => null),
- this.apiGet('/api/app/activities').catch(() => null)
+ fetchWithRetry('/api/app/notices'),
+ fetchWithRetry('/api/app/banners'),
+ fetchWithRetry('/api/app/activities')
])
if (nData) this.notices = this.normalizeNotices(nData)
if (bData) this.banners = this.normalizeBanners(bData)
- if (acData) this.activities = this.normalizeActivities(acData)
+
+ // 只有获取到有效活动数据才更新,保留旧数据兜底
+ if (acData) {
+ const validActivities = this.normalizeActivities(acData)
+ if (validActivities.length > 0) {
+ this.activities = validActivities
+ }
+ }
} catch (e) {
console.error('Home data load failed', e)
+ if (isRefresh) {
+ uni.showToast({ title: '刷新失败,请稍后重试', icon: 'none' })
+ }
} finally {
this.isHomeLoading = false
+ if (isRefresh) {
+ uni.stopPullDownRefresh()
+ uni.showToast({ title: '刷新成功', icon: 'none' })
+ }
}
},
onBannerTap(b) {
diff --git a/utils/nakama-adapter.js b/utils/nakama-adapter.js
new file mode 100644
index 0000000..af9bb9f
--- /dev/null
+++ b/utils/nakama-adapter.js
@@ -0,0 +1,71 @@
+// Nakama SDK 小程序适配器
+// 将 uni-app 的 connectSocket 和 Storage 适配到 Web 标准接口
+
+export const WebSocketAdapter = {
+ build: function (url) {
+ const socketTask = uni.connectSocket({
+ url: url,
+ complete: () => { }
+ });
+
+ const webSocket = {
+ url: url,
+ readyState: 0, // CONNECTING
+ onopen: null,
+ onclose: null,
+ onerror: null,
+ onmessage: null,
+ send: (data) => {
+ socketTask.send({
+ data: data
+ });
+ },
+ close: () => {
+ socketTask.close();
+ }
+ };
+
+ socketTask.onOpen(() => {
+ webSocket.readyState = 1; // OPEN
+ if (webSocket.onopen) {
+ webSocket.onopen({ type: 'open' });
+ }
+ });
+
+ socketTask.onClose((res) => {
+ webSocket.readyState = 3; // CLOSED
+ if (webSocket.onclose) {
+ webSocket.onclose({ code: res.code, reason: res.reason, wasClean: true });
+ }
+ });
+
+ socketTask.onError((err) => {
+ if (webSocket.onerror) {
+ webSocket.onerror({ error: err, message: err.errMsg });
+ }
+ });
+
+ socketTask.onMessage((res) => {
+ if (webSocket.onmessage) {
+ webSocket.onmessage({ data: res.data });
+ }
+ });
+
+ return webSocket;
+ }
+};
+
+export const localStorageAdapter = {
+ getItem: (key) => {
+ return uni.getStorageSync(key);
+ },
+ setItem: (key, value) => {
+ uni.setStorageSync(key, value);
+ },
+ removeItem: (key) => {
+ uni.removeStorageSync(key);
+ },
+ clear: () => {
+ uni.clearStorageSync();
+ }
+};
diff --git a/utils/nakama-js/nakama-js.js b/utils/nakama-js/nakama-js.js
new file mode 100644
index 0000000..c50d5a3
--- /dev/null
+++ b/utils/nakama-js/nakama-js.js
@@ -0,0 +1,5305 @@
+/* eslint-disable */
+// --- Polyfill Start ---
+var uniFetch = function (url, options) {
+ options = options || {};
+ return new Promise(function (resolve, reject) {
+ var method = (options.method || 'GET').toUpperCase();
+ var header = options.headers || {};
+
+ if (typeof header.forEach === 'function') {
+ var plain = {};
+ header.forEach(function (v, k) { plain[k] = v; });
+ header = plain;
+ }
+
+ if (!header['Content-Type'] && method !== 'GET') {
+ header['Content-Type'] = 'application/json';
+ }
+
+ console.log(`[Fetch Polyfill] ${method} ${url}`);
+
+ uni.request({
+ url: url,
+ method: method,
+ header: header,
+ data: options.body,
+ dataType: 'text',
+ responseType: 'text',
+ success: function (res) {
+ resolve({
+ ok: res.statusCode >= 200 && res.statusCode < 300,
+ status: res.statusCode,
+ statusText: res.statusCode === 200 ? 'OK' : '',
+ headers: {
+ get: function (key) {
+ return res.header[key] || res.header[key.toLowerCase()];
+ }
+ },
+ text: function () {
+ return Promise.resolve(res.data);
+ },
+ json: function () {
+ try {
+ return Promise.resolve(JSON.parse(res.data));
+ } catch (e) {
+ return Promise.reject(e);
+ }
+ }
+ });
+ },
+ fail: function (err) {
+ reject(new TypeError(err.errMsg || 'Network request failed'));
+ }
+ });
+ });
+};
+
+// 显式声明模块级变量,确保文件内引用的 fetch 都指向这里
+var fetch = uniFetch;
+
+// 同时尝试覆盖全局对象,以防万一
+if (typeof globalThis !== "undefined") globalThis.fetch = uniFetch;
+if (typeof global !== "undefined") global.fetch = uniFetch;
+if (typeof window !== "undefined") window.fetch = uniFetch;
+// --- Polyfill End ---
+
+var __defProp = Object.defineProperty;
+var __getOwnPropSymbols = Object.getOwnPropertySymbols;
+var __hasOwnProp = Object.prototype.hasOwnProperty;
+var __propIsEnum = Object.prototype.propertyIsEnumerable;
+var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
+var __spreadValues = (a, b) => {
+ for (var prop in b || (b = {}))
+ if (__hasOwnProp.call(b, prop))
+ __defNormalProp(a, prop, b[prop]);
+ if (__getOwnPropSymbols)
+ for (var prop of __getOwnPropSymbols(b)) {
+ if (__propIsEnum.call(b, prop))
+ __defNormalProp(a, prop, b[prop]);
+ }
+ return a;
+};
+var __async = (__this, __arguments, generator) => {
+ return new Promise((resolve, reject) => {
+ var fulfilled = (value) => {
+ try {
+ step(generator.next(value));
+ } catch (e) {
+ reject(e);
+ }
+ };
+ var rejected = (value) => {
+ try {
+ step(generator.throw(value));
+ } catch (e) {
+ reject(e);
+ }
+ };
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
+ step((generator = generator.apply(__this, __arguments)).next());
+ });
+};
+
+// ../../node_modules/whatwg-fetch/fetch.js
+var global = typeof globalThis !== "undefined" && globalThis || typeof self !== "undefined" && self || typeof global !== "undefined" && global;
+var support = {
+ searchParams: "URLSearchParams" in global,
+ iterable: "Symbol" in global && "iterator" in Symbol,
+ blob: "FileReader" in global && "Blob" in global && function () {
+ try {
+ new Blob();
+ return true;
+ } catch (e) {
+ return false;
+ }
+ }(),
+ formData: "FormData" in global,
+ arrayBuffer: "ArrayBuffer" in global
+};
+function isDataView(obj) {
+ return obj && DataView.prototype.isPrototypeOf(obj);
+}
+if (support.arrayBuffer) {
+ viewClasses = [
+ "[object Int8Array]",
+ "[object Uint8Array]",
+ "[object Uint8ClampedArray]",
+ "[object Int16Array]",
+ "[object Uint16Array]",
+ "[object Int32Array]",
+ "[object Uint32Array]",
+ "[object Float32Array]",
+ "[object Float64Array]"
+ ];
+ isArrayBufferView = ArrayBuffer.isView || function (obj) {
+ return obj && viewClasses.indexOf(Object.prototype.toString.call(obj)) > -1;
+ };
+}
+var viewClasses;
+var isArrayBufferView;
+function normalizeName(name) {
+ if (typeof name !== "string") {
+ name = String(name);
+ }
+ if (/[^a-z0-9\-#$%&'*+.^_`|~!]/i.test(name) || name === "") {
+ throw new TypeError('Invalid character in header field name: "' + name + '"');
+ }
+ return name.toLowerCase();
+}
+function normalizeValue(value) {
+ if (typeof value !== "string") {
+ value = String(value);
+ }
+ return value;
+}
+function iteratorFor(items) {
+ var iterator = {
+ next: function () {
+ var value = items.shift();
+ return { done: value === void 0, value };
+ }
+ };
+ if (support.iterable) {
+ iterator[Symbol.iterator] = function () {
+ return iterator;
+ };
+ }
+ return iterator;
+}
+function Headers(headers) {
+ this.map = {};
+ if (headers instanceof Headers) {
+ headers.forEach(function (value, name) {
+ this.append(name, value);
+ }, this);
+ } else if (Array.isArray(headers)) {
+ headers.forEach(function (header) {
+ this.append(header[0], header[1]);
+ }, this);
+ } else if (headers) {
+ Object.getOwnPropertyNames(headers).forEach(function (name) {
+ this.append(name, headers[name]);
+ }, this);
+ }
+}
+Headers.prototype.append = function (name, value) {
+ name = normalizeName(name);
+ value = normalizeValue(value);
+ var oldValue = this.map[name];
+ this.map[name] = oldValue ? oldValue + ", " + value : value;
+};
+Headers.prototype["delete"] = function (name) {
+ delete this.map[normalizeName(name)];
+};
+Headers.prototype.get = function (name) {
+ name = normalizeName(name);
+ return this.has(name) ? this.map[name] : null;
+};
+Headers.prototype.has = function (name) {
+ return this.map.hasOwnProperty(normalizeName(name));
+};
+Headers.prototype.set = function (name, value) {
+ this.map[normalizeName(name)] = normalizeValue(value);
+};
+Headers.prototype.forEach = function (callback, thisArg) {
+ for (var name in this.map) {
+ if (this.map.hasOwnProperty(name)) {
+ callback.call(thisArg, this.map[name], name, this);
+ }
+ }
+};
+Headers.prototype.keys = function () {
+ var items = [];
+ this.forEach(function (value, name) {
+ items.push(name);
+ });
+ return iteratorFor(items);
+};
+Headers.prototype.values = function () {
+ var items = [];
+ this.forEach(function (value) {
+ items.push(value);
+ });
+ return iteratorFor(items);
+};
+Headers.prototype.entries = function () {
+ var items = [];
+ this.forEach(function (value, name) {
+ items.push([name, value]);
+ });
+ return iteratorFor(items);
+};
+if (support.iterable) {
+ Headers.prototype[Symbol.iterator] = Headers.prototype.entries;
+}
+function consumed(body) {
+ if (body.bodyUsed) {
+ return Promise.reject(new TypeError("Already read"));
+ }
+ body.bodyUsed = true;
+}
+function fileReaderReady(reader) {
+ return new Promise(function (resolve, reject) {
+ reader.onload = function () {
+ resolve(reader.result);
+ };
+ reader.onerror = function () {
+ reject(reader.error);
+ };
+ });
+}
+function readBlobAsArrayBuffer(blob) {
+ var reader = new FileReader();
+ var promise = fileReaderReady(reader);
+ reader.readAsArrayBuffer(blob);
+ return promise;
+}
+function readBlobAsText(blob) {
+ var reader = new FileReader();
+ var promise = fileReaderReady(reader);
+ reader.readAsText(blob);
+ return promise;
+}
+function readArrayBufferAsText(buf) {
+ var view = new Uint8Array(buf);
+ var chars2 = new Array(view.length);
+ for (var i = 0; i < view.length; i++) {
+ chars2[i] = String.fromCharCode(view[i]);
+ }
+ return chars2.join("");
+}
+function bufferClone(buf) {
+ if (buf.slice) {
+ return buf.slice(0);
+ } else {
+ var view = new Uint8Array(buf.byteLength);
+ view.set(new Uint8Array(buf));
+ return view.buffer;
+ }
+}
+function Body() {
+ this.bodyUsed = false;
+ this._initBody = function (body) {
+ this.bodyUsed = this.bodyUsed;
+ this._bodyInit = body;
+ if (!body) {
+ this._bodyText = "";
+ } else if (typeof body === "string") {
+ this._bodyText = body;
+ } else if (support.blob && Blob.prototype.isPrototypeOf(body)) {
+ this._bodyBlob = body;
+ } else if (support.formData && FormData.prototype.isPrototypeOf(body)) {
+ this._bodyFormData = body;
+ } else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) {
+ this._bodyText = body.toString();
+ } else if (support.arrayBuffer && support.blob && isDataView(body)) {
+ this._bodyArrayBuffer = bufferClone(body.buffer);
+ this._bodyInit = new Blob([this._bodyArrayBuffer]);
+ } else if (support.arrayBuffer && (ArrayBuffer.prototype.isPrototypeOf(body) || isArrayBufferView(body))) {
+ this._bodyArrayBuffer = bufferClone(body);
+ } else {
+ this._bodyText = body = Object.prototype.toString.call(body);
+ }
+ if (!this.headers.get("content-type")) {
+ if (typeof body === "string") {
+ this.headers.set("content-type", "text/plain;charset=UTF-8");
+ } else if (this._bodyBlob && this._bodyBlob.type) {
+ this.headers.set("content-type", this._bodyBlob.type);
+ } else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) {
+ this.headers.set("content-type", "application/x-www-form-urlencoded;charset=UTF-8");
+ }
+ }
+ };
+ if (support.blob) {
+ this.blob = function () {
+ var rejected = consumed(this);
+ if (rejected) {
+ return rejected;
+ }
+ if (this._bodyBlob) {
+ return Promise.resolve(this._bodyBlob);
+ } else if (this._bodyArrayBuffer) {
+ return Promise.resolve(new Blob([this._bodyArrayBuffer]));
+ } else if (this._bodyFormData) {
+ throw new Error("could not read FormData body as blob");
+ } else {
+ return Promise.resolve(new Blob([this._bodyText]));
+ }
+ };
+ this.arrayBuffer = function () {
+ if (this._bodyArrayBuffer) {
+ var isConsumed = consumed(this);
+ if (isConsumed) {
+ return isConsumed;
+ }
+ if (ArrayBuffer.isView(this._bodyArrayBuffer)) {
+ return Promise.resolve(
+ this._bodyArrayBuffer.buffer.slice(
+ this._bodyArrayBuffer.byteOffset,
+ this._bodyArrayBuffer.byteOffset + this._bodyArrayBuffer.byteLength
+ )
+ );
+ } else {
+ return Promise.resolve(this._bodyArrayBuffer);
+ }
+ } else {
+ return this.blob().then(readBlobAsArrayBuffer);
+ }
+ };
+ }
+ this.text = function () {
+ var rejected = consumed(this);
+ if (rejected) {
+ return rejected;
+ }
+ if (this._bodyBlob) {
+ return readBlobAsText(this._bodyBlob);
+ } else if (this._bodyArrayBuffer) {
+ return Promise.resolve(readArrayBufferAsText(this._bodyArrayBuffer));
+ } else if (this._bodyFormData) {
+ throw new Error("could not read FormData body as text");
+ } else {
+ return Promise.resolve(this._bodyText);
+ }
+ };
+ if (support.formData) {
+ this.formData = function () {
+ return this.text().then(decode);
+ };
+ }
+ this.json = function () {
+ return this.text().then(JSON.parse);
+ };
+ return this;
+}
+var methods = ["DELETE", "GET", "HEAD", "OPTIONS", "POST", "PUT"];
+function normalizeMethod(method) {
+ var upcased = method.toUpperCase();
+ return methods.indexOf(upcased) > -1 ? upcased : method;
+}
+function Request(input, options) {
+ if (!(this instanceof Request)) {
+ throw new TypeError('Please use the "new" operator, this DOM object constructor cannot be called as a function.');
+ }
+ options = options || {};
+ var body = options.body;
+ if (input instanceof Request) {
+ if (input.bodyUsed) {
+ throw new TypeError("Already read");
+ }
+ this.url = input.url;
+ this.credentials = input.credentials;
+ if (!options.headers) {
+ this.headers = new Headers(input.headers);
+ }
+ this.method = input.method;
+ this.mode = input.mode;
+ this.signal = input.signal;
+ if (!body && input._bodyInit != null) {
+ body = input._bodyInit;
+ input.bodyUsed = true;
+ }
+ } else {
+ this.url = String(input);
+ }
+ this.credentials = options.credentials || this.credentials || "same-origin";
+ if (options.headers || !this.headers) {
+ this.headers = new Headers(options.headers);
+ }
+ this.method = normalizeMethod(options.method || this.method || "GET");
+ this.mode = options.mode || this.mode || null;
+ this.signal = options.signal || this.signal;
+ this.referrer = null;
+ if ((this.method === "GET" || this.method === "HEAD") && body) {
+ throw new TypeError("Body not allowed for GET or HEAD requests");
+ }
+ this._initBody(body);
+ if (this.method === "GET" || this.method === "HEAD") {
+ if (options.cache === "no-store" || options.cache === "no-cache") {
+ var reParamSearch = /([?&])_=[^&]*/;
+ if (reParamSearch.test(this.url)) {
+ this.url = this.url.replace(reParamSearch, "$1_=" + (/* @__PURE__ */ new Date()).getTime());
+ } else {
+ var reQueryString = /\?/;
+ this.url += (reQueryString.test(this.url) ? "&" : "?") + "_=" + (/* @__PURE__ */ new Date()).getTime();
+ }
+ }
+ }
+}
+Request.prototype.clone = function () {
+ return new Request(this, { body: this._bodyInit });
+};
+function decode(body) {
+ var form = new FormData();
+ body.trim().split("&").forEach(function (bytes) {
+ if (bytes) {
+ var split = bytes.split("=");
+ var name = split.shift().replace(/\+/g, " ");
+ var value = split.join("=").replace(/\+/g, " ");
+ form.append(decodeURIComponent(name), decodeURIComponent(value));
+ }
+ });
+ return form;
+}
+function parseHeaders(rawHeaders) {
+ var headers = new Headers();
+ var preProcessedHeaders = rawHeaders.replace(/\r?\n[\t ]+/g, " ");
+ preProcessedHeaders.split("\r").map(function (header) {
+ return header.indexOf("\n") === 0 ? header.substr(1, header.length) : header;
+ }).forEach(function (line) {
+ var parts = line.split(":");
+ var key = parts.shift().trim();
+ if (key) {
+ var value = parts.join(":").trim();
+ headers.append(key, value);
+ }
+ });
+ return headers;
+}
+Body.call(Request.prototype);
+function Response(bodyInit, options) {
+ if (!(this instanceof Response)) {
+ throw new TypeError('Please use the "new" operator, this DOM object constructor cannot be called as a function.');
+ }
+ if (!options) {
+ options = {};
+ }
+ this.type = "default";
+ this.status = options.status === void 0 ? 200 : options.status;
+ this.ok = this.status >= 200 && this.status < 300;
+ this.statusText = options.statusText === void 0 ? "" : "" + options.statusText;
+ this.headers = new Headers(options.headers);
+ this.url = options.url || "";
+ this._initBody(bodyInit);
+}
+Body.call(Response.prototype);
+Response.prototype.clone = function () {
+ return new Response(this._bodyInit, {
+ status: this.status,
+ statusText: this.statusText,
+ headers: new Headers(this.headers),
+ url: this.url
+ });
+};
+Response.error = function () {
+ var response = new Response(null, { status: 0, statusText: "" });
+ response.type = "error";
+ return response;
+};
+var redirectStatuses = [301, 302, 303, 307, 308];
+Response.redirect = function (url, status) {
+ if (redirectStatuses.indexOf(status) === -1) {
+ throw new RangeError("Invalid status code");
+ }
+ return new Response(null, { status, headers: { location: url } });
+};
+var DOMException = global.DOMException;
+try {
+ new DOMException();
+} catch (err) {
+ DOMException = function (message, name) {
+ this.message = message;
+ this.name = name;
+ var error = Error(message);
+ this.stack = error.stack;
+ };
+ DOMException.prototype = Object.create(Error.prototype);
+ DOMException.prototype.constructor = DOMException;
+}
+function fetch2(input, init) {
+ return new Promise(function (resolve, reject) {
+ var request = new Request(input, init);
+ if (request.signal && request.signal.aborted) {
+ return reject(new DOMException("Aborted", "AbortError"));
+ }
+ var xhr = new XMLHttpRequest();
+ function abortXhr() {
+ xhr.abort();
+ }
+ xhr.onload = function () {
+ var options = {
+ status: xhr.status,
+ statusText: xhr.statusText,
+ headers: parseHeaders(xhr.getAllResponseHeaders() || "")
+ };
+ options.url = "responseURL" in xhr ? xhr.responseURL : options.headers.get("X-Request-URL");
+ var body = "response" in xhr ? xhr.response : xhr.responseText;
+ setTimeout(function () {
+ resolve(new Response(body, options));
+ }, 0);
+ };
+ xhr.onerror = function () {
+ setTimeout(function () {
+ reject(new TypeError("Network request failed"));
+ }, 0);
+ };
+ xhr.ontimeout = function () {
+ setTimeout(function () {
+ reject(new TypeError("Network request failed"));
+ }, 0);
+ };
+ xhr.onabort = function () {
+ setTimeout(function () {
+ reject(new DOMException("Aborted", "AbortError"));
+ }, 0);
+ };
+ function fixUrl(url) {
+ try {
+ return url === "" && global.location.href ? global.location.href : url;
+ } catch (e) {
+ return url;
+ }
+ }
+ xhr.open(request.method, fixUrl(request.url), true);
+ if (request.credentials === "include") {
+ xhr.withCredentials = true;
+ } else if (request.credentials === "omit") {
+ xhr.withCredentials = false;
+ }
+ if ("responseType" in xhr) {
+ if (support.blob) {
+ xhr.responseType = "blob";
+ } else if (support.arrayBuffer && request.headers.get("Content-Type") && request.headers.get("Content-Type").indexOf("application/octet-stream") !== -1) {
+ xhr.responseType = "arraybuffer";
+ }
+ }
+ if (init && typeof init.headers === "object" && !(init.headers instanceof Headers)) {
+ Object.getOwnPropertyNames(init.headers).forEach(function (name) {
+ xhr.setRequestHeader(name, normalizeValue(init.headers[name]));
+ });
+ } else {
+ request.headers.forEach(function (value, name) {
+ xhr.setRequestHeader(name, value);
+ });
+ }
+ if (request.signal) {
+ request.signal.addEventListener("abort", abortXhr);
+ xhr.onreadystatechange = function () {
+ if (xhr.readyState === 4) {
+ request.signal.removeEventListener("abort", abortXhr);
+ }
+ };
+ }
+ xhr.send(typeof request._bodyInit === "undefined" ? null : request._bodyInit);
+ });
+}
+fetch2.polyfill = true;
+if (!global.fetch) {
+ global.fetch = fetch2;
+ global.Headers = Headers;
+ global.Request = Request;
+ global.Response = Response;
+}
+
+// ../../node_modules/js-base64/base64.mjs
+var _hasatob = typeof atob === "function";
+var _hasbtoa = typeof btoa === "function";
+var _hasBuffer = typeof Buffer === "function";
+var _TD = typeof TextDecoder === "function" ? new TextDecoder() : void 0;
+var _TE = typeof TextEncoder === "function" ? new TextEncoder() : void 0;
+var b64ch = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
+var b64chs = Array.prototype.slice.call(b64ch);
+var b64tab = ((a) => {
+ let tab = {};
+ a.forEach((c, i) => tab[c] = i);
+ return tab;
+})(b64chs);
+var b64re = /^(?:[A-Za-z\d+\/]{4})*?(?:[A-Za-z\d+\/]{2}(?:==)?|[A-Za-z\d+\/]{3}=?)?$/;
+var _fromCC = String.fromCharCode.bind(String);
+var _U8Afrom = typeof Uint8Array.from === "function" ? Uint8Array.from.bind(Uint8Array) : (it) => new Uint8Array(Array.prototype.slice.call(it, 0));
+var _mkUriSafe = (src) => src.replace(/=/g, "").replace(/[+\/]/g, (m0) => m0 == "+" ? "-" : "_");
+var _tidyB64 = (s) => s.replace(/[^A-Za-z0-9\+\/]/g, "");
+var btoaPolyfill = (bin) => {
+ let u32, c0, c1, c2, asc = "";
+ const pad = bin.length % 3;
+ for (let i = 0; i < bin.length;) {
+ if ((c0 = bin.charCodeAt(i++)) > 255 || (c1 = bin.charCodeAt(i++)) > 255 || (c2 = bin.charCodeAt(i++)) > 255)
+ throw new TypeError("invalid character found");
+ u32 = c0 << 16 | c1 << 8 | c2;
+ asc += b64chs[u32 >> 18 & 63] + b64chs[u32 >> 12 & 63] + b64chs[u32 >> 6 & 63] + b64chs[u32 & 63];
+ }
+ return pad ? asc.slice(0, pad - 3) + "===".substring(pad) : asc;
+};
+var _btoa = _hasbtoa ? (bin) => btoa(bin) : _hasBuffer ? (bin) => Buffer.from(bin, "binary").toString("base64") : btoaPolyfill;
+var _fromUint8Array = _hasBuffer ? (u8a) => Buffer.from(u8a).toString("base64") : (u8a) => {
+ const maxargs = 4096;
+ let strs = [];
+ for (let i = 0, l = u8a.length; i < l; i += maxargs) {
+ strs.push(_fromCC.apply(null, u8a.subarray(i, i + maxargs)));
+ }
+ return _btoa(strs.join(""));
+};
+var cb_utob = (c) => {
+ if (c.length < 2) {
+ var cc = c.charCodeAt(0);
+ return cc < 128 ? c : cc < 2048 ? _fromCC(192 | cc >>> 6) + _fromCC(128 | cc & 63) : _fromCC(224 | cc >>> 12 & 15) + _fromCC(128 | cc >>> 6 & 63) + _fromCC(128 | cc & 63);
+ } else {
+ var cc = 65536 + (c.charCodeAt(0) - 55296) * 1024 + (c.charCodeAt(1) - 56320);
+ return _fromCC(240 | cc >>> 18 & 7) + _fromCC(128 | cc >>> 12 & 63) + _fromCC(128 | cc >>> 6 & 63) + _fromCC(128 | cc & 63);
+ }
+};
+var re_utob = /[\uD800-\uDBFF][\uDC00-\uDFFFF]|[^\x00-\x7F]/g;
+var utob = (u) => u.replace(re_utob, cb_utob);
+var _encode = _hasBuffer ? (s) => Buffer.from(s, "utf8").toString("base64") : _TE ? (s) => _fromUint8Array(_TE.encode(s)) : (s) => _btoa(utob(s));
+var encode = (src, urlsafe = false) => urlsafe ? _mkUriSafe(_encode(src)) : _encode(src);
+var re_btou = /[\xC0-\xDF][\x80-\xBF]|[\xE0-\xEF][\x80-\xBF]{2}|[\xF0-\xF7][\x80-\xBF]{3}/g;
+var cb_btou = (cccc) => {
+ switch (cccc.length) {
+ case 4:
+ var cp = (7 & cccc.charCodeAt(0)) << 18 | (63 & cccc.charCodeAt(1)) << 12 | (63 & cccc.charCodeAt(2)) << 6 | 63 & cccc.charCodeAt(3), offset = cp - 65536;
+ return _fromCC((offset >>> 10) + 55296) + _fromCC((offset & 1023) + 56320);
+ case 3:
+ return _fromCC((15 & cccc.charCodeAt(0)) << 12 | (63 & cccc.charCodeAt(1)) << 6 | 63 & cccc.charCodeAt(2));
+ default:
+ return _fromCC((31 & cccc.charCodeAt(0)) << 6 | 63 & cccc.charCodeAt(1));
+ }
+};
+var btou = (b) => b.replace(re_btou, cb_btou);
+var atobPolyfill = (asc) => {
+ asc = asc.replace(/\s+/g, "");
+ if (!b64re.test(asc))
+ throw new TypeError("malformed base64.");
+ asc += "==".slice(2 - (asc.length & 3));
+ let u24, bin = "", r1, r2;
+ for (let i = 0; i < asc.length;) {
+ u24 = b64tab[asc.charAt(i++)] << 18 | b64tab[asc.charAt(i++)] << 12 | (r1 = b64tab[asc.charAt(i++)]) << 6 | (r2 = b64tab[asc.charAt(i++)]);
+ bin += r1 === 64 ? _fromCC(u24 >> 16 & 255) : r2 === 64 ? _fromCC(u24 >> 16 & 255, u24 >> 8 & 255) : _fromCC(u24 >> 16 & 255, u24 >> 8 & 255, u24 & 255);
+ }
+ return bin;
+};
+var _atob = _hasatob ? (asc) => atob(_tidyB64(asc)) : _hasBuffer ? (asc) => Buffer.from(asc, "base64").toString("binary") : atobPolyfill;
+var _toUint8Array = _hasBuffer ? (a) => _U8Afrom(Buffer.from(a, "base64")) : (a) => _U8Afrom(_atob(a).split("").map((c) => c.charCodeAt(0)));
+var _decode = _hasBuffer ? (a) => Buffer.from(a, "base64").toString("utf8") : _TD ? (a) => _TD.decode(_toUint8Array(a)) : (a) => btou(_atob(a));
+var _unURI = (a) => _tidyB64(a.replace(/[-_]/g, (m0) => m0 == "-" ? "+" : "/"));
+var decode2 = (src) => _decode(_unURI(src));
+
+// utils.ts
+function buildFetchOptions(method, options, bodyJson) {
+ const fetchOptions = __spreadValues(__spreadValues({}, { method }), options);
+ fetchOptions.headers = __spreadValues({}, options.headers);
+ if (typeof XMLHttpRequest !== "undefined") {
+ const descriptor = Object.getOwnPropertyDescriptor(XMLHttpRequest.prototype, "withCredentials");
+ if (!(descriptor == null ? void 0 : descriptor.set)) {
+ fetchOptions.credentials = "cocos-ignore";
+ }
+ }
+ if (!Object.keys(fetchOptions.headers).includes("Accept")) {
+ fetchOptions.headers["Accept"] = "application/json";
+ }
+ if (!Object.keys(fetchOptions.headers).includes("Content-Type")) {
+ fetchOptions.headers["Content-Type"] = "application/json";
+ }
+ Object.keys(fetchOptions.headers).forEach((key) => {
+ if (!fetchOptions.headers[key]) {
+ delete fetchOptions.headers[key];
+ }
+ });
+ if (bodyJson) {
+ fetchOptions.body = bodyJson;
+ }
+ return fetchOptions;
+}
+
+// api.gen.ts
+var NakamaApi = class {
+ constructor(serverKey, basePath, timeoutMs) {
+ this.serverKey = serverKey;
+ this.basePath = basePath;
+ this.timeoutMs = timeoutMs;
+ }
+ /** A healthcheck which load balancers can use to check the service. */
+ healthcheck(bearerToken, options = {}) {
+ const urlPath = "/healthcheck";
+ const queryParams = /* @__PURE__ */ new Map();
+ let bodyJson = "";
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("GET", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Delete the current user's account. */
+ deleteAccount(bearerToken, options = {}) {
+ const urlPath = "/v2/account";
+ const queryParams = /* @__PURE__ */ new Map();
+ let bodyJson = "";
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("DELETE", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Fetch the current user's account. */
+ getAccount(bearerToken, options = {}) {
+ const urlPath = "/v2/account";
+ const queryParams = /* @__PURE__ */ new Map();
+ let bodyJson = "";
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("GET", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Update fields in the current user's account. */
+ updateAccount(bearerToken, body, options = {}) {
+ if (body === null || body === void 0) {
+ throw new Error("'body' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/account";
+ const queryParams = /* @__PURE__ */ new Map();
+ let bodyJson = "";
+ bodyJson = JSON.stringify(body || {});
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("PUT", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Authenticate a user with an Apple ID against the server. */
+ authenticateApple(basicAuthUsername, basicAuthPassword, account, create, username, options = {}) {
+ if (account === null || account === void 0) {
+ throw new Error("'account' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/account/authenticate/apple";
+ const queryParams = /* @__PURE__ */ new Map();
+ queryParams.set("create", create);
+ queryParams.set("username", username);
+ let bodyJson = "";
+ bodyJson = JSON.stringify(account || {});
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("POST", options, bodyJson);
+ if (basicAuthUsername) {
+ fetchOptions.headers["Authorization"] = "Basic " + encode(basicAuthUsername + ":" + basicAuthPassword);
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Authenticate a user with a custom id against the server. */
+ authenticateCustom(basicAuthUsername, basicAuthPassword, account, create, username, options = {}) {
+ if (account === null || account === void 0) {
+ throw new Error("'account' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/account/authenticate/custom";
+ const queryParams = /* @__PURE__ */ new Map();
+ queryParams.set("create", create);
+ queryParams.set("username", username);
+ let bodyJson = "";
+ bodyJson = JSON.stringify(account || {});
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("POST", options, bodyJson);
+ if (basicAuthUsername) {
+ fetchOptions.headers["Authorization"] = "Basic " + encode(basicAuthUsername + ":" + basicAuthPassword);
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Authenticate a user with a device id against the server. */
+ authenticateDevice(basicAuthUsername, basicAuthPassword, account, create, username, options = {}) {
+ if (account === null || account === void 0) {
+ throw new Error("'account' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/account/authenticate/device";
+ const queryParams = /* @__PURE__ */ new Map();
+ queryParams.set("create", create);
+ queryParams.set("username", username);
+ let bodyJson = "";
+ bodyJson = JSON.stringify(account || {});
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("POST", options, bodyJson);
+ if (basicAuthUsername) {
+ fetchOptions.headers["Authorization"] = "Basic " + encode(basicAuthUsername + ":" + basicAuthPassword);
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Authenticate a user with an email+password against the server. */
+ authenticateEmail(basicAuthUsername, basicAuthPassword, account, create, username, options = {}) {
+ if (account === null || account === void 0) {
+ throw new Error("'account' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/account/authenticate/email";
+ const queryParams = /* @__PURE__ */ new Map();
+ queryParams.set("create", create);
+ queryParams.set("username", username);
+ let bodyJson = "";
+ bodyJson = JSON.stringify(account || {});
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("POST", options, bodyJson);
+ if (basicAuthUsername) {
+ fetchOptions.headers["Authorization"] = "Basic " + encode(basicAuthUsername + ":" + basicAuthPassword);
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Authenticate a user with a Facebook OAuth token against the server. */
+ authenticateFacebook(basicAuthUsername, basicAuthPassword, account, create, username, sync, options = {}) {
+ if (account === null || account === void 0) {
+ throw new Error("'account' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/account/authenticate/facebook";
+ const queryParams = /* @__PURE__ */ new Map();
+ queryParams.set("create", create);
+ queryParams.set("username", username);
+ queryParams.set("sync", sync);
+ let bodyJson = "";
+ bodyJson = JSON.stringify(account || {});
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("POST", options, bodyJson);
+ if (basicAuthUsername) {
+ fetchOptions.headers["Authorization"] = "Basic " + encode(basicAuthUsername + ":" + basicAuthPassword);
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Authenticate a user with a Facebook Instant Game token against the server. */
+ authenticateFacebookInstantGame(basicAuthUsername, basicAuthPassword, account, create, username, options = {}) {
+ if (account === null || account === void 0) {
+ throw new Error("'account' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/account/authenticate/facebookinstantgame";
+ const queryParams = /* @__PURE__ */ new Map();
+ queryParams.set("create", create);
+ queryParams.set("username", username);
+ let bodyJson = "";
+ bodyJson = JSON.stringify(account || {});
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("POST", options, bodyJson);
+ if (basicAuthUsername) {
+ fetchOptions.headers["Authorization"] = "Basic " + encode(basicAuthUsername + ":" + basicAuthPassword);
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Authenticate a user with Apple's GameCenter against the server. */
+ authenticateGameCenter(basicAuthUsername, basicAuthPassword, account, create, username, options = {}) {
+ if (account === null || account === void 0) {
+ throw new Error("'account' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/account/authenticate/gamecenter";
+ const queryParams = /* @__PURE__ */ new Map();
+ queryParams.set("create", create);
+ queryParams.set("username", username);
+ let bodyJson = "";
+ bodyJson = JSON.stringify(account || {});
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("POST", options, bodyJson);
+ if (basicAuthUsername) {
+ fetchOptions.headers["Authorization"] = "Basic " + encode(basicAuthUsername + ":" + basicAuthPassword);
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Authenticate a user with Google against the server. */
+ authenticateGoogle(basicAuthUsername, basicAuthPassword, account, create, username, options = {}) {
+ if (account === null || account === void 0) {
+ throw new Error("'account' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/account/authenticate/google";
+ const queryParams = /* @__PURE__ */ new Map();
+ queryParams.set("create", create);
+ queryParams.set("username", username);
+ let bodyJson = "";
+ bodyJson = JSON.stringify(account || {});
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("POST", options, bodyJson);
+ if (basicAuthUsername) {
+ fetchOptions.headers["Authorization"] = "Basic " + encode(basicAuthUsername + ":" + basicAuthPassword);
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Authenticate a user with Steam against the server. */
+ authenticateSteam(basicAuthUsername, basicAuthPassword, account, create, username, sync, options = {}) {
+ if (account === null || account === void 0) {
+ throw new Error("'account' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/account/authenticate/steam";
+ const queryParams = /* @__PURE__ */ new Map();
+ queryParams.set("create", create);
+ queryParams.set("username", username);
+ queryParams.set("sync", sync);
+ let bodyJson = "";
+ bodyJson = JSON.stringify(account || {});
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("POST", options, bodyJson);
+ if (basicAuthUsername) {
+ fetchOptions.headers["Authorization"] = "Basic " + encode(basicAuthUsername + ":" + basicAuthPassword);
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Add an Apple ID to the social profiles on the current user's account. */
+ linkApple(bearerToken, body, options = {}) {
+ if (body === null || body === void 0) {
+ throw new Error("'body' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/account/link/apple";
+ const queryParams = /* @__PURE__ */ new Map();
+ let bodyJson = "";
+ bodyJson = JSON.stringify(body || {});
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("POST", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Add a custom ID to the social profiles on the current user's account. */
+ linkCustom(bearerToken, body, options = {}) {
+ if (body === null || body === void 0) {
+ throw new Error("'body' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/account/link/custom";
+ const queryParams = /* @__PURE__ */ new Map();
+ let bodyJson = "";
+ bodyJson = JSON.stringify(body || {});
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("POST", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Add a device ID to the social profiles on the current user's account. */
+ linkDevice(bearerToken, body, options = {}) {
+ if (body === null || body === void 0) {
+ throw new Error("'body' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/account/link/device";
+ const queryParams = /* @__PURE__ */ new Map();
+ let bodyJson = "";
+ bodyJson = JSON.stringify(body || {});
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("POST", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Add an email+password to the social profiles on the current user's account. */
+ linkEmail(bearerToken, body, options = {}) {
+ if (body === null || body === void 0) {
+ throw new Error("'body' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/account/link/email";
+ const queryParams = /* @__PURE__ */ new Map();
+ let bodyJson = "";
+ bodyJson = JSON.stringify(body || {});
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("POST", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Add Facebook to the social profiles on the current user's account. */
+ linkFacebook(bearerToken, account, sync, options = {}) {
+ if (account === null || account === void 0) {
+ throw new Error("'account' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/account/link/facebook";
+ const queryParams = /* @__PURE__ */ new Map();
+ queryParams.set("sync", sync);
+ let bodyJson = "";
+ bodyJson = JSON.stringify(account || {});
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("POST", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Add Facebook Instant Game to the social profiles on the current user's account. */
+ linkFacebookInstantGame(bearerToken, body, options = {}) {
+ if (body === null || body === void 0) {
+ throw new Error("'body' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/account/link/facebookinstantgame";
+ const queryParams = /* @__PURE__ */ new Map();
+ let bodyJson = "";
+ bodyJson = JSON.stringify(body || {});
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("POST", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Add Apple's GameCenter to the social profiles on the current user's account. */
+ linkGameCenter(bearerToken, body, options = {}) {
+ if (body === null || body === void 0) {
+ throw new Error("'body' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/account/link/gamecenter";
+ const queryParams = /* @__PURE__ */ new Map();
+ let bodyJson = "";
+ bodyJson = JSON.stringify(body || {});
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("POST", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Add Google to the social profiles on the current user's account. */
+ linkGoogle(bearerToken, body, options = {}) {
+ if (body === null || body === void 0) {
+ throw new Error("'body' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/account/link/google";
+ const queryParams = /* @__PURE__ */ new Map();
+ let bodyJson = "";
+ bodyJson = JSON.stringify(body || {});
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("POST", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Add Steam to the social profiles on the current user's account. */
+ linkSteam(bearerToken, body, options = {}) {
+ if (body === null || body === void 0) {
+ throw new Error("'body' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/account/link/steam";
+ const queryParams = /* @__PURE__ */ new Map();
+ let bodyJson = "";
+ bodyJson = JSON.stringify(body || {});
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("POST", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Refresh a user's session using a refresh token retrieved from a previous authentication request. */
+ sessionRefresh(basicAuthUsername, basicAuthPassword, body, options = {}) {
+ if (body === null || body === void 0) {
+ throw new Error("'body' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/account/session/refresh";
+ const queryParams = /* @__PURE__ */ new Map();
+ let bodyJson = "";
+ bodyJson = JSON.stringify(body || {});
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("POST", options, bodyJson);
+ if (basicAuthUsername) {
+ fetchOptions.headers["Authorization"] = "Basic " + encode(basicAuthUsername + ":" + basicAuthPassword);
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Remove the Apple ID from the social profiles on the current user's account. */
+ unlinkApple(bearerToken, body, options = {}) {
+ if (body === null || body === void 0) {
+ throw new Error("'body' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/account/unlink/apple";
+ const queryParams = /* @__PURE__ */ new Map();
+ let bodyJson = "";
+ bodyJson = JSON.stringify(body || {});
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("POST", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Remove the custom ID from the social profiles on the current user's account. */
+ unlinkCustom(bearerToken, body, options = {}) {
+ if (body === null || body === void 0) {
+ throw new Error("'body' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/account/unlink/custom";
+ const queryParams = /* @__PURE__ */ new Map();
+ let bodyJson = "";
+ bodyJson = JSON.stringify(body || {});
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("POST", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Remove the device ID from the social profiles on the current user's account. */
+ unlinkDevice(bearerToken, body, options = {}) {
+ if (body === null || body === void 0) {
+ throw new Error("'body' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/account/unlink/device";
+ const queryParams = /* @__PURE__ */ new Map();
+ let bodyJson = "";
+ bodyJson = JSON.stringify(body || {});
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("POST", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Remove the email+password from the social profiles on the current user's account. */
+ unlinkEmail(bearerToken, body, options = {}) {
+ if (body === null || body === void 0) {
+ throw new Error("'body' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/account/unlink/email";
+ const queryParams = /* @__PURE__ */ new Map();
+ let bodyJson = "";
+ bodyJson = JSON.stringify(body || {});
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("POST", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Remove Facebook from the social profiles on the current user's account. */
+ unlinkFacebook(bearerToken, body, options = {}) {
+ if (body === null || body === void 0) {
+ throw new Error("'body' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/account/unlink/facebook";
+ const queryParams = /* @__PURE__ */ new Map();
+ let bodyJson = "";
+ bodyJson = JSON.stringify(body || {});
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("POST", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Remove Facebook Instant Game profile from the social profiles on the current user's account. */
+ unlinkFacebookInstantGame(bearerToken, body, options = {}) {
+ if (body === null || body === void 0) {
+ throw new Error("'body' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/account/unlink/facebookinstantgame";
+ const queryParams = /* @__PURE__ */ new Map();
+ let bodyJson = "";
+ bodyJson = JSON.stringify(body || {});
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("POST", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Remove Apple's GameCenter from the social profiles on the current user's account. */
+ unlinkGameCenter(bearerToken, body, options = {}) {
+ if (body === null || body === void 0) {
+ throw new Error("'body' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/account/unlink/gamecenter";
+ const queryParams = /* @__PURE__ */ new Map();
+ let bodyJson = "";
+ bodyJson = JSON.stringify(body || {});
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("POST", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Remove Google from the social profiles on the current user's account. */
+ unlinkGoogle(bearerToken, body, options = {}) {
+ if (body === null || body === void 0) {
+ throw new Error("'body' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/account/unlink/google";
+ const queryParams = /* @__PURE__ */ new Map();
+ let bodyJson = "";
+ bodyJson = JSON.stringify(body || {});
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("POST", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Remove Steam from the social profiles on the current user's account. */
+ unlinkSteam(bearerToken, body, options = {}) {
+ if (body === null || body === void 0) {
+ throw new Error("'body' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/account/unlink/steam";
+ const queryParams = /* @__PURE__ */ new Map();
+ let bodyJson = "";
+ bodyJson = JSON.stringify(body || {});
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("POST", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** List a channel's message history. */
+ listChannelMessages(bearerToken, channelId, limit, forward, cursor, options = {}) {
+ if (channelId === null || channelId === void 0) {
+ throw new Error("'channelId' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/channel/{channelId}".replace("{channelId}", encodeURIComponent(String(channelId)));
+ const queryParams = /* @__PURE__ */ new Map();
+ queryParams.set("limit", limit);
+ queryParams.set("forward", forward);
+ queryParams.set("cursor", cursor);
+ let bodyJson = "";
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("GET", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Submit an event for processing in the server's registered runtime custom events handler. */
+ event(bearerToken, body, options = {}) {
+ if (body === null || body === void 0) {
+ throw new Error("'body' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/event";
+ const queryParams = /* @__PURE__ */ new Map();
+ let bodyJson = "";
+ bodyJson = JSON.stringify(body || {});
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("POST", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Delete one or more users by ID or username. */
+ deleteFriends(bearerToken, ids, usernames, options = {}) {
+ const urlPath = "/v2/friend";
+ const queryParams = /* @__PURE__ */ new Map();
+ queryParams.set("ids", ids);
+ queryParams.set("usernames", usernames);
+ let bodyJson = "";
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("DELETE", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** List all friends for the current user. */
+ listFriends(bearerToken, limit, state, cursor, options = {}) {
+ const urlPath = "/v2/friend";
+ const queryParams = /* @__PURE__ */ new Map();
+ queryParams.set("limit", limit);
+ queryParams.set("state", state);
+ queryParams.set("cursor", cursor);
+ let bodyJson = "";
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("GET", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Add friends by ID or username to a user's account. */
+ addFriends(bearerToken, ids, usernames, options = {}) {
+ const urlPath = "/v2/friend";
+ const queryParams = /* @__PURE__ */ new Map();
+ queryParams.set("ids", ids);
+ queryParams.set("usernames", usernames);
+ let bodyJson = "";
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("POST", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Block one or more users by ID or username. */
+ blockFriends(bearerToken, ids, usernames, options = {}) {
+ const urlPath = "/v2/friend/block";
+ const queryParams = /* @__PURE__ */ new Map();
+ queryParams.set("ids", ids);
+ queryParams.set("usernames", usernames);
+ let bodyJson = "";
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("POST", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Import Facebook friends and add them to a user's account. */
+ importFacebookFriends(bearerToken, account, reset, options = {}) {
+ if (account === null || account === void 0) {
+ throw new Error("'account' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/friend/facebook";
+ const queryParams = /* @__PURE__ */ new Map();
+ queryParams.set("reset", reset);
+ let bodyJson = "";
+ bodyJson = JSON.stringify(account || {});
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("POST", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** List friends of friends for the current user. */
+ listFriendsOfFriends(bearerToken, limit, cursor, options = {}) {
+ const urlPath = "/v2/friend/friends";
+ const queryParams = /* @__PURE__ */ new Map();
+ queryParams.set("limit", limit);
+ queryParams.set("cursor", cursor);
+ let bodyJson = "";
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("GET", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Import Steam friends and add them to a user's account. */
+ importSteamFriends(bearerToken, account, reset, options = {}) {
+ if (account === null || account === void 0) {
+ throw new Error("'account' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/friend/steam";
+ const queryParams = /* @__PURE__ */ new Map();
+ queryParams.set("reset", reset);
+ let bodyJson = "";
+ bodyJson = JSON.stringify(account || {});
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("POST", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** List groups based on given filters. */
+ listGroups(bearerToken, name, cursor, limit, langTag, members, open, options = {}) {
+ const urlPath = "/v2/group";
+ const queryParams = /* @__PURE__ */ new Map();
+ queryParams.set("name", name);
+ queryParams.set("cursor", cursor);
+ queryParams.set("limit", limit);
+ queryParams.set("lang_tag", langTag);
+ queryParams.set("members", members);
+ queryParams.set("open", open);
+ let bodyJson = "";
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("GET", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Create a new group with the current user as the owner. */
+ createGroup(bearerToken, body, options = {}) {
+ if (body === null || body === void 0) {
+ throw new Error("'body' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/group";
+ const queryParams = /* @__PURE__ */ new Map();
+ let bodyJson = "";
+ bodyJson = JSON.stringify(body || {});
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("POST", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Delete a group by ID. */
+ deleteGroup(bearerToken, groupId, options = {}) {
+ if (groupId === null || groupId === void 0) {
+ throw new Error("'groupId' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/group/{groupId}".replace("{groupId}", encodeURIComponent(String(groupId)));
+ const queryParams = /* @__PURE__ */ new Map();
+ let bodyJson = "";
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("DELETE", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Update fields in a given group. */
+ updateGroup(bearerToken, groupId, body, options = {}) {
+ if (groupId === null || groupId === void 0) {
+ throw new Error("'groupId' is a required parameter but is null or undefined.");
+ }
+ if (body === null || body === void 0) {
+ throw new Error("'body' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/group/{groupId}".replace("{groupId}", encodeURIComponent(String(groupId)));
+ const queryParams = /* @__PURE__ */ new Map();
+ let bodyJson = "";
+ bodyJson = JSON.stringify(body || {});
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("PUT", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Add users to a group. */
+ addGroupUsers(bearerToken, groupId, userIds, options = {}) {
+ if (groupId === null || groupId === void 0) {
+ throw new Error("'groupId' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/group/{groupId}/add".replace("{groupId}", encodeURIComponent(String(groupId)));
+ const queryParams = /* @__PURE__ */ new Map();
+ queryParams.set("user_ids", userIds);
+ let bodyJson = "";
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("POST", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Ban a set of users from a group. */
+ banGroupUsers(bearerToken, groupId, userIds, options = {}) {
+ if (groupId === null || groupId === void 0) {
+ throw new Error("'groupId' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/group/{groupId}/ban".replace("{groupId}", encodeURIComponent(String(groupId)));
+ const queryParams = /* @__PURE__ */ new Map();
+ queryParams.set("user_ids", userIds);
+ let bodyJson = "";
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("POST", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Demote a set of users in a group to the next role down. */
+ demoteGroupUsers(bearerToken, groupId, userIds, options = {}) {
+ if (groupId === null || groupId === void 0) {
+ throw new Error("'groupId' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/group/{groupId}/demote".replace("{groupId}", encodeURIComponent(String(groupId)));
+ const queryParams = /* @__PURE__ */ new Map();
+ queryParams.set("user_ids", userIds);
+ let bodyJson = "";
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("POST", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Immediately join an open group, or request to join a closed one. */
+ joinGroup(bearerToken, groupId, options = {}) {
+ if (groupId === null || groupId === void 0) {
+ throw new Error("'groupId' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/group/{groupId}/join".replace("{groupId}", encodeURIComponent(String(groupId)));
+ const queryParams = /* @__PURE__ */ new Map();
+ let bodyJson = "";
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("POST", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Kick a set of users from a group. */
+ kickGroupUsers(bearerToken, groupId, userIds, options = {}) {
+ if (groupId === null || groupId === void 0) {
+ throw new Error("'groupId' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/group/{groupId}/kick".replace("{groupId}", encodeURIComponent(String(groupId)));
+ const queryParams = /* @__PURE__ */ new Map();
+ queryParams.set("user_ids", userIds);
+ let bodyJson = "";
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("POST", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Leave a group the user is a member of. */
+ leaveGroup(bearerToken, groupId, options = {}) {
+ if (groupId === null || groupId === void 0) {
+ throw new Error("'groupId' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/group/{groupId}/leave".replace("{groupId}", encodeURIComponent(String(groupId)));
+ const queryParams = /* @__PURE__ */ new Map();
+ let bodyJson = "";
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("POST", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Promote a set of users in a group to the next role up. */
+ promoteGroupUsers(bearerToken, groupId, userIds, options = {}) {
+ if (groupId === null || groupId === void 0) {
+ throw new Error("'groupId' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/group/{groupId}/promote".replace("{groupId}", encodeURIComponent(String(groupId)));
+ const queryParams = /* @__PURE__ */ new Map();
+ queryParams.set("user_ids", userIds);
+ let bodyJson = "";
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("POST", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** List all users that are part of a group. */
+ listGroupUsers(bearerToken, groupId, limit, state, cursor, options = {}) {
+ if (groupId === null || groupId === void 0) {
+ throw new Error("'groupId' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/group/{groupId}/user".replace("{groupId}", encodeURIComponent(String(groupId)));
+ const queryParams = /* @__PURE__ */ new Map();
+ queryParams.set("limit", limit);
+ queryParams.set("state", state);
+ queryParams.set("cursor", cursor);
+ let bodyJson = "";
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("GET", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Validate Apple IAP Receipt */
+ validatePurchaseApple(bearerToken, body, options = {}) {
+ if (body === null || body === void 0) {
+ throw new Error("'body' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/iap/purchase/apple";
+ const queryParams = /* @__PURE__ */ new Map();
+ let bodyJson = "";
+ bodyJson = JSON.stringify(body || {});
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("POST", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Validate FB Instant IAP Receipt */
+ validatePurchaseFacebookInstant(bearerToken, body, options = {}) {
+ if (body === null || body === void 0) {
+ throw new Error("'body' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/iap/purchase/facebookinstant";
+ const queryParams = /* @__PURE__ */ new Map();
+ let bodyJson = "";
+ bodyJson = JSON.stringify(body || {});
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("POST", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Validate Google IAP Receipt */
+ validatePurchaseGoogle(bearerToken, body, options = {}) {
+ if (body === null || body === void 0) {
+ throw new Error("'body' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/iap/purchase/google";
+ const queryParams = /* @__PURE__ */ new Map();
+ let bodyJson = "";
+ bodyJson = JSON.stringify(body || {});
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("POST", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Validate Huawei IAP Receipt */
+ validatePurchaseHuawei(bearerToken, body, options = {}) {
+ if (body === null || body === void 0) {
+ throw new Error("'body' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/iap/purchase/huawei";
+ const queryParams = /* @__PURE__ */ new Map();
+ let bodyJson = "";
+ bodyJson = JSON.stringify(body || {});
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("POST", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** List user's subscriptions. */
+ listSubscriptions(bearerToken, body, options = {}) {
+ if (body === null || body === void 0) {
+ throw new Error("'body' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/iap/subscription";
+ const queryParams = /* @__PURE__ */ new Map();
+ let bodyJson = "";
+ bodyJson = JSON.stringify(body || {});
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("POST", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Validate Apple Subscription Receipt */
+ validateSubscriptionApple(bearerToken, body, options = {}) {
+ if (body === null || body === void 0) {
+ throw new Error("'body' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/iap/subscription/apple";
+ const queryParams = /* @__PURE__ */ new Map();
+ let bodyJson = "";
+ bodyJson = JSON.stringify(body || {});
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("POST", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Validate Google Subscription Receipt */
+ validateSubscriptionGoogle(bearerToken, body, options = {}) {
+ if (body === null || body === void 0) {
+ throw new Error("'body' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/iap/subscription/google";
+ const queryParams = /* @__PURE__ */ new Map();
+ let bodyJson = "";
+ bodyJson = JSON.stringify(body || {});
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("POST", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Get subscription by product id. */
+ getSubscription(bearerToken, productId, options = {}) {
+ if (productId === null || productId === void 0) {
+ throw new Error("'productId' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/iap/subscription/{productId}".replace("{productId}", encodeURIComponent(String(productId)));
+ const queryParams = /* @__PURE__ */ new Map();
+ let bodyJson = "";
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("GET", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Delete a leaderboard record. */
+ deleteLeaderboardRecord(bearerToken, leaderboardId, options = {}) {
+ if (leaderboardId === null || leaderboardId === void 0) {
+ throw new Error("'leaderboardId' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/leaderboard/{leaderboardId}".replace("{leaderboardId}", encodeURIComponent(String(leaderboardId)));
+ const queryParams = /* @__PURE__ */ new Map();
+ let bodyJson = "";
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("DELETE", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** List leaderboard records. */
+ listLeaderboardRecords(bearerToken, leaderboardId, ownerIds, limit, cursor, expiry, options = {}) {
+ if (leaderboardId === null || leaderboardId === void 0) {
+ throw new Error("'leaderboardId' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/leaderboard/{leaderboardId}".replace("{leaderboardId}", encodeURIComponent(String(leaderboardId)));
+ const queryParams = /* @__PURE__ */ new Map();
+ queryParams.set("owner_ids", ownerIds);
+ queryParams.set("limit", limit);
+ queryParams.set("cursor", cursor);
+ queryParams.set("expiry", expiry);
+ let bodyJson = "";
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("GET", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Write a record to a leaderboard. */
+ writeLeaderboardRecord(bearerToken, leaderboardId, record, options = {}) {
+ if (leaderboardId === null || leaderboardId === void 0) {
+ throw new Error("'leaderboardId' is a required parameter but is null or undefined.");
+ }
+ if (record === null || record === void 0) {
+ throw new Error("'record' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/leaderboard/{leaderboardId}".replace("{leaderboardId}", encodeURIComponent(String(leaderboardId)));
+ const queryParams = /* @__PURE__ */ new Map();
+ let bodyJson = "";
+ bodyJson = JSON.stringify(record || {});
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("POST", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** List leaderboard records that belong to a user. */
+ listLeaderboardRecordsAroundOwner(bearerToken, leaderboardId, ownerId, limit, expiry, cursor, options = {}) {
+ if (leaderboardId === null || leaderboardId === void 0) {
+ throw new Error("'leaderboardId' is a required parameter but is null or undefined.");
+ }
+ if (ownerId === null || ownerId === void 0) {
+ throw new Error("'ownerId' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/leaderboard/{leaderboardId}/owner/{ownerId}".replace("{leaderboardId}", encodeURIComponent(String(leaderboardId))).replace("{ownerId}", encodeURIComponent(String(ownerId)));
+ const queryParams = /* @__PURE__ */ new Map();
+ queryParams.set("limit", limit);
+ queryParams.set("expiry", expiry);
+ queryParams.set("cursor", cursor);
+ let bodyJson = "";
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("GET", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Fetch list of running matches. */
+ listMatches(bearerToken, limit, authoritative, label, minSize, maxSize, query, options = {}) {
+ const urlPath = "/v2/match";
+ const queryParams = /* @__PURE__ */ new Map();
+ queryParams.set("limit", limit);
+ queryParams.set("authoritative", authoritative);
+ queryParams.set("label", label);
+ queryParams.set("min_size", minSize);
+ queryParams.set("max_size", maxSize);
+ queryParams.set("query", query);
+ let bodyJson = "";
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("GET", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Delete one or more notifications for the current user. */
+ deleteNotifications(bearerToken, ids, options = {}) {
+ const urlPath = "/v2/notification";
+ const queryParams = /* @__PURE__ */ new Map();
+ queryParams.set("ids", ids);
+ let bodyJson = "";
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("DELETE", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Fetch list of notifications. */
+ listNotifications(bearerToken, limit, cacheableCursor, options = {}) {
+ const urlPath = "/v2/notification";
+ const queryParams = /* @__PURE__ */ new Map();
+ queryParams.set("limit", limit);
+ queryParams.set("cacheable_cursor", cacheableCursor);
+ let bodyJson = "";
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("GET", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Execute a Lua function on the server. */
+ rpcFunc2(bearerToken, id, payload, httpKey, options = {}) {
+ if (id === null || id === void 0) {
+ throw new Error("'id' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/rpc/{id}".replace("{id}", encodeURIComponent(String(id)));
+ const queryParams = /* @__PURE__ */ new Map();
+ queryParams.set("payload", payload);
+ queryParams.set("http_key", httpKey);
+ let bodyJson = "";
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("GET", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Execute a Lua function on the server. */
+ rpcFunc(bearerToken, id, body, httpKey, options = {}) {
+ if (id === null || id === void 0) {
+ throw new Error("'id' is a required parameter but is null or undefined.");
+ }
+ if (body === null || body === void 0) {
+ throw new Error("'body' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/rpc/{id}".replace("{id}", encodeURIComponent(String(id)));
+ const queryParams = /* @__PURE__ */ new Map();
+ queryParams.set("http_key", httpKey);
+ let bodyJson = "";
+ bodyJson = JSON.stringify(body || {});
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("POST", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Log out a session, invalidate a refresh token, or log out all sessions/refresh tokens for a user. */
+ sessionLogout(bearerToken, body, options = {}) {
+ if (body === null || body === void 0) {
+ throw new Error("'body' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/session/logout";
+ const queryParams = /* @__PURE__ */ new Map();
+ let bodyJson = "";
+ bodyJson = JSON.stringify(body || {});
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("POST", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Get storage objects. */
+ readStorageObjects(bearerToken, body, options = {}) {
+ if (body === null || body === void 0) {
+ throw new Error("'body' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/storage";
+ const queryParams = /* @__PURE__ */ new Map();
+ let bodyJson = "";
+ bodyJson = JSON.stringify(body || {});
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("POST", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Write objects into the storage engine. */
+ writeStorageObjects(bearerToken, body, options = {}) {
+ if (body === null || body === void 0) {
+ throw new Error("'body' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/storage";
+ const queryParams = /* @__PURE__ */ new Map();
+ let bodyJson = "";
+ bodyJson = JSON.stringify(body || {});
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("PUT", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Delete one or more objects by ID or username. */
+ deleteStorageObjects(bearerToken, body, options = {}) {
+ if (body === null || body === void 0) {
+ throw new Error("'body' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/storage/delete";
+ const queryParams = /* @__PURE__ */ new Map();
+ let bodyJson = "";
+ bodyJson = JSON.stringify(body || {});
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("PUT", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** List publicly readable storage objects in a given collection. */
+ listStorageObjects(bearerToken, collection, userId, limit, cursor, options = {}) {
+ if (collection === null || collection === void 0) {
+ throw new Error("'collection' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/storage/{collection}".replace("{collection}", encodeURIComponent(String(collection)));
+ const queryParams = /* @__PURE__ */ new Map();
+ queryParams.set("user_id", userId);
+ queryParams.set("limit", limit);
+ queryParams.set("cursor", cursor);
+ let bodyJson = "";
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("GET", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** List publicly readable storage objects in a given collection. */
+ listStorageObjects2(bearerToken, collection, userId, limit, cursor, options = {}) {
+ if (collection === null || collection === void 0) {
+ throw new Error("'collection' is a required parameter but is null or undefined.");
+ }
+ if (userId === null || userId === void 0) {
+ throw new Error("'userId' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/storage/{collection}/{userId}".replace("{collection}", encodeURIComponent(String(collection))).replace("{userId}", encodeURIComponent(String(userId)));
+ const queryParams = /* @__PURE__ */ new Map();
+ queryParams.set("limit", limit);
+ queryParams.set("cursor", cursor);
+ let bodyJson = "";
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("GET", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** List current or upcoming tournaments. */
+ listTournaments(bearerToken, categoryStart, categoryEnd, startTime, endTime, limit, cursor, options = {}) {
+ const urlPath = "/v2/tournament";
+ const queryParams = /* @__PURE__ */ new Map();
+ queryParams.set("category_start", categoryStart);
+ queryParams.set("category_end", categoryEnd);
+ queryParams.set("start_time", startTime);
+ queryParams.set("end_time", endTime);
+ queryParams.set("limit", limit);
+ queryParams.set("cursor", cursor);
+ let bodyJson = "";
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("GET", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Delete a tournament record. */
+ deleteTournamentRecord(bearerToken, tournamentId, options = {}) {
+ if (tournamentId === null || tournamentId === void 0) {
+ throw new Error("'tournamentId' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/tournament/{tournamentId}".replace("{tournamentId}", encodeURIComponent(String(tournamentId)));
+ const queryParams = /* @__PURE__ */ new Map();
+ let bodyJson = "";
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("DELETE", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** List tournament records. */
+ listTournamentRecords(bearerToken, tournamentId, ownerIds, limit, cursor, expiry, options = {}) {
+ if (tournamentId === null || tournamentId === void 0) {
+ throw new Error("'tournamentId' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/tournament/{tournamentId}".replace("{tournamentId}", encodeURIComponent(String(tournamentId)));
+ const queryParams = /* @__PURE__ */ new Map();
+ queryParams.set("owner_ids", ownerIds);
+ queryParams.set("limit", limit);
+ queryParams.set("cursor", cursor);
+ queryParams.set("expiry", expiry);
+ let bodyJson = "";
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("GET", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Write a record to a tournament. */
+ writeTournamentRecord2(bearerToken, tournamentId, record, options = {}) {
+ if (tournamentId === null || tournamentId === void 0) {
+ throw new Error("'tournamentId' is a required parameter but is null or undefined.");
+ }
+ if (record === null || record === void 0) {
+ throw new Error("'record' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/tournament/{tournamentId}".replace("{tournamentId}", encodeURIComponent(String(tournamentId)));
+ const queryParams = /* @__PURE__ */ new Map();
+ let bodyJson = "";
+ bodyJson = JSON.stringify(record || {});
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("POST", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Write a record to a tournament. */
+ writeTournamentRecord(bearerToken, tournamentId, record, options = {}) {
+ if (tournamentId === null || tournamentId === void 0) {
+ throw new Error("'tournamentId' is a required parameter but is null or undefined.");
+ }
+ if (record === null || record === void 0) {
+ throw new Error("'record' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/tournament/{tournamentId}".replace("{tournamentId}", encodeURIComponent(String(tournamentId)));
+ const queryParams = /* @__PURE__ */ new Map();
+ let bodyJson = "";
+ bodyJson = JSON.stringify(record || {});
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("PUT", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Attempt to join an open and running tournament. */
+ joinTournament(bearerToken, tournamentId, options = {}) {
+ if (tournamentId === null || tournamentId === void 0) {
+ throw new Error("'tournamentId' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/tournament/{tournamentId}/join".replace("{tournamentId}", encodeURIComponent(String(tournamentId)));
+ const queryParams = /* @__PURE__ */ new Map();
+ let bodyJson = "";
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("POST", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** List tournament records for a given owner. */
+ listTournamentRecordsAroundOwner(bearerToken, tournamentId, ownerId, limit, expiry, cursor, options = {}) {
+ if (tournamentId === null || tournamentId === void 0) {
+ throw new Error("'tournamentId' is a required parameter but is null or undefined.");
+ }
+ if (ownerId === null || ownerId === void 0) {
+ throw new Error("'ownerId' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/tournament/{tournamentId}/owner/{ownerId}".replace("{tournamentId}", encodeURIComponent(String(tournamentId))).replace("{ownerId}", encodeURIComponent(String(ownerId)));
+ const queryParams = /* @__PURE__ */ new Map();
+ queryParams.set("limit", limit);
+ queryParams.set("expiry", expiry);
+ queryParams.set("cursor", cursor);
+ let bodyJson = "";
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("GET", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** Fetch zero or more users by ID and/or username. */
+ getUsers(bearerToken, ids, usernames, facebookIds, options = {}) {
+ const urlPath = "/v2/user";
+ const queryParams = /* @__PURE__ */ new Map();
+ queryParams.set("ids", ids);
+ queryParams.set("usernames", usernames);
+ queryParams.set("facebook_ids", facebookIds);
+ let bodyJson = "";
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("GET", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ /** List groups the current user belongs to. */
+ listUserGroups(bearerToken, userId, limit, state, cursor, options = {}) {
+ if (userId === null || userId === void 0) {
+ throw new Error("'userId' is a required parameter but is null or undefined.");
+ }
+ const urlPath = "/v2/user/{userId}/group".replace("{userId}", encodeURIComponent(String(userId)));
+ const queryParams = /* @__PURE__ */ new Map();
+ queryParams.set("limit", limit);
+ queryParams.set("state", state);
+ queryParams.set("cursor", cursor);
+ let bodyJson = "";
+ const fullUrl = this.buildFullUrl(this.basePath, urlPath, queryParams);
+ const fetchOptions = buildFetchOptions("GET", options, bodyJson);
+ if (bearerToken) {
+ fetchOptions.headers["Authorization"] = "Bearer " + bearerToken;
+ }
+ return Promise.race([
+ fetch(fullUrl, fetchOptions).then((response) => {
+ if (response.status == 204) {
+ return response;
+ } else if (response.status >= 200 && response.status < 300) {
+ return response.json();
+ } else {
+ throw response;
+ }
+ }),
+ new Promise(
+ (_, reject) => setTimeout(reject, this.timeoutMs, "Request timed out.")
+ )
+ ]);
+ }
+ buildFullUrl(basePath, fragment, queryParams) {
+ let fullPath = basePath + fragment + "?";
+ for (let [k, v] of queryParams) {
+ if (v instanceof Array) {
+ fullPath += v.reduce((prev, curr) => {
+ return prev + encodeURIComponent(k) + "=" + encodeURIComponent(curr) + "&";
+ }, "");
+ } else {
+ if (v != null) {
+ fullPath += encodeURIComponent(k) + "=" + encodeURIComponent(v) + "&";
+ }
+ }
+ }
+ return fullPath;
+ }
+};
+
+// session.ts
+var Session = class {
+ constructor(token, refresh_token, created) {
+ this.created = created;
+ this.token = token;
+ this.refresh_token = refresh_token;
+ this.created_at = Math.floor((/* @__PURE__ */ new Date()).getTime() / 1e3);
+ this.update(token, refresh_token);
+ }
+ isexpired(currenttime) {
+ return this.expires_at - currenttime < 0;
+ }
+ isrefreshexpired(currenttime) {
+ return this.refresh_expires_at - currenttime < 0;
+ }
+ update(token, refreshToken) {
+ const tokenParts = token.split(".");
+ if (tokenParts.length != 3) {
+ throw "jwt is not valid.";
+ }
+ const tokenDecoded = JSON.parse(_atob(tokenParts[1]));
+ const tokenExpiresAt = Math.floor(parseInt(tokenDecoded["exp"]));
+ if (refreshToken) {
+ const refreshTokenParts = refreshToken.split(".");
+ if (refreshTokenParts.length != 3) {
+ throw "refresh jwt is not valid.";
+ }
+ const refreshTokenDecoded = JSON.parse(_atob(refreshTokenParts[1]));
+ const refreshTokenExpiresAt = Math.floor(parseInt(refreshTokenDecoded["exp"]));
+ this.refresh_expires_at = refreshTokenExpiresAt;
+ this.refresh_token = refreshToken;
+ }
+ this.token = token;
+ this.expires_at = tokenExpiresAt;
+ this.username = tokenDecoded["usn"];
+ this.user_id = tokenDecoded["uid"];
+ this.vars = tokenDecoded["vrs"];
+ }
+ static restore(token, refreshToken) {
+ return new Session(token, refreshToken, false);
+ }
+};
+
+// ../../node_modules/base64-arraybuffer/dist/base64-arraybuffer.es5.js
+var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+var lookup = typeof Uint8Array === "undefined" ? [] : new Uint8Array(256);
+for (i = 0; i < chars.length; i++) {
+ lookup[chars.charCodeAt(i)] = i;
+}
+var i;
+var encode2 = function (arraybuffer) {
+ var bytes = new Uint8Array(arraybuffer), i, len = bytes.length, base64 = "";
+ for (i = 0; i < len; i += 3) {
+ base64 += chars[bytes[i] >> 2];
+ base64 += chars[(bytes[i] & 3) << 4 | bytes[i + 1] >> 4];
+ base64 += chars[(bytes[i + 1] & 15) << 2 | bytes[i + 2] >> 6];
+ base64 += chars[bytes[i + 2] & 63];
+ }
+ if (len % 3 === 2) {
+ base64 = base64.substring(0, base64.length - 1) + "=";
+ } else if (len % 3 === 1) {
+ base64 = base64.substring(0, base64.length - 2) + "==";
+ }
+ return base64;
+};
+var decode3 = function (base64) {
+ var bufferLength = base64.length * 0.75, len = base64.length, i, p = 0, encoded1, encoded2, encoded3, encoded4;
+ if (base64[base64.length - 1] === "=") {
+ bufferLength--;
+ if (base64[base64.length - 2] === "=") {
+ bufferLength--;
+ }
+ }
+ var arraybuffer = new ArrayBuffer(bufferLength), bytes = new Uint8Array(arraybuffer);
+ for (i = 0; i < len; i += 4) {
+ encoded1 = lookup[base64.charCodeAt(i)];
+ encoded2 = lookup[base64.charCodeAt(i + 1)];
+ encoded3 = lookup[base64.charCodeAt(i + 2)];
+ encoded4 = lookup[base64.charCodeAt(i + 3)];
+ bytes[p++] = encoded1 << 2 | encoded2 >> 4;
+ bytes[p++] = (encoded2 & 15) << 4 | encoded3 >> 2;
+ bytes[p++] = (encoded3 & 3) << 6 | encoded4 & 63;
+ }
+ return arraybuffer;
+};
+
+// web_socket_adapter.ts
+var WebSocketAdapterText = class {
+ get onClose() {
+ return this._socket.onclose;
+ }
+ set onClose(value) {
+ this._socket.onclose = value;
+ }
+ get onError() {
+ return this._socket.onerror;
+ }
+ set onError(value) {
+ this._socket.onerror = value;
+ }
+ get onMessage() {
+ return this._socket.onmessage;
+ }
+ set onMessage(value) {
+ if (value) {
+ this._socket.onmessage = (evt) => {
+ const message = JSON.parse(evt.data);
+ if (message.match_data && message.match_data.data) {
+ message.match_data.data = new Uint8Array(decode3(message.match_data.data));
+ } else if (message.party_data && message.party_data.data) {
+ message.party_data.data = new Uint8Array(decode3(message.party_data.data));
+ }
+ value(message);
+ };
+ } else {
+ value = null;
+ }
+ }
+ get onOpen() {
+ return this._socket.onopen;
+ }
+ set onOpen(value) {
+ this._socket.onopen = value;
+ }
+ isOpen() {
+ var _a;
+ return ((_a = this._socket) == null ? void 0 : _a.readyState) == WebSocket.OPEN;
+ }
+ connect(scheme, host, port, createStatus, token) {
+ const url = `${scheme}${host}:${port}/ws?lang=en&status=${encodeURIComponent(createStatus.toString())}&token=${encodeURIComponent(token)}`;
+ this._socket = new WebSocket(url);
+ }
+ close() {
+ this._socket.close();
+ this._socket = void 0;
+ }
+ send(msg) {
+ if (msg.match_data_send) {
+ msg.match_data_send.op_code = msg.match_data_send.op_code.toString();
+ let payload = msg.match_data_send.data;
+ if (payload && payload instanceof Uint8Array) {
+ msg.match_data_send.data = encode2(payload.buffer);
+ } else if (payload) {
+ msg.match_data_send.data = _btoa(payload);
+ }
+ } else if (msg.party_data_send) {
+ msg.party_data_send.op_code = msg.party_data_send.op_code.toString();
+ let payload = msg.party_data_send.data;
+ if (payload && payload instanceof Uint8Array) {
+ msg.party_data_send.data = encode2(payload.buffer);
+ } else if (payload) {
+ msg.party_data_send.data = _btoa(payload);
+ }
+ }
+ this._socket.send(JSON.stringify(msg));
+ }
+};
+
+// socket.ts
+var _DefaultSocket = class {
+ constructor(host, port, useSSL = false, verbose = false, adapter = new WebSocketAdapterText(), sendTimeoutMs = _DefaultSocket.DefaultSendTimeoutMs) {
+ this.host = host;
+ this.port = port;
+ this.useSSL = useSSL;
+ this.verbose = verbose;
+ this.adapter = adapter;
+ this.sendTimeoutMs = sendTimeoutMs;
+ this.cIds = {};
+ this.nextCid = 1;
+ this._heartbeatTimeoutMs = _DefaultSocket.DefaultHeartbeatTimeoutMs;
+ }
+ generatecid() {
+ const cid = this.nextCid.toString();
+ ++this.nextCid;
+ return cid;
+ }
+ connect(session, createStatus = false, connectTimeoutMs = _DefaultSocket.DefaultConnectTimeoutMs) {
+ if (this.adapter.isOpen()) {
+ return Promise.resolve(session);
+ }
+ const scheme = this.useSSL ? "wss://" : "ws://";
+ this.adapter.connect(scheme, this.host, this.port, createStatus, session.token);
+ this.adapter.onClose = (evt) => {
+ this.ondisconnect(evt);
+ };
+ this.adapter.onError = (evt) => {
+ this.onerror(evt);
+ };
+ this.adapter.onMessage = (message) => {
+ if (this.verbose && window && window.console) {
+ console.log("Response: %o", JSON.stringify(message));
+ }
+ if (!message.cid) {
+ if (message.notifications) {
+ message.notifications.notifications.forEach((n) => {
+ n.content = n.content ? JSON.parse(n.content) : void 0;
+ this.onnotification(n);
+ });
+ } else if (message.match_data) {
+ message.match_data.op_code = parseInt(message.match_data.op_code);
+ this.onmatchdata(message.match_data);
+ } else if (message.match_presence_event) {
+ this.onmatchpresence(message.match_presence_event);
+ } else if (message.matchmaker_ticket) {
+ this.onmatchmakerticket(message.matchmaker_ticket);
+ } else if (message.matchmaker_matched) {
+ this.onmatchmakermatched(message.matchmaker_matched);
+ } else if (message.status_presence_event) {
+ this.onstatuspresence(message.status_presence_event);
+ } else if (message.stream_presence_event) {
+ this.onstreampresence(message.stream_presence_event);
+ } else if (message.stream_data) {
+ this.onstreamdata(message.stream_data);
+ } else if (message.channel_message) {
+ message.channel_message.content = JSON.parse(message.channel_message.content);
+ this.onchannelmessage(message.channel_message);
+ } else if (message.channel_presence_event) {
+ this.onchannelpresence(message.channel_presence_event);
+ } else if (message.party_data) {
+ message.party_data.op_code = parseInt(message.party_data.op_code);
+ this.onpartydata(message.party_data);
+ } else if (message.party_close) {
+ this.onpartyclose(message.party_close);
+ } else if (message.party_join_request) {
+ this.onpartyjoinrequest(message.party_join_request);
+ } else if (message.party_leader) {
+ this.onpartyleader(message.party_leader);
+ } else if (message.party_matchmaker_ticket) {
+ this.onpartymatchmakerticket(message.party_matchmaker_ticket);
+ } else if (message.party_presence_event) {
+ this.onpartypresence(message.party_presence_event);
+ } else if (message.party) {
+ this.onparty(message.party);
+ } else {
+ if (this.verbose && window && window.console) {
+ console.log("Unrecognized message received: %o", message);
+ }
+ }
+ } else {
+ const executor = this.cIds[message.cid];
+ if (!executor) {
+ if (this.verbose && window && window.console) {
+ console.error("No promise executor for message: %o", message);
+ }
+ return;
+ }
+ delete this.cIds[message.cid];
+ if (message.error) {
+ executor.reject(message.error);
+ } else {
+ executor.resolve(message);
+ }
+ }
+ };
+ return new Promise((resolve, reject) => {
+ this.adapter.onOpen = (evt) => {
+ if (this.verbose && window && window.console) {
+ console.log(evt);
+ }
+ this.pingPong();
+ resolve(session);
+ };
+ this.adapter.onError = (evt) => {
+ reject(evt);
+ this.adapter.close();
+ };
+ setTimeout(() => {
+ reject("The socket timed out when trying to connect.");
+ }, connectTimeoutMs);
+ });
+ }
+ disconnect(fireDisconnectEvent = true) {
+ if (this.adapter.isOpen()) {
+ this.adapter.close();
+ }
+ if (fireDisconnectEvent) {
+ this.ondisconnect({});
+ }
+ }
+ setHeartbeatTimeoutMs(ms) {
+ this._heartbeatTimeoutMs = ms;
+ }
+ getHeartbeatTimeoutMs() {
+ return this._heartbeatTimeoutMs;
+ }
+ ondisconnect(evt) {
+ if (this.verbose && window && window.console) {
+ console.log(evt);
+ }
+ }
+ onerror(evt) {
+ if (this.verbose && window && window.console) {
+ console.log(evt);
+ }
+ }
+ onchannelmessage(channelMessage) {
+ if (this.verbose && window && window.console) {
+ console.log(channelMessage);
+ }
+ }
+ onchannelpresence(channelPresence) {
+ if (this.verbose && window && window.console) {
+ console.log(channelPresence);
+ }
+ }
+ onnotification(notification) {
+ if (this.verbose && window && window.console) {
+ console.log(notification);
+ }
+ }
+ onmatchdata(matchData) {
+ if (this.verbose && window && window.console) {
+ console.log(matchData);
+ }
+ }
+ onmatchpresence(matchPresence) {
+ if (this.verbose && window && window.console) {
+ console.log(matchPresence);
+ }
+ }
+ onmatchmakerticket(matchmakerTicket) {
+ if (this.verbose && window && window.console) {
+ console.log(matchmakerTicket);
+ }
+ }
+ onmatchmakermatched(matchmakerMatched) {
+ if (this.verbose && window && window.console) {
+ console.log(matchmakerMatched);
+ }
+ }
+ onparty(party) {
+ if (this.verbose && window && window.console) {
+ console.log(party);
+ }
+ }
+ onpartyclose(close) {
+ if (this.verbose && window && window.console) {
+ console.log("Party closed: " + close);
+ }
+ }
+ onpartyjoinrequest(partyJoinRequest) {
+ if (this.verbose && window && window.console) {
+ console.log(partyJoinRequest);
+ }
+ }
+ onpartydata(partyData) {
+ if (this.verbose && window && window.console) {
+ console.log(partyData);
+ }
+ }
+ onpartyleader(partyLeader) {
+ if (this.verbose && window && window.console) {
+ console.log(partyLeader);
+ }
+ }
+ onpartymatchmakerticket(partyMatched) {
+ if (this.verbose && window && window.console) {
+ console.log(partyMatched);
+ }
+ }
+ onpartypresence(partyPresence) {
+ if (this.verbose && window && window.console) {
+ console.log(partyPresence);
+ }
+ }
+ onstatuspresence(statusPresence) {
+ if (this.verbose && window && window.console) {
+ console.log(statusPresence);
+ }
+ }
+ onstreampresence(streamPresence) {
+ if (this.verbose && window && window.console) {
+ console.log(streamPresence);
+ }
+ }
+ onstreamdata(streamData) {
+ if (this.verbose && window && window.console) {
+ console.log(streamData);
+ }
+ }
+ onheartbeattimeout() {
+ if (this.verbose && window && window.console) {
+ console.log("Heartbeat timeout.");
+ }
+ }
+ send(message, sendTimeout = _DefaultSocket.DefaultSendTimeoutMs) {
+ const untypedMessage = message;
+ return new Promise((resolve, reject) => {
+ if (!this.adapter.isOpen()) {
+ reject("Socket connection has not been established yet.");
+ } else {
+ if (untypedMessage.match_data_send) {
+ this.adapter.send(untypedMessage);
+ resolve();
+ } else if (untypedMessage.party_data_send) {
+ this.adapter.send(untypedMessage);
+ resolve();
+ } else {
+ if (untypedMessage.channel_message_send) {
+ untypedMessage.channel_message_send.content = JSON.stringify(untypedMessage.channel_message_send.content);
+ } else if (untypedMessage.channel_message_update) {
+ untypedMessage.channel_message_update.content = JSON.stringify(untypedMessage.channel_message_update.content);
+ }
+ const cid = this.generatecid();
+ this.cIds[cid] = { resolve, reject };
+ setTimeout(() => {
+ reject("The socket timed out while waiting for a response.");
+ }, sendTimeout);
+ untypedMessage.cid = cid;
+ this.adapter.send(untypedMessage);
+ }
+ }
+ if (this.verbose && window && window.console) {
+ const loggedMessage = __spreadValues({}, untypedMessage);
+ if (loggedMessage.match_data_send && loggedMessage.match_data_send.data) {
+ loggedMessage.match_data_send.data = decode2(loggedMessage.match_data_send.data);
+ } else if (loggedMessage.party_data_send && loggedMessage.party_data_send.data) {
+ loggedMessage.party_data_send.data = decode2(loggedMessage.party_data_send.data);
+ }
+ console.log("Sent message: %o", JSON.stringify(loggedMessage));
+ }
+ });
+ }
+ acceptPartyMember(party_id, presence) {
+ return this.send({ party_accept: { party_id, presence } });
+ }
+ addMatchmaker(query, min_count, max_count, string_properties, numeric_properties) {
+ return __async(this, null, function* () {
+ const response = yield this.send({
+ "matchmaker_add": {
+ min_count,
+ max_count,
+ query,
+ string_properties,
+ numeric_properties
+ }
+ });
+ return response.matchmaker_ticket;
+ });
+ }
+ addMatchmakerParty(party_id, query, min_count, max_count, string_properties, numeric_properties) {
+ return __async(this, null, function* () {
+ const response = yield this.send({
+ party_matchmaker_add: {
+ party_id,
+ min_count,
+ max_count,
+ query,
+ string_properties,
+ numeric_properties
+ }
+ });
+ return response.party_matchmaker_ticket;
+ });
+ }
+ closeParty(party_id) {
+ return __async(this, null, function* () {
+ return yield this.send({ party_close: { party_id } });
+ });
+ }
+ createMatch(name) {
+ return __async(this, null, function* () {
+ const response = yield this.send({ match_create: { name } });
+ return response.match;
+ });
+ }
+ createParty(open, max_size) {
+ return __async(this, null, function* () {
+ const response = yield this.send({ party_create: { open, max_size } });
+ return response.party;
+ });
+ }
+ followUsers(userIds) {
+ return __async(this, null, function* () {
+ const response = yield this.send({ status_follow: { user_ids: userIds } });
+ return response.status;
+ });
+ }
+ joinChat(target, type, persistence, hidden) {
+ return __async(this, null, function* () {
+ const response = yield this.send(
+ {
+ channel_join: {
+ target,
+ type,
+ persistence,
+ hidden
+ }
+ }
+ );
+ return response.channel;
+ });
+ }
+ joinMatch(match_id, token, metadata) {
+ return __async(this, null, function* () {
+ const join = { match_join: { metadata } };
+ if (token) {
+ join.match_join.token = token;
+ } else {
+ join.match_join.match_id = match_id;
+ }
+ const response = yield this.send(join);
+ return response.match;
+ });
+ }
+ joinParty(party_id) {
+ return __async(this, null, function* () {
+ return yield this.send({ party_join: { party_id } });
+ });
+ }
+ leaveChat(channel_id) {
+ return this.send({ channel_leave: { channel_id } });
+ }
+ leaveMatch(matchId) {
+ return this.send({ match_leave: { match_id: matchId } });
+ }
+ leaveParty(party_id) {
+ return this.send({ party_leave: { party_id } });
+ }
+ listPartyJoinRequests(party_id) {
+ return __async(this, null, function* () {
+ const response = yield this.send({ party_join_request_list: { party_id } });
+ return response.party_join_request;
+ });
+ }
+ promotePartyMember(party_id, party_member) {
+ return __async(this, null, function* () {
+ const response = yield this.send({ party_promote: { party_id, presence: party_member } });
+ return response.party_leader;
+ });
+ }
+ removeChatMessage(channel_id, message_id) {
+ return __async(this, null, function* () {
+ const response = yield this.send(
+ {
+ channel_message_remove: {
+ channel_id,
+ message_id
+ }
+ }
+ );
+ return response.channel_message_ack;
+ });
+ }
+ removeMatchmaker(ticket) {
+ return this.send({ matchmaker_remove: { ticket } });
+ }
+ removeMatchmakerParty(party_id, ticket) {
+ return this.send(
+ {
+ party_matchmaker_remove: {
+ party_id,
+ ticket
+ }
+ }
+ );
+ }
+ removePartyMember(party_id, member) {
+ return __async(this, null, function* () {
+ return this.send({
+ party_remove: {
+ party_id,
+ presence: member
+ }
+ });
+ });
+ }
+ rpc(id, payload, http_key) {
+ return __async(this, null, function* () {
+ const response = yield this.send(
+ {
+ rpc: {
+ id,
+ payload,
+ http_key
+ }
+ }
+ );
+ return response.rpc;
+ });
+ }
+ sendMatchState(matchId, opCode, data, presences, reliable) {
+ return __async(this, null, function* () {
+ return this.send(
+ {
+ match_data_send: {
+ match_id: matchId,
+ op_code: opCode,
+ data,
+ presences: presences != null ? presences : [],
+ reliable
+ }
+ }
+ );
+ });
+ }
+ sendPartyData(party_id, op_code, data) {
+ return this.send({ party_data_send: { party_id, op_code, data } });
+ }
+ unfollowUsers(user_ids) {
+ return this.send({ status_unfollow: { user_ids } });
+ }
+ updateChatMessage(channel_id, message_id, content) {
+ return __async(this, null, function* () {
+ const response = yield this.send({ channel_message_update: { channel_id, message_id, content } });
+ return response.channel_message_ack;
+ });
+ }
+ updateStatus(status) {
+ return this.send({ status_update: { status } });
+ }
+ writeChatMessage(channel_id, content) {
+ return __async(this, null, function* () {
+ const response = yield this.send({ channel_message_send: { channel_id, content } });
+ return response.channel_message_ack;
+ });
+ }
+ pingPong() {
+ return __async(this, null, function* () {
+ if (!this.adapter.isOpen()) {
+ return;
+ }
+ try {
+ yield this.send({ ping: {} }, this._heartbeatTimeoutMs);
+ } catch (e) {
+ if (this.adapter.isOpen()) {
+ if (window && window.console) {
+ console.error("Server unreachable from heartbeat.");
+ }
+ this.onheartbeattimeout();
+ this.adapter.close();
+ }
+ return;
+ }
+ setTimeout(() => this.pingPong(), this._heartbeatTimeoutMs);
+ });
+ }
+};
+var DefaultSocket = _DefaultSocket;
+DefaultSocket.DefaultHeartbeatTimeoutMs = 1e4;
+DefaultSocket.DefaultSendTimeoutMs = 1e4;
+DefaultSocket.DefaultConnectTimeoutMs = 3e4;
+
+// client.ts
+var DEFAULT_HOST = "127.0.0.1";
+var DEFAULT_PORT = "7350";
+var DEFAULT_SERVER_KEY = "defaultkey";
+var DEFAULT_TIMEOUT_MS = 7e3;
+var DEFAULT_EXPIRED_TIMESPAN_MS = 5 * 60 * 1e3;
+var Client = class {
+ constructor(serverkey = DEFAULT_SERVER_KEY, host = DEFAULT_HOST, port = DEFAULT_PORT, useSSL = false, timeout = DEFAULT_TIMEOUT_MS, autoRefreshSession = true) {
+ this.serverkey = serverkey;
+ this.host = host;
+ this.port = port;
+ this.useSSL = useSSL;
+ this.timeout = timeout;
+ this.autoRefreshSession = autoRefreshSession;
+ /** The expired timespan used to check session lifetime. */
+ this.expiredTimespanMs = DEFAULT_EXPIRED_TIMESPAN_MS;
+ const scheme = useSSL ? "https://" : "http://";
+ const portSuffix = ((useSSL && (port === '443' || port === 443)) || (!useSSL && (port === '80' || port === 80))) ? "" : `:${port}`;
+ const basePath = `${scheme}${host}${portSuffix}`;
+ this.apiClient = new NakamaApi(serverkey, basePath, timeout);
+ }
+ /** Add users to a group, or accept their join requests. */
+ addGroupUsers(session, groupId, ids) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ return this.apiClient.addGroupUsers(session.token, groupId, ids).then((response) => {
+ return response !== void 0;
+ });
+ });
+ }
+ /** Add friends by ID or username to a user's account. */
+ addFriends(session, ids, usernames) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ return this.apiClient.addFriends(session.token, ids, usernames).then((response) => {
+ return response !== void 0;
+ });
+ });
+ }
+ /** Authenticate a user with an Apple ID against the server. */
+ authenticateApple(_0, _1, _2) {
+ return __async(this, arguments, function* (token, create, username, vars = {}, options = {}) {
+ const request = {
+ "token": token,
+ "vars": vars
+ };
+ return this.apiClient.authenticateApple(this.serverkey, "", request, create, username, options).then((apiSession) => {
+ return new Session(apiSession.token || "", apiSession.refresh_token || "", apiSession.created || false);
+ });
+ });
+ }
+ /** Authenticate a user with a custom id against the server. */
+ authenticateCustom(id, create, username, vars = {}, options = {}) {
+ const request = {
+ "id": id,
+ "vars": vars
+ };
+ return this.apiClient.authenticateCustom(this.serverkey, "", request, create, username, options).then((apiSession) => {
+ return new Session(apiSession.token || "", apiSession.refresh_token || "", apiSession.created || false);
+ });
+ }
+ /** Authenticate a user with a device id against the server. */
+ authenticateDevice(id, create, username, vars) {
+ const request = {
+ "id": id,
+ "vars": vars
+ };
+ return this.apiClient.authenticateDevice(this.serverkey, "", request, create, username).then((apiSession) => {
+ return new Session(apiSession.token || "", apiSession.refresh_token || "", apiSession.created || false);
+ });
+ }
+ /** Authenticate a user with an email+password against the server. */
+ authenticateEmail(email, password, create, username, vars) {
+ const request = {
+ "email": email,
+ "password": password,
+ "vars": vars
+ };
+ return this.apiClient.authenticateEmail(this.serverkey, "", request, create, username).then((apiSession) => {
+ return new Session(apiSession.token || "", apiSession.refresh_token || "", apiSession.created || false);
+ });
+ }
+ /** Authenticate a user with a Facebook Instant Game token against the server. */
+ authenticateFacebookInstantGame(signedPlayerInfo, create, username, vars, options = {}) {
+ const request = {
+ "signed_player_info": signedPlayerInfo,
+ "vars": vars
+ };
+ return this.apiClient.authenticateFacebookInstantGame(
+ this.serverkey,
+ "",
+ { signed_player_info: request.signed_player_info, vars: request.vars },
+ create,
+ username,
+ options
+ ).then((apiSession) => {
+ return new Session(apiSession.token || "", apiSession.refresh_token || "", apiSession.created || false);
+ });
+ }
+ /** Authenticate a user with a Facebook OAuth token against the server. */
+ authenticateFacebook(token, create, username, sync, vars, options = {}) {
+ const request = {
+ "token": token,
+ "vars": vars
+ };
+ return this.apiClient.authenticateFacebook(this.serverkey, "", request, create, username, sync, options).then((apiSession) => {
+ return new Session(apiSession.token || "", apiSession.refresh_token || "", apiSession.created || false);
+ });
+ }
+ /** Authenticate a user with Google against the server. */
+ authenticateGoogle(_0, _1, _2, _3) {
+ return __async(this, arguments, function* (token, create, username, vars, options = {}) {
+ const request = {
+ token,
+ vars
+ };
+ const apiSession = yield this.apiClient.authenticateGoogle(
+ this.serverkey,
+ "",
+ request,
+ create,
+ username,
+ options
+ );
+ return new Session(
+ apiSession.token || "",
+ apiSession.refresh_token || "",
+ apiSession.created || false
+ );
+ });
+ }
+ /** Authenticate a user with GameCenter against the server. */
+ authenticateGameCenter(_0, _1, _2, _3, _4, _5, _6, _7, _8) {
+ return __async(this, arguments, function* (bundleId, playerId, publicKeyUrl, salt, signature, timestamp, username, create, vars, options = {}) {
+ const request = {
+ bundle_id: bundleId,
+ player_id: playerId,
+ public_key_url: publicKeyUrl,
+ salt,
+ signature,
+ timestamp_seconds: timestamp,
+ vars
+ };
+ const apiSession = yield this.apiClient.authenticateGameCenter(
+ this.serverkey,
+ "",
+ request,
+ create,
+ username,
+ options
+ );
+ return new Session(
+ apiSession.token || "",
+ apiSession.refresh_token || "",
+ apiSession.created || false
+ );
+ });
+ }
+ /** Authenticate a user with Steam against the server. */
+ authenticateSteam(token, create, username, sync, vars) {
+ return __async(this, null, function* () {
+ const request = {
+ "token": token,
+ "vars": vars,
+ "sync": sync
+ };
+ return this.apiClient.authenticateSteam(this.serverkey, "", request, create, username).then((apiSession) => {
+ return new Session(apiSession.token || "", apiSession.refresh_token || "", apiSession.created || false);
+ });
+ });
+ }
+ /** Ban users from a group. */
+ banGroupUsers(session, groupId, ids) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ return this.apiClient.banGroupUsers(session.token, groupId, ids).then((response) => {
+ return response !== void 0;
+ });
+ });
+ }
+ /** Block one or more users by ID or username. */
+ blockFriends(session, ids, usernames) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ return this.apiClient.blockFriends(session.token, ids, usernames).then((response) => {
+ return Promise.resolve(response != void 0);
+ });
+ });
+ }
+ /** Create a new group with the current user as the creator and superadmin. */
+ createGroup(session, request) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ return this.apiClient.createGroup(session.token, request).then((response) => {
+ return Promise.resolve({
+ avatar_url: response.avatar_url,
+ create_time: response.create_time,
+ creator_id: response.creator_id,
+ description: response.description,
+ edge_count: response.edge_count ? Number(response.edge_count) : 0,
+ id: response.id,
+ lang_tag: response.lang_tag,
+ max_count: response.max_count ? Number(response.max_count) : 0,
+ metadata: response.metadata ? JSON.parse(response.metadata) : void 0,
+ name: response.name,
+ open: response.open,
+ update_time: response.update_time
+ });
+ });
+ });
+ }
+ /** A socket created with the client's configuration. */
+ createSocket(useSSL = false, verbose = false, adapter = new WebSocketAdapterText(), sendTimeoutMs = DefaultSocket.DefaultSendTimeoutMs) {
+ return new DefaultSocket(this.host, this.port, useSSL, verbose, adapter, sendTimeoutMs);
+ }
+ /** Delete the current user's account. */
+ deleteAccount(session) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ return this.apiClient.deleteAccount(session.token).then((response) => {
+ return response !== void 0;
+ });
+ });
+ }
+ /** Delete one or more users by ID or username. */
+ deleteFriends(session, ids, usernames) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ return this.apiClient.deleteFriends(session.token, ids, usernames).then((response) => {
+ return response !== void 0;
+ });
+ });
+ }
+ /** Delete a group the user is part of and has permissions to delete. */
+ deleteGroup(session, groupId) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ return this.apiClient.deleteGroup(session.token, groupId).then((response) => {
+ return response !== void 0;
+ });
+ });
+ }
+ /** Delete one or more notifications */
+ deleteNotifications(session, ids) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ return this.apiClient.deleteNotifications(session.token, ids).then((response) => {
+ return Promise.resolve(response != void 0);
+ });
+ });
+ }
+ /** Delete one or more storage objects */
+ deleteStorageObjects(session, request) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ return this.apiClient.deleteStorageObjects(session.token, request).then((response) => {
+ return Promise.resolve(response != void 0);
+ });
+ });
+ }
+ /** Delete a tournament record. */
+ deleteTournamentRecord(session, tournamentId) {
+ return __async(this, null, function* () {
+ return this.apiClient.deleteTournamentRecord(session.token, tournamentId);
+ });
+ }
+ /** Demote a set of users in a group to the next role down. */
+ demoteGroupUsers(session, groupId, ids) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ return this.apiClient.demoteGroupUsers(session.token, groupId, ids).then((response) => {
+ return Promise.resolve(response != void 0);
+ });
+ });
+ }
+ /** Submit an event for processing in the server's registered runtime custom events handler. */
+ emitEvent(session, request) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ return this.apiClient.event(session.token, request).then((response) => {
+ return Promise.resolve(response != void 0);
+ });
+ });
+ }
+ /** Fetch the current user's account. */
+ getAccount(session) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ return this.apiClient.getAccount(session.token);
+ });
+ }
+ /** Get subscription by product id. */
+ getSubscription(session, productId) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ return this.apiClient.getSubscription(session.token, productId);
+ });
+ }
+ /** Import Facebook friends and add them to a user's account. */
+ importFacebookFriends(session, request) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ return this.apiClient.importFacebookFriends(session.token, request).then((response) => {
+ return response !== void 0;
+ });
+ });
+ }
+ /** Import Steam friends and add them to a user's account. */
+ importSteamFriends(session, request, reset) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ return this.apiClient.importSteamFriends(session.token, request, reset).then((response) => {
+ return response !== void 0;
+ });
+ });
+ }
+ /** Fetch zero or more users by ID and/or username. */
+ getUsers(session, ids, usernames, facebookIds) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ return this.apiClient.getUsers(session.token, ids, usernames, facebookIds).then((response) => {
+ var result = {
+ users: []
+ };
+ if (response.users == null) {
+ return Promise.resolve(result);
+ }
+ response.users.forEach((u) => {
+ result.users.push({
+ avatar_url: u.avatar_url,
+ create_time: u.create_time,
+ display_name: u.display_name,
+ edge_count: u.edge_count ? Number(u.edge_count) : 0,
+ facebook_id: u.facebook_id,
+ gamecenter_id: u.gamecenter_id,
+ google_id: u.google_id,
+ id: u.id,
+ lang_tag: u.lang_tag,
+ location: u.location,
+ online: u.online,
+ steam_id: u.steam_id,
+ timezone: u.timezone,
+ update_time: u.update_time,
+ username: u.username,
+ metadata: u.metadata ? JSON.parse(u.metadata) : void 0
+ });
+ });
+ return Promise.resolve(result);
+ });
+ });
+ }
+ /** Join a group that's open, or send a request to join a group that is closed. */
+ joinGroup(session, groupId) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ return this.apiClient.joinGroup(session.token, groupId, {}).then((response) => {
+ return response !== void 0;
+ });
+ });
+ }
+ joinTournament(session, tournamentId) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ return this.apiClient.joinTournament(session.token, tournamentId, {}).then((response) => {
+ return response !== void 0;
+ });
+ });
+ }
+ /** Kick users from a group, or decline their join requests. */
+ kickGroupUsers(session, groupId, ids) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ return this.apiClient.kickGroupUsers(session.token, groupId, ids).then((response) => {
+ return Promise.resolve(response != void 0);
+ });
+ });
+ }
+ /** Leave a group the user is part of. */
+ leaveGroup(session, groupId) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ return this.apiClient.leaveGroup(session.token, groupId, {}).then((response) => {
+ return response !== void 0;
+ });
+ });
+ }
+ /** List a channel's message history. */
+ listChannelMessages(session, channelId, limit, forward, cursor) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ return this.apiClient.listChannelMessages(session.token, channelId, limit, forward, cursor).then((response) => {
+ var result = {
+ messages: [],
+ next_cursor: response.next_cursor,
+ prev_cursor: response.prev_cursor,
+ cacheable_cursor: response.cacheable_cursor
+ };
+ if (response.messages == null) {
+ return Promise.resolve(result);
+ }
+ response.messages.forEach((m) => {
+ result.messages.push({
+ channel_id: m.channel_id,
+ code: m.code ? Number(m.code) : 0,
+ create_time: m.create_time,
+ message_id: m.message_id,
+ persistent: m.persistent,
+ sender_id: m.sender_id,
+ update_time: m.update_time,
+ username: m.username,
+ content: m.content ? JSON.parse(m.content) : void 0,
+ group_id: m.group_id,
+ room_name: m.room_name,
+ user_id_one: m.user_id_one,
+ user_id_two: m.user_id_two
+ });
+ });
+ return Promise.resolve(result);
+ });
+ });
+ }
+ /** List a group's users. */
+ listGroupUsers(session, groupId, state, limit, cursor) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ return this.apiClient.listGroupUsers(session.token, groupId, limit, state, cursor).then((response) => {
+ var result = {
+ group_users: [],
+ cursor: response.cursor
+ };
+ if (response.group_users == null) {
+ return Promise.resolve(result);
+ }
+ response.group_users.forEach((gu) => {
+ result.group_users.push({
+ user: {
+ avatar_url: gu.user.avatar_url,
+ create_time: gu.user.create_time,
+ display_name: gu.user.display_name,
+ edge_count: gu.user.edge_count ? Number(gu.user.edge_count) : 0,
+ facebook_id: gu.user.facebook_id,
+ gamecenter_id: gu.user.gamecenter_id,
+ google_id: gu.user.google_id,
+ id: gu.user.id,
+ lang_tag: gu.user.lang_tag,
+ location: gu.user.location,
+ online: gu.user.online,
+ steam_id: gu.user.steam_id,
+ timezone: gu.user.timezone,
+ update_time: gu.user.update_time,
+ username: gu.user.username,
+ metadata: gu.user.metadata ? JSON.parse(gu.user.metadata) : void 0
+ },
+ state: gu.state ? Number(gu.state) : 0
+ });
+ });
+ return Promise.resolve(result);
+ });
+ });
+ }
+ /** List a user's groups. */
+ listUserGroups(session, userId, state, limit, cursor) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ return this.apiClient.listUserGroups(session.token, userId, state, limit, cursor).then((response) => {
+ var result = {
+ user_groups: [],
+ cursor: response.cursor
+ };
+ if (response.user_groups == null) {
+ return Promise.resolve(result);
+ }
+ response.user_groups.forEach((ug) => {
+ result.user_groups.push({
+ group: {
+ avatar_url: ug.group.avatar_url,
+ create_time: ug.group.create_time,
+ creator_id: ug.group.creator_id,
+ description: ug.group.description,
+ edge_count: ug.group.edge_count ? Number(ug.group.edge_count) : 0,
+ id: ug.group.id,
+ lang_tag: ug.group.lang_tag,
+ max_count: ug.group.max_count,
+ metadata: ug.group.metadata ? JSON.parse(ug.group.metadata) : void 0,
+ name: ug.group.name,
+ open: ug.group.open,
+ update_time: ug.group.update_time
+ },
+ state: ug.state ? Number(ug.state) : 0
+ });
+ });
+ return Promise.resolve(result);
+ });
+ });
+ }
+ /** List groups based on given filters. */
+ listGroups(session, name, cursor, limit) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ return this.apiClient.listGroups(session.token, name, cursor, limit).then((response) => {
+ var result = {
+ groups: []
+ };
+ if (response.groups == null) {
+ return Promise.resolve(result);
+ }
+ result.cursor = response.cursor;
+ response.groups.forEach((ug) => {
+ result.groups.push({
+ avatar_url: ug.avatar_url,
+ create_time: ug.create_time,
+ creator_id: ug.creator_id,
+ description: ug.description,
+ edge_count: ug.edge_count ? Number(ug.edge_count) : 0,
+ id: ug.id,
+ lang_tag: ug.lang_tag,
+ max_count: ug.max_count,
+ metadata: ug.metadata ? JSON.parse(ug.metadata) : void 0,
+ name: ug.name,
+ open: ug.open,
+ update_time: ug.update_time
+ });
+ });
+ return Promise.resolve(result);
+ });
+ });
+ }
+ /** Add an Apple ID to the social profiles on the current user's account. */
+ linkApple(session, request) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ return this.apiClient.linkApple(session.token, request).then((response) => {
+ return response !== void 0;
+ });
+ });
+ }
+ /** Add a custom ID to the social profiles on the current user's account. */
+ linkCustom(session, request) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ return this.apiClient.linkCustom(session.token, request).then((response) => {
+ return response !== void 0;
+ });
+ });
+ }
+ /** Add a device ID to the social profiles on the current user's account. */
+ linkDevice(session, request) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ return this.apiClient.linkDevice(session.token, request).then((response) => {
+ return response !== void 0;
+ });
+ });
+ }
+ /** Add an email+password to the social profiles on the current user's account. */
+ linkEmail(session, request) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ return this.apiClient.linkEmail(session.token, request).then((response) => {
+ return response !== void 0;
+ });
+ });
+ }
+ /** Add Facebook to the social profiles on the current user's account. */
+ linkFacebook(session, request) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ return this.apiClient.linkFacebook(session.token, request).then((response) => {
+ return response !== void 0;
+ });
+ });
+ }
+ /** Add Facebook Instant to the social profiles on the current user's account. */
+ linkFacebookInstantGame(session, request) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ return this.apiClient.linkFacebookInstantGame(session.token, request).then((response) => {
+ return response !== void 0;
+ });
+ });
+ }
+ /** Add Google to the social profiles on the current user's account. */
+ linkGoogle(session, request) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ return this.apiClient.linkGoogle(session.token, request).then((response) => {
+ return response !== void 0;
+ });
+ });
+ }
+ /** Add GameCenter to the social profiles on the current user's account. */
+ linkGameCenter(session, request) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ return this.apiClient.linkGameCenter(session.token, request).then((response) => {
+ return response !== void 0;
+ });
+ });
+ }
+ /** Add Steam to the social profiles on the current user's account. */
+ linkSteam(session, request) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ return this.apiClient.linkSteam(session.token, request).then((response) => {
+ return response !== void 0;
+ });
+ });
+ }
+ /** List all friends for the current user. */
+ listFriends(session, state, limit, cursor) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ return this.apiClient.listFriends(session.token, limit, state, cursor).then((response) => {
+ var result = {
+ friends: [],
+ cursor: response.cursor
+ };
+ if (response.friends == null) {
+ return Promise.resolve(result);
+ }
+ response.friends.forEach((f) => {
+ result.friends.push({
+ user: {
+ avatar_url: f.user.avatar_url,
+ create_time: f.user.create_time,
+ display_name: f.user.display_name,
+ edge_count: f.user.edge_count ? Number(f.user.edge_count) : 0,
+ facebook_id: f.user.facebook_id,
+ gamecenter_id: f.user.gamecenter_id,
+ google_id: f.user.google_id,
+ id: f.user.id,
+ lang_tag: f.user.lang_tag,
+ location: f.user.location,
+ online: f.user.online,
+ steam_id: f.user.steam_id,
+ timezone: f.user.timezone,
+ update_time: f.user.update_time,
+ username: f.user.username,
+ metadata: f.user.metadata ? JSON.parse(f.user.metadata) : void 0,
+ facebook_instant_game_id: f.user.facebook_instant_game_id
+ },
+ state: f.state
+ });
+ });
+ return Promise.resolve(result);
+ });
+ });
+ }
+ /** List friends of friends for the current user. */
+ listFriendsOfFriends(session, limit, cursor) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ return this.apiClient.listFriendsOfFriends(session.token, limit, cursor).then((response) => {
+ var result = {
+ friends_of_friends: [],
+ cursor: response.cursor
+ };
+ if (response.friends_of_friends == null) {
+ return Promise.resolve(result);
+ }
+ response.friends_of_friends.forEach((f) => {
+ result.friends_of_friends.push({
+ referrer: f.referrer,
+ user: {
+ avatar_url: f.user.avatar_url,
+ create_time: f.user.create_time,
+ display_name: f.user.display_name,
+ edge_count: f.user.edge_count ? Number(f.user.edge_count) : 0,
+ facebook_id: f.user.facebook_id,
+ gamecenter_id: f.user.gamecenter_id,
+ google_id: f.user.google_id,
+ id: f.user.id,
+ lang_tag: f.user.lang_tag,
+ location: f.user.location,
+ online: f.user.online,
+ steam_id: f.user.steam_id,
+ timezone: f.user.timezone,
+ update_time: f.user.update_time,
+ username: f.user.username,
+ metadata: f.user.metadata ? JSON.parse(f.user.metadata) : void 0,
+ facebook_instant_game_id: f.user.facebook_instant_game_id
+ }
+ });
+ });
+ return Promise.resolve(result);
+ });
+ });
+ }
+ /** List leaderboard records */
+ listLeaderboardRecords(session, leaderboardId, ownerIds, limit, cursor, expiry) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ return this.apiClient.listLeaderboardRecords(session.token, leaderboardId, ownerIds, limit, cursor, expiry).then((response) => {
+ var list = {
+ next_cursor: response.next_cursor,
+ prev_cursor: response.prev_cursor,
+ rank_count: response.rank_count ? Number(response.rank_count) : 0,
+ owner_records: [],
+ records: []
+ };
+ if (response.owner_records != null) {
+ response.owner_records.forEach((o) => {
+ list.owner_records.push({
+ expiry_time: o.expiry_time,
+ leaderboard_id: o.leaderboard_id,
+ metadata: o.metadata ? JSON.parse(o.metadata) : void 0,
+ num_score: o.num_score ? Number(o.num_score) : 0,
+ owner_id: o.owner_id,
+ rank: o.rank ? Number(o.rank) : 0,
+ score: o.score ? Number(o.score) : 0,
+ subscore: o.subscore ? Number(o.subscore) : 0,
+ update_time: o.update_time,
+ username: o.username,
+ max_num_score: o.max_num_score ? Number(o.max_num_score) : 0
+ });
+ });
+ }
+ if (response.records != null) {
+ response.records.forEach((o) => {
+ list.records.push({
+ expiry_time: o.expiry_time,
+ leaderboard_id: o.leaderboard_id,
+ metadata: o.metadata ? JSON.parse(o.metadata) : void 0,
+ num_score: o.num_score ? Number(o.num_score) : 0,
+ owner_id: o.owner_id,
+ rank: o.rank ? Number(o.rank) : 0,
+ score: o.score ? Number(o.score) : 0,
+ subscore: o.subscore ? Number(o.subscore) : 0,
+ update_time: o.update_time,
+ username: o.username,
+ max_num_score: o.max_num_score ? Number(o.max_num_score) : 0
+ });
+ });
+ }
+ return Promise.resolve(list);
+ });
+ });
+ }
+ listLeaderboardRecordsAroundOwner(session, leaderboardId, ownerId, limit, expiry, cursor) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ return this.apiClient.listLeaderboardRecordsAroundOwner(session.token, leaderboardId, ownerId, limit, expiry, cursor).then((response) => {
+ var list = {
+ next_cursor: response.next_cursor,
+ prev_cursor: response.prev_cursor,
+ rank_count: response.rank_count ? Number(response.rank_count) : 0,
+ owner_records: [],
+ records: []
+ };
+ if (response.owner_records != null) {
+ response.owner_records.forEach((o) => {
+ list.owner_records.push({
+ expiry_time: o.expiry_time,
+ leaderboard_id: o.leaderboard_id,
+ metadata: o.metadata ? JSON.parse(o.metadata) : void 0,
+ num_score: o.num_score ? Number(o.num_score) : 0,
+ owner_id: o.owner_id,
+ rank: o.rank ? Number(o.rank) : 0,
+ score: o.score ? Number(o.score) : 0,
+ subscore: o.subscore ? Number(o.subscore) : 0,
+ update_time: o.update_time,
+ username: o.username,
+ max_num_score: o.max_num_score ? Number(o.max_num_score) : 0
+ });
+ });
+ }
+ if (response.records != null) {
+ response.records.forEach((o) => {
+ list.records.push({
+ expiry_time: o.expiry_time,
+ leaderboard_id: o.leaderboard_id,
+ metadata: o.metadata ? JSON.parse(o.metadata) : void 0,
+ num_score: o.num_score ? Number(o.num_score) : 0,
+ owner_id: o.owner_id,
+ rank: o.rank ? Number(o.rank) : 0,
+ score: o.score ? Number(o.score) : 0,
+ subscore: o.subscore ? Number(o.subscore) : 0,
+ update_time: o.update_time,
+ username: o.username,
+ max_num_score: o.max_num_score ? Number(o.max_num_score) : 0
+ });
+ });
+ }
+ return Promise.resolve(list);
+ });
+ });
+ }
+ /** Fetch list of running matches. */
+ listMatches(session, limit, authoritative, label, minSize, maxSize, query) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ return this.apiClient.listMatches(session.token, limit, authoritative, label, minSize, maxSize, query);
+ });
+ }
+ /** Fetch list of notifications. */
+ listNotifications(session, limit, cacheableCursor) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ return this.apiClient.listNotifications(session.token, limit, cacheableCursor).then((response) => {
+ var result = {
+ cacheable_cursor: response.cacheable_cursor,
+ notifications: []
+ };
+ if (response.notifications == null) {
+ return Promise.resolve(result);
+ }
+ response.notifications.forEach((n) => {
+ result.notifications.push({
+ code: n.code ? Number(n.code) : 0,
+ create_time: n.create_time,
+ id: n.id,
+ persistent: n.persistent,
+ sender_id: n.sender_id,
+ subject: n.subject,
+ content: n.content ? JSON.parse(n.content) : void 0
+ });
+ });
+ return Promise.resolve(result);
+ });
+ });
+ }
+ /** List storage objects. */
+ listStorageObjects(session, collection, userId, limit, cursor) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ return this.apiClient.listStorageObjects(session.token, collection, userId, limit, cursor).then((response) => {
+ var result = {
+ objects: [],
+ cursor: response.cursor
+ };
+ if (response.objects == null) {
+ return Promise.resolve(result);
+ }
+ response.objects.forEach((o) => {
+ result.objects.push({
+ collection: o.collection,
+ key: o.key,
+ permission_read: o.permission_read ? Number(o.permission_read) : 0,
+ permission_write: o.permission_write ? Number(o.permission_write) : 0,
+ value: o.value ? JSON.parse(o.value) : void 0,
+ version: o.version,
+ user_id: o.user_id,
+ create_time: o.create_time,
+ update_time: o.update_time
+ });
+ });
+ return Promise.resolve(result);
+ });
+ });
+ }
+ /** List current or upcoming tournaments. */
+ listTournaments(session, categoryStart, categoryEnd, startTime, endTime, limit, cursor) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ return this.apiClient.listTournaments(session.token, categoryStart, categoryEnd, startTime, endTime, limit, cursor).then((response) => {
+ var list = {
+ cursor: response.cursor,
+ tournaments: []
+ };
+ if (response.tournaments != null) {
+ response.tournaments.forEach((o) => {
+ list.tournaments.push({
+ id: o.id,
+ title: o.title,
+ description: o.description,
+ duration: o.duration ? Number(o.duration) : 0,
+ category: o.category ? Number(o.category) : 0,
+ sort_order: o.sort_order ? Number(o.sort_order) : 0,
+ size: o.size ? Number(o.size) : 0,
+ max_size: o.max_size ? Number(o.max_size) : 0,
+ max_num_score: o.max_num_score ? Number(o.max_num_score) : 0,
+ can_enter: o.can_enter,
+ end_active: o.end_active ? Number(o.end_active) : 0,
+ next_reset: o.next_reset ? Number(o.next_reset) : 0,
+ metadata: o.metadata ? JSON.parse(o.metadata) : void 0,
+ create_time: o.create_time,
+ start_time: o.start_time,
+ end_time: o.end_time,
+ start_active: o.start_active,
+ authoritative: o.authoritative
+ });
+ });
+ }
+ return Promise.resolve(list);
+ });
+ });
+ }
+ /** List user subscriptions. */
+ listSubscriptions(session, cursor, limit) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ return this.apiClient.listSubscriptions(session.token, {
+ cursor,
+ limit
+ });
+ });
+ }
+ /** List tournament records from a given tournament. */
+ listTournamentRecords(session, tournamentId, ownerIds, limit, cursor, expiry) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ return this.apiClient.listTournamentRecords(session.token, tournamentId, ownerIds, limit, cursor, expiry).then((response) => {
+ var list = {
+ next_cursor: response.next_cursor,
+ prev_cursor: response.prev_cursor,
+ owner_records: [],
+ records: []
+ };
+ if (response.owner_records != null) {
+ response.owner_records.forEach((o) => {
+ list.owner_records.push({
+ expiry_time: o.expiry_time,
+ leaderboard_id: o.leaderboard_id,
+ metadata: o.metadata ? JSON.parse(o.metadata) : void 0,
+ num_score: o.num_score ? Number(o.num_score) : 0,
+ owner_id: o.owner_id,
+ rank: o.rank ? Number(o.rank) : 0,
+ score: o.score ? Number(o.score) : 0,
+ subscore: o.subscore ? Number(o.subscore) : 0,
+ update_time: o.update_time,
+ username: o.username,
+ max_num_score: o.max_num_score ? Number(o.max_num_score) : 0
+ });
+ });
+ }
+ if (response.records != null) {
+ response.records.forEach((o) => {
+ list.records.push({
+ expiry_time: o.expiry_time,
+ leaderboard_id: o.leaderboard_id,
+ metadata: o.metadata ? JSON.parse(o.metadata) : void 0,
+ num_score: o.num_score ? Number(o.num_score) : 0,
+ owner_id: o.owner_id,
+ rank: o.rank ? Number(o.rank) : 0,
+ score: o.score ? Number(o.score) : 0,
+ subscore: o.subscore ? Number(o.subscore) : 0,
+ update_time: o.update_time,
+ username: o.username,
+ max_num_score: o.max_num_score ? Number(o.max_num_score) : 0
+ });
+ });
+ }
+ return Promise.resolve(list);
+ });
+ });
+ }
+ /** List tournament records from a given tournament around the owner. */
+ listTournamentRecordsAroundOwner(session, tournamentId, ownerId, limit, expiry, cursor) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ return this.apiClient.listTournamentRecordsAroundOwner(session.token, tournamentId, ownerId, limit, expiry, cursor).then((response) => {
+ var list = {
+ next_cursor: response.next_cursor,
+ prev_cursor: response.prev_cursor,
+ owner_records: [],
+ records: []
+ };
+ if (response.owner_records != null) {
+ response.owner_records.forEach((o) => {
+ list.owner_records.push({
+ expiry_time: o.expiry_time,
+ leaderboard_id: o.leaderboard_id,
+ metadata: o.metadata ? JSON.parse(o.metadata) : void 0,
+ num_score: o.num_score ? Number(o.num_score) : 0,
+ owner_id: o.owner_id,
+ rank: o.rank ? Number(o.rank) : 0,
+ score: o.score ? Number(o.score) : 0,
+ subscore: o.subscore ? Number(o.subscore) : 0,
+ update_time: o.update_time,
+ username: o.username,
+ max_num_score: o.max_num_score ? Number(o.max_num_score) : 0
+ });
+ });
+ }
+ if (response.records != null) {
+ response.records.forEach((o) => {
+ list.records.push({
+ expiry_time: o.expiry_time,
+ leaderboard_id: o.leaderboard_id,
+ metadata: o.metadata ? JSON.parse(o.metadata) : void 0,
+ num_score: o.num_score ? Number(o.num_score) : 0,
+ owner_id: o.owner_id,
+ rank: o.rank ? Number(o.rank) : 0,
+ score: o.score ? Number(o.score) : 0,
+ subscore: o.subscore ? Number(o.subscore) : 0,
+ update_time: o.update_time,
+ username: o.username,
+ max_num_score: o.max_num_score ? Number(o.max_num_score) : 0
+ });
+ });
+ }
+ return Promise.resolve(list);
+ });
+ });
+ }
+ /** Promote users in a group to the next role up. */
+ promoteGroupUsers(session, groupId, ids) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ return this.apiClient.promoteGroupUsers(session.token, groupId, ids);
+ });
+ }
+ /** Fetch storage objects. */
+ readStorageObjects(session, request) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ return this.apiClient.readStorageObjects(session.token, request).then((response) => {
+ var result = { objects: [] };
+ if (response.objects == null) {
+ return Promise.resolve(result);
+ }
+ response.objects.forEach((o) => {
+ result.objects.push({
+ collection: o.collection,
+ key: o.key,
+ permission_read: o.permission_read ? Number(o.permission_read) : 0,
+ permission_write: o.permission_write ? Number(o.permission_write) : 0,
+ value: o.value ? JSON.parse(o.value) : void 0,
+ version: o.version,
+ user_id: o.user_id,
+ create_time: o.create_time,
+ update_time: o.update_time
+ });
+ });
+ return Promise.resolve(result);
+ });
+ });
+ }
+ /** Execute an RPC function on the server. */
+ rpc(session, id, input) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ return this.apiClient.rpcFunc(session.token, id, JSON.stringify(input)).then((response) => {
+ return Promise.resolve({
+ id: response.id,
+ payload: !response.payload ? void 0 : JSON.parse(response.payload)
+ });
+ });
+ });
+ }
+ /** Execute an RPC function on the server. */
+ rpcHttpKey(httpKey, id, input) {
+ return __async(this, null, function* () {
+ return this.apiClient.rpcFunc2("", id, input && JSON.stringify(input) || "", httpKey).then((response) => {
+ return Promise.resolve({
+ id: response.id,
+ payload: !response.payload ? void 0 : JSON.parse(response.payload)
+ });
+ }).catch((err) => {
+ throw err;
+ });
+ });
+ }
+ /** Log out a session, invalidate a refresh token, or log out all sessions/refresh tokens for a user. */
+ sessionLogout(session, token, refreshToken) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ return this.apiClient.sessionLogout(session.token, { refresh_token: refreshToken, token }).then((response) => {
+ return response !== void 0;
+ });
+ });
+ }
+ /** Refresh a user's session using a refresh token retrieved from a previous authentication request. */
+ sessionRefresh(_0) {
+ return __async(this, arguments, function* (session, vars = {}) {
+ if (!session) {
+ console.error("Cannot refresh a null session.");
+ return session;
+ }
+ if (session.created && session.expires_at - session.created_at < 70) {
+ console.warn("Session lifetime too short, please set '--session.token_expiry_sec' option. See the documentation for more info: https://heroiclabs.com/docs/nakama/getting-started/configuration/#session");
+ }
+ if (session.created && session.refresh_expires_at - session.created_at < 3700) {
+ console.warn("Session refresh lifetime too short, please set '--session.refresh_token_expiry_sec' option. See the documentation for more info: https://heroiclabs.com/docs/nakama/getting-started/configuration/#session");
+ }
+ const apiSession = yield this.apiClient.sessionRefresh(this.serverkey, "", { token: session.refresh_token, vars });
+ session.update(apiSession.token, apiSession.refresh_token);
+ return session;
+ });
+ }
+ /** Remove the Apple ID from the social profiles on the current user's account. */
+ unlinkApple(session, request) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ return this.apiClient.unlinkApple(session.token, request).then((response) => {
+ return response !== void 0;
+ });
+ });
+ }
+ /** Remove custom ID from the social profiles on the current user's account. */
+ unlinkCustom(session, request) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ return this.apiClient.unlinkCustom(session.token, request).then((response) => {
+ return response !== void 0;
+ });
+ });
+ }
+ /** Remove a device ID from the social profiles on the current user's account. */
+ unlinkDevice(session, request) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ return this.apiClient.unlinkDevice(session.token, request).then((response) => {
+ return response !== void 0;
+ });
+ });
+ }
+ /** Remove an email+password from the social profiles on the current user's account. */
+ unlinkEmail(session, request) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ return this.apiClient.unlinkEmail(session.token, request).then((response) => {
+ return response !== void 0;
+ });
+ });
+ }
+ /** Remove Facebook from the social profiles on the current user's account. */
+ unlinkFacebook(session, request) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ return this.apiClient.unlinkFacebook(session.token, request).then((response) => {
+ return response !== void 0;
+ });
+ });
+ }
+ /** Remove Facebook Instant social profiles from the current user's account. */
+ unlinkFacebookInstantGame(session, request) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ return this.apiClient.unlinkFacebookInstantGame(session.token, request).then((response) => {
+ return response !== void 0;
+ });
+ });
+ }
+ /** Remove Google from the social profiles on the current user's account. */
+ unlinkGoogle(session, request) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ return this.apiClient.unlinkGoogle(session.token, request).then((response) => {
+ return response !== void 0;
+ });
+ });
+ }
+ /** Remove GameCenter from the social profiles on the current user's account. */
+ unlinkGameCenter(session, request) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ return this.apiClient.unlinkGameCenter(session.token, request).then((response) => {
+ return response !== void 0;
+ });
+ });
+ }
+ /** Remove Steam from the social profiles on the current user's account. */
+ unlinkSteam(session, request) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ return this.apiClient.unlinkSteam(session.token, request).then((response) => {
+ return response !== void 0;
+ });
+ });
+ }
+ /** Update fields in the current user's account. */
+ updateAccount(session, request) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ return this.apiClient.updateAccount(session.token, request).then((response) => {
+ return response !== void 0;
+ });
+ });
+ }
+ /** Update a group the user is part of and has permissions to update. */
+ updateGroup(session, groupId, request) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ return this.apiClient.updateGroup(session.token, groupId, request).then((response) => {
+ return response !== void 0;
+ });
+ });
+ }
+ /** Validate an Apple IAP receipt. */
+ validatePurchaseApple(session, receipt, persist = true) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ return this.apiClient.validatePurchaseApple(session.token, { receipt, persist });
+ });
+ }
+ /** Validate a FB Instant IAP receipt. */
+ validatePurchaseFacebookInstant(session, signedRequest, persist = true) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ return this.apiClient.validatePurchaseFacebookInstant(session.token, { signed_request: signedRequest, persist });
+ });
+ }
+ /** Validate a Google IAP receipt. */
+ validatePurchaseGoogle(session, purchase, persist = true) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ return this.apiClient.validatePurchaseGoogle(session.token, { purchase, persist });
+ });
+ }
+ /** Validate a Huawei IAP receipt. */
+ validatePurchaseHuawei(session, purchase, signature, persist = true) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ return this.apiClient.validatePurchaseHuawei(session.token, { purchase, signature, persist });
+ });
+ }
+ /** Validate Apple Subscription Receipt */
+ validateSubscriptionApple(session, receipt, persist = true) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ return this.apiClient.validateSubscriptionApple(session.token, { receipt, persist });
+ });
+ }
+ /** Validate Google Subscription Receipt */
+ validateSubscriptionGoogle(session, receipt, persist = true) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ return this.apiClient.validateSubscriptionGoogle(session.token, { receipt, persist });
+ });
+ }
+ /** Write a record to a leaderboard. */
+ writeLeaderboardRecord(session, leaderboardId, request) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ return this.apiClient.writeLeaderboardRecord(session.token, leaderboardId, {
+ metadata: request.metadata ? JSON.stringify(request.metadata) : void 0,
+ score: request.score,
+ subscore: request.subscore
+ }).then((response) => {
+ return Promise.resolve({
+ expiry_time: response.expiry_time,
+ leaderboard_id: response.leaderboard_id,
+ metadata: response.metadata ? JSON.parse(response.metadata) : void 0,
+ num_score: response.num_score ? Number(response.num_score) : 0,
+ owner_id: response.owner_id,
+ score: response.score ? Number(response.score) : 0,
+ subscore: response.subscore ? Number(response.subscore) : 0,
+ update_time: response.update_time,
+ username: response.username,
+ max_num_score: response.max_num_score ? Number(response.max_num_score) : 0,
+ rank: response.rank ? Number(response.rank) : 0
+ });
+ });
+ });
+ }
+ /** Write storage objects. */
+ writeStorageObjects(session, objects) {
+ return __async(this, null, function* () {
+ if (this.autoRefreshSession && session.refresh_token && session.isexpired((Date.now() + this.expiredTimespanMs) / 1e3)) {
+ yield this.sessionRefresh(session);
+ }
+ var request = { objects: [] };
+ objects.forEach((o) => {
+ request.objects.push({
+ collection: o.collection,
+ key: o.key,
+ permission_read: o.permission_read,
+ permission_write: o.permission_write,
+ value: JSON.stringify(o.value),
+ version: o.version
+ });
+ });
+ return this.apiClient.writeStorageObjects(session.token, request);
+ });
+ }
+ /** Write a record to a tournament. */
+ writeTournamentRecord(session, tournamentId, request) {
+ return __async(this, null, function* () {
+ return this.apiClient.writeTournamentRecord(session.token, tournamentId, {
+ metadata: request.metadata ? JSON.stringify(request.metadata) : void 0,
+ score: request.score,
+ subscore: request.subscore
+ }).then((response) => {
+ return Promise.resolve({
+ expiry_time: response.expiry_time,
+ leaderboard_id: response.leaderboard_id,
+ metadata: response.metadata ? JSON.parse(response.metadata) : void 0,
+ num_score: response.num_score ? Number(response.num_score) : 0,
+ owner_id: response.owner_id,
+ score: response.score ? Number(response.score) : 0,
+ subscore: response.subscore ? Number(response.subscore) : 0,
+ update_time: response.update_time,
+ username: response.username,
+ max_num_score: response.max_num_score ? Number(response.max_num_score) : 0,
+ rank: response.rank ? Number(response.rank) : 0
+ });
+ });
+ });
+ }
+};
+export {
+ Client,
+ DefaultSocket,
+ Session,
+ WebSocketAdapterText
+};
diff --git a/utils/nakamaManager.js b/utils/nakamaManager.js
new file mode 100644
index 0000000..c668a15
--- /dev/null
+++ b/utils/nakamaManager.js
@@ -0,0 +1,468 @@
+/**
+ * Nakama WebSocket Manager - 小程序直连版
+ * 移除 SDK 依赖,直接使用原生 WebSocket 协议
+ */
+
+class NakamaManager {
+ constructor() {
+ this.serverUrl = null;
+ this.serverKey = 'defaultkey';
+ this.useSSL = true;
+ this.host = null;
+ this.port = '443';
+
+ this.session = null;
+ this.gameToken = null;
+ this.socketTask = null;
+ this.isConnected = false;
+
+ // 消息 ID 和待处理的 Promise
+ this.nextCid = 1;
+ this.pendingRequests = {};
+
+ // 事件监听器
+ this.listeners = {
+ onmatchmakermatched: null,
+ onmatchdata: null,
+ onmatchpresence: null,
+ ondisconnect: null,
+ onerror: null
+ };
+
+ // 心跳定时器
+ this.heartbeatTimer = null;
+ this.heartbeatInterval = 10000; // 10秒
+ }
+
+ /**
+ * 初始化客户端配置
+ */
+ initClient(serverUrl, serverKey = 'defaultkey') {
+ this.serverKey = serverKey;
+ this.serverUrl = serverUrl;
+
+ // 解析 URL
+ const isWss = serverUrl.startsWith('wss://') || serverUrl.startsWith('https://');
+ let host = serverUrl.replace('wss://', '').replace('ws://', '').replace('https://', '').replace('http://', '');
+ let port = isWss ? '443' : '7350';
+
+ if (host.includes(':')) {
+ const parts = host.split(':');
+ host = parts[0];
+ port = parts[1];
+ }
+
+ this.host = host;
+ this.port = port;
+ this.useSSL = isWss;
+
+ console.log(`[Nakama] Initialized: ${this.useSSL ? 'wss' : 'ws'}://${this.host}:${this.port}`);
+ }
+
+ /**
+ * 设置事件监听器
+ */
+ setListeners(config) {
+ Object.keys(config).forEach(key => {
+ if (this.listeners.hasOwnProperty(key)) {
+ this.listeners[key] = config[key];
+ }
+ });
+ }
+
+ /**
+ * 使用 game_token 认证
+ */
+ async authenticateWithGameToken(gameToken) {
+ this.gameToken = gameToken;
+
+ // 生成唯一的 custom ID
+ const customId = `game_${Date.now()}_${Math.random().toString(36).substring(7)}`;
+ console.log('[Nakama] Authenticating with Custom ID:', customId);
+
+ // HTTP 认证请求
+ const scheme = this.useSSL ? 'https://' : 'http://';
+ const portSuffix = (this.useSSL && this.port === '443') || (!this.useSSL && this.port === '80') ? '' : `:${this.port}`;
+ const authUrl = `${scheme}${this.host}${portSuffix}/v2/account/authenticate/custom?create=true`;
+
+ return new Promise((resolve, reject) => {
+ uni.request({
+ url: authUrl,
+ method: 'POST',
+ header: {
+ 'Authorization': 'Basic ' + this._base64Encode(`${this.serverKey}:`),
+ 'Content-Type': 'application/json'
+ },
+ data: { id: customId },
+ success: (res) => {
+ if (res.statusCode === 200 && res.data && res.data.token) {
+ this.session = {
+ token: res.data.token,
+ refresh_token: res.data.refresh_token,
+ user_id: this._parseUserIdFromToken(res.data.token)
+ };
+ console.log('[Nakama] Authenticated, user_id:', this.session.user_id);
+
+ // 认证成功后建立 WebSocket 连接
+ this._connectWebSocket()
+ .then(() => resolve(this.session))
+ .catch(reject);
+ } else {
+ reject(new Error('Authentication failed: ' + JSON.stringify(res.data)));
+ }
+ },
+ fail: (err) => {
+ reject(new Error('Authentication request failed: ' + err.errMsg));
+ }
+ });
+ });
+ }
+
+ /**
+ * 建立 WebSocket 连接
+ */
+ _connectWebSocket() {
+ return new Promise((resolve, reject) => {
+ const scheme = this.useSSL ? 'wss://' : 'ws://';
+ const portSuffix = (this.useSSL && this.port === '443') || (!this.useSSL && this.port === '80') ? '' : `:${this.port}`;
+ const wsUrl = `${scheme}${this.host}${portSuffix}/ws?lang=en&status=true&token=${encodeURIComponent(this.session.token)}`;
+
+ console.log('[Nakama] WebSocket connecting...');
+
+ this.socketTask = uni.connectSocket({
+ url: wsUrl,
+ complete: () => { }
+ });
+
+ const connectTimeout = setTimeout(() => {
+ reject(new Error('WebSocket connection timeout'));
+ }, 15000);
+
+ this.socketTask.onOpen(() => {
+ clearTimeout(connectTimeout);
+ this.isConnected = true;
+ console.log('[Nakama] WebSocket connected');
+ this._startHeartbeat();
+ resolve();
+ });
+
+ this.socketTask.onClose((res) => {
+ console.log('[Nakama] WebSocket closed:', res.code, res.reason);
+ this.isConnected = false;
+ this._stopHeartbeat();
+ if (this.listeners.ondisconnect) {
+ this.listeners.ondisconnect(res);
+ }
+ });
+
+ this.socketTask.onError((err) => {
+ clearTimeout(connectTimeout);
+ console.error('[Nakama] WebSocket error:', err);
+ this.isConnected = false;
+ if (this.listeners.onerror) {
+ this.listeners.onerror(err);
+ }
+ reject(new Error('WebSocket connection failed'));
+ });
+
+ this.socketTask.onMessage((res) => {
+ this._handleMessage(res.data);
+ });
+ });
+ }
+
+ /**
+ * 处理收到的消息
+ */
+ _handleMessage(rawData) {
+ let message;
+ try {
+ message = typeof rawData === 'string' ? JSON.parse(rawData) : rawData;
+ } catch (e) {
+ console.error('[Nakama] Failed to parse message:', e);
+ return;
+ }
+
+ // 有 cid 的消息是请求的响应
+ if (message.cid) {
+ const pending = this.pendingRequests[message.cid];
+ if (pending) {
+ delete this.pendingRequests[message.cid];
+ clearTimeout(pending.timeout);
+ if (message.error) {
+ pending.reject(new Error(message.error.message || JSON.stringify(message.error)));
+ } else {
+ pending.resolve(message);
+ }
+ }
+ return;
+ }
+
+ // 无 cid 的消息是服务器主动推送
+ if (message.matchmaker_matched) {
+ console.log('[Nakama] Matchmaker matched:', message.matchmaker_matched.match_id);
+ if (this.listeners.onmatchmakermatched) {
+ this.listeners.onmatchmakermatched(message.matchmaker_matched);
+ }
+ } else if (message.match_data) {
+ // 解码 base64 数据
+ if (message.match_data.data) {
+ message.match_data.data = this._base64ToUint8Array(message.match_data.data);
+ }
+ message.match_data.op_code = parseInt(message.match_data.op_code);
+ if (this.listeners.onmatchdata) {
+ this.listeners.onmatchdata(message.match_data);
+ }
+ } else if (message.match_presence_event) {
+ if (this.listeners.onmatchpresence) {
+ this.listeners.onmatchpresence(message.match_presence_event);
+ }
+ }
+ }
+
+ /**
+ * 发送消息并等待响应
+ */
+ _send(message, timeoutMs = 10000) {
+ return new Promise((resolve, reject) => {
+ if (!this.isConnected || !this.socketTask) {
+ reject(new Error('Socket not connected'));
+ return;
+ }
+
+ const cid = String(this.nextCid++);
+ message.cid = cid;
+
+ const timeout = setTimeout(() => {
+ delete this.pendingRequests[cid];
+ reject(new Error('Request timeout'));
+ }, timeoutMs);
+
+ this.pendingRequests[cid] = { resolve, reject, timeout };
+
+ this.socketTask.send({
+ data: JSON.stringify(message),
+ fail: (err) => {
+ delete this.pendingRequests[cid];
+ clearTimeout(timeout);
+ reject(new Error('Send failed: ' + err.errMsg));
+ }
+ });
+ });
+ }
+
+ /**
+ * 发送消息(无需响应)
+ */
+ _sendNoResponse(message) {
+ if (!this.isConnected || !this.socketTask) {
+ console.error('[Nakama] Cannot send, not connected');
+ return;
+ }
+
+ this.socketTask.send({
+ data: JSON.stringify(message),
+ fail: (err) => {
+ console.error('[Nakama] Send failed:', err);
+ }
+ });
+ }
+
+ /**
+ * 开始匹配
+ */
+ async findMatch(minCount, maxCount) {
+ if (!this.isConnected) {
+ console.log('[Nakama] Not connected, reconnecting...');
+ await this.authenticateWithGameToken(this.gameToken);
+ }
+
+ console.log('[Nakama] Adding to matchmaker:', minCount, '-', maxCount);
+ const response = await this._send({
+ matchmaker_add: {
+ min_count: minCount || 2,
+ max_count: maxCount || 2,
+ query: '*',
+ string_properties: { game_token: this.gameToken }
+ }
+ });
+ console.log('[Nakama] Matchmaker ticket:', response.matchmaker_ticket);
+ return response.matchmaker_ticket;
+ }
+
+ /**
+ * 加入比赛
+ */
+ async joinMatch(matchId, token) {
+ console.log('[Nakama] Joining match:', matchId);
+ const join = { match_join: {} };
+ if (token) {
+ join.match_join.token = token;
+ } else {
+ join.match_join.match_id = matchId;
+ }
+
+ // 关键:传递 game_token 用于服务端验证
+ join.match_join.metadata = { game_token: this.gameToken };
+
+ const response = await this._send(join);
+ console.log('[Nakama] Joined match:', response.match?.match_id);
+ return response.match;
+ }
+
+ /**
+ * 发送游戏状态
+ */
+ sendMatchState(matchId, opCode, data) {
+ const payload = typeof data === 'string' ? data : JSON.stringify(data);
+ this._sendNoResponse({
+ match_data_send: {
+ match_id: matchId,
+ op_code: String(opCode),
+ data: this._base64Encode(payload)
+ }
+ });
+ }
+
+ /**
+ * 断开连接
+ */
+ disconnect() {
+ this._stopHeartbeat();
+ if (this.socketTask) {
+ this.socketTask.close();
+ this.socketTask = null;
+ }
+ this.isConnected = false;
+ this.session = null;
+ this.gameToken = null;
+ console.log('[Nakama] Disconnected');
+ }
+
+ // ============ 心跳 ============
+
+ _startHeartbeat() {
+ this._stopHeartbeat();
+ this.heartbeatTimer = setInterval(() => {
+ if (this.isConnected) {
+ this._send({ ping: {} }, 5000).catch(() => {
+ console.warn('[Nakama] Heartbeat failed');
+ });
+ }
+ }, this.heartbeatInterval);
+ }
+
+ _stopHeartbeat() {
+ if (this.heartbeatTimer) {
+ clearInterval(this.heartbeatTimer);
+ this.heartbeatTimer = null;
+ }
+ }
+
+ // ============ 工具方法 ============
+
+ _base64Encode(str) {
+ // 小程序环境没有 btoa,需要手动实现
+ const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
+ let output = '';
+
+ // 将字符串转为 UTF-8 字节数组
+ const bytes = [];
+ for (let i = 0; i < str.length; i++) {
+ const code = str.charCodeAt(i);
+ if (code < 0x80) {
+ bytes.push(code);
+ } else if (code < 0x800) {
+ bytes.push(0xc0 | (code >> 6), 0x80 | (code & 0x3f));
+ } else {
+ bytes.push(0xe0 | (code >> 12), 0x80 | ((code >> 6) & 0x3f), 0x80 | (code & 0x3f));
+ }
+ }
+
+ for (let i = 0; i < bytes.length; i += 3) {
+ const b1 = bytes[i];
+ const b2 = bytes[i + 1];
+ const b3 = bytes[i + 2];
+
+ output += chars.charAt(b1 >> 2);
+ output += chars.charAt(((b1 & 3) << 4) | (b2 >> 4) || 0);
+ output += b2 !== undefined ? chars.charAt(((b2 & 15) << 2) | (b3 >> 6) || 0) : '=';
+ output += b3 !== undefined ? chars.charAt(b3 & 63) : '=';
+ }
+
+ return output;
+ }
+
+ _base64ToUint8Array(base64) {
+ const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
+ const lookup = new Uint8Array(256);
+ for (let i = 0; i < chars.length; i++) {
+ lookup[chars.charCodeAt(i)] = i;
+ }
+
+ let bufferLength = base64.length * 0.75;
+ if (base64[base64.length - 1] === '=') bufferLength--;
+ if (base64[base64.length - 2] === '=') bufferLength--;
+
+ const bytes = new Uint8Array(bufferLength);
+ let p = 0;
+
+ for (let i = 0; i < base64.length; i += 4) {
+ const e1 = lookup[base64.charCodeAt(i)];
+ const e2 = lookup[base64.charCodeAt(i + 1)];
+ const e3 = lookup[base64.charCodeAt(i + 2)];
+ const e4 = lookup[base64.charCodeAt(i + 3)];
+
+ bytes[p++] = (e1 << 2) | (e2 >> 4);
+ if (base64[i + 2] !== '=') bytes[p++] = ((e2 & 15) << 4) | (e3 >> 2);
+ if (base64[i + 3] !== '=') bytes[p++] = ((e3 & 3) << 6) | e4;
+ }
+
+ return bytes;
+ }
+
+ _parseUserIdFromToken(token) {
+ try {
+ const parts = token.split('.');
+ if (parts.length !== 3) return null;
+
+ const payload = parts[1];
+ // Base64 URL 解码
+ const base64 = payload.replace(/-/g, '+').replace(/_/g, '/');
+ const padded = base64 + '=='.slice(0, (4 - base64.length % 4) % 4);
+
+ // 解码 base64
+ const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
+ const lookup = {};
+ for (let i = 0; i < chars.length; i++) {
+ lookup[chars[i]] = i;
+ }
+
+ let bytes = [];
+ for (let i = 0; i < padded.length; i += 4) {
+ const e1 = lookup[padded[i]] || 0;
+ const e2 = lookup[padded[i + 1]] || 0;
+ const e3 = lookup[padded[i + 2]] || 0;
+ const e4 = lookup[padded[i + 3]] || 0;
+
+ bytes.push((e1 << 2) | (e2 >> 4));
+ if (padded[i + 2] !== '=') bytes.push(((e2 & 15) << 4) | (e3 >> 2));
+ if (padded[i + 3] !== '=') bytes.push(((e3 & 3) << 6) | e4);
+ }
+
+ // UTF-8 解码
+ let str = '';
+ for (let i = 0; i < bytes.length; i++) {
+ str += String.fromCharCode(bytes[i]);
+ }
+
+ const parsed = JSON.parse(str);
+ return parsed.uid || parsed.sub || null;
+ } catch (e) {
+ console.error('[Nakama] Failed to parse token:', e);
+ return null;
+ }
+ }
+}
+
+export const nakamaManager = new NakamaManager();