@geekapps/post-nextjs 0.1.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/dist/client.d.ts +31 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +29 -0
- package/dist/client.js.map +1 -0
- package/dist/errors.d.ts +11 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +14 -0
- package/dist/errors.js.map +1 -0
- package/dist/http.d.ts +25 -0
- package/dist/http.d.ts.map +1 -0
- package/dist/http.js +51 -0
- package/dist/http.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/react-exports.d.ts +3 -0
- package/dist/react-exports.d.ts.map +1 -0
- package/dist/react-exports.js +3 -0
- package/dist/react-exports.js.map +1 -0
- package/dist/react.d.ts +12 -0
- package/dist/react.d.ts.map +1 -0
- package/dist/react.js +22 -0
- package/dist/react.js.map +1 -0
- package/dist/resources/domains.d.ts +14 -0
- package/dist/resources/domains.d.ts.map +1 -0
- package/dist/resources/domains.js +21 -0
- package/dist/resources/domains.js.map +1 -0
- package/dist/resources/history.d.ts +9 -0
- package/dist/resources/history.d.ts.map +1 -0
- package/dist/resources/history.js +26 -0
- package/dist/resources/history.js.map +1 -0
- package/dist/resources/managed-numbers.d.ts +28 -0
- package/dist/resources/managed-numbers.d.ts.map +1 -0
- package/dist/resources/managed-numbers.js +24 -0
- package/dist/resources/managed-numbers.js.map +1 -0
- package/dist/resources/messages.d.ts +8 -0
- package/dist/resources/messages.d.ts.map +1 -0
- package/dist/resources/messages.js +9 -0
- package/dist/resources/messages.js.map +1 -0
- package/dist/resources/plans.d.ts +10 -0
- package/dist/resources/plans.d.ts.map +1 -0
- package/dist/resources/plans.js +15 -0
- package/dist/resources/plans.js.map +1 -0
- package/dist/resources/smtp.d.ts +14 -0
- package/dist/resources/smtp.d.ts.map +1 -0
- package/dist/resources/smtp.js +18 -0
- package/dist/resources/smtp.js.map +1 -0
- package/dist/resources/statistics.d.ts +8 -0
- package/dist/resources/statistics.d.ts.map +1 -0
- package/dist/resources/statistics.js +17 -0
- package/dist/resources/statistics.js.map +1 -0
- package/dist/resources/templates.d.ts +17 -0
- package/dist/resources/templates.d.ts.map +1 -0
- package/dist/resources/templates.js +33 -0
- package/dist/resources/templates.js.map +1 -0
- package/dist/resources/webhooks.d.ts +13 -0
- package/dist/resources/webhooks.d.ts.map +1 -0
- package/dist/resources/webhooks.js +24 -0
- package/dist/resources/webhooks.js.map +1 -0
- package/dist/resources/whatsapp-numbers.d.ts +23 -0
- package/dist/resources/whatsapp-numbers.d.ts.map +1 -0
- package/dist/resources/whatsapp-numbers.js +54 -0
- package/dist/resources/whatsapp-numbers.js.map +1 -0
- package/dist/resources/whatsapp-templates.d.ts +12 -0
- package/dist/resources/whatsapp-templates.d.ts.map +1 -0
- package/dist/resources/whatsapp-templates.js +21 -0
- package/dist/resources/whatsapp-templates.js.map +1 -0
- package/dist/server-exports.d.ts +8 -0
- package/dist/server-exports.d.ts.map +1 -0
- package/dist/server-exports.js +5 -0
- package/dist/server-exports.js.map +1 -0
- package/dist/server.d.ts +21 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +25 -0
- package/dist/server.js.map +1 -0
- package/dist/service-account.d.ts +23 -0
- package/dist/service-account.d.ts.map +1 -0
- package/dist/service-account.js +69 -0
- package/dist/service-account.js.map +1 -0
- package/dist/types.d.ts +346 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/package.json +38 -0
- package/src/client.ts +48 -0
- package/src/errors.ts +16 -0
- package/src/http.ts +75 -0
- package/src/index.ts +76 -0
- package/src/react-exports.ts +4 -0
- package/src/react.ts +38 -0
- package/src/resources/domains.ts +26 -0
- package/src/resources/history.ts +22 -0
- package/src/resources/managed-numbers.ts +47 -0
- package/src/resources/messages.ts +10 -0
- package/src/resources/plans.ts +18 -0
- package/src/resources/smtp.ts +22 -0
- package/src/resources/statistics.ts +15 -0
- package/src/resources/templates.ts +44 -0
- package/src/resources/webhooks.ts +37 -0
- package/src/resources/whatsapp-numbers.ts +80 -0
- package/src/resources/whatsapp-templates.ts +31 -0
- package/src/server-exports.ts +8 -0
- package/src/server.ts +42 -0
- package/src/service-account.ts +97 -0
- package/src/types.ts +418 -0
- package/tsconfig.json +20 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { HttpClient, RequestOptions } from "../http.js";
|
|
2
|
+
import type { CreateDomainInput, CreateDomainResult, OrgDomain } from "../types.js";
|
|
3
|
+
|
|
4
|
+
export class DomainsResource {
|
|
5
|
+
constructor(private readonly http: HttpClient) {}
|
|
6
|
+
|
|
7
|
+
list(opts?: RequestOptions): Promise<OrgDomain[]> {
|
|
8
|
+
return this.http.get<OrgDomain[]>("/domains", opts);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
get(id: string, opts?: RequestOptions): Promise<OrgDomain> {
|
|
12
|
+
return this.http.get<OrgDomain>(`/domains/${id}`, opts);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
create(input: CreateDomainInput, opts?: RequestOptions): Promise<CreateDomainResult> {
|
|
16
|
+
return this.http.post<CreateDomainResult>("/domains", input, opts);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
verify(id: string, opts?: RequestOptions): Promise<{ status: "verified" | "failed" }> {
|
|
20
|
+
return this.http.post<{ status: "verified" | "failed" }>(`/domains/${id}/verify`, undefined, opts);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
delete(id: string, opts?: RequestOptions): Promise<void> {
|
|
24
|
+
return this.http.delete(`/domains/${id}`, opts);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { HttpClient, RequestOptions } from "../http.js";
|
|
2
|
+
import type { ListHistoryParams, MessageLog, MessageLogDetail, PaginatedResult } from "../types.js";
|
|
3
|
+
|
|
4
|
+
export class HistoryResource {
|
|
5
|
+
constructor(private readonly http: HttpClient) {}
|
|
6
|
+
|
|
7
|
+
list(params?: ListHistoryParams, opts?: RequestOptions): Promise<PaginatedResult<MessageLog>> {
|
|
8
|
+
const qs = new URLSearchParams();
|
|
9
|
+
if (params?.type) qs.set("type", params.type);
|
|
10
|
+
if (params?.status) qs.set("status", params.status);
|
|
11
|
+
if (params?.from) qs.set("from", params.from);
|
|
12
|
+
if (params?.to) qs.set("to", params.to);
|
|
13
|
+
if (params?.page !== undefined) qs.set("page", String(params.page));
|
|
14
|
+
if (params?.limit !== undefined) qs.set("limit", String(params.limit));
|
|
15
|
+
const query = qs.toString();
|
|
16
|
+
return this.http.get<PaginatedResult<MessageLog>>(`/history${query ? `?${query}` : ""}`, opts);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
get(id: string, opts?: RequestOptions): Promise<MessageLogDetail> {
|
|
20
|
+
return this.http.get<MessageLogDetail>(`/history/${id}`, opts);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { HttpClient, RequestOptions } from "../http.js";
|
|
2
|
+
import type { AreaCode, ManagedNumber } from "../types.js";
|
|
3
|
+
|
|
4
|
+
export interface ProvisionManagedNumberInput {
|
|
5
|
+
areaCode: number;
|
|
6
|
+
name?: string;
|
|
7
|
+
displayName: string;
|
|
8
|
+
otpMethod?: "SMS" | "VOICE";
|
|
9
|
+
otpLanguage?: string;
|
|
10
|
+
pin?: string;
|
|
11
|
+
orgWabaId?: string;
|
|
12
|
+
wabaId?: string;
|
|
13
|
+
accessToken?: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface RetryVerificationInput {
|
|
17
|
+
otpMethod?: "SMS" | "VOICE";
|
|
18
|
+
otpLanguage?: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export class ManagedNumbersResource {
|
|
22
|
+
constructor(private readonly http: HttpClient) {}
|
|
23
|
+
|
|
24
|
+
listAreaCodes(opts?: RequestOptions): Promise<AreaCode[]> {
|
|
25
|
+
return this.http.get<AreaCode[]>("/managed-numbers/area-codes", opts);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
list(opts?: RequestOptions): Promise<ManagedNumber[]> {
|
|
29
|
+
return this.http.get<ManagedNumber[]>("/managed-numbers", opts);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
get(id: string, opts?: RequestOptions): Promise<ManagedNumber> {
|
|
33
|
+
return this.http.get<ManagedNumber>(`/managed-numbers/${id}`, opts);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
provision(input: ProvisionManagedNumberInput, opts?: RequestOptions): Promise<ManagedNumber> {
|
|
37
|
+
return this.http.post<ManagedNumber>("/managed-numbers", input, opts);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
retryVerification(id: string, input?: RetryVerificationInput, opts?: RequestOptions): Promise<ManagedNumber> {
|
|
41
|
+
return this.http.post<ManagedNumber>(`/managed-numbers/${id}/retry-verification`, input, opts);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
cancel(id: string, opts?: RequestOptions): Promise<ManagedNumber> {
|
|
45
|
+
return this.http.post<ManagedNumber>(`/managed-numbers/${id}/cancel`, undefined, opts);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { HttpClient, RequestOptions } from "../http.js";
|
|
2
|
+
import type { SendMessageInput, SendMessageResult } from "../types.js";
|
|
3
|
+
|
|
4
|
+
export class MessagesResource {
|
|
5
|
+
constructor(private readonly http: HttpClient) {}
|
|
6
|
+
|
|
7
|
+
send(input: SendMessageInput, opts?: RequestOptions): Promise<SendMessageResult> {
|
|
8
|
+
return this.http.post<SendMessageResult>("/messages", input, opts);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { HttpClient, RequestOptions } from "../http.js";
|
|
2
|
+
import type { AvailablePlan, OrgPlan, PlansResult, UpdatePlanInput } from "../types.js";
|
|
3
|
+
|
|
4
|
+
export class PlansResource {
|
|
5
|
+
constructor(private readonly http: HttpClient) {}
|
|
6
|
+
|
|
7
|
+
get(opts?: RequestOptions): Promise<PlansResult> {
|
|
8
|
+
return this.http.get<PlansResult>("/plans", opts);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
update(input: UpdatePlanInput, opts?: RequestOptions): Promise<OrgPlan> {
|
|
12
|
+
return this.http.put<OrgPlan>("/plans", input, opts);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
listAvailable(opts?: RequestOptions): Promise<AvailablePlan[]> {
|
|
16
|
+
return this.http.get<AvailablePlan[]>("/plans/available", opts);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { HttpClient, RequestOptions } from "../http.js";
|
|
2
|
+
import type { SmtpConfig, UpsertSmtpConfigInput } from "../types.js";
|
|
3
|
+
|
|
4
|
+
export class SmtpResource {
|
|
5
|
+
constructor(private readonly http: HttpClient) {}
|
|
6
|
+
|
|
7
|
+
get(opts?: RequestOptions): Promise<SmtpConfig> {
|
|
8
|
+
return this.http.get<SmtpConfig>("/smtp-config", opts);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
upsert(input: UpsertSmtpConfigInput, opts?: RequestOptions): Promise<SmtpConfig> {
|
|
12
|
+
return this.http.put<SmtpConfig>("/smtp-config", input, opts);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
delete(opts?: RequestOptions): Promise<void> {
|
|
16
|
+
return this.http.delete("/smtp-config", opts);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
test(to: string, opts?: RequestOptions): Promise<{ success: boolean; error?: string }> {
|
|
20
|
+
return this.http.post<{ success: boolean; error?: string }>("/smtp-config/test", { to }, opts);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { HttpClient, RequestOptions } from "../http.js";
|
|
2
|
+
import type { StatisticsParams, StatisticsResult } from "../types.js";
|
|
3
|
+
|
|
4
|
+
export class StatisticsResource {
|
|
5
|
+
constructor(private readonly http: HttpClient) {}
|
|
6
|
+
|
|
7
|
+
get(params?: StatisticsParams, opts?: RequestOptions): Promise<StatisticsResult> {
|
|
8
|
+
const qs = new URLSearchParams();
|
|
9
|
+
if (params?.from) qs.set("from", params.from);
|
|
10
|
+
if (params?.to) qs.set("to", params.to);
|
|
11
|
+
if (params?.groupBy) qs.set("groupBy", params.groupBy);
|
|
12
|
+
const query = qs.toString();
|
|
13
|
+
return this.http.get<StatisticsResult>(`/statistics${query ? `?${query}` : ""}`, opts);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { HttpClient, RequestOptions } from "../http.js";
|
|
2
|
+
import type {
|
|
3
|
+
CreateTemplateInput,
|
|
4
|
+
MessageTemplate,
|
|
5
|
+
MessageType,
|
|
6
|
+
SaveDraftInput,
|
|
7
|
+
UpdateTemplateInput,
|
|
8
|
+
} from "../types.js";
|
|
9
|
+
|
|
10
|
+
export class TemplatesResource {
|
|
11
|
+
constructor(private readonly http: HttpClient) {}
|
|
12
|
+
|
|
13
|
+
list(params?: { type?: MessageType; isActive?: boolean }, opts?: RequestOptions): Promise<MessageTemplate[]> {
|
|
14
|
+
const qs = new URLSearchParams();
|
|
15
|
+
if (params?.type) qs.set("type", params.type);
|
|
16
|
+
if (params?.isActive !== undefined) qs.set("isActive", String(params.isActive));
|
|
17
|
+
const query = qs.toString();
|
|
18
|
+
return this.http.get<MessageTemplate[]>(`/templates${query ? `?${query}` : ""}`, opts);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
get(id: string, opts?: RequestOptions): Promise<MessageTemplate> {
|
|
22
|
+
return this.http.get<MessageTemplate>(`/templates/${id}`, opts);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
create(input: CreateTemplateInput, opts?: RequestOptions): Promise<MessageTemplate> {
|
|
26
|
+
return this.http.post<MessageTemplate>("/templates", input, opts);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
update(id: string, input: UpdateTemplateInput, opts?: RequestOptions): Promise<MessageTemplate> {
|
|
30
|
+
return this.http.put<MessageTemplate>(`/templates/${id}`, input, opts);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
saveDraft(id: string, input: SaveDraftInput, opts?: RequestOptions): Promise<MessageTemplate> {
|
|
34
|
+
return this.http.patch<MessageTemplate>(`/templates/${id}/draft`, input, opts);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
publish(id: string, opts?: RequestOptions): Promise<MessageTemplate> {
|
|
38
|
+
return this.http.post<MessageTemplate>(`/templates/${id}/publish`, undefined, opts);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
delete(id: string, opts?: RequestOptions): Promise<void> {
|
|
42
|
+
return this.http.delete(`/templates/${id}`, opts);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { HttpClient, RequestOptions } from "../http.js";
|
|
2
|
+
import type {
|
|
3
|
+
CreateWebhookInput,
|
|
4
|
+
OrgWebhook,
|
|
5
|
+
OrgWebhookWithSecret,
|
|
6
|
+
RotateSecretResult,
|
|
7
|
+
UpdateWebhookInput,
|
|
8
|
+
WebhookDelivery,
|
|
9
|
+
} from "../types.js";
|
|
10
|
+
|
|
11
|
+
export class WebhooksResource {
|
|
12
|
+
constructor(private readonly http: HttpClient) {}
|
|
13
|
+
|
|
14
|
+
list(opts?: RequestOptions): Promise<OrgWebhook[]> {
|
|
15
|
+
return this.http.get<OrgWebhook[]>("/webhooks", opts);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
create(input: CreateWebhookInput, opts?: RequestOptions): Promise<OrgWebhookWithSecret> {
|
|
19
|
+
return this.http.post<OrgWebhookWithSecret>("/webhooks", input, opts);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
update(id: string, input: UpdateWebhookInput, opts?: RequestOptions): Promise<OrgWebhook> {
|
|
23
|
+
return this.http.put<OrgWebhook>(`/webhooks/${id}`, input, opts);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
delete(id: string, opts?: RequestOptions): Promise<void> {
|
|
27
|
+
return this.http.delete(`/webhooks/${id}`, opts);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
listDeliveries(id: string, opts?: RequestOptions): Promise<WebhookDelivery[]> {
|
|
31
|
+
return this.http.get<WebhookDelivery[]>(`/webhooks/${id}/deliveries`, opts);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
rotateSecret(id: string, opts?: RequestOptions): Promise<RotateSecretResult> {
|
|
35
|
+
return this.http.post<RotateSecretResult>(`/webhooks/${id}/rotate-secret`, undefined, opts);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import type { HttpClient, RequestOptions } from "../http.js";
|
|
2
|
+
import type {
|
|
3
|
+
ConnectWabaInput,
|
|
4
|
+
ConnectWhatsappNumberInput,
|
|
5
|
+
OrgWaba,
|
|
6
|
+
PhoneNumberStatusResult,
|
|
7
|
+
RegisterWhatsappNumberInput,
|
|
8
|
+
UpdateWhatsappProfileInput,
|
|
9
|
+
WabaHealthResult,
|
|
10
|
+
WhatsappNumber,
|
|
11
|
+
WhatsappNumberProfile,
|
|
12
|
+
} from "../types.js";
|
|
13
|
+
|
|
14
|
+
export class WhatsappNumbersResource {
|
|
15
|
+
constructor(private readonly http: HttpClient) {}
|
|
16
|
+
|
|
17
|
+
listWabas(opts?: RequestOptions): Promise<OrgWaba[]> {
|
|
18
|
+
return this.http.get<OrgWaba[]>("/whatsapp/wabas", opts);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
connectWaba(input: ConnectWabaInput, opts?: RequestOptions): Promise<OrgWaba> {
|
|
22
|
+
return this.http.post<OrgWaba>("/whatsapp/wabas/connect", input, opts);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
reconnectWaba(id: string, opts?: RequestOptions): Promise<OrgWaba> {
|
|
26
|
+
return this.http.post<OrgWaba>(`/whatsapp/wabas/${id}/reconnect`, undefined, opts);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
disconnectWaba(id: string, opts?: RequestOptions): Promise<void> {
|
|
30
|
+
return this.http.delete(`/whatsapp/wabas/${id}`, opts);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
getWabaHealth(id: string, opts?: RequestOptions): Promise<WabaHealthResult> {
|
|
34
|
+
return this.http.get<WabaHealthResult>(`/whatsapp/wabas/${id}/health`, opts);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
listNumbers(opts?: RequestOptions): Promise<WhatsappNumber[]> {
|
|
38
|
+
return this.http.get<WhatsappNumber[]>("/whatsapp/numbers", opts);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
connectNumber(input: ConnectWhatsappNumberInput, opts?: RequestOptions): Promise<WhatsappNumber> {
|
|
42
|
+
return this.http.post<WhatsappNumber>("/whatsapp/numbers/connect", input, opts);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
registerNumber(input: RegisterWhatsappNumberInput, opts?: RequestOptions): Promise<WhatsappNumber> {
|
|
46
|
+
return this.http.post<WhatsappNumber>("/whatsapp/numbers", input, opts);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
verifyCode(id: string, code: string, opts?: RequestOptions): Promise<WhatsappNumber> {
|
|
50
|
+
return this.http.post<WhatsappNumber>(`/whatsapp/numbers/${id}/verify-code`, { code }, opts);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
resendCode(id: string, opts?: RequestOptions): Promise<void> {
|
|
54
|
+
return this.http.post(`/whatsapp/numbers/${id}/resend-code`, undefined, opts);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
getProfile(id: string, opts?: RequestOptions): Promise<WhatsappNumberProfile> {
|
|
58
|
+
return this.http.get<WhatsappNumberProfile>(`/whatsapp/numbers/${id}/profile`, opts);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
updateProfile(id: string, input: UpdateWhatsappProfileInput, opts?: RequestOptions): Promise<WhatsappNumberProfile> {
|
|
62
|
+
return this.http.patch<WhatsappNumberProfile>(`/whatsapp/numbers/${id}/profile`, input, opts);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
updateDisplayName(id: string, displayName: string, opts?: RequestOptions): Promise<WhatsappNumber> {
|
|
66
|
+
return this.http.patch<WhatsappNumber>(`/whatsapp/numbers/${id}`, { displayName }, opts);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
getStatus(id: string, opts?: RequestOptions): Promise<PhoneNumberStatusResult> {
|
|
70
|
+
return this.http.get<PhoneNumberStatusResult>(`/whatsapp/numbers/${id}/status`, opts);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
refreshNumbers(opts?: RequestOptions): Promise<WhatsappNumber[]> {
|
|
74
|
+
return this.http.post<WhatsappNumber[]>("/whatsapp/numbers/refresh", undefined, opts);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
deleteNumber(id: string, opts?: RequestOptions): Promise<void> {
|
|
78
|
+
return this.http.delete(`/whatsapp/numbers/${id}`, opts);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { HttpClient, RequestOptions } from "../http.js";
|
|
2
|
+
import type {
|
|
3
|
+
CreateWhatsappTemplateInput,
|
|
4
|
+
SyncWhatsappTemplatesResult,
|
|
5
|
+
UpdateWhatsappTemplateInput,
|
|
6
|
+
WhatsappTemplate,
|
|
7
|
+
} from "../types.js";
|
|
8
|
+
|
|
9
|
+
export class WhatsappTemplatesResource {
|
|
10
|
+
constructor(private readonly http: HttpClient) {}
|
|
11
|
+
|
|
12
|
+
list(opts?: RequestOptions): Promise<WhatsappTemplate[]> {
|
|
13
|
+
return this.http.get<WhatsappTemplate[]>("/whatsapp/templates", opts);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
create(input: CreateWhatsappTemplateInput, opts?: RequestOptions): Promise<WhatsappTemplate> {
|
|
17
|
+
return this.http.post<WhatsappTemplate>("/whatsapp/templates", input, opts);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
update(id: string, input: UpdateWhatsappTemplateInput, opts?: RequestOptions): Promise<WhatsappTemplate> {
|
|
21
|
+
return this.http.put<WhatsappTemplate>(`/whatsapp/templates/${id}`, input, opts);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
sync(opts?: RequestOptions): Promise<SyncWhatsappTemplatesResult> {
|
|
25
|
+
return this.http.post<SyncWhatsappTemplatesResult>("/whatsapp/templates/sync", undefined, opts);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
delete(id: string, opts?: RequestOptions): Promise<void> {
|
|
29
|
+
return this.http.delete(`/whatsapp/templates/${id}`, opts);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { createPostClient } from "./server.js";
|
|
2
|
+
export type { PostNextjsOptions, PostNextjsServiceAccountOptions, CreatePostClientOptions } from "./server.js";
|
|
3
|
+
|
|
4
|
+
export { PostClient } from "./client.js";
|
|
5
|
+
export { PostApiError } from "./errors.js";
|
|
6
|
+
export type { HttpClientOptions, TokenResolver } from "./http.js";
|
|
7
|
+
export { ServiceAccountTokenProvider, createServiceAccountToken } from "./service-account.js";
|
|
8
|
+
export type { ServiceAccountOptions } from "./service-account.js";
|
package/src/server.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { PostClient } from "./client.js";
|
|
2
|
+
import { ServiceAccountTokenProvider, type ServiceAccountOptions } from "./service-account.js";
|
|
3
|
+
import type { TokenResolver } from "./http.js";
|
|
4
|
+
|
|
5
|
+
export interface PostNextjsServiceAccountOptions {
|
|
6
|
+
baseUrl?: string;
|
|
7
|
+
serviceAccount: ServiceAccountOptions;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface PostNextjsOptions {
|
|
11
|
+
baseUrl?: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export type CreatePostClientOptions = PostNextjsServiceAccountOptions | PostNextjsOptions;
|
|
15
|
+
|
|
16
|
+
function isServiceAccountOptions(opts: CreatePostClientOptions): opts is PostNextjsServiceAccountOptions {
|
|
17
|
+
return "serviceAccount" in opts;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Creates a PostClient for use in Server Components, Route Handlers, and Server Actions.
|
|
22
|
+
*
|
|
23
|
+
* Two modes:
|
|
24
|
+
* - Service account: pass `serviceAccount` credentials, the SDK handles token acquisition internally
|
|
25
|
+
* - Token per request: call with no token config, pass `{ token }` in each method call
|
|
26
|
+
*/
|
|
27
|
+
export function createPostClient(options?: CreatePostClientOptions): PostClient {
|
|
28
|
+
const baseUrl = options?.baseUrl ?? process.env.POST_API_URL ?? "https://api.usepost.com.br";
|
|
29
|
+
|
|
30
|
+
if (options && isServiceAccountOptions(options)) {
|
|
31
|
+
const provider = new ServiceAccountTokenProvider(options.serviceAccount);
|
|
32
|
+
return new PostClient({
|
|
33
|
+
baseUrl,
|
|
34
|
+
token: () => provider.getToken(),
|
|
35
|
+
organizationId: () => provider.getOrganizationId() as Promise<string>,
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return new PostClient({ baseUrl });
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export type { TokenResolver, ServiceAccountOptions };
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import type { TokenResolver } from "./http.js";
|
|
2
|
+
|
|
3
|
+
export interface ServiceAccountOptions {
|
|
4
|
+
issuerUrl: string;
|
|
5
|
+
clientId: string;
|
|
6
|
+
clientSecret: string;
|
|
7
|
+
refreshBeforeExpirySeconds?: number;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
interface CachedToken {
|
|
11
|
+
value: string;
|
|
12
|
+
expiresAt: number;
|
|
13
|
+
organizationId: string | undefined;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function decodeJwtPayload(token: string): Record<string, unknown> {
|
|
17
|
+
try {
|
|
18
|
+
const [, payload] = token.split(".");
|
|
19
|
+
if (!payload) return {};
|
|
20
|
+
const json = atob(payload.replace(/-/g, "+").replace(/_/g, "/"));
|
|
21
|
+
return JSON.parse(json) as Record<string, unknown>;
|
|
22
|
+
} catch {
|
|
23
|
+
return {};
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export class ServiceAccountTokenProvider {
|
|
28
|
+
private readonly issuerUrl: string;
|
|
29
|
+
private readonly clientId: string;
|
|
30
|
+
private readonly clientSecret: string;
|
|
31
|
+
private readonly refreshBeforeMs: number;
|
|
32
|
+
private cached: CachedToken | null = null;
|
|
33
|
+
private inflight: Promise<CachedToken> | null = null;
|
|
34
|
+
|
|
35
|
+
constructor(options: ServiceAccountOptions) {
|
|
36
|
+
this.issuerUrl = options.issuerUrl.replace(/\/$/, "");
|
|
37
|
+
this.clientId = options.clientId;
|
|
38
|
+
this.clientSecret = options.clientSecret;
|
|
39
|
+
this.refreshBeforeMs = (options.refreshBeforeExpirySeconds ?? 30) * 1000;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
private async ensureFresh(): Promise<CachedToken> {
|
|
43
|
+
const now = Date.now();
|
|
44
|
+
if (this.cached && this.cached.expiresAt - now > this.refreshBeforeMs) {
|
|
45
|
+
return this.cached;
|
|
46
|
+
}
|
|
47
|
+
if (this.inflight) return this.inflight;
|
|
48
|
+
this.inflight = this.fetchToken().finally(() => { this.inflight = null; });
|
|
49
|
+
return this.inflight;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
getToken(): Promise<string> {
|
|
53
|
+
return this.ensureFresh().then((c) => c.value);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
getOrganizationId(): Promise<string | undefined> {
|
|
57
|
+
return this.ensureFresh().then((c) => c.organizationId);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
private async fetchToken(): Promise<CachedToken> {
|
|
61
|
+
const credentials = btoa(`${this.clientId}:${this.clientSecret}`);
|
|
62
|
+
|
|
63
|
+
const res = await fetch(`${this.issuerUrl}/auth/token`, {
|
|
64
|
+
method: "POST",
|
|
65
|
+
headers: {
|
|
66
|
+
"Content-Type": "application/json",
|
|
67
|
+
Authorization: `Basic ${credentials}`,
|
|
68
|
+
},
|
|
69
|
+
body: JSON.stringify({ grant_type: "service_account" }),
|
|
70
|
+
cache: "no-store" as RequestCache,
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
if (!res.ok) {
|
|
74
|
+
const err = await res.json().catch(() => ({})) as { error?: string };
|
|
75
|
+
throw new Error(`ServiceAccount token fetch failed (${res.status}): ${err.error ?? "unknown error"}`);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
const data = await res.json() as { access_token: string; expires_in?: number };
|
|
79
|
+
const claims = decodeJwtPayload(data.access_token);
|
|
80
|
+
const organizationId =
|
|
81
|
+
typeof claims.organizationId === "string" ? claims.organizationId :
|
|
82
|
+
typeof claims.organization_id === "string" ? claims.organization_id :
|
|
83
|
+
undefined;
|
|
84
|
+
|
|
85
|
+
const expiresInMs = (data.expires_in ?? 420) * 1000;
|
|
86
|
+
this.cached = { value: data.access_token, expiresAt: Date.now() + expiresInMs, organizationId };
|
|
87
|
+
return this.cached;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
asTokenResolver(): TokenResolver {
|
|
91
|
+
return () => this.getToken();
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export function createServiceAccountToken(options: ServiceAccountOptions): TokenResolver {
|
|
96
|
+
return new ServiceAccountTokenProvider(options).asTokenResolver();
|
|
97
|
+
}
|