@crayonscodetech/cms-sdk 1.0.8 → 1.0.10
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 +167 -33
- package/dist/index.cjs +332 -207
- package/dist/index.d.cts +175 -42
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +175 -42
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +329 -182
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -19
package/dist/index.cjs
CHANGED
|
@@ -1,52 +1,28 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
//#region \0rolldown/runtime.js
|
|
3
|
-
var __create = Object.create;
|
|
4
|
-
var __defProp = Object.defineProperty;
|
|
5
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
-
var __copyProps = (to, from, except, desc) => {
|
|
10
|
-
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
11
|
-
key = keys[i];
|
|
12
|
-
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
13
|
-
get: ((k) => from[k]).bind(null, key),
|
|
14
|
-
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
15
|
-
});
|
|
16
|
-
}
|
|
17
|
-
return to;
|
|
18
|
-
};
|
|
19
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
|
|
20
|
-
value: mod,
|
|
21
|
-
enumerable: true
|
|
22
|
-
}) : target, mod));
|
|
23
|
-
//#endregion
|
|
24
|
-
let react = require("react");
|
|
25
|
-
react = __toESM(react, 1);
|
|
26
|
-
let lucide_react = require("lucide-react");
|
|
27
2
|
//#region src/constants/pageTypes.ts
|
|
3
|
+
/**
|
|
4
|
+
* Page type identifiers. Mirrors cms-backend/src/constants/pageTypes.ts.
|
|
5
|
+
*
|
|
6
|
+
* `pageTypes` are the singleton types — a site may have at most one page of
|
|
7
|
+
* each, enforced on create by the backend (cms/page/page.routes.ts). Attempting
|
|
8
|
+
* a second one is rejected with "A page with type "<type>" already exists for
|
|
9
|
+
* this site". `custom` is the only repeatable type.
|
|
10
|
+
*/
|
|
28
11
|
const pageTypes = [
|
|
29
12
|
"home",
|
|
30
13
|
"about",
|
|
31
|
-
"contact"
|
|
32
|
-
];
|
|
33
|
-
const defaultPageTypes = [
|
|
34
|
-
...pageTypes,
|
|
14
|
+
"contact",
|
|
35
15
|
"services",
|
|
36
16
|
"blog",
|
|
37
17
|
"team",
|
|
38
18
|
"gallery",
|
|
39
|
-
"events"
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
"custom",
|
|
44
|
-
"services",
|
|
45
|
-
"blog",
|
|
46
|
-
"team",
|
|
47
|
-
"gallery",
|
|
48
|
-
"events"
|
|
19
|
+
"events",
|
|
20
|
+
"clients-partners",
|
|
21
|
+
"testimonial",
|
|
22
|
+
"faq"
|
|
49
23
|
];
|
|
24
|
+
/** The full set accepted by the backend's page validator. */
|
|
25
|
+
const allPageTypes = [...pageTypes, "custom"];
|
|
50
26
|
//#endregion
|
|
51
27
|
//#region src/constants/index.ts
|
|
52
28
|
const PAGINATION = {
|
|
@@ -106,6 +82,30 @@ const MEDIA = {
|
|
|
106
82
|
MAX_IMAGE_SIZE: 5242880
|
|
107
83
|
};
|
|
108
84
|
//#endregion
|
|
85
|
+
//#region src/types/contact.ts
|
|
86
|
+
/** Attachment caps enforced by the API; mirrored here to fail fast client-side. */
|
|
87
|
+
const MAX_CONTACT_ATTACHMENTS = 3;
|
|
88
|
+
/**
|
|
89
|
+
* Total attachment budget, measured on RAW bytes.
|
|
90
|
+
*
|
|
91
|
+
* Attachments are forwarded onto the notification email, so the ceiling is
|
|
92
|
+
* Cloudflare Email's 5 MiB message limit — but the wire format is base64, 4/3
|
|
93
|
+
* the size. 3 MiB raw leaves headroom; 4 MiB encoded to ~5.33 MiB and was
|
|
94
|
+
* already over. Keep in step with MAX_CONTACT_ATTACHMENTS_TOTAL_BYTES in
|
|
95
|
+
* cms-backend/src/constants/limits.ts.
|
|
96
|
+
*/
|
|
97
|
+
const MAX_CONTACT_ATTACHMENTS_TOTAL_BYTES = 3145728;
|
|
98
|
+
const CONTACT_ATTACHMENT_MIME_ALLOWLIST = [
|
|
99
|
+
"application/pdf",
|
|
100
|
+
"image/png",
|
|
101
|
+
"image/jpeg",
|
|
102
|
+
"image/webp",
|
|
103
|
+
"image/gif",
|
|
104
|
+
"text/plain",
|
|
105
|
+
"application/msword",
|
|
106
|
+
"application/vnd.openxmlformats-officedocument.wordprocessingml.document"
|
|
107
|
+
];
|
|
108
|
+
//#endregion
|
|
109
109
|
//#region src/core/client.ts
|
|
110
110
|
var CmsError = class extends Error {
|
|
111
111
|
message;
|
|
@@ -122,9 +122,9 @@ var CmsError = class extends Error {
|
|
|
122
122
|
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
123
123
|
function createCmsClient(config) {
|
|
124
124
|
const { baseUrl, defaultOptions = {} } = config;
|
|
125
|
-
async function cmsFetch(endpoint, options = {}
|
|
125
|
+
async function cmsFetch(endpoint, options = {}) {
|
|
126
126
|
const url = `${baseUrl}${endpoint}`;
|
|
127
|
-
const { revalidate = CACHE.NO_CACHE, tags, ...rest } = {
|
|
127
|
+
const { revalidate = CACHE.NO_CACHE, tags, retries = 1, ...rest } = {
|
|
128
128
|
...defaultOptions,
|
|
129
129
|
...options
|
|
130
130
|
};
|
|
@@ -135,12 +135,9 @@ function createCmsClient(config) {
|
|
|
135
135
|
...tags && { tags }
|
|
136
136
|
}
|
|
137
137
|
};
|
|
138
|
-
let lastError = null;
|
|
139
138
|
for (let attempt = 0; attempt <= retries; attempt++) try {
|
|
140
139
|
const response = await fetch(url, fetchConfig);
|
|
141
140
|
if (!response.ok) {
|
|
142
|
-
const errorMsg = `API request failed: ${response.status} ${url}`;
|
|
143
|
-
console.error(errorMsg);
|
|
144
141
|
if (attempt < retries && [
|
|
145
142
|
502,
|
|
146
143
|
503,
|
|
@@ -149,32 +146,29 @@ function createCmsClient(config) {
|
|
|
149
146
|
await sleep(Math.pow(2, attempt) * 1e3);
|
|
150
147
|
continue;
|
|
151
148
|
}
|
|
152
|
-
|
|
149
|
+
let errorMsg = `API request failed: ${response.status} ${url}`;
|
|
150
|
+
try {
|
|
151
|
+
const body = await response.json();
|
|
152
|
+
if (body?.message) errorMsg = body.message;
|
|
153
|
+
} catch {}
|
|
154
|
+
throw new CmsError(errorMsg, response.status, url);
|
|
153
155
|
}
|
|
154
156
|
if (response.status === 204) return null;
|
|
155
157
|
const result = await response.json();
|
|
156
158
|
return result.data ?? result;
|
|
157
159
|
} catch (error) {
|
|
158
|
-
|
|
159
|
-
console.error(`API request error (attempt ${attempt + 1}/${retries + 1}): ${url}`, lastError);
|
|
160
|
+
if (error instanceof CmsError) throw error;
|
|
160
161
|
if (attempt < retries) {
|
|
161
162
|
await sleep(Math.pow(2, attempt) * 1e3);
|
|
162
163
|
continue;
|
|
163
164
|
}
|
|
165
|
+
throw new CmsError(`Request failed: ${error instanceof Error ? error.message : String(error)}`, void 0, url);
|
|
164
166
|
}
|
|
165
|
-
|
|
166
|
-
}
|
|
167
|
-
async function cmsFetchPaginated(endpoint, options = {}
|
|
168
|
-
const emptyResponse = {
|
|
169
|
-
data: [],
|
|
170
|
-
pagination: {
|
|
171
|
-
page: 1,
|
|
172
|
-
limit: PAGINATION.DEFAULT_LIMIT,
|
|
173
|
-
total: 0
|
|
174
|
-
}
|
|
175
|
-
};
|
|
167
|
+
throw new CmsError(`Request failed after ${retries + 1} attempts`, void 0, url);
|
|
168
|
+
}
|
|
169
|
+
async function cmsFetchPaginated(endpoint, options = {}) {
|
|
176
170
|
const url = `${baseUrl}${endpoint}`;
|
|
177
|
-
const { revalidate = CACHE.NO_CACHE, tags, ...rest } = {
|
|
171
|
+
const { revalidate = CACHE.NO_CACHE, tags, retries = 1, ...rest } = {
|
|
178
172
|
...defaultOptions,
|
|
179
173
|
...options
|
|
180
174
|
};
|
|
@@ -188,7 +182,6 @@ function createCmsClient(config) {
|
|
|
188
182
|
for (let attempt = 0; attempt <= retries; attempt++) try {
|
|
189
183
|
const response = await fetch(url, fetchConfig);
|
|
190
184
|
if (!response.ok) {
|
|
191
|
-
console.error(`API request failed: ${response.status} ${url}`);
|
|
192
185
|
if (attempt < retries && [
|
|
193
186
|
502,
|
|
194
187
|
503,
|
|
@@ -197,17 +190,23 @@ function createCmsClient(config) {
|
|
|
197
190
|
await sleep(Math.pow(2, attempt) * 1e3);
|
|
198
191
|
continue;
|
|
199
192
|
}
|
|
200
|
-
|
|
193
|
+
let errorMsg = `API request failed: ${response.status} ${url}`;
|
|
194
|
+
try {
|
|
195
|
+
const body = await response.json();
|
|
196
|
+
if (body?.message) errorMsg = body.message;
|
|
197
|
+
} catch {}
|
|
198
|
+
throw new CmsError(errorMsg, response.status, url);
|
|
201
199
|
}
|
|
202
200
|
return await response.json();
|
|
203
201
|
} catch (error) {
|
|
204
|
-
|
|
202
|
+
if (error instanceof CmsError) throw error;
|
|
205
203
|
if (attempt < retries) {
|
|
206
204
|
await sleep(Math.pow(2, attempt) * 1e3);
|
|
207
205
|
continue;
|
|
208
206
|
}
|
|
207
|
+
throw new CmsError(`Request failed: ${error instanceof Error ? error.message : String(error)}`, void 0, url);
|
|
209
208
|
}
|
|
210
|
-
|
|
209
|
+
throw new CmsError(`Request failed after ${retries + 1} attempts`, void 0, url);
|
|
211
210
|
}
|
|
212
211
|
function buildQueryString(params) {
|
|
213
212
|
const query = new URLSearchParams();
|
|
@@ -249,17 +248,25 @@ function createCmsClient(config) {
|
|
|
249
248
|
});
|
|
250
249
|
}
|
|
251
250
|
async function fetchPageByUrl(siteId, urlPath, options) {
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
251
|
+
const targetUrl = urlPath === "/" || urlPath === "" ? "/" : `/${urlPath.replace(/^\/|\/$/g, "")}`;
|
|
252
|
+
return cmsFetch(`/api/public/cms/${siteId}/page/by-url/?url=${encodeURIComponent(targetUrl)}`, {
|
|
253
|
+
revalidate: CACHE.SHORT,
|
|
254
|
+
tags: ["pages", `page-${targetUrl || "root"}`],
|
|
255
|
+
...options
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* The site's single published page of a given type, with its sections — the
|
|
260
|
+
* same payload as `fetchPageByUrl`. Prefer this when you know which kind of
|
|
261
|
+
* page you want but not its url, since an editor can rename the url at any
|
|
262
|
+
* time. Returns null when the site has no published page of that type.
|
|
263
|
+
*/
|
|
264
|
+
async function fetchPageByType(siteId, pageType, options) {
|
|
265
|
+
return cmsFetch(`/api/public/cms/${siteId}/page/by-type/${encodeURIComponent(pageType)}/`, {
|
|
266
|
+
revalidate: CACHE.SHORT,
|
|
267
|
+
tags: ["pages", `page-type-${pageType}`],
|
|
268
|
+
...options
|
|
269
|
+
});
|
|
263
270
|
}
|
|
264
271
|
function fetchAboutUs(siteId, options) {
|
|
265
272
|
return cmsFetch(`/api/public/cms/${siteId}/about-us/`, {
|
|
@@ -385,14 +392,73 @@ function createCmsClient(config) {
|
|
|
385
392
|
...options
|
|
386
393
|
});
|
|
387
394
|
}
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
395
|
+
/**
|
|
396
|
+
* Public Turnstile settings for the site's contact form.
|
|
397
|
+
*
|
|
398
|
+
* Call this before rendering the form: when `turnstile.enabled` is true the
|
|
399
|
+
* widget must be rendered with `turnstile.site_key` and its token passed to
|
|
400
|
+
* `submitContactForm`, or every submission is rejected.
|
|
401
|
+
*/
|
|
402
|
+
function fetchContactConfig(siteId, options) {
|
|
403
|
+
return cmsFetch(`/api/public/cms/${siteId}/contact-config/`, {
|
|
404
|
+
revalidate: CACHE.SHORT,
|
|
405
|
+
tags: ["contact-config"],
|
|
406
|
+
...options
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
/**
|
|
410
|
+
* Submit the contact form.
|
|
411
|
+
*
|
|
412
|
+
* Unlike the read methods, this THROWS `CmsError` on a rejection rather than
|
|
413
|
+
* returning null — a form needs to tell "captcha failed, reset the widget"
|
|
414
|
+
* (403) apart from "rate limited" (429) and a network blip, and a single
|
|
415
|
+
* `null` cannot carry that. `error.status` holds the HTTP status.
|
|
416
|
+
*
|
|
417
|
+
* Pass `attachments` to send files; the request then goes out as multipart
|
|
418
|
+
* instead of JSON. Caps are enforced server-side and pre-checked here.
|
|
419
|
+
*/
|
|
420
|
+
async function submitContactForm(siteId, payload, attachments, options) {
|
|
421
|
+
const url = `${baseUrl}/api/public/cms/${siteId}/contact/`;
|
|
422
|
+
if (attachments?.length) {
|
|
423
|
+
if (attachments.length > 3) throw new CmsError(`At most 3 attachments are allowed`, 400, url);
|
|
424
|
+
if (attachments.reduce((sum, f) => sum + f.size, 0) > 3145728) throw new CmsError(`Attachments exceed the ${MAX_CONTACT_ATTACHMENTS_TOTAL_BYTES / 1048576} MiB total size limit`, 400, url);
|
|
425
|
+
for (const f of attachments) if (!CONTACT_ATTACHMENT_MIME_ALLOWLIST.includes(f.type)) throw new CmsError(`Attachment type not allowed: ${f.type || "unknown"}`, 400, url);
|
|
426
|
+
}
|
|
427
|
+
let body;
|
|
428
|
+
const headers = {};
|
|
429
|
+
if (attachments?.length) {
|
|
430
|
+
const form = new FormData();
|
|
431
|
+
for (const [key, value] of Object.entries(payload)) if (value !== void 0 && value !== null) form.append(key, String(value));
|
|
432
|
+
for (const file of attachments) form.append("attachments", file, file.name);
|
|
433
|
+
body = form;
|
|
434
|
+
} else {
|
|
435
|
+
headers["Content-Type"] = "application/json";
|
|
436
|
+
body = JSON.stringify(payload);
|
|
437
|
+
}
|
|
438
|
+
let response;
|
|
439
|
+
try {
|
|
440
|
+
response = await fetch(url, {
|
|
441
|
+
...options,
|
|
442
|
+
method: "POST",
|
|
443
|
+
headers: {
|
|
444
|
+
...headers,
|
|
445
|
+
...options?.headers
|
|
446
|
+
},
|
|
447
|
+
body
|
|
448
|
+
});
|
|
449
|
+
} catch (error) {
|
|
450
|
+
throw new CmsError(error instanceof Error ? error.message : "Network request failed", void 0, url);
|
|
451
|
+
}
|
|
452
|
+
if (!response.ok) {
|
|
453
|
+
let message = `Request failed with status ${response.status}`;
|
|
454
|
+
try {
|
|
455
|
+
const parsed = await response.json();
|
|
456
|
+
if (parsed?.message) message = parsed.message;
|
|
457
|
+
} catch {}
|
|
458
|
+
throw new CmsError(message, response.status, url);
|
|
459
|
+
}
|
|
460
|
+
const result = await response.json();
|
|
461
|
+
return result.data ?? result;
|
|
396
462
|
}
|
|
397
463
|
function fetchFaqs(siteId, params, options) {
|
|
398
464
|
return cmsFetchPaginated(`/api/public/cms/${siteId}/faqs/?${buildQueryString({
|
|
@@ -433,8 +499,9 @@ function createCmsClient(config) {
|
|
|
433
499
|
referrer
|
|
434
500
|
}),
|
|
435
501
|
revalidate: CACHE.NO_CACHE,
|
|
436
|
-
tags: ["redirects", "redirect-404-logs"]
|
|
437
|
-
|
|
502
|
+
tags: ["redirects", "redirect-404-logs"],
|
|
503
|
+
retries: 0
|
|
504
|
+
});
|
|
438
505
|
}
|
|
439
506
|
function fetchStoreSettings(siteId, options) {
|
|
440
507
|
return cmsFetch(`/api/public/store/${siteId}/settings/`, {
|
|
@@ -514,6 +581,7 @@ function createCmsClient(config) {
|
|
|
514
581
|
headers: { "Content-Type": "application/json" },
|
|
515
582
|
body: JSON.stringify(payload),
|
|
516
583
|
revalidate: CACHE.NO_CACHE,
|
|
584
|
+
retries: 0,
|
|
517
585
|
...options
|
|
518
586
|
});
|
|
519
587
|
}
|
|
@@ -549,6 +617,70 @@ function createCmsClient(config) {
|
|
|
549
617
|
...options
|
|
550
618
|
});
|
|
551
619
|
}
|
|
620
|
+
const SITEMAP_ROUTES = {
|
|
621
|
+
blogs: {
|
|
622
|
+
segment: "blogs",
|
|
623
|
+
store: false
|
|
624
|
+
},
|
|
625
|
+
pages: {
|
|
626
|
+
segment: "pages",
|
|
627
|
+
store: false
|
|
628
|
+
},
|
|
629
|
+
services: {
|
|
630
|
+
segment: "services",
|
|
631
|
+
store: false
|
|
632
|
+
},
|
|
633
|
+
events: {
|
|
634
|
+
segment: "events",
|
|
635
|
+
store: false
|
|
636
|
+
},
|
|
637
|
+
albums: {
|
|
638
|
+
segment: "albums",
|
|
639
|
+
store: false
|
|
640
|
+
},
|
|
641
|
+
"team-members": {
|
|
642
|
+
segment: "team-members",
|
|
643
|
+
store: false
|
|
644
|
+
},
|
|
645
|
+
"team-categories": {
|
|
646
|
+
segment: "team-categories",
|
|
647
|
+
store: false
|
|
648
|
+
},
|
|
649
|
+
"brand-groups": {
|
|
650
|
+
segment: "brand-groups",
|
|
651
|
+
store: false
|
|
652
|
+
},
|
|
653
|
+
products: {
|
|
654
|
+
segment: "products",
|
|
655
|
+
store: true
|
|
656
|
+
},
|
|
657
|
+
collections: {
|
|
658
|
+
segment: "collections",
|
|
659
|
+
store: true
|
|
660
|
+
},
|
|
661
|
+
"product-categories": {
|
|
662
|
+
segment: "categories",
|
|
663
|
+
store: true
|
|
664
|
+
},
|
|
665
|
+
"product-brands": {
|
|
666
|
+
segment: "brands",
|
|
667
|
+
store: true
|
|
668
|
+
}
|
|
669
|
+
};
|
|
670
|
+
/**
|
|
671
|
+
* Fetch any sitemap resource. Returns slug/url, title/name, image (where
|
|
672
|
+
* the content type has one) and `updatedAt` for `lastModified`.
|
|
673
|
+
*/
|
|
674
|
+
function fetchSitemap(siteId, resource, params = {}, options) {
|
|
675
|
+
const { segment, store } = SITEMAP_ROUTES[resource];
|
|
676
|
+
const namespace = store ? "store" : "cms";
|
|
677
|
+
const query = buildQueryString(params);
|
|
678
|
+
return cmsFetchPaginated(`/api/public/${namespace}/${siteId}/sitemap/${segment}/${query ? `?${query}` : ""}`, {
|
|
679
|
+
revalidate: CACHE.STATIC,
|
|
680
|
+
tags: ["sitemap", `sitemap-${resource}`],
|
|
681
|
+
...options
|
|
682
|
+
});
|
|
683
|
+
}
|
|
552
684
|
return {
|
|
553
685
|
LIST_DEFAULT_LIMIT,
|
|
554
686
|
fetchHeader,
|
|
@@ -556,6 +688,7 @@ function createCmsClient(config) {
|
|
|
556
688
|
fetchSiteConfig,
|
|
557
689
|
fetchPages,
|
|
558
690
|
fetchPageByUrl,
|
|
691
|
+
fetchPageByType,
|
|
559
692
|
fetchAboutUs,
|
|
560
693
|
fetchServices,
|
|
561
694
|
fetchServiceBySlug,
|
|
@@ -578,6 +711,7 @@ function createCmsClient(config) {
|
|
|
578
711
|
resolveRedirect,
|
|
579
712
|
reportRedirect404,
|
|
580
713
|
submitContactForm,
|
|
714
|
+
fetchContactConfig,
|
|
581
715
|
fetchStoreSettings,
|
|
582
716
|
fetchProductCategories,
|
|
583
717
|
fetchProductBrands,
|
|
@@ -588,6 +722,7 @@ function createCmsClient(config) {
|
|
|
588
722
|
fetchCollectionDetail,
|
|
589
723
|
fetchCollectionDetailById,
|
|
590
724
|
placeOrder,
|
|
725
|
+
fetchSitemap,
|
|
591
726
|
fetchSitemapBlogs,
|
|
592
727
|
fetchSitemapPages,
|
|
593
728
|
fetchSitemapProducts,
|
|
@@ -598,138 +733,128 @@ function createCmsClient(config) {
|
|
|
598
733
|
};
|
|
599
734
|
}
|
|
600
735
|
//#endregion
|
|
601
|
-
//#region src/
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
Brain: lucide_react.Brain,
|
|
711
|
-
Lightbulb: lucide_react.Lightbulb
|
|
712
|
-
};
|
|
713
|
-
/**
|
|
714
|
-
* Dynamic Icon component that renders Lucide icons by name.
|
|
715
|
-
* Useful for CMS-driven icons where names are stored as strings.
|
|
716
|
-
*/
|
|
717
|
-
function Icon({ name, fallback = "HelpCircle", ...props }) {
|
|
718
|
-
const IconComponent = ICON_MAP[name] ?? ICON_MAP[fallback] ?? lucide_react.HelpCircle;
|
|
719
|
-
return react.default.createElement(IconComponent, props);
|
|
720
|
-
}
|
|
736
|
+
//#region src/types/icon.ts
|
|
737
|
+
const ICON_NAMES = [
|
|
738
|
+
"Home",
|
|
739
|
+
"User",
|
|
740
|
+
"Settings",
|
|
741
|
+
"Mail",
|
|
742
|
+
"Bell",
|
|
743
|
+
"Calendar",
|
|
744
|
+
"Star",
|
|
745
|
+
"Heart",
|
|
746
|
+
"Bookmark",
|
|
747
|
+
"Search",
|
|
748
|
+
"Filter",
|
|
749
|
+
"Download",
|
|
750
|
+
"Upload",
|
|
751
|
+
"Trash",
|
|
752
|
+
"Edit",
|
|
753
|
+
"Plus",
|
|
754
|
+
"Minus",
|
|
755
|
+
"Check",
|
|
756
|
+
"X",
|
|
757
|
+
"ChevronRight",
|
|
758
|
+
"ChevronLeft",
|
|
759
|
+
"ChevronUp",
|
|
760
|
+
"ChevronDown",
|
|
761
|
+
"ChevronsUpDown",
|
|
762
|
+
"ArrowRight",
|
|
763
|
+
"ArrowLeft",
|
|
764
|
+
"ArrowUp",
|
|
765
|
+
"ArrowDown",
|
|
766
|
+
"File",
|
|
767
|
+
"Folder",
|
|
768
|
+
"Image",
|
|
769
|
+
"Video",
|
|
770
|
+
"Music",
|
|
771
|
+
"Lock",
|
|
772
|
+
"Unlock",
|
|
773
|
+
"Eye",
|
|
774
|
+
"EyeOff",
|
|
775
|
+
"Sun",
|
|
776
|
+
"Moon",
|
|
777
|
+
"Cloud",
|
|
778
|
+
"Zap",
|
|
779
|
+
"Activity",
|
|
780
|
+
"TrendingUp",
|
|
781
|
+
"TrendingDown",
|
|
782
|
+
"BarChart",
|
|
783
|
+
"PieChart",
|
|
784
|
+
"Database",
|
|
785
|
+
"Server",
|
|
786
|
+
"Wifi",
|
|
787
|
+
"Battery",
|
|
788
|
+
"Camera",
|
|
789
|
+
"Mic",
|
|
790
|
+
"Phone",
|
|
791
|
+
"MessageSquare",
|
|
792
|
+
"Send",
|
|
793
|
+
"Share",
|
|
794
|
+
"Link",
|
|
795
|
+
"ExternalLink",
|
|
796
|
+
"Globe",
|
|
797
|
+
"MapPin",
|
|
798
|
+
"Users",
|
|
799
|
+
"ShoppingCart",
|
|
800
|
+
"CreditCard",
|
|
801
|
+
"Package",
|
|
802
|
+
"Briefcase",
|
|
803
|
+
"Target",
|
|
804
|
+
"Flag",
|
|
805
|
+
"Clipboard",
|
|
806
|
+
"List",
|
|
807
|
+
"Grid",
|
|
808
|
+
"Layout",
|
|
809
|
+
"Layers",
|
|
810
|
+
"Copy",
|
|
811
|
+
"Save",
|
|
812
|
+
"RefreshCw",
|
|
813
|
+
"Maximize",
|
|
814
|
+
"Code",
|
|
815
|
+
"AlertCircle",
|
|
816
|
+
"Info",
|
|
817
|
+
"HelpCircle",
|
|
818
|
+
"CheckCircle",
|
|
819
|
+
"XCircle",
|
|
820
|
+
"Menu",
|
|
821
|
+
"MoreVertical",
|
|
822
|
+
"MoreHorizontal",
|
|
823
|
+
"PlayCircle",
|
|
824
|
+
"PauseCircle",
|
|
825
|
+
"LogIn",
|
|
826
|
+
"LogOut",
|
|
827
|
+
"UserPlus",
|
|
828
|
+
"UserMinus",
|
|
829
|
+
"Tag",
|
|
830
|
+
"Award",
|
|
831
|
+
"Gift",
|
|
832
|
+
"Truck",
|
|
833
|
+
"Clock",
|
|
834
|
+
"Handshake",
|
|
835
|
+
"Stethoscope",
|
|
836
|
+
"Microscope",
|
|
837
|
+
"GraduationCap",
|
|
838
|
+
"BookOpen",
|
|
839
|
+
"Building2",
|
|
840
|
+
"Trees",
|
|
841
|
+
"HeartHandshake",
|
|
842
|
+
"Brain",
|
|
843
|
+
"Lightbulb"
|
|
844
|
+
];
|
|
721
845
|
//#endregion
|
|
722
846
|
exports.ANIMATION = ANIMATION;
|
|
723
847
|
exports.CACHE = CACHE;
|
|
848
|
+
exports.CONTACT_ATTACHMENT_MIME_ALLOWLIST = CONTACT_ATTACHMENT_MIME_ALLOWLIST;
|
|
724
849
|
exports.CONTACT_SUBJECTS = CONTACT_SUBJECTS;
|
|
725
850
|
exports.CmsError = CmsError;
|
|
726
851
|
exports.HTTP_STATUS = HTTP_STATUS;
|
|
727
|
-
exports.
|
|
728
|
-
exports.
|
|
852
|
+
exports.ICON_NAMES = ICON_NAMES;
|
|
853
|
+
exports.MAX_CONTACT_ATTACHMENTS = MAX_CONTACT_ATTACHMENTS;
|
|
854
|
+
exports.MAX_CONTACT_ATTACHMENTS_TOTAL_BYTES = MAX_CONTACT_ATTACHMENTS_TOTAL_BYTES;
|
|
729
855
|
exports.MEDIA = MEDIA;
|
|
730
856
|
exports.PAGINATION = PAGINATION;
|
|
731
857
|
exports.SEARCH = SEARCH;
|
|
732
858
|
exports.allPageTypes = allPageTypes;
|
|
733
859
|
exports.createCmsClient = createCmsClient;
|
|
734
|
-
exports.defaultPageTypes = defaultPageTypes;
|
|
735
860
|
exports.pageTypes = pageTypes;
|