Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 6 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# ActivitySmith Node.js Library
# ActivitySmith Node SDK

The ActivitySmith Node library provides convenient access to the ActivitySmith API from server-side JavaScript and TypeScript applications.
The ActivitySmith Node SDK provides convenient access to the ActivitySmith API from server-side JavaScript and TypeScript applications.

## Documentation

Expand All @@ -24,17 +24,13 @@ const client = new ActivitySmith({
});

// Push Notifications
await client.notifications.sendPushNotification({
pushNotificationRequest: {
// See PushNotificationRequest for fields
},
await client.notifications.send({
// See PushNotificationRequest for fields
});

// Live Activities
await client.liveActivities.startLiveActivity({
liveActivityStartRequest: {
// See LiveActivityStartRequest for fields
},
await client.liveActivities.start({
// See LiveActivityStartRequest for fields
});
```

Expand Down
81 changes: 77 additions & 4 deletions src/ActivitySmith.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,82 @@ export interface ActivitySmithOptions {
apiKey: string;
}

type PushRequestBody = Parameters<PushNotificationsApi["sendPushNotification"]>[0]["pushNotificationRequest"];
type SendInitOverrides = Parameters<PushNotificationsApi["sendPushNotification"]>[1];
type StartRequestBody = Parameters<LiveActivitiesApi["startLiveActivity"]>[0]["liveActivityStartRequest"];
type UpdateRequestBody = Parameters<LiveActivitiesApi["updateLiveActivity"]>[0]["liveActivityUpdateRequest"];
type EndRequestBody = Parameters<LiveActivitiesApi["endLiveActivity"]>[0]["liveActivityEndRequest"];
type LiveInitOverrides = Parameters<LiveActivitiesApi["startLiveActivity"]>[1];

export class NotificationsResource {
private readonly api: PushNotificationsApi;

constructor(api: PushNotificationsApi) {
this.api = api;
}

send(request: PushRequestBody, initOverrides?: SendInitOverrides) {
return this.api.sendPushNotification({ pushNotificationRequest: request }, initOverrides);
}

// Backward-compatible alias.
sendPushNotification(...args: Parameters<PushNotificationsApi["sendPushNotification"]>) {
return this.api.sendPushNotification(...args);
}

sendPushNotificationRaw(...args: Parameters<PushNotificationsApi["sendPushNotificationRaw"]>) {
return this.api.sendPushNotificationRaw(...args);
}
}

export class LiveActivitiesResource {
private readonly api: LiveActivitiesApi;

constructor(api: LiveActivitiesApi) {
this.api = api;
}

start(request: StartRequestBody, initOverrides?: LiveInitOverrides) {
return this.api.startLiveActivity({ liveActivityStartRequest: request }, initOverrides);
}

update(request: UpdateRequestBody, initOverrides?: LiveInitOverrides) {
return this.api.updateLiveActivity({ liveActivityUpdateRequest: request }, initOverrides);
}

end(request: EndRequestBody, initOverrides?: LiveInitOverrides) {
return this.api.endLiveActivity({ liveActivityEndRequest: request }, initOverrides);
}

// Backward-compatible aliases.
startLiveActivity(...args: Parameters<LiveActivitiesApi["startLiveActivity"]>) {
return this.api.startLiveActivity(...args);
}

updateLiveActivity(...args: Parameters<LiveActivitiesApi["updateLiveActivity"]>) {
return this.api.updateLiveActivity(...args);
}

endLiveActivity(...args: Parameters<LiveActivitiesApi["endLiveActivity"]>) {
return this.api.endLiveActivity(...args);
}

startLiveActivityRaw(...args: Parameters<LiveActivitiesApi["startLiveActivityRaw"]>) {
return this.api.startLiveActivityRaw(...args);
}

updateLiveActivityRaw(...args: Parameters<LiveActivitiesApi["updateLiveActivityRaw"]>) {
return this.api.updateLiveActivityRaw(...args);
}

endLiveActivityRaw(...args: Parameters<LiveActivitiesApi["endLiveActivityRaw"]>) {
return this.api.endLiveActivityRaw(...args);
}
}

export class ActivitySmith {
public readonly notifications: PushNotificationsApi;
public readonly liveActivities: LiveActivitiesApi;
public readonly notifications: NotificationsResource;
public readonly liveActivities: LiveActivitiesResource;

constructor(opts: ActivitySmithOptions) {
if (!opts?.apiKey) {
Expand All @@ -18,7 +91,7 @@ export class ActivitySmith {
accessToken: opts.apiKey,
});

this.notifications = new PushNotificationsApi(config);
this.liveActivities = new LiveActivitiesApi(config);
this.notifications = new NotificationsResource(new PushNotificationsApi(config));
this.liveActivities = new LiveActivitiesResource(new LiveActivitiesApi(config));
}
}
34 changes: 34 additions & 0 deletions tests/smoke.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,38 @@ describe("smoke", () => {

expect(client).toBeTruthy();
});

it("supports short method names for resources", async () => {
const fetchSpy = vi.fn(async () =>
new Response(
JSON.stringify({
success: true,
devices_notified: 1,
}),
{
status: 200,
headers: { "content-type": "application/json" },
},
),
);

globalThis.fetch = fetchSpy;

const ActivitySmith = require("../dist/src/index.js");
const client = new ActivitySmith({ apiKey: "test" });

await client.notifications.send({ title: "Build Failed" });
await client.liveActivities.start({
content_state: {
title: "Deploy",
number_of_steps: 4,
current_step: 1,
type: "segmented_progress",
},
});

expect(fetchSpy).toHaveBeenCalledTimes(2);
expect(String(fetchSpy.mock.calls[0][0])).toContain("/push-notification");
expect(String(fetchSpy.mock.calls[1][0])).toContain("/live-activity/start");
});
});