@kookee/sdk 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,131 @@
1
+ # @kookee/sdk
2
+
3
+ Official SDK for Kookee - Access your blog, changelog, help center, forms, and announcements.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @kookee/sdk
9
+ # or
10
+ pnpm add @kookee/sdk
11
+ # or
12
+ yarn add @kookee/sdk
13
+ ```
14
+
15
+ ## Quick Start
16
+
17
+ ```typescript
18
+ import { Kookee } from '@kookee/sdk';
19
+
20
+ const kookee = new Kookee({
21
+ projectId: 'your-project-id',
22
+ });
23
+
24
+ // Fetch blog posts
25
+ const posts = await kookee.blog.list({ limit: 10 });
26
+
27
+ // Get a single post by slug
28
+ const post = await kookee.blog.getBySlug('hello-world');
29
+ ```
30
+
31
+ ## Features
32
+
33
+ ### Blog
34
+
35
+ ```typescript
36
+ // List posts with pagination
37
+ const posts = await kookee.blog.list({ limit: 10, offset: 0 });
38
+
39
+ // Filter by tag
40
+ const taggedPosts = await kookee.blog.list({ tag: 'news' });
41
+
42
+ // Get single post
43
+ const post = await kookee.blog.getBySlug('my-post');
44
+
45
+ // Get all tags
46
+ const tags = await kookee.blog.getTags();
47
+ ```
48
+
49
+ ### Changelog
50
+
51
+ ```typescript
52
+ // List changelog entries
53
+ const entries = await kookee.changelog.list();
54
+
55
+ // Filter by type
56
+ const features = await kookee.changelog.list({ type: 'feature' });
57
+
58
+ // Get single entry
59
+ const entry = await kookee.changelog.getBySlug('v1.0.0');
60
+ ```
61
+
62
+ ### Help Center
63
+
64
+ ```typescript
65
+ // List categories
66
+ const categories = await kookee.helpCenter.listCategories();
67
+
68
+ // List articles
69
+ const articles = await kookee.helpCenter.listArticles();
70
+
71
+ // Filter by category
72
+ const gettingStarted = await kookee.helpCenter.listArticles({
73
+ categorySlug: 'getting-started',
74
+ });
75
+
76
+ // Search articles
77
+ const results = await kookee.helpCenter.search('how to');
78
+
79
+ // Get single article
80
+ const article = await kookee.helpCenter.getArticleBySlug('installation');
81
+ ```
82
+
83
+ ### Forms
84
+
85
+ ```typescript
86
+ // Get form structure
87
+ const form = await kookee.forms.get('contact');
88
+
89
+ // Submit form
90
+ const result = await kookee.forms.submit('contact', {
91
+ email: 'user@example.com',
92
+ message: 'Hello!',
93
+ });
94
+ ```
95
+
96
+ ### Announcements
97
+
98
+ ```typescript
99
+ // Get active announcements
100
+ const announcements = await kookee.announcements.getActive();
101
+
102
+ // Filter by type
103
+ const banners = await kookee.announcements.getActive({ type: 'banner' });
104
+ ```
105
+
106
+ ## Error Handling
107
+
108
+ ```typescript
109
+ import { Kookee, KookeeApiError } from '@kookee/sdk';
110
+
111
+ try {
112
+ const post = await kookee.blog.getBySlug('non-existent');
113
+ } catch (error) {
114
+ if (error instanceof KookeeApiError) {
115
+ console.error(`Error ${error.code}: ${error.message}`);
116
+ console.error(`Status: ${error.status}`);
117
+ }
118
+ }
119
+ ```
120
+
121
+ ## TypeScript
122
+
123
+ The SDK is written in TypeScript and provides full type definitions:
124
+
125
+ ```typescript
126
+ import type { BlogPost, ChangelogEntry, HelpArticle } from '@kookee/sdk';
127
+ ```
128
+
129
+ ## License
130
+
131
+ MIT
package/dist/index.cjs ADDED
@@ -0,0 +1,3 @@
1
+ 'use strict';var h="https://api.kookee.dev",c="Kookee-API-Key",r=class extends Error{constructor(e,o,g){super(o);this.code=e;this.status=g;this.name="KookeeApiError";}},i=class{baseUrl;apiKey;constructor(t,e){this.apiKey=t,this.baseUrl=e??h;}getHeaders(){return {"Content-Type":"application/json",[c]:this.apiKey}}async get(t,e){let o=new URL(`${this.baseUrl}${t}`);if(e)for(let[l,a]of Object.entries(e))a!=null&&o.searchParams.set(l,String(a));let g=await fetch(o.toString(),{method:"GET",headers:this.getHeaders()});return this.handleResponse(g)}async post(t,e){let o=await fetch(`${this.baseUrl}${t}`,{method:"POST",headers:this.getHeaders(),body:e?JSON.stringify(e):void 0});return this.handleResponse(o)}async handleResponse(t){if(!t.ok){let e=null;try{e=await t.json();}catch{}throw new r(e?.code??"UNKNOWN_ERROR",e?.message??`Request failed with status ${t.status}`,t.status)}return t.json()}};var s=class{constructor(t){this.http=t;}async list(t){return this.http.get("/v1/blog/posts",t)}async getBySlug(t){return this.http.get(`/v1/blog/posts/${encodeURIComponent(t)}`)}async getById(t){return this.http.get(`/v1/blog/posts/by-id/${encodeURIComponent(t)}`)}async getTags(){return this.http.get("/v1/blog/tags")}};var p=class{http;blog;constructor(t){if(!t.apiKey)throw new Error("apiKey is required");this.http=new i(t.apiKey,t.baseUrl),this.blog=new s(this.http);}};
2
+ exports.BlogModule=s;exports.Kookee=p;exports.KookeeApiError=r;//# sourceMappingURL=index.cjs.map
3
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/http-client.ts","../src/lib/modules/blog.ts","../src/lib/client.ts"],"names":["DEFAULT_BASE_URL","API_KEY_HEADER","KookeeApiError","code","message","status","HttpClient","apiKey","baseUrl","path","params","url","key","value","response","body","errorData","BlogModule","http","slug","id","Kookee","config"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { ApiError } from './types';\n\nconst DEFAULT_BASE_URL = 'https://api.kookee.dev';\nconst API_KEY_HEADER = 'Kookee-API-Key';\n\nexport class KookeeApiError extends Error {\n constructor(\n public readonly code: string,\n message: string,\n public readonly status: number\n ) {\n super(message);\n this.name = 'KookeeApiError';\n }\n}\n\nexport class HttpClient {\n private readonly baseUrl: string;\n private readonly apiKey: string;\n\n constructor(apiKey: string, baseUrl?: string) {\n this.apiKey = apiKey;\n this.baseUrl = baseUrl ?? DEFAULT_BASE_URL;\n }\n\n private getHeaders(): Record<string, string> {\n return {\n 'Content-Type': 'application/json',\n [API_KEY_HEADER]: this.apiKey,\n };\n }\n\n async get<T>(path: string, params?: object): Promise<T> {\n const url = new URL(`${this.baseUrl}${path}`);\n\n if (params) {\n for (const [key, value] of Object.entries(params)) {\n if (value !== undefined && value !== null) {\n url.searchParams.set(key, String(value));\n }\n }\n }\n\n const response = await fetch(url.toString(), {\n method: 'GET',\n headers: this.getHeaders(),\n });\n\n return this.handleResponse<T>(response);\n }\n\n async post<T>(path: string, body?: unknown): Promise<T> {\n const response = await fetch(`${this.baseUrl}${path}`, {\n method: 'POST',\n headers: this.getHeaders(),\n body: body ? JSON.stringify(body) : undefined,\n });\n\n return this.handleResponse<T>(response);\n }\n\n private async handleResponse<T>(response: Response): Promise<T> {\n if (!response.ok) {\n let errorData: ApiError | null = null;\n\n try {\n errorData = (await response.json()) as ApiError;\n } catch {\n // Response body is not JSON\n }\n\n throw new KookeeApiError(\n errorData?.code ?? 'UNKNOWN_ERROR',\n errorData?.message ?? `Request failed with status ${response.status}`,\n response.status\n );\n }\n\n return response.json() as Promise<T>;\n }\n}\n","import type { HttpClient } from '../http-client';\nimport type { BlogPost, BlogPostListItem, BlogTagWithCount, PaginatedResponse, PaginationParams } from '../types';\n\nexport interface BlogListParams extends PaginationParams {\n tag?: string;\n search?: string;\n}\n\nexport class BlogModule {\n constructor(private readonly http: HttpClient) {}\n\n async list(params?: BlogListParams): Promise<PaginatedResponse<BlogPostListItem>> {\n return this.http.get<PaginatedResponse<BlogPostListItem>>('/v1/blog/posts', params);\n }\n\n async getBySlug(slug: string): Promise<BlogPost> {\n return this.http.get<BlogPost>(`/v1/blog/posts/${encodeURIComponent(slug)}`);\n }\n\n async getById(id: string): Promise<BlogPost> {\n return this.http.get<BlogPost>(`/v1/blog/posts/by-id/${encodeURIComponent(id)}`);\n }\n\n async getTags(): Promise<BlogTagWithCount[]> {\n return this.http.get<BlogTagWithCount[]>('/v1/blog/tags');\n }\n}\n","import { HttpClient } from './http-client';\nimport { BlogModule } from './modules/blog';\nimport type { KookeeConfig } from './types';\n\nexport class Kookee {\n private readonly http: HttpClient;\n\n public readonly blog: BlogModule;\n\n constructor(config: KookeeConfig) {\n if (!config.apiKey) {\n throw new Error('apiKey is required');\n }\n\n this.http = new HttpClient(config.apiKey, config.baseUrl);\n\n this.blog = new BlogModule(this.http);\n }\n}\n"]}
@@ -0,0 +1,85 @@
1
+ declare class KookeeApiError extends Error {
2
+ readonly code: string;
3
+ readonly status: number;
4
+ constructor(code: string, message: string, status: number);
5
+ }
6
+ declare class HttpClient {
7
+ private readonly baseUrl;
8
+ private readonly apiKey;
9
+ constructor(apiKey: string, baseUrl?: string);
10
+ private getHeaders;
11
+ get<T>(path: string, params?: object): Promise<T>;
12
+ post<T>(path: string, body?: unknown): Promise<T>;
13
+ private handleResponse;
14
+ }
15
+
16
+ interface KookeeConfig {
17
+ apiKey: string;
18
+ baseUrl?: string;
19
+ }
20
+ interface PaginationParams {
21
+ page?: number;
22
+ limit?: number;
23
+ }
24
+ interface PaginatedResponse<T> {
25
+ data: T[];
26
+ total: number;
27
+ limit: number;
28
+ offset: number;
29
+ page: number;
30
+ totalPages: number;
31
+ }
32
+ interface BlogTag {
33
+ name: string;
34
+ slug: string;
35
+ }
36
+ interface BlogTagWithCount extends BlogTag {
37
+ count: number;
38
+ }
39
+ interface BlogPostAuthor {
40
+ name: string;
41
+ }
42
+ interface BlogPostListItem {
43
+ id: string;
44
+ slug: string;
45
+ title: string;
46
+ excerptHtml: string | null;
47
+ coverImageUrl: string | null;
48
+ status: string;
49
+ publishedAt: string | null;
50
+ metadata: Record<string, unknown> | null;
51
+ createdAt: string;
52
+ author: BlogPostAuthor;
53
+ tags: BlogTag[];
54
+ }
55
+ interface BlogPost extends BlogPostListItem {
56
+ contentHtml: string;
57
+ metaTitle: string | null;
58
+ metaDescription: string | null;
59
+ updatedAt: string;
60
+ }
61
+ interface ApiError {
62
+ code: string;
63
+ message: string;
64
+ }
65
+
66
+ interface BlogListParams extends PaginationParams {
67
+ tag?: string;
68
+ search?: string;
69
+ }
70
+ declare class BlogModule {
71
+ private readonly http;
72
+ constructor(http: HttpClient);
73
+ list(params?: BlogListParams): Promise<PaginatedResponse<BlogPostListItem>>;
74
+ getBySlug(slug: string): Promise<BlogPost>;
75
+ getById(id: string): Promise<BlogPost>;
76
+ getTags(): Promise<BlogTagWithCount[]>;
77
+ }
78
+
79
+ declare class Kookee {
80
+ private readonly http;
81
+ readonly blog: BlogModule;
82
+ constructor(config: KookeeConfig);
83
+ }
84
+
85
+ export { type ApiError, type BlogListParams, BlogModule, type BlogPost, type BlogPostAuthor, type BlogPostListItem, type BlogTag, type BlogTagWithCount, Kookee, KookeeApiError, type KookeeConfig, type PaginatedResponse, type PaginationParams };
@@ -0,0 +1,85 @@
1
+ declare class KookeeApiError extends Error {
2
+ readonly code: string;
3
+ readonly status: number;
4
+ constructor(code: string, message: string, status: number);
5
+ }
6
+ declare class HttpClient {
7
+ private readonly baseUrl;
8
+ private readonly apiKey;
9
+ constructor(apiKey: string, baseUrl?: string);
10
+ private getHeaders;
11
+ get<T>(path: string, params?: object): Promise<T>;
12
+ post<T>(path: string, body?: unknown): Promise<T>;
13
+ private handleResponse;
14
+ }
15
+
16
+ interface KookeeConfig {
17
+ apiKey: string;
18
+ baseUrl?: string;
19
+ }
20
+ interface PaginationParams {
21
+ page?: number;
22
+ limit?: number;
23
+ }
24
+ interface PaginatedResponse<T> {
25
+ data: T[];
26
+ total: number;
27
+ limit: number;
28
+ offset: number;
29
+ page: number;
30
+ totalPages: number;
31
+ }
32
+ interface BlogTag {
33
+ name: string;
34
+ slug: string;
35
+ }
36
+ interface BlogTagWithCount extends BlogTag {
37
+ count: number;
38
+ }
39
+ interface BlogPostAuthor {
40
+ name: string;
41
+ }
42
+ interface BlogPostListItem {
43
+ id: string;
44
+ slug: string;
45
+ title: string;
46
+ excerptHtml: string | null;
47
+ coverImageUrl: string | null;
48
+ status: string;
49
+ publishedAt: string | null;
50
+ metadata: Record<string, unknown> | null;
51
+ createdAt: string;
52
+ author: BlogPostAuthor;
53
+ tags: BlogTag[];
54
+ }
55
+ interface BlogPost extends BlogPostListItem {
56
+ contentHtml: string;
57
+ metaTitle: string | null;
58
+ metaDescription: string | null;
59
+ updatedAt: string;
60
+ }
61
+ interface ApiError {
62
+ code: string;
63
+ message: string;
64
+ }
65
+
66
+ interface BlogListParams extends PaginationParams {
67
+ tag?: string;
68
+ search?: string;
69
+ }
70
+ declare class BlogModule {
71
+ private readonly http;
72
+ constructor(http: HttpClient);
73
+ list(params?: BlogListParams): Promise<PaginatedResponse<BlogPostListItem>>;
74
+ getBySlug(slug: string): Promise<BlogPost>;
75
+ getById(id: string): Promise<BlogPost>;
76
+ getTags(): Promise<BlogTagWithCount[]>;
77
+ }
78
+
79
+ declare class Kookee {
80
+ private readonly http;
81
+ readonly blog: BlogModule;
82
+ constructor(config: KookeeConfig);
83
+ }
84
+
85
+ export { type ApiError, type BlogListParams, BlogModule, type BlogPost, type BlogPostAuthor, type BlogPostListItem, type BlogTag, type BlogTagWithCount, Kookee, KookeeApiError, type KookeeConfig, type PaginatedResponse, type PaginationParams };
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ var h="https://api.kookee.dev",c="Kookee-API-Key",r=class extends Error{constructor(e,o,g){super(o);this.code=e;this.status=g;this.name="KookeeApiError";}},i=class{baseUrl;apiKey;constructor(t,e){this.apiKey=t,this.baseUrl=e??h;}getHeaders(){return {"Content-Type":"application/json",[c]:this.apiKey}}async get(t,e){let o=new URL(`${this.baseUrl}${t}`);if(e)for(let[l,a]of Object.entries(e))a!=null&&o.searchParams.set(l,String(a));let g=await fetch(o.toString(),{method:"GET",headers:this.getHeaders()});return this.handleResponse(g)}async post(t,e){let o=await fetch(`${this.baseUrl}${t}`,{method:"POST",headers:this.getHeaders(),body:e?JSON.stringify(e):void 0});return this.handleResponse(o)}async handleResponse(t){if(!t.ok){let e=null;try{e=await t.json();}catch{}throw new r(e?.code??"UNKNOWN_ERROR",e?.message??`Request failed with status ${t.status}`,t.status)}return t.json()}};var s=class{constructor(t){this.http=t;}async list(t){return this.http.get("/v1/blog/posts",t)}async getBySlug(t){return this.http.get(`/v1/blog/posts/${encodeURIComponent(t)}`)}async getById(t){return this.http.get(`/v1/blog/posts/by-id/${encodeURIComponent(t)}`)}async getTags(){return this.http.get("/v1/blog/tags")}};var p=class{http;blog;constructor(t){if(!t.apiKey)throw new Error("apiKey is required");this.http=new i(t.apiKey,t.baseUrl),this.blog=new s(this.http);}};
2
+ export{s as BlogModule,p as Kookee,r as KookeeApiError};//# sourceMappingURL=index.js.map
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/http-client.ts","../src/lib/modules/blog.ts","../src/lib/client.ts"],"names":["DEFAULT_BASE_URL","API_KEY_HEADER","KookeeApiError","code","message","status","HttpClient","apiKey","baseUrl","path","params","url","key","value","response","body","errorData","BlogModule","http","slug","id","Kookee","config"],"mappings":"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","file":"index.js","sourcesContent":["import type { ApiError } from './types';\n\nconst DEFAULT_BASE_URL = 'https://api.kookee.dev';\nconst API_KEY_HEADER = 'Kookee-API-Key';\n\nexport class KookeeApiError extends Error {\n constructor(\n public readonly code: string,\n message: string,\n public readonly status: number\n ) {\n super(message);\n this.name = 'KookeeApiError';\n }\n}\n\nexport class HttpClient {\n private readonly baseUrl: string;\n private readonly apiKey: string;\n\n constructor(apiKey: string, baseUrl?: string) {\n this.apiKey = apiKey;\n this.baseUrl = baseUrl ?? DEFAULT_BASE_URL;\n }\n\n private getHeaders(): Record<string, string> {\n return {\n 'Content-Type': 'application/json',\n [API_KEY_HEADER]: this.apiKey,\n };\n }\n\n async get<T>(path: string, params?: object): Promise<T> {\n const url = new URL(`${this.baseUrl}${path}`);\n\n if (params) {\n for (const [key, value] of Object.entries(params)) {\n if (value !== undefined && value !== null) {\n url.searchParams.set(key, String(value));\n }\n }\n }\n\n const response = await fetch(url.toString(), {\n method: 'GET',\n headers: this.getHeaders(),\n });\n\n return this.handleResponse<T>(response);\n }\n\n async post<T>(path: string, body?: unknown): Promise<T> {\n const response = await fetch(`${this.baseUrl}${path}`, {\n method: 'POST',\n headers: this.getHeaders(),\n body: body ? JSON.stringify(body) : undefined,\n });\n\n return this.handleResponse<T>(response);\n }\n\n private async handleResponse<T>(response: Response): Promise<T> {\n if (!response.ok) {\n let errorData: ApiError | null = null;\n\n try {\n errorData = (await response.json()) as ApiError;\n } catch {\n // Response body is not JSON\n }\n\n throw new KookeeApiError(\n errorData?.code ?? 'UNKNOWN_ERROR',\n errorData?.message ?? `Request failed with status ${response.status}`,\n response.status\n );\n }\n\n return response.json() as Promise<T>;\n }\n}\n","import type { HttpClient } from '../http-client';\nimport type { BlogPost, BlogPostListItem, BlogTagWithCount, PaginatedResponse, PaginationParams } from '../types';\n\nexport interface BlogListParams extends PaginationParams {\n tag?: string;\n search?: string;\n}\n\nexport class BlogModule {\n constructor(private readonly http: HttpClient) {}\n\n async list(params?: BlogListParams): Promise<PaginatedResponse<BlogPostListItem>> {\n return this.http.get<PaginatedResponse<BlogPostListItem>>('/v1/blog/posts', params);\n }\n\n async getBySlug(slug: string): Promise<BlogPost> {\n return this.http.get<BlogPost>(`/v1/blog/posts/${encodeURIComponent(slug)}`);\n }\n\n async getById(id: string): Promise<BlogPost> {\n return this.http.get<BlogPost>(`/v1/blog/posts/by-id/${encodeURIComponent(id)}`);\n }\n\n async getTags(): Promise<BlogTagWithCount[]> {\n return this.http.get<BlogTagWithCount[]>('/v1/blog/tags');\n }\n}\n","import { HttpClient } from './http-client';\nimport { BlogModule } from './modules/blog';\nimport type { KookeeConfig } from './types';\n\nexport class Kookee {\n private readonly http: HttpClient;\n\n public readonly blog: BlogModule;\n\n constructor(config: KookeeConfig) {\n if (!config.apiKey) {\n throw new Error('apiKey is required');\n }\n\n this.http = new HttpClient(config.apiKey, config.baseUrl);\n\n this.blog = new BlogModule(this.http);\n }\n}\n"]}
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@kookee/sdk",
3
+ "version": "0.0.1",
4
+ "description": "Official Kookee SDK - Access your blog, changelog, help center, and more",
5
+ "main": "./dist/index.cjs",
6
+ "module": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js",
12
+ "require": "./dist/index.cjs"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist",
17
+ "README.md"
18
+ ],
19
+ "keywords": [
20
+ "kookee",
21
+ "sdk",
22
+ "blog",
23
+ "changelog",
24
+ "help-center",
25
+ "cms",
26
+ "headless"
27
+ ],
28
+ "author": "",
29
+ "license": "MIT",
30
+ "repository": {
31
+ "type": "git",
32
+ "url": "https://github.com/kookee/sdk"
33
+ },
34
+ "homepage": "https://kookee.dev",
35
+ "devDependencies": {
36
+ "@repo/typescript-config": "0.0.0",
37
+ "@repo/eslint-config": "0.0.0"
38
+ },
39
+ "publishConfig": {
40
+ "access": "public"
41
+ },
42
+ "type": "module",
43
+ "scripts": {
44
+ "build": "tsup",
45
+ "dev": "tsup --watch",
46
+ "lint": "tsc --project tsconfig.json --noEmit && eslint . --max-warnings 0"
47
+ }
48
+ }