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
24 changes: 24 additions & 0 deletions src/Client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ export type Events = {
// ^ userRelationshipChanged: [user: User, previousRelationship: RelationshipStatus];
// ^ userPresenceChanged: [user: User, previousPresence: boolean];
userSettingsUpdate: [id: string, update: Record<string, [number, string]>];
entitlementsUpdate: [entitlements: ProtocolV1["types"]["entitlement"][]];

emojiCreate: [emoji: Emoji];
emojiDelete: [emoji: HydratedEmoji];
Expand Down Expand Up @@ -206,6 +207,14 @@ export class Client extends AsyncEventEmitter<Events> {

readonly connectionFailureCount: Accessor<number>;
#setConnectionFailureCount: Setter<number>;

/**
* Entitlements the current user holds, as last sent by the server.
* Note that passing an expiration date will NOT remove its data,
* so you may need to keep track of expiration yourself.
*/
readonly entitlements: Accessor<ProtocolV1["types"]["entitlement"][]>;
#setEntitlements: Setter<ProtocolV1["types"]["entitlement"][]>;
#reconnectTimeout: number | undefined;

/**
Expand Down Expand Up @@ -270,6 +279,12 @@ export class Client extends AsyncEventEmitter<Events> {
this.connectionFailureCount = connectionFailureCount;
this.#setConnectionFailureCount = setConnectionFailureCount;

const [entitlements, setEntitlements] = createSignal<
ProtocolV1["types"]["entitlement"][]
>([]);
this.entitlements = entitlements;
this.#setEntitlements = setEntitlements;

this.account = new AccountCollection(this);
this.bots = new BotCollection(this);
this.channels = new ChannelCollection(this);
Expand Down Expand Up @@ -428,6 +443,15 @@ export class Client extends AsyncEventEmitter<Events> {
this.events.removeAllListeners();
this.removeAllListeners();
this.events.disconnect();
this.#setEntitlements([]);
}

/**
* Replace the current user's entitlements, from the events socket
* @internal
*/
setEntitlements(entitlements: ProtocolV1["types"]["entitlement"][]): void {
this.#setEntitlements(entitlements);
}

/**
Expand Down
28 changes: 28 additions & 0 deletions src/events/v1.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export type ProtocolV1 = {

types: {
policyChange: PolicyChange;
entitlement: Entitlement;
};
};

Expand Down Expand Up @@ -161,6 +162,7 @@ type ServerMessage =
update: { [key: string]: [number, string] };
}
| { type: "UserPlatformWipe"; user_id: string; flags: number }
| { type: "EntitlementsUpdate"; entitlements: Entitlement[] }
| ({ type: "EmojiCreate" } & Emoji)
| { type: "EmojiDelete"; id: string }
| ({
Expand Down Expand Up @@ -210,6 +212,22 @@ type ServerMessage =
slowmodes: UserSlowmodes[];
};

/**
* Entitlement the user holds
*/
type Entitlement = {
/** Entitlement key, a ULID */
key: string;
/** When it stops granting access; may be in the past */
expires_at: string;
/** Entitlement data revision. Backend implementation detail. Only ever increases */
revision: number;
/** Issuer that last set it. Opaque string */
source: string;
/** Start of the holder's current streak of access to this entitlement */
since: string;
};

/**
* Policy change type
*/
Expand Down Expand Up @@ -265,6 +283,7 @@ type ReadyData = {
channel_unreads: ChannelUnread[];

policy_changes: PolicyChange[];
entitlements: Entitlement[];
};

/**
Expand Down Expand Up @@ -339,8 +358,12 @@ export async function handleEvent(
client.emojis.getOrCreate(emoji._id, emoji);
}
}

client.setEntitlements(event.entitlements ?? []);
});

client.emit("entitlementsUpdate", client.entitlements());

if (client.options.syncUnreads) {
await client.channelUnreads.sync();
}
Expand Down Expand Up @@ -958,6 +981,11 @@ export async function handleEvent(
);
break;
}
case "EntitlementsUpdate": {
client.setEntitlements(event.entitlements);
client.emit("entitlementsUpdate", event.entitlements);
break;
}
case "UserSettingsUpdate": {
client.emit("userSettingsUpdate", event.id, event.update);
break;
Expand Down
Loading