@takeal/cusfront-sdk 0.1.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.
Files changed (74) hide show
  1. package/CHANGELOG.md +66 -0
  2. package/LICENSE +21 -0
  3. package/README.md +283 -0
  4. package/dist/customer-CoxPwe5o.d.cts +32 -0
  5. package/dist/customer-CoxPwe5o.d.ts +32 -0
  6. package/dist/http-BkZZZI8K.d.cts +72 -0
  7. package/dist/http-BkZZZI8K.d.ts +72 -0
  8. package/dist/index.cjs +486 -0
  9. package/dist/index.cjs.map +1 -0
  10. package/dist/index.d.cts +149 -0
  11. package/dist/index.d.ts +149 -0
  12. package/dist/index.js +478 -0
  13. package/dist/index.js.map +1 -0
  14. package/dist/react/index.cjs +82 -0
  15. package/dist/react/index.cjs.map +1 -0
  16. package/dist/react/index.d.cts +93 -0
  17. package/dist/react/index.d.ts +93 -0
  18. package/dist/react/index.js +75 -0
  19. package/dist/react/index.js.map +1 -0
  20. package/dist/resources/auth.cjs +88 -0
  21. package/dist/resources/auth.cjs.map +1 -0
  22. package/dist/resources/auth.d.cts +132 -0
  23. package/dist/resources/auth.d.ts +132 -0
  24. package/dist/resources/auth.js +86 -0
  25. package/dist/resources/auth.js.map +1 -0
  26. package/dist/resources/balance.cjs +21 -0
  27. package/dist/resources/balance.cjs.map +1 -0
  28. package/dist/resources/balance.d.cts +27 -0
  29. package/dist/resources/balance.d.ts +27 -0
  30. package/dist/resources/balance.js +19 -0
  31. package/dist/resources/balance.js.map +1 -0
  32. package/dist/resources/blog.cjs +39 -0
  33. package/dist/resources/blog.cjs.map +1 -0
  34. package/dist/resources/blog.d.cts +112 -0
  35. package/dist/resources/blog.d.ts +112 -0
  36. package/dist/resources/blog.js +37 -0
  37. package/dist/resources/blog.js.map +1 -0
  38. package/dist/resources/branding.cjs +16 -0
  39. package/dist/resources/branding.cjs.map +1 -0
  40. package/dist/resources/branding.d.cts +35 -0
  41. package/dist/resources/branding.d.ts +35 -0
  42. package/dist/resources/branding.js +14 -0
  43. package/dist/resources/branding.js.map +1 -0
  44. package/dist/resources/cards.cjs +91 -0
  45. package/dist/resources/cards.cjs.map +1 -0
  46. package/dist/resources/cards.d.cts +166 -0
  47. package/dist/resources/cards.d.ts +166 -0
  48. package/dist/resources/cards.js +89 -0
  49. package/dist/resources/cards.js.map +1 -0
  50. package/dist/resources/deposits.cjs +52 -0
  51. package/dist/resources/deposits.cjs.map +1 -0
  52. package/dist/resources/deposits.d.cts +168 -0
  53. package/dist/resources/deposits.d.ts +168 -0
  54. package/dist/resources/deposits.js +50 -0
  55. package/dist/resources/deposits.js.map +1 -0
  56. package/dist/resources/subscriptions.cjs +24 -0
  57. package/dist/resources/subscriptions.cjs.map +1 -0
  58. package/dist/resources/subscriptions.d.cts +36 -0
  59. package/dist/resources/subscriptions.d.ts +36 -0
  60. package/dist/resources/subscriptions.js +22 -0
  61. package/dist/resources/subscriptions.js.map +1 -0
  62. package/dist/telegram.cjs +557 -0
  63. package/dist/telegram.cjs.map +1 -0
  64. package/dist/telegram.d.cts +105 -0
  65. package/dist/telegram.d.ts +105 -0
  66. package/dist/telegram.js +550 -0
  67. package/dist/telegram.js.map +1 -0
  68. package/dist/webhooks.cjs +78 -0
  69. package/dist/webhooks.cjs.map +1 -0
  70. package/dist/webhooks.d.cts +70 -0
  71. package/dist/webhooks.d.ts +70 -0
  72. package/dist/webhooks.js +72 -0
  73. package/dist/webhooks.js.map +1 -0
  74. package/package.json +123 -0
