bitsnap-react 1.18.0 → 1.19.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/AGENTS.md +106 -0
- package/README.md +98 -0
- package/dist/BitsnapCart-E72W5RRZ.mjs +2 -0
- package/dist/BitsnapCart-LHJ6KOTV.css +2 -0
- package/dist/BitsnapCart-LHJ6KOTV.css.map +1 -0
- package/dist/BitsnapCart-Q2HER6GU.js +2 -0
- package/dist/BitsnapCart-Q2HER6GU.js.map +1 -0
- package/dist/CartProvider-677CE2FI.js +2 -0
- package/dist/CartProvider-677CE2FI.js.map +1 -0
- package/dist/CartProvider-YPDOFSYC.mjs +2 -0
- package/dist/{PanelModelFiles-JZFSF7BF.mjs → PanelModelFiles-4B2HYGIE.mjs} +2 -2
- package/dist/{PanelModelFiles-7HPXWONN.js → PanelModelFiles-EKQRLF46.js} +2 -2
- package/dist/PanelModelFiles-EKQRLF46.js.map +1 -0
- package/dist/analytics.js +1 -1
- package/dist/analytics.js.map +1 -1
- package/dist/analytics.mjs +1 -1
- package/dist/catalog.js +1 -1
- package/dist/catalog.js.map +1 -1
- package/dist/catalog.mjs +1 -1
- package/dist/chat.css +2 -0
- package/dist/chat.css.map +1 -0
- package/dist/chat.d.mts +172 -0
- package/dist/chat.d.ts +172 -0
- package/dist/chat.js +2 -0
- package/dist/chat.js.map +1 -0
- package/dist/chat.mjs +2 -0
- package/dist/chat.mjs.map +1 -0
- package/dist/chunk-2FD2QP4Y.js +2 -0
- package/dist/chunk-2FD2QP4Y.js.map +1 -0
- package/dist/chunk-5JRUPLXY.mjs +2 -0
- package/dist/chunk-5JRUPLXY.mjs.map +1 -0
- package/dist/chunk-5M6M7FAR.mjs +2 -0
- package/dist/chunk-5M6M7FAR.mjs.map +1 -0
- package/dist/chunk-6Q3VGPSF.js.map +1 -1
- package/dist/chunk-AAC576BC.mjs +5 -0
- package/dist/chunk-AAC576BC.mjs.map +1 -0
- package/dist/{chunk-4OVOKGGS.mjs → chunk-AB37DWOK.mjs} +2 -2
- package/dist/{chunk-ZATPBYOA.js → chunk-BUYTK7KM.js} +2 -2
- package/dist/chunk-BUYTK7KM.js.map +1 -0
- package/dist/{chunk-DP2NOHCI.js → chunk-D2ASWUXM.js} +2 -2
- package/dist/chunk-D2ASWUXM.js.map +1 -0
- package/dist/chunk-DDIEFKNP.mjs +2 -0
- package/dist/{chunk-ZHTMK5TA.mjs.map → chunk-DDIEFKNP.mjs.map} +1 -1
- package/dist/{chunk-4HGZZJEL.js → chunk-DOJICJCQ.js} +2 -2
- package/dist/chunk-DOJICJCQ.js.map +1 -0
- package/dist/chunk-EMR4YXNY.mjs +2 -0
- package/dist/chunk-EMR4YXNY.mjs.map +1 -0
- package/dist/{chunk-JA62KNAQ.js → chunk-GJOGATP6.js} +2 -2
- package/dist/chunk-GJOGATP6.js.map +1 -0
- package/dist/chunk-GQ5OKU74.js +2 -0
- package/dist/chunk-GQ5OKU74.js.map +1 -0
- package/dist/chunk-JSDGZ4NY.js.map +1 -1
- package/dist/chunk-KHQEDQYF.js +5 -0
- package/dist/chunk-KHQEDQYF.js.map +1 -0
- package/dist/chunk-KOYBZORL.js.map +1 -1
- package/dist/chunk-LGPNJ5XE.js +2 -0
- package/dist/chunk-LGPNJ5XE.js.map +1 -0
- package/dist/chunk-MDAFPGPA.js +2 -0
- package/dist/chunk-MDAFPGPA.js.map +1 -0
- package/dist/{chunk-JHJ3ZZF4.mjs → chunk-MMLBQHBM.mjs} +2 -2
- package/dist/chunk-MWWEPEU2.js +2 -0
- package/dist/chunk-MWWEPEU2.js.map +1 -0
- package/dist/{chunk-GEBRXFT3.mjs → chunk-N523LFAM.mjs} +2 -2
- package/dist/chunk-NWXZ45TV.js +2 -0
- package/dist/chunk-NWXZ45TV.js.map +1 -0
- package/dist/chunk-OFPRIENJ.mjs +2 -0
- package/dist/chunk-OFPRIENJ.mjs.map +1 -0
- package/dist/chunk-OR566YJI.mjs +2 -0
- package/dist/chunk-OR566YJI.mjs.map +1 -0
- package/dist/chunk-Q337IQNA.js +2 -0
- package/dist/chunk-Q337IQNA.js.map +1 -0
- package/dist/chunk-SCEWYZUZ.mjs +2 -0
- package/dist/chunk-SCEWYZUZ.mjs.map +1 -0
- package/dist/{chunk-CF45RDMD.mjs → chunk-SSSF64M7.mjs} +2 -2
- package/dist/{chunk-CF45RDMD.mjs.map → chunk-SSSF64M7.mjs.map} +1 -1
- package/dist/chunk-W3RGQYPD.js.map +1 -1
- package/dist/chunk-WG54EHST.mjs +2 -0
- package/dist/chunk-WG54EHST.mjs.map +1 -0
- package/dist/chunk-XEXPQFKN.mjs +2 -0
- package/dist/chunk-XEXPQFKN.mjs.map +1 -0
- package/dist/chunk-YV2C276H.js +2 -0
- package/dist/chunk-YV2C276H.js.map +1 -0
- package/dist/consent.js.map +1 -1
- package/dist/course.d.mts +2 -14
- package/dist/course.d.ts +2 -14
- package/dist/course.js +1 -1
- package/dist/course.js.map +1 -1
- package/dist/course.mjs +1 -1
- package/dist/course.mjs.map +1 -1
- package/dist/embed/analytics.js +1 -1
- package/dist/errors.js.map +1 -1
- package/dist/index.css +1 -1
- package/dist/index.css.map +1 -1
- package/dist/index.d.mts +288 -4
- package/dist/index.d.ts +288 -4
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/internal.js.map +1 -1
- package/dist/methods-64D5DD6K.js +2 -0
- package/dist/methods-64D5DD6K.js.map +1 -0
- package/dist/methods-NQA3DFLE.mjs +2 -0
- package/dist/methods-NQA3DFLE.mjs.map +1 -0
- package/dist/model-files-client-P4PORZJ6.js.map +1 -1
- package/dist/models.js.map +1 -1
- package/dist/returns.js +1 -1
- package/dist/returns.js.map +1 -1
- package/dist/returns.mjs +1 -1
- package/dist/texts-9kfgClsA.d.mts +14 -0
- package/dist/texts-9kfgClsA.d.ts +14 -0
- package/dist/{types-D6LsoycW.d.mts → types-B-sjyZQs.d.mts} +7 -1
- package/dist/{types-ClFCVzk_.d.ts → types-iRe6ix2y.d.ts} +7 -1
- package/dist/viewer3d.js.map +1 -1
- package/dist/viewer3d.mjs +1 -1
- package/dist/viewer3d.mjs.map +1 -1
- package/dist/widgets-BT2LN2Nq.d.mts +547 -0
- package/dist/widgets-BVOSj9fU.d.ts +547 -0
- package/package.json +18 -3
- package/dist/CartProvider-OEI526IN.js +0 -2
- package/dist/CartProvider-OEI526IN.js.map +0 -1
- package/dist/CartProvider-RYAA3JDA.mjs +0 -2
- package/dist/PanelModelFiles-7HPXWONN.js.map +0 -1
- package/dist/chunk-4HGZZJEL.js.map +0 -1
- package/dist/chunk-5X7TP3TQ.mjs +0 -2
- package/dist/chunk-5X7TP3TQ.mjs.map +0 -1
- package/dist/chunk-7RXW6XFY.js +0 -2
- package/dist/chunk-7RXW6XFY.js.map +0 -1
- package/dist/chunk-DP2NOHCI.js.map +0 -1
- package/dist/chunk-EVIDNS22.mjs +0 -2
- package/dist/chunk-EVIDNS22.mjs.map +0 -1
- package/dist/chunk-G4V2KWTV.js +0 -2
- package/dist/chunk-G4V2KWTV.js.map +0 -1
- package/dist/chunk-GWF3MRUP.js +0 -2
- package/dist/chunk-GWF3MRUP.js.map +0 -1
- package/dist/chunk-JA62KNAQ.js.map +0 -1
- package/dist/chunk-UPAOIY4R.mjs +0 -2
- package/dist/chunk-UPAOIY4R.mjs.map +0 -1
- package/dist/chunk-V5ECGBFW.js +0 -5
- package/dist/chunk-V5ECGBFW.js.map +0 -1
- package/dist/chunk-VNV5BD4X.js +0 -2
- package/dist/chunk-VNV5BD4X.js.map +0 -1
- package/dist/chunk-VNYHJT6V.mjs +0 -2
- package/dist/chunk-VNYHJT6V.mjs.map +0 -1
- package/dist/chunk-WJO5GSY3.mjs +0 -5
- package/dist/chunk-WJO5GSY3.mjs.map +0 -1
- package/dist/chunk-ZATPBYOA.js.map +0 -1
- package/dist/chunk-ZHTMK5TA.mjs +0 -2
- package/dist/methods-AULQDKVS.mjs +0 -2
- package/dist/methods-PMH5VQ25.js +0 -2
- package/dist/methods-PMH5VQ25.js.map +0 -1
- /package/dist/{CartProvider-RYAA3JDA.mjs.map → BitsnapCart-E72W5RRZ.mjs.map} +0 -0
- /package/dist/{methods-AULQDKVS.mjs.map → CartProvider-YPDOFSYC.mjs.map} +0 -0
- /package/dist/{PanelModelFiles-JZFSF7BF.mjs.map → PanelModelFiles-4B2HYGIE.mjs.map} +0 -0
- /package/dist/{chunk-4OVOKGGS.mjs.map → chunk-AB37DWOK.mjs.map} +0 -0
- /package/dist/{chunk-JHJ3ZZF4.mjs.map → chunk-MMLBQHBM.mjs.map} +0 -0
- /package/dist/{chunk-GEBRXFT3.mjs.map → chunk-N523LFAM.mjs.map} +0 -0
|
@@ -0,0 +1,547 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { L as LocaleTables } from './texts-9kfgClsA.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Buyer side of the Bitsnap chat service (`bitsnap-messaging`): the shapes
|
|
6
|
+
* the library works with. The wire is snake_case JSON; `client.ts` maps it to
|
|
7
|
+
* these camelCase types. Times are ISO 8601 strings, `null` when absent.
|
|
8
|
+
*/
|
|
9
|
+
/** Default base URL of the chat service. */
|
|
10
|
+
declare const DEFAULT_CHAT_API_URL = "https://chat.bitsnap.pl";
|
|
11
|
+
/** Default NATS WebSocket URL, used when the realtime token lists no server. */
|
|
12
|
+
declare const DEFAULT_CHAT_REALTIME_URL = "wss://bitsnap-nats-queue-production.up.railway.app";
|
|
13
|
+
/** One paid order that gives a pack thread creator replies. */
|
|
14
|
+
type ChatPack = {
|
|
15
|
+
orderId: string;
|
|
16
|
+
productId?: string;
|
|
17
|
+
replies: number;
|
|
18
|
+
used: number;
|
|
19
|
+
left: number;
|
|
20
|
+
expiresAt: string | null;
|
|
21
|
+
expired: boolean;
|
|
22
|
+
};
|
|
23
|
+
/** A stored message, or the pending answer of a send. */
|
|
24
|
+
type ChatMessage = {
|
|
25
|
+
id: string;
|
|
26
|
+
threadId: string;
|
|
27
|
+
authorEmail: string;
|
|
28
|
+
body: string;
|
|
29
|
+
attachmentKey?: string;
|
|
30
|
+
attachmentKind?: string;
|
|
31
|
+
createdAt: string;
|
|
32
|
+
pinned: boolean;
|
|
33
|
+
/** Soft deleted: the body is empty. */
|
|
34
|
+
deleted: boolean;
|
|
35
|
+
/** A message of the service, such as the creator's away notice. */
|
|
36
|
+
system: boolean;
|
|
37
|
+
/** `"pending"` in the answer of a send: queued, not stored yet. */
|
|
38
|
+
status?: "pending";
|
|
39
|
+
};
|
|
40
|
+
/** The state of a conversation for the caller (`ThreadView` on the wire). */
|
|
41
|
+
type ChatThreadSummary = {
|
|
42
|
+
id: string;
|
|
43
|
+
kind: "pack" | "channel";
|
|
44
|
+
channelId?: string;
|
|
45
|
+
/** For a buyer, the creator's e-mail (pack) or the channel name. */
|
|
46
|
+
title: string;
|
|
47
|
+
lastMessage?: ChatMessage;
|
|
48
|
+
unread: number;
|
|
49
|
+
repliesTotal: number;
|
|
50
|
+
repliesUsed: number;
|
|
51
|
+
repliesLeft: number;
|
|
52
|
+
expiresAt: string | null;
|
|
53
|
+
/** The caller cannot write: every pack has expired. */
|
|
54
|
+
composerLocked: boolean;
|
|
55
|
+
productId?: string;
|
|
56
|
+
/** The creator's promise in hours ("odpowiedź w ciągu 48 h"), 0 for none. */
|
|
57
|
+
responseHours: number;
|
|
58
|
+
packs: ChatPack[];
|
|
59
|
+
muted: boolean;
|
|
60
|
+
};
|
|
61
|
+
/** A channel the caller may read. */
|
|
62
|
+
type ChatChannelSummary = {
|
|
63
|
+
id: string;
|
|
64
|
+
name: string;
|
|
65
|
+
topic: string;
|
|
66
|
+
welcome: string;
|
|
67
|
+
whoCanPost: "creator" | "members";
|
|
68
|
+
productId: string;
|
|
69
|
+
/** `creator`, `member` or `muted`. */
|
|
70
|
+
role: string;
|
|
71
|
+
memberCount: number;
|
|
72
|
+
createdAt: string;
|
|
73
|
+
blockLinks: boolean;
|
|
74
|
+
blockMedia: boolean;
|
|
75
|
+
cooldownSeconds: number;
|
|
76
|
+
};
|
|
77
|
+
/** A pack the buyer holds and has not opened a thread for yet. */
|
|
78
|
+
type ChatPackEntitlement = {
|
|
79
|
+
productId: string;
|
|
80
|
+
name: string;
|
|
81
|
+
repliesLeftHint: number;
|
|
82
|
+
expiresAt: string | null;
|
|
83
|
+
};
|
|
84
|
+
/** A community product the buyer holds; `channelId` once a channel is bound. */
|
|
85
|
+
type ChatChannelEntitlement = {
|
|
86
|
+
productId: string;
|
|
87
|
+
channelId?: string;
|
|
88
|
+
};
|
|
89
|
+
/** `GET /v1/me`: the buyer's chat in one project. */
|
|
90
|
+
type ChatMe = {
|
|
91
|
+
email: string;
|
|
92
|
+
threads: ChatThreadSummary[];
|
|
93
|
+
entitlements: {
|
|
94
|
+
packs: ChatPackEntitlement[];
|
|
95
|
+
channels: ChatChannelEntitlement[];
|
|
96
|
+
};
|
|
97
|
+
channels: ChatChannelSummary[];
|
|
98
|
+
};
|
|
99
|
+
/** One page of history, newest first as the service answers it. */
|
|
100
|
+
type ChatMessagePage = {
|
|
101
|
+
messages: ChatMessage[];
|
|
102
|
+
hasMore: boolean;
|
|
103
|
+
};
|
|
104
|
+
/** The thread part of a send answer. */
|
|
105
|
+
type ChatThreadState = Pick<ChatThreadSummary, "id" | "kind" | "repliesTotal" | "repliesUsed" | "repliesLeft" | "expiresAt" | "composerLocked" | "responseHours">;
|
|
106
|
+
/** `POST /v1/threads/{id}/messages` answers 202 with the queued message. */
|
|
107
|
+
type ChatSendResult = {
|
|
108
|
+
message: ChatMessage;
|
|
109
|
+
thread: ChatThreadState;
|
|
110
|
+
};
|
|
111
|
+
type ChatReportReason = "spam" | "abuse" | "illegal" | "other";
|
|
112
|
+
/** `POST /v1/realtime/token`. */
|
|
113
|
+
type ChatRealtimeToken = {
|
|
114
|
+
jwt: string;
|
|
115
|
+
expiresAt: string;
|
|
116
|
+
servers: string[];
|
|
117
|
+
subjects: string[];
|
|
118
|
+
truncated: boolean;
|
|
119
|
+
};
|
|
120
|
+
/** Live events on the thread or channel subject. */
|
|
121
|
+
type ChatRealtimeEvent = {
|
|
122
|
+
type: "message.created";
|
|
123
|
+
message: ChatMessage;
|
|
124
|
+
} | {
|
|
125
|
+
type: "message.rejected";
|
|
126
|
+
id: string;
|
|
127
|
+
reason: string;
|
|
128
|
+
} | {
|
|
129
|
+
type: "message.deleted";
|
|
130
|
+
id: string;
|
|
131
|
+
} | {
|
|
132
|
+
type: "message.pinned";
|
|
133
|
+
id: string;
|
|
134
|
+
} | {
|
|
135
|
+
type: "message.unpinned";
|
|
136
|
+
id: string;
|
|
137
|
+
};
|
|
138
|
+
/** How a conversation hears about new messages. */
|
|
139
|
+
type ChatLiveMode = "connecting" | "live" | "polling" | "off";
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* An error answer of the chat service (`{"error":"<code>"}`), or `network`
|
|
143
|
+
* (status 0) when the request did not get an answer.
|
|
144
|
+
*
|
|
145
|
+
* Codes the buyer UI handles: `unauthorized` (401), `plan_required`,
|
|
146
|
+
* `locked`, `muted`, `blocked`, `forbidden`, `read_only` (403), `not_found`
|
|
147
|
+
* (404), `moderation_link`, `moderation_banned_word`, `moderation_media`
|
|
148
|
+
* (422), `cooldown` (429, with `retryAfter`), `unavailable` (503),
|
|
149
|
+
* `invalid_project` (400).
|
|
150
|
+
*/
|
|
151
|
+
declare class ChatError extends Error {
|
|
152
|
+
readonly code: string;
|
|
153
|
+
readonly status: number;
|
|
154
|
+
/** `cooldown`: seconds to wait before the next post. */
|
|
155
|
+
readonly retryAfter?: number;
|
|
156
|
+
/** Extra fields of the answer (`locked`: `product_id`, `price_cents`, `welcome`). */
|
|
157
|
+
readonly data: Record<string, unknown>;
|
|
158
|
+
constructor(code: string, status: number, data?: Record<string, unknown>);
|
|
159
|
+
}
|
|
160
|
+
type ChatClientOptions = {
|
|
161
|
+
/** Project id sent as `X-Bitsnap-Project`. */
|
|
162
|
+
projectId: string;
|
|
163
|
+
/** Bearer credential: the panel session token or a `bcht_` buyer token. */
|
|
164
|
+
token: string;
|
|
165
|
+
/** Base URL of the chat service. Defaults to `https://chat.bitsnap.pl`. */
|
|
166
|
+
baseUrl?: string;
|
|
167
|
+
/** Replaces `fetch` (tests, server rendering). */
|
|
168
|
+
fetch?: typeof fetch;
|
|
169
|
+
};
|
|
170
|
+
/** The buyer calls of the chat service HTTP API. */
|
|
171
|
+
type ChatClient = {
|
|
172
|
+
readonly baseUrl: string;
|
|
173
|
+
readonly projectId: string;
|
|
174
|
+
me(): Promise<ChatMe>;
|
|
175
|
+
/** Opens or returns the pack thread of a service product. */
|
|
176
|
+
openThread(productId: string): Promise<ChatThreadSummary>;
|
|
177
|
+
/** Newest first; `before` is a message id. */
|
|
178
|
+
messages(threadId: string, options?: {
|
|
179
|
+
before?: string;
|
|
180
|
+
limit?: number;
|
|
181
|
+
}): Promise<ChatMessagePage>;
|
|
182
|
+
/** Queues a message. The service answers 202 with `status: "pending"`. */
|
|
183
|
+
send(threadId: string, input: {
|
|
184
|
+
body: string;
|
|
185
|
+
clientId?: string;
|
|
186
|
+
}): Promise<ChatSendResult>;
|
|
187
|
+
deleteMessage(threadId: string, messageId: string): Promise<void>;
|
|
188
|
+
mute(threadId: string, muted: boolean): Promise<void>;
|
|
189
|
+
report(input: {
|
|
190
|
+
threadId: string;
|
|
191
|
+
messageId?: string;
|
|
192
|
+
reason: ChatReportReason;
|
|
193
|
+
note?: string;
|
|
194
|
+
}): Promise<void>;
|
|
195
|
+
markRead(threadId: string, messageId: string): Promise<void>;
|
|
196
|
+
/**
|
|
197
|
+
* A NATS token for every conversation the caller may read. The answer is
|
|
198
|
+
* kept until a minute and a half before it expires (the service mints one
|
|
199
|
+
* per caller every 10 s); `fresh` asks for a new one.
|
|
200
|
+
*/
|
|
201
|
+
realtimeToken(options?: {
|
|
202
|
+
fresh?: boolean;
|
|
203
|
+
}): Promise<ChatRealtimeToken>;
|
|
204
|
+
};
|
|
205
|
+
declare function createChatClient(options: ChatClientOptions): ChatClient;
|
|
206
|
+
/** Parses one live event of the thread or channel subject. */
|
|
207
|
+
declare function parseRealtimeEvent(raw: unknown): ChatRealtimeEvent | null;
|
|
208
|
+
|
|
209
|
+
/** The part of `@nats-io/nats-core` the chat uses. */
|
|
210
|
+
type NatsModule = {
|
|
211
|
+
wsconnect(options: {
|
|
212
|
+
servers: string[];
|
|
213
|
+
authenticator: unknown;
|
|
214
|
+
name?: string;
|
|
215
|
+
reconnect?: boolean;
|
|
216
|
+
maxReconnectAttempts?: number;
|
|
217
|
+
}): Promise<NatsConnectionLike>;
|
|
218
|
+
jwtAuthenticator(jwt: () => string): unknown;
|
|
219
|
+
};
|
|
220
|
+
type NatsConnectionLike = {
|
|
221
|
+
subscribe(subject: string, options: {
|
|
222
|
+
callback: (error: Error | null, msg: {
|
|
223
|
+
data: Uint8Array;
|
|
224
|
+
}) => void;
|
|
225
|
+
}): {
|
|
226
|
+
unsubscribe(): void;
|
|
227
|
+
};
|
|
228
|
+
closed(): Promise<void | Error>;
|
|
229
|
+
close(): Promise<void>;
|
|
230
|
+
};
|
|
231
|
+
type LiveOptions = {
|
|
232
|
+
client: ChatClient;
|
|
233
|
+
/** `thread` for a pack thread, `channel` for a channel. */
|
|
234
|
+
kind: "thread" | "channel";
|
|
235
|
+
/** Thread id (a channel thread has the channel's id). */
|
|
236
|
+
id: string;
|
|
237
|
+
onEvent: (event: ChatRealtimeEvent) => void;
|
|
238
|
+
onMode: (mode: ChatLiveMode) => void;
|
|
239
|
+
/** Loads the newest page: the fallback, and the catch-up after a connect. */
|
|
240
|
+
poll: () => Promise<void>;
|
|
241
|
+
/** Polling interval while the socket is down. Default 8 s. */
|
|
242
|
+
pollIntervalMs?: number;
|
|
243
|
+
/** Delay before the socket is tried again after a failure. Default 60 s. */
|
|
244
|
+
retryMs?: number;
|
|
245
|
+
/** Overrides the WebSocket servers of the realtime token. */
|
|
246
|
+
realtimeUrl?: string;
|
|
247
|
+
/** Replaces the NATS loader (tests). */
|
|
248
|
+
loadNats?: () => Promise<NatsModule>;
|
|
249
|
+
};
|
|
250
|
+
/**
|
|
251
|
+
* Listens to one conversation: a realtime token from the chat service, then
|
|
252
|
+
* a subscribe-only NATS WebSocket on the conversation's subject. When any
|
|
253
|
+
* step fails (no WebSocket, token refused, subject not granted, socket
|
|
254
|
+
* closed) it polls the newest page instead and tries the socket again later.
|
|
255
|
+
* Returns the stop function.
|
|
256
|
+
*/
|
|
257
|
+
declare function startLive(options: LiveOptions): () => void;
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Every string of the chat (panel "Wiadomości", `ChatThread`, `Channel`).
|
|
261
|
+
* Pass a partial object through the `texts` prop to override any of them,
|
|
262
|
+
* whatever the locale. Placeholders like `{count}` stay in overrides.
|
|
263
|
+
*
|
|
264
|
+
* Counts use three forms (`One`, `Few`, `Many`) for Polish; English uses
|
|
265
|
+
* `One` and `Many`.
|
|
266
|
+
*/
|
|
267
|
+
type ChatTexts = {
|
|
268
|
+
inboxHeading: string;
|
|
269
|
+
inboxIntro: string;
|
|
270
|
+
inboxEmpty: string;
|
|
271
|
+
inboxError: string;
|
|
272
|
+
loading: string;
|
|
273
|
+
retry: string;
|
|
274
|
+
back: string;
|
|
275
|
+
selectConversation: string;
|
|
276
|
+
kindChat: string;
|
|
277
|
+
kindChannel: string;
|
|
278
|
+
startSection: string;
|
|
279
|
+
startChat: string;
|
|
280
|
+
openChannel: string;
|
|
281
|
+
channelNotReady: string;
|
|
282
|
+
chatFallbackTitle: string;
|
|
283
|
+
channelFallbackTitle: string;
|
|
284
|
+
/** Placeholder `{count}`. */
|
|
285
|
+
repliesLeftOne: string;
|
|
286
|
+
repliesLeftFew: string;
|
|
287
|
+
repliesLeftMany: string;
|
|
288
|
+
noRepliesLeft: string;
|
|
289
|
+
/** Placeholder `{date}`. */
|
|
290
|
+
expiresOn: string;
|
|
291
|
+
/** Placeholder `{date}`. */
|
|
292
|
+
expiredOn: string;
|
|
293
|
+
/** Placeholder `{hours}`. */
|
|
294
|
+
responseHours: string;
|
|
295
|
+
/** Placeholder `{count}`. */
|
|
296
|
+
unread: string;
|
|
297
|
+
/** Placeholder `{count}`. */
|
|
298
|
+
members: string;
|
|
299
|
+
mutedBadge: string;
|
|
300
|
+
noMessagesYet: string;
|
|
301
|
+
emptyThread: string;
|
|
302
|
+
emptyChannel: string;
|
|
303
|
+
privacyNote: string;
|
|
304
|
+
loadOlder: string;
|
|
305
|
+
you: string;
|
|
306
|
+
creator: string;
|
|
307
|
+
systemLabel: string;
|
|
308
|
+
pinned: string;
|
|
309
|
+
deletedPlaceholder: string;
|
|
310
|
+
attachment: string;
|
|
311
|
+
composerLabel: string;
|
|
312
|
+
composerPlaceholder: string;
|
|
313
|
+
send: string;
|
|
314
|
+
composerExpired: string;
|
|
315
|
+
composerCreatorOnly: string;
|
|
316
|
+
composerMuted: string;
|
|
317
|
+
composerReadOnly: string;
|
|
318
|
+
lockRepliesTitle: string;
|
|
319
|
+
lockRepliesBody: string;
|
|
320
|
+
lockExpiredTitle: string;
|
|
321
|
+
lockExpiredBody: string;
|
|
322
|
+
lockThreadTitle: string;
|
|
323
|
+
lockThreadBody: string;
|
|
324
|
+
lockChannelTitle: string;
|
|
325
|
+
lockChannelBody: string;
|
|
326
|
+
buyPack: string;
|
|
327
|
+
buyAccess: string;
|
|
328
|
+
buying: string;
|
|
329
|
+
buyError: string;
|
|
330
|
+
pending: string;
|
|
331
|
+
notConfirmed: string;
|
|
332
|
+
rejectedLink: string;
|
|
333
|
+
rejectedBannedWord: string;
|
|
334
|
+
rejectedMedia: string;
|
|
335
|
+
/** Placeholder `{seconds}`. */
|
|
336
|
+
rejectedCooldown: string;
|
|
337
|
+
rejectedBlocked: string;
|
|
338
|
+
rejectedMuted: string;
|
|
339
|
+
rejectedReadOnly: string;
|
|
340
|
+
rejectedPackEmpty: string;
|
|
341
|
+
rejectedForbidden: string;
|
|
342
|
+
rejectedGeneric: string;
|
|
343
|
+
failedNetwork: string;
|
|
344
|
+
editMessage: string;
|
|
345
|
+
retrySend: string;
|
|
346
|
+
dismiss: string;
|
|
347
|
+
messageActions: string;
|
|
348
|
+
deleteMessage: string;
|
|
349
|
+
deleteConfirm: string;
|
|
350
|
+
reportMessage: string;
|
|
351
|
+
conversationActions: string;
|
|
352
|
+
muteThread: string;
|
|
353
|
+
unmuteThread: string;
|
|
354
|
+
muteError: string;
|
|
355
|
+
reportConversation: string;
|
|
356
|
+
reportTitle: string;
|
|
357
|
+
reportConversationTitle: string;
|
|
358
|
+
reportReason: string;
|
|
359
|
+
reasonSpam: string;
|
|
360
|
+
reasonAbuse: string;
|
|
361
|
+
reasonIllegal: string;
|
|
362
|
+
reasonOther: string;
|
|
363
|
+
reportNote: string;
|
|
364
|
+
reportSend: string;
|
|
365
|
+
reportCancel: string;
|
|
366
|
+
reportSent: string;
|
|
367
|
+
reportError: string;
|
|
368
|
+
liveLabel: string;
|
|
369
|
+
pollingLabel: string;
|
|
370
|
+
errorNoToken: string;
|
|
371
|
+
errorUnauthorized: string;
|
|
372
|
+
errorPlan: string;
|
|
373
|
+
errorNotFound: string;
|
|
374
|
+
errorUnavailable: string;
|
|
375
|
+
errorGeneric: string;
|
|
376
|
+
};
|
|
377
|
+
declare const CHAT_TEXT_TABLES: LocaleTables<keyof ChatTexts>;
|
|
378
|
+
/** Chat strings for a locale (default: the library locale), with overrides. */
|
|
379
|
+
declare function getChatTexts(overrides?: Partial<ChatTexts>, locale?: string): ChatTexts;
|
|
380
|
+
|
|
381
|
+
/** What to open: a pack thread (by product or id) or a channel. */
|
|
382
|
+
type ConversationTarget = {
|
|
383
|
+
kind: "thread";
|
|
384
|
+
threadId?: string;
|
|
385
|
+
productId?: string;
|
|
386
|
+
} | {
|
|
387
|
+
kind: "channel";
|
|
388
|
+
channelId: string;
|
|
389
|
+
productId?: string;
|
|
390
|
+
};
|
|
391
|
+
/** The client-side state of a message the service has not stored. */
|
|
392
|
+
type LocalMessageState = {
|
|
393
|
+
state: "pending" | "unconfirmed" | "rejected" | "failed";
|
|
394
|
+
/** Error code or live reject reason. */
|
|
395
|
+
reason?: string;
|
|
396
|
+
retryAfter?: number;
|
|
397
|
+
/** An earlier send of this message may have been queued: retries keep its id. */
|
|
398
|
+
keepId?: boolean;
|
|
399
|
+
};
|
|
400
|
+
type ConversationMessage = ChatMessage & {
|
|
401
|
+
local?: LocalMessageState;
|
|
402
|
+
};
|
|
403
|
+
/**
|
|
404
|
+
* Why the buyer sees the lock: `replies` (no creator replies left, writing
|
|
405
|
+
* still works), `expired` (every pack expired), `no-pack` (no thread and no
|
|
406
|
+
* pack for the product), `no-access` (a paid channel without a grant).
|
|
407
|
+
*/
|
|
408
|
+
type ConversationLock = {
|
|
409
|
+
reason: "replies" | "expired" | "no-pack" | "no-access";
|
|
410
|
+
productId?: string;
|
|
411
|
+
priceCents?: number;
|
|
412
|
+
welcome?: string;
|
|
413
|
+
};
|
|
414
|
+
type ConversationState = {
|
|
415
|
+
status: "loading" | "ready" | "locked" | "error";
|
|
416
|
+
error?: ChatError;
|
|
417
|
+
threadId?: string;
|
|
418
|
+
/** The caller's e-mail, lowercased. */
|
|
419
|
+
me?: string;
|
|
420
|
+
thread?: ChatThreadSummary;
|
|
421
|
+
channel?: ChatChannelSummary;
|
|
422
|
+
lock?: ConversationLock;
|
|
423
|
+
/** Oldest first. */
|
|
424
|
+
messages: ConversationMessage[];
|
|
425
|
+
hasMore: boolean;
|
|
426
|
+
loadingOlder: boolean;
|
|
427
|
+
live: ChatLiveMode;
|
|
428
|
+
};
|
|
429
|
+
type ConversationActions = {
|
|
430
|
+
send(body: string): Promise<void>;
|
|
431
|
+
/** Sends a failed or refused message again. */
|
|
432
|
+
retry(id: string): Promise<void>;
|
|
433
|
+
/** Removes a message that was not stored. */
|
|
434
|
+
discard(id: string): void;
|
|
435
|
+
deleteMessage(id: string): Promise<void>;
|
|
436
|
+
report(input: {
|
|
437
|
+
messageId?: string;
|
|
438
|
+
reason: ChatReportReason;
|
|
439
|
+
note?: string;
|
|
440
|
+
}): Promise<void>;
|
|
441
|
+
setMuted(muted: boolean): Promise<void>;
|
|
442
|
+
loadOlder(): Promise<void>;
|
|
443
|
+
reload(): void;
|
|
444
|
+
};
|
|
445
|
+
type UseConversationOptions = {
|
|
446
|
+
/**
|
|
447
|
+
* `undefined` when there is no credential (the state is an error), `null`
|
|
448
|
+
* while the credential is still being looked up (the state stays loading).
|
|
449
|
+
*/
|
|
450
|
+
client: ChatClient | null | undefined;
|
|
451
|
+
target: ConversationTarget;
|
|
452
|
+
pollIntervalMs?: number;
|
|
453
|
+
realtimeUrl?: string;
|
|
454
|
+
loadNats?: () => Promise<NatsModule>;
|
|
455
|
+
/** A pending send counts as unconfirmed after this long. Default 45 s. */
|
|
456
|
+
confirmTimeoutMs?: number;
|
|
457
|
+
};
|
|
458
|
+
/**
|
|
459
|
+
* State and actions of one conversation: resolves the thread (opening a pack
|
|
460
|
+
* thread when the buyer holds a pack and has none yet), loads the newest
|
|
461
|
+
* page, listens live (or polls) and sends optimistically.
|
|
462
|
+
*/
|
|
463
|
+
declare function useConversation(options: UseConversationOptions): ConversationState & ConversationActions;
|
|
464
|
+
|
|
465
|
+
/** What the lock's buy action gets. */
|
|
466
|
+
type ChatBuyRequest = {
|
|
467
|
+
/** The product (or variant) to sell: `buyProductId`, else the locked product. */
|
|
468
|
+
productId: string;
|
|
469
|
+
/** `replies`, `expired`, `no-pack` or `no-access`. */
|
|
470
|
+
reason: ConversationLock["reason"];
|
|
471
|
+
/** Known for a locked channel (from the chat service). */
|
|
472
|
+
priceCents?: number;
|
|
473
|
+
};
|
|
474
|
+
/** Props shared by `ChatThread` and `Channel`. */
|
|
475
|
+
type ChatWidgetBaseProps = {
|
|
476
|
+
/**
|
|
477
|
+
* Public Bitsnap project id of the shop. The cart uses it, the panel
|
|
478
|
+
* session is looked up with it, and it is the `X-Bitsnap-Project` of the
|
|
479
|
+
* chat service unless `chatProjectID` is given.
|
|
480
|
+
*/
|
|
481
|
+
projectID: string;
|
|
482
|
+
/** Project id for the chat service, when it differs from `projectID`. */
|
|
483
|
+
chatProjectID?: string;
|
|
484
|
+
/**
|
|
485
|
+
* Bearer for the chat service: a `bcht_` buyer token from your server
|
|
486
|
+
* (`POST /api/v1/chat/buyer-token`). Defaults to the customer panel session
|
|
487
|
+
* of this browser (after `PanelLogin`).
|
|
488
|
+
*/
|
|
489
|
+
token?: string;
|
|
490
|
+
/** Chat service base URL. Defaults to `https://chat.bitsnap.pl`. */
|
|
491
|
+
apiUrl?: string;
|
|
492
|
+
/** NATS WebSocket URL overriding the one of the realtime token. */
|
|
493
|
+
realtimeUrl?: string;
|
|
494
|
+
/** Bitsnap host of the panel session (`setHost`), when not the default. */
|
|
495
|
+
host?: string;
|
|
496
|
+
/** Polling interval in ms while the live connection is down. Default 8000. */
|
|
497
|
+
pollIntervalMs?: number;
|
|
498
|
+
/** Language of the default texts; defaults to the library locale. */
|
|
499
|
+
locale?: string;
|
|
500
|
+
/** Text overrides, whatever the locale. */
|
|
501
|
+
texts?: Partial<ChatTexts>;
|
|
502
|
+
/** Heading of the conversation. */
|
|
503
|
+
title?: string;
|
|
504
|
+
/** Shows a back button in the header. */
|
|
505
|
+
onBack?: () => void;
|
|
506
|
+
/**
|
|
507
|
+
* The lock's "Kup pakiet" / "Kup dostęp". Default: add the product to the
|
|
508
|
+
* page cart and open it (mount `BitsnapCheckout` on the page). Throw to
|
|
509
|
+
* show the error line.
|
|
510
|
+
*/
|
|
511
|
+
onBuy?: (request: ChatBuyRequest) => Promise<void> | void;
|
|
512
|
+
/** The product or variant the buy action sells (e.g. the pack variant). */
|
|
513
|
+
buyProductId?: string;
|
|
514
|
+
className?: string;
|
|
515
|
+
/** A ready client (tests, custom transport). Replaces token and URLs. */
|
|
516
|
+
client?: ChatClient;
|
|
517
|
+
/** @internal Replaces the NATS loader (tests). */
|
|
518
|
+
loadNats?: () => Promise<NatsModule>;
|
|
519
|
+
};
|
|
520
|
+
type ChatThreadProps = ChatWidgetBaseProps & {
|
|
521
|
+
/** The service product of the pack: opens its thread, creating it if needed. */
|
|
522
|
+
productId?: string;
|
|
523
|
+
/** An existing thread. Give this or `productId`. */
|
|
524
|
+
threadId?: string;
|
|
525
|
+
};
|
|
526
|
+
type ChannelProps = ChatWidgetBaseProps & {
|
|
527
|
+
/** The channel (its id is also the id of its conversation). */
|
|
528
|
+
channelId: string;
|
|
529
|
+
/** The community product sold by the lock; defaults to the channel's own. */
|
|
530
|
+
productId?: string;
|
|
531
|
+
};
|
|
532
|
+
/**
|
|
533
|
+
* A buyer's pack thread for one service product: history, live updates,
|
|
534
|
+
* sending with pending and refused states, report and mute, and the lock
|
|
535
|
+
* with "Kup pakiet" when the replies are used up or the pack expired.
|
|
536
|
+
* Load `bitsnap-react/dist/index.css` once.
|
|
537
|
+
*/
|
|
538
|
+
declare function ChatThread(props: ChatThreadProps): react_jsx_runtime.JSX.Element;
|
|
539
|
+
/**
|
|
540
|
+
* A community channel: messages, live updates, posting when the channel
|
|
541
|
+
* allows it (with the channel's moderation refusals shown on the message),
|
|
542
|
+
* report, and the lock with "Kup dostęp" for a buyer without a grant.
|
|
543
|
+
* Load `bitsnap-react/dist/index.css` once.
|
|
544
|
+
*/
|
|
545
|
+
declare function Channel(props: ChannelProps): react_jsx_runtime.JSX.Element;
|
|
546
|
+
|
|
547
|
+
export { type ChatPackEntitlement as A, type ChatRealtimeEvent as B, type ChatTexts as C, DEFAULT_CHAT_API_URL as D, type ChatRealtimeToken as E, type ChatReportReason as F, type ChatSendResult as G, type ChatThreadState as H, type ChatThreadSummary as I, type LiveOptions as L, type UseConversationOptions as U, Channel as a, ChatThread as b, type ChannelProps as c, type ChatBuyRequest as d, type ChatThreadProps as e, type ChatWidgetBaseProps as f, ChatError as g, createChatClient as h, type ChatClient as i, type ChatClientOptions as j, type ConversationLock as k, type ConversationMessage as l, type ConversationTarget as m, CHAT_TEXT_TABLES as n, getChatTexts as o, parseRealtimeEvent as p, DEFAULT_CHAT_REALTIME_URL as q, type ChatChannelEntitlement as r, startLive as s, type ChatChannelSummary as t, useConversation as u, type ChatLiveMode as v, type ChatMe as w, type ChatMessage as x, type ChatMessagePage as y, type ChatPack as z };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bitsnap-react",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.19.0",
|
|
4
4
|
"description": "This is Bitsnap React library for easy integration with any website which is using React framework",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -14,9 +14,10 @@
|
|
|
14
14
|
"clean": "rimraf ./dist",
|
|
15
15
|
"dev": "node scripts/write-version.mjs && tsup --watch",
|
|
16
16
|
"dev:publish": "pnpm dev --env.publish",
|
|
17
|
-
"test": "tsup src/components/checkout/appearance.test.ts src/components/checkout/texts.test.ts src/components/checkout/buy-error.test.ts src/components/checkout/cart-buy-error.test.tsx src/lib/appearance-core.test.ts src/lib/texts.test.ts src/components/returns/appearance.test.ts src/components/returns/texts.test.ts src/components/returns/errors.test.ts src/components/returns/money.test.ts src/components/returns/session-storage.test.ts src/components/returns/state-machine.test.ts src/components/returns/selection.test.ts src/components/returns/legacy.test.ts src/panel/returns-appearance.test.ts src/components/products/appearance.test.ts src/components/products/texts.test.ts src/components/products/format.test.ts src/components/products/fetch.test.ts src/components/products/useProducts.test.ts src/components/products/cart-target.test.ts src/components/checkout/cart-items.test.ts src/components/checkout/pending-order.test.ts src/components/checkout/quantity.test.ts src/components/checkout/cart-a11y.test.tsx src/components/checkout/payment-method.test.ts src/components/checkout/cart-payment-method.test.tsx src/course/logic.test.ts src/course/accent.test.ts src/course/texts.test.ts src/course/datasource.test.ts src/course/sanitize.test.ts src/course/VideoPlayer.test.tsx src/course/PanelCourse.test.tsx src/consent/core/cookie.test.ts src/consent/core/texts.test.ts src/consent/core/activate.test.ts src/consent/core/gcm.test.ts src/consent/core/contrast.test.ts src/consent/core/controller.test.ts src/consent/embed.test.ts src/consent/react.test.tsx src/consent/react-shown.test.tsx src/analytics/core.test.ts src/analytics/embed.test.ts src/analytics/instrument.test.tsx src/analytics/page-views.test.tsx src/analytics/visitor.test.ts src/components/checkout/visitor-header.test.ts src/components/products/impressions.test.ts src/components/products/ProductList.analytics.test.tsx src/components/checkout/cart-analytics.test.tsx src/components/checkout/apple-pay-analytics.test.tsx src/components/notifications/notifications-analytics.test.tsx src/components/returns/returns-analytics.test.tsx src/panel/panel-analytics.test.tsx src/course/course-analytics.test.tsx src/viewer3d/viewer3d.test.ts src/viewer3d/Model3DViewer.test.tsx src/panel/panel-products.test.tsx src/ui/email-code-login/email-code-login.test.tsx src/ui/email-code-login/login-brand-logo.test.tsx src/panel/panel-login.test.tsx src/components/returns/returns-login.test.tsx src/components/notifications/notifications-login.test.tsx src/panel/audio-player/audio-player.test.tsx --format esm --out-dir .test-dist --no-config --external jsdom --silent && node --test --test-force-exit \".test-dist/**/*.test.mjs\"",
|
|
17
|
+
"test": "tsup src/components/checkout/appearance.test.ts src/components/checkout/texts.test.ts src/components/checkout/buy-error.test.ts src/components/checkout/cart-buy-error.test.tsx src/lib/appearance-core.test.ts src/lib/texts.test.ts src/components/returns/appearance.test.ts src/components/returns/texts.test.ts src/components/returns/errors.test.ts src/components/returns/money.test.ts src/components/returns/session-storage.test.ts src/components/returns/state-machine.test.ts src/components/returns/selection.test.ts src/components/returns/legacy.test.ts src/panel/returns-appearance.test.ts src/components/products/appearance.test.ts src/components/products/texts.test.ts src/components/products/format.test.ts src/components/products/fetch.test.ts src/components/products/useProducts.test.ts src/components/products/cart-target.test.ts src/components/checkout/cart-items.test.ts src/components/checkout/pending-order.test.ts src/components/checkout/quantity.test.ts src/components/checkout/cart-a11y.test.tsx src/components/checkout/payment-method.test.ts src/components/checkout/cart-payment-method.test.tsx src/course/logic.test.ts src/course/accent.test.ts src/course/texts.test.ts src/course/datasource.test.ts src/course/sanitize.test.ts src/course/VideoPlayer.test.tsx src/course/PanelCourse.test.tsx src/consent/core/cookie.test.ts src/consent/core/texts.test.ts src/consent/core/activate.test.ts src/consent/core/gcm.test.ts src/consent/core/contrast.test.ts src/consent/core/controller.test.ts src/consent/embed.test.ts src/consent/react.test.tsx src/consent/react-shown.test.tsx src/analytics/core.test.ts src/analytics/embed.test.ts src/analytics/instrument.test.tsx src/analytics/page-views.test.tsx src/analytics/visitor.test.ts src/components/checkout/visitor-header.test.ts src/components/products/impressions.test.ts src/components/products/ProductList.analytics.test.tsx src/components/checkout/cart-analytics.test.tsx src/components/checkout/apple-pay-analytics.test.tsx src/components/notifications/notifications-analytics.test.tsx src/components/returns/returns-analytics.test.tsx src/panel/panel-analytics.test.tsx src/course/course-analytics.test.tsx src/viewer3d/viewer3d.test.ts src/viewer3d/Model3DViewer.test.tsx src/panel/panel-products.test.tsx src/ui/email-code-login/email-code-login.test.tsx src/ui/email-code-login/login-brand-logo.test.tsx src/panel/panel-login.test.tsx src/components/returns/returns-login.test.tsx src/components/notifications/notifications-login.test.tsx src/panel/audio-player/audio-player.test.tsx src/express/client.test.ts src/express/cart-record.test.ts src/express/cart-session.test.ts src/express/revolut.test.ts src/express/return-url.test.ts src/express/loaders.test.ts src/components/express/express-ssr.test.tsx src/components/express/InPostPayButton.test.tsx src/components/express/RevolutPayButton.test.tsx src/chat/client.test.ts src/chat/realtime.test.ts src/chat/widgets.test.tsx src/chat/panel-messages.test.tsx --format esm --out-dir .test-dist --no-config --external jsdom --silent && node --test --test-force-exit \".test-dist/**/*.test.mjs\"",
|
|
18
18
|
"test:types": "tsc -p test/consumer/tsconfig.json",
|
|
19
|
-
"test:package": "node test/consumer/verify-package.mjs"
|
|
19
|
+
"test:package": "node test/consumer/verify-package.mjs",
|
|
20
|
+
"test:express-ssr": "pnpm build && node --test test/express.ssr.test.cjs"
|
|
20
21
|
},
|
|
21
22
|
"repository": {
|
|
22
23
|
"type": "git",
|
|
@@ -64,6 +65,7 @@
|
|
|
64
65
|
"@formkit/auto-animate": "^0.8.2",
|
|
65
66
|
"@google-pay/button-react": "^3.2.1",
|
|
66
67
|
"@inpost-pay/widget": "^2.2.0",
|
|
68
|
+
"@nats-io/nats-core": "3.4.0",
|
|
67
69
|
"@radix-ui/react-dialog": "^1.1.15",
|
|
68
70
|
"@radix-ui/react-label": "^2.1.8",
|
|
69
71
|
"@radix-ui/react-popover": "^1.1.15",
|
|
@@ -196,6 +198,16 @@
|
|
|
196
198
|
"default": "./dist/course.js"
|
|
197
199
|
}
|
|
198
200
|
},
|
|
201
|
+
"./chat": {
|
|
202
|
+
"import": {
|
|
203
|
+
"types": "./dist/chat.d.mts",
|
|
204
|
+
"default": "./dist/chat.mjs"
|
|
205
|
+
},
|
|
206
|
+
"require": {
|
|
207
|
+
"types": "./dist/chat.d.ts",
|
|
208
|
+
"default": "./dist/chat.js"
|
|
209
|
+
}
|
|
210
|
+
},
|
|
199
211
|
"./consent": {
|
|
200
212
|
"import": {
|
|
201
213
|
"types": "./dist/consent.d.mts",
|
|
@@ -244,6 +256,9 @@
|
|
|
244
256
|
"course": [
|
|
245
257
|
"./dist/course.d.ts"
|
|
246
258
|
],
|
|
259
|
+
"chat": [
|
|
260
|
+
"./dist/chat.d.ts"
|
|
261
|
+
],
|
|
247
262
|
"consent": [
|
|
248
263
|
"./dist/consent.d.ts"
|
|
249
264
|
],
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports, "__esModule", {value: true});var _chunkV5ECGBFWjs = require('./chunk-V5ECGBFW.js');require('./chunk-ZATPBYOA.js');require('./chunk-KOYBZORL.js');require('./chunk-VNV5BD4X.js');require('./chunk-G4V2KWTV.js');require('./chunk-4HGZZJEL.js');require('./chunk-DP2NOHCI.js');var _chunk7RXW6XFYjs = require('./chunk-7RXW6XFY.js');require('./chunk-W3RGQYPD.js');require('./chunk-JSDGZ4NY.js');exports.MARKETING_AGREEMENT_ID = _chunkV5ECGBFWjs.H; exports.bitsnapProjectID = _chunkV5ECGBFWjs.I; exports.default = _chunkV5ECGBFWjs.P; exports.getCartLines = _chunkV5ECGBFWjs.M; exports.getCheckoutMethods = _chunkV5ECGBFWjs.Q; exports.getCheckoutSelection = _chunkV5ECGBFWjs.L; exports.getLocale = _chunk7RXW6XFYjs.f; exports.getProjectID = _chunkV5ECGBFWjs.K; exports.reconcileOrderOfLastPayment = _chunkV5ECGBFWjs.N; exports.setLocale = _chunk7RXW6XFYjs.e; exports.setProjectID = _chunkV5ECGBFWjs.J; exports.useCartProvider = _chunkV5ECGBFWjs.O;
|
|
2
|
-
//# sourceMappingURL=CartProvider-OEI526IN.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["/home/emems/web/bitsnap/bitsnap/bitsnap-react/dist/CartProvider-OEI526IN.js"],"names":[],"mappings":"AAAA,+HAAsG,+BAA4B,+BAA4B,+BAA4B,+BAA4B,+BAA4B,+BAA4B,sDAA+C,+BAA4B,+BAA4B,siBAAmQ","file":"/home/emems/web/bitsnap/bitsnap/bitsnap-react/dist/CartProvider-OEI526IN.js"}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{H as c,I as d,J as e,K as f,L as g,M as h,N as i,O as j,P as k,Q as l}from"./chunk-WJO5GSY3.mjs";import"./chunk-4OVOKGGS.mjs";import"./chunk-KOVKUJAW.mjs";import"./chunk-5X7TP3TQ.mjs";import"./chunk-CUPG4B5W.mjs";import"./chunk-EVIDNS22.mjs";import"./chunk-5R6AGO3Z.mjs";import"./chunk-GEBRXFT3.mjs";import"./chunk-CF45RDMD.mjs";import{e as a,f as b}from"./chunk-VNYHJT6V.mjs";import"./chunk-MDCP5JNP.mjs";import"./chunk-U6FLIRIV.mjs";export{c as MARKETING_AGREEMENT_ID,d as bitsnapProjectID,k as default,h as getCartLines,l as getCheckoutMethods,g as getCheckoutSelection,b as getLocale,f as getProjectID,i as reconcileOrderOfLastPayment,a as setLocale,e as setProjectID,j as useCartProvider};
|
|
2
|
-
//# sourceMappingURL=CartProvider-RYAA3JDA.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["/home/emems/web/bitsnap/bitsnap/bitsnap-react/dist/PanelModelFiles-7HPXWONN.js","../src/panel/components/PanelModelFiles.tsx"],"names":["COPY","formatSize","bytes","en","value","mb","fmt"],"mappings":"AAAA,uuBAA8C,sDAAwC,+BAA4B,8CCArF,yDACA,8BACkB,+CAsG3C,IAhEEA,CAAAA,CAA+B,CACnC,EAAA,CAAI,CACF,KAAA,CAAO,UAAA,CACP,QAAA,CAAU,mDAAA,CACV,QAAA,CAAU,SAAA,CACV,SAAA,CAAW,yBAAA,CACX,OAAA,CAAS,UAAA,CACT,SAAA,CAAW,SAAA,CACX,WAAA,CAAa,gBAAA,CACb,OAAA,CAAS,uCAAA,CACT,OAAA,CAAS,sBAAA,CACT,OAAA,CAAS,kCAAA,CACT,OAAA,CAAS,CACN,CAAA,CAAoC,gDAAA,CACpC,CAAA,CAAiC,uCAAA,CACjC,CAAA,CAAgC,uDAAA,CAChC,CAAA,CAA+B,mCAAA,CAC/B,CAAA,CAA+B,uCAAA,CAC/B,CAAA,CAA8B,uCACjC,CAAA,CACA,KAAA,CAAO,iEACT,CAAA,CACA,EAAA,CAAI,CACF,KAAA,CAAO,UAAA,CACP,QAAA,CAAU,sDAAA,CACV,QAAA,CAAU,UAAA,CACV,SAAA,CAAW,iBAAA,CACX,OAAA,CAAS,SAAA,CACT,SAAA,CAAW,WAAA,CACX,WAAA,CAAa,cAAA,CACb,OAAA,CAAS,+BAAA,CACT,OAAA,CAAS,oBAAA,CACT,OAAA,CAAS,8BAAA,CACT,OAAA,CAAS,CACN,CAAA,CAAoC,0CAAA,CACpC,CAAA,CAAiC,8BAAA,CACjC,CAAA,CAAgC,qCAAA,CAChC,CAAA,CAA+B,+BAAA,CAC/B,CAAA,CAA+B,+BAAA,CAC/B,CAAA,CAA8B,wBACjC,CAAA,CACA,KAAA,CAAO,8CACT,CACF,CAAA,CAEA,SAASC,CAAAA,CAAWC,CAAAA,CAAeC,CAAAA,CAAqB,CACtD,IAAMC,CAAAA,CAAQ,MAAA,CAAOF,CAAK,CAAA,CAC1B,EAAA,CAAI,CAAC,MAAA,CAAO,QAAA,CAASE,CAAK,CAAA,EAAKA,CAAAA,EAAS,CAAA,CAAG,MAAO,EAAA,CAClD,IAAMC,CAAAA,CAAKD,CAAAA,CAAAA,CAAS,IAAA,CAAO,IAAA,CAAA,CACrBE,CAAAA,CAAM,IAAI,IAAA,CAAK,YAAA,CAAaH,CAAAA,CAAK,OAAA,CAAU,OAAA,CAAS,CACxD,qBAAA,CAAuB,CACzB,CAAC,CAAA,CACD,OAAOE,CAAAA,EAAM,CAAA,CAAI,CAAA,EAAA","file":"/home/emems/web/bitsnap/bitsnap/bitsnap-react/dist/PanelModelFiles-7HPXWONN.js","sourcesContent":[null,"import { createClient } from \"@connectrpc/connect\";\nimport { useTransport } from \"@connectrpc/connect-query\";\nimport { useCallback, useMemo, useState } from \"react\";\n\nimport { getLocale } from \"../../components/checkout/locale\";\nimport {\n ModelDeliveryFailure,\n ModelDeliveryService,\n ModelFileState,\n type PurchasedModel,\n} from \"../../gen/proto/public/v1/model_delivery_pb\";\n\n/**\n * \"3D files\" of the customer panel: the 3D files of the buyer's paid orders in\n * this shop (`public.v1.ModelDeliveryService`), with a download button, the\n * licence and the \"seller removed the file\" state. The download URL is signed\n * on click and expires quickly, so it is never rendered into the page.\n *\n * Older Bitsnap servers have no such service: any transport error (404,\n * unimplemented, network) hides the section, so the panel looks as before.\n *\n * Loaded on demand (with `model-files-client.ts`) only when the buyer has 3D\n * files, so the main bundle carries just `model-files-load.ts`.\n */\n\ntype Copy = {\n title: string;\n subtitle: string;\n download: string;\n preparing: string;\n licence: string;\n purchased: string;\n accessUntil: string;\n removed: string;\n contact: string;\n expired: string;\n failure: Partial<Record<ModelDeliveryFailure, string>>;\n error: string;\n};\n\nconst COPY: { pl: Copy; en: Copy } = {\n pl: {\n title: \"Pliki 3D\",\n subtitle: \"Pobierasz zawsze aktualną wersję pliku.\",\n download: \"Pobierz\",\n preparing: \"Przygotowuję…\",\n licence: \"Licencja\",\n purchased: \"Kupiono\",\n accessUntil: \"Dostęp do\",\n removed: \"Sprzedawca usunął ten plik.\",\n contact: \"Napisz do sprzedawcy\",\n expired: \"Dostęp do pliku wygasł\",\n failure: {\n [ModelDeliveryFailure.UNAUTHORIZED]: \"Sesja wygasła. Zaloguj się ponownie.\",\n [ModelDeliveryFailure.NOT_FOUND]: \"Nie znaleźliśmy tego pliku.\",\n [ModelDeliveryFailure.REFUNDED]: \"Zamówienie zostało zwrócone lub anulowane.\",\n [ModelDeliveryFailure.EXPIRED]: \"Dostęp do pliku wygasł.\",\n [ModelDeliveryFailure.REMOVED]: \"Sprzedawca usunął ten plik.\",\n [ModelDeliveryFailure.UNPAID]: \"Zamówienie nie jest opłacone.\",\n },\n error: \"Nie udało się pobrać pliku. Spróbuj ponownie.\",\n },\n en: {\n title: \"3D files\",\n subtitle: \"You always download the current version of the file.\",\n download: \"Download\",\n preparing: \"Preparing…\",\n licence: \"Licence\",\n purchased: \"Purchased\",\n accessUntil: \"Access until\",\n removed: \"The seller removed this file.\",\n contact: \"Contact the seller\",\n expired: \"Access to the file has ended\",\n failure: {\n [ModelDeliveryFailure.UNAUTHORIZED]: \"Your session has expired. Sign in again.\",\n [ModelDeliveryFailure.NOT_FOUND]: \"We could not find this file.\",\n [ModelDeliveryFailure.REFUNDED]: \"The order was refunded or canceled.\",\n [ModelDeliveryFailure.EXPIRED]: \"Access to the file has ended.\",\n [ModelDeliveryFailure.REMOVED]: \"The seller removed this file.\",\n [ModelDeliveryFailure.UNPAID]: \"The order is not paid.\",\n },\n error: \"The file could not be downloaded. Try again.\",\n },\n};\n\nfunction formatSize(bytes: bigint, en: boolean): string {\n const value = Number(bytes);\n if (!Number.isFinite(value) || value <= 0) return \"\";\n const mb = value / (1024 * 1024);\n const fmt = new Intl.NumberFormat(en ? \"en-GB\" : \"pl-PL\", {\n maximumFractionDigits: 1,\n });\n return mb >= 1 ? `${fmt.format(mb)} MB` : `${fmt.format(value / 1024)} KB`;\n}\n\nfunction formatDate(seconds: bigint | undefined, en: boolean): string {\n if (seconds == null || seconds <= 0n) return \"\";\n return new Intl.DateTimeFormat(en ? \"en-GB\" : \"pl-PL\", {\n dateStyle: \"medium\",\n }).format(new Date(Number(seconds) * 1000));\n}\n\nfunction CubeIcon({ className }: { className?: string }) {\n return (\n <svg\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={1.5}\n className={className}\n aria-hidden\n >\n <path d=\"M12 2.5 3.5 7v10L12 21.5 20.5 17V7L12 2.5Z\" strokeLinejoin=\"round\" />\n <path d=\"M3.5 7 12 11.5 20.5 7M12 11.5v10\" strokeLinejoin=\"round\" />\n </svg>\n );\n}\n\nexport default function PanelModelFiles({\n accessToken,\n models,\n buttonStyle,\n}: {\n accessToken: string;\n models: PurchasedModel[];\n buttonStyle?: React.CSSProperties;\n}) {\n const en = getLocale().toLowerCase().startsWith(\"en\");\n const t = en ? COPY.en : COPY.pl;\n const transport = useTransport();\n const client = useMemo(\n () => createClient(ModelDeliveryService, transport),\n [transport],\n );\n const [pending, setPending] = useState<string | null>(null);\n const [errors, setErrors] = useState<Record<string, string>>({});\n\n const download = useCallback(\n async (model: PurchasedModel, index: number) => {\n const key = `${model.orderId}:${model.lineId}:${index}`;\n setPending(key);\n setErrors((current) => ({ ...current, [key]: \"\" }));\n try {\n const response = await client.getModelFileDownloadUrl({\n accessToken,\n orderId: model.orderId,\n lineId: model.lineId,\n fileIndex: index,\n });\n if (response.result.case === \"success\") {\n // An attachment: the browser downloads it and stays on the panel.\n window.location.assign(response.result.value.url);\n } else {\n const failure =\n response.result.case === \"failure\" ? response.result.value : undefined;\n setErrors((current) => ({\n ...current,\n [key]: (failure != null ? t.failure[failure] : undefined) ?? t.error,\n }));\n }\n } catch {\n setErrors((current) => ({ ...current, [key]: t.error }));\n } finally {\n setPending(null);\n }\n },\n [client, accessToken, t],\n );\n\n if (models.length === 0) return null;\n\n return (\n <section\n aria-labelledby=\"bitsnap-panel-model-files\"\n className=\"mt-10 w-full max-w-5xl\"\n data-testid=\"model-files\"\n >\n <div className=\"rounded-2xl border border-neutral-200 bg-white dark:border-neutral-800 dark:bg-neutral-900\">\n <header className=\"border-b border-neutral-200 px-5 py-4 dark:border-neutral-800\">\n <h2\n id=\"bitsnap-panel-model-files\"\n className=\"text-lg font-semibold text-neutral-900 dark:text-neutral-50\"\n >\n {t.title}\n </h2>\n <p className=\"mt-0.5 text-sm text-neutral-500 dark:text-neutral-400\">\n {t.subtitle}\n </p>\n </header>\n <ul className=\"grid grid-cols-1 gap-4 p-4 sm:grid-cols-2 xl:grid-cols-3\">\n {models.map((model) => {\n const title = model.variantName\n ? `${model.productName} – ${model.variantName}`\n : model.productName;\n return (\n <li\n key={`${model.orderId}:${model.lineId}`}\n className=\"flex min-w-0 flex-col gap-4 rounded-xl border border-neutral-200 p-4 dark:border-neutral-700\"\n data-state={ModelFileState[model.state]}\n >\n <div className=\"flex min-w-0 flex-1 items-center gap-4\">\n <div className=\"flex size-14 shrink-0 items-center justify-center overflow-hidden rounded-xl bg-neutral-100 text-neutral-400 dark:bg-neutral-800\">\n {model.thumbnailUrl ? (\n <img\n src={model.thumbnailUrl}\n alt={title}\n className=\"size-full object-contain\"\n loading=\"lazy\"\n />\n ) : (\n <CubeIcon className=\"size-7\" />\n )}\n </div>\n <div className=\"min-w-0\">\n <p className=\"break-words font-medium text-neutral-900 dark:text-neutral-50\">\n {title}\n </p>\n <p className=\"mt-0.5 text-sm text-neutral-500 dark:text-neutral-400\">\n {[\n model.files[0]\n ? `${model.files[0].format.toUpperCase()} · ${formatSize(model.files[0].fileSize, en)}`\n : \"\",\n `${t.purchased} ${formatDate(model.purchasedAt, en)}`,\n model.accessExpiresAt != null &&\n model.state === ModelFileState.AVAILABLE\n ? `${t.accessUntil} ${formatDate(model.accessExpiresAt, en)}`\n : \"\",\n ]\n .filter(Boolean)\n .join(\" · \")}\n </p>\n {model.licence && (\n <p className=\"mt-0.5 text-sm text-neutral-600 dark:text-neutral-300\">\n {t.licence}:{\" \"}\n {model.licence.url ? (\n <a\n href={model.licence.url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"underline underline-offset-2 hover:text-neutral-900 dark:hover:text-neutral-50\"\n >\n {model.licence.name}\n </a>\n ) : (\n model.licence.name\n )}\n </p>\n )}\n {model.state === ModelFileState.REMOVED && (\n <p\n className=\"mt-1 text-sm text-neutral-700 dark:text-neutral-200\"\n data-model-removed=\"\"\n >\n {t.removed}\n {model.seller?.email && (\n <>\n {\" \"}\n {t.contact}\n {model.seller.name ? ` (${model.seller.name})` : \"\"}:{\" \"}\n <a\n className=\"font-medium underline underline-offset-2\"\n href={`mailto:${model.seller.email}`}\n >\n {model.seller.email}\n </a>\n </>\n )}\n </p>\n )}\n {model.state === ModelFileState.EXPIRED && (\n <p className=\"mt-1 text-sm text-neutral-700 dark:text-neutral-200\">\n {t.expired}\n {model.accessExpiresAt != null\n ? ` ${formatDate(model.accessExpiresAt, en)}`\n : \"\"}\n .\n </p>\n )}\n </div>\n </div>\n {model.state === ModelFileState.AVAILABLE &&\n model.files.map((file) => {\n const key = `${model.orderId}:${model.lineId}:${file.index}`;\n const busy = pending === key;\n return (\n <div\n key={key}\n className=\"flex flex-col items-start gap-1 sm:items-end\"\n >\n <button\n type=\"button\"\n onClick={() => void download(model, file.index)}\n disabled={pending != null}\n aria-busy={busy || undefined}\n aria-label={`${t.download}: ${file.fileName}`}\n data-model-download=\"\"\n style={buttonStyle}\n className=\"min-h-11 inline-flex h-10 items-center justify-center rounded-lg bg-neutral-900 px-4 text-sm font-medium text-white transition-opacity hover:opacity-90 disabled:opacity-60 dark:bg-neutral-50 dark:text-neutral-900\"\n >\n {busy ? t.preparing : t.download}\n </button>\n {errors[key] && (\n <p\n className=\"text-sm text-red-700 dark:text-red-400\"\n role=\"alert\"\n >\n {errors[key]}\n </p>\n )}\n </div>\n );\n })}\n </li>\n );\n })}\n </ul>\n </div>\n </section>\n );\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["/home/emems/web/bitsnap/bitsnap/bitsnap-react/dist/chunk-4HGZZJEL.js","../src/lib/client-header.ts"],"names":["CLIENT_HEADER_NAME","CLIENT_HEADER_VALUE","SDK_VERSION"],"mappings":"AAAA,+HAAuC,ICG1BA,CAAAA,CAAqB,kBAAA,CACrBC,CAAAA,CAAsB,CAAA,cAAA,EAAiBC,kBAAW,CAAA,CAAA","file":"/home/emems/web/bitsnap/bitsnap/bitsnap-react/dist/chunk-4HGZZJEL.js","sourcesContent":[null,"import type { Interceptor } from \"@connectrpc/connect\";\nimport { SDK_VERSION } from \"../version\";\n\nexport const CLIENT_HEADER_NAME = \"X-Bitsnap-Client\";\nexport const CLIENT_HEADER_VALUE = `bitsnap-react@${SDK_VERSION}`;\n\nexport const CLIENT_QUERY_PARAM = \"bs_client\";\n\n/**\n * Spread into the `headers` of a fetch that already triggers a CORS preflight\n * (JSON POST, Connect RPC). Never use it on a simple cross-origin GET: the\n * custom header would force a preflight that older servers and merchant\n * proxies do not allow. Use `withClientParam` there.\n */\nexport const clientHeaders: Record<string, string> = {\n [CLIENT_HEADER_NAME]: CLIENT_HEADER_VALUE,\n};\n\n/** Connect interceptor adding the client header to every RPC. */\nexport const clientHeaderInterceptor: Interceptor = (next) => (req) => {\n req.header.set(CLIENT_HEADER_NAME, CLIENT_HEADER_VALUE);\n return next(req);\n};\n\n/** Adds `bs_client=<pkg>@<ver>` to a URL, for simple GETs that must stay preflight-free. */\nexport function withClientParam(url: string): string {\n const hash = url.indexOf(\"#\");\n const base = hash === -1 ? url : url.slice(0, hash);\n const fragment = hash === -1 ? \"\" : url.slice(hash);\n const separator = base.includes(\"?\") ? (/[?&]$/.test(base) ? \"\" : \"&\") : \"?\";\n return `${base}${separator}${CLIENT_QUERY_PARAM}=${encodeURIComponent(CLIENT_HEADER_VALUE)}${fragment}`;\n}\n"]}
|