@stadium-ws/core
Version:
Build scalable realtime applications.
390 lines (382 loc) • 11.6 kB
JavaScript
"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
var __async = (__this, __arguments, generator) => {
return new Promise((resolve, reject) => {
var fulfilled = (value) => {
try {
step(generator.next(value));
} catch (e) {
reject(e);
}
};
var rejected = (value) => {
try {
step(generator.throw(value));
} catch (e) {
reject(e);
}
};
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
step((generator = generator.apply(__this, __arguments)).next());
});
};
// src/index.ts
var src_exports = {};
__export(src_exports, {
ChannelType: () => ChannelType,
SortDirection: () => SortDirection,
Stadium: () => Stadium
});
module.exports = __toCommonJS(src_exports);
// src/types.ts
var ChannelType = /* @__PURE__ */ ((ChannelType2) => {
ChannelType2["PUBLIC"] = "PUBLIC";
ChannelType2["PRIVATE"] = "PRIVATE";
ChannelType2["DIRECT"] = "DIRECT";
return ChannelType2;
})(ChannelType || {});
var SortDirection = /* @__PURE__ */ ((SortDirection2) => {
SortDirection2["ASC"] = "asc";
SortDirection2["DESC"] = "desc";
return SortDirection2;
})(SortDirection || {});
// src/Stadium.ts
var import_eventemitter3 = __toESM(require("eventemitter3"));
// src/Connection.ts
var import_isomorphic_ws = __toESM(require("isomorphic-ws"));
var Connection = class {
constructor(config) {
this.isConnected = false;
this.connect = ({ onEvent, token }) => {
return new Promise((resolve, reject) => {
this.webSocket = new import_isomorphic_ws.default(`${this.baseUrl}?token=${token}`);
this.webSocket.addEventListener("error", () => {
reject(new Error("nope"));
});
this.webSocket.addEventListener("message", (e) => {
const data = JSON.parse(e.data);
onEvent(data);
});
this.webSocket.addEventListener("open", () => {
this.isConnected = true;
resolve();
});
this.webSocket.addEventListener("close", () => {
this.isConnected = false;
});
});
};
this.disconnect = () => __async(this, null, function* () {
if (!this.isConnected) {
return;
}
this.webSocket.close();
});
this.baseUrl = config.baseUrl;
}
};
var Connection_default = Connection;
// src/Requester.ts
var import_qs = __toESM(require("qs"));
var ApiRequestError = class extends Error {
constructor(message, statusCode) {
super(message);
this.statusCode = statusCode;
Error.captureStackTrace(this, this.constructor);
}
};
var Requester = class {
constructor(baseUrl, successStatuses = [200, 201]) {
this.successStatuses = [200, 201];
this.headers = {
"Content-Type": "application/json",
Accept: "application/json"
};
this.setTokenHeader = (token) => {
this.headers["Authorization"] = `Bearer ${token}`;
};
this.clearTokenHeader = () => {
delete this.headers["Authorization"];
};
this.request = (options) => __async(this, null, function* () {
let url = `${this.baseUrl}/${options.urlSegment}`;
if (options.query) {
url += `?${import_qs.default.stringify(options.query)}`;
}
const method = (options == null ? void 0 : options.method) || "GET";
const fetchRes = yield fetch(url, {
method,
body: (options == null ? void 0 : options.body) ? JSON.stringify(options.body) : void 0,
headers: this.headers
});
if (!this.successStatuses.includes(fetchRes.status)) {
const text = yield fetchRes.text();
throw new ApiRequestError(text, fetchRes.status);
}
if (fetchRes.status === 201) {
return {};
}
const json = yield fetchRes.json();
return json;
});
this.baseUrl = baseUrl;
this.successStatuses = successStatuses;
}
};
var Requester_default = Requester;
// src/utils.ts
var MessageTypeMap = {
[0 /* EVENT_CREATE */]: "eventCreate",
[2 /* EVENT_UPDATE */]: "eventUpdate",
[1 /* EVENT_DELETE */]: "eventDelete",
[3 /* EVENT_REACTION_CREATE */]: "eventReactionCreate",
[4 /* EVENT_REACTION_DELETE */]: "eventReactionDelete",
[5 /* CHANNEL_UPDATE */]: "channelUpdate",
[6 /* CHANNEL_USER_ADDED */]: "channelUserAdded"
};
var getEventName = (type) => {
return MessageTypeMap[type];
};
// src/Stadium.ts
var Stadium = class {
constructor(config = {}) {
this.updateUser = (userId, options) => __async(this, null, function* () {
yield this.ensureAccessToken();
const body = {};
if (options.displayName) {
body.displayName = options.displayName;
}
if (options.isOnline) {
body.isOnline = options.isOnline;
}
if (options.meta) {
body.meta = options.meta;
}
if (options.userRoleId) {
body.userRoleId = options.userRoleId;
}
return this.requester.request({
urlSegment: `users/${userId}`,
method: "PUT",
body
});
});
this.onEvent = (event) => {
var _a;
const eventName = getEventName(event.type);
(_a = this.emitter) == null ? void 0 : _a.emit(eventName, event.data);
};
this.apiUrl = config.apiUrl || "https://api.stadium.ws";
this.gatewayUrl = config.gatewayUrl || "wss://gateway.stadium.ws";
this.config = config;
this.requester = new Requester_default(this.apiUrl);
}
on(event, listener) {
if (!this.emitter) {
this.emitter = new import_eventemitter3.default();
}
this.emitter.on(event, listener);
}
once(event, listener) {
if (!this.emitter) {
this.emitter = new import_eventemitter3.default();
}
this.emitter.once(event, listener);
}
off(event, listener) {
if (!this.emitter) {
return;
}
this.emitter.off(event, listener);
}
removeAllListeners() {
if (!this.emitter) {
return;
}
this.emitter.removeAllListeners();
}
createUser(_0) {
return __async(this, arguments, function* ({
userRoleId,
displayName,
meta
}) {
yield this.ensureAccessToken();
return this.requester.request({
urlSegment: "users",
method: "POST",
body: {
userRoleId,
displayName,
meta
}
});
});
}
setUserToken(token) {
this.accessToken = token;
this.requester.setTokenHeader(this.accessToken);
}
getMe() {
return __async(this, null, function* () {
const res = yield this.requester.request({
urlSegment: "oauth/token"
});
return res.user;
});
}
getChannel(channelId) {
return __async(this, null, function* () {
yield this.ensureAccessToken();
return this.requester.request({
urlSegment: `channels/${channelId}`
});
});
}
getChannelUsers(channelId) {
return __async(this, null, function* () {
yield this.ensureAccessToken();
return this.requester.request({
urlSegment: `channels/${channelId}/users`
});
});
}
createEvent(options) {
return __async(this, null, function* () {
yield this.ensureAccessToken();
return this.requester.request({
urlSegment: "events",
method: "POST",
body: options
});
});
}
getChannelEvents(channelId, options) {
return __async(this, null, function* () {
yield this.ensureAccessToken();
const query = {
from: options == null ? void 0 : options.from,
limit: options == null ? void 0 : options.limit,
direction: options == null ? void 0 : options.direction,
type: options == null ? void 0 : options.type
};
return this.requester.request({
urlSegment: `channels/${channelId}/events`,
query
});
});
}
getUserRoles(options) {
return __async(this, null, function* () {
yield this.ensureAccessToken();
const query = {
from: options == null ? void 0 : options.from,
limit: options == null ? void 0 : options.limit,
direction: options == null ? void 0 : options.direction
};
return this.requester.request({
urlSegment: "user-roles",
query
});
});
}
getUsers(options) {
return __async(this, null, function* () {
yield this.ensureAccessToken();
const query = {
from: options == null ? void 0 : options.from,
limit: options == null ? void 0 : options.limit,
direction: options == null ? void 0 : options.direction
};
return this.requester.request({
urlSegment: "users",
query
});
});
}
getChannels(options) {
return __async(this, null, function* () {
yield this.ensureAccessToken();
const query = {
from: options == null ? void 0 : options.from,
limit: options == null ? void 0 : options.limit,
direction: options == null ? void 0 : options.direction
};
return this.requester.request({
urlSegment: "channels",
query
});
});
}
ensureAccessToken() {
return __async(this, null, function* () {
if (this.accessToken) {
return;
}
const accessTokenResponse = yield this.requester.request({
urlSegment: "oauth/token",
method: "POST",
body: {
grant_type: "client_credentials",
client_id: this.config.clientId,
client_secret: this.config.clientSecret
}
});
if (!(accessTokenResponse == null ? void 0 : accessTokenResponse.access_token)) {
throw new Error("Could not authenticate with Stadium");
}
this.accessToken = accessTokenResponse.access_token;
this.requester.setTokenHeader(this.accessToken);
});
}
connect() {
return __async(this, null, function* () {
this.connection = new Connection_default({
baseUrl: this.gatewayUrl
});
this.emitter = new import_eventemitter3.default();
yield this.connection.connect({
token: this.accessToken,
onEvent: this.onEvent
});
});
}
disconnect() {
return __async(this, null, function* () {
var _a;
if (!this.connection) {
return;
}
(_a = this.emitter) == null ? void 0 : _a.removeAllListeners();
return this.connection.disconnect();
});
}
};
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
ChannelType,
SortDirection,
Stadium
});