connectbase-client 3.35.2 → 3.36.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -0
- package/dist/connect-base.umd.js +2 -2
- package/dist/index.d.mts +52 -19
- package/dist/index.d.ts +52 -19
- package/dist/index.js +69 -40
- package/dist/index.mjs +69 -40
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -5471,11 +5471,23 @@ var PaymentAPI = class {
|
|
|
5471
5471
|
* // Mount PaymentElement, then:
|
|
5472
5472
|
* // stripe.confirmPayment({ elements, redirect: 'if_required' })
|
|
5473
5473
|
* }
|
|
5474
|
+
*
|
|
5475
|
+
* // PayApp 결제 플로우 (위젯 불필요 — 호스팅 결제창으로 redirect)
|
|
5476
|
+
* // 결제 결과는 서버의 feedbackurl webhook 으로 확정되며, 사용자는 success_url 로 복귀한다.
|
|
5477
|
+
* if (result.payment_provider === 'payapp' && result.payapp_pay_url) {
|
|
5478
|
+
* window.location.href = result.payapp_pay_url
|
|
5479
|
+
* }
|
|
5474
5480
|
* ```
|
|
5481
|
+
*
|
|
5482
|
+
* @remarks
|
|
5483
|
+
* PayApp 은 `customer_phone` 이 필수입니다(결제요청 수신 번호). 미지정 시 서버가 거부합니다.
|
|
5475
5484
|
*/
|
|
5476
5485
|
async prepare(data) {
|
|
5477
5486
|
const prefix = this.getPublicPrefix();
|
|
5478
|
-
return this.http.post(
|
|
5487
|
+
return this.http.post(
|
|
5488
|
+
`${prefix}/payments/prepare`,
|
|
5489
|
+
data
|
|
5490
|
+
);
|
|
5479
5491
|
}
|
|
5480
5492
|
/**
|
|
5481
5493
|
* Stripe-hosted 결제 페이지 세션 생성 (client_secret 미노출 플로우).
|
|
@@ -5539,7 +5551,10 @@ var PaymentAPI = class {
|
|
|
5539
5551
|
*/
|
|
5540
5552
|
async confirm(data) {
|
|
5541
5553
|
const prefix = this.getPublicPrefix();
|
|
5542
|
-
return this.http.post(
|
|
5554
|
+
return this.http.post(
|
|
5555
|
+
`${prefix}/payments/confirm`,
|
|
5556
|
+
data
|
|
5557
|
+
);
|
|
5543
5558
|
}
|
|
5544
5559
|
/**
|
|
5545
5560
|
* 결제 취소
|
|
@@ -6093,20 +6108,22 @@ var PushAPI = class {
|
|
|
6093
6108
|
}
|
|
6094
6109
|
// ============ Server-side Send (Functions / cb_sk_ 전용) ============
|
|
6095
6110
|
/**
|
|
6096
|
-
* 회원 ID 목록으로 푸시 발송 — Functions /
|
|
6111
|
+
* 회원 ID 목록으로 푸시 발송 — Functions / 서버사이드 인증 환경 전용.
|
|
6097
6112
|
*
|
|
6098
|
-
* 백엔드 라우트 `POST /v1/apps/:appID/push/send` 는 콘솔 JWT
|
|
6099
|
-
* (`
|
|
6100
|
-
* 자체가
|
|
6113
|
+
* 백엔드 라우트 `POST /v1/apps/:appID/push/send` 는 콘솔 JWT, User Secret Key(`cb_sk_`),
|
|
6114
|
+
* 또는 service_role 토큰(`ctx.cbAdmin`)을 받는다. 브라우저 SDK 의 Public Key(`cb_pk_`)
|
|
6115
|
+
* **단독** 인스턴스에서는 호출 자체가 차단되며(권한 누설 방지), 명확한 에러를 던진다.
|
|
6116
|
+
* 위임 Bearer 토큰을 가진 인스턴스(`ctx.cbAdmin`/`ctx.cb`)는 cb_pk_ 가 앱 식별용으로만
|
|
6117
|
+
* 실리므로 허용된다.
|
|
6101
6118
|
*
|
|
6102
|
-
* @param appId 발송 대상 앱 ID
|
|
6119
|
+
* @param appId 발송 대상 앱 ID.
|
|
6103
6120
|
* @param memberIds 받는 회원 ID 배열 (UUID).
|
|
6104
6121
|
* @param payload 푸시 내용/옵션.
|
|
6105
6122
|
*
|
|
6106
6123
|
* @example
|
|
6107
6124
|
* ```ts
|
|
6108
|
-
* // ConnectBase Function (
|
|
6109
|
-
* const result = await
|
|
6125
|
+
* // ConnectBase Function (service_role=true) — 시크릿 키 없이 ctx.cbAdmin 으로 발송
|
|
6126
|
+
* const result = await ctx.cbAdmin.push.sendToMembers(ctx.appId, [memberId], {
|
|
6110
6127
|
* title: '새 알림',
|
|
6111
6128
|
* body: '확인해보세요',
|
|
6112
6129
|
* data: { route: '/notifications' },
|
|
@@ -6115,9 +6132,9 @@ var PushAPI = class {
|
|
|
6115
6132
|
* ```
|
|
6116
6133
|
*/
|
|
6117
6134
|
async sendToMembers(appId, memberIds, payload) {
|
|
6118
|
-
if (this.http.hasPublicKey()) {
|
|
6135
|
+
if (this.http.hasPublicKey() && !this.http.hasJWT()) {
|
|
6119
6136
|
throw new Error(
|
|
6120
|
-
"cb.push.sendToMembers() \uB294 User Secret Key(cb_sk_) \
|
|
6137
|
+
"cb.push.sendToMembers() \uB294 User Secret Key(cb_sk_), \uCF58\uC194 JWT, \uB610\uB294 service_role(ctx.cbAdmin) \uC778\uC99D\uC774 \uD544\uC694\uD569\uB2C8\uB2E4. Public Key(cb_pk_) \uB2E8\uB3C5 SDK \uC778\uC2A4\uD134\uC2A4\uB85C\uB294 \uD638\uCD9C\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4 \u2014 Functions \uD658\uACBD\uC5D0\uC11C \uC0AC\uC6A9\uD558\uC138\uC694."
|
|
6121
6138
|
);
|
|
6122
6139
|
}
|
|
6123
6140
|
if (memberIds.length === 0) {
|
|
@@ -6569,8 +6586,9 @@ var VideoAPI = class {
|
|
|
6569
6586
|
*
|
|
6570
6587
|
* @example
|
|
6571
6588
|
* ```ts
|
|
6572
|
-
* const {
|
|
6573
|
-
* videoElement.src =
|
|
6589
|
+
* const { master_playlist, qualities, expires_at } = await cb.video.getStreamUrl(videoId)
|
|
6590
|
+
* videoElement.src = master_playlist // 적응형 비트레이트(HLS.js 등으로 재생)
|
|
6591
|
+
* // 특정 화질 고정이 필요하면 qualities['720p'] 사용
|
|
6574
6592
|
* ```
|
|
6575
6593
|
*/
|
|
6576
6594
|
async getStreamUrl(videoId, quality) {
|
|
@@ -6749,7 +6767,8 @@ var VideoAPI = class {
|
|
|
6749
6767
|
*/
|
|
6750
6768
|
async postComment(videoId, content, parentId) {
|
|
6751
6769
|
const prefix = this.getPublicPrefix();
|
|
6752
|
-
return this.videoFetch("POST", `${prefix}/
|
|
6770
|
+
return this.videoFetch("POST", `${prefix}/comments`, {
|
|
6771
|
+
video_id: videoId,
|
|
6753
6772
|
content,
|
|
6754
6773
|
parent_id: parentId
|
|
6755
6774
|
});
|
|
@@ -6816,31 +6835,31 @@ var VideoAPI = class {
|
|
|
6816
6835
|
const prefix = this.getPublicPrefix();
|
|
6817
6836
|
const response = await this.videoFetch(
|
|
6818
6837
|
"GET",
|
|
6819
|
-
`${prefix}/channels/${channelId}/
|
|
6838
|
+
`${prefix}/channels/${channelId}/membership/tiers`
|
|
6820
6839
|
);
|
|
6821
6840
|
return response.tiers;
|
|
6822
6841
|
}
|
|
6823
6842
|
/**
|
|
6824
6843
|
* Join a membership tier
|
|
6844
|
+
*
|
|
6845
|
+
* @param _channelId 현재 서버에서 무시됩니다 (tier 가 채널을 함의). API 안정성을 위해 시그니처만 유지.
|
|
6846
|
+
* @param tierId 가입할 멤버십 티어 ID
|
|
6825
6847
|
*/
|
|
6826
|
-
async joinMembership(
|
|
6848
|
+
async joinMembership(_channelId, tierId) {
|
|
6827
6849
|
const prefix = this.getPublicPrefix();
|
|
6828
|
-
return this.videoFetch(
|
|
6829
|
-
|
|
6830
|
-
|
|
6831
|
-
{}
|
|
6832
|
-
);
|
|
6850
|
+
return this.videoFetch("POST", `${prefix}/membership/join`, {
|
|
6851
|
+
tier_id: tierId
|
|
6852
|
+
});
|
|
6833
6853
|
}
|
|
6834
6854
|
/**
|
|
6835
6855
|
* Cancel membership
|
|
6856
|
+
*
|
|
6857
|
+
* @param _channelId 현재 서버에서 무시됩니다. API 안정성을 위해 시그니처만 유지.
|
|
6858
|
+
* @param membershipId 취소할 멤버십 ID
|
|
6836
6859
|
*/
|
|
6837
|
-
async cancelMembership(
|
|
6860
|
+
async cancelMembership(_channelId, membershipId) {
|
|
6838
6861
|
const prefix = this.getPublicPrefix();
|
|
6839
|
-
await this.videoFetch(
|
|
6840
|
-
"POST",
|
|
6841
|
-
`${prefix}/channels/${channelId}/memberships/${membershipId}/cancel`,
|
|
6842
|
-
{}
|
|
6843
|
-
);
|
|
6862
|
+
await this.videoFetch("POST", `${prefix}/membership/${membershipId}/cancel`, {});
|
|
6844
6863
|
}
|
|
6845
6864
|
// ========== Super Chat Operations ==========
|
|
6846
6865
|
/**
|
|
@@ -6868,13 +6887,15 @@ var VideoAPI = class {
|
|
|
6868
6887
|
// ========== Recommendation Operations ==========
|
|
6869
6888
|
/**
|
|
6870
6889
|
* Get recommended videos
|
|
6890
|
+
*
|
|
6891
|
+
* @deprecated Use getHomeFeed() — 동일한 개인화 피드(`/recommendations/feed`)를 반환합니다.
|
|
6871
6892
|
*/
|
|
6872
6893
|
async getRecommendations(limit) {
|
|
6873
6894
|
const prefix = this.getPublicPrefix();
|
|
6874
6895
|
const params = limit ? `?limit=${limit}` : "";
|
|
6875
6896
|
const response = await this.videoFetch(
|
|
6876
6897
|
"GET",
|
|
6877
|
-
`${prefix}/recommendations${params}`
|
|
6898
|
+
`${prefix}/recommendations/feed${params}`
|
|
6878
6899
|
);
|
|
6879
6900
|
return response.videos;
|
|
6880
6901
|
}
|
|
@@ -6886,7 +6907,7 @@ var VideoAPI = class {
|
|
|
6886
6907
|
const params = limit ? `?limit=${limit}` : "";
|
|
6887
6908
|
const response = await this.videoFetch(
|
|
6888
6909
|
"GET",
|
|
6889
|
-
`${prefix}/recommendations/
|
|
6910
|
+
`${prefix}/recommendations/feed${params}`
|
|
6890
6911
|
);
|
|
6891
6912
|
return response.videos;
|
|
6892
6913
|
}
|
|
@@ -6898,7 +6919,7 @@ var VideoAPI = class {
|
|
|
6898
6919
|
const params = limit ? `?limit=${limit}` : "";
|
|
6899
6920
|
const response = await this.videoFetch(
|
|
6900
6921
|
"GET",
|
|
6901
|
-
`${prefix}/
|
|
6922
|
+
`${prefix}/videos/${videoId}/related${params}`
|
|
6902
6923
|
);
|
|
6903
6924
|
return response.videos;
|
|
6904
6925
|
}
|
|
@@ -6919,9 +6940,17 @@ var VideoAPI = class {
|
|
|
6919
6940
|
*/
|
|
6920
6941
|
async submitFeedback(videoId, feedback) {
|
|
6921
6942
|
const prefix = this.getPublicPrefix();
|
|
6922
|
-
|
|
6943
|
+
if (feedback === "not_interested") {
|
|
6944
|
+
await this.videoFetch(
|
|
6945
|
+
"POST",
|
|
6946
|
+
`${prefix}/recommendations/not-interested/${videoId}`,
|
|
6947
|
+
{}
|
|
6948
|
+
);
|
|
6949
|
+
return;
|
|
6950
|
+
}
|
|
6951
|
+
await this.videoFetch("POST", `${prefix}/recommendations/interactions`, {
|
|
6923
6952
|
video_id: videoId,
|
|
6924
|
-
|
|
6953
|
+
type: "like"
|
|
6925
6954
|
});
|
|
6926
6955
|
}
|
|
6927
6956
|
};
|
|
@@ -6963,7 +6992,7 @@ var GameConfigAPI = class {
|
|
|
6963
6992
|
/**
|
|
6964
6993
|
* 단일 기능 활성화 — set() 의 편의 wrapper.
|
|
6965
6994
|
*
|
|
6966
|
-
* @example await cb.game.config.enable(appId, "
|
|
6995
|
+
* @example await cb.game.config.enable(appId, "matchqueue_enabled")
|
|
6967
6996
|
*/
|
|
6968
6997
|
async enable(appId, feature) {
|
|
6969
6998
|
return this.set(appId, { [feature]: true });
|
|
@@ -7621,7 +7650,7 @@ var GameAPI = class {
|
|
|
7621
7650
|
const response = await fetch(`${this.gameServerUrl}/v1/game/${id}/rooms/${roomId}/spectators`, {
|
|
7622
7651
|
method: "POST",
|
|
7623
7652
|
headers: { ...this.getHeaders(), "Content-Type": "application/json" },
|
|
7624
|
-
body: JSON.stringify({
|
|
7653
|
+
body: JSON.stringify({ user_id: playerId })
|
|
7625
7654
|
});
|
|
7626
7655
|
if (!response.ok) throw new Error(`Failed to join spectator: ${response.statusText}`);
|
|
7627
7656
|
return response.json();
|
|
@@ -10947,11 +10976,11 @@ var GameRoomTransport = class {
|
|
|
10947
10976
|
});
|
|
10948
10977
|
}
|
|
10949
10978
|
// Private methods
|
|
10950
|
-
send(type, data) {
|
|
10979
|
+
send(type, data, msgId) {
|
|
10951
10980
|
if (!this.transport?.isConnected()) {
|
|
10952
10981
|
throw new GameError({ code: "NOT_CONNECTED", message: "Not connected" });
|
|
10953
10982
|
}
|
|
10954
|
-
const message = JSON.stringify({ type, data });
|
|
10983
|
+
const message = JSON.stringify({ type, data, msg_id: msgId });
|
|
10955
10984
|
this.transport.send(message, true);
|
|
10956
10985
|
}
|
|
10957
10986
|
sendWithHandler(type, data, handler) {
|
|
@@ -10960,14 +10989,14 @@ var GameRoomTransport = class {
|
|
|
10960
10989
|
setTimeout(() => {
|
|
10961
10990
|
this.pendingHandlers.delete(id);
|
|
10962
10991
|
}, 1e4);
|
|
10963
|
-
this.send(type,
|
|
10992
|
+
this.send(type, data, id);
|
|
10964
10993
|
}
|
|
10965
10994
|
handleMessage(data) {
|
|
10966
10995
|
try {
|
|
10967
10996
|
const msg = JSON.parse(data);
|
|
10968
|
-
if (msg.
|
|
10969
|
-
const handler = this.pendingHandlers.get(msg.
|
|
10970
|
-
this.pendingHandlers.delete(msg.
|
|
10997
|
+
if (msg.msg_id && this.pendingHandlers.has(msg.msg_id)) {
|
|
10998
|
+
const handler = this.pendingHandlers.get(msg.msg_id);
|
|
10999
|
+
this.pendingHandlers.delete(msg.msg_id);
|
|
10971
11000
|
handler(msg);
|
|
10972
11001
|
return;
|
|
10973
11002
|
}
|