Skip to content

Commit 1802d76

Browse files
andrewbonigmethvin
andauthored
Adds runtime response validation + improves URL encoding (#9)
* Adds runtime validation --------- Co-authored-by: Greg Methvin <[email protected]>
1 parent a44e47b commit 1802d76

19 files changed

+417
-168
lines changed

src/client/export.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
11
import {
22
CancelExportJobParams,
33
CancelExportJobResponse,
4+
CancelExportJobResponseSchema,
45
GetExportFilesParams,
56
GetExportFilesResponse,
7+
GetExportFilesResponseSchema,
68
GetExportJobsParams,
79
GetExportJobsResponse,
10+
GetExportJobsResponseSchema,
811
StartExportJobParams,
912
StartExportJobResponse,
1013
StartExportJobResponseSchema,
1114
} from "../types/export.js";
12-
import type { Constructor } from "./base.js";
13-
import type { BaseIterableClient } from "./base.js";
15+
import type { BaseIterableClient, Constructor } from "./base.js";
1416

1517
/**
1618
* Export operations mixin
@@ -26,7 +28,7 @@ export function Export<T extends Constructor<BaseIterableClient>>(Base: T) {
2628
const response = await this.client.get(
2729
`/api/export/jobs?${urlParams.toString()}`
2830
);
29-
return response.data;
31+
return this.validateResponse(response, GetExportJobsResponseSchema);
3032
}
3133

3234
async getExportFiles(
@@ -38,7 +40,7 @@ export function Export<T extends Constructor<BaseIterableClient>>(Base: T) {
3840
const response = await this.client.get(
3941
`/api/export/${params.jobId}/files?${urlParams.toString()}`
4042
);
41-
return response.data;
43+
return this.validateResponse(response, GetExportFilesResponseSchema);
4244
}
4345

4446
async startExportJob(
@@ -52,7 +54,7 @@ export function Export<T extends Constructor<BaseIterableClient>>(Base: T) {
5254
params: CancelExportJobParams
5355
): Promise<CancelExportJobResponse> {
5456
const response = await this.client.delete(`/api/export/${params.jobId}`);
55-
return response.data;
57+
return this.validateResponse(response, CancelExportJobResponseSchema);
5658
}
5759
};
5860
}

src/client/journeys.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ import {
66
import {
77
GetJourneysParams,
88
GetJourneysResponse,
9+
GetJourneysResponseSchema,
910
TriggerJourneyParams,
1011
} from "../types/journeys.js";
11-
import type { Constructor } from "./base.js";
12-
import type { BaseIterableClient } from "./base.js";
12+
import type { BaseIterableClient, Constructor } from "./base.js";
1313

1414
/**
1515
* Journeys operations mixin
@@ -48,7 +48,7 @@ export function Journeys<T extends Constructor<BaseIterableClient>>(Base: T) {
4848

4949
const url = `/api/journeys?${queryParams.toString()}`;
5050
const response = await this.client.get(url);
51-
return response.data;
51+
return this.validateResponse(response, GetJourneysResponseSchema);
5252
}
5353
};
5454
}

src/client/messaging.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
import { IterableSuccessResponse } from "../types/common.js";
2-
import { IterableSuccessResponseSchema } from "../types/common.js";
1+
import {
2+
IterableSuccessResponse,
3+
IterableSuccessResponseSchema,
4+
} from "../types/common.js";
35
import {
46
CancelEmailParams,
57
CancelInAppParams,
@@ -10,6 +12,7 @@ import {
1012
ChannelsResponse,
1113
ChannelsResponseSchema,
1214
EmbeddedMessagesResponse,
15+
EmbeddedMessagesResponseSchema,
1316
GetEmbeddedMessagesParams,
1417
GetInAppMessagesParams,
1518
GetInAppMessagesResponse,
@@ -160,7 +163,7 @@ export function Messaging<T extends Constructor<BaseIterableClient>>(Base: T) {
160163
const response = await this.client.get(
161164
`/api/embedded-messaging/messages?${queryParams.toString()}`
162165
);
163-
return response.data;
166+
return this.validateResponse(response, EmbeddedMessagesResponseSchema);
164167
}
165168

166169
// get available message channels

src/client/snippets.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ export function Snippets<T extends Constructor<BaseIterableClient>>(Base: T) {
4444
opts?: { signal?: AbortSignal }
4545
): Promise<GetSnippetResponse> {
4646
const response = await this.client.get(
47-
`/api/snippets/${params.identifier}`,
47+
`/api/snippets/${encodeURIComponent(String(params.identifier))}`,
4848
opts?.signal ? { signal: opts.signal } : {}
4949
);
5050
return this.validateResponse(response, GetSnippetResponseSchema);
@@ -56,7 +56,7 @@ export function Snippets<T extends Constructor<BaseIterableClient>>(Base: T) {
5656
): Promise<UpdateSnippetResponse> {
5757
const { identifier, ...body } = params;
5858
const response = await this.client.put(
59-
`/api/snippets/${identifier}`,
59+
`/api/snippets/${encodeURIComponent(String(identifier))}`,
6060
body,
6161
opts
6262
);
@@ -68,7 +68,7 @@ export function Snippets<T extends Constructor<BaseIterableClient>>(Base: T) {
6868
opts?: { signal?: AbortSignal }
6969
): Promise<DeleteSnippetResponse> {
7070
const response = await this.client.delete(
71-
`/api/snippets/${params.identifier}`,
71+
`/api/snippets/${encodeURIComponent(String(params.identifier))}`,
7272
opts?.signal ? { signal: opts.signal } : {}
7373
);
7474
return this.validateResponse(response, DeleteSnippetResponseSchema);

src/client/subscriptions.ts

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
1-
import { IterableSuccessResponse } from "../types/common.js";
1+
import {
2+
IterableSuccessResponse,
3+
IterableSuccessResponseSchema,
4+
} from "../types/common.js";
25
import {
36
BulkUpdateSubscriptionsParams,
47
SubscribeUserByEmailParams,
58
SubscribeUserByUserIdParams,
69
UnsubscribeUserByEmailParams,
710
UnsubscribeUserByUserIdParams,
811
} from "../types/subscriptions.js";
9-
import type { Constructor } from "./base.js";
10-
import type { BaseIterableClient } from "./base.js";
12+
import type { BaseIterableClient, Constructor } from "./base.js";
1113

1214
export function Subscriptions<T extends Constructor<BaseIterableClient>>(
1315
Base: T
@@ -30,7 +32,7 @@ export function Subscriptions<T extends Constructor<BaseIterableClient>>(
3032
`/api/subscriptions/${encodeURIComponent(subscriptionGroup)}/${subscriptionGroupId}?action=${action}`,
3133
requestBody
3234
);
33-
return response.data;
35+
return this.validateResponse(response, IterableSuccessResponseSchema);
3436
}
3537

3638
async subscribeUserByEmail(
@@ -41,7 +43,7 @@ export function Subscriptions<T extends Constructor<BaseIterableClient>>(
4143
const response = await this.client.patch(
4244
`/api/subscriptions/${encodeURIComponent(subscriptionGroup)}/${subscriptionGroupId}/user/${encodeURIComponent(userEmail)}`
4345
);
44-
return response.data;
46+
return this.validateResponse(response, IterableSuccessResponseSchema);
4547
}
4648

4749
async subscribeUserByUserId(
@@ -52,7 +54,7 @@ export function Subscriptions<T extends Constructor<BaseIterableClient>>(
5254
const response = await this.client.patch(
5355
`/api/subscriptions/${encodeURIComponent(subscriptionGroup)}/${subscriptionGroupId}/byUserId/${encodeURIComponent(userId)}`
5456
);
55-
return response.data;
57+
return this.validateResponse(response, IterableSuccessResponseSchema);
5658
}
5759

5860
async unsubscribeUserByEmail(
@@ -63,7 +65,7 @@ export function Subscriptions<T extends Constructor<BaseIterableClient>>(
6365
const response = await this.client.delete(
6466
`/api/subscriptions/${encodeURIComponent(subscriptionGroup)}/${subscriptionGroupId}/user/${encodeURIComponent(userEmail)}`
6567
);
66-
return response.data;
68+
return this.validateResponse(response, IterableSuccessResponseSchema);
6769
}
6870

6971
async unsubscribeUserByUserId(
@@ -74,7 +76,7 @@ export function Subscriptions<T extends Constructor<BaseIterableClient>>(
7476
const response = await this.client.delete(
7577
`/api/subscriptions/${encodeURIComponent(subscriptionGroup)}/${subscriptionGroupId}/byUserId/${encodeURIComponent(userId)}`
7678
);
77-
return response.data;
79+
return this.validateResponse(response, IterableSuccessResponseSchema);
7880
}
7981
};
8082
}

src/client/templates.ts

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -79,16 +79,6 @@ export function Templates<T extends Constructor<BaseIterableClient>>(Base: T) {
7979
return this.validateResponse(response, IterableSuccessResponseSchema);
8080
}
8181

82-
// Template deletion - works for all template types
83-
async deleteTemplates(
84-
templateIds: number[]
85-
): Promise<BulkDeleteTemplatesResponse> {
86-
const response = await this.client.post(`/api/templates/bulkDelete`, {
87-
ids: templateIds,
88-
});
89-
return this.validateResponse(response, BulkDeleteTemplatesResponseSchema);
90-
}
91-
9282
async #sendTemplateProof(
9383
pathSegment: string,
9484
request: SendTemplateProofParams
@@ -155,12 +145,22 @@ export function Templates<T extends Constructor<BaseIterableClient>>(Base: T) {
155145

156146
async bulkDeleteTemplates(
157147
params: BulkDeleteTemplatesParams
158-
): Promise<IterableSuccessResponse> {
148+
): Promise<BulkDeleteTemplatesResponse> {
159149
const response = await this.client.post(
160150
`/api/templates/bulkDelete`,
161151
params
162152
);
163-
return this.validateResponse(response, IterableSuccessResponseSchema);
153+
return this.validateResponse(response, BulkDeleteTemplatesResponseSchema);
154+
}
155+
156+
/**
157+
* Delete one or more templates by ID
158+
* @deprecated Use {@link bulkDeleteTemplates} instead
159+
*/
160+
async deleteTemplates(
161+
templateIds: number[]
162+
): Promise<BulkDeleteTemplatesResponse> {
163+
return this.bulkDeleteTemplates({ ids: templateIds });
164164
}
165165

166166
// Email Template Management

src/client/users.ts

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,25 @@
1-
import { IterableSuccessResponse } from "../types/common.js";
2-
import { IterableSuccessResponseSchema } from "../types/common.js";
3-
import { UserBulkUpdateListResponse } from "../types/lists.js";
4-
import { UserBulkUpdateListResponseSchema } from "../types/lists.js";
1+
import {
2+
IterableSuccessResponse,
3+
IterableSuccessResponseSchema,
4+
} from "../types/common.js";
5+
import {
6+
UserBulkUpdateListResponse,
7+
UserBulkUpdateListResponseSchema,
8+
} from "../types/lists.js";
59
import {
610
BulkUpdateUsersParams,
711
GetSentMessagesParams,
812
GetSentMessagesResponse,
13+
GetSentMessagesResponseSchema,
914
GetUserFieldsResponse,
1015
GetUserFieldsResponseSchema,
1116
UpdateEmailParams,
1217
UpdateUserParams,
1318
UpdateUserSubscriptionsParams,
1419
UserResponse,
20+
UserResponseSchema,
1521
} from "../types/users.js";
16-
import type { Constructor } from "./base.js";
17-
import type { BaseIterableClient } from "./base.js";
22+
import type { BaseIterableClient, Constructor } from "./base.js";
1823

1924
/**
2025
* User management operations mixin
@@ -32,7 +37,7 @@ export function Users<T extends Constructor<BaseIterableClient>>(Base: T) {
3237
`/api/users/${encodeURIComponent(email)}`,
3338
opts?.signal ? { signal: opts.signal } : {}
3439
);
35-
return response.data;
40+
return this.validateResponse(response, UserResponseSchema);
3641
}
3742

3843
/**
@@ -42,10 +47,11 @@ export function Users<T extends Constructor<BaseIterableClient>>(Base: T) {
4247
userId: string,
4348
opts?: { signal?: AbortSignal }
4449
): Promise<UserResponse> {
45-
const response = await this.client.get(`/api/users/byUserId/${userId}`, {
46-
...(opts?.signal ? { signal: opts.signal } : {}),
47-
});
48-
return response.data;
50+
const response = await this.client.get(
51+
`/api/users/byUserId/${encodeURIComponent(userId)}`,
52+
opts?.signal ? { signal: opts.signal } : {}
53+
);
54+
return this.validateResponse(response, UserResponseSchema);
4955
}
5056

5157
/**
@@ -67,7 +73,7 @@ export function Users<T extends Constructor<BaseIterableClient>>(Base: T) {
6773
const response = await this.client.delete(
6874
`/api/users/${encodeURIComponent(email)}`
6975
);
70-
return response.data;
76+
return this.validateResponse(response, IterableSuccessResponseSchema);
7177
}
7278

7379
/**
@@ -79,7 +85,7 @@ export function Users<T extends Constructor<BaseIterableClient>>(Base: T) {
7985
const response = await this.client.delete(
8086
`/api/users/byUserId/${encodeURIComponent(userId)}`
8187
);
82-
return response.data;
88+
return this.validateResponse(response, IterableSuccessResponseSchema);
8389
}
8490

8591
/**
@@ -159,7 +165,7 @@ export function Users<T extends Constructor<BaseIterableClient>>(Base: T) {
159165
const response = await this.client.get(
160166
`/api/users/getSentMessages?${queryParams.toString()}`
161167
);
162-
return response.data;
168+
return this.validateResponse(response, GetSentMessagesResponseSchema);
163169
}
164170

165171
/**

0 commit comments

Comments
 (0)