@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.
Files changed (6) hide show
  1. package/README.md +134 -325
  2. package/index.cjs +128 -106
  3. package/index.d.cts +22 -33
  4. package/index.d.ts +22 -33
  5. package/index.mjs +126 -104
  6. package/package.json +1 -1
package/index.mjs CHANGED
@@ -1,62 +1,69 @@
1
1
  // src/lib.ts
2
2
  import * as jmespath from "jmespath";
3
- function isDevToken(token) {
4
- return token.startsWith("dev-");
5
- }
6
- function getBaseUrl(token) {
3
+ function getBaseUrl(token, devEnv) {
7
4
  let [env, siteId, ...rest] = token.split("-");
8
- return `https://${env}.sleekcms.com/${siteId}`;
5
+ if (devEnv === "production") return `https://${env}.sleekcms.com/${siteId}`;
6
+ else if (devEnv === "development") return `https://${env}.sleekcms.net/${siteId}`;
7
+ else if (devEnv === "localhost") return `http://localhost:9001/${env}/${siteId}`;
8
+ else throw new Error(`[SleekCMS] Unknown devEnv: ${devEnv}`);
9
9
  }
10
10
  function applyJmes(data, query) {
11
11
  if (!query) return data;
12
12
  return jmespath.search(data, query);
13
13
  }
14
- function createFetchSiteContent(options) {
15
- const { siteToken, env = "latest", mock } = options;
16
- const dev = isDevToken(siteToken);
17
- let cacheMode = !!options.cache || !!mock && dev;
18
- let cachedContent = null;
19
- return async function fetchSiteContent(searchQuery) {
20
- if (!siteToken) {
21
- throw new Error("[SleekCMS] siteToken is required");
22
- }
23
- if (cachedContent) {
24
- return applyJmes(cachedContent, searchQuery);
25
- }
26
- const baseUrl = getBaseUrl(siteToken).replace(/\/$/, "");
27
- const url = new URL(`${baseUrl}/${env}`);
28
- if (searchQuery && !cacheMode && !cachedContent) {
29
- url.searchParams.set("search", searchQuery);
30
- }
31
- if (mock && dev) {
32
- url.searchParams.set("mock", "true");
33
- }
34
- const res = await fetch(url.toString(), {
35
- method: "GET",
14
+ function getUrl({ siteToken, env, search: search2, lang, devEnv = "production" }) {
15
+ const baseUrl = getBaseUrl(siteToken, devEnv).replace(/\/$/, "");
16
+ const url = new URL(`${baseUrl}/${env}`);
17
+ if (search2) url.searchParams.append("search", search2);
18
+ if (lang) url.searchParams.append("lang", lang);
19
+ return url.toString();
20
+ }
21
+ async function fetchEnvTag({ siteToken, env }) {
22
+ const url = getUrl({ siteToken, env });
23
+ try {
24
+ let res = await fetch(url, {
25
+ method: "POST",
36
26
  headers: {
37
27
  "Content-Type": "application/json",
38
28
  Authorization: siteToken
39
29
  }
40
30
  });
41
- if (!res.ok) {
42
- let message = res.statusText;
43
- try {
44
- const data2 = await res.json();
45
- if (data2 && data2.message) message = data2.message;
46
- } catch {
31
+ if (res.ok) {
32
+ let data = await res.json();
33
+ if (data.tag) {
34
+ return data.tag;
47
35
  }
48
- throw new Error(`[SleekCMS] Request failed (${res.status}): ${message}`);
49
36
  }
50
- const data = await res.json();
51
- if (!searchQuery) {
52
- cachedContent = data;
53
- cacheMode = true;
37
+ } catch (e) {
38
+ console.error("[SleekCMS] Unable to resolve env tag.");
39
+ }
40
+ return env;
41
+ }
42
+ async function fetchSiteContent(options) {
43
+ const { siteToken, env = "latest", cdn = false, search: search2, lang } = options;
44
+ let url = getUrl({ siteToken, env, search: search2, lang });
45
+ if (cdn && !search2) {
46
+ let tag = await fetchEnvTag({ siteToken, env });
47
+ url = getUrl({ siteToken, env: tag, search: search2, lang });
48
+ }
49
+ const res = await fetch(url, {
50
+ method: "GET",
51
+ headers: {
52
+ "Content-Type": "application/json",
53
+ Authorization: siteToken
54
+ }
55
+ });
56
+ if (!res.ok) {
57
+ let message = res.statusText;
58
+ try {
59
+ const data = await res.json();
60
+ if (data && data.message) message = data.message;
61
+ } catch {
54
62
  }
55
- return data;
56
- };
63
+ throw new Error(`[SleekCMS] Request failed (${res.status}): ${message}`);
64
+ }
65
+ return await res.json();
57
66
  }
58
-
59
- // src/index.ts
60
67
  function extractSlugs(pages, path) {
61
68
  const slugs = [];
62
69
  const pagesList = pages ?? [];
@@ -75,121 +82,136 @@ function filterPagesByPath(pages, path) {
75
82
  return pth.startsWith(path);
76
83
  });
77
84
  }
78
- function createClient(options) {
79
- const fetchSiteContent = createFetchSiteContent(options);
80
- async function getContent(query) {
81
- return await fetchSiteContent(query);
85
+
86
+ // src/index.ts
87
+ async function createClient(options) {
88
+ const data = await fetchSiteContent(options);
89
+ function getContent(query) {
90
+ return applyJmes(data, query);
82
91
  }
83
- async function getPages(path, query) {
92
+ function getPages(path) {
84
93
  if (!path) {
85
94
  throw new Error("[SleekCMS] path is required for getPages");
86
95
  }
87
- const data = await fetchSiteContent();
88
- const filtered = filterPagesByPath(data.pages, path);
89
- return applyJmes(filtered, query);
96
+ return filterPagesByPath(data.pages, path);
90
97
  }
91
- async function getPage(path) {
98
+ function getPage(path) {
92
99
  if (!path) {
93
100
  throw new Error("[SleekCMS] path is required for getPage");
94
101
  }
95
- const data = await fetchSiteContent();
96
102
  const pages = data.pages ?? [];
97
103
  const page = pages.find((p) => {
98
104
  const pth = typeof p._path === "string" ? p._path : "";
99
105
  return pth === path;
100
106
  });
101
- if (!page) {
102
- throw new Error(`[SleekCMS] Page not found: ${path}`);
107
+ return page ?? null;
108
+ }
109
+ function getEntry(handle) {
110
+ if (!handle) {
111
+ throw new Error("[SleekCMS] handle is required for getEntry");
103
112
  }
104
- return page;
113
+ const entries = data.entries ?? {};
114
+ const entry = entries[handle] ?? null;
115
+ return entry;
105
116
  }
106
- async function getSlugs(path) {
117
+ function getSlugs(path) {
107
118
  if (!path) {
108
119
  throw new Error("[SleekCMS] path is required for getSlugs");
109
120
  }
110
- const data = await fetchSiteContent();
111
121
  return extractSlugs(data.pages, path);
112
122
  }
113
- async function getImages() {
114
- const data = await fetchSiteContent();
115
- return data.images ?? {};
116
- }
117
- async function getImage(name) {
118
- if (!name) return void 0;
119
- const data = await fetchSiteContent();
120
- return data.images ? data.images[name] : void 0;
123
+ function getImage(name) {
124
+ if (!name) return null;
125
+ return data.images ? data.images[name] : null;
121
126
  }
122
- async function getList(name) {
123
- if (!name) return void 0;
124
- const data = await fetchSiteContent();
127
+ function getList(name) {
128
+ if (!name) return null;
125
129
  const lists = data.lists ?? {};
126
130
  const list = lists[name];
127
- return Array.isArray(list) ? list : void 0;
131
+ return Array.isArray(list) ? list : null;
128
132
  }
129
133
  return {
130
134
  getContent,
131
135
  getPages,
132
136
  getPage,
137
+ getEntry,
133
138
  getSlugs,
134
- getImages,
135
139
  getImage,
136
140
  getList
137
141
  };
138
142
  }
139
- async function createSyncClient(options) {
140
- const fetchSiteContent = createFetchSiteContent(options);
141
- const data = await fetchSiteContent();
142
- function getContent(query) {
143
- return applyJmes(data, query);
144
- }
145
- function getPages(path, query) {
146
- if (!path) {
147
- throw new Error("[SleekCMS] path is required for getPages");
143
+ function createAsyncClient({ siteToken, env = "latest", cdn, lang }) {
144
+ let syncClient = null;
145
+ let tag = null;
146
+ let cache = {};
147
+ async function getContent(search2) {
148
+ if (cdn && !tag) tag = await fetchEnvTag({ siteToken, env });
149
+ if (!search2 && !syncClient) {
150
+ syncClient = await createClient({ siteToken, env: tag ?? env, cdn, lang });
151
+ cache = {};
148
152
  }
149
- const filtered = filterPagesByPath(data.pages, path);
150
- return applyJmes(filtered, query);
153
+ if (syncClient) return syncClient.getContent(search2);
154
+ if (!search2) return null;
155
+ if (!cache[search2]) cache[search2] = await fetchSiteContent({ siteToken, env: tag ?? env, search: search2, lang });
156
+ return cache[search2] ?? null;
151
157
  }
152
- function getPage(path) {
153
- if (!path) {
154
- throw new Error("[SleekCMS] path is required for getPage");
155
- }
156
- const pages = data.pages ?? [];
157
- const page = pages.find((p) => {
158
+ async function getPages(path) {
159
+ if (cdn && !tag) tag = await fetchEnvTag({ siteToken, env });
160
+ if (syncClient) return syncClient.getPages(path);
161
+ if (!cache.pages) cache.pages = await fetchSiteContent({ siteToken, env: tag ?? env, search: "pages", lang });
162
+ if (!path) return cache.pages;
163
+ else return filterPagesByPath(cache.pages, path);
164
+ }
165
+ async function getPage(path) {
166
+ var _a;
167
+ if (cdn && !tag) tag = await fetchEnvTag({ siteToken, env });
168
+ if (syncClient) return syncClient.getPage(path);
169
+ if (!cache.pages) cache.pages = await fetchSiteContent({ siteToken, env: tag ?? env, search: "pages", lang });
170
+ const page = (_a = cache.pages) == null ? void 0 : _a.find((p) => {
158
171
  const pth = typeof p._path === "string" ? p._path : "";
159
172
  return pth === path;
160
173
  });
161
174
  return page ?? null;
162
175
  }
163
- function getSlugs(path) {
164
- if (!path) {
165
- throw new Error("[SleekCMS] path is required for getSlugs");
176
+ async function getEntry(handle) {
177
+ if (cdn && !tag) tag = await fetchEnvTag({ siteToken, env });
178
+ if (syncClient) return syncClient.getEntry(handle);
179
+ let search2 = `entries.${handle}`;
180
+ if (cache[search2] === void 0) {
181
+ cache[search2] = await fetchSiteContent({ siteToken, env: tag ?? env, search: search2, lang });
166
182
  }
167
- return extractSlugs(data.pages, path);
183
+ return cache[search2];
168
184
  }
169
- function getImages() {
170
- return data.images ?? {};
185
+ async function getSlugs(path) {
186
+ if (cdn && !tag) tag = await fetchEnvTag({ siteToken, env });
187
+ if (syncClient) return syncClient.getSlugs(path);
188
+ if (!cache.pages) cache.pages = await fetchSiteContent({ siteToken, env: tag ?? env, search: "pages", lang });
189
+ return extractSlugs(cache.pages, path);
171
190
  }
172
- function getImage(name) {
173
- if (!name) return void 0;
174
- return data.images ? data.images[name] : void 0;
191
+ async function getImage(name) {
192
+ if (cdn && !tag) tag = await fetchEnvTag({ siteToken, env });
193
+ if (syncClient) return syncClient.getImage(name);
194
+ if (!cache.images) cache.images = await fetchSiteContent({ siteToken, env: tag ?? env, search: "images", lang });
195
+ return cache.images ? cache.images[name] : null;
175
196
  }
176
- function getList(name) {
177
- if (!name) return void 0;
178
- const lists = data.lists ?? {};
179
- const list = lists[name];
180
- return Array.isArray(list) ? list : void 0;
197
+ async function getList(name) {
198
+ if (cdn && !tag) tag = await fetchEnvTag({ siteToken, env });
199
+ if (syncClient) return syncClient.getList(name);
200
+ if (!cache.lists) cache.lists = await fetchSiteContent({ siteToken, env: tag ?? env, search: "lists", lang });
201
+ const list = cache.lists[name];
202
+ return Array.isArray(list) ? list : null;
181
203
  }
182
204
  return {
183
205
  getContent,
184
206
  getPages,
185
207
  getPage,
208
+ getEntry,
186
209
  getSlugs,
187
- getImages,
188
210
  getImage,
189
211
  getList
190
212
  };
191
213
  }
192
214
  export {
193
- createClient,
194
- createSyncClient
215
+ createAsyncClient,
216
+ createClient
195
217
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sleekcms/client",
3
- "version": "1.0.0",
3
+ "version": "2.0.0",
4
4
  "description": "Official SleekCMS content client for Node 18+ and browser",
5
5
  "type": "module",
6
6
  "main": "index.cjs",