@pushary/server 1.0.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/LICENSE +22 -0
- package/README.md +157 -0
- package/dist/index.cjs +127 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +180 -0
- package/dist/index.d.ts +180 -0
- package/dist/index.js +100 -0
- package/dist/index.js.map +1 -0
- package/package.json +56 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Pushary
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
package/README.md
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
# @pushary/server
|
|
2
|
+
|
|
3
|
+
Server-side SDK for [Pushary](https://pushary.com) - Manage subscribers, campaigns, templates, and send push notifications from your backend.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @pushary/server
|
|
9
|
+
# or
|
|
10
|
+
yarn add @pushary/server
|
|
11
|
+
# or
|
|
12
|
+
pnpm add @pushary/server
|
|
13
|
+
# or
|
|
14
|
+
bun add @pushary/server
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Quick Start
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
import { createPusharyServer } from '@pushary/server'
|
|
21
|
+
|
|
22
|
+
const pushary = createPusharyServer({
|
|
23
|
+
apiKey: process.env.PUSHARY_API_KEY, // Required: pk_xxx.sk_xxx
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
// Send a notification
|
|
27
|
+
await pushary.notifications.send({
|
|
28
|
+
title: 'Hello!',
|
|
29
|
+
body: 'Your order has shipped',
|
|
30
|
+
subscriberIds: ['sub_123'],
|
|
31
|
+
})
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## API Key
|
|
35
|
+
|
|
36
|
+
The server SDK requires your full API key (`pk_xxx.sk_xxx`) which includes the secret portion. Never expose this in client-side code.
|
|
37
|
+
|
|
38
|
+
Get your API key from your [Pushary Dashboard](https://pushary.com/dashboard/settings).
|
|
39
|
+
|
|
40
|
+
## Resources
|
|
41
|
+
|
|
42
|
+
### Subscribers
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
// List subscribers
|
|
46
|
+
const { data, hasMore, nextCursor } = await pushary.subscribers.list({
|
|
47
|
+
limit: 100,
|
|
48
|
+
status: 'active',
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
// Get a subscriber
|
|
52
|
+
const subscriber = await pushary.subscribers.get('sub_123')
|
|
53
|
+
|
|
54
|
+
// Update subscriber
|
|
55
|
+
await pushary.subscribers.update('sub_123', {
|
|
56
|
+
tags: ['vip', 'newsletter'],
|
|
57
|
+
externalId: 'user-456',
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
// Delete subscriber
|
|
61
|
+
await pushary.subscribers.delete('sub_123')
|
|
62
|
+
|
|
63
|
+
// Get subscriber count
|
|
64
|
+
const count = await pushary.subscribers.count()
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Campaigns
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
// List campaigns
|
|
71
|
+
const { data } = await pushary.campaigns.list()
|
|
72
|
+
|
|
73
|
+
// Create campaign
|
|
74
|
+
const campaign = await pushary.campaigns.create({
|
|
75
|
+
name: 'Welcome Campaign',
|
|
76
|
+
title: 'Welcome!',
|
|
77
|
+
body: 'Thanks for subscribing',
|
|
78
|
+
actionUrl: 'https://example.com/welcome',
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
// Send campaign
|
|
82
|
+
await pushary.campaigns.send(campaign.id)
|
|
83
|
+
|
|
84
|
+
// Pause/Resume
|
|
85
|
+
await pushary.campaigns.pause(campaign.id)
|
|
86
|
+
await pushary.campaigns.resume(campaign.id)
|
|
87
|
+
|
|
88
|
+
// Get stats
|
|
89
|
+
const stats = await pushary.campaigns.stats(campaign.id)
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Templates
|
|
93
|
+
|
|
94
|
+
```typescript
|
|
95
|
+
// List templates
|
|
96
|
+
const { data } = await pushary.templates.list()
|
|
97
|
+
|
|
98
|
+
// Create template
|
|
99
|
+
const template = await pushary.templates.create({
|
|
100
|
+
name: 'Order Update',
|
|
101
|
+
title: 'Order {{orderId}} Update',
|
|
102
|
+
body: 'Your order status: {{status}}',
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
// Update template
|
|
106
|
+
await pushary.templates.update(template.id, {
|
|
107
|
+
body: 'Your order {{orderId}} is now {{status}}',
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
// Delete template
|
|
111
|
+
await pushary.templates.delete(template.id)
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Notifications (Direct Send)
|
|
115
|
+
|
|
116
|
+
```typescript
|
|
117
|
+
// Send to specific subscribers
|
|
118
|
+
await pushary.notifications.send({
|
|
119
|
+
title: 'Flash Sale!',
|
|
120
|
+
body: '50% off everything',
|
|
121
|
+
url: 'https://example.com/sale',
|
|
122
|
+
subscriberIds: ['sub_123', 'sub_456'],
|
|
123
|
+
})
|
|
124
|
+
|
|
125
|
+
// Send to external IDs (your user IDs)
|
|
126
|
+
await pushary.notifications.send({
|
|
127
|
+
title: 'New Message',
|
|
128
|
+
body: 'You have a new message',
|
|
129
|
+
externalIds: ['user-123'],
|
|
130
|
+
})
|
|
131
|
+
|
|
132
|
+
// Send to subscribers with tags
|
|
133
|
+
await pushary.notifications.send({
|
|
134
|
+
title: 'VIP Exclusive',
|
|
135
|
+
body: 'Special offer just for you',
|
|
136
|
+
tags: ['vip'],
|
|
137
|
+
})
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## TypeScript
|
|
141
|
+
|
|
142
|
+
Full TypeScript support with exported types:
|
|
143
|
+
|
|
144
|
+
```typescript
|
|
145
|
+
import {
|
|
146
|
+
createPusharyServer,
|
|
147
|
+
type Subscriber,
|
|
148
|
+
type Campaign,
|
|
149
|
+
type Template,
|
|
150
|
+
type SendNotification,
|
|
151
|
+
} from '@pushary/server'
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## License
|
|
155
|
+
|
|
156
|
+
MIT
|
|
157
|
+
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var src_exports = {};
|
|
22
|
+
__export(src_exports, {
|
|
23
|
+
createPusharyServer: () => createPusharyServer
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(src_exports);
|
|
26
|
+
|
|
27
|
+
// src/request.ts
|
|
28
|
+
var buildUrl = (baseUrl, path, params) => {
|
|
29
|
+
const url = new URL(path, baseUrl);
|
|
30
|
+
if (params) {
|
|
31
|
+
Object.entries(params).forEach(([key, value]) => {
|
|
32
|
+
if (value !== void 0 && value !== null) {
|
|
33
|
+
url.searchParams.set(key, String(value));
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
return url.toString();
|
|
38
|
+
};
|
|
39
|
+
var handleResponse = async (response) => {
|
|
40
|
+
if (!response.ok) {
|
|
41
|
+
const error = await response.json().catch(() => ({ message: "Request failed" }));
|
|
42
|
+
throw new Error(error.message || `HTTP ${response.status}`);
|
|
43
|
+
}
|
|
44
|
+
return response.json();
|
|
45
|
+
};
|
|
46
|
+
var createRequest = (ctx) => async (method, path, body) => {
|
|
47
|
+
const isGet = method === "GET";
|
|
48
|
+
const url = isGet && body ? buildUrl(ctx.baseUrl, path, body) : `${ctx.baseUrl}${path}`;
|
|
49
|
+
const response = await fetch(url, {
|
|
50
|
+
method,
|
|
51
|
+
headers: ctx.headers,
|
|
52
|
+
body: !isGet && body ? JSON.stringify(body) : void 0
|
|
53
|
+
});
|
|
54
|
+
return handleResponse(response);
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
// src/resources/subscribers.ts
|
|
58
|
+
var createSubscribersResource = (request) => Object.freeze({
|
|
59
|
+
list: (params) => request("GET", "/subscribers", params),
|
|
60
|
+
get: (id) => request("GET", `/subscribers/${id}`),
|
|
61
|
+
update: (id, data) => request("PATCH", `/subscribers/${id}`, data),
|
|
62
|
+
delete: (id) => request("DELETE", `/subscribers/${id}`),
|
|
63
|
+
count: () => request("GET", "/subscribers/count")
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
// src/resources/campaigns.ts
|
|
67
|
+
var createCampaignsResource = (request) => Object.freeze({
|
|
68
|
+
list: (params) => request("GET", "/campaigns", params),
|
|
69
|
+
create: (data) => request("POST", "/campaigns", data),
|
|
70
|
+
get: (id) => request("GET", `/campaigns/${id}`),
|
|
71
|
+
update: (id, data) => request("PATCH", `/campaigns/${id}`, data),
|
|
72
|
+
delete: (id) => request("DELETE", `/campaigns/${id}`),
|
|
73
|
+
send: (id) => request("POST", `/campaigns/${id}/send`),
|
|
74
|
+
pause: (id) => request("POST", `/campaigns/${id}/pause`),
|
|
75
|
+
resume: (id) => request("POST", `/campaigns/${id}/resume`),
|
|
76
|
+
stats: (id) => request("GET", `/campaigns/${id}/stats`)
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
// src/resources/templates.ts
|
|
80
|
+
var createTemplatesResource = (request) => Object.freeze({
|
|
81
|
+
list: (params) => request("GET", "/templates", params),
|
|
82
|
+
create: (data) => request("POST", "/templates", data),
|
|
83
|
+
get: (id) => request("GET", `/templates/${id}`),
|
|
84
|
+
update: (id, data) => request("PATCH", `/templates/${id}`, data),
|
|
85
|
+
delete: (id) => request("DELETE", `/templates/${id}`)
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
// src/resources/notifications.ts
|
|
89
|
+
var createNotificationsResource = (request) => Object.freeze({
|
|
90
|
+
send: (data) => request("POST", "/send", data)
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
// src/client.ts
|
|
94
|
+
var DEFAULT_BASE_URL = "https://pushary.com/api/v1/server";
|
|
95
|
+
var validateApiKey = (apiKey) => {
|
|
96
|
+
if (!apiKey) {
|
|
97
|
+
throw new Error("API key is required. Get your API key from https://pushary.com/dashboard/settings");
|
|
98
|
+
}
|
|
99
|
+
if (!apiKey.includes(".")) {
|
|
100
|
+
throw new Error("Invalid API key format. Use the full API key (pk_xxx.sk_xxx)");
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
var createContext = (config) => {
|
|
104
|
+
validateApiKey(config.apiKey);
|
|
105
|
+
return Object.freeze({
|
|
106
|
+
baseUrl: config.baseUrl ?? DEFAULT_BASE_URL,
|
|
107
|
+
headers: Object.freeze({
|
|
108
|
+
"Content-Type": "application/json",
|
|
109
|
+
"Authorization": `Bearer ${config.apiKey}`
|
|
110
|
+
})
|
|
111
|
+
});
|
|
112
|
+
};
|
|
113
|
+
var createPusharyServer = (config) => {
|
|
114
|
+
const ctx = createContext(config);
|
|
115
|
+
const request = createRequest(ctx);
|
|
116
|
+
return Object.freeze({
|
|
117
|
+
subscribers: createSubscribersResource(request),
|
|
118
|
+
campaigns: createCampaignsResource(request),
|
|
119
|
+
templates: createTemplatesResource(request),
|
|
120
|
+
notifications: createNotificationsResource(request)
|
|
121
|
+
});
|
|
122
|
+
};
|
|
123
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
124
|
+
0 && (module.exports = {
|
|
125
|
+
createPusharyServer
|
|
126
|
+
});
|
|
127
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/request.ts","../src/resources/subscribers.ts","../src/resources/campaigns.ts","../src/resources/templates.ts","../src/resources/notifications.ts","../src/client.ts"],"sourcesContent":["export { createPusharyServer, type PusharyServer } from './client'\n\nexport type {\n PusharyConfig,\n Subscriber,\n SubscriberListParams,\n UpdateSubscriber,\n SubscriberCount,\n Campaign,\n CreateCampaign,\n UpdateCampaign,\n CampaignStats,\n Template,\n CreateTemplate,\n UpdateTemplate,\n SendNotification,\n SendResult,\n ListParams,\n PaginatedResponse,\n} from './types'\n\nexport type { SubscribersResource } from './resources/subscribers'\nexport type { CampaignsResource } from './resources/campaigns'\nexport type { TemplatesResource } from './resources/templates'\nexport type { NotificationsResource } from './resources/notifications'\n\n","import type { RequestContext, RequestFn } from './types'\n\nconst buildUrl = (baseUrl: string, path: string, params?: Record<string, unknown>): string => {\n const url = new URL(path, baseUrl)\n \n if (params) {\n Object.entries(params).forEach(([key, value]) => {\n if (value !== undefined && value !== null) {\n url.searchParams.set(key, String(value))\n }\n })\n }\n \n return url.toString()\n}\n\nconst handleResponse = async <T>(response: Response): Promise<T> => {\n if (!response.ok) {\n const error = await response.json().catch(() => ({ message: 'Request failed' }))\n throw new Error(error.message || `HTTP ${response.status}`)\n }\n return response.json() as Promise<T>\n}\n\nexport const createRequest = (ctx: RequestContext): RequestFn =>\n async <T>(method: string, path: string, body?: unknown): Promise<T> => {\n const isGet = method === 'GET'\n const url = isGet && body \n ? buildUrl(ctx.baseUrl, path, body as Record<string, unknown>)\n : `${ctx.baseUrl}${path}`\n \n const response = await fetch(url, {\n method,\n headers: ctx.headers,\n body: !isGet && body ? JSON.stringify(body) : undefined,\n })\n \n return handleResponse<T>(response)\n }\n\n","import type {\n RequestFn,\n Subscriber,\n SubscriberListParams,\n UpdateSubscriber,\n PaginatedResponse,\n SubscriberCount,\n} from '../types'\n\nexport interface SubscribersResource {\n readonly list: (params?: SubscriberListParams) => Promise<PaginatedResponse<Subscriber>>\n readonly get: (id: string) => Promise<Subscriber>\n readonly update: (id: string, data: UpdateSubscriber) => Promise<Subscriber>\n readonly delete: (id: string) => Promise<void>\n readonly count: () => Promise<SubscriberCount>\n}\n\nexport const createSubscribersResource = (request: RequestFn): SubscribersResource =>\n Object.freeze({\n list: (params?: SubscriberListParams) =>\n request<PaginatedResponse<Subscriber>>('GET', '/subscribers', params),\n \n get: (id: string) =>\n request<Subscriber>('GET', `/subscribers/${id}`),\n \n update: (id: string, data: UpdateSubscriber) =>\n request<Subscriber>('PATCH', `/subscribers/${id}`, data),\n \n delete: (id: string) =>\n request<void>('DELETE', `/subscribers/${id}`),\n \n count: () =>\n request<SubscriberCount>('GET', '/subscribers/count'),\n })\n\n","import type {\n RequestFn,\n Campaign,\n CreateCampaign,\n UpdateCampaign,\n ListParams,\n PaginatedResponse,\n CampaignStats,\n} from '../types'\n\nexport interface CampaignsResource {\n readonly list: (params?: ListParams) => Promise<PaginatedResponse<Campaign>>\n readonly create: (data: CreateCampaign) => Promise<Campaign>\n readonly get: (id: string) => Promise<Campaign>\n readonly update: (id: string, data: UpdateCampaign) => Promise<Campaign>\n readonly delete: (id: string) => Promise<void>\n readonly send: (id: string) => Promise<Campaign>\n readonly pause: (id: string) => Promise<Campaign>\n readonly resume: (id: string) => Promise<Campaign>\n readonly stats: (id: string) => Promise<CampaignStats>\n}\n\nexport const createCampaignsResource = (request: RequestFn): CampaignsResource =>\n Object.freeze({\n list: (params?: ListParams) =>\n request<PaginatedResponse<Campaign>>('GET', '/campaigns', params),\n \n create: (data: CreateCampaign) =>\n request<Campaign>('POST', '/campaigns', data),\n \n get: (id: string) =>\n request<Campaign>('GET', `/campaigns/${id}`),\n \n update: (id: string, data: UpdateCampaign) =>\n request<Campaign>('PATCH', `/campaigns/${id}`, data),\n \n delete: (id: string) =>\n request<void>('DELETE', `/campaigns/${id}`),\n \n send: (id: string) =>\n request<Campaign>('POST', `/campaigns/${id}/send`),\n \n pause: (id: string) =>\n request<Campaign>('POST', `/campaigns/${id}/pause`),\n \n resume: (id: string) =>\n request<Campaign>('POST', `/campaigns/${id}/resume`),\n \n stats: (id: string) =>\n request<CampaignStats>('GET', `/campaigns/${id}/stats`),\n })\n\n","import type {\n RequestFn,\n Template,\n CreateTemplate,\n UpdateTemplate,\n ListParams,\n PaginatedResponse,\n} from '../types'\n\nexport interface TemplatesResource {\n readonly list: (params?: ListParams) => Promise<PaginatedResponse<Template>>\n readonly create: (data: CreateTemplate) => Promise<Template>\n readonly get: (id: string) => Promise<Template>\n readonly update: (id: string, data: UpdateTemplate) => Promise<Template>\n readonly delete: (id: string) => Promise<void>\n}\n\nexport const createTemplatesResource = (request: RequestFn): TemplatesResource =>\n Object.freeze({\n list: (params?: ListParams) =>\n request<PaginatedResponse<Template>>('GET', '/templates', params),\n \n create: (data: CreateTemplate) =>\n request<Template>('POST', '/templates', data),\n \n get: (id: string) =>\n request<Template>('GET', `/templates/${id}`),\n \n update: (id: string, data: UpdateTemplate) =>\n request<Template>('PATCH', `/templates/${id}`, data),\n \n delete: (id: string) =>\n request<void>('DELETE', `/templates/${id}`),\n })\n\n","import type { RequestFn, SendNotification, SendResult } from '../types'\n\nexport interface NotificationsResource {\n readonly send: (data: SendNotification) => Promise<SendResult>\n}\n\nexport const createNotificationsResource = (request: RequestFn): NotificationsResource =>\n Object.freeze({\n send: (data: SendNotification) =>\n request<SendResult>('POST', '/send', data),\n })\n\n","import type { PusharyConfig, RequestContext } from './types'\nimport { createRequest } from './request'\nimport { createSubscribersResource, type SubscribersResource } from './resources/subscribers'\nimport { createCampaignsResource, type CampaignsResource } from './resources/campaigns'\nimport { createTemplatesResource, type TemplatesResource } from './resources/templates'\nimport { createNotificationsResource, type NotificationsResource } from './resources/notifications'\n\nconst DEFAULT_BASE_URL = 'https://pushary.com/api/v1/server'\n\nexport interface PusharyServer {\n readonly subscribers: SubscribersResource\n readonly campaigns: CampaignsResource\n readonly templates: TemplatesResource\n readonly notifications: NotificationsResource\n}\n\nconst validateApiKey = (apiKey: string): void => {\n if (!apiKey) {\n throw new Error('API key is required. Get your API key from https://pushary.com/dashboard/settings')\n }\n \n if (!apiKey.includes('.')) {\n throw new Error('Invalid API key format. Use the full API key (pk_xxx.sk_xxx)')\n }\n}\n\nconst createContext = (config: PusharyConfig): RequestContext => {\n validateApiKey(config.apiKey)\n \n return Object.freeze({\n baseUrl: config.baseUrl ?? DEFAULT_BASE_URL,\n headers: Object.freeze({\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${config.apiKey}`,\n }),\n })\n}\n\nexport const createPusharyServer = (config: PusharyConfig): PusharyServer => {\n const ctx = createContext(config)\n const request = createRequest(ctx)\n \n return Object.freeze({\n subscribers: createSubscribersResource(request),\n campaigns: createCampaignsResource(request),\n templates: createTemplatesResource(request),\n notifications: createNotificationsResource(request),\n })\n}\n\n"],"mappings":"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","names":[]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
interface PusharyConfig {
|
|
2
|
+
readonly apiKey: string;
|
|
3
|
+
readonly baseUrl?: string;
|
|
4
|
+
}
|
|
5
|
+
interface ListParams {
|
|
6
|
+
readonly limit?: number;
|
|
7
|
+
readonly cursor?: string;
|
|
8
|
+
}
|
|
9
|
+
interface PaginatedResponse<T> {
|
|
10
|
+
readonly data: readonly T[];
|
|
11
|
+
readonly nextCursor?: string;
|
|
12
|
+
readonly hasMore: boolean;
|
|
13
|
+
}
|
|
14
|
+
interface Subscriber {
|
|
15
|
+
readonly id: string;
|
|
16
|
+
readonly siteId: string;
|
|
17
|
+
readonly endpoint: string;
|
|
18
|
+
readonly status: 'active' | 'unsubscribed' | 'expired' | 'bounced';
|
|
19
|
+
readonly browser?: string;
|
|
20
|
+
readonly os?: string;
|
|
21
|
+
readonly deviceType?: string;
|
|
22
|
+
readonly country?: string;
|
|
23
|
+
readonly city?: string;
|
|
24
|
+
readonly timezone?: string;
|
|
25
|
+
readonly language?: string;
|
|
26
|
+
readonly tags?: readonly string[];
|
|
27
|
+
readonly externalId?: string;
|
|
28
|
+
readonly createdAt: string;
|
|
29
|
+
readonly lastActiveAt?: string;
|
|
30
|
+
}
|
|
31
|
+
interface SubscriberListParams extends ListParams {
|
|
32
|
+
readonly status?: 'active' | 'unsubscribed' | 'expired' | 'bounced';
|
|
33
|
+
readonly tags?: readonly string[];
|
|
34
|
+
readonly externalId?: string;
|
|
35
|
+
}
|
|
36
|
+
interface UpdateSubscriber {
|
|
37
|
+
readonly tags?: readonly string[];
|
|
38
|
+
readonly externalId?: string;
|
|
39
|
+
readonly customData?: Readonly<Record<string, unknown>>;
|
|
40
|
+
}
|
|
41
|
+
interface Campaign {
|
|
42
|
+
readonly id: string;
|
|
43
|
+
readonly siteId: string;
|
|
44
|
+
readonly name: string;
|
|
45
|
+
readonly title: string;
|
|
46
|
+
readonly body: string;
|
|
47
|
+
readonly iconUrl?: string;
|
|
48
|
+
readonly imageUrl?: string;
|
|
49
|
+
readonly actionUrl?: string;
|
|
50
|
+
readonly status: 'draft' | 'scheduled' | 'sending' | 'active' | 'paused' | 'completed' | 'cancelled';
|
|
51
|
+
readonly scheduledAt?: string;
|
|
52
|
+
readonly totalTargeted: number;
|
|
53
|
+
readonly totalSent: number;
|
|
54
|
+
readonly totalDelivered: number;
|
|
55
|
+
readonly totalClicked: number;
|
|
56
|
+
readonly createdAt: string;
|
|
57
|
+
}
|
|
58
|
+
interface CreateCampaign {
|
|
59
|
+
readonly name: string;
|
|
60
|
+
readonly title: string;
|
|
61
|
+
readonly body: string;
|
|
62
|
+
readonly iconUrl?: string;
|
|
63
|
+
readonly imageUrl?: string;
|
|
64
|
+
readonly actionUrl?: string;
|
|
65
|
+
readonly scheduledAt?: string;
|
|
66
|
+
readonly segmentId?: string;
|
|
67
|
+
readonly tags?: readonly string[];
|
|
68
|
+
}
|
|
69
|
+
interface UpdateCampaign {
|
|
70
|
+
readonly name?: string;
|
|
71
|
+
readonly title?: string;
|
|
72
|
+
readonly body?: string;
|
|
73
|
+
readonly iconUrl?: string;
|
|
74
|
+
readonly imageUrl?: string;
|
|
75
|
+
readonly actionUrl?: string;
|
|
76
|
+
readonly scheduledAt?: string;
|
|
77
|
+
readonly status?: 'draft' | 'paused' | 'cancelled';
|
|
78
|
+
}
|
|
79
|
+
interface Template {
|
|
80
|
+
readonly id: string;
|
|
81
|
+
readonly siteId: string;
|
|
82
|
+
readonly name: string;
|
|
83
|
+
readonly title: string;
|
|
84
|
+
readonly body: string;
|
|
85
|
+
readonly iconUrl?: string;
|
|
86
|
+
readonly imageUrl?: string;
|
|
87
|
+
readonly actionUrl?: string;
|
|
88
|
+
readonly createdAt: string;
|
|
89
|
+
}
|
|
90
|
+
interface CreateTemplate {
|
|
91
|
+
readonly name: string;
|
|
92
|
+
readonly title: string;
|
|
93
|
+
readonly body: string;
|
|
94
|
+
readonly iconUrl?: string;
|
|
95
|
+
readonly imageUrl?: string;
|
|
96
|
+
readonly actionUrl?: string;
|
|
97
|
+
}
|
|
98
|
+
interface UpdateTemplate {
|
|
99
|
+
readonly name?: string;
|
|
100
|
+
readonly title?: string;
|
|
101
|
+
readonly body?: string;
|
|
102
|
+
readonly iconUrl?: string;
|
|
103
|
+
readonly imageUrl?: string;
|
|
104
|
+
readonly actionUrl?: string;
|
|
105
|
+
}
|
|
106
|
+
interface SendNotification {
|
|
107
|
+
readonly title: string;
|
|
108
|
+
readonly body: string;
|
|
109
|
+
readonly iconUrl?: string;
|
|
110
|
+
readonly imageUrl?: string;
|
|
111
|
+
readonly url?: string;
|
|
112
|
+
readonly subscriberIds?: readonly string[];
|
|
113
|
+
readonly externalIds?: readonly string[];
|
|
114
|
+
readonly tags?: readonly string[];
|
|
115
|
+
readonly data?: Readonly<Record<string, unknown>>;
|
|
116
|
+
}
|
|
117
|
+
interface SendResult {
|
|
118
|
+
readonly success: boolean;
|
|
119
|
+
readonly campaignId?: string;
|
|
120
|
+
readonly sent: number;
|
|
121
|
+
readonly limits: {
|
|
122
|
+
readonly remaining: number;
|
|
123
|
+
readonly limit: number;
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
interface SubscriberCount {
|
|
127
|
+
readonly total: number;
|
|
128
|
+
readonly active: number;
|
|
129
|
+
readonly unsubscribed: number;
|
|
130
|
+
}
|
|
131
|
+
interface CampaignStats {
|
|
132
|
+
readonly totalSent: number;
|
|
133
|
+
readonly totalDelivered: number;
|
|
134
|
+
readonly totalClicked: number;
|
|
135
|
+
readonly totalFailed: number;
|
|
136
|
+
readonly deliveryRate: number;
|
|
137
|
+
readonly clickRate: number;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
interface SubscribersResource {
|
|
141
|
+
readonly list: (params?: SubscriberListParams) => Promise<PaginatedResponse<Subscriber>>;
|
|
142
|
+
readonly get: (id: string) => Promise<Subscriber>;
|
|
143
|
+
readonly update: (id: string, data: UpdateSubscriber) => Promise<Subscriber>;
|
|
144
|
+
readonly delete: (id: string) => Promise<void>;
|
|
145
|
+
readonly count: () => Promise<SubscriberCount>;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
interface CampaignsResource {
|
|
149
|
+
readonly list: (params?: ListParams) => Promise<PaginatedResponse<Campaign>>;
|
|
150
|
+
readonly create: (data: CreateCampaign) => Promise<Campaign>;
|
|
151
|
+
readonly get: (id: string) => Promise<Campaign>;
|
|
152
|
+
readonly update: (id: string, data: UpdateCampaign) => Promise<Campaign>;
|
|
153
|
+
readonly delete: (id: string) => Promise<void>;
|
|
154
|
+
readonly send: (id: string) => Promise<Campaign>;
|
|
155
|
+
readonly pause: (id: string) => Promise<Campaign>;
|
|
156
|
+
readonly resume: (id: string) => Promise<Campaign>;
|
|
157
|
+
readonly stats: (id: string) => Promise<CampaignStats>;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
interface TemplatesResource {
|
|
161
|
+
readonly list: (params?: ListParams) => Promise<PaginatedResponse<Template>>;
|
|
162
|
+
readonly create: (data: CreateTemplate) => Promise<Template>;
|
|
163
|
+
readonly get: (id: string) => Promise<Template>;
|
|
164
|
+
readonly update: (id: string, data: UpdateTemplate) => Promise<Template>;
|
|
165
|
+
readonly delete: (id: string) => Promise<void>;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
interface NotificationsResource {
|
|
169
|
+
readonly send: (data: SendNotification) => Promise<SendResult>;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
interface PusharyServer {
|
|
173
|
+
readonly subscribers: SubscribersResource;
|
|
174
|
+
readonly campaigns: CampaignsResource;
|
|
175
|
+
readonly templates: TemplatesResource;
|
|
176
|
+
readonly notifications: NotificationsResource;
|
|
177
|
+
}
|
|
178
|
+
declare const createPusharyServer: (config: PusharyConfig) => PusharyServer;
|
|
179
|
+
|
|
180
|
+
export { type Campaign, type CampaignStats, type CampaignsResource, type CreateCampaign, type CreateTemplate, type ListParams, type NotificationsResource, type PaginatedResponse, type PusharyConfig, type PusharyServer, type SendNotification, type SendResult, type Subscriber, type SubscriberCount, type SubscriberListParams, type SubscribersResource, type Template, type TemplatesResource, type UpdateCampaign, type UpdateSubscriber, type UpdateTemplate, createPusharyServer };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
interface PusharyConfig {
|
|
2
|
+
readonly apiKey: string;
|
|
3
|
+
readonly baseUrl?: string;
|
|
4
|
+
}
|
|
5
|
+
interface ListParams {
|
|
6
|
+
readonly limit?: number;
|
|
7
|
+
readonly cursor?: string;
|
|
8
|
+
}
|
|
9
|
+
interface PaginatedResponse<T> {
|
|
10
|
+
readonly data: readonly T[];
|
|
11
|
+
readonly nextCursor?: string;
|
|
12
|
+
readonly hasMore: boolean;
|
|
13
|
+
}
|
|
14
|
+
interface Subscriber {
|
|
15
|
+
readonly id: string;
|
|
16
|
+
readonly siteId: string;
|
|
17
|
+
readonly endpoint: string;
|
|
18
|
+
readonly status: 'active' | 'unsubscribed' | 'expired' | 'bounced';
|
|
19
|
+
readonly browser?: string;
|
|
20
|
+
readonly os?: string;
|
|
21
|
+
readonly deviceType?: string;
|
|
22
|
+
readonly country?: string;
|
|
23
|
+
readonly city?: string;
|
|
24
|
+
readonly timezone?: string;
|
|
25
|
+
readonly language?: string;
|
|
26
|
+
readonly tags?: readonly string[];
|
|
27
|
+
readonly externalId?: string;
|
|
28
|
+
readonly createdAt: string;
|
|
29
|
+
readonly lastActiveAt?: string;
|
|
30
|
+
}
|
|
31
|
+
interface SubscriberListParams extends ListParams {
|
|
32
|
+
readonly status?: 'active' | 'unsubscribed' | 'expired' | 'bounced';
|
|
33
|
+
readonly tags?: readonly string[];
|
|
34
|
+
readonly externalId?: string;
|
|
35
|
+
}
|
|
36
|
+
interface UpdateSubscriber {
|
|
37
|
+
readonly tags?: readonly string[];
|
|
38
|
+
readonly externalId?: string;
|
|
39
|
+
readonly customData?: Readonly<Record<string, unknown>>;
|
|
40
|
+
}
|
|
41
|
+
interface Campaign {
|
|
42
|
+
readonly id: string;
|
|
43
|
+
readonly siteId: string;
|
|
44
|
+
readonly name: string;
|
|
45
|
+
readonly title: string;
|
|
46
|
+
readonly body: string;
|
|
47
|
+
readonly iconUrl?: string;
|
|
48
|
+
readonly imageUrl?: string;
|
|
49
|
+
readonly actionUrl?: string;
|
|
50
|
+
readonly status: 'draft' | 'scheduled' | 'sending' | 'active' | 'paused' | 'completed' | 'cancelled';
|
|
51
|
+
readonly scheduledAt?: string;
|
|
52
|
+
readonly totalTargeted: number;
|
|
53
|
+
readonly totalSent: number;
|
|
54
|
+
readonly totalDelivered: number;
|
|
55
|
+
readonly totalClicked: number;
|
|
56
|
+
readonly createdAt: string;
|
|
57
|
+
}
|
|
58
|
+
interface CreateCampaign {
|
|
59
|
+
readonly name: string;
|
|
60
|
+
readonly title: string;
|
|
61
|
+
readonly body: string;
|
|
62
|
+
readonly iconUrl?: string;
|
|
63
|
+
readonly imageUrl?: string;
|
|
64
|
+
readonly actionUrl?: string;
|
|
65
|
+
readonly scheduledAt?: string;
|
|
66
|
+
readonly segmentId?: string;
|
|
67
|
+
readonly tags?: readonly string[];
|
|
68
|
+
}
|
|
69
|
+
interface UpdateCampaign {
|
|
70
|
+
readonly name?: string;
|
|
71
|
+
readonly title?: string;
|
|
72
|
+
readonly body?: string;
|
|
73
|
+
readonly iconUrl?: string;
|
|
74
|
+
readonly imageUrl?: string;
|
|
75
|
+
readonly actionUrl?: string;
|
|
76
|
+
readonly scheduledAt?: string;
|
|
77
|
+
readonly status?: 'draft' | 'paused' | 'cancelled';
|
|
78
|
+
}
|
|
79
|
+
interface Template {
|
|
80
|
+
readonly id: string;
|
|
81
|
+
readonly siteId: string;
|
|
82
|
+
readonly name: string;
|
|
83
|
+
readonly title: string;
|
|
84
|
+
readonly body: string;
|
|
85
|
+
readonly iconUrl?: string;
|
|
86
|
+
readonly imageUrl?: string;
|
|
87
|
+
readonly actionUrl?: string;
|
|
88
|
+
readonly createdAt: string;
|
|
89
|
+
}
|
|
90
|
+
interface CreateTemplate {
|
|
91
|
+
readonly name: string;
|
|
92
|
+
readonly title: string;
|
|
93
|
+
readonly body: string;
|
|
94
|
+
readonly iconUrl?: string;
|
|
95
|
+
readonly imageUrl?: string;
|
|
96
|
+
readonly actionUrl?: string;
|
|
97
|
+
}
|
|
98
|
+
interface UpdateTemplate {
|
|
99
|
+
readonly name?: string;
|
|
100
|
+
readonly title?: string;
|
|
101
|
+
readonly body?: string;
|
|
102
|
+
readonly iconUrl?: string;
|
|
103
|
+
readonly imageUrl?: string;
|
|
104
|
+
readonly actionUrl?: string;
|
|
105
|
+
}
|
|
106
|
+
interface SendNotification {
|
|
107
|
+
readonly title: string;
|
|
108
|
+
readonly body: string;
|
|
109
|
+
readonly iconUrl?: string;
|
|
110
|
+
readonly imageUrl?: string;
|
|
111
|
+
readonly url?: string;
|
|
112
|
+
readonly subscriberIds?: readonly string[];
|
|
113
|
+
readonly externalIds?: readonly string[];
|
|
114
|
+
readonly tags?: readonly string[];
|
|
115
|
+
readonly data?: Readonly<Record<string, unknown>>;
|
|
116
|
+
}
|
|
117
|
+
interface SendResult {
|
|
118
|
+
readonly success: boolean;
|
|
119
|
+
readonly campaignId?: string;
|
|
120
|
+
readonly sent: number;
|
|
121
|
+
readonly limits: {
|
|
122
|
+
readonly remaining: number;
|
|
123
|
+
readonly limit: number;
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
interface SubscriberCount {
|
|
127
|
+
readonly total: number;
|
|
128
|
+
readonly active: number;
|
|
129
|
+
readonly unsubscribed: number;
|
|
130
|
+
}
|
|
131
|
+
interface CampaignStats {
|
|
132
|
+
readonly totalSent: number;
|
|
133
|
+
readonly totalDelivered: number;
|
|
134
|
+
readonly totalClicked: number;
|
|
135
|
+
readonly totalFailed: number;
|
|
136
|
+
readonly deliveryRate: number;
|
|
137
|
+
readonly clickRate: number;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
interface SubscribersResource {
|
|
141
|
+
readonly list: (params?: SubscriberListParams) => Promise<PaginatedResponse<Subscriber>>;
|
|
142
|
+
readonly get: (id: string) => Promise<Subscriber>;
|
|
143
|
+
readonly update: (id: string, data: UpdateSubscriber) => Promise<Subscriber>;
|
|
144
|
+
readonly delete: (id: string) => Promise<void>;
|
|
145
|
+
readonly count: () => Promise<SubscriberCount>;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
interface CampaignsResource {
|
|
149
|
+
readonly list: (params?: ListParams) => Promise<PaginatedResponse<Campaign>>;
|
|
150
|
+
readonly create: (data: CreateCampaign) => Promise<Campaign>;
|
|
151
|
+
readonly get: (id: string) => Promise<Campaign>;
|
|
152
|
+
readonly update: (id: string, data: UpdateCampaign) => Promise<Campaign>;
|
|
153
|
+
readonly delete: (id: string) => Promise<void>;
|
|
154
|
+
readonly send: (id: string) => Promise<Campaign>;
|
|
155
|
+
readonly pause: (id: string) => Promise<Campaign>;
|
|
156
|
+
readonly resume: (id: string) => Promise<Campaign>;
|
|
157
|
+
readonly stats: (id: string) => Promise<CampaignStats>;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
interface TemplatesResource {
|
|
161
|
+
readonly list: (params?: ListParams) => Promise<PaginatedResponse<Template>>;
|
|
162
|
+
readonly create: (data: CreateTemplate) => Promise<Template>;
|
|
163
|
+
readonly get: (id: string) => Promise<Template>;
|
|
164
|
+
readonly update: (id: string, data: UpdateTemplate) => Promise<Template>;
|
|
165
|
+
readonly delete: (id: string) => Promise<void>;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
interface NotificationsResource {
|
|
169
|
+
readonly send: (data: SendNotification) => Promise<SendResult>;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
interface PusharyServer {
|
|
173
|
+
readonly subscribers: SubscribersResource;
|
|
174
|
+
readonly campaigns: CampaignsResource;
|
|
175
|
+
readonly templates: TemplatesResource;
|
|
176
|
+
readonly notifications: NotificationsResource;
|
|
177
|
+
}
|
|
178
|
+
declare const createPusharyServer: (config: PusharyConfig) => PusharyServer;
|
|
179
|
+
|
|
180
|
+
export { type Campaign, type CampaignStats, type CampaignsResource, type CreateCampaign, type CreateTemplate, type ListParams, type NotificationsResource, type PaginatedResponse, type PusharyConfig, type PusharyServer, type SendNotification, type SendResult, type Subscriber, type SubscriberCount, type SubscriberListParams, type SubscribersResource, type Template, type TemplatesResource, type UpdateCampaign, type UpdateSubscriber, type UpdateTemplate, createPusharyServer };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
// src/request.ts
|
|
2
|
+
var buildUrl = (baseUrl, path, params) => {
|
|
3
|
+
const url = new URL(path, baseUrl);
|
|
4
|
+
if (params) {
|
|
5
|
+
Object.entries(params).forEach(([key, value]) => {
|
|
6
|
+
if (value !== void 0 && value !== null) {
|
|
7
|
+
url.searchParams.set(key, String(value));
|
|
8
|
+
}
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
return url.toString();
|
|
12
|
+
};
|
|
13
|
+
var handleResponse = async (response) => {
|
|
14
|
+
if (!response.ok) {
|
|
15
|
+
const error = await response.json().catch(() => ({ message: "Request failed" }));
|
|
16
|
+
throw new Error(error.message || `HTTP ${response.status}`);
|
|
17
|
+
}
|
|
18
|
+
return response.json();
|
|
19
|
+
};
|
|
20
|
+
var createRequest = (ctx) => async (method, path, body) => {
|
|
21
|
+
const isGet = method === "GET";
|
|
22
|
+
const url = isGet && body ? buildUrl(ctx.baseUrl, path, body) : `${ctx.baseUrl}${path}`;
|
|
23
|
+
const response = await fetch(url, {
|
|
24
|
+
method,
|
|
25
|
+
headers: ctx.headers,
|
|
26
|
+
body: !isGet && body ? JSON.stringify(body) : void 0
|
|
27
|
+
});
|
|
28
|
+
return handleResponse(response);
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
// src/resources/subscribers.ts
|
|
32
|
+
var createSubscribersResource = (request) => Object.freeze({
|
|
33
|
+
list: (params) => request("GET", "/subscribers", params),
|
|
34
|
+
get: (id) => request("GET", `/subscribers/${id}`),
|
|
35
|
+
update: (id, data) => request("PATCH", `/subscribers/${id}`, data),
|
|
36
|
+
delete: (id) => request("DELETE", `/subscribers/${id}`),
|
|
37
|
+
count: () => request("GET", "/subscribers/count")
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
// src/resources/campaigns.ts
|
|
41
|
+
var createCampaignsResource = (request) => Object.freeze({
|
|
42
|
+
list: (params) => request("GET", "/campaigns", params),
|
|
43
|
+
create: (data) => request("POST", "/campaigns", data),
|
|
44
|
+
get: (id) => request("GET", `/campaigns/${id}`),
|
|
45
|
+
update: (id, data) => request("PATCH", `/campaigns/${id}`, data),
|
|
46
|
+
delete: (id) => request("DELETE", `/campaigns/${id}`),
|
|
47
|
+
send: (id) => request("POST", `/campaigns/${id}/send`),
|
|
48
|
+
pause: (id) => request("POST", `/campaigns/${id}/pause`),
|
|
49
|
+
resume: (id) => request("POST", `/campaigns/${id}/resume`),
|
|
50
|
+
stats: (id) => request("GET", `/campaigns/${id}/stats`)
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
// src/resources/templates.ts
|
|
54
|
+
var createTemplatesResource = (request) => Object.freeze({
|
|
55
|
+
list: (params) => request("GET", "/templates", params),
|
|
56
|
+
create: (data) => request("POST", "/templates", data),
|
|
57
|
+
get: (id) => request("GET", `/templates/${id}`),
|
|
58
|
+
update: (id, data) => request("PATCH", `/templates/${id}`, data),
|
|
59
|
+
delete: (id) => request("DELETE", `/templates/${id}`)
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
// src/resources/notifications.ts
|
|
63
|
+
var createNotificationsResource = (request) => Object.freeze({
|
|
64
|
+
send: (data) => request("POST", "/send", data)
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
// src/client.ts
|
|
68
|
+
var DEFAULT_BASE_URL = "https://pushary.com/api/v1/server";
|
|
69
|
+
var validateApiKey = (apiKey) => {
|
|
70
|
+
if (!apiKey) {
|
|
71
|
+
throw new Error("API key is required. Get your API key from https://pushary.com/dashboard/settings");
|
|
72
|
+
}
|
|
73
|
+
if (!apiKey.includes(".")) {
|
|
74
|
+
throw new Error("Invalid API key format. Use the full API key (pk_xxx.sk_xxx)");
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
var createContext = (config) => {
|
|
78
|
+
validateApiKey(config.apiKey);
|
|
79
|
+
return Object.freeze({
|
|
80
|
+
baseUrl: config.baseUrl ?? DEFAULT_BASE_URL,
|
|
81
|
+
headers: Object.freeze({
|
|
82
|
+
"Content-Type": "application/json",
|
|
83
|
+
"Authorization": `Bearer ${config.apiKey}`
|
|
84
|
+
})
|
|
85
|
+
});
|
|
86
|
+
};
|
|
87
|
+
var createPusharyServer = (config) => {
|
|
88
|
+
const ctx = createContext(config);
|
|
89
|
+
const request = createRequest(ctx);
|
|
90
|
+
return Object.freeze({
|
|
91
|
+
subscribers: createSubscribersResource(request),
|
|
92
|
+
campaigns: createCampaignsResource(request),
|
|
93
|
+
templates: createTemplatesResource(request),
|
|
94
|
+
notifications: createNotificationsResource(request)
|
|
95
|
+
});
|
|
96
|
+
};
|
|
97
|
+
export {
|
|
98
|
+
createPusharyServer
|
|
99
|
+
};
|
|
100
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/request.ts","../src/resources/subscribers.ts","../src/resources/campaigns.ts","../src/resources/templates.ts","../src/resources/notifications.ts","../src/client.ts"],"sourcesContent":["import type { RequestContext, RequestFn } from './types'\n\nconst buildUrl = (baseUrl: string, path: string, params?: Record<string, unknown>): string => {\n const url = new URL(path, baseUrl)\n \n if (params) {\n Object.entries(params).forEach(([key, value]) => {\n if (value !== undefined && value !== null) {\n url.searchParams.set(key, String(value))\n }\n })\n }\n \n return url.toString()\n}\n\nconst handleResponse = async <T>(response: Response): Promise<T> => {\n if (!response.ok) {\n const error = await response.json().catch(() => ({ message: 'Request failed' }))\n throw new Error(error.message || `HTTP ${response.status}`)\n }\n return response.json() as Promise<T>\n}\n\nexport const createRequest = (ctx: RequestContext): RequestFn =>\n async <T>(method: string, path: string, body?: unknown): Promise<T> => {\n const isGet = method === 'GET'\n const url = isGet && body \n ? buildUrl(ctx.baseUrl, path, body as Record<string, unknown>)\n : `${ctx.baseUrl}${path}`\n \n const response = await fetch(url, {\n method,\n headers: ctx.headers,\n body: !isGet && body ? JSON.stringify(body) : undefined,\n })\n \n return handleResponse<T>(response)\n }\n\n","import type {\n RequestFn,\n Subscriber,\n SubscriberListParams,\n UpdateSubscriber,\n PaginatedResponse,\n SubscriberCount,\n} from '../types'\n\nexport interface SubscribersResource {\n readonly list: (params?: SubscriberListParams) => Promise<PaginatedResponse<Subscriber>>\n readonly get: (id: string) => Promise<Subscriber>\n readonly update: (id: string, data: UpdateSubscriber) => Promise<Subscriber>\n readonly delete: (id: string) => Promise<void>\n readonly count: () => Promise<SubscriberCount>\n}\n\nexport const createSubscribersResource = (request: RequestFn): SubscribersResource =>\n Object.freeze({\n list: (params?: SubscriberListParams) =>\n request<PaginatedResponse<Subscriber>>('GET', '/subscribers', params),\n \n get: (id: string) =>\n request<Subscriber>('GET', `/subscribers/${id}`),\n \n update: (id: string, data: UpdateSubscriber) =>\n request<Subscriber>('PATCH', `/subscribers/${id}`, data),\n \n delete: (id: string) =>\n request<void>('DELETE', `/subscribers/${id}`),\n \n count: () =>\n request<SubscriberCount>('GET', '/subscribers/count'),\n })\n\n","import type {\n RequestFn,\n Campaign,\n CreateCampaign,\n UpdateCampaign,\n ListParams,\n PaginatedResponse,\n CampaignStats,\n} from '../types'\n\nexport interface CampaignsResource {\n readonly list: (params?: ListParams) => Promise<PaginatedResponse<Campaign>>\n readonly create: (data: CreateCampaign) => Promise<Campaign>\n readonly get: (id: string) => Promise<Campaign>\n readonly update: (id: string, data: UpdateCampaign) => Promise<Campaign>\n readonly delete: (id: string) => Promise<void>\n readonly send: (id: string) => Promise<Campaign>\n readonly pause: (id: string) => Promise<Campaign>\n readonly resume: (id: string) => Promise<Campaign>\n readonly stats: (id: string) => Promise<CampaignStats>\n}\n\nexport const createCampaignsResource = (request: RequestFn): CampaignsResource =>\n Object.freeze({\n list: (params?: ListParams) =>\n request<PaginatedResponse<Campaign>>('GET', '/campaigns', params),\n \n create: (data: CreateCampaign) =>\n request<Campaign>('POST', '/campaigns', data),\n \n get: (id: string) =>\n request<Campaign>('GET', `/campaigns/${id}`),\n \n update: (id: string, data: UpdateCampaign) =>\n request<Campaign>('PATCH', `/campaigns/${id}`, data),\n \n delete: (id: string) =>\n request<void>('DELETE', `/campaigns/${id}`),\n \n send: (id: string) =>\n request<Campaign>('POST', `/campaigns/${id}/send`),\n \n pause: (id: string) =>\n request<Campaign>('POST', `/campaigns/${id}/pause`),\n \n resume: (id: string) =>\n request<Campaign>('POST', `/campaigns/${id}/resume`),\n \n stats: (id: string) =>\n request<CampaignStats>('GET', `/campaigns/${id}/stats`),\n })\n\n","import type {\n RequestFn,\n Template,\n CreateTemplate,\n UpdateTemplate,\n ListParams,\n PaginatedResponse,\n} from '../types'\n\nexport interface TemplatesResource {\n readonly list: (params?: ListParams) => Promise<PaginatedResponse<Template>>\n readonly create: (data: CreateTemplate) => Promise<Template>\n readonly get: (id: string) => Promise<Template>\n readonly update: (id: string, data: UpdateTemplate) => Promise<Template>\n readonly delete: (id: string) => Promise<void>\n}\n\nexport const createTemplatesResource = (request: RequestFn): TemplatesResource =>\n Object.freeze({\n list: (params?: ListParams) =>\n request<PaginatedResponse<Template>>('GET', '/templates', params),\n \n create: (data: CreateTemplate) =>\n request<Template>('POST', '/templates', data),\n \n get: (id: string) =>\n request<Template>('GET', `/templates/${id}`),\n \n update: (id: string, data: UpdateTemplate) =>\n request<Template>('PATCH', `/templates/${id}`, data),\n \n delete: (id: string) =>\n request<void>('DELETE', `/templates/${id}`),\n })\n\n","import type { RequestFn, SendNotification, SendResult } from '../types'\n\nexport interface NotificationsResource {\n readonly send: (data: SendNotification) => Promise<SendResult>\n}\n\nexport const createNotificationsResource = (request: RequestFn): NotificationsResource =>\n Object.freeze({\n send: (data: SendNotification) =>\n request<SendResult>('POST', '/send', data),\n })\n\n","import type { PusharyConfig, RequestContext } from './types'\nimport { createRequest } from './request'\nimport { createSubscribersResource, type SubscribersResource } from './resources/subscribers'\nimport { createCampaignsResource, type CampaignsResource } from './resources/campaigns'\nimport { createTemplatesResource, type TemplatesResource } from './resources/templates'\nimport { createNotificationsResource, type NotificationsResource } from './resources/notifications'\n\nconst DEFAULT_BASE_URL = 'https://pushary.com/api/v1/server'\n\nexport interface PusharyServer {\n readonly subscribers: SubscribersResource\n readonly campaigns: CampaignsResource\n readonly templates: TemplatesResource\n readonly notifications: NotificationsResource\n}\n\nconst validateApiKey = (apiKey: string): void => {\n if (!apiKey) {\n throw new Error('API key is required. Get your API key from https://pushary.com/dashboard/settings')\n }\n \n if (!apiKey.includes('.')) {\n throw new Error('Invalid API key format. Use the full API key (pk_xxx.sk_xxx)')\n }\n}\n\nconst createContext = (config: PusharyConfig): RequestContext => {\n validateApiKey(config.apiKey)\n \n return Object.freeze({\n baseUrl: config.baseUrl ?? DEFAULT_BASE_URL,\n headers: Object.freeze({\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${config.apiKey}`,\n }),\n })\n}\n\nexport const createPusharyServer = (config: PusharyConfig): PusharyServer => {\n const ctx = createContext(config)\n const request = createRequest(ctx)\n \n return Object.freeze({\n subscribers: createSubscribersResource(request),\n campaigns: createCampaignsResource(request),\n templates: createTemplatesResource(request),\n notifications: createNotificationsResource(request),\n })\n}\n\n"],"mappings":"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","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@pushary/server",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Pushary Server SDK - Manage subscribers, campaigns, templates, and send notifications",
|
|
5
|
+
"author": "Pushary <business@ralphnex.com>",
|
|
6
|
+
"homepage": "https://pushary.com",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/pushary/pushary.git",
|
|
10
|
+
"directory": "packages/server"
|
|
11
|
+
},
|
|
12
|
+
"license": "MIT",
|
|
13
|
+
"type": "module",
|
|
14
|
+
"main": "./dist/index.cjs",
|
|
15
|
+
"module": "./dist/index.js",
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"exports": {
|
|
18
|
+
".": {
|
|
19
|
+
"types": "./dist/index.d.ts",
|
|
20
|
+
"import": "./dist/index.js",
|
|
21
|
+
"require": "./dist/index.cjs"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"files": [
|
|
25
|
+
"dist",
|
|
26
|
+
"README.md",
|
|
27
|
+
"LICENSE"
|
|
28
|
+
],
|
|
29
|
+
"sideEffects": false,
|
|
30
|
+
"engines": {
|
|
31
|
+
"node": ">=18"
|
|
32
|
+
},
|
|
33
|
+
"scripts": {
|
|
34
|
+
"build": "tsup",
|
|
35
|
+
"dev": "tsup --watch",
|
|
36
|
+
"typecheck": "tsc --noEmit",
|
|
37
|
+
"clean": "rm -rf dist",
|
|
38
|
+
"prepublishOnly": "npm run build && npm run typecheck"
|
|
39
|
+
},
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"tsup": "^8.0.0",
|
|
42
|
+
"typescript": "^5.0.0"
|
|
43
|
+
},
|
|
44
|
+
"publishConfig": {
|
|
45
|
+
"access": "public"
|
|
46
|
+
},
|
|
47
|
+
"keywords": [
|
|
48
|
+
"pushary",
|
|
49
|
+
"push-notifications",
|
|
50
|
+
"web-push",
|
|
51
|
+
"notifications",
|
|
52
|
+
"server-sdk",
|
|
53
|
+
"api-client"
|
|
54
|
+
]
|
|
55
|
+
}
|
|
56
|
+
|