@sleekcms/client 1.0.0 → 2.0.0
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 +134 -325
- package/index.cjs +128 -106
- package/index.d.cts +22 -33
- package/index.d.ts +22 -33
- package/index.mjs +126 -104
- package/package.json +1 -1
package/index.cjs
CHANGED
|
@@ -29,70 +29,77 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
29
29
|
// src/index.ts
|
|
30
30
|
var index_exports = {};
|
|
31
31
|
__export(index_exports, {
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
createAsyncClient: () => createAsyncClient,
|
|
33
|
+
createClient: () => createClient
|
|
34
34
|
});
|
|
35
35
|
module.exports = __toCommonJS(index_exports);
|
|
36
36
|
|
|
37
37
|
// src/lib.ts
|
|
38
38
|
var jmespath = __toESM(require("jmespath"), 1);
|
|
39
|
-
function
|
|
40
|
-
return token.startsWith("dev-");
|
|
41
|
-
}
|
|
42
|
-
function getBaseUrl(token) {
|
|
39
|
+
function getBaseUrl(token, devEnv) {
|
|
43
40
|
let [env, siteId, ...rest] = token.split("-");
|
|
44
|
-
return `https://${env}.sleekcms.com/${siteId}`;
|
|
41
|
+
if (devEnv === "production") return `https://${env}.sleekcms.com/${siteId}`;
|
|
42
|
+
else if (devEnv === "development") return `https://${env}.sleekcms.net/${siteId}`;
|
|
43
|
+
else if (devEnv === "localhost") return `http://localhost:9001/${env}/${siteId}`;
|
|
44
|
+
else throw new Error(`[SleekCMS] Unknown devEnv: ${devEnv}`);
|
|
45
45
|
}
|
|
46
46
|
function applyJmes(data, query) {
|
|
47
47
|
if (!query) return data;
|
|
48
48
|
return jmespath.search(data, query);
|
|
49
49
|
}
|
|
50
|
-
function
|
|
51
|
-
const
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
return
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
const baseUrl = getBaseUrl(siteToken).replace(/\/$/, "");
|
|
63
|
-
const url = new URL(`${baseUrl}/${env}`);
|
|
64
|
-
if (searchQuery && !cacheMode && !cachedContent) {
|
|
65
|
-
url.searchParams.set("search", searchQuery);
|
|
66
|
-
}
|
|
67
|
-
if (mock && dev) {
|
|
68
|
-
url.searchParams.set("mock", "true");
|
|
69
|
-
}
|
|
70
|
-
const res = await fetch(url.toString(), {
|
|
71
|
-
method: "GET",
|
|
50
|
+
function getUrl({ siteToken, env, search: search2, lang, devEnv = "production" }) {
|
|
51
|
+
const baseUrl = getBaseUrl(siteToken, devEnv).replace(/\/$/, "");
|
|
52
|
+
const url = new URL(`${baseUrl}/${env}`);
|
|
53
|
+
if (search2) url.searchParams.append("search", search2);
|
|
54
|
+
if (lang) url.searchParams.append("lang", lang);
|
|
55
|
+
return url.toString();
|
|
56
|
+
}
|
|
57
|
+
async function fetchEnvTag({ siteToken, env }) {
|
|
58
|
+
const url = getUrl({ siteToken, env });
|
|
59
|
+
try {
|
|
60
|
+
let res = await fetch(url, {
|
|
61
|
+
method: "POST",
|
|
72
62
|
headers: {
|
|
73
63
|
"Content-Type": "application/json",
|
|
74
64
|
Authorization: siteToken
|
|
75
65
|
}
|
|
76
66
|
});
|
|
77
|
-
if (
|
|
78
|
-
let
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
if (data2 && data2.message) message = data2.message;
|
|
82
|
-
} catch {
|
|
67
|
+
if (res.ok) {
|
|
68
|
+
let data = await res.json();
|
|
69
|
+
if (data.tag) {
|
|
70
|
+
return data.tag;
|
|
83
71
|
}
|
|
84
|
-
throw new Error(`[SleekCMS] Request failed (${res.status}): ${message}`);
|
|
85
72
|
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
73
|
+
} catch (e) {
|
|
74
|
+
console.error("[SleekCMS] Unable to resolve env tag.");
|
|
75
|
+
}
|
|
76
|
+
return env;
|
|
77
|
+
}
|
|
78
|
+
async function fetchSiteContent(options) {
|
|
79
|
+
const { siteToken, env = "latest", cdn = false, search: search2, lang } = options;
|
|
80
|
+
let url = getUrl({ siteToken, env, search: search2, lang });
|
|
81
|
+
if (cdn && !search2) {
|
|
82
|
+
let tag = await fetchEnvTag({ siteToken, env });
|
|
83
|
+
url = getUrl({ siteToken, env: tag, search: search2, lang });
|
|
84
|
+
}
|
|
85
|
+
const res = await fetch(url, {
|
|
86
|
+
method: "GET",
|
|
87
|
+
headers: {
|
|
88
|
+
"Content-Type": "application/json",
|
|
89
|
+
Authorization: siteToken
|
|
90
90
|
}
|
|
91
|
-
|
|
92
|
-
|
|
91
|
+
});
|
|
92
|
+
if (!res.ok) {
|
|
93
|
+
let message = res.statusText;
|
|
94
|
+
try {
|
|
95
|
+
const data = await res.json();
|
|
96
|
+
if (data && data.message) message = data.message;
|
|
97
|
+
} catch {
|
|
98
|
+
}
|
|
99
|
+
throw new Error(`[SleekCMS] Request failed (${res.status}): ${message}`);
|
|
100
|
+
}
|
|
101
|
+
return await res.json();
|
|
93
102
|
}
|
|
94
|
-
|
|
95
|
-
// src/index.ts
|
|
96
103
|
function extractSlugs(pages, path) {
|
|
97
104
|
const slugs = [];
|
|
98
105
|
const pagesList = pages ?? [];
|
|
@@ -111,122 +118,137 @@ function filterPagesByPath(pages, path) {
|
|
|
111
118
|
return pth.startsWith(path);
|
|
112
119
|
});
|
|
113
120
|
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
121
|
+
|
|
122
|
+
// src/index.ts
|
|
123
|
+
async function createClient(options) {
|
|
124
|
+
const data = await fetchSiteContent(options);
|
|
125
|
+
function getContent(query) {
|
|
126
|
+
return applyJmes(data, query);
|
|
118
127
|
}
|
|
119
|
-
|
|
128
|
+
function getPages(path) {
|
|
120
129
|
if (!path) {
|
|
121
130
|
throw new Error("[SleekCMS] path is required for getPages");
|
|
122
131
|
}
|
|
123
|
-
|
|
124
|
-
const filtered = filterPagesByPath(data.pages, path);
|
|
125
|
-
return applyJmes(filtered, query);
|
|
132
|
+
return filterPagesByPath(data.pages, path);
|
|
126
133
|
}
|
|
127
|
-
|
|
134
|
+
function getPage(path) {
|
|
128
135
|
if (!path) {
|
|
129
136
|
throw new Error("[SleekCMS] path is required for getPage");
|
|
130
137
|
}
|
|
131
|
-
const data = await fetchSiteContent();
|
|
132
138
|
const pages = data.pages ?? [];
|
|
133
139
|
const page = pages.find((p) => {
|
|
134
140
|
const pth = typeof p._path === "string" ? p._path : "";
|
|
135
141
|
return pth === path;
|
|
136
142
|
});
|
|
137
|
-
|
|
138
|
-
|
|
143
|
+
return page ?? null;
|
|
144
|
+
}
|
|
145
|
+
function getEntry(handle) {
|
|
146
|
+
if (!handle) {
|
|
147
|
+
throw new Error("[SleekCMS] handle is required for getEntry");
|
|
139
148
|
}
|
|
140
|
-
|
|
149
|
+
const entries = data.entries ?? {};
|
|
150
|
+
const entry = entries[handle] ?? null;
|
|
151
|
+
return entry;
|
|
141
152
|
}
|
|
142
|
-
|
|
153
|
+
function getSlugs(path) {
|
|
143
154
|
if (!path) {
|
|
144
155
|
throw new Error("[SleekCMS] path is required for getSlugs");
|
|
145
156
|
}
|
|
146
|
-
const data = await fetchSiteContent();
|
|
147
157
|
return extractSlugs(data.pages, path);
|
|
148
158
|
}
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
return data.images
|
|
152
|
-
}
|
|
153
|
-
async function getImage(name) {
|
|
154
|
-
if (!name) return void 0;
|
|
155
|
-
const data = await fetchSiteContent();
|
|
156
|
-
return data.images ? data.images[name] : void 0;
|
|
159
|
+
function getImage(name) {
|
|
160
|
+
if (!name) return null;
|
|
161
|
+
return data.images ? data.images[name] : null;
|
|
157
162
|
}
|
|
158
|
-
|
|
159
|
-
if (!name) return
|
|
160
|
-
const data = await fetchSiteContent();
|
|
163
|
+
function getList(name) {
|
|
164
|
+
if (!name) return null;
|
|
161
165
|
const lists = data.lists ?? {};
|
|
162
166
|
const list = lists[name];
|
|
163
|
-
return Array.isArray(list) ? list :
|
|
167
|
+
return Array.isArray(list) ? list : null;
|
|
164
168
|
}
|
|
165
169
|
return {
|
|
166
170
|
getContent,
|
|
167
171
|
getPages,
|
|
168
172
|
getPage,
|
|
173
|
+
getEntry,
|
|
169
174
|
getSlugs,
|
|
170
|
-
getImages,
|
|
171
175
|
getImage,
|
|
172
176
|
getList
|
|
173
177
|
};
|
|
174
178
|
}
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
179
|
+
function createAsyncClient({ siteToken, env = "latest", cdn, lang }) {
|
|
180
|
+
let syncClient = null;
|
|
181
|
+
let tag = null;
|
|
182
|
+
let cache = {};
|
|
183
|
+
async function getContent(search2) {
|
|
184
|
+
if (cdn && !tag) tag = await fetchEnvTag({ siteToken, env });
|
|
185
|
+
if (!search2 && !syncClient) {
|
|
186
|
+
syncClient = await createClient({ siteToken, env: tag ?? env, cdn, lang });
|
|
187
|
+
cache = {};
|
|
184
188
|
}
|
|
185
|
-
|
|
186
|
-
|
|
189
|
+
if (syncClient) return syncClient.getContent(search2);
|
|
190
|
+
if (!search2) return null;
|
|
191
|
+
if (!cache[search2]) cache[search2] = await fetchSiteContent({ siteToken, env: tag ?? env, search: search2, lang });
|
|
192
|
+
return cache[search2] ?? null;
|
|
193
|
+
}
|
|
194
|
+
async function getPages(path) {
|
|
195
|
+
if (cdn && !tag) tag = await fetchEnvTag({ siteToken, env });
|
|
196
|
+
if (syncClient) return syncClient.getPages(path);
|
|
197
|
+
if (!cache.pages) cache.pages = await fetchSiteContent({ siteToken, env: tag ?? env, search: "pages", lang });
|
|
198
|
+
if (!path) return cache.pages;
|
|
199
|
+
else return filterPagesByPath(cache.pages, path);
|
|
187
200
|
}
|
|
188
|
-
function getPage(path) {
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
const page = pages.find((p) => {
|
|
201
|
+
async function getPage(path) {
|
|
202
|
+
var _a;
|
|
203
|
+
if (cdn && !tag) tag = await fetchEnvTag({ siteToken, env });
|
|
204
|
+
if (syncClient) return syncClient.getPage(path);
|
|
205
|
+
if (!cache.pages) cache.pages = await fetchSiteContent({ siteToken, env: tag ?? env, search: "pages", lang });
|
|
206
|
+
const page = (_a = cache.pages) == null ? void 0 : _a.find((p) => {
|
|
194
207
|
const pth = typeof p._path === "string" ? p._path : "";
|
|
195
208
|
return pth === path;
|
|
196
209
|
});
|
|
197
210
|
return page ?? null;
|
|
198
211
|
}
|
|
199
|
-
function
|
|
200
|
-
if (!
|
|
201
|
-
|
|
212
|
+
async function getEntry(handle) {
|
|
213
|
+
if (cdn && !tag) tag = await fetchEnvTag({ siteToken, env });
|
|
214
|
+
if (syncClient) return syncClient.getEntry(handle);
|
|
215
|
+
let search2 = `entries.${handle}`;
|
|
216
|
+
if (cache[search2] === void 0) {
|
|
217
|
+
cache[search2] = await fetchSiteContent({ siteToken, env: tag ?? env, search: search2, lang });
|
|
202
218
|
}
|
|
203
|
-
return
|
|
219
|
+
return cache[search2];
|
|
204
220
|
}
|
|
205
|
-
function
|
|
206
|
-
|
|
221
|
+
async function getSlugs(path) {
|
|
222
|
+
if (cdn && !tag) tag = await fetchEnvTag({ siteToken, env });
|
|
223
|
+
if (syncClient) return syncClient.getSlugs(path);
|
|
224
|
+
if (!cache.pages) cache.pages = await fetchSiteContent({ siteToken, env: tag ?? env, search: "pages", lang });
|
|
225
|
+
return extractSlugs(cache.pages, path);
|
|
207
226
|
}
|
|
208
|
-
function getImage(name) {
|
|
209
|
-
if (!
|
|
210
|
-
|
|
227
|
+
async function getImage(name) {
|
|
228
|
+
if (cdn && !tag) tag = await fetchEnvTag({ siteToken, env });
|
|
229
|
+
if (syncClient) return syncClient.getImage(name);
|
|
230
|
+
if (!cache.images) cache.images = await fetchSiteContent({ siteToken, env: tag ?? env, search: "images", lang });
|
|
231
|
+
return cache.images ? cache.images[name] : null;
|
|
211
232
|
}
|
|
212
|
-
function getList(name) {
|
|
213
|
-
if (!
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
233
|
+
async function getList(name) {
|
|
234
|
+
if (cdn && !tag) tag = await fetchEnvTag({ siteToken, env });
|
|
235
|
+
if (syncClient) return syncClient.getList(name);
|
|
236
|
+
if (!cache.lists) cache.lists = await fetchSiteContent({ siteToken, env: tag ?? env, search: "lists", lang });
|
|
237
|
+
const list = cache.lists[name];
|
|
238
|
+
return Array.isArray(list) ? list : null;
|
|
217
239
|
}
|
|
218
240
|
return {
|
|
219
241
|
getContent,
|
|
220
242
|
getPages,
|
|
221
243
|
getPage,
|
|
244
|
+
getEntry,
|
|
222
245
|
getSlugs,
|
|
223
|
-
getImages,
|
|
224
246
|
getImage,
|
|
225
247
|
getList
|
|
226
248
|
};
|
|
227
249
|
}
|
|
228
250
|
// Annotate the CommonJS export names for ESM import in node:
|
|
229
251
|
0 && (module.exports = {
|
|
230
|
-
|
|
231
|
-
|
|
252
|
+
createAsyncClient,
|
|
253
|
+
createClient
|
|
232
254
|
});
|
package/index.d.cts
CHANGED
|
@@ -12,7 +12,9 @@ type List = Array<{
|
|
|
12
12
|
value: string;
|
|
13
13
|
}>;
|
|
14
14
|
interface SleekSiteContent {
|
|
15
|
-
entries?:
|
|
15
|
+
entries?: {
|
|
16
|
+
[handle: string]: Entry | Entry[];
|
|
17
|
+
};
|
|
16
18
|
pages?: Array<Page>;
|
|
17
19
|
images?: Record<string, Image>;
|
|
18
20
|
lists?: Record<string, List>;
|
|
@@ -23,42 +25,29 @@ interface SleekSiteContent {
|
|
|
23
25
|
interface ClientOptions {
|
|
24
26
|
siteToken: string;
|
|
25
27
|
env?: string;
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
resolveEnv?: boolean;
|
|
28
|
+
cdn?: boolean;
|
|
29
|
+
lang?: string;
|
|
29
30
|
}
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Async SleekCMS client: methods return Promises.
|
|
33
|
-
*/
|
|
34
31
|
interface SleekClient {
|
|
35
|
-
getContent(query?: string): Promise<SleekSiteContent>;
|
|
36
|
-
getPages(path: string, query?: string): Promise<SleekSiteContent["pages"]>;
|
|
37
|
-
getPage(path: string): Promise<Page>;
|
|
38
|
-
getSlugs(path: string): Promise<string[]>;
|
|
39
|
-
getImages(): Promise<SleekSiteContent["images"]>;
|
|
40
|
-
getImage(name: string): Promise<unknown | undefined>;
|
|
41
|
-
getList<T = unknown>(name: string): Promise<T[] | undefined>;
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* Sync client: prefetches full content once; subsequent calls are in-memory only.
|
|
45
|
-
*/
|
|
46
|
-
interface SleekSyncClient {
|
|
47
32
|
getContent(query?: string): SleekSiteContent;
|
|
48
|
-
getPages(path: string
|
|
33
|
+
getPages(path: string): SleekSiteContent["pages"];
|
|
49
34
|
getPage(path: string): Page | null;
|
|
35
|
+
getEntry(handle: string): Entry | Entry[] | null;
|
|
50
36
|
getSlugs(path: string): string[];
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
getList<T = unknown>(name: string): T[] | undefined;
|
|
37
|
+
getImage(name: string): Image | null;
|
|
38
|
+
getList(name: string): List | null;
|
|
54
39
|
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
40
|
+
interface SleekAsyncClient {
|
|
41
|
+
getContent(query?: string): Promise<SleekSiteContent>;
|
|
42
|
+
getPages(path: string): Promise<SleekSiteContent["pages"]>;
|
|
43
|
+
getPage(path: string): Promise<Page | null>;
|
|
44
|
+
getEntry(handle: string): Promise<Entry | Entry[] | null>;
|
|
45
|
+
getSlugs(path: string): Promise<string[]>;
|
|
46
|
+
getImage(name: string): Promise<Image | null>;
|
|
47
|
+
getList(name: string): Promise<List | null>;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
declare function createClient(options: ClientOptions): Promise<SleekClient>;
|
|
51
|
+
declare function createAsyncClient({ siteToken, env, cdn, lang }: ClientOptions): SleekAsyncClient | any;
|
|
63
52
|
|
|
64
|
-
export { type ClientOptions, type
|
|
53
|
+
export { type ClientOptions, type Image, type List, type SleekSiteContent, createAsyncClient, createClient };
|
package/index.d.ts
CHANGED
|
@@ -12,7 +12,9 @@ type List = Array<{
|
|
|
12
12
|
value: string;
|
|
13
13
|
}>;
|
|
14
14
|
interface SleekSiteContent {
|
|
15
|
-
entries?:
|
|
15
|
+
entries?: {
|
|
16
|
+
[handle: string]: Entry | Entry[];
|
|
17
|
+
};
|
|
16
18
|
pages?: Array<Page>;
|
|
17
19
|
images?: Record<string, Image>;
|
|
18
20
|
lists?: Record<string, List>;
|
|
@@ -23,42 +25,29 @@ interface SleekSiteContent {
|
|
|
23
25
|
interface ClientOptions {
|
|
24
26
|
siteToken: string;
|
|
25
27
|
env?: string;
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
resolveEnv?: boolean;
|
|
28
|
+
cdn?: boolean;
|
|
29
|
+
lang?: string;
|
|
29
30
|
}
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Async SleekCMS client: methods return Promises.
|
|
33
|
-
*/
|
|
34
31
|
interface SleekClient {
|
|
35
|
-
getContent(query?: string): Promise<SleekSiteContent>;
|
|
36
|
-
getPages(path: string, query?: string): Promise<SleekSiteContent["pages"]>;
|
|
37
|
-
getPage(path: string): Promise<Page>;
|
|
38
|
-
getSlugs(path: string): Promise<string[]>;
|
|
39
|
-
getImages(): Promise<SleekSiteContent["images"]>;
|
|
40
|
-
getImage(name: string): Promise<unknown | undefined>;
|
|
41
|
-
getList<T = unknown>(name: string): Promise<T[] | undefined>;
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* Sync client: prefetches full content once; subsequent calls are in-memory only.
|
|
45
|
-
*/
|
|
46
|
-
interface SleekSyncClient {
|
|
47
32
|
getContent(query?: string): SleekSiteContent;
|
|
48
|
-
getPages(path: string
|
|
33
|
+
getPages(path: string): SleekSiteContent["pages"];
|
|
49
34
|
getPage(path: string): Page | null;
|
|
35
|
+
getEntry(handle: string): Entry | Entry[] | null;
|
|
50
36
|
getSlugs(path: string): string[];
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
getList<T = unknown>(name: string): T[] | undefined;
|
|
37
|
+
getImage(name: string): Image | null;
|
|
38
|
+
getList(name: string): List | null;
|
|
54
39
|
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
40
|
+
interface SleekAsyncClient {
|
|
41
|
+
getContent(query?: string): Promise<SleekSiteContent>;
|
|
42
|
+
getPages(path: string): Promise<SleekSiteContent["pages"]>;
|
|
43
|
+
getPage(path: string): Promise<Page | null>;
|
|
44
|
+
getEntry(handle: string): Promise<Entry | Entry[] | null>;
|
|
45
|
+
getSlugs(path: string): Promise<string[]>;
|
|
46
|
+
getImage(name: string): Promise<Image | null>;
|
|
47
|
+
getList(name: string): Promise<List | null>;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
declare function createClient(options: ClientOptions): Promise<SleekClient>;
|
|
51
|
+
declare function createAsyncClient({ siteToken, env, cdn, lang }: ClientOptions): SleekAsyncClient | any;
|
|
63
52
|
|
|
64
|
-
export { type ClientOptions, type
|
|
53
|
+
export { type ClientOptions, type Image, type List, type SleekSiteContent, createAsyncClient, createClient };
|