@kookee/sdk 0.0.31 → 0.0.33
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 +57 -28
- package/dist/index.cjs +2 -2
- package/dist/index.d.cts +235 -222
- package/dist/index.d.ts +235 -222
- package/dist/index.global.js +2 -2
- package/dist/index.js +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -44,6 +44,43 @@ const kookee = new Kookee({
|
|
|
44
44
|
});
|
|
45
45
|
```
|
|
46
46
|
|
|
47
|
+
## User Identification
|
|
48
|
+
|
|
49
|
+
Set user identity once and it's automatically used across all feedback operations:
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
// Set user identity globally
|
|
53
|
+
kookee.identify({
|
|
54
|
+
externalId: 'user-456',
|
|
55
|
+
name: 'Jane Doe',
|
|
56
|
+
email: 'jane@example.com', // optional
|
|
57
|
+
avatarUrl: 'https://...', // optional
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
// All feedback methods now auto-use the identified user
|
|
61
|
+
await kookee.feedback.createPost({ title: 'Feature request', category: 'feature' });
|
|
62
|
+
await kookee.feedback.createComment(postId, { content: 'Great idea!' });
|
|
63
|
+
const myPosts = await kookee.feedback.listMyPosts();
|
|
64
|
+
|
|
65
|
+
// Check current user
|
|
66
|
+
const user = kookee.getUser(); // KookeeUser | null
|
|
67
|
+
|
|
68
|
+
// Clear identity on logout
|
|
69
|
+
kookee.reset();
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### React usage
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
useEffect(() => {
|
|
76
|
+
if (user) {
|
|
77
|
+
kookee.identify({ externalId: user.id, name: user.name, email: user.email });
|
|
78
|
+
} else {
|
|
79
|
+
kookee.reset();
|
|
80
|
+
}
|
|
81
|
+
}, [user]);
|
|
82
|
+
```
|
|
83
|
+
|
|
47
84
|
## Blog
|
|
48
85
|
|
|
49
86
|
```typescript
|
|
@@ -219,48 +256,39 @@ const contributors = await kookee.feedback.getTopContributors({ limit: 10 });
|
|
|
219
256
|
|
|
220
257
|
### Creating and managing feedback
|
|
221
258
|
|
|
222
|
-
These operations require
|
|
259
|
+
These operations require user identification — either globally via `kookee.identify()` or per-call via `externalUser`/`externalId`:
|
|
223
260
|
|
|
224
261
|
```typescript
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
const user: ExternalUser = {
|
|
228
|
-
externalId: 'user-123', // your system's user ID
|
|
229
|
-
name: 'Jane Doe',
|
|
230
|
-
email: 'jane@example.com', // optional
|
|
231
|
-
avatarUrl: 'https://...', // optional
|
|
232
|
-
};
|
|
262
|
+
// With global identity (recommended — see User Identification section above)
|
|
263
|
+
kookee.identify({ externalId: 'user-123', name: 'Jane Doe' });
|
|
233
264
|
|
|
234
|
-
// Create a feedback post
|
|
235
265
|
const newPost = await kookee.feedback.createPost({
|
|
236
266
|
title: 'Add dark mode',
|
|
237
267
|
description: 'It would be great to have a dark mode option.',
|
|
238
|
-
category: 'feature',
|
|
239
|
-
externalUser: user,
|
|
268
|
+
category: 'feature',
|
|
240
269
|
});
|
|
241
270
|
|
|
242
|
-
// Add a comment to a post
|
|
243
271
|
const comment = await kookee.feedback.createComment('post-id', {
|
|
244
272
|
content: 'Great idea, I would love this too!',
|
|
245
|
-
externalUser: user,
|
|
246
273
|
});
|
|
247
274
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
search: 'dark mode', // optional search
|
|
256
|
-
sort: 'newest', // optional sort
|
|
257
|
-
});
|
|
275
|
+
const myPosts = await kookee.feedback.listMyPosts();
|
|
276
|
+
|
|
277
|
+
await kookee.feedback.deletePost('post-id');
|
|
278
|
+
await kookee.feedback.deleteComment('comment-id');
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
Per-call override still works (takes precedence over global identity):
|
|
258
282
|
|
|
259
|
-
|
|
260
|
-
await kookee.feedback.
|
|
283
|
+
```typescript
|
|
284
|
+
const newPost = await kookee.feedback.createPost({
|
|
285
|
+
title: 'Add dark mode',
|
|
286
|
+
externalUser: { externalId: 'other-user', name: 'John' },
|
|
287
|
+
});
|
|
261
288
|
|
|
262
|
-
|
|
263
|
-
await kookee.feedback.
|
|
289
|
+
const myPosts = await kookee.feedback.listMyPosts({ externalId: 'other-user' });
|
|
290
|
+
await kookee.feedback.deletePost('post-id', { externalId: 'other-user' });
|
|
291
|
+
await kookee.feedback.deleteComment('comment-id', { externalId: 'other-user' });
|
|
264
292
|
```
|
|
265
293
|
|
|
266
294
|
## Config
|
|
@@ -387,6 +415,7 @@ import type {
|
|
|
387
415
|
FeedbackPostListItem,
|
|
388
416
|
FeedbackComment,
|
|
389
417
|
FeedbackTopContributor,
|
|
418
|
+
KookeeUser,
|
|
390
419
|
ExternalUser,
|
|
391
420
|
PublicConfig,
|
|
392
421
|
PaginatedResponse,
|
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
'use strict';var k="https://api.kookee.dev",B="Kookee-API-Key",
|
|
2
|
-
`);
|
|
1
|
+
'use strict';var k="https://api.kookee.dev",B="Kookee-API-Key",I="Kookee-Project-Id",i=class s extends Error{constructor(t,r,o){super(r);this.code=t;this.status=o;this.name="KookeeApiError",Object.setPrototypeOf(this,s.prototype);}},C=class{baseUrl;apiKey;projectId;constructor(e){this.apiKey=e.apiKey,this.projectId=e.projectId,this.baseUrl=e.baseUrl??k;}getHeaders(){let e={"Content-Type":"application/json"};return this.apiKey&&(e[B]=this.apiKey),this.projectId&&(e[I]=this.projectId),e}async get(e,t){let r=new URL(`${this.baseUrl}${e}`);if(t){for(let[h,n]of Object.entries(t))if(n!=null)if(Array.isArray(n))for(let a of n)r.searchParams.append(h,String(a));else r.searchParams.set(h,String(n));}let o=await fetch(r.toString(),{method:"GET",headers:this.getHeaders()});return this.handleResponse(o)}async post(e,t){let r=await fetch(`${this.baseUrl}${e}`,{method:"POST",headers:this.getHeaders(),body:t?JSON.stringify(t):void 0});return this.handleResponse(r)}async delete(e,t){let r=await fetch(`${this.baseUrl}${e}`,{method:"DELETE",headers:this.getHeaders(),body:t?JSON.stringify(t):void 0});return this.handleResponse(r)}async*streamPost(e,t){let r=await fetch(`${this.baseUrl}${e}`,{method:"POST",headers:{...this.getHeaders(),Accept:"text/event-stream"},body:t?JSON.stringify(t):void 0});if(!r.ok){let a=null;try{a=await r.json();}catch{}throw new i(a?.code??"UNKNOWN_ERROR",a?.message??`Request failed with status ${r.status}`,r.status)}if(!r.body)return;let o=r.body.getReader(),h=new TextDecoder,n="";try{for(;;){let{done:a,value:b}=await o.read();if(a)break;n+=h.decode(b,{stream:!0});let E=n.split(`
|
|
2
|
+
`);n=E.pop()??"";for(let x of E){let u=x.trim();if(!(!u||u.startsWith(":"))&&u.startsWith("data: ")){let R=u.slice(6);if(R==="[DONE]")return;yield JSON.parse(R);}}}}finally{o.releaseLock();}}async handleResponse(e){if(!e.ok){let t=null;try{t=await e.json();}catch{}throw new i(t?.code??"UNKNOWN_ERROR",t?.message??`Request failed with status ${e.status}`,e.status)}return e.json()}};var m=class{constructor(e){this.entries=e;}async list(e){return this.entries.list({type:"announcement",...e})}async getById(e,t){return this.entries.getById(e,t)}async getTranslationsById(e){return this.entries.getTranslationsById(e)}async getComments(e,t){return this.entries.getComments(e,t)}};var p=class{constructor(e){this.entries=e;}async list(e){return this.entries.list({type:"blog",...e})}async getBySlug(e,t){return this.entries.getBySlug(e,{type:"blog",...t})}async getById(e,t){return this.entries.getById(e,t)}async getTags(){return this.entries.getTags("blog")}async getTranslationsById(e){return this.entries.getTranslationsById(e)}async getTranslationsBySlug(e){return this.entries.getTranslationsBySlug(e)}async getComments(e,t){return this.entries.getComments(e,t)}async react(e,t){return this.entries.react(e,t)}};var c=class{constructor(e){this.entries=e;}async list(e){return this.entries.list({type:"changelog",...e})}async getBySlug(e,t){return this.entries.getBySlug(e,{type:"changelog",...t})}async getById(e,t){return this.entries.getById(e,t)}async getTranslationsById(e){return this.entries.getTranslationsById(e)}async getTranslationsBySlug(e){return this.entries.getTranslationsBySlug(e)}async getComments(e,t){return this.entries.getComments(e,t)}async react(e,t){return this.entries.react(e,t)}};var g=class{constructor(e){this.http=e;}async getByKey(e){return this.http.get(`/v1/config/${encodeURIComponent(e)}`)}async list(e){return this.http.get("/v1/config",e)}};var l=class{constructor(e){this.http=e;}async list(e){return this.http.get("/v1/entries",e)}async getById(e,t){return this.http.get(`/v1/entries/by-id/${encodeURIComponent(e)}`,t)}async getBySlug(e,t){return this.http.get(`/v1/entries/${encodeURIComponent(e)}`,t)}async getTranslationsById(e){return this.http.get(`/v1/entries/by-id/${encodeURIComponent(e)}/translations`)}async getTranslationsBySlug(e){return this.http.get(`/v1/entries/${encodeURIComponent(e)}/translations`)}async getComments(e,t){return this.http.get(`/v1/entries/${encodeURIComponent(e)}/comments`,t)}async react(e,t){return this.http.post(`/v1/entries/${encodeURIComponent(e)}/reactions`,t)}async getTags(e){return this.http.get("/v1/tags",{type:e})}async getCategories(e,t){return this.http.get("/v1/categories",{type:e,...t})}};var y=class{constructor(e,t){this.http=e;this.getUserContext=t;}async list(e){return this.http.get("/v1/feedback",e)}async getById(e){return this.http.get(`/v1/feedback/by-id/${encodeURIComponent(e)}`)}async vote(e,t){return this.http.post(`/v1/feedback/${encodeURIComponent(e)}/vote`,t)}async getTopContributors(e){return this.http.get("/v1/feedback/top-contributors",e)}async createPost(e){let t=e.externalUser??this.getUserContext();if(!t)throw new Error("No user identified. Call kookee.identify() first or pass externalUser in params.");return this.http.post("/v1/feedback",{...e,externalUser:t})}async createComment(e,t){let r=t.externalUser??this.getUserContext();if(!r)throw new Error("No user identified. Call kookee.identify() first or pass externalUser in params.");return this.http.post(`/v1/feedback/${encodeURIComponent(e)}/comments`,{...t,externalUser:r})}async listMyPosts(e){let t=e?.externalId??this.getUserContext()?.externalId;if(!t)throw new Error("No user identified. Call kookee.identify() first or pass externalId in params.");return this.http.get("/v1/feedback/mine",{...e,externalId:t})}async deletePost(e,t){let r=t?.externalId??this.getUserContext()?.externalId;if(!r)throw new Error("No user identified. Call kookee.identify() first or pass externalId in params.");return this.http.delete(`/v1/feedback/${encodeURIComponent(e)}`,{externalId:r})}async deleteComment(e,t){let r=t?.externalId??this.getUserContext()?.externalId;if(!r)throw new Error("No user identified. Call kookee.identify() first or pass externalId in params.");return this.http.delete(`/v1/feedback/comments/${encodeURIComponent(e)}`,{externalId:r})}};var d=class{http;entries;constructor(e,t){this.http=e,this.entries=t;}async categories(e){return this.entries.getCategories("help_article",e)}async list(e){return this.entries.list({type:"help_article",...e})}async getBySlug(e,t){return this.entries.getBySlug(e,{type:"help_article",...t})}async getById(e,t){return this.entries.getById(e,t)}async search(e){return this.http.get("/v1/help/search",e)}async getTranslationsById(e){return this.entries.getTranslationsById(e)}async getTranslationsBySlug(e){return this.entries.getTranslationsBySlug(e)}async getComments(e,t){return this.entries.getComments(e,t)}async react(e,t){return this.entries.react(e,t)}async chat(e){return this.http.post("/v1/help/chat",e)}chatStream(e){return this.http.streamPost("/v1/help/chat/stream",e)}};var P=class{constructor(e){this.entries=e;}async list(e){return this.entries.list({type:"page",...e})}async getBySlug(e,t){return this.entries.getBySlug(e,{type:"page",...t})}async getById(e,t){return this.entries.getById(e,t)}async getTranslationsById(e){return this.entries.getTranslationsById(e)}async getTranslationsBySlug(e){return this.entries.getTranslationsBySlug(e)}async getComments(e,t){return this.entries.getComments(e,t)}};var f=class{http;user=null;entries;announcements;blog;changelog;config;feedback;help;pages;constructor(e){if(!e.apiKey&&!e.projectId)throw new Error("Either apiKey or projectId is required");this.http=new C({apiKey:e.apiKey,projectId:e.projectId,baseUrl:e.baseUrl}),this.entries=new l(this.http),this.announcements=new m(this.entries),this.blog=new p(this.entries),this.changelog=new c(this.entries),this.config=new g(this.http),this.feedback=new y(this.http,()=>this.user),this.help=new d(this.http,this.entries),this.pages=new P(this.entries);}identify(e){this.user=e;}reset(){this.user=null;}getUser(){return this.user}async health(){return this.http.get("/v1/health")}};exports.AnnouncementModule=m;exports.BlogModule=p;exports.ChangelogModule=c;exports.ConfigModule=g;exports.EntriesModule=l;exports.FeedbackModule=y;exports.HelpModule=d;exports.Kookee=f;exports.KookeeApiError=i;exports.PagesModule=P;
|