@proappstore/sdk 1.15.0 → 1.16.1
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/README.md +82 -11
- package/dist/email.d.ts +22 -0
- package/dist/email.d.ts.map +1 -0
- package/dist/email.js +49 -0
- package/dist/email.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -5
- package/dist/index.js.map +1 -1
- package/dist/maps.d.ts.map +1 -1
- package/dist/maps.js +4 -2
- package/dist/maps.js.map +1 -1
- package/dist/webhooks.d.ts +41 -0
- package/dist/webhooks.d.ts.map +1 -0
- package/dist/webhooks.js +93 -0
- package/dist/webhooks.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @proappstore/sdk
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Full SDK for premium apps on **proappstore.online**. Auth, per-user KV, counters, real-time rooms, API proxy, per-app SQL database, file storage, maps & routing, subscriptions, license keys, push notifications, SMS, email, webhooks, server-side AI, and multi-tenant helpers.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -23,20 +23,63 @@ Options:
|
|
|
23
23
|
| Option | Default | Description |
|
|
24
24
|
|--------|---------|-------------|
|
|
25
25
|
| `appId` | (required) | Your app's unique identifier |
|
|
26
|
-
| `
|
|
27
|
-
| `proApiBase` | `https://api.proappstore.online` | Pro-tier backend URL |
|
|
26
|
+
| `proApiBase` | `https://api.proappstore.online` | Platform API base URL |
|
|
28
27
|
| `dataApiBase` | `https://data-{appId}.proappstore.online` | Per-app data worker URL |
|
|
29
28
|
|
|
29
|
+
## Types
|
|
30
|
+
|
|
31
|
+
```ts
|
|
32
|
+
import type { User, Subscription, QueryResult, ExecuteResult, Migration } from '@proappstore/sdk'
|
|
33
|
+
// Also available from hooks:
|
|
34
|
+
import type { User } from '@proappstore/sdk/hooks'
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
**User** — returned by `app.auth.user` and `useProAuth()`:
|
|
38
|
+
|
|
39
|
+
```ts
|
|
40
|
+
interface User {
|
|
41
|
+
id: string
|
|
42
|
+
login: string
|
|
43
|
+
avatarUrl: string | null
|
|
44
|
+
dateOfBirth: string | null // YYYY-MM-DD, null until set
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
**Database types:**
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
interface QueryResult<T> {
|
|
52
|
+
rows: T[]
|
|
53
|
+
meta: { changes: number; duration: number }
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
interface ExecuteResult {
|
|
57
|
+
meta: { changes: number; duration: number; last_row_id: number }
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
interface Migration {
|
|
61
|
+
name: string // e.g. "0001_init" — tracked, only applied once
|
|
62
|
+
sql: string // semicolon-separated statements
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
interface MigrateResult {
|
|
66
|
+
applied: string[] // migrations just applied
|
|
67
|
+
already: string[] // previously applied
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
30
71
|
## Modules
|
|
31
72
|
|
|
32
73
|
### Auth
|
|
33
74
|
|
|
34
|
-
GitHub OAuth — shared identity across all
|
|
75
|
+
GitHub OAuth — shared identity across all ProAppStore apps.
|
|
35
76
|
|
|
36
77
|
```ts
|
|
37
78
|
await app.auth.init()
|
|
38
79
|
app.auth.onChange((user) => console.log(user))
|
|
39
|
-
app.auth.signIn()
|
|
80
|
+
app.auth.signIn() // GitHub (default)
|
|
81
|
+
app.auth.signIn('google') // Google
|
|
82
|
+
app.auth.signIn('apple') // Apple
|
|
40
83
|
app.auth.signOut()
|
|
41
84
|
```
|
|
42
85
|
|
|
@@ -85,23 +128,38 @@ const response = await app.proxy.fetch('/openai/chat/completions', {
|
|
|
85
128
|
Each Pro app gets its own D1 SQL database accessed through a dedicated data worker at `data-{appId}.proappstore.online`.
|
|
86
129
|
|
|
87
130
|
```ts
|
|
131
|
+
// Schema migrations — idempotent, tracked by name
|
|
132
|
+
const { applied, already } = await app.db.migrate([
|
|
133
|
+
{
|
|
134
|
+
name: '0001_init',
|
|
135
|
+
sql: `
|
|
136
|
+
CREATE TABLE IF NOT EXISTS users (
|
|
137
|
+
id TEXT PRIMARY KEY,
|
|
138
|
+
name TEXT NOT NULL
|
|
139
|
+
);
|
|
140
|
+
`,
|
|
141
|
+
},
|
|
142
|
+
])
|
|
143
|
+
|
|
88
144
|
// Query rows
|
|
89
|
-
const { rows } = await app.db.query('SELECT * FROM users WHERE active = ?', [true])
|
|
145
|
+
const { rows } = await app.db.query<User>('SELECT * FROM users WHERE active = ?', [true])
|
|
90
146
|
|
|
91
147
|
// Execute writes
|
|
92
|
-
const { meta } = await app.db.execute('INSERT INTO users (name) VALUES (
|
|
148
|
+
const { meta } = await app.db.execute('INSERT INTO users (id, name) VALUES (?,?)', ['u1', 'Alice'])
|
|
93
149
|
console.log(meta.last_row_id) // auto-increment id
|
|
94
150
|
|
|
95
151
|
// Batch (transactional)
|
|
96
152
|
const results = await app.db.batch([
|
|
97
|
-
{ sql: 'INSERT INTO orders (user_id, total) VALUES (?, ?)', params: [
|
|
98
|
-
{ sql: 'UPDATE users SET order_count = order_count + 1 WHERE id = ?', params: [
|
|
153
|
+
{ sql: 'INSERT INTO orders (user_id, total) VALUES (?, ?)', params: ['u1', 99.99] },
|
|
154
|
+
{ sql: 'UPDATE users SET order_count = order_count + 1 WHERE id = ?', params: ['u1'] },
|
|
99
155
|
])
|
|
100
156
|
|
|
101
157
|
// List tables
|
|
102
158
|
const tables = await app.db.tables()
|
|
103
159
|
```
|
|
104
160
|
|
|
161
|
+
**Recommended pattern:** define migrations in a `db/core.ts` file and call `ensureMigrated()` at the top of each query function. See the [kanban app](https://github.com/proappstore-online/kanban/blob/main/web/src/lib/db/core.ts) for the full pattern.
|
|
162
|
+
|
|
105
163
|
### Subscription (Stripe-powered)
|
|
106
164
|
|
|
107
165
|
```ts
|
|
@@ -441,13 +499,26 @@ Props:
|
|
|
441
499
|
ProShell handles:
|
|
442
500
|
- Auth initialization and sign-in gate
|
|
443
501
|
- Subscription check and upgrade wall (unless `allowFree=true`)
|
|
444
|
-
- Topbar with avatar, app name, and user menu (sign out, manage billing, delete account)
|
|
502
|
+
- Topbar with avatar, app name, text size toggle, and user menu (sign out, manage billing, delete account)
|
|
503
|
+
|
|
504
|
+
## UI Components
|
|
505
|
+
|
|
506
|
+
Import from `@proappstore/sdk/ui`:
|
|
507
|
+
|
|
508
|
+
```tsx
|
|
509
|
+
import { Avatar, SignInButton, ThemeToggle, TextSizeToggle, ProBadge, ProfileMenu } from '@proappstore/sdk/ui'
|
|
510
|
+
```
|
|
511
|
+
|
|
512
|
+
- **TextSizeToggle** -- A/A+/A- button, cycles default/large/small text size. No props. Persists to localStorage.
|
|
513
|
+
- **ThemeToggle** -- Sun/moon button, cycles system/light/dark. No props.
|
|
514
|
+
|
|
515
|
+
See the [UI Component Library](https://proappstore.online/docs/ui) for the full list.
|
|
445
516
|
|
|
446
517
|
## Per-app SQL Database
|
|
447
518
|
|
|
448
519
|
Each Pro app is provisioned with a dedicated Cloudflare D1 database fronted by a data worker (`data-{appId}.proappstore.online`). The SDK's `db` module provides a typed client for this worker.
|
|
449
520
|
|
|
450
|
-
The database is per-user isolated at the auth layer — all requests require a valid Bearer token. The data worker validates the token against the
|
|
521
|
+
The database is per-user isolated at the auth layer — all requests require a valid Bearer token. The data worker validates the token against the platform auth API before executing queries.
|
|
451
522
|
|
|
452
523
|
Tables are user-defined (create them via `db.execute('CREATE TABLE IF NOT EXISTS ...')`). The schema is entirely up to the app developer.
|
|
453
524
|
|
package/dist/email.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
interface AuthLike {
|
|
2
|
+
token: string | null;
|
|
3
|
+
handleUnauthorized(): void;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Transactional email — send emails via the PAS API (Resend-backed server-side).
|
|
7
|
+
*
|
|
8
|
+
* The platform owns the Resend credentials; the app never sees them.
|
|
9
|
+
* Only app owners and editors can send. Rate-limited to 100/day per app.
|
|
10
|
+
*/
|
|
11
|
+
export declare class Email {
|
|
12
|
+
private readonly appId;
|
|
13
|
+
private readonly apiBase;
|
|
14
|
+
private readonly auth;
|
|
15
|
+
constructor(appId: string, apiBase: string, auth: AuthLike);
|
|
16
|
+
/** Send a transactional email. Caller must be app owner or editor. */
|
|
17
|
+
send(to: string, subject: string, body: string, opts?: {
|
|
18
|
+
replyTo?: string;
|
|
19
|
+
}): Promise<void>;
|
|
20
|
+
}
|
|
21
|
+
export {};
|
|
22
|
+
//# sourceMappingURL=email.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"email.d.ts","sourceRoot":"","sources":["../src/email.ts"],"names":[],"mappings":"AAAA,UAAU,QAAQ;IAChB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,kBAAkB,IAAI,IAAI,CAAC;CAC5B;AAED;;;;;GAKG;AACH,qBAAa,KAAK;IAEd,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAFJ,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,QAAQ;IAGjC,sEAAsE;IAChE,IAAI,CACR,EAAE,EAAE,MAAM,EACV,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,GAC1B,OAAO,CAAC,IAAI,CAAC;CA4BjB"}
|
package/dist/email.js
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Transactional email — send emails via the PAS API (Resend-backed server-side).
|
|
3
|
+
*
|
|
4
|
+
* The platform owns the Resend credentials; the app never sees them.
|
|
5
|
+
* Only app owners and editors can send. Rate-limited to 100/day per app.
|
|
6
|
+
*/
|
|
7
|
+
export class Email {
|
|
8
|
+
appId;
|
|
9
|
+
apiBase;
|
|
10
|
+
auth;
|
|
11
|
+
constructor(appId, apiBase, auth) {
|
|
12
|
+
this.appId = appId;
|
|
13
|
+
this.apiBase = apiBase;
|
|
14
|
+
this.auth = auth;
|
|
15
|
+
}
|
|
16
|
+
/** Send a transactional email. Caller must be app owner or editor. */
|
|
17
|
+
async send(to, subject, body, opts) {
|
|
18
|
+
const token = this.auth.token;
|
|
19
|
+
if (!token)
|
|
20
|
+
throw new Error('Not signed in.');
|
|
21
|
+
const res = await fetch(`${this.apiBase}/v1/email/send`, {
|
|
22
|
+
method: 'POST',
|
|
23
|
+
headers: {
|
|
24
|
+
Authorization: `Bearer ${token}`,
|
|
25
|
+
'Content-Type': 'application/json',
|
|
26
|
+
},
|
|
27
|
+
body: JSON.stringify({
|
|
28
|
+
appId: this.appId,
|
|
29
|
+
to,
|
|
30
|
+
subject,
|
|
31
|
+
body,
|
|
32
|
+
replyTo: opts?.replyTo,
|
|
33
|
+
}),
|
|
34
|
+
});
|
|
35
|
+
if (res.status === 401) {
|
|
36
|
+
this.auth.handleUnauthorized();
|
|
37
|
+
throw new Error('Not signed in.');
|
|
38
|
+
}
|
|
39
|
+
if (res.status === 403)
|
|
40
|
+
throw new Error('Not authorized to send email for this app.');
|
|
41
|
+
if (res.status === 429)
|
|
42
|
+
throw new Error('Daily email limit reached.');
|
|
43
|
+
if (res.status === 503)
|
|
44
|
+
throw new Error('Email is not configured on this platform.');
|
|
45
|
+
if (!res.ok)
|
|
46
|
+
throw new Error(`Email send failed: ${res.status}`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=email.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"email.js","sourceRoot":"","sources":["../src/email.ts"],"names":[],"mappings":"AAKA;;;;;GAKG;AACH,MAAM,OAAO,KAAK;IAEG;IACA;IACA;IAHnB,YACmB,KAAa,EACb,OAAe,EACf,IAAc;QAFd,UAAK,GAAL,KAAK,CAAQ;QACb,YAAO,GAAP,OAAO,CAAQ;QACf,SAAI,GAAJ,IAAI,CAAU;IAC9B,CAAC;IAEJ,sEAAsE;IACtE,KAAK,CAAC,IAAI,CACR,EAAU,EACV,OAAe,EACf,IAAY,EACZ,IAA2B;QAE3B,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;QAC9B,IAAI,CAAC,KAAK;YAAE,MAAM,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC;QAE9C,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,CAAC,OAAO,gBAAgB,EAAE;YACvD,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,aAAa,EAAE,UAAU,KAAK,EAAE;gBAChC,cAAc,EAAE,kBAAkB;aACnC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,EAAE;gBACF,OAAO;gBACP,IAAI;gBACJ,OAAO,EAAE,IAAI,EAAE,OAAO;aACvB,CAAC;SACH,CAAC,CAAC;QAEH,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YACvB,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC;YAC/B,MAAM,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC;QACpC,CAAC;QACD,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG;YAAE,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;QACtF,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG;YAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC;QACtE,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG;YAAE,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;QACrF,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,sBAAsB,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;IACnE,CAAC;CACF"}
|
package/dist/index.d.ts
CHANGED
|
@@ -8,6 +8,8 @@ import { Storage } from './storage.js';
|
|
|
8
8
|
import { SubscriptionApi } from './subscription.js';
|
|
9
9
|
import { LicenseApi } from './license.js';
|
|
10
10
|
import { Usage } from './usage.js';
|
|
11
|
+
import { Email } from './email.js';
|
|
12
|
+
import { Webhooks } from './webhooks.js';
|
|
11
13
|
import type { ProInitOptions } from './types.js';
|
|
12
14
|
export type { User, Unsubscribe, FasInitOptions, ConnectionState, Room, RoomMessage, RoomPeer, } from '@freeappstore/sdk';
|
|
13
15
|
export type { ProInitOptions, Subscription, SubscriptionStatus, CheckoutRequest, LicenseInfo, } from './types.js';
|
|
@@ -18,6 +20,9 @@ export type { TextModelAlias, EmbedModelAlias, ChatMessage, GenerateOptions, Gen
|
|
|
18
20
|
export { TenantScope } from './tenant.js';
|
|
19
21
|
export { Usage } from './usage.js';
|
|
20
22
|
export type { UsageOptions } from './usage.js';
|
|
23
|
+
export { Email } from './email.js';
|
|
24
|
+
export { Webhooks } from './webhooks.js';
|
|
25
|
+
export type { WebhookConfig, WebhookTestResult } from './webhooks.js';
|
|
21
26
|
/**
|
|
22
27
|
* Pro SDK instance — includes everything from @freeappstore/sdk (auth, kv,
|
|
23
28
|
* counters, rooms, proxy) plus subscription management and license keys.
|
|
@@ -34,6 +39,8 @@ export declare class ProAppStore extends FreeAppStore {
|
|
|
34
39
|
readonly sms: SMS;
|
|
35
40
|
readonly ai: AI;
|
|
36
41
|
readonly usage: Usage;
|
|
42
|
+
readonly email: Email;
|
|
43
|
+
readonly webhooks: Webhooks;
|
|
37
44
|
constructor(opts: ProInitOptions);
|
|
38
45
|
}
|
|
39
46
|
/** Create a new ProAppStore SDK instance. Includes all free + pro features. */
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAC/B,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAGjD,YAAY,EACV,IAAI,EACJ,WAAW,EACX,cAAc,EACd,eAAe,EACf,IAAI,EACJ,WAAW,EACX,QAAQ,GACT,MAAM,mBAAmB,CAAC;AAE3B,YAAY,EACV,cAAc,EACd,YAAY,EACZ,kBAAkB,EAClB,eAAe,EACf,WAAW,GACZ,MAAM,YAAY,CAAC;AAEpB,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACpF,YAAY,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAC1E,YAAY,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAC9C,YAAY,EACV,cAAc,EACd,eAAe,EACf,WAAW,EACX,eAAe,EACf,cAAc,EACd,YAAY,EACZ,WAAW,GACZ,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAC/B,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAGjD,YAAY,EACV,IAAI,EACJ,WAAW,EACX,cAAc,EACd,eAAe,EACf,IAAI,EACJ,WAAW,EACX,QAAQ,GACT,MAAM,mBAAmB,CAAC;AAE3B,YAAY,EACV,cAAc,EACd,YAAY,EACZ,kBAAkB,EAClB,eAAe,EACf,WAAW,GACZ,MAAM,YAAY,CAAC;AAEpB,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACpF,YAAY,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAC1E,YAAY,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAC9C,YAAY,EACV,cAAc,EACd,eAAe,EACf,WAAW,EACX,eAAe,EACf,cAAc,EACd,YAAY,EACZ,WAAW,GACZ,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,YAAY,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAEtE;;;;;GAKG;AACH,qBAAa,WAAY,SAAQ,YAAY;IAC3C,QAAQ,CAAC,YAAY,EAAE,eAAe,CAAC;IACvC,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC;IAC7B,QAAQ,CAAC,EAAE,EAAE,QAAQ,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;IACpB,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC;IACtC,QAAQ,CAAC,GAAG,EAAE,GAAG,CAAC;IAClB,QAAQ,CAAC,EAAE,EAAE,EAAE,CAAC;IAChB,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;gBAEhB,IAAI,EAAE,cAAc;CAqBjC;AAED,+EAA+E;AAC/E,wBAAgB,OAAO,CAAC,IAAI,EAAE,cAAc,GAAG,WAAW,CAEzD"}
|
package/dist/index.js
CHANGED
|
@@ -8,8 +8,12 @@ import { Storage } from './storage.js';
|
|
|
8
8
|
import { SubscriptionApi } from './subscription.js';
|
|
9
9
|
import { LicenseApi } from './license.js';
|
|
10
10
|
import { Usage } from './usage.js';
|
|
11
|
+
import { Email } from './email.js';
|
|
12
|
+
import { Webhooks } from './webhooks.js';
|
|
11
13
|
export { TenantScope } from './tenant.js';
|
|
12
14
|
export { Usage } from './usage.js';
|
|
15
|
+
export { Email } from './email.js';
|
|
16
|
+
export { Webhooks } from './webhooks.js';
|
|
13
17
|
/**
|
|
14
18
|
* Pro SDK instance — includes everything from @freeappstore/sdk (auth, kv,
|
|
15
19
|
* counters, rooms, proxy) plus subscription management and license keys.
|
|
@@ -26,6 +30,8 @@ export class ProAppStore extends FreeAppStore {
|
|
|
26
30
|
sms;
|
|
27
31
|
ai;
|
|
28
32
|
usage;
|
|
33
|
+
email;
|
|
34
|
+
webhooks;
|
|
29
35
|
constructor(opts) {
|
|
30
36
|
super({ appId: opts.appId, ...(opts.fasApiBase && { apiBase: opts.fasApiBase }) });
|
|
31
37
|
const proApiBase = opts.proApiBase ?? 'https://api.proappstore.online';
|
|
@@ -38,11 +44,17 @@ export class ProAppStore extends FreeAppStore {
|
|
|
38
44
|
this.sms = new SMS(opts.appId, proApiBase, this.auth);
|
|
39
45
|
this.ai = new AI(proApiBase, this.auth);
|
|
40
46
|
this.usage = new Usage(opts.appId, proApiBase, this.auth);
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
//
|
|
44
|
-
|
|
45
|
-
|
|
47
|
+
this.email = new Email(opts.appId, proApiBase, this.auth);
|
|
48
|
+
this.webhooks = new Webhooks(opts.appId, proApiBase, this.auth);
|
|
49
|
+
// Auto-start telemetry unless the app opts out. Wrapped in try-catch
|
|
50
|
+
// because localStorage can throw in incognito, sandboxed iframes, or
|
|
51
|
+
// when storage quota is exceeded.
|
|
52
|
+
if (opts.usage?.auto !== false) {
|
|
53
|
+
try {
|
|
54
|
+
this.usage.start();
|
|
55
|
+
}
|
|
56
|
+
catch { /* non-fatal — app runs without usage tracking */ }
|
|
57
|
+
}
|
|
46
58
|
}
|
|
47
59
|
}
|
|
48
60
|
/** Create a new ProAppStore SDK instance. Includes all free + pro features. */
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAC/B,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/maps.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"maps.d.ts","sourceRoot":"","sources":["../src/maps.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,WAAW;IAC1B,6EAA6E;IAC7E,QAAQ,EAAE;QAAE,IAAI,EAAE,YAAY,CAAC;QAAC,WAAW,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAA;KAAE,CAAC;IAClE,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,qBAAa,IAAI;IACH,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,MAAM;IAE5C,+EAA+E;IACzE,OAAO,CACX,KAAK,EAAE,MAAM,EACb,KAAK,SAAI,EACT,IAAI,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GAC9B,OAAO,CAAC,SAAS,EAAE,CAAC;IAYvB;;;;OAIG;IACG,KAAK,CACT,IAAI,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,EAClC,EAAE,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,EAChC,IAAI,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GAC9B,OAAO,CAAC,WAAW,CAAC;IAWvB,yCAAyC;IACnC,cAAc,CAClB,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,IAAI,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GAC9B,OAAO,CAAC,aAAa,CAAC;IAWzB;;;;;OAKG;IACH,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,SAAK,GAAG,MAAM;
|
|
1
|
+
{"version":3,"file":"maps.d.ts","sourceRoot":"","sources":["../src/maps.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,WAAW;IAC1B,6EAA6E;IAC7E,QAAQ,EAAE;QAAE,IAAI,EAAE,YAAY,CAAC;QAAC,WAAW,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAA;KAAE,CAAC;IAClE,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,qBAAa,IAAI;IACH,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,MAAM;IAE5C,+EAA+E;IACzE,OAAO,CACX,KAAK,EAAE,MAAM,EACb,KAAK,SAAI,EACT,IAAI,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GAC9B,OAAO,CAAC,SAAS,EAAE,CAAC;IAYvB;;;;OAIG;IACG,KAAK,CACT,IAAI,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,EAClC,EAAE,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,EAChC,IAAI,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GAC9B,OAAO,CAAC,WAAW,CAAC;IAWvB,yCAAyC;IACnC,cAAc,CAClB,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,MAAM,EACX,IAAI,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GAC9B,OAAO,CAAC,aAAa,CAAC;IAWzB;;;;;OAKG;IACH,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,SAAK,GAAG,MAAM;IAKrD;;;;;OAKG;IACH,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,SAAK,GAAG,MAAM;CAMvD"}
|
package/dist/maps.js
CHANGED
|
@@ -50,7 +50,8 @@ export class Maps {
|
|
|
50
50
|
* Usage: <iframe src={app.maps.embedUrl(lat, lng, zoom)} />
|
|
51
51
|
*/
|
|
52
52
|
embedUrl(lat, lng, zoom = 15) {
|
|
53
|
-
|
|
53
|
+
const delta = 360 / Math.pow(2, zoom);
|
|
54
|
+
return `https://www.openstreetmap.org/export/embed.html?bbox=${lng - delta},${lat - delta},${lng + delta},${lat + delta}&layer=mapnik&marker=${lat},${lng}`;
|
|
54
55
|
}
|
|
55
56
|
/**
|
|
56
57
|
* Get a static map image URL (no JavaScript needed).
|
|
@@ -59,8 +60,9 @@ export class Maps {
|
|
|
59
60
|
* Usage: <img src={app.maps.staticUrl(lat, lng)} />
|
|
60
61
|
*/
|
|
61
62
|
staticUrl(lat, lng, zoom = 15) {
|
|
63
|
+
const clampedLat = Math.max(-85.05, Math.min(85.05, lat));
|
|
62
64
|
const x = Math.floor(((lng + 180) / 360) * Math.pow(2, zoom));
|
|
63
|
-
const y = Math.floor((1 - Math.log(Math.tan((
|
|
65
|
+
const y = Math.floor((1 - Math.log(Math.tan((clampedLat * Math.PI) / 180) + 1 / Math.cos((clampedLat * Math.PI) / 180)) / Math.PI) / 2 * Math.pow(2, zoom));
|
|
64
66
|
return `https://tile.openstreetmap.org/${zoom}/${x}/${y}.png`;
|
|
65
67
|
}
|
|
66
68
|
}
|
package/dist/maps.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"maps.js","sourceRoot":"","sources":["../src/maps.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"maps.js","sourceRoot":"","sources":["../src/maps.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
interface AuthLike {
|
|
2
|
+
token: string | null;
|
|
3
|
+
handleUnauthorized(): void;
|
|
4
|
+
}
|
|
5
|
+
export interface WebhookConfig {
|
|
6
|
+
id: string;
|
|
7
|
+
event: string;
|
|
8
|
+
url: string;
|
|
9
|
+
active: number;
|
|
10
|
+
created_at: number;
|
|
11
|
+
}
|
|
12
|
+
export interface WebhookTestResult {
|
|
13
|
+
status: number;
|
|
14
|
+
body: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Outbound webhooks — register URLs to receive signed event payloads.
|
|
18
|
+
*
|
|
19
|
+
* Events are delivered via POST with HMAC-SHA256 signature in
|
|
20
|
+
* `X-Webhook-Signature` header. The signing secret is returned once
|
|
21
|
+
* on registration.
|
|
22
|
+
*/
|
|
23
|
+
export declare class Webhooks {
|
|
24
|
+
private readonly appId;
|
|
25
|
+
private readonly apiBase;
|
|
26
|
+
private readonly auth;
|
|
27
|
+
constructor(appId: string, apiBase: string, auth: AuthLike);
|
|
28
|
+
/** List all registered webhooks for this app. */
|
|
29
|
+
list(): Promise<WebhookConfig[]>;
|
|
30
|
+
/** Register a new webhook. Returns the ID and signing secret. */
|
|
31
|
+
register(event: string, url: string): Promise<{
|
|
32
|
+
id: string;
|
|
33
|
+
secret: string;
|
|
34
|
+
}>;
|
|
35
|
+
/** Remove a registered webhook. */
|
|
36
|
+
remove(id: string): Promise<void>;
|
|
37
|
+
/** Fire a test event to a registered webhook and return the response. */
|
|
38
|
+
test(id: string): Promise<WebhookTestResult>;
|
|
39
|
+
}
|
|
40
|
+
export {};
|
|
41
|
+
//# sourceMappingURL=webhooks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webhooks.d.ts","sourceRoot":"","sources":["../src/webhooks.ts"],"names":[],"mappings":"AAAA,UAAU,QAAQ;IAChB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,kBAAkB,IAAI,IAAI,CAAC;CAC5B;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;;;;;GAMG;AACH,qBAAa,QAAQ;IAEjB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,IAAI;gBAFJ,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,QAAQ;IAGjC,iDAAiD;IAC3C,IAAI,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;IAkBtC,iEAAiE;IAC3D,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAsBnF,mCAAmC;IAC7B,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBvC,yEAAyE;IACnE,IAAI,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;CAiBnD"}
|
package/dist/webhooks.js
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Outbound webhooks — register URLs to receive signed event payloads.
|
|
3
|
+
*
|
|
4
|
+
* Events are delivered via POST with HMAC-SHA256 signature in
|
|
5
|
+
* `X-Webhook-Signature` header. The signing secret is returned once
|
|
6
|
+
* on registration.
|
|
7
|
+
*/
|
|
8
|
+
export class Webhooks {
|
|
9
|
+
appId;
|
|
10
|
+
apiBase;
|
|
11
|
+
auth;
|
|
12
|
+
constructor(appId, apiBase, auth) {
|
|
13
|
+
this.appId = appId;
|
|
14
|
+
this.apiBase = apiBase;
|
|
15
|
+
this.auth = auth;
|
|
16
|
+
}
|
|
17
|
+
/** List all registered webhooks for this app. */
|
|
18
|
+
async list() {
|
|
19
|
+
const token = this.auth.token;
|
|
20
|
+
if (!token)
|
|
21
|
+
throw new Error('Not signed in.');
|
|
22
|
+
const appId = encodeURIComponent(this.appId);
|
|
23
|
+
const res = await fetch(`${this.apiBase}/v1/apps/${appId}/webhooks`, {
|
|
24
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
25
|
+
});
|
|
26
|
+
if (res.status === 401) {
|
|
27
|
+
this.auth.handleUnauthorized();
|
|
28
|
+
throw new Error('Not signed in.');
|
|
29
|
+
}
|
|
30
|
+
if (!res.ok)
|
|
31
|
+
throw new Error(`Failed to list webhooks: ${res.status}`);
|
|
32
|
+
const data = (await res.json());
|
|
33
|
+
return data.webhooks;
|
|
34
|
+
}
|
|
35
|
+
/** Register a new webhook. Returns the ID and signing secret. */
|
|
36
|
+
async register(event, url) {
|
|
37
|
+
const token = this.auth.token;
|
|
38
|
+
if (!token)
|
|
39
|
+
throw new Error('Not signed in.');
|
|
40
|
+
const appId = encodeURIComponent(this.appId);
|
|
41
|
+
const res = await fetch(`${this.apiBase}/v1/apps/${appId}/webhooks`, {
|
|
42
|
+
method: 'POST',
|
|
43
|
+
headers: {
|
|
44
|
+
Authorization: `Bearer ${token}`,
|
|
45
|
+
'Content-Type': 'application/json',
|
|
46
|
+
},
|
|
47
|
+
body: JSON.stringify({ event, url }),
|
|
48
|
+
});
|
|
49
|
+
if (res.status === 401) {
|
|
50
|
+
this.auth.handleUnauthorized();
|
|
51
|
+
throw new Error('Not signed in.');
|
|
52
|
+
}
|
|
53
|
+
if (!res.ok)
|
|
54
|
+
throw new Error(`Failed to register webhook: ${res.status}`);
|
|
55
|
+
return (await res.json());
|
|
56
|
+
}
|
|
57
|
+
/** Remove a registered webhook. */
|
|
58
|
+
async remove(id) {
|
|
59
|
+
const token = this.auth.token;
|
|
60
|
+
if (!token)
|
|
61
|
+
throw new Error('Not signed in.');
|
|
62
|
+
const appId = encodeURIComponent(this.appId);
|
|
63
|
+
const res = await fetch(`${this.apiBase}/v1/apps/${appId}/webhooks/${id}`, {
|
|
64
|
+
method: 'DELETE',
|
|
65
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
66
|
+
});
|
|
67
|
+
if (res.status === 401) {
|
|
68
|
+
this.auth.handleUnauthorized();
|
|
69
|
+
throw new Error('Not signed in.');
|
|
70
|
+
}
|
|
71
|
+
if (!res.ok)
|
|
72
|
+
throw new Error(`Failed to remove webhook: ${res.status}`);
|
|
73
|
+
}
|
|
74
|
+
/** Fire a test event to a registered webhook and return the response. */
|
|
75
|
+
async test(id) {
|
|
76
|
+
const token = this.auth.token;
|
|
77
|
+
if (!token)
|
|
78
|
+
throw new Error('Not signed in.');
|
|
79
|
+
const appId = encodeURIComponent(this.appId);
|
|
80
|
+
const res = await fetch(`${this.apiBase}/v1/apps/${appId}/webhooks/${id}/test`, {
|
|
81
|
+
method: 'POST',
|
|
82
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
83
|
+
});
|
|
84
|
+
if (res.status === 401) {
|
|
85
|
+
this.auth.handleUnauthorized();
|
|
86
|
+
throw new Error('Not signed in.');
|
|
87
|
+
}
|
|
88
|
+
if (!res.ok)
|
|
89
|
+
throw new Error(`Failed to test webhook: ${res.status}`);
|
|
90
|
+
return (await res.json());
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=webhooks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webhooks.js","sourceRoot":"","sources":["../src/webhooks.ts"],"names":[],"mappings":"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"}
|