@@ -0,0 +1,550 @@
1
+ // src/error.ts
2
+ var ApiError = class extends Error {
3
+ constructor(status, code, message, body) {
4
+ super(message);
5
+ this.status = status;
6
+ this.code = code;
7
+ this.body = body;
8
+ this.isApiError = true;
9
+ this.name = "ApiError";
10
+ }
11
+ };
12
+ var NetworkError = class extends Error {
13
+ constructor(message, cause) {
14
+ super(message);
15
+ this.cause = cause;
16
+ this.isNetworkError = true;
17
+ this.name = "NetworkError";
18
+ }
19
+ };
20
+
21
+ // src/http.ts
22
+ var HttpClient = class {
23
+ constructor(baseUrl, tokens, fetchImpl) {
24
+ this.baseUrl = baseUrl;
25
+ this.tokens = tokens;
26
+ this.fetchImpl = fetchImpl;
27
+ if (!baseUrl) throw new Error("HttpClient: baseUrl is required");
28
+ }
29
+ async get(path, opts = {}) {
30
+ return this.request("GET", path, opts);
31
+ }
32
+ async post(path, opts = {}) {
33
+ return this.request("POST", path, opts);
34
+ }
35
+ async put(path, opts = {}) {
36
+ return this.request("PUT", path, opts);
37
+ }
38
+ async patch(path, opts = {}) {
39
+ return this.request("PATCH", path, opts);
40
+ }
41
+ async delete(path, opts = {}) {
42
+ return this.request("DELETE", path, opts);
43
+ }
44
+ async request(method, path, opts) {
45
+ const url = this.absolute(path);
46
+ const headers = {
47
+ Accept: "application/json"
48
+ };
49
+ if (opts.body !== void 0) headers["Content-Type"] = "application/json";
50
+ if (opts.idempotencyKey) headers["Idempotency-Key"] = opts.idempotencyKey;
51
+ if (!opts.skipAuth) {
52
+ const token = await Promise.resolve(this.tokens.get());
53
+ if (token) headers["Authorization"] = `Bearer ${token}`;
54
+ }
55
+ Object.assign(headers, opts.headers ?? {});
56
+ const init = {
57
+ method,
58
+ headers,
59
+ ...opts.signal ? { signal: opts.signal } : {}
60
+ };
61
+ if (opts.body !== void 0) {
62
+ init.body = typeof opts.body === "string" ? opts.body : JSON.stringify(opts.body);
63
+ }
64
+ let resp;
65
+ try {
66
+ resp = await this.fetchImpl(url, init);
67
+ } catch (e) {
68
+ throw new NetworkError(
69
+ e instanceof Error ? e.message : "network error",
70
+ e
71
+ );
72
+ }
73
+ return parseResponse(resp);
74
+ }
75
+ absolute(path) {
76
+ if (path.startsWith("http://") || path.startsWith("https://")) return path;
77
+ const base = this.baseUrl.replace(/\/+$/, "");
78
+ const tail = path.startsWith("/") ? path : `/${path}`;
79
+ return `${base}${tail}`;
80
+ }
81
+ };
82
+ async function parseResponse(resp) {
83
+ const text = await resp.text();
84
+ let body;
85
+ if (text.length === 0) {
86
+ body = void 0;
87
+ } else {
88
+ try {
89
+ body = JSON.parse(text);
90
+ } catch {
91
+ body = { raw: text };
92
+ }
93
+ }
94
+ if (!resp.ok) {
95
+ const errBody = body ?? {};
96
+ throw new ApiError(
97
+ resp.status,
98
+ errBody.code ?? `http_${resp.status}`,
99
+ errBody.message ?? resp.statusText ?? "request failed",
100
+ body
101
+ );
102
+ }
103
+ return body;
104
+ }
105
+
106
+ // src/resources/auth.ts
107
+ var AuthResource = class {
108
+ constructor(http, tokens) {
109
+ this.http = http;
110
+ this.tokens = tokens;
111
+ }
112
+ /** Password-auth entry. May resolve to a JWT, or to a step-up
113
+ * challenge that needs `verifyTotp` / `verifyOtp` next. */
114
+ async login(input) {
115
+ const resp = await this.http.post("/auth/login", {
116
+ body: input,
117
+ skipAuth: true
118
+ });
119
+ if (resp.stage === "jwt") {
120
+ await Promise.resolve(this.tokens.set(resp.access_token));
121
+ }
122
+ return resp;
123
+ }
124
+ /** Verify a TOTP code (or XXXX-XXXX backup code) against a
125
+ * `totp_required` challenge. On success the JWT is stored. */
126
+ async verifyTotp(input) {
127
+ const resp = await this.http.post("/auth/login/totp", {
128
+ body: input,
129
+ skipAuth: true
130
+ });
131
+ await Promise.resolve(this.tokens.set(resp.access_token));
132
+ return resp;
133
+ }
134
+ /** Verify a 6-digit OTP code (Telegram / email) against an
135
+ * `otp_sent` challenge. */
136
+ async verifyOtp(input) {
137
+ const resp = await this.http.post("/auth/login/otp/verify", {
138
+ body: input,
139
+ skipAuth: true
140
+ });
141
+ await Promise.resolve(this.tokens.set(resp.access_token));
142
+ return resp;
143
+ }
144
+ /** Swap the 2FA method mid-flow. Resolves to `otp_sent` for
145
+ * telegram/email; for TOTP it short-circuits back to the challenge. */
146
+ async switchMethod(input) {
147
+ return this.http.post("/auth/login/2fa/switch", {
148
+ body: input,
149
+ skipAuth: true
150
+ });
151
+ }
152
+ /** Exchange a signed Telegram Mini App `initData` payload for a session
153
+ * JWT. The server validates the initData HMAC against the deployment's bot
154
+ * token, then find-or-creates the end-user. First-time Telegram users are
155
+ * auto-provisioned with `user.email_pending === true` — prompt them for a
156
+ * real email and call {@link linkEmail}. Stores the JWT on success.
157
+ *
158
+ * Most consumers use the higher-level `fromInitData` / `fromTelegramWebApp`
159
+ * helpers in `@takeal/cusfront-sdk/telegram`; reach for this directly when
160
+ * you already hold a configured client. */
161
+ async exchangeTelegram(input) {
162
+ const resp = await this.http.post("/auth/telegram/exchange", {
163
+ body: { init_data: input.initData },
164
+ skipAuth: true
165
+ });
166
+ await Promise.resolve(this.tokens.set(resp.access_token));
167
+ return resp;
168
+ }
169
+ /** Attach a real email to the current user (and clear `email_pending`).
170
+ * Used after a Telegram exchange to satisfy the email requirement; also
171
+ * works for a password user changing their address. 409 if taken. */
172
+ async linkEmail(input) {
173
+ return this.http.post("/me/email", { body: { email: input.email } });
174
+ }
175
+ /** Current user — fails 401 when the stored JWT is expired or
176
+ * missing. Useful as a "do I have a session" probe on app boot. */
177
+ async me() {
178
+ return this.http.get("/auth/me");
179
+ }
180
+ /** Local sign-out. The SDK doesn't currently call a server-side
181
+ * endpoint (the Takeal API issues stateless JWTs); clearing the
182
+ * store is enough. Server-side session invalidation may land
183
+ * with a future session table. */
184
+ async signOut() {
185
+ await Promise.resolve(this.tokens.clear());
186
+ }
187
+ };
188
+
189
+ // src/resources/deposits.ts
190
+ var DepositsResource = class {
191
+ constructor(http) {
192
+ this.http = http;
193
+ }
194
+ /**
195
+ * Initiate a top-up. Resolves to the freshly-created `Deposit`, whose
196
+ * `status` may already be `confirmed` (synchronous rails / mock) or
197
+ * `redirect_required` (3DS / APM — forward the user to `redirect_url`).
198
+ */
199
+ /**
200
+ * Price a cross-currency deposit BEFORE paying. The rate is locked
201
+ * server-side until `expires_at`; deposits in the local currency need no
202
+ * quote (the API answers 400 `no_quote_needed`).
203
+ */
204
+ async quote(input) {
205
+ return this.http.post("/me/deposits/quotes", { body: input });
206
+ }
207
+ async initiate(input) {
208
+ const { idempotencyKey, ...body } = input;
209
+ return this.http.post("/me/deposits", {
210
+ body,
211
+ idempotencyKey
212
+ });
213
+ }
214
+ /** Fetch one deposit by id — the poll target while a redirect resolves. */
215
+ async get(id) {
216
+ return this.http.get(`/me/deposits/${encodeURIComponent(id)}`);
217
+ }
218
+ /** List the caller's deposits, most recent first. */
219
+ async list() {
220
+ return this.http.get("/me/deposits");
221
+ }
222
+ /**
223
+ * Refund a previously-confirmed deposit. Synchronous when the
224
+ * connector settles inline; otherwise the row stays `pending` and flips
225
+ * later via the inbound `deposit.refunded` event.
226
+ */
227
+ async refund(depositId, input) {
228
+ const { idempotencyKey, ...body } = input;
229
+ return this.http.post(
230
+ `/me/deposits/${encodeURIComponent(depositId)}/refunds`,
231
+ { body, idempotencyKey }
232
+ );
233
+ }
234
+ };
235
+
236
+ // src/resources/cards.ts
237
+ var CardsResource = class {
238
+ constructor(http) {
239
+ this.http = http;
240
+ }
241
+ /**
242
+ * Issue a card backed by the user's wallet balance. Resolves to the new
243
+ * `Card`. On a ledger failure after provider creation, the Takeal API rolls the row
244
+ * to `failed` (never an orphaned active card); inspect `status` /
245
+ * `failure_reason` on the result.
246
+ */
247
+ async create(input) {
248
+ const { idempotencyKey, ...body } = input;
249
+ return this.http.post("/me/cards", {
250
+ body,
251
+ idempotencyKey
252
+ });
253
+ }
254
+ /** Fetch one card by id. */
255
+ async get(id) {
256
+ return this.http.get(`/me/cards/${encodeURIComponent(id)}`);
257
+ }
258
+ /** List the caller's cards, most recent first. */
259
+ async list() {
260
+ return this.http.get("/me/cards");
261
+ }
262
+ /**
263
+ * Remaining balance of a prepaid card. `currency` is required by the Takeal API and
264
+ * forwarded as a query param.
265
+ */
266
+ async balance(id, currency) {
267
+ const q = new URLSearchParams({ currency }).toString();
268
+ return this.http.get(
269
+ `/me/cards/${encodeURIComponent(id)}/balance?${q}`
270
+ );
271
+ }
272
+ /**
273
+ * Freeze the caller's own card. Reversible via {@link unfreeze}. The optional
274
+ * `reason` is recorded on the audit trail. Resolves to the updated card.
275
+ * 404 if the card isn't the caller's; 501 if the issuer can't freeze.
276
+ */
277
+ async freeze(id, reason) {
278
+ return this.http.post(
279
+ `/me/cards/${encodeURIComponent(id)}/freeze`,
280
+ { body: { reason } }
281
+ );
282
+ }
283
+ /**
284
+ * Reveal the FULL PAN + CVV for the caller's own card. Re-auth gated
285
+ * (password, + TOTP when the user has it enrolled) and rate-limited
286
+ * server-side. The Takeal API never persists this data and marks the
287
+ * response no-store; the SDK returns it verbatim and holds nothing.
288
+ *
289
+ * **Consumer security duties** (the SDK can't enforce these for you):
290
+ * keep the result in volatile memory only, never write it to
291
+ * localStorage / logs, and clear it within `expires_in_seconds`.
292
+ *
293
+ * 401 bad re-auth · 403 not your card · 429 rate-limited · 501 connector
294
+ * has no sensitive-data endpoint · 503 provider error.
295
+ */
296
+ async reveal(id, input) {
297
+ return this.http.post(
298
+ `/me/cards/${encodeURIComponent(id)}/reveal`,
299
+ { body: { password: input.password, totp_code: input.totpCode } }
300
+ );
301
+ }
302
+ /** Unfreeze a previously-frozen card. Idempotent on an already-active card. */
303
+ async unfreeze(id) {
304
+ return this.http.post(
305
+ `/me/cards/${encodeURIComponent(id)}/unfreeze`,
306
+ { body: {} }
307
+ );
308
+ }
309
+ /**
310
+ * Terminate the caller's own card. **One-way** — a terminated card cannot be
311
+ * reactivated. The optional `reason` is audited. Idempotent on an
312
+ * already-terminated card.
313
+ */
314
+ async terminate(id, reason) {
315
+ return this.http.post(
316
+ `/me/cards/${encodeURIComponent(id)}/terminate`,
317
+ { body: { reason } }
318
+ );
319
+ }
320
+ };
321
+
322
+ // src/resources/balance.ts
323
+ var BalanceResource = class {
324
+ constructor(http) {
325
+ this.http = http;
326
+ }
327
+ /**
328
+ * Fetch the user's wallet balance for `currency` (ISO 4217, e.g. `"USD"`).
329
+ * Required — the ledger holds a separate balance per currency, so there is
330
+ * no "total" without one.
331
+ */
332
+ async get(currency) {
333
+ const q = new URLSearchParams({ currency }).toString();
334
+ return this.http.get(`/me/balance?${q}`);
335
+ }
336
+ };
337
+
338
+ // src/resources/branding.ts
339
+ var BrandingResource = class {
340
+ constructor(http) {
341
+ this.http = http;
342
+ }
343
+ /** Fetch the deployment's public brand config. Safe to call before login. */
344
+ async get(opts = {}) {
345
+ return this.http.get("/branding", { skipAuth: true, signal: opts.signal });
346
+ }
347
+ };
348
+
349
+ // src/resources/blog.ts
350
+ var BlogResource = class {
351
+ constructor(http) {
352
+ this.http = http;
353
+ }
354
+ /** Published posts, newest first. No authentication required. */
355
+ async list(input = {}) {
356
+ const q = new URLSearchParams();
357
+ if (input.page) q.set("page", String(input.page));
358
+ if (input.perPage) q.set("per_page", String(input.perPage));
359
+ if (input.tag) q.set("tag", input.tag);
360
+ if (input.locale) q.set("locale", input.locale);
361
+ const qs = q.toString();
362
+ return this.http.get(`/blog/posts${qs ? `?${qs}` : ""}`, {
363
+ skipAuth: true
364
+ });
365
+ }
366
+ /** One post by slug. No authentication required. */
367
+ async get(slug) {
368
+ return this.http.get(`/blog/posts/${encodeURIComponent(slug)}`, {
369
+ skipAuth: true
370
+ });
371
+ }
372
+ /**
373
+ * Absolute URL for an image path returned inside a post (`cover_url`, or an
374
+ * image block's `url`). Handy when the app renders on a different origin
375
+ * than the API.
376
+ */
377
+ imageUrl(baseUrl, path) {
378
+ if (/^https?:\/\//i.test(path)) return path;
379
+ return `${baseUrl.replace(/\/$/, "")}${path.startsWith("/") ? "" : "/"}${path}`;
380
+ }
381
+ };
382
+
383
+ // src/resources/subscriptions.ts
384
+ var SubscriptionsResource = class {
385
+ constructor(http) {
386
+ this.http = http;
387
+ }
388
+ async get() {
389
+ return this.http.get("/me/subscriptions");
390
+ }
391
+ /**
392
+ * Replace the whole set — this is a PUT, not a merge. Pass `[]` to opt out
393
+ * of everything.
394
+ */
395
+ async set(channels) {
396
+ return this.http.put("/me/subscriptions", {
397
+ body: { channels }
398
+ });
399
+ }
400
+ };
401
+
402
+ // src/token-store.ts
403
+ function defaultBrowserStore(key = "takeal_jwt") {
404
+ const fallback = inMemoryStore();
405
+ let usable = false;
406
+ try {
407
+ if (typeof globalThis !== "undefined" && "localStorage" in globalThis) {
408
+ const ls2 = globalThis.localStorage;
409
+ const probe = "__takeal_probe__";
410
+ ls2.setItem(probe, "1");
411
+ ls2.removeItem(probe);
412
+ usable = true;
413
+ }
414
+ } catch {
415
+ usable = false;
416
+ }
417
+ if (!usable) return fallback;
418
+ const ls = globalThis.localStorage;
419
+ return {
420
+ get: () => ls.getItem(key),
421
+ set: (token) => ls.setItem(key, token),
422
+ clear: () => ls.removeItem(key)
423
+ };
424
+ }
425
+ function inMemoryStore() {
426
+ let value = null;
427
+ return {
428
+ get: () => value,
429
+ set: (token) => {
430
+ value = token;
431
+ },
432
+ clear: () => {
433
+ value = null;
434
+ }
435
+ };
436
+ }
437
+
438
+ // src/index.ts
439
+ function createClient(opts) {
440
+ const tokens = opts.tokenStore ?? pickDefaultStore();
441
+ const fetchImpl = opts.fetch ?? defaultFetch();
442
+ const http = new HttpClient(opts.baseUrl, tokens, fetchImpl);
443
+ return {
444
+ brand: opts.brand,
445
+ tokens,
446
+ auth: new AuthResource(http, tokens),
447
+ deposits: new DepositsResource(http),
448
+ cards: new CardsResource(http),
449
+ balance: new BalanceResource(http),
450
+ branding: new BrandingResource(http),
451
+ blog: new BlogResource(http),
452
+ subscriptions: new SubscriptionsResource(http)
453
+ };
454
+ }
455
+ function pickDefaultStore() {
456
+ if (typeof globalThis !== "undefined" && "localStorage" in globalThis) {
457
+ return defaultBrowserStore();
458
+ }
459
+ return inMemoryStore();
460
+ }
461
+ function defaultFetch() {
462
+ if (typeof globalThis !== "undefined" && typeof globalThis.fetch === "function") {
463
+ return globalThis.fetch.bind(globalThis);
464
+ }
465
+ throw new Error(
466
+ "@takeal/cusfront-sdk: native fetch is not available in this runtime. Pass a polyfill via createClient({ fetch })."
467
+ );
468
+ }
469
+
470
+ // src/telegram.ts
471
+ var InitDataError = class extends Error {
472
+ constructor(message, reason) {
473
+ super(message);
474
+ this.reason = reason;
475
+ this.name = "InitDataError";
476
+ }
477
+ };
478
+ function parseInitData(initData) {
479
+ const params = {};
480
+ const sp = new URLSearchParams(initData);
481
+ for (const [k, v] of sp.entries()) params[k] = v;
482
+ let user;
483
+ if (params.user) {
484
+ try {
485
+ user = JSON.parse(params.user);
486
+ } catch {
487
+ user = void 0;
488
+ }
489
+ }
490
+ const authDateRaw = params.auth_date;
491
+ const auth_date = authDateRaw && /^\d+$/.test(authDateRaw) ? Number(authDateRaw) : void 0;
492
+ return {
493
+ raw: initData,
494
+ params,
495
+ ...params.hash ? { hash: params.hash } : {},
496
+ ...auth_date !== void 0 ? { auth_date } : {},
497
+ ...params.query_id ? { query_id: params.query_id } : {},
498
+ ...user ? { user } : {}
499
+ };
500
+ }
501
+ function assertWellFormed(initData, opts = {}) {
502
+ if (!initData) throw new InitDataError("initData is empty", "empty");
503
+ const parsed = parseInitData(initData);
504
+ if (!parsed.hash)
505
+ throw new InitDataError("initData is missing `hash`", "missing_hash");
506
+ if (parsed.auth_date === void 0)
507
+ throw new InitDataError(
508
+ "initData is missing a valid `auth_date`",
509
+ "missing_auth_date"
510
+ );
511
+ if (!parsed.user || typeof parsed.user.id !== "number")
512
+ throw new InitDataError(
513
+ "initData is missing a valid `user`",
514
+ "bad_user"
515
+ );
516
+ const maxAge = opts.maxAgeSeconds ?? 86400;
517
+ if (maxAge > 0) {
518
+ const now = opts.nowUnix ?? Math.floor(Date.now() / 1e3);
519
+ if (now - parsed.auth_date > maxAge)
520
+ throw new InitDataError(
521
+ "initData is stale (auth_date older than the freshness window)",
522
+ "stale"
523
+ );
524
+ }
525
+ return parsed;
526
+ }
527
+ async function fromInitData(initData, config, opts = {}) {
528
+ if (!opts.skipWellFormedCheck) assertWellFormed(initData, opts);
529
+ const client = createClient(config);
530
+ await client.auth.exchangeTelegram({ initData });
531
+ return client;
532
+ }
533
+ function readWebAppInitData() {
534
+ const tg = globalThis.Telegram;
535
+ const data = tg?.WebApp?.initData;
536
+ return data && data.length > 0 ? data : null;
537
+ }
538
+ async function fromTelegramWebApp(config, opts = {}) {
539
+ const initData = readWebAppInitData();
540
+ if (!initData)
541
+ throw new InitDataError(
542
+ "not running inside a Telegram Mini App (window.Telegram.WebApp.initData is empty)",
543
+ "empty"
544
+ );
545
+ return fromInitData(initData, config, opts);
546
+ }
547
+
548
+ export { InitDataError, assertWellFormed, fromInitData, fromTelegramWebApp, parseInitData, readWebAppInitData };
549
+ //# sourceMappingURL=telegram.js.map
550
+ //# sourceMappingURL=telegram.js.map