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