@zenith-open/zenithcms-sdk 1.0.0-beta.8 → 1.0.0-beta.9
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/package.json +2 -2
- package/dist/cache.d.ts +0 -21
- package/dist/cache.js +0 -55
- package/dist/client.d.ts +0 -65
- package/dist/client.js +0 -129
- package/dist/index.test.d.ts +0 -1
- package/dist/index.test.js +0 -95
- package/dist/src/index.d.ts +0 -43
- package/dist/src/index.js +0 -86
- package/dist/types.d.ts +0 -54
- package/dist/types.js +0 -16
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zenith-open/zenithcms-sdk",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.9",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"license": "MIT",
|
|
20
20
|
"devDependencies": {
|
|
21
21
|
"vitest": "^1.6.0",
|
|
22
|
-
"@zenith-open/zenithcms-types": "1.0.0-beta.
|
|
22
|
+
"@zenith-open/zenithcms-types": "1.0.0-beta.9"
|
|
23
23
|
},
|
|
24
24
|
"files": [
|
|
25
25
|
"dist",
|
package/dist/cache.d.ts
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Zenith Advanced Cache Service
|
|
3
|
-
* ─────────────────────────────
|
|
4
|
-
* Features:
|
|
5
|
-
* 1. Tag-based invalidation (e.g., invalidate all 'posts')
|
|
6
|
-
* 2. TTL support
|
|
7
|
-
* 3. Atomic clears
|
|
8
|
-
*/
|
|
9
|
-
export declare class CacheService {
|
|
10
|
-
private static cache;
|
|
11
|
-
private static tags;
|
|
12
|
-
static initialize(): void;
|
|
13
|
-
static get<T>(key: string): T | undefined;
|
|
14
|
-
static set(key: string, value: unknown, ttl?: number, tags?: string[]): void;
|
|
15
|
-
static del(keys: string | string[]): void;
|
|
16
|
-
/**
|
|
17
|
-
* Invalidate all keys associated with a tag
|
|
18
|
-
*/
|
|
19
|
-
static invalidateTag(tag: string): void;
|
|
20
|
-
static flush(): void;
|
|
21
|
-
}
|
package/dist/cache.js
DELETED
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import NodeCache from 'node-cache';
|
|
2
|
-
import { logger } from './logger';
|
|
3
|
-
/**
|
|
4
|
-
* Zenith Advanced Cache Service
|
|
5
|
-
* ─────────────────────────────
|
|
6
|
-
* Features:
|
|
7
|
-
* 1. Tag-based invalidation (e.g., invalidate all 'posts')
|
|
8
|
-
* 2. TTL support
|
|
9
|
-
* 3. Atomic clears
|
|
10
|
-
*/
|
|
11
|
-
export class CacheService {
|
|
12
|
-
static cache = new NodeCache({ stdTTL: 600 }); // 10 min default
|
|
13
|
-
static tags = {};
|
|
14
|
-
// Handle key expiration to prevent memory leaks in the tags array
|
|
15
|
-
static initialize() {
|
|
16
|
-
this.cache.on('expired', (key) => {
|
|
17
|
-
Object.keys(this.tags).forEach((tag) => {
|
|
18
|
-
this.tags[tag] = this.tags[tag].filter((k) => k !== key);
|
|
19
|
-
});
|
|
20
|
-
});
|
|
21
|
-
}
|
|
22
|
-
static get(key) {
|
|
23
|
-
return this.cache.get(key);
|
|
24
|
-
}
|
|
25
|
-
static set(key, value, ttl, tags = []) {
|
|
26
|
-
this.cache.set(key, value, ttl || 600);
|
|
27
|
-
// Track tags
|
|
28
|
-
tags.forEach((tag) => {
|
|
29
|
-
if (!this.tags[tag])
|
|
30
|
-
this.tags[tag] = [];
|
|
31
|
-
if (!this.tags[tag].includes(key)) {
|
|
32
|
-
this.tags[tag].push(key);
|
|
33
|
-
}
|
|
34
|
-
});
|
|
35
|
-
}
|
|
36
|
-
static del(keys) {
|
|
37
|
-
this.cache.del(keys);
|
|
38
|
-
}
|
|
39
|
-
/**
|
|
40
|
-
* Invalidate all keys associated with a tag
|
|
41
|
-
*/
|
|
42
|
-
static invalidateTag(tag) {
|
|
43
|
-
const keys = this.tags[tag];
|
|
44
|
-
if (keys && keys.length > 0) {
|
|
45
|
-
logger.info({ tag, count: keys.length }, 'Invalidating cache tag');
|
|
46
|
-
this.cache.del(keys);
|
|
47
|
-
this.tags[tag] = [];
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
static flush() {
|
|
51
|
-
this.cache.flushAll();
|
|
52
|
-
this.tags = {};
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
CacheService.initialize();
|
package/dist/client.d.ts
DELETED
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
export interface ZenithClientOptions {
|
|
2
|
-
url: string;
|
|
3
|
-
apiKey?: string;
|
|
4
|
-
siteId?: string;
|
|
5
|
-
}
|
|
6
|
-
export interface FetchOptions extends RequestInit {
|
|
7
|
-
locale?: string;
|
|
8
|
-
depth?: number;
|
|
9
|
-
drafts?: boolean;
|
|
10
|
-
}
|
|
11
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
12
|
-
export interface FindOptions extends FetchOptions {
|
|
13
|
-
where?: Record<string, any>; // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
14
|
-
sort?: string;
|
|
15
|
-
limit?: number;
|
|
16
|
-
page?: number;
|
|
17
|
-
}
|
|
18
|
-
/**
|
|
19
|
-
* Lightweight JavaScript client for Zenith CMS, optimized for Edge environments.
|
|
20
|
-
*/
|
|
21
|
-
export declare class ZenithClient {
|
|
22
|
-
private url;
|
|
23
|
-
private apiKey?;
|
|
24
|
-
private siteId?;
|
|
25
|
-
constructor(options: ZenithClientOptions);
|
|
26
|
-
private buildQueryString;
|
|
27
|
-
private flattenWhereParams;
|
|
28
|
-
private fetchAPI;
|
|
29
|
-
/**
|
|
30
|
-
* Find multiple documents in a collection.
|
|
31
|
-
*/
|
|
32
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
33
|
-
find<T = any>(collection: string, options?: FindOptions): Promise<{ // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
34
|
-
docs: T[];
|
|
35
|
-
totalDocs: number;
|
|
36
|
-
totalPages: number;
|
|
37
|
-
page: number;
|
|
38
|
-
}>;
|
|
39
|
-
/**
|
|
40
|
-
* Find a single document by its ID.
|
|
41
|
-
*/
|
|
42
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
43
|
-
findById<T = any>(collection: string, id: string, options?: FetchOptions): Promise<T>; // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
44
|
-
/**
|
|
45
|
-
* Fetch a singleton configuration.
|
|
46
|
-
*/
|
|
47
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
48
|
-
findGlobal<T = any>(slug: string, options?: FetchOptions): Promise<T>; // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
49
|
-
/**
|
|
50
|
-
* Create a new document in a collection.
|
|
51
|
-
*/
|
|
52
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
53
|
-
create<T = any>(collection: string, payload: any, options?: FetchOptions): Promise<T>; // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
54
|
-
/**
|
|
55
|
-
* Update an existing document.
|
|
56
|
-
*/
|
|
57
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
58
|
-
update<T = any>(collection: string, id: string, payload: any, options?: FetchOptions): Promise<T>; // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
59
|
-
/**
|
|
60
|
-
* Delete a document.
|
|
61
|
-
*/
|
|
62
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
63
|
-
delete<T = any>(collection: string, id: string, options?: FetchOptions): Promise<T>; // eslint-disable-line @typescript-eslint/no-explicit-any
|
|
64
|
-
}
|
|
65
|
-
export declare function createClient(options: ZenithClientOptions): ZenithClient;
|
package/dist/client.js
DELETED
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Lightweight JavaScript client for Zenith CMS, optimized for Edge environments.
|
|
3
|
-
*/
|
|
4
|
-
export class ZenithClient {
|
|
5
|
-
url;
|
|
6
|
-
apiKey;
|
|
7
|
-
siteId;
|
|
8
|
-
constructor(options) {
|
|
9
|
-
this.url = options.url.replace(/\/$/, '');
|
|
10
|
-
this.apiKey = options.apiKey;
|
|
11
|
-
this.siteId = options.siteId;
|
|
12
|
-
}
|
|
13
|
-
buildQueryString(options) {
|
|
14
|
-
const params = new URLSearchParams();
|
|
15
|
-
if (options.locale)
|
|
16
|
-
params.append('locale', options.locale);
|
|
17
|
-
if (options.depth !== undefined)
|
|
18
|
-
params.append('depth', String(options.depth));
|
|
19
|
-
if (options.drafts)
|
|
20
|
-
params.append('drafts', 'true');
|
|
21
|
-
if (options.sort)
|
|
22
|
-
params.append('sort', options.sort);
|
|
23
|
-
if (options.limit !== undefined)
|
|
24
|
-
params.append('limit', String(options.limit));
|
|
25
|
-
if (options.page !== undefined)
|
|
26
|
-
params.append('page', String(options.page));
|
|
27
|
-
if (options.where) {
|
|
28
|
-
this.flattenWhereParams(options.where, 'where').forEach((value, key) => {
|
|
29
|
-
params.append(key, value);
|
|
30
|
-
});
|
|
31
|
-
}
|
|
32
|
-
const str = params.toString();
|
|
33
|
-
return str ? `?${str}` : '';
|
|
34
|
-
}
|
|
35
|
-
flattenWhereParams(obj, prefix) {
|
|
36
|
-
const map = new Map();
|
|
37
|
-
for (const [key, value] of Object.entries(obj)) {
|
|
38
|
-
if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
|
|
39
|
-
const nested = this.flattenWhereParams(value, `${prefix}[${key}]`);
|
|
40
|
-
nested.forEach((v, k) => map.set(k, v));
|
|
41
|
-
}
|
|
42
|
-
else {
|
|
43
|
-
map.set(`${prefix}[${key}]`, String(value));
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
return map;
|
|
47
|
-
}
|
|
48
|
-
async fetchAPI(path, options = {}) {
|
|
49
|
-
const headers = new Headers(options.headers);
|
|
50
|
-
headers.set('Content-Type', 'application/json');
|
|
51
|
-
if (this.apiKey) {
|
|
52
|
-
headers.set('Authorization', `Bearer ${this.apiKey}`);
|
|
53
|
-
}
|
|
54
|
-
if (this.siteId) {
|
|
55
|
-
headers.set('X-Zenith-Site-Id', this.siteId);
|
|
56
|
-
}
|
|
57
|
-
const response = await fetch(`${this.url}${path}`, {
|
|
58
|
-
...options,
|
|
59
|
-
headers,
|
|
60
|
-
});
|
|
61
|
-
const data = await response.json().catch(() => null);
|
|
62
|
-
if (!response.ok) {
|
|
63
|
-
throw new Error(data?.message || `Zenith API error: ${response.status} ${response.statusText}`);
|
|
64
|
-
}
|
|
65
|
-
return data;
|
|
66
|
-
}
|
|
67
|
-
/**
|
|
68
|
-
* Find multiple documents in a collection.
|
|
69
|
-
*/
|
|
70
|
-
async find(collection, options = {}) {
|
|
71
|
-
const qs = this.buildQueryString(options);
|
|
72
|
-
const data = await this.fetchAPI(`/api/v1/${collection}${qs}`, { method: 'GET', ...options });
|
|
73
|
-
return data.data || data; // Handles different API response envelopes
|
|
74
|
-
}
|
|
75
|
-
/**
|
|
76
|
-
* Find a single document by its ID.
|
|
77
|
-
*/
|
|
78
|
-
async findById(collection, id, options = {}) {
|
|
79
|
-
const qs = this.buildQueryString(options);
|
|
80
|
-
const data = await this.fetchAPI(`/api/v1/${collection}/${id}${qs}`, { method: 'GET', ...options });
|
|
81
|
-
return data.data?.document || data.data || data;
|
|
82
|
-
}
|
|
83
|
-
/**
|
|
84
|
-
* Fetch a singleton configuration.
|
|
85
|
-
*/
|
|
86
|
-
async findGlobal(slug, options = {}) {
|
|
87
|
-
const qs = this.buildQueryString(options);
|
|
88
|
-
const data = await this.fetchAPI(`/api/v1/globals/${slug}${qs}`, { method: 'GET', ...options });
|
|
89
|
-
return data.data?.document || data.data || data;
|
|
90
|
-
}
|
|
91
|
-
/**
|
|
92
|
-
* Create a new document in a collection.
|
|
93
|
-
*/
|
|
94
|
-
async create(collection, payload, options = {}) {
|
|
95
|
-
const qs = this.buildQueryString(options);
|
|
96
|
-
const data = await this.fetchAPI(`/api/v1/${collection}${qs}`, {
|
|
97
|
-
method: 'POST',
|
|
98
|
-
body: JSON.stringify(payload),
|
|
99
|
-
...options,
|
|
100
|
-
});
|
|
101
|
-
return data.data || data;
|
|
102
|
-
}
|
|
103
|
-
/**
|
|
104
|
-
* Update an existing document.
|
|
105
|
-
*/
|
|
106
|
-
async update(collection, id, payload, options = {}) {
|
|
107
|
-
const qs = this.buildQueryString(options);
|
|
108
|
-
const data = await this.fetchAPI(`/api/v1/${collection}/${id}${qs}`, {
|
|
109
|
-
method: 'PATCH',
|
|
110
|
-
body: JSON.stringify(payload),
|
|
111
|
-
...options,
|
|
112
|
-
});
|
|
113
|
-
return data.data?.document || data.data || data;
|
|
114
|
-
}
|
|
115
|
-
/**
|
|
116
|
-
* Delete a document.
|
|
117
|
-
*/
|
|
118
|
-
async delete(collection, id, options = {}) {
|
|
119
|
-
const qs = this.buildQueryString(options);
|
|
120
|
-
const data = await this.fetchAPI(`/api/v1/${collection}/${id}${qs}`, {
|
|
121
|
-
method: 'DELETE',
|
|
122
|
-
...options,
|
|
123
|
-
});
|
|
124
|
-
return data.data?.document || data.data || data;
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
export function createClient(options) {
|
|
128
|
-
return new ZenithClient(options);
|
|
129
|
-
}
|
package/dist/index.test.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/dist/index.test.js
DELETED
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
2
|
-
import { ZenithClient } from './index';
|
|
3
|
-
// Minimal fetch mock — intercepts calls and returns JSON
|
|
4
|
-
function makeClient() {
|
|
5
|
-
return new ZenithClient({ url: 'http://localhost:3000' });
|
|
6
|
-
}
|
|
7
|
-
beforeEach(() => {
|
|
8
|
-
global.fetch = vi.fn();
|
|
9
|
-
});
|
|
10
|
-
describe('ZenithClient — SWR cache', () => {
|
|
11
|
-
it('serves stale data immediately and revalidates in background', async () => {
|
|
12
|
-
const client = makeClient();
|
|
13
|
-
const mockData = { data: { docs: [{ _id: '1', title: 'Cached Post' }] } };
|
|
14
|
-
fetch.mockResolvedValueOnce({
|
|
15
|
-
ok: true,
|
|
16
|
-
json: () => Promise.resolve(mockData),
|
|
17
|
-
});
|
|
18
|
-
const result1 = await client.find('posts', { limit: 5, cacheTtl: 30_000 });
|
|
19
|
-
expect(result1.docs[0].title).toBe('Cached Post');
|
|
20
|
-
// Second request should return cached data immediately without waiting
|
|
21
|
-
const start = Date.now();
|
|
22
|
-
const result2 = await client.find('posts', { limit: 5 });
|
|
23
|
-
const elapsed = Date.now() - start;
|
|
24
|
-
// With cache hit and SWR revalidation, this should be near-instant
|
|
25
|
-
expect(elapsed).toBeLessThan(50);
|
|
26
|
-
expect(result2.docs[0].title).toBe('Cached Post');
|
|
27
|
-
});
|
|
28
|
-
it('bypasses cache when cacheTtl is 0', async () => {
|
|
29
|
-
const client = makeClient();
|
|
30
|
-
fetch.mockResolvedValue({
|
|
31
|
-
ok: true,
|
|
32
|
-
json: () => Promise.resolve({ data: { docs: [] } }),
|
|
33
|
-
});
|
|
34
|
-
// Should call fetch both times
|
|
35
|
-
await client.find('posts', { cacheTtl: 0 });
|
|
36
|
-
await client.find('posts', { cacheTtl: 0 });
|
|
37
|
-
expect(fetch.mock.calls.length).toBeGreaterThanOrEqual(2);
|
|
38
|
-
});
|
|
39
|
-
});
|
|
40
|
-
describe('ZenithClient — batch', () => {
|
|
41
|
-
it('executes multiple requests in parallel', async () => {
|
|
42
|
-
const client = makeClient();
|
|
43
|
-
fetch.mockResolvedValue({
|
|
44
|
-
ok: true,
|
|
45
|
-
json: () => Promise.resolve({ data: { posts: [] } }),
|
|
46
|
-
});
|
|
47
|
-
await client.batch([
|
|
48
|
-
{ method: 'GET', path: '/api/beta/posts' },
|
|
49
|
-
{ method: 'GET', path: '/api/beta/authors' },
|
|
50
|
-
]);
|
|
51
|
-
expect(fetch.mock.calls.length).toBe(2);
|
|
52
|
-
});
|
|
53
|
-
});
|
|
54
|
-
describe('ZenithClient — upload', () => {
|
|
55
|
-
it('sends FormData for file uploads and omits Content-Type header', async () => {
|
|
56
|
-
const client = makeClient();
|
|
57
|
-
fetch.mockResolvedValue({
|
|
58
|
-
ok: true,
|
|
59
|
-
json: () => Promise.resolve({ data: { _id: '123', url: 'http://cdn/img.jpg' } }),
|
|
60
|
-
});
|
|
61
|
-
const file = new File(['hello'], 'test.jpg', { type: 'image/jpeg' });
|
|
62
|
-
await client.upload(file, { alt: 'Test alt', focalPoint: { x: 50, y: 50 } });
|
|
63
|
-
const [url, options] = fetch.mock.calls[0];
|
|
64
|
-
expect(url).toContain('/api/beta/upload');
|
|
65
|
-
expect(options.headers.get('Content-Type')).toBeNull(); // fetch auto-sets multipart
|
|
66
|
-
expect(options.method).toBe('POST');
|
|
67
|
-
});
|
|
68
|
-
});
|
|
69
|
-
describe('ZenithClient — site switching', () => {
|
|
70
|
-
it('updates siteId and flushes cache when setSiteId is called', async () => {
|
|
71
|
-
const client = makeClient();
|
|
72
|
-
const mockData1 = { data: { docs: [{ _id: '1', title: 'Post Site A' }] } };
|
|
73
|
-
const mockData2 = { data: { docs: [{ _id: '2', title: 'Post Site B' }] } };
|
|
74
|
-
fetch
|
|
75
|
-
.mockResolvedValueOnce({
|
|
76
|
-
ok: true,
|
|
77
|
-
json: () => Promise.resolve(mockData1),
|
|
78
|
-
})
|
|
79
|
-
.mockResolvedValueOnce({
|
|
80
|
-
ok: true,
|
|
81
|
-
json: () => Promise.resolve(mockData2),
|
|
82
|
-
});
|
|
83
|
-
// Fetch on default site ID (empty)
|
|
84
|
-
const res1 = await client.find('posts', { limit: 5 });
|
|
85
|
-
expect(res1.docs[0].title).toBe('Post Site A');
|
|
86
|
-
// Change site ID using setSiteId
|
|
87
|
-
client.setSiteId('site-b');
|
|
88
|
-
// Fetch again — cache should be flushed, performing a new fetch with headers
|
|
89
|
-
const res2 = await client.find('posts', { limit: 5 });
|
|
90
|
-
expect(res2.docs[0].title).toBe('Post Site B');
|
|
91
|
-
// Verify correct header was sent in the second request
|
|
92
|
-
const lastCall = fetch.mock.calls[1];
|
|
93
|
-
expect(lastCall[1].headers.get('X-Zenith-Site-Id')).toBe('site-b');
|
|
94
|
-
});
|
|
95
|
-
});
|
package/dist/src/index.d.ts
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
interface ZenithConfig {
|
|
2
|
-
baseURL: string;
|
|
3
|
-
token?: string;
|
|
4
|
-
cacheTTL?: number;
|
|
5
|
-
}
|
|
6
|
-
/**
|
|
7
|
-
* Zenith SDK — Universal Client
|
|
8
|
-
* ─────────────────────────────
|
|
9
|
-
* A high-performance, type-safe client for consuming Zenith CMS content.
|
|
10
|
-
* Features built-in caching and automated error handling.
|
|
11
|
-
*/
|
|
12
|
-
export declare class ZenithClient {
|
|
13
|
-
private api;
|
|
14
|
-
private cache;
|
|
15
|
-
private ttl;
|
|
16
|
-
constructor(config: ZenithConfig);
|
|
17
|
-
/**
|
|
18
|
-
* Fetch a list of entries from a collection
|
|
19
|
-
*/
|
|
20
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
21
|
-
find<T = any>(slug: string, params?: Record<string, any>): Promise<{
|
|
22
|
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
23
|
-
data: T[];
|
|
24
|
-
meta: any;
|
|
25
1
|
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
26
|
-
}>;
|
|
27
|
-
/**
|
|
28
|
-
* Fetch a single entry by ID
|
|
29
|
-
*/
|
|
30
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
31
|
-
findOne<T = any>(slug: string, id: string): Promise<{
|
|
32
2
|
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
33
|
-
data: T;
|
|
34
|
-
}>;
|
|
35
|
-
/**
|
|
36
|
-
* Fetch a singleton collection
|
|
37
|
-
*/
|
|
38
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
39
|
-
getSingleton<T = any>(slug: string): Promise<{
|
|
40
3
|
// eslint-disable-line @typescript-eslint/no-explicit-any
|
|
41
|
-
data: T;
|
|
42
|
-
}>;
|
|
43
|
-
private getCache;
|
|
44
|
-
private setCache;
|
|
45
|
-
private handleError;
|
|
46
|
-
}
|
|
47
|
-
export {};
|
package/dist/src/index.js
DELETED
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
import axios from 'axios';
|
|
2
|
-
/**
|
|
3
|
-
* Zenith SDK — Universal Client
|
|
4
|
-
* ─────────────────────────────
|
|
5
|
-
* A high-performance, type-safe client for consuming Zenith CMS content.
|
|
6
|
-
* Features built-in caching and automated error handling.
|
|
7
|
-
*/
|
|
8
|
-
export class ZenithClient {
|
|
9
|
-
api;
|
|
10
|
-
cache = new Map();
|
|
11
|
-
ttl;
|
|
12
|
-
constructor(config) {
|
|
13
|
-
this.ttl = config.cacheTTL || 60000; // Default 1 min
|
|
14
|
-
this.api = axios.create({
|
|
15
|
-
baseURL: config.baseURL.endsWith('/api/beta') ? config.baseURL : `${config.baseURL}/api/beta`,
|
|
16
|
-
headers: config.token ? { Authorization: `Bearer ${config.token}` } : {},
|
|
17
|
-
});
|
|
18
|
-
}
|
|
19
|
-
/**
|
|
20
|
-
* Fetch a list of entries from a collection
|
|
21
|
-
*/
|
|
22
|
-
async find(slug, params = {}) {
|
|
23
|
-
const cacheKey = `${slug}:list:${JSON.stringify(params)}`;
|
|
24
|
-
const cached = this.getCache(cacheKey);
|
|
25
|
-
if (cached)
|
|
26
|
-
return cached;
|
|
27
|
-
try {
|
|
28
|
-
const res = await this.api.get(`/${slug}`, { params });
|
|
29
|
-
this.setCache(cacheKey, res.data);
|
|
30
|
-
return res.data;
|
|
31
|
-
}
|
|
32
|
-
catch (err) {
|
|
33
|
-
this.handleError(err);
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* Fetch a single entry by ID
|
|
38
|
-
*/
|
|
39
|
-
async findOne(slug, id) {
|
|
40
|
-
const cacheKey = `${slug}:${id}`;
|
|
41
|
-
const cached = this.getCache(cacheKey);
|
|
42
|
-
if (cached)
|
|
43
|
-
return cached;
|
|
44
|
-
try {
|
|
45
|
-
const res = await this.api.get(`/${slug}/${id}`);
|
|
46
|
-
this.setCache(cacheKey, res.data);
|
|
47
|
-
return res.data;
|
|
48
|
-
}
|
|
49
|
-
catch (err) {
|
|
50
|
-
this.handleError(err);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
/**
|
|
54
|
-
* Fetch a singleton collection
|
|
55
|
-
*/
|
|
56
|
-
async getSingleton(slug) {
|
|
57
|
-
const cacheKey = `singleton:${slug}`;
|
|
58
|
-
const cached = this.getCache(cacheKey);
|
|
59
|
-
if (cached)
|
|
60
|
-
return cached;
|
|
61
|
-
try {
|
|
62
|
-
const res = await this.api.get(`/${slug}`);
|
|
63
|
-
this.setCache(cacheKey, res.data);
|
|
64
|
-
return res.data;
|
|
65
|
-
}
|
|
66
|
-
catch (err) {
|
|
67
|
-
this.handleError(err);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
// --- Cache Helpers ---
|
|
71
|
-
getCache(key) {
|
|
72
|
-
const cached = this.cache.get(key);
|
|
73
|
-
if (cached && cached.expiry > Date.now())
|
|
74
|
-
return cached.data;
|
|
75
|
-
if (cached)
|
|
76
|
-
this.cache.delete(key);
|
|
77
|
-
return null;
|
|
78
|
-
}
|
|
79
|
-
setCache(key, data) {
|
|
80
|
-
this.cache.set(key, { data, expiry: Date.now() + this.ttl });
|
|
81
|
-
}
|
|
82
|
-
handleError(err) {
|
|
83
|
-
const message = err.response?.data?.error?.message || err.message || 'Unknown Zenith SDK Error';
|
|
84
|
-
throw new Error(`[Zenith SDK] ${message}`);
|
|
85
|
-
}
|
|
86
|
-
}
|
package/dist/types.d.ts
DELETED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import type { paths } from './schema';
|
|
2
|
-
/**
|
|
3
|
-
* Resolve a collection name string to its document type via OpenAPI schema paths.
|
|
4
|
-
* Falls back to unknown for unknown collections.
|
|
5
|
-
*/
|
|
6
|
-
type GetPath<C extends string> = `/${C}`;
|
|
7
|
-
type ExtractArrayItem<T> = T extends (infer U)[] ? U : unknown;
|
|
8
|
-
type OpenAPIResponse<P extends string> = P extends keyof paths ? 'get' extends keyof paths[P] ? 'responses' extends keyof paths[P]['get'] ? 200 extends keyof paths[P]['get']['responses'] ? 'content' extends keyof paths[P]['get']['responses'][200] ? 'application/json' extends keyof paths[P]['get']['responses'][200]['content'] ? 'schema' extends keyof paths[P]['get']['responses'][200]['content']['application/json'] ? paths[P]['get']['responses'][200]['content']['application/json']['schema'] : unknown : unknown : unknown : unknown : unknown : unknown : unknown;
|
|
9
|
-
export type DocType<C extends string> = OpenAPIResponse<GetPath<C>> extends never ? unknown : ExtractArrayItem<OpenAPIResponse<GetPath<C>>>;
|
|
10
|
-
export interface ZenithClientOptions {
|
|
11
|
-
url: string;
|
|
12
|
-
apiKey?: string;
|
|
13
|
-
siteId?: string;
|
|
14
|
-
/** SWR cache TTL in ms. default 30_000 (30s). set 0 to disable. */
|
|
15
|
-
cacheTtl?: number;
|
|
16
|
-
}
|
|
17
|
-
export interface FetchOptions extends RequestInit {
|
|
18
|
-
locale?: string;
|
|
19
|
-
depth?: number;
|
|
20
|
-
drafts?: boolean;
|
|
21
|
-
populate?: string[] | string;
|
|
22
|
-
select?: string[] | string;
|
|
23
|
-
/** Override the global cache TTL for this request. 0 = bypass cache. */
|
|
24
|
-
cacheTtl?: number;
|
|
25
|
-
/** Tag-based cache invalidation key for this request */
|
|
26
|
-
cacheTag?: string;
|
|
27
|
-
}
|
|
28
|
-
export interface FindOptions extends FetchOptions {
|
|
29
|
-
where?: Record<string, unknown>;
|
|
30
|
-
sort?: string;
|
|
31
|
-
limit?: number;
|
|
32
|
-
page?: number;
|
|
33
|
-
}
|
|
34
|
-
export interface BatchRequest {
|
|
35
|
-
method?: 'GET' | 'POST' | 'PATCH' | 'DELETE';
|
|
36
|
-
path: string;
|
|
37
|
-
body?: unknown;
|
|
38
|
-
headers?: Record<string, string>;
|
|
39
|
-
}
|
|
40
|
-
/** Structured error thrown by all ZenithClient methods. */
|
|
41
|
-
export declare class ZenithAPIError extends Error {
|
|
42
|
-
readonly status: number;
|
|
43
|
-
readonly code?: string;
|
|
44
|
-
readonly isNetworkError: boolean;
|
|
45
|
-
readonly isParseError: boolean;
|
|
46
|
-
constructor(opts: {
|
|
47
|
-
message: string;
|
|
48
|
-
status: number;
|
|
49
|
-
code?: string;
|
|
50
|
-
isNetworkError?: boolean;
|
|
51
|
-
isParseError?: boolean;
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
export {};
|
package/dist/types.js
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
// ── Error Handling ────────────────────────────────────────────────────────────
|
|
2
|
-
/** Structured error thrown by all ZenithClient methods. */
|
|
3
|
-
export class ZenithAPIError extends Error {
|
|
4
|
-
status;
|
|
5
|
-
code;
|
|
6
|
-
isNetworkError;
|
|
7
|
-
isParseError;
|
|
8
|
-
constructor(opts) {
|
|
9
|
-
super(opts.message);
|
|
10
|
-
this.name = 'ZenithAPIError';
|
|
11
|
-
this.status = opts.status;
|
|
12
|
-
this.code = opts.code;
|
|
13
|
-
this.isNetworkError = opts.isNetworkError ?? false;
|
|
14
|
-
this.isParseError = opts.isParseError ?? false;
|
|
15
|
-
}
|
|
16
|
-
}
|