@sayrio/public 0.0.5
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 +264 -0
- package/dist/index.cjs +356 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +258 -0
- package/dist/index.d.ts +258 -0
- package/dist/index.js +324 -0
- package/dist/index.js.map +1 -0
- package/dist/react/index.cjs +431 -0
- package/dist/react/index.cjs.map +1 -0
- package/dist/react/index.d.cts +88 -0
- package/dist/react/index.d.ts +88 -0
- package/dist/react/index.js +400 -0
- package/dist/react/index.js.map +1 -0
- package/package.json +46 -0
package/README.md
ADDED
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
# @sayrio/public
|
|
2
|
+
|
|
3
|
+
Public JavaScript & TypeScript SDK for **Sayr.io**.
|
|
4
|
+
Provides **read‑only access** to Sayr organizations, tasks, comments, and
|
|
5
|
+
real‑time updates via WebSockets.
|
|
6
|
+
|
|
7
|
+
- ✅ REST + WebSocket
|
|
8
|
+
- ✅ Browser‑safe
|
|
9
|
+
- ✅ TypeScript first
|
|
10
|
+
- ✅ Zero runtime dependencies
|
|
11
|
+
- ✅ Versioned API (`v1`)
|
|
12
|
+
|
|
13
|
+
> React hooks are available via the **`@sayrio/public/react`** sub‑path export.
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install @sayrio/public
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
or
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
pnpm add @sayrio/public
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Usage
|
|
32
|
+
|
|
33
|
+
### Basic Usage (REST)
|
|
34
|
+
|
|
35
|
+
Fetch public organization data.
|
|
36
|
+
|
|
37
|
+
`Sayr.org` is an alias for the current API version (`v1`):
|
|
38
|
+
|
|
39
|
+
```ts
|
|
40
|
+
import Sayr from "@sayrio/public";
|
|
41
|
+
|
|
42
|
+
const org = await Sayr.org.get("acme");
|
|
43
|
+
|
|
44
|
+
console.log(org.name);
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
You can also use the versioned API explicitly:
|
|
48
|
+
|
|
49
|
+
```ts
|
|
50
|
+
const org = await Sayr.v1.org.get("acme");
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
### Listing Tasks
|
|
56
|
+
|
|
57
|
+
Retrieve tasks for an organization:
|
|
58
|
+
|
|
59
|
+
```ts
|
|
60
|
+
const { data: tasks } = await Sayr.org.tasks.list("acme", {
|
|
61
|
+
order: "desc",
|
|
62
|
+
limit: 10
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
console.log(tasks);
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
### Fetching a Single Task
|
|
71
|
+
|
|
72
|
+
```ts
|
|
73
|
+
const task = await Sayr.org.tasks.get("acme", 42);
|
|
74
|
+
|
|
75
|
+
console.log(task.title);
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
### Task Comments
|
|
81
|
+
|
|
82
|
+
Fetch comments for a specific task:
|
|
83
|
+
|
|
84
|
+
```ts
|
|
85
|
+
const { data: comments } =
|
|
86
|
+
await Sayr.org.comments.list("acme", 42);
|
|
87
|
+
|
|
88
|
+
console.log(comments);
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
### Labels & Categories
|
|
94
|
+
|
|
95
|
+
```ts
|
|
96
|
+
const labels = await Sayr.org.labels.list("acme");
|
|
97
|
+
const categories = await Sayr.org.categories.list("acme");
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## Authenticated User (`/me`)
|
|
103
|
+
|
|
104
|
+
The `/me` namespace provides **read‑only access** to the currently
|
|
105
|
+
authenticated user.
|
|
106
|
+
|
|
107
|
+
> Authentication is required.
|
|
108
|
+
> Set a token using `Sayr.client.setToken(...)`.
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
### Fetch Current User
|
|
113
|
+
|
|
114
|
+
```ts
|
|
115
|
+
Sayr.client.setToken(token);
|
|
116
|
+
|
|
117
|
+
const me = await Sayr.me.get();
|
|
118
|
+
|
|
119
|
+
console.log(me.email);
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
### List Your Organizations
|
|
125
|
+
|
|
126
|
+
```ts
|
|
127
|
+
const orgs = await Sayr.me.organizations();
|
|
128
|
+
|
|
129
|
+
console.log(orgs);
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
## Real‑Time Updates (WebSocket)
|
|
135
|
+
|
|
136
|
+
Subscribe to public real‑time events using WebSockets:
|
|
137
|
+
|
|
138
|
+
```ts
|
|
139
|
+
Sayr.ws(org.wsUrl, {
|
|
140
|
+
[Sayr.WS_EVENTS.UPDATE_TASK]: (task) => {
|
|
141
|
+
console.log("Task updated", task);
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### WebSocket Features
|
|
147
|
+
|
|
148
|
+
- Automatic reconnection
|
|
149
|
+
- Heartbeat support (PING / PONG)
|
|
150
|
+
- Typed event constants
|
|
151
|
+
- Public‑safe payloads only
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
## Browser Usage (No Bundler)
|
|
156
|
+
|
|
157
|
+
```html
|
|
158
|
+
<script type="module">
|
|
159
|
+
import Sayr from "https://esm.sh/@sayrio/public";
|
|
160
|
+
|
|
161
|
+
const org = await Sayr.org.get("acme");
|
|
162
|
+
console.log(org);
|
|
163
|
+
</script>
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## API
|
|
169
|
+
|
|
170
|
+
### `Sayr.org` (latest)
|
|
171
|
+
|
|
172
|
+
Alias for `Sayr.v1.org`.
|
|
173
|
+
|
|
174
|
+
#### Organization
|
|
175
|
+
|
|
176
|
+
| Method | Description |
|
|
177
|
+
| ----------- | --------------------------- |
|
|
178
|
+
| `get(slug)` | Fetch a public organization |
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
#### Tasks
|
|
183
|
+
|
|
184
|
+
| Method | Description |
|
|
185
|
+
| --------------------------- | ---------------------- |
|
|
186
|
+
| `tasks.list(slug, opts?)` | List tasks (paginated) |
|
|
187
|
+
| `tasks.get(slug, shortId)` | Fetch a single task |
|
|
188
|
+
|
|
189
|
+
---
|
|
190
|
+
|
|
191
|
+
#### Comments
|
|
192
|
+
|
|
193
|
+
| Method | Description |
|
|
194
|
+
| ------------------------------------- | ------------------ |
|
|
195
|
+
| `comments.list(slug, shortId, opts?)` | List task comments |
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
#### Labels
|
|
200
|
+
|
|
201
|
+
| Method | Description |
|
|
202
|
+
| ------------------- | ------------------------ |
|
|
203
|
+
| `labels.list(slug)` | List organization labels |
|
|
204
|
+
|
|
205
|
+
---
|
|
206
|
+
|
|
207
|
+
#### Categories
|
|
208
|
+
|
|
209
|
+
| Method | Description |
|
|
210
|
+
| ------------------------------ | --------------- |
|
|
211
|
+
| `categories.list(slug, order?)` | List categories |
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
### `Sayr.me`
|
|
216
|
+
|
|
217
|
+
Authenticated user endpoints.
|
|
218
|
+
|
|
219
|
+
| Method | Description |
|
|
220
|
+
| ------------------- | -------------------------------------- |
|
|
221
|
+
| `get()` | Fetch the current authenticated user |
|
|
222
|
+
| `organizations()` | List organizations the user belongs to |
|
|
223
|
+
|
|
224
|
+
---
|
|
225
|
+
|
|
226
|
+
### `Sayr.ws(url, handlers)`
|
|
227
|
+
|
|
228
|
+
Create a WebSocket connection for public events:
|
|
229
|
+
|
|
230
|
+
```ts
|
|
231
|
+
const conn = Sayr.ws(wsUrl, {
|
|
232
|
+
UPDATE_TASK: () => {}
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
conn.close();
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
---
|
|
239
|
+
|
|
240
|
+
### `WS_EVENTS`
|
|
241
|
+
|
|
242
|
+
Typed WebSocket event constants:
|
|
243
|
+
|
|
244
|
+
```ts
|
|
245
|
+
Sayr.WS_EVENTS.UPDATE_TASK;
|
|
246
|
+
Sayr.WS_EVENTS.UPDATE_ORG;
|
|
247
|
+
Sayr.WS_EVENTS.ERROR;
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
---
|
|
251
|
+
|
|
252
|
+
## TypeScript
|
|
253
|
+
|
|
254
|
+
This package ships with full TypeScript definitions:
|
|
255
|
+
|
|
256
|
+
```ts
|
|
257
|
+
import type {
|
|
258
|
+
Organization,
|
|
259
|
+
Task,
|
|
260
|
+
Comment
|
|
261
|
+
} from "@sayrio/public";
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
---
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,356 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
SayrClient: () => SayrClient,
|
|
24
|
+
SayrV1: () => SayrV1,
|
|
25
|
+
SayrWS: () => SayrWS,
|
|
26
|
+
SayrWSEvents: () => SayrWSEvents,
|
|
27
|
+
WS_EVENTS: () => WS_EVENTS,
|
|
28
|
+
buildPaginationParams: () => buildPaginationParams,
|
|
29
|
+
default: () => index_default
|
|
30
|
+
});
|
|
31
|
+
module.exports = __toCommonJS(index_exports);
|
|
32
|
+
|
|
33
|
+
// src/client/index.ts
|
|
34
|
+
var DEFAULT_API = "https://api.sayr.io";
|
|
35
|
+
var config = {
|
|
36
|
+
fetch: globalThis.fetch,
|
|
37
|
+
baseUrl: DEFAULT_API
|
|
38
|
+
};
|
|
39
|
+
var hooks = {};
|
|
40
|
+
function setToken(token) {
|
|
41
|
+
config.token = token;
|
|
42
|
+
}
|
|
43
|
+
function setHeaders(headers) {
|
|
44
|
+
config.headers = {
|
|
45
|
+
...config.headers,
|
|
46
|
+
...headers
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
function setFetch(fn) {
|
|
50
|
+
config.fetch = fn;
|
|
51
|
+
}
|
|
52
|
+
function setBaseUrl(url) {
|
|
53
|
+
config.baseUrl = url.replace(/\/$/, "");
|
|
54
|
+
}
|
|
55
|
+
function setHooks(h) {
|
|
56
|
+
Object.assign(hooks, h);
|
|
57
|
+
}
|
|
58
|
+
function resetClient() {
|
|
59
|
+
config.token = void 0;
|
|
60
|
+
config.headers = void 0;
|
|
61
|
+
config.baseUrl = DEFAULT_API;
|
|
62
|
+
}
|
|
63
|
+
async function request(path, opts = {}) {
|
|
64
|
+
const url = path.startsWith("http") ? path : `${config.baseUrl}${path}`;
|
|
65
|
+
hooks.onRequest?.(url, opts);
|
|
66
|
+
let res;
|
|
67
|
+
try {
|
|
68
|
+
res = await config.fetch(url, {
|
|
69
|
+
method: opts.method ?? "GET",
|
|
70
|
+
headers: {
|
|
71
|
+
...config.token ? { Authorization: `Bearer ${config.token}` } : {},
|
|
72
|
+
...opts.body ? { "Content-Type": "application/json" } : {},
|
|
73
|
+
...config.headers,
|
|
74
|
+
...opts.headers
|
|
75
|
+
},
|
|
76
|
+
body: opts.body ? JSON.stringify(opts.body) : void 0,
|
|
77
|
+
signal: opts.signal
|
|
78
|
+
});
|
|
79
|
+
} catch (err) {
|
|
80
|
+
const error = {
|
|
81
|
+
success: false,
|
|
82
|
+
error: "NETWORK_ERROR",
|
|
83
|
+
message: "Failed to reach Sayr API"
|
|
84
|
+
};
|
|
85
|
+
hooks.onError?.(error);
|
|
86
|
+
throw error;
|
|
87
|
+
}
|
|
88
|
+
hooks.onResponse?.(res);
|
|
89
|
+
let json;
|
|
90
|
+
try {
|
|
91
|
+
json = await res.json();
|
|
92
|
+
} catch {
|
|
93
|
+
const error = {
|
|
94
|
+
success: false,
|
|
95
|
+
error: "INVALID_RESPONSE",
|
|
96
|
+
message: "Server returned invalid JSON",
|
|
97
|
+
status: res.status
|
|
98
|
+
};
|
|
99
|
+
hooks.onError?.(error);
|
|
100
|
+
throw error;
|
|
101
|
+
}
|
|
102
|
+
if (!res.ok || !json.success) {
|
|
103
|
+
const error = {
|
|
104
|
+
...json,
|
|
105
|
+
success: false,
|
|
106
|
+
status: res.status
|
|
107
|
+
};
|
|
108
|
+
hooks.onError?.(error);
|
|
109
|
+
throw error;
|
|
110
|
+
}
|
|
111
|
+
return json;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// src/api/v1/org/org.ts
|
|
115
|
+
var org_default = {
|
|
116
|
+
/**
|
|
117
|
+
* Fetches a public organization by slug.
|
|
118
|
+
*
|
|
119
|
+
* @since v1.0.0
|
|
120
|
+
*/
|
|
121
|
+
async get(slug, opts) {
|
|
122
|
+
const r = await request(
|
|
123
|
+
`/v1/organization/${slug}`,
|
|
124
|
+
opts
|
|
125
|
+
);
|
|
126
|
+
return r.data;
|
|
127
|
+
}
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
// src/shared/index.ts
|
|
131
|
+
function buildPaginationParams(params) {
|
|
132
|
+
return new URLSearchParams({
|
|
133
|
+
order: params?.order ?? "desc",
|
|
134
|
+
limit: String(params?.limit ?? 5),
|
|
135
|
+
page: String(params?.page ?? 1)
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// src/api/v1/org/tasks.ts
|
|
140
|
+
var tasks_default = {
|
|
141
|
+
/**
|
|
142
|
+
* Lists public tasks for an organization.
|
|
143
|
+
*
|
|
144
|
+
* @since v1.0.0
|
|
145
|
+
*/
|
|
146
|
+
async list(slug, params, opts) {
|
|
147
|
+
const q = buildPaginationParams(params);
|
|
148
|
+
const r = await request(
|
|
149
|
+
`/v1/organization/${slug}/tasks?${q}`,
|
|
150
|
+
opts
|
|
151
|
+
);
|
|
152
|
+
return {
|
|
153
|
+
data: r.data,
|
|
154
|
+
pagination: r.pagination
|
|
155
|
+
};
|
|
156
|
+
},
|
|
157
|
+
/**
|
|
158
|
+
* Fetches a single public task by short ID.
|
|
159
|
+
*
|
|
160
|
+
* @since v1.0.0
|
|
161
|
+
*/
|
|
162
|
+
async get(slug, shortId, opts) {
|
|
163
|
+
const r = await request(
|
|
164
|
+
`/v1/organization/${slug}/tasks/${shortId}`,
|
|
165
|
+
opts
|
|
166
|
+
);
|
|
167
|
+
return r.data;
|
|
168
|
+
}
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
// src/api/v1/org/comments.ts
|
|
172
|
+
var comments_default = {
|
|
173
|
+
/**
|
|
174
|
+
* Lists public comments for a task.
|
|
175
|
+
*
|
|
176
|
+
* @since v1.0.0
|
|
177
|
+
*/
|
|
178
|
+
async list(slug, shortId, params, opts) {
|
|
179
|
+
const q = buildPaginationParams(params);
|
|
180
|
+
const r = await request(
|
|
181
|
+
`/v1/organization/${slug}/tasks/${shortId}/comments?${q}`,
|
|
182
|
+
opts
|
|
183
|
+
);
|
|
184
|
+
return {
|
|
185
|
+
data: r.data,
|
|
186
|
+
pagination: r.pagination
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
// src/api/v1/org/labels.ts
|
|
192
|
+
var labels_default = {
|
|
193
|
+
/**
|
|
194
|
+
* Lists public labels for an organization.
|
|
195
|
+
*
|
|
196
|
+
* @since v1.0.0
|
|
197
|
+
*/
|
|
198
|
+
async list(slug, opts) {
|
|
199
|
+
const r = await request(
|
|
200
|
+
`/v1/organization/${slug}/labels`,
|
|
201
|
+
opts
|
|
202
|
+
);
|
|
203
|
+
return r.data;
|
|
204
|
+
}
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
// src/api/v1/org/categories.ts
|
|
208
|
+
var categories_default = {
|
|
209
|
+
/**
|
|
210
|
+
* Lists public categories for an organization.
|
|
211
|
+
*
|
|
212
|
+
* @since v1.0.0
|
|
213
|
+
*/
|
|
214
|
+
async list(slug, order = "desc", opts) {
|
|
215
|
+
const r = await request(
|
|
216
|
+
`/v1/organization/${slug}/categories?order=${order}`,
|
|
217
|
+
opts
|
|
218
|
+
);
|
|
219
|
+
return r.data;
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
// src/api/v1/org/index.ts
|
|
224
|
+
var OrgAPI = {
|
|
225
|
+
...org_default,
|
|
226
|
+
tasks: tasks_default,
|
|
227
|
+
comments: comments_default,
|
|
228
|
+
labels: labels_default,
|
|
229
|
+
categories: categories_default
|
|
230
|
+
};
|
|
231
|
+
var org_default2 = OrgAPI;
|
|
232
|
+
|
|
233
|
+
// src/api/v1/me/index.ts
|
|
234
|
+
var me_default = {
|
|
235
|
+
/**
|
|
236
|
+
* Fetches the currently authenticated user.
|
|
237
|
+
*
|
|
238
|
+
* @since v1.0.0
|
|
239
|
+
*/
|
|
240
|
+
async get(opts) {
|
|
241
|
+
const r = await request(
|
|
242
|
+
"/me",
|
|
243
|
+
opts
|
|
244
|
+
);
|
|
245
|
+
return r.data;
|
|
246
|
+
},
|
|
247
|
+
/**
|
|
248
|
+
* Lists organizations the current user belongs to.
|
|
249
|
+
*
|
|
250
|
+
* @since v1.0.0
|
|
251
|
+
*/
|
|
252
|
+
async organizations(opts) {
|
|
253
|
+
const r = await request(
|
|
254
|
+
"/organizations",
|
|
255
|
+
opts
|
|
256
|
+
);
|
|
257
|
+
return r.data;
|
|
258
|
+
}
|
|
259
|
+
};
|
|
260
|
+
|
|
261
|
+
// src/api/v1/index.ts
|
|
262
|
+
var v1 = {
|
|
263
|
+
org: org_default2,
|
|
264
|
+
me: me_default
|
|
265
|
+
};
|
|
266
|
+
var v1_default = v1;
|
|
267
|
+
|
|
268
|
+
// src/ws/types.ts
|
|
269
|
+
var WS_EVENTS = {
|
|
270
|
+
CONNECTION_STATUS: "CONNECTION_STATUS",
|
|
271
|
+
SUBSCRIBED: "SUBSCRIBED",
|
|
272
|
+
ERROR: "ERROR",
|
|
273
|
+
PING: "PING",
|
|
274
|
+
PONG: "PONG",
|
|
275
|
+
UPDATE_ORG: "UPDATE_ORG",
|
|
276
|
+
CREATE_TASK: "CREATE_TASK",
|
|
277
|
+
UPDATE_TASK: "UPDATE_TASK",
|
|
278
|
+
UPDATE_TASK_COMMENTS: "UPDATE_TASK_COMMENTS",
|
|
279
|
+
UPDATE_TASK_VOTE: "UPDATE_TASK_VOTE",
|
|
280
|
+
UPDATE_LABELS: "UPDATE_LABELS",
|
|
281
|
+
UPDATE_VIEWS: "UPDATE_VIEWS",
|
|
282
|
+
UPDATE_CATEGORIES: "UPDATE_CATEGORIES",
|
|
283
|
+
UPDATE_ISSUE_TEMPLATES: "UPDATE_ISSUE_TEMPLATES",
|
|
284
|
+
DISCONNECTED: "DISCONNECTED"
|
|
285
|
+
};
|
|
286
|
+
|
|
287
|
+
// src/ws/index.ts
|
|
288
|
+
function ws(url, handlers = {}) {
|
|
289
|
+
if (!url) {
|
|
290
|
+
throw new Error(
|
|
291
|
+
"[Sayr.ws] WebSocket URL is required. Did you forget to pass org.wsUrl?"
|
|
292
|
+
);
|
|
293
|
+
}
|
|
294
|
+
let socket;
|
|
295
|
+
let retry = 0;
|
|
296
|
+
let closed = false;
|
|
297
|
+
function connect() {
|
|
298
|
+
if (closed) return;
|
|
299
|
+
socket = new WebSocket(url);
|
|
300
|
+
socket.onmessage = (e) => {
|
|
301
|
+
const msg = JSON.parse(e.data);
|
|
302
|
+
if (msg.type === WS_EVENTS.PING) {
|
|
303
|
+
socket.send(JSON.stringify({ type: WS_EVENTS.PONG }));
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
handlers[msg.type]?.(msg.data, msg);
|
|
307
|
+
};
|
|
308
|
+
socket.onclose = () => {
|
|
309
|
+
if (closed) return;
|
|
310
|
+
setTimeout(connect, Math.min(1e3 * 2 ** retry++, 3e4));
|
|
311
|
+
};
|
|
312
|
+
socket.onerror = () => socket.close();
|
|
313
|
+
}
|
|
314
|
+
connect();
|
|
315
|
+
return {
|
|
316
|
+
close() {
|
|
317
|
+
closed = true;
|
|
318
|
+
socket?.close();
|
|
319
|
+
}
|
|
320
|
+
};
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
// src/index.ts
|
|
324
|
+
var SayrV1 = v1_default;
|
|
325
|
+
var SayrWS = ws;
|
|
326
|
+
var SayrWSEvents = WS_EVENTS;
|
|
327
|
+
var SayrClient = {
|
|
328
|
+
setToken,
|
|
329
|
+
setHeaders,
|
|
330
|
+
setBaseUrl,
|
|
331
|
+
resetClient,
|
|
332
|
+
setHooks,
|
|
333
|
+
setFetch
|
|
334
|
+
};
|
|
335
|
+
var Sayr = {
|
|
336
|
+
// client configuration
|
|
337
|
+
client: SayrClient,
|
|
338
|
+
// APIs
|
|
339
|
+
v1: v1_default,
|
|
340
|
+
org: v1_default.org,
|
|
341
|
+
me: v1_default.me,
|
|
342
|
+
// realtime
|
|
343
|
+
ws,
|
|
344
|
+
WS_EVENTS
|
|
345
|
+
};
|
|
346
|
+
var index_default = Sayr;
|
|
347
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
348
|
+
0 && (module.exports = {
|
|
349
|
+
SayrClient,
|
|
350
|
+
SayrV1,
|
|
351
|
+
SayrWS,
|
|
352
|
+
SayrWSEvents,
|
|
353
|
+
WS_EVENTS,
|
|
354
|
+
buildPaginationParams
|
|
355
|
+
});
|
|
356
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/client/index.ts","../src/api/v1/org/org.ts","../src/shared/index.ts","../src/api/v1/org/tasks.ts","../src/api/v1/org/comments.ts","../src/api/v1/org/labels.ts","../src/api/v1/org/categories.ts","../src/api/v1/org/index.ts","../src/api/v1/me/index.ts","../src/api/v1/index.ts","../src/ws/types.ts","../src/ws/index.ts"],"sourcesContent":["/* ────────────────────────────\r\n API versions\r\n──────────────────────────── */\r\nimport v1 from \"./api/v1\";\r\n\r\n/* ────────────────────────────\r\n Realtime\r\n──────────────────────────── */\r\nimport { ws } from \"./ws\";\r\nimport { WS_EVENTS } from \"./ws/types\";\r\n\r\n/* ────────────────────────────\r\n Client config\r\n──────────────────────────── */\r\nimport {\r\n setToken,\r\n setHeaders,\r\n setBaseUrl,\r\n resetClient,\r\n setHooks,\r\n setFetch\r\n} from \"./client\";\r\n\r\n/* ────────────────────────────\r\n Named exports (power users)\r\n──────────────────────────── */\r\n\r\n/**\r\n * Sayr Public API — Version 1.\r\n *\r\n * @since v1.0.0\r\n */\r\nexport const SayrV1 = v1;\r\n\r\n\r\n/**\r\n * Create a WebSocket connection for public real‑time updates.\r\n */\r\nexport const SayrWS = ws;\r\n\r\n/**\r\n * Typed WebSocket event constants.\r\n */\r\nexport const SayrWSEvents = WS_EVENTS;\r\n\r\n/**\r\n * Global client configuration helpers.\r\n */\r\nexport const SayrClient = {\r\n setToken,\r\n setHeaders,\r\n setBaseUrl,\r\n resetClient,\r\n setHooks,\r\n setFetch\r\n};\r\n\r\n/* ────────────────────────────\r\n Default facade\r\n──────────────────────────── */\r\n\r\n/**\r\n * Sayr Public SDK.\r\n *\r\n * Read‑only access to public Sayr data via REST and WebSockets.\r\n *\r\n * @since v1.0.0\r\n */\r\nconst Sayr: {\r\n /**\r\n * Client configuration helpers.\r\n */\r\n client: typeof SayrClient;\r\n\r\n /**\r\n * Versioned API namespaces.\r\n */\r\n v1: typeof v1;\r\n\r\n /**\r\n * Alias for the current API version (`v1`).\r\n *\r\n * @since v1.0.0\r\n */\r\n org: typeof v1.org;\r\n me: typeof v1.me;\r\n\r\n /**\r\n * WebSocket helper for real‑time updates.\r\n */\r\n ws: typeof ws;\r\n\r\n /**\r\n * WebSocket event constants.\r\n */\r\n WS_EVENTS: typeof WS_EVENTS;\r\n} = {\r\n // client configuration\r\n client: SayrClient,\r\n\r\n // APIs\r\n v1,\r\n org: v1.org,\r\n me: v1.me,\r\n\r\n // realtime\r\n ws,\r\n WS_EVENTS\r\n};\r\n\r\nexport default Sayr;\r\n\r\n/* ────────────────────────────\r\n Types & shared helpers\r\n──────────────────────────── */\r\nexport * from \"./types\";\r\nexport * from \"./shared\";\r\nexport * from \"./ws/types\";","import { ApiError } from \"../types\";\r\n\r\n/* ────────────────────────────\r\n Types\r\n──────────────────────────── */\r\nexport type RequestOptions = {\r\n method?: \"GET\" | \"POST\" | \"PUT\" | \"PATCH\" | \"DELETE\";\r\n headers?: Record<string, string>;\r\n body?: Record<string, string>;\r\n signal?: AbortSignal;\r\n};\r\n\r\ntype Hooks = {\r\n onRequest?: (url: string, opts: RequestOptions) => void;\r\n onResponse?: (res: Response) => void;\r\n onError?: (error: ApiError | unknown) => void;\r\n};\r\n\r\ntype ClientConfig = {\r\n token?: string;\r\n headers?: Record<string, string>;\r\n fetch: typeof fetch;\r\n baseUrl: string;\r\n};\r\n\r\n/* ────────────────────────────\r\n Internal state\r\n──────────────────────────── */\r\nconst DEFAULT_API = \"https://api.sayr.io\";\r\n\r\nconst config: ClientConfig = {\r\n fetch: globalThis.fetch,\r\n baseUrl: DEFAULT_API\r\n};\r\n\r\nconst hooks: Hooks = {};\r\n\r\n/* ────────────────────────────\r\n Public config API\r\n──────────────────────────── */\r\nexport function setToken(token?: string) {\r\n config.token = token;\r\n}\r\n\r\nexport function getToken() {\r\n return config.token;\r\n}\r\n\r\nexport function setHeaders(headers?: Record<string, string>) {\r\n config.headers = {\r\n ...config.headers,\r\n ...headers\r\n };\r\n}\r\n\r\nexport function setFetch(fn: typeof fetch) {\r\n config.fetch = fn;\r\n}\r\n\r\nexport function setBaseUrl(url: string) {\r\n config.baseUrl = url.replace(/\\/$/, \"\");\r\n}\r\n\r\nexport function setHooks(h: Hooks) {\r\n Object.assign(hooks, h);\r\n}\r\n\r\nexport function resetClient() {\r\n config.token = undefined;\r\n config.headers = undefined;\r\n config.baseUrl = DEFAULT_API;\r\n}\r\n\r\n/* ────────────────────────────\r\n Request helper\r\n──────────────────────────── */\r\nexport async function request<T>(\r\n path: string,\r\n opts: RequestOptions = {}\r\n): Promise<T> {\r\n const url = path.startsWith(\"http\")\r\n ? path\r\n : `${config.baseUrl}${path}`;\r\n\r\n hooks.onRequest?.(url, opts);\r\n\r\n let res: Response;\r\n\r\n try {\r\n res = await config.fetch(url, {\r\n method: opts.method ?? \"GET\",\r\n headers: {\r\n ...(config.token\r\n ? { Authorization: `Bearer ${config.token}` }\r\n : {}),\r\n ...(opts.body\r\n ? { \"Content-Type\": \"application/json\" }\r\n : {}),\r\n ...config.headers,\r\n ...opts.headers\r\n },\r\n body: opts.body\r\n ? JSON.stringify(opts.body)\r\n : undefined,\r\n signal: opts.signal\r\n });\r\n } catch (err) {\r\n const error: ApiError = {\r\n success: false,\r\n error: \"NETWORK_ERROR\",\r\n message: \"Failed to reach Sayr API\"\r\n };\r\n hooks.onError?.(error);\r\n throw error;\r\n }\r\n\r\n hooks.onResponse?.(res);\r\n\r\n let json: any;\r\n try {\r\n json = await res.json();\r\n } catch {\r\n const error: ApiError = {\r\n success: false,\r\n error: \"INVALID_RESPONSE\",\r\n message: \"Server returned invalid JSON\",\r\n status: res.status\r\n };\r\n hooks.onError?.(error);\r\n throw error;\r\n }\r\n\r\n if (!res.ok || !json.success) {\r\n const error: ApiError = {\r\n ...json,\r\n success: false,\r\n status: res.status\r\n };\r\n hooks.onError?.(error);\r\n throw error;\r\n }\r\n\r\n return json;\r\n}","import { Organization, ApiSuccess } from \"../../../types\";\r\nimport { request, type RequestOptions } from \"../../../client\";\r\n\r\n/**\r\n * Organization core operations.\r\n */\r\nexport default {\r\n /**\r\n * Fetches a public organization by slug.\r\n *\r\n * @since v1.0.0\r\n */\r\n async get(\r\n slug: string,\r\n opts?: RequestOptions\r\n ): Promise<Organization> {\r\n const r = await request<ApiSuccess<Organization>>(\r\n `/v1/organization/${slug}`,\r\n opts\r\n );\r\n return r.data;\r\n }\r\n};","/* =======================\r\n * Shared params & helpers\r\n * ======================= */\r\n\r\nexport type Order = \"asc\" | \"desc\";\r\n\r\nexport interface PaginationParams {\r\n page?: number;\r\n limit?: number;\r\n}\r\n\r\nexport interface OrderedPaginationParams extends PaginationParams {\r\n order?: Order;\r\n}\r\n\r\nexport function buildPaginationParams(\r\n params?: OrderedPaginationParams\r\n): URLSearchParams {\r\n return new URLSearchParams({\r\n order: params?.order ?? \"desc\",\r\n limit: String(params?.limit ?? 5),\r\n page: String(params?.page ?? 1)\r\n });\r\n}","import {\r\n Task,\r\n Pagination,\r\n ApiSuccess\r\n} from \"../../../types\";\r\nimport { request, type RequestOptions } from \"../../../client\";\r\nimport {\r\n type OrderedPaginationParams,\r\n buildPaginationParams\r\n} from \"../../../shared\";\r\n\r\n/**\r\n * Organization tasks.\r\n */\r\nexport default {\r\n /**\r\n * Lists public tasks for an organization.\r\n *\r\n * @since v1.0.0\r\n */\r\n async list(\r\n slug: string,\r\n params?: OrderedPaginationParams,\r\n opts?: RequestOptions\r\n ): Promise<{ data: Task[]; pagination: Pagination }> {\r\n const q = buildPaginationParams(params);\r\n\r\n const r = await request<\r\n ApiSuccess<Task[]> & { pagination: Pagination }\r\n >(\r\n `/v1/organization/${slug}/tasks?${q}`,\r\n opts\r\n );\r\n\r\n return {\r\n data: r.data,\r\n pagination: r.pagination\r\n };\r\n },\r\n\r\n /**\r\n * Fetches a single public task by short ID.\r\n *\r\n * @since v1.0.0\r\n */\r\n async get(\r\n slug: string,\r\n shortId: number,\r\n opts?: RequestOptions\r\n ): Promise<Task> {\r\n const r = await request<ApiSuccess<Task>>(\r\n `/v1/organization/${slug}/tasks/${shortId}`,\r\n opts\r\n );\r\n return r.data;\r\n }\r\n};","import {\r\n Comment,\r\n Pagination,\r\n ApiSuccess\r\n} from \"../../../types\";\r\nimport { request, type RequestOptions } from \"../../../client\";\r\nimport {\r\n type OrderedPaginationParams,\r\n buildPaginationParams\r\n} from \"../../../shared\";\r\n\r\n/**\r\n * Organization task comments.\r\n */\r\nexport default {\r\n /**\r\n * Lists public comments for a task.\r\n *\r\n * @since v1.0.0\r\n */\r\n async list(\r\n slug: string,\r\n shortId: number,\r\n params?: OrderedPaginationParams,\r\n opts?: RequestOptions\r\n ): Promise<{ data: Comment[]; pagination: Pagination }> {\r\n const q = buildPaginationParams(params);\r\n\r\n const r = await request<\r\n ApiSuccess<Comment[]> & { pagination: Pagination }\r\n >(\r\n `/v1/organization/${slug}/tasks/${shortId}/comments?${q}`,\r\n opts\r\n );\r\n\r\n return {\r\n data: r.data,\r\n pagination: r.pagination\r\n };\r\n }\r\n};","import { Label, ApiSuccess } from \"../../../types\";\r\nimport { request, type RequestOptions } from \"../../../client\";\r\n\r\n/**\r\n * Organization labels.\r\n */\r\nexport default {\r\n /**\r\n * Lists public labels for an organization.\r\n *\r\n * @since v1.0.0\r\n */\r\n async list(\r\n slug: string,\r\n opts?: RequestOptions\r\n ): Promise<Label[]> {\r\n const r = await request<ApiSuccess<Label[]>>(\r\n `/v1/organization/${slug}/labels`,\r\n opts\r\n );\r\n return r.data;\r\n }\r\n};","import {\r\n Category,\r\n ApiSuccess\r\n} from \"../../../types\";\r\nimport { request, type RequestOptions } from \"../../../client\";\r\nimport { type Order } from \"../../../shared\";\r\n\r\n/**\r\n * Organization categories.\r\n */\r\nexport default {\r\n /**\r\n * Lists public categories for an organization.\r\n *\r\n * @since v1.0.0\r\n */\r\n async list(\r\n slug: string,\r\n order: Order = \"desc\",\r\n opts?: RequestOptions\r\n ): Promise<Category[]> {\r\n const r = await request<ApiSuccess<Category[]>>(\r\n `/v1/organization/${slug}/categories?order=${order}`,\r\n opts\r\n );\r\n return r.data;\r\n }\r\n};","import org from \"./org\";\r\nimport tasks from \"./tasks\";\r\nimport comments from \"./comments\";\r\nimport labels from \"./labels\";\r\nimport categories from \"./categories\";\r\n\r\n/**\r\n * Public Sayr Organization API — Version 1.\r\n *\r\n * @since v1.0.0\r\n */\r\nconst OrgAPI = {\r\n ...org,\r\n tasks,\r\n comments,\r\n labels,\r\n categories\r\n};\r\n\r\nexport default OrgAPI;","import { request, type RequestOptions } from \"../../../client\";\r\nimport { ApiSuccess, Organization } from \"../../../types\";\r\n\r\nexport interface Me {\r\n id: string;\r\n name: string | null;\r\n email: string | null;\r\n image: string | null;\r\n createdAt: string;\r\n}\r\n\r\n/**\r\n * Authenticated user API — Version 1.\r\n *\r\n * @since v1.0.0\r\n */\r\nexport default {\r\n /**\r\n * Fetches the currently authenticated user.\r\n *\r\n * @since v1.0.0\r\n */\r\n async get(opts?: RequestOptions): Promise<Me> {\r\n const r = await request<ApiSuccess<Me>>(\r\n \"/me\",\r\n opts\r\n );\r\n return r.data;\r\n },\r\n\r\n /**\r\n * Lists organizations the current user belongs to.\r\n *\r\n * @since v1.0.0\r\n */\r\n async organizations(\r\n opts?: RequestOptions\r\n ): Promise<Organization[]> {\r\n const r = await request<ApiSuccess<Organization[]>>(\r\n \"/organizations\",\r\n opts\r\n );\r\n return r.data;\r\n }\r\n};","import org from \"./org\";\r\nimport me from \"./me\";\r\nexport const v1 = {\r\n org,\r\n me\r\n};\r\n\r\nexport default v1;","export type WSMessageType =\r\n | \"CONNECTION_STATUS\"\r\n | \"SUBSCRIBED\"\r\n | \"ERROR\"\r\n | \"PING\"\r\n | \"PONG\"\r\n | \"UPDATE_ORG\"\r\n | \"CREATE_TASK\"\r\n | \"UPDATE_TASK\"\r\n | \"UPDATE_TASK_COMMENTS\"\r\n | \"UPDATE_TASK_VOTE\"\r\n | \"UPDATE_LABELS\"\r\n | \"UPDATE_VIEWS\"\r\n | \"UPDATE_CATEGORIES\"\r\n | \"UPDATE_ISSUE_TEMPLATES\"\r\n | \"DISCONNECTED\";\r\n\r\n/**\r\n * String enum replacement for WS event names.\r\n * Use this instead of raw strings.\r\n */\r\nexport const WS_EVENTS: Record<WSMessageType, WSMessageType> = {\r\n CONNECTION_STATUS: \"CONNECTION_STATUS\",\r\n SUBSCRIBED: \"SUBSCRIBED\",\r\n ERROR: \"ERROR\",\r\n PING: \"PING\",\r\n PONG: \"PONG\",\r\n UPDATE_ORG: \"UPDATE_ORG\",\r\n CREATE_TASK: \"CREATE_TASK\",\r\n UPDATE_TASK: \"UPDATE_TASK\",\r\n UPDATE_TASK_COMMENTS: \"UPDATE_TASK_COMMENTS\",\r\n UPDATE_TASK_VOTE: \"UPDATE_TASK_VOTE\",\r\n UPDATE_LABELS: \"UPDATE_LABELS\",\r\n UPDATE_VIEWS: \"UPDATE_VIEWS\",\r\n UPDATE_CATEGORIES: \"UPDATE_CATEGORIES\",\r\n UPDATE_ISSUE_TEMPLATES: \"UPDATE_ISSUE_TEMPLATES\",\r\n DISCONNECTED: \"DISCONNECTED\"\r\n};\r\n\r\nexport interface WSMessage<T = unknown> {\r\n type: WSMessageType;\r\n scope: \"PUBLIC\";\r\n data: T;\r\n meta?: { ts: number };\r\n}","import { WS_EVENTS, type WSMessage, type WSMessageType } from \"./types\";\r\n\r\ntype Handlers = Partial<\r\n Record<WSMessageType, (data: any, msg: WSMessage) => void>\r\n>;\r\n\r\nexport function ws(url: string, handlers: Handlers = {}) {\r\n if (!url) {\r\n throw new Error(\r\n \"[Sayr.ws] WebSocket URL is required. \" +\r\n \"Did you forget to pass org.wsUrl?\"\r\n );\r\n }\r\n let socket: WebSocket;\r\n let retry = 0;\r\n let closed = false;\r\n\r\n function connect() {\r\n if (closed) return;\r\n\r\n socket = new WebSocket(url);\r\n\r\n socket.onmessage = (e) => {\r\n const msg = JSON.parse(e.data) as WSMessage;\r\n\r\n if (msg.type === WS_EVENTS.PING) {\r\n socket.send(JSON.stringify({ type: WS_EVENTS.PONG }));\r\n return;\r\n }\r\n\r\n handlers[msg.type]?.(msg.data, msg);\r\n };\r\n\r\n socket.onclose = () => {\r\n if (closed) return;\r\n setTimeout(connect, Math.min(1000 * 2 ** retry++, 30000));\r\n };\r\n\r\n socket.onerror = () => socket.close();\r\n }\r\n\r\n connect();\r\n\r\n return {\r\n close() {\r\n closed = true;\r\n socket?.close();\r\n }\r\n };\r\n}"],"mappings":"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","names":["org_default","org_default"]}
|