@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/README.md ADDED
@@ -0,0 +1,166 @@
1
+ # Scryme Chat TypeScript SDK (`@scryme/chat`)
2
+
3
+ A high-performance, developer-friendly, fully typed TypeScript/JavaScript SDK for interacting with the Skyrme Chat V2 and V3 Enterprise APIs.
4
+
5
+ Designed primarily for backend integrations, servers, and automated Machine-to-Machine (M2M) environments, this SDK provides unmatched DX with automatic OAuth2 token management, dynamic API proxying, and fluent nested helper chains.
6
+
7
+ ---
8
+
9
+ ## Features
10
+
11
+ - **OAuth2 Client Credentials Grant**: Built-in, fully automated caching and renewal of M2M access tokens with timing-safe, proactive expiration buffers.
12
+ - **Dynamic Method Proxying (`sdk.raw`)**: Automatic injection of Bearer token and Base URL headers into any of the 100+ generated V3 API endpoints with complete TypeScript autocompletion.
13
+ - **Fluent Nested Namespaces**: High-level, developer-friendly helper routes (`sdk.workspace`, `sdk.channel`, `sdk.message`, etc.) for seamless workspace, department, team, and member administration.
14
+ - **Isomorphic Support**: Works out-of-the-box in Node.js, Next.js (server/client), Vite, and React Native.
15
+
16
+ ---
17
+
18
+ ## Installation
19
+
20
+ ```bash
21
+ npm install @scryme/chat
22
+ # or
23
+ pnpm add @scryme/chat
24
+ # or
25
+ yarn add @scryme/chat
26
+ ```
27
+
28
+ ---
29
+
30
+ ## Getting Started
31
+
32
+ ### 1. Initialize the SDK
33
+
34
+ You can initialize `ScrymeSDK` using a static bearer token or using M2M client credentials (`clientId` and `clientSecret`) to enable auto-authentication.
35
+
36
+ ```typescript
37
+ import { ScrymeSDK } from '@scryme/chat';
38
+
39
+ // Option A: Machine-to-Machine (M2M) Auth (Highly recommended for servers/bots)
40
+ const sdk = new ScrymeSDK({
41
+ baseURL: 'https://api.chat.scryme.tech',
42
+ clientId: 'm2m_client_abc123',
43
+ clientSecret: 'sk_m2m_secret_xyz789',
44
+ });
45
+
46
+ // Option B: Static Bearer Token Auth
47
+ const sdkWithToken = new ScrymeSDK({
48
+ baseURL: 'https://api.chat.scryme.tech',
49
+ token: 'oat_your_token_here',
50
+ });
51
+ ```
52
+
53
+ ---
54
+
55
+ ## Usage Guide
56
+
57
+ ### High-Level Fluent Namespaces (Excellent DX)
58
+
59
+ For standard CRUD workflows, utilize our intuitive nested namespace chains:
60
+
61
+ #### Workspaces
62
+ ```typescript
63
+ // List all workspaces associated with the organization
64
+ const workspaces = await sdk.workspace.list();
65
+
66
+ // Provision/Create a new tenant workspace
67
+ const newWorkspace = await sdk.workspace.create({
68
+ name: 'Acme Corp',
69
+ slug: 'acme-corp',
70
+ ownerEmail: 'admin@acme.com',
71
+ channels: ['general', 'engineering'],
72
+ });
73
+
74
+ // Retrieve detailed workspace metadata
75
+ const workspace = await sdk.workspace.get('acme-corp');
76
+
77
+ // Update workspace branding or details
78
+ await sdk.workspace.update('acme-corp', {
79
+ name: 'Acme Corp International',
80
+ description: 'Updated team workspace',
81
+ });
82
+
83
+ // Delete a workspace
84
+ await sdk.workspace.delete('acme-corp');
85
+ ```
86
+
87
+ #### Workspace Members
88
+ ```typescript
89
+ // List workspace members
90
+ const members = await sdk.workspace.members.list('acme-corp');
91
+
92
+ // Invite/Add a new member
93
+ await sdk.workspace.members.add('acme-corp', {
94
+ email: 'developer@acme.com',
95
+ role: 'member',
96
+ });
97
+
98
+ // Remove a member
99
+ await sdk.workspace.members.delete('acme-corp', 'member_id_xyz');
100
+ ```
101
+
102
+ #### Channels & Messaging
103
+ ```typescript
104
+ // List channels in a workspace
105
+ const channels = await sdk.workspace.channels.list('acme-corp');
106
+
107
+ // Create a new channel
108
+ const channel = await sdk.workspace.channels.create('acme-corp', {
109
+ name: 'announcements',
110
+ type: 'text',
111
+ });
112
+
113
+ // Send a message to a channel
114
+ await sdk.channel.message.create('channel_id_123', {
115
+ content: 'Hello Team! This is automated via our new TS SDK 🚀',
116
+ });
117
+
118
+ // Fetch channel messages
119
+ const messages = await sdk.channel.message.list('channel_id_123', { limit: 10 });
120
+ ```
121
+
122
+ ---
123
+
124
+ ### Dynamic API Proxying (`sdk.raw`)
125
+
126
+ If you need lower-level control or need to access raw Orval/Axios endpoints not wrapped in our helper namespaces, use `sdk.raw`.
127
+
128
+ Every raw endpoint:
129
+ 1. Offers **full TypeScript types** for parameters, request body, and response.
130
+ 2. **Automatically injects** the required Bearer Authorization header (fetching or refreshing the M2M token on the fly).
131
+ 3. Resolves to the correct configured API Base URL.
132
+
133
+ ```typescript
134
+ // Access lower-level generated controller methods directly
135
+ const health = await sdk.raw.appControllerGetHealth();
136
+
137
+ // User search
138
+ const users = await sdk.raw.usersControllerSearchUsers({ q: 'alice' });
139
+
140
+ // Fully typed update workspace webhook call
141
+ const webhook = await sdk.raw.v3WebhooksControllerCreateWebhook('acme-corp', {
142
+ name: 'Slack Sync Sync',
143
+ url: 'https://hooks.slack.com/services/...',
144
+ events: ['message.created'],
145
+ });
146
+ ```
147
+
148
+ ---
149
+
150
+ ## Development
151
+
152
+ ### Compile the SDK
153
+ ```bash
154
+ pnpm build
155
+ ```
156
+
157
+ ### Run Unit Tests
158
+ ```bash
159
+ pnpm test
160
+ ```
161
+
162
+ ---
163
+
164
+ ## License
165
+
166
+ MIT © Skyrme Chat Enterprise
@@ -0,0 +1,2 @@
1
+ export * from './custom-instance';
2
+ export * from './generated/v3-client';
package/dist/client.js ADDED
@@ -0,0 +1,2 @@
1
+ export * from './custom-instance';
2
+ export * from './generated/v3-client';
@@ -0,0 +1,5 @@
1
+ import { AxiosRequestConfig, AxiosError } from 'axios';
2
+ export declare const AXIOS_INSTANCE: import("axios").AxiosInstance;
3
+ export declare const customInstance: <T>(config: AxiosRequestConfig, options?: AxiosRequestConfig) => Promise<T>;
4
+ export type ErrorType<Error> = AxiosError<Error>;
5
+ export type BodyType<Body> = Body;
@@ -0,0 +1,100 @@
1
+ var __assign = (this && this.__assign) || function () {
2
+ __assign = Object.assign || function(t) {
3
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
4
+ s = arguments[i];
5
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
6
+ t[p] = s[p];
7
+ }
8
+ return t;
9
+ };
10
+ return __assign.apply(this, arguments);
11
+ };
12
+ import axios from 'axios';
13
+ // Helper to safely access env variables across Vite, Next.js and React Native
14
+ var getEnv = function (name) {
15
+ var _a, _b, _c;
16
+ var g = globalThis;
17
+ // Try various common locations for env variables
18
+ // Avoid explicit import.meta to prevent TS1470
19
+ var env = ((_a = g.process) === null || _a === void 0 ? void 0 : _a.env) || ((_c = (_b = g.import) === null || _b === void 0 ? void 0 : _b.meta) === null || _c === void 0 ? void 0 : _c.env) || g.__env__;
20
+ if (!env)
21
+ return undefined;
22
+ return (env[name] || env["VITE_".concat(name)] || env["NEXT_PUBLIC_".concat(name)] || env["EXPO_PUBLIC_".concat(name)] || env["TAURI_".concat(name)]);
23
+ };
24
+ var getBaseURL = function () {
25
+ var url = '';
26
+ if (typeof window !== 'undefined') {
27
+ var customUrl = window.localStorage.getItem('CUSTOM_API_URL');
28
+ if (customUrl) {
29
+ url = customUrl;
30
+ }
31
+ }
32
+ if (!url) {
33
+ var isProd = (typeof process !== 'undefined' && process.env && process.env.NODE_ENV === 'production') ||
34
+ getEnv('NODE_ENV') === 'production' ||
35
+ (typeof window !== 'undefined' && window.location.hostname !== 'localhost' && window.location.hostname !== '127.0.0.1');
36
+ url = getEnv('API_URL') || getEnv('NEXT_PUBLIC_API_URL') || (isProd ? 'https://api.chat.scryme.tech' : 'http://localhost:3000');
37
+ }
38
+ return url.replace(/\/$/, '') + '/api';
39
+ };
40
+ export var AXIOS_INSTANCE = axios.create({
41
+ baseURL: getBaseURL(),
42
+ timeout: 10000,
43
+ withCredentials: true,
44
+ });
45
+ AXIOS_INSTANCE.interceptors.request.use(function (config) {
46
+ if (typeof window !== 'undefined') {
47
+ var getCookie = function (name) {
48
+ var _a;
49
+ var value = "; ".concat(document.cookie);
50
+ var parts = value.split("; ".concat(name, "="));
51
+ if (parts.length === 2)
52
+ return ((_a = parts.pop()) === null || _a === void 0 ? void 0 : _a.split(';').shift()) || null;
53
+ return null;
54
+ };
55
+ var token = window.localStorage.getItem('better-auth.session-token') ||
56
+ window.localStorage.getItem('better-auth.session_token') ||
57
+ window.localStorage.getItem('bearer_token');
58
+ if (!token) {
59
+ token =
60
+ getCookie('better-auth.session_token') ||
61
+ getCookie('better-auth.session-token') ||
62
+ getCookie('bearer_token');
63
+ if (token) {
64
+ window.localStorage.setItem('better-auth.session_token', token);
65
+ window.localStorage.setItem('better-auth.session-token', token);
66
+ window.localStorage.setItem('bearer_token', token);
67
+ }
68
+ }
69
+ else {
70
+ // Keep everything in sync
71
+ if (!window.localStorage.getItem('bearer_token')) {
72
+ window.localStorage.setItem('bearer_token', token);
73
+ }
74
+ if (!window.localStorage.getItem('better-auth.session_token')) {
75
+ window.localStorage.setItem('better-auth.session_token', token);
76
+ }
77
+ if (!window.localStorage.getItem('better-auth.session-token')) {
78
+ window.localStorage.setItem('better-auth.session-token', token);
79
+ }
80
+ }
81
+ if (token) {
82
+ config.headers.Authorization = "Bearer ".concat(token);
83
+ }
84
+ }
85
+ return config;
86
+ });
87
+ export var customInstance = function (config, options) {
88
+ var source = axios.CancelToken.source();
89
+ // Merge headers carefully so that options.headers does not overwrite config.headers completely
90
+ var mergedHeaders = __assign(__assign({}, config.headers), options === null || options === void 0 ? void 0 : options.headers);
91
+ var promise = AXIOS_INSTANCE(__assign(__assign(__assign({}, config), options), { headers: mergedHeaders, cancelToken: source.token })).then(function (_a) {
92
+ var data = _a.data;
93
+ return data;
94
+ });
95
+ // @ts-ignore
96
+ promise.cancel = function () {
97
+ source.cancel('Query was cancelled by React Query');
98
+ };
99
+ return promise;
100
+ };