@scryme/chat 0.0.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/src/index.ts ADDED
@@ -0,0 +1,3 @@
1
+ export * from './custom-instance';
2
+ export * from './generated/v3-client';
3
+ export * from './sdk';
package/src/sdk.ts ADDED
@@ -0,0 +1,298 @@
1
+ import axios, { AxiosRequestConfig } from 'axios';
2
+ import { getSkyrmeChatAPI } from './generated/v3-server';
3
+ import type {
4
+ V3ProvisionWorkspaceDto,
5
+ V3UpdateWorkspaceDto,
6
+ V3AddMemberDto,
7
+ V3UpdateMemberRoleDto,
8
+ CreateWorkspaceChannelDto,
9
+ UpdateWorkspaceChannelDto,
10
+ ChannelsControllerGetMessagesParams,
11
+ ChannelsControllerUpdateMessageBody,
12
+ ChannelsControllerAddReactionBody,
13
+ CreateDmDto,
14
+ UpdateDmMessageDto,
15
+ MarkAsReadDto,
16
+ UsersControllerSearchUsersParams,
17
+ V3WorkspacesControllerGetWorkspaces200,
18
+ V3WorkspacesControllerGetWorkspaceBySlug200,
19
+ V3WorkspacesControllerProvisionWorkspace201,
20
+ V3WorkspacesControllerUpdateWorkspace200,
21
+ V3WorkspacesControllerDeleteWorkspace200,
22
+ DmsControllerGetMessagesParams,
23
+ } from './generated/v3-server';
24
+
25
+ export interface ScrymeSDKOptions {
26
+ baseURL?: string;
27
+ clientId?: string;
28
+ clientSecret?: string;
29
+ token?: string;
30
+ }
31
+
32
+ export class ScrymeSDK {
33
+ private token: string | null = null;
34
+ private tokenExpiresAt: number | null = null;
35
+ public baseURL: string;
36
+ private clientId?: string;
37
+ private clientSecret?: string;
38
+
39
+ constructor(options: ScrymeSDKOptions = {}) {
40
+ this.clientId = options.clientId;
41
+ this.clientSecret = options.clientSecret;
42
+ this.token = options.token || null;
43
+
44
+ let url = options.baseURL || '';
45
+ if (!url && typeof window !== 'undefined') {
46
+ url = window.localStorage.getItem('CUSTOM_API_URL') || '';
47
+ }
48
+ if (!url) {
49
+ const g = globalThis as typeof globalThis & {
50
+ process?: { env?: Record<string, string> };
51
+ __env__?: Record<string, string>;
52
+ };
53
+ const env = g.process?.env || g.__env__ || {};
54
+ const isProd =
55
+ env.NODE_ENV === 'production' ||
56
+ (typeof window !== 'undefined' && window.location.hostname !== 'localhost' && window.location.hostname !== '127.0.0.1');
57
+
58
+ url =
59
+ env.API_URL ||
60
+ env.NEXT_PUBLIC_API_URL ||
61
+ env.VITE_API_URL ||
62
+ (isProd ? 'https://api.chat.scryme.tech' : 'http://localhost:3000');
63
+ }
64
+ this.baseURL = url.replace(/\/$/, '');
65
+ }
66
+
67
+ /**
68
+ * Automatically retrieves or refreshes the M2M OAuth2 Token using client_credentials
69
+ */
70
+ public async getOrFetchToken(): Promise<string | null> {
71
+ // If we already have a token and it is not expired, return it
72
+ if (this.token && (!this.tokenExpiresAt || this.tokenExpiresAt > Date.now())) {
73
+ return this.token;
74
+ }
75
+
76
+ if (this.clientId && this.clientSecret) {
77
+ try {
78
+ const response = await axios.post(
79
+ `${this.baseURL}/api/v3/oauth/token`,
80
+ {
81
+ client_id: this.clientId,
82
+ client_secret: this.clientSecret,
83
+ grant_type: 'client_credentials',
84
+ },
85
+ {
86
+ headers: { 'Content-Type': 'application/json' },
87
+ }
88
+ );
89
+
90
+ if (response.data?.success && response.data?.data?.access_token) {
91
+ this.token = response.data.data.access_token;
92
+ if (response.data.data.expires_in) {
93
+ // Expire 10 seconds early as a safety buffer
94
+ this.tokenExpiresAt = Date.now() + (response.data.data.expires_in - 10) * 1000;
95
+ } else {
96
+ this.tokenExpiresAt = null;
97
+ }
98
+ return this.token;
99
+ } else if (response.data?.access_token) {
100
+ // Fallback in case response is not wrapped
101
+ this.token = response.data.access_token;
102
+ if (response.data.expires_in) {
103
+ this.tokenExpiresAt = Date.now() + (response.data.expires_in - 10) * 1000;
104
+ } else {
105
+ this.tokenExpiresAt = null;
106
+ }
107
+ return this.token;
108
+ }
109
+ } catch (error) {
110
+ console.error('ScrymeSDK failed to authenticate via client_credentials:', error);
111
+ throw error;
112
+ }
113
+ }
114
+
115
+ return this.token;
116
+ }
117
+
118
+ /**
119
+ * Gets the axios request config containing authorization and base url
120
+ */
121
+ private async getRequestConfig(): Promise<any> {
122
+ const token = await this.getOrFetchToken();
123
+ return {
124
+ baseURL: `${this.baseURL}/api`,
125
+ headers: {
126
+ ...(token ? { Authorization: `Bearer ${token}` } : {}),
127
+ },
128
+ };
129
+ }
130
+
131
+ /**
132
+ * Dynamic proxy that maps to the generated server API methods from Orval,
133
+ * injecting authentication token and baseURL automatically.
134
+ */
135
+ public get raw(): ReturnType<typeof getSkyrmeChatAPI> {
136
+ const rawMethods = getSkyrmeChatAPI();
137
+ return new Proxy(rawMethods, {
138
+ get: (target, prop) => {
139
+ const originalMethod = Reflect.get(target, prop);
140
+ if (typeof originalMethod === 'function') {
141
+ return async (...args: any[]) => {
142
+ const config = await this.getRequestConfig();
143
+ const arity = originalMethod.length;
144
+ const newArgs = [...args];
145
+
146
+ // Orval generated functions accept `options` as their last parameter.
147
+ // If the user provided options, we merge them with our default request config.
148
+ if (args.length >= arity && typeof args[args.length - 1] === 'object') {
149
+ const userOptions = args[args.length - 1];
150
+ newArgs[args.length - 1] = {
151
+ ...userOptions,
152
+ baseURL: config.baseURL,
153
+ headers: {
154
+ ...config.headers,
155
+ ...userOptions.headers,
156
+ },
157
+ };
158
+ } else {
159
+ // Otherwise, we pad missing parameters with undefined and append our config as the options object.
160
+ while (newArgs.length < arity - 1) {
161
+ newArgs.push(undefined);
162
+ }
163
+ newArgs.push(config);
164
+ }
165
+
166
+ return originalMethod(...newArgs);
167
+ };
168
+ }
169
+ return originalMethod;
170
+ },
171
+ }) as any;
172
+ }
173
+
174
+ // --- High-level nested namespace chains for excellent DX ---
175
+
176
+ public get workspace() {
177
+ return {
178
+ list: async (options?: AxiosRequestConfig): Promise<V3WorkspacesControllerGetWorkspaces200> => {
179
+ return this.raw.v3WorkspacesControllerGetWorkspaces(options);
180
+ },
181
+ get: async (slug: string, options?: AxiosRequestConfig): Promise<V3WorkspacesControllerGetWorkspaceBySlug200> => {
182
+ return this.raw.v3WorkspacesControllerGetWorkspaceBySlug(slug, options);
183
+ },
184
+ create: async (data: V3ProvisionWorkspaceDto, options?: AxiosRequestConfig): Promise<V3WorkspacesControllerProvisionWorkspace201> => {
185
+ return this.raw.v3WorkspacesControllerProvisionWorkspace(data, options);
186
+ },
187
+ update: async (slug: string, data: V3UpdateWorkspaceDto, options?: AxiosRequestConfig): Promise<V3WorkspacesControllerUpdateWorkspace200> => {
188
+ return this.raw.v3WorkspacesControllerUpdateWorkspace(slug, data, options);
189
+ },
190
+ delete: async (slug: string, options?: AxiosRequestConfig): Promise<V3WorkspacesControllerDeleteWorkspace200> => {
191
+ return this.raw.v3WorkspacesControllerDeleteWorkspace(slug, options);
192
+ },
193
+ members: {
194
+ list: async (slug: string, options?: AxiosRequestConfig): Promise<any> => {
195
+ return this.raw.v3WorkspacesControllerGetWorkspaceMembers(slug, options);
196
+ },
197
+ add: async (slug: string, data: V3AddMemberDto, options?: AxiosRequestConfig): Promise<any> => {
198
+ return this.raw.v3WorkspacesControllerAddWorkspaceMember(slug, data, options);
199
+ },
200
+ get: async (slug: string, memberId: string, options?: AxiosRequestConfig): Promise<any> => {
201
+ return this.raw.v3WorkspacesControllerGetWorkspaceMember(slug, memberId, options);
202
+ },
203
+ update: async (slug: string, memberId: string, data: V3UpdateMemberRoleDto, options?: AxiosRequestConfig): Promise<any> => {
204
+ return this.raw.v3WorkspacesControllerUpdateWorkspaceMember(slug, memberId, data, options);
205
+ },
206
+ delete: async (slug: string, memberId: string, options?: AxiosRequestConfig): Promise<any> => {
207
+ return this.raw.v3WorkspacesControllerDeleteWorkspaceMember(slug, memberId, options);
208
+ },
209
+ },
210
+ channels: {
211
+ list: async (slug: string, options?: AxiosRequestConfig): Promise<any> => {
212
+ return this.raw.channelsControllerGetWorkspaceChannels(slug, options);
213
+ },
214
+ create: async (slug: string, data: CreateWorkspaceChannelDto, options?: AxiosRequestConfig): Promise<any> => {
215
+ return this.raw.channelsControllerCreateChannel(slug, data, options);
216
+ },
217
+ },
218
+ };
219
+ }
220
+
221
+ public get channel() {
222
+ return {
223
+ get: async (slug: string, channelId: string, options?: AxiosRequestConfig): Promise<any> => {
224
+ return this.raw.channelsControllerGetChannel(slug, channelId, options);
225
+ },
226
+ update: async (slug: string, channelId: string, data: UpdateWorkspaceChannelDto, options?: AxiosRequestConfig): Promise<any> => {
227
+ return this.raw.channelsControllerUpdateChannel(slug, channelId, data, options);
228
+ },
229
+ delete: async (slug: string, channelId: string, options?: AxiosRequestConfig): Promise<any> => {
230
+ return this.raw.channelsControllerDeleteChannel(slug, channelId, options);
231
+ },
232
+ message: {
233
+ list: async (channelId: string, params?: ChannelsControllerGetMessagesParams, options?: AxiosRequestConfig): Promise<any> => {
234
+ return this.raw.channelsControllerGetMessages(channelId, params, options);
235
+ },
236
+ create: async (channelId: string, options?: AxiosRequestConfig): Promise<any> => {
237
+ return this.raw.channelsControllerCreateMessage(channelId, options);
238
+ },
239
+ },
240
+ };
241
+ }
242
+
243
+ public get message() {
244
+ return {
245
+ update: async (channelId: string, messageId: string, data: ChannelsControllerUpdateMessageBody, options?: AxiosRequestConfig): Promise<any> => {
246
+ return this.raw.channelsControllerUpdateMessage(channelId, messageId, data, options);
247
+ },
248
+ delete: async (channelId: string, messageId: string, options?: AxiosRequestConfig): Promise<any> => {
249
+ return this.raw.channelsControllerDeleteMessage(channelId, messageId, options);
250
+ },
251
+ addReaction: async (channelId: string, messageId: string, data: ChannelsControllerAddReactionBody, options?: AxiosRequestConfig): Promise<any> => {
252
+ return this.raw.channelsControllerAddReaction(channelId, messageId, data, options);
253
+ },
254
+ removeReaction: async (channelId: string, messageId: string, emoji: string, options?: AxiosRequestConfig): Promise<any> => {
255
+ return this.raw.channelsControllerRemoveReaction(channelId, messageId, emoji, options);
256
+ },
257
+ };
258
+ }
259
+
260
+ public get dm() {
261
+ return {
262
+ list: async (options?: AxiosRequestConfig): Promise<any> => {
263
+ return this.raw.dmsControllerGetDms(options);
264
+ },
265
+ create: async (data: CreateDmDto, options?: AxiosRequestConfig): Promise<any> => {
266
+ return this.raw.dmsControllerCreateDm(data, options);
267
+ },
268
+ get: async (dmId: string, options?: AxiosRequestConfig): Promise<any> => {
269
+ return this.raw.dmsControllerGetDm(dmId, options);
270
+ },
271
+ delete: async (dmId: string, options?: AxiosRequestConfig): Promise<any> => {
272
+ return this.raw.dmsControllerDeleteDm(dmId, options);
273
+ },
274
+ message: {
275
+ list: async (dmId: string, params?: DmsControllerGetMessagesParams, options?: AxiosRequestConfig): Promise<any> => {
276
+ return this.raw.dmsControllerGetMessages(dmId, params, options);
277
+ },
278
+ create: async (dmId: string, options?: AxiosRequestConfig): Promise<any> => {
279
+ return this.raw.dmsControllerCreateMessage(dmId, options);
280
+ },
281
+ },
282
+ };
283
+ }
284
+
285
+ public get user() {
286
+ return {
287
+ me: async (options?: AxiosRequestConfig): Promise<any> => {
288
+ return this.raw.usersControllerGetMe(options);
289
+ },
290
+ get: async (userId: string, options?: AxiosRequestConfig): Promise<any> => {
291
+ return this.raw.usersControllerGetUser(userId, options);
292
+ },
293
+ search: async (params: UsersControllerSearchUsersParams, options?: AxiosRequestConfig): Promise<any> => {
294
+ return this.raw.usersControllerSearchUsers(params, options);
295
+ },
296
+ };
297
+ }
298
+ }
package/src/server.ts ADDED
@@ -0,0 +1,3 @@
1
+ export * from './custom-instance';
2
+ export * from './generated/v3-server';
3
+ export * from './sdk';