@deepsel/cms-utils 1.1.3 → 1.1.6
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/dist/blog/fetchBlogList.d.ts +15 -0
- package/dist/blog/fetchBlogList.js +51 -0
- package/dist/blog/fetchBlogPost.d.ts +14 -0
- package/dist/blog/fetchBlogPost.js +61 -0
- package/dist/blog/index.d.ts +3 -0
- package/dist/blog/index.js +3 -0
- package/dist/blog/types.d.ts +45 -0
- package/dist/blog/types.js +1 -0
- package/dist/common/utils/cookieUtils.d.ts +12 -0
- package/dist/common/utils/cookieUtils.js +39 -0
- package/dist/common/utils/index.d.ts +48 -0
- package/dist/common/utils/index.js +95 -0
- package/dist/common/utils/isObjectOrArray.d.ts +4 -0
- package/dist/common/utils/isObjectOrArray.js +7 -0
- package/dist/constants/index.d.ts +2 -0
- package/dist/constants/index.js +2 -0
- package/dist/constants/pagingTableParams.d.ts +8 -0
- package/dist/constants/pagingTableParams.js +8 -0
- package/dist/constants/websiteDataTypes.d.ts +7 -0
- package/dist/constants/websiteDataTypes.js +6 -0
- package/dist/index.d.ts +6 -4
- package/dist/index.js +6 -4
- package/dist/menus/index.d.ts +2 -2
- package/dist/menus/index.js +2 -2
- package/dist/menus/isActiveMenu.d.ts +3 -3
- package/dist/menus/isActiveMenu.js +2 -2
- package/dist/page/fetchPageData.d.ts +10 -2
- package/dist/page/fetchPageData.js +23 -23
- package/dist/page/fetchPublicSettings.d.ts +1 -1
- package/dist/page/fetchSearchResults.d.ts +31 -0
- package/dist/page/fetchSearchResults.js +73 -0
- package/dist/page/getPathType.d.ts +9 -0
- package/dist/page/getPathType.js +46 -0
- package/dist/page/index.d.ts +7 -6
- package/dist/page/index.js +7 -6
- package/dist/page/isCrossingTemplateBoundary.d.ts +1 -0
- package/dist/page/isCrossingTemplateBoundary.js +6 -0
- package/dist/page/parseSlug.d.ts +12 -0
- package/dist/page/{parseSlugForLangAndPath.js → parseSlug.js} +8 -6
- package/dist/page/types.d.ts +4 -32
- package/dist/types.d.ts +8 -0
- package/package.json +9 -64
- package/dist/language/index.d.ts +0 -1
- package/dist/language/index.js +0 -1
- package/dist/page/constants.d.ts +0 -0
- package/dist/page/constants.js +0 -1
- package/dist/page/fetchFormData.d.ts +0 -4
- package/dist/page/fetchFormData.js +0 -38
- package/dist/page/parseSlugForLangAndPath.d.ts +0 -5
- /package/dist/{language → page}/isValidLanguageCode.d.ts +0 -0
- /package/dist/{language → page}/isValidLanguageCode.js +0 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { BlogListData } from './types.js';
|
|
2
|
+
import type { Pagination } from '../page/getPathType.js';
|
|
3
|
+
interface FetchBlogListProps {
|
|
4
|
+
lang?: string;
|
|
5
|
+
pagination?: Pagination;
|
|
6
|
+
astroRequest?: Request;
|
|
7
|
+
authToken?: string;
|
|
8
|
+
backendHost?: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Fetches blog list from the backend by language
|
|
12
|
+
* Corresponds to GET /blog_post/website/{lang}
|
|
13
|
+
*/
|
|
14
|
+
export declare function fetchBlogList({ astroRequest, pagination, authToken, lang, backendHost, }: FetchBlogListProps): Promise<BlogListData>;
|
|
15
|
+
export {};
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fetches blog list from the backend by language
|
|
3
|
+
* Corresponds to GET /blog_post/website/{lang}
|
|
4
|
+
*/
|
|
5
|
+
export async function fetchBlogList({ astroRequest, pagination, authToken, lang = 'default', backendHost = 'http://localhost:8000/api/v1', }) {
|
|
6
|
+
try {
|
|
7
|
+
let url = `${backendHost}/blog_post/list/${lang}`;
|
|
8
|
+
if (pagination) {
|
|
9
|
+
const searchParams = new URLSearchParams();
|
|
10
|
+
if (pagination.page)
|
|
11
|
+
searchParams.append('page', pagination.page.toString());
|
|
12
|
+
if (pagination.pageSize)
|
|
13
|
+
searchParams.append('page_size', pagination.pageSize.toString());
|
|
14
|
+
url += `?${searchParams.toString()}`;
|
|
15
|
+
}
|
|
16
|
+
const fetchOptions = {
|
|
17
|
+
method: 'GET',
|
|
18
|
+
headers: {
|
|
19
|
+
'Content-Type': 'application/json',
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
let hostname = null;
|
|
23
|
+
if (astroRequest) {
|
|
24
|
+
const url = new URL(astroRequest.url);
|
|
25
|
+
hostname = url.hostname;
|
|
26
|
+
}
|
|
27
|
+
else if (typeof window !== 'undefined') {
|
|
28
|
+
hostname = window.location.hostname;
|
|
29
|
+
}
|
|
30
|
+
if (hostname) {
|
|
31
|
+
fetchOptions.headers['X-Original-Host'] = hostname;
|
|
32
|
+
fetchOptions.headers['X-Frontend-Host'] = hostname;
|
|
33
|
+
}
|
|
34
|
+
if (authToken) {
|
|
35
|
+
fetchOptions.headers['Authorization'] = `Bearer ${authToken}`;
|
|
36
|
+
}
|
|
37
|
+
const response = await fetch(url, fetchOptions);
|
|
38
|
+
if (response.status === 401) {
|
|
39
|
+
throw new Error('Authentication required');
|
|
40
|
+
}
|
|
41
|
+
if (!response.ok) {
|
|
42
|
+
throw new Error(`Failed to fetch blog list: ${response.statusText}`);
|
|
43
|
+
}
|
|
44
|
+
const jsonData = await response.json();
|
|
45
|
+
return jsonData;
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
console.error('Error fetching blog list:', error);
|
|
49
|
+
throw error;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { BlogPostData } from './types.js';
|
|
2
|
+
interface FetchBlogPostProps {
|
|
3
|
+
path: string;
|
|
4
|
+
lang?: string;
|
|
5
|
+
astroRequest?: Request;
|
|
6
|
+
authToken?: string;
|
|
7
|
+
backendHost?: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Fetches a single blog post from the backend by language and path
|
|
11
|
+
* Corresponds to GET /blog_post/website/{lang}/{path}
|
|
12
|
+
*/
|
|
13
|
+
export declare function fetchBlogPost({ path, lang, astroRequest, authToken, backendHost, }: FetchBlogPostProps): Promise<BlogPostData>;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { fetchPublicSettings } from '../page/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Fetches a single blog post from the backend by language and path
|
|
4
|
+
* Corresponds to GET /blog_post/website/{lang}/{path}
|
|
5
|
+
*/
|
|
6
|
+
export async function fetchBlogPost({ path, lang = 'default', astroRequest, authToken, backendHost = 'http://localhost:8000/api/v1', }) {
|
|
7
|
+
try {
|
|
8
|
+
const cleanPath = path.startsWith('/') ? path.substring(1) : path;
|
|
9
|
+
let postSlug = cleanPath;
|
|
10
|
+
// rm the blog/ prefix
|
|
11
|
+
if (cleanPath.startsWith('blog/')) {
|
|
12
|
+
postSlug = cleanPath.substring('blog/'.length);
|
|
13
|
+
}
|
|
14
|
+
const url = `${backendHost}/blog_post/single/${lang}/${postSlug}`;
|
|
15
|
+
const fetchOptions = {
|
|
16
|
+
method: 'GET',
|
|
17
|
+
headers: {
|
|
18
|
+
'Content-Type': 'application/json',
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
let hostname = null;
|
|
22
|
+
if (astroRequest) {
|
|
23
|
+
const url = new URL(astroRequest.url);
|
|
24
|
+
hostname = url.hostname;
|
|
25
|
+
}
|
|
26
|
+
else if (typeof window !== 'undefined') {
|
|
27
|
+
hostname = window.location.hostname;
|
|
28
|
+
}
|
|
29
|
+
if (hostname) {
|
|
30
|
+
fetchOptions.headers['X-Original-Host'] = hostname;
|
|
31
|
+
fetchOptions.headers['X-Frontend-Host'] = hostname;
|
|
32
|
+
}
|
|
33
|
+
if (authToken) {
|
|
34
|
+
fetchOptions.headers['Authorization'] = `Bearer ${authToken}`;
|
|
35
|
+
}
|
|
36
|
+
const response = await fetch(url, fetchOptions);
|
|
37
|
+
if (response.status === 401) {
|
|
38
|
+
throw new Error('Authentication required');
|
|
39
|
+
}
|
|
40
|
+
if (response.status === 404) {
|
|
41
|
+
try {
|
|
42
|
+
const { detail } = (await response.json());
|
|
43
|
+
console.warn('404', url, { detail });
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
console.warn('404', url);
|
|
47
|
+
}
|
|
48
|
+
const siteSettings = await fetchPublicSettings(null, astroRequest, lang, backendHost);
|
|
49
|
+
return {
|
|
50
|
+
notFound: true,
|
|
51
|
+
public_settings: siteSettings,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
const jsonData = await response.json();
|
|
55
|
+
return jsonData;
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
console.error('Error fetching blog post:', error);
|
|
59
|
+
throw error;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { SiteSettings } from '../types.js';
|
|
2
|
+
import type { SeoMetadata, LanguageAlternative } from '../page/types.js';
|
|
3
|
+
export interface BlogPostAuthor {
|
|
4
|
+
id: number;
|
|
5
|
+
display_name?: string;
|
|
6
|
+
username: string;
|
|
7
|
+
image?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface BlogPostListItem {
|
|
10
|
+
id: number;
|
|
11
|
+
title: string;
|
|
12
|
+
slug: string;
|
|
13
|
+
excerpt?: string;
|
|
14
|
+
featured_image_id?: number;
|
|
15
|
+
featured_image_name?: string;
|
|
16
|
+
publish_date?: string;
|
|
17
|
+
author?: BlogPostAuthor;
|
|
18
|
+
lang: string;
|
|
19
|
+
}
|
|
20
|
+
export interface BlogListData {
|
|
21
|
+
lang: string;
|
|
22
|
+
public_settings: SiteSettings;
|
|
23
|
+
blog_posts: BlogPostListItem[];
|
|
24
|
+
page: number;
|
|
25
|
+
page_size: number;
|
|
26
|
+
total_count: number;
|
|
27
|
+
total_pages: number;
|
|
28
|
+
}
|
|
29
|
+
export interface BlogPostData {
|
|
30
|
+
id?: number;
|
|
31
|
+
title?: string;
|
|
32
|
+
content?: string;
|
|
33
|
+
lang?: string;
|
|
34
|
+
public_settings: SiteSettings;
|
|
35
|
+
seo_metadata?: SeoMetadata;
|
|
36
|
+
custom_code?: string | null;
|
|
37
|
+
page_custom_code?: string | null;
|
|
38
|
+
require_login?: boolean | null;
|
|
39
|
+
featured_image_id?: number | null;
|
|
40
|
+
featured_image_name?: string | null;
|
|
41
|
+
publish_date?: string | null;
|
|
42
|
+
author?: BlogPostAuthor | null;
|
|
43
|
+
language_alternatives?: LanguageAlternative[];
|
|
44
|
+
notFound?: boolean;
|
|
45
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sets a cookie with the given name, value, and expiration days
|
|
3
|
+
*/
|
|
4
|
+
export declare function setCookie(name: string, value: string, days?: number): void;
|
|
5
|
+
/**
|
|
6
|
+
* Gets a cookie value by name
|
|
7
|
+
*/
|
|
8
|
+
export declare function getCookie(name: string): string | null;
|
|
9
|
+
/**
|
|
10
|
+
* Removes a cookie by name
|
|
11
|
+
*/
|
|
12
|
+
export declare function removeCookie(name: string): void;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cookie expiration in days when not specified
|
|
3
|
+
*/
|
|
4
|
+
const COOKIE_DEFAULT_EXPIRY_DAYS = 30;
|
|
5
|
+
/**
|
|
6
|
+
* Sets a cookie with the given name, value, and expiration days
|
|
7
|
+
*/
|
|
8
|
+
export function setCookie(name, value, days = COOKIE_DEFAULT_EXPIRY_DAYS) {
|
|
9
|
+
if (typeof document !== 'undefined') {
|
|
10
|
+
const expiryDate = new Date();
|
|
11
|
+
expiryDate.setDate(expiryDate.getDate() + days);
|
|
12
|
+
document.cookie = `${name}=${value}; expires=${expiryDate.toUTCString()}; path=/; SameSite=Lax`;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Gets a cookie value by name
|
|
17
|
+
*/
|
|
18
|
+
export function getCookie(name) {
|
|
19
|
+
if (typeof document !== 'undefined') {
|
|
20
|
+
const nameEQ = name + '=';
|
|
21
|
+
const ca = document.cookie.split(';');
|
|
22
|
+
for (let i = 0; i < ca.length; i++) {
|
|
23
|
+
let c = ca[i];
|
|
24
|
+
while (c.charAt(0) === ' ')
|
|
25
|
+
c = c.substring(1, c.length);
|
|
26
|
+
if (c.indexOf(nameEQ) === 0)
|
|
27
|
+
return c.substring(nameEQ.length, c.length);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Removes a cookie by name
|
|
34
|
+
*/
|
|
35
|
+
export function removeCookie(name) {
|
|
36
|
+
if (typeof document !== 'undefined') {
|
|
37
|
+
document.cookie = `${name}=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;`;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
export * from './cookieUtils.js';
|
|
2
|
+
export * from './isObjectOrArray.js';
|
|
3
|
+
/**
|
|
4
|
+
* Builds the full URL for an attachment file
|
|
5
|
+
* @param backendHost - The backend host URL (e.g. "https://api.example.com")
|
|
6
|
+
* @param name - The attachment filename
|
|
7
|
+
* @returns Full URL to serve the attachment, or empty string if name is falsy
|
|
8
|
+
*/
|
|
9
|
+
export declare function getAttachmentUrl(backendHost: string, name: string): string;
|
|
10
|
+
/**
|
|
11
|
+
* Builds the relative URL for an attachment file (no host)
|
|
12
|
+
* @param name - The attachment filename
|
|
13
|
+
* @returns Relative URL to serve the attachment, or empty string if name is falsy
|
|
14
|
+
*/
|
|
15
|
+
export declare function getAttachmentRelativeUrl(name: string): string;
|
|
16
|
+
/**
|
|
17
|
+
* Extracts the filename from an attachment serve URL
|
|
18
|
+
* @param url - The attachment URL (e.g. "https://api.example.com/attachment/serve/file.png")
|
|
19
|
+
* @returns The filename portion of the URL, or empty string if url is falsy
|
|
20
|
+
*/
|
|
21
|
+
export declare function getFileNameFromAttachUrl(url: string): string;
|
|
22
|
+
/**
|
|
23
|
+
* Triggers a browser download for a file from an attachment URL
|
|
24
|
+
* @param url - The attachment URL to download from
|
|
25
|
+
*/
|
|
26
|
+
export declare function downloadFromAttachUrl(url: string): void;
|
|
27
|
+
/**
|
|
28
|
+
* Converts a string to a deterministic hex color via a simple hash
|
|
29
|
+
*/
|
|
30
|
+
export declare function stringToColor(string: string): string;
|
|
31
|
+
/**
|
|
32
|
+
* Returns a background color and initials string derived from a display name.
|
|
33
|
+
* Suitable for use in avatar components.
|
|
34
|
+
*/
|
|
35
|
+
export declare function stringAvatar(name: string): {
|
|
36
|
+
color: string;
|
|
37
|
+
children: string;
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Extracts the file extension from a filename or URL
|
|
41
|
+
* @param fileName - The filename or path (e.g. "photo.jpg", "/path/to/file.pdf")
|
|
42
|
+
* @returns The extension without the dot (e.g. "jpg"), or empty string if none
|
|
43
|
+
*/
|
|
44
|
+
export declare function getFileExtension(fileName: string): string;
|
|
45
|
+
/**
|
|
46
|
+
* Format file size in human-readable format
|
|
47
|
+
*/
|
|
48
|
+
export declare const formatFileSize: (bytes: number) => string;
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
export * from './cookieUtils.js';
|
|
2
|
+
export * from './isObjectOrArray.js';
|
|
3
|
+
/**
|
|
4
|
+
* Builds the full URL for an attachment file
|
|
5
|
+
* @param backendHost - The backend host URL (e.g. "https://api.example.com")
|
|
6
|
+
* @param name - The attachment filename
|
|
7
|
+
* @returns Full URL to serve the attachment, or empty string if name is falsy
|
|
8
|
+
*/
|
|
9
|
+
export function getAttachmentUrl(backendHost, name) {
|
|
10
|
+
return name ? `${backendHost}/attachment/serve/${name}` : '';
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Builds the relative URL for an attachment file (no host)
|
|
14
|
+
* @param name - The attachment filename
|
|
15
|
+
* @returns Relative URL to serve the attachment, or empty string if name is falsy
|
|
16
|
+
*/
|
|
17
|
+
export function getAttachmentRelativeUrl(name) {
|
|
18
|
+
return name ? `/attachment/serve/${name}` : '';
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Extracts the filename from an attachment serve URL
|
|
22
|
+
* @param url - The attachment URL (e.g. "https://api.example.com/attachment/serve/file.png")
|
|
23
|
+
* @returns The filename portion of the URL, or empty string if url is falsy
|
|
24
|
+
*/
|
|
25
|
+
export function getFileNameFromAttachUrl(url) {
|
|
26
|
+
return url?.substring(url.lastIndexOf('/') + 1) || '';
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Triggers a browser download for a file from an attachment URL
|
|
30
|
+
* @param url - The attachment URL to download from
|
|
31
|
+
*/
|
|
32
|
+
export function downloadFromAttachUrl(url) {
|
|
33
|
+
const downloadUrl = url.includes('?') ? `${url}&download=true` : `${url}?download=true`;
|
|
34
|
+
fetch(downloadUrl)
|
|
35
|
+
.then((response) => response.blob())
|
|
36
|
+
.then((blob) => {
|
|
37
|
+
const objectUrl = URL.createObjectURL(blob);
|
|
38
|
+
const link = document.createElement('a');
|
|
39
|
+
link.href = objectUrl;
|
|
40
|
+
link.setAttribute('download', getFileNameFromAttachUrl(url));
|
|
41
|
+
document.body.appendChild(link);
|
|
42
|
+
link.click();
|
|
43
|
+
document.body.removeChild(link);
|
|
44
|
+
URL.revokeObjectURL(objectUrl);
|
|
45
|
+
})
|
|
46
|
+
.catch((error) => {
|
|
47
|
+
console.error('Error downloading the file:', error);
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Converts a string to a deterministic hex color via a simple hash
|
|
52
|
+
*/
|
|
53
|
+
export function stringToColor(string) {
|
|
54
|
+
let hash = 0;
|
|
55
|
+
for (let i = 0; i < string.length; i++) {
|
|
56
|
+
hash = string.charCodeAt(i) + ((hash << 5) - hash);
|
|
57
|
+
}
|
|
58
|
+
let color = '#';
|
|
59
|
+
for (let i = 0; i < 3; i++) {
|
|
60
|
+
const value = (hash >> (i * 8)) & 0xff;
|
|
61
|
+
color += `00${value.toString(16)}`.slice(-2);
|
|
62
|
+
}
|
|
63
|
+
return color;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Returns a background color and initials string derived from a display name.
|
|
67
|
+
* Suitable for use in avatar components.
|
|
68
|
+
*/
|
|
69
|
+
export function stringAvatar(name) {
|
|
70
|
+
const children = name.includes(' ')
|
|
71
|
+
? `${name.split(' ')[0][0]}${name.split(' ')[1][0]}`
|
|
72
|
+
: (name[0] ?? '');
|
|
73
|
+
return {
|
|
74
|
+
color: stringToColor(name),
|
|
75
|
+
children,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Extracts the file extension from a filename or URL
|
|
80
|
+
* @param fileName - The filename or path (e.g. "photo.jpg", "/path/to/file.pdf")
|
|
81
|
+
* @returns The extension without the dot (e.g. "jpg"), or empty string if none
|
|
82
|
+
*/
|
|
83
|
+
export function getFileExtension(fileName) {
|
|
84
|
+
return fileName?.split('.').pop() ?? '';
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Format file size in human-readable format
|
|
88
|
+
*/
|
|
89
|
+
export const formatFileSize = (bytes) => {
|
|
90
|
+
if (!bytes)
|
|
91
|
+
return '';
|
|
92
|
+
const sizes = ['Bytes', 'KB', 'MB', 'GB'];
|
|
93
|
+
const i = Math.floor(Math.log(bytes) / Math.log(1024));
|
|
94
|
+
return Math.round((bytes / Math.pow(1024, i)) * 100) / 100 + ' ' + sizes[i];
|
|
95
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare const WebsiteDataTypes: {
|
|
2
|
+
readonly Page: "Page";
|
|
3
|
+
readonly BlogList: "BlogList";
|
|
4
|
+
readonly BlogPost: "BlogPost";
|
|
5
|
+
readonly SearchResults: "SearchResults";
|
|
6
|
+
};
|
|
7
|
+
export type WebsiteDataType = (typeof WebsiteDataTypes)[keyof typeof WebsiteDataTypes];
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
export * from './
|
|
2
|
-
export * from './
|
|
3
|
-
export * from './
|
|
4
|
-
export * from './
|
|
1
|
+
export * from './blog/index.js';
|
|
2
|
+
export * from './common/utils/index.js';
|
|
3
|
+
export * from './constants/index.js';
|
|
4
|
+
export * from './menus/index.js';
|
|
5
|
+
export * from './page/index.js';
|
|
6
|
+
export * from './types.js';
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
export * from './
|
|
2
|
-
export * from './
|
|
3
|
-
export * from './
|
|
4
|
-
export * from './
|
|
1
|
+
export * from './blog/index.js';
|
|
2
|
+
export * from './common/utils/index.js';
|
|
3
|
+
export * from './constants/index.js';
|
|
4
|
+
export * from './menus/index.js';
|
|
5
|
+
export * from './page/index.js';
|
|
6
|
+
export * from './types.js';
|
package/dist/menus/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export * from './isActiveMenu';
|
|
2
|
-
export * from './types';
|
|
1
|
+
export * from './isActiveMenu.js';
|
|
2
|
+
export * from './types.js';
|
package/dist/menus/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export * from './isActiveMenu';
|
|
2
|
-
export * from './types';
|
|
1
|
+
export * from './isActiveMenu.js';
|
|
2
|
+
export * from './types.js';
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import type { MenuItem } from './types';
|
|
2
|
-
import type {
|
|
3
|
-
export declare const isActiveMenu: (menuItem: MenuItem,
|
|
1
|
+
import type { MenuItem } from './types.js';
|
|
2
|
+
import type { WebsiteData } from '../types.js';
|
|
3
|
+
export declare const isActiveMenu: (menuItem: MenuItem, websiteData: WebsiteData) => boolean;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
// Check if a menu item should be marked as active
|
|
2
|
-
export const isActiveMenu = (menuItem,
|
|
2
|
+
export const isActiveMenu = (menuItem, websiteData) => {
|
|
3
3
|
// return if not browser
|
|
4
4
|
if (typeof window === 'undefined') {
|
|
5
5
|
return false;
|
|
6
6
|
}
|
|
7
7
|
const location = window.location;
|
|
8
|
-
const currentLang =
|
|
8
|
+
const currentLang = websiteData.data.lang;
|
|
9
9
|
let result;
|
|
10
10
|
if (menuItem.url === '/') {
|
|
11
11
|
result =
|
|
@@ -1,5 +1,13 @@
|
|
|
1
|
-
import type { PageData } from './types';
|
|
1
|
+
import type { PageData } from './types.js';
|
|
2
|
+
interface FetchPageDataProps {
|
|
3
|
+
path: string;
|
|
4
|
+
lang?: string;
|
|
5
|
+
astroRequest?: Request;
|
|
6
|
+
authToken?: string;
|
|
7
|
+
backendHost?: string;
|
|
8
|
+
}
|
|
2
9
|
/**
|
|
3
10
|
* Fetches page data from the backend by language and slug
|
|
4
11
|
*/
|
|
5
|
-
export declare function fetchPageData(
|
|
12
|
+
export declare function fetchPageData({ path, lang, astroRequest, authToken, backendHost, }: FetchPageDataProps): Promise<PageData>;
|
|
13
|
+
export {};
|
|
@@ -1,26 +1,24 @@
|
|
|
1
|
-
import { fetchPublicSettings } from './fetchPublicSettings';
|
|
1
|
+
import { fetchPublicSettings } from './fetchPublicSettings.js';
|
|
2
2
|
/**
|
|
3
3
|
* Fetches page data from the backend by language and slug
|
|
4
4
|
*/
|
|
5
|
-
export async function fetchPageData(
|
|
5
|
+
export async function fetchPageData({ path, lang, astroRequest, authToken, backendHost = 'http://localhost:8000/api/v1', }) {
|
|
6
6
|
try {
|
|
7
|
-
// Format the
|
|
8
|
-
let
|
|
7
|
+
// Format the path properly, make sure it starts with a slash
|
|
8
|
+
let formattedPath = path.startsWith('/') ? path : `/${path}`;
|
|
9
9
|
// Backend will consider 'default' as the home slug
|
|
10
|
-
if (
|
|
11
|
-
|
|
10
|
+
if (formattedPath === '/') {
|
|
11
|
+
formattedPath = '/default';
|
|
12
12
|
}
|
|
13
13
|
// Determine the URL based on whether a language is provided
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
url = `${backendHost}/page/website/${lang}${formattedSlug}`;
|
|
17
|
-
}
|
|
18
|
-
else {
|
|
19
|
-
url = `${backendHost}/page/website/default${formattedSlug}`;
|
|
20
|
-
}
|
|
14
|
+
const langPrefix = lang || 'default';
|
|
15
|
+
let url = `${backendHost}/page/website/${langPrefix}${formattedPath}`;
|
|
21
16
|
// Add preview parameter if enabled
|
|
22
|
-
if (
|
|
23
|
-
|
|
17
|
+
if (astroRequest) {
|
|
18
|
+
const previewParam = new URL(astroRequest.url).searchParams.get('preview');
|
|
19
|
+
if (previewParam === 'true') {
|
|
20
|
+
url += `?preview=true`;
|
|
21
|
+
}
|
|
24
22
|
}
|
|
25
23
|
// Prepare fetch options
|
|
26
24
|
const fetchOptions = {
|
|
@@ -33,8 +31,8 @@ export async function fetchPageData(lang, slug, isPreview = false, authToken = n
|
|
|
33
31
|
let hostname = null;
|
|
34
32
|
// Server-side: Extract hostname from Astro request
|
|
35
33
|
if (astroRequest) {
|
|
36
|
-
const
|
|
37
|
-
hostname =
|
|
34
|
+
const requestUrl = new URL(astroRequest.url);
|
|
35
|
+
hostname = requestUrl.hostname;
|
|
38
36
|
}
|
|
39
37
|
// Client-side: Extract hostname from window
|
|
40
38
|
else if (typeof window !== 'undefined') {
|
|
@@ -57,22 +55,24 @@ export async function fetchPageData(lang, slug, isPreview = false, authToken = n
|
|
|
57
55
|
}
|
|
58
56
|
// Only treat actual 404 as not found
|
|
59
57
|
if (response.status === 404) {
|
|
60
|
-
|
|
61
|
-
|
|
58
|
+
try {
|
|
59
|
+
const { detail } = await response.json();
|
|
60
|
+
console.warn('404', url, { detail });
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
console.warn('404', url);
|
|
64
|
+
}
|
|
62
65
|
// When page is not found, still fetch menus and site settings
|
|
63
66
|
try {
|
|
64
67
|
const siteSettings = await fetchPublicSettings(null, astroRequest, lang, backendHost);
|
|
65
68
|
return {
|
|
66
69
|
notFound: true,
|
|
67
|
-
status: 404,
|
|
68
|
-
detail,
|
|
69
70
|
public_settings: siteSettings,
|
|
70
|
-
lang: lang || siteSettings.default_language?.iso_code || 'en',
|
|
71
71
|
};
|
|
72
72
|
}
|
|
73
73
|
catch (settingsError) {
|
|
74
74
|
console.warn('Could not fetch site settings for 404 page:', settingsError);
|
|
75
|
-
throw new Error(`Page not found
|
|
75
|
+
throw new Error(`Page not found`);
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
78
|
try {
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { SiteSettings } from '../types.js';
|
|
2
|
+
export interface SearchResultItem {
|
|
3
|
+
id: string;
|
|
4
|
+
title: string;
|
|
5
|
+
url: string;
|
|
6
|
+
publishDate: string | null;
|
|
7
|
+
contentType: string;
|
|
8
|
+
relevanceScore: number;
|
|
9
|
+
}
|
|
10
|
+
export interface SearchResultsData {
|
|
11
|
+
lang: string;
|
|
12
|
+
query: string;
|
|
13
|
+
public_settings: SiteSettings;
|
|
14
|
+
results: SearchResultItem[];
|
|
15
|
+
total: number;
|
|
16
|
+
suggestions: string[];
|
|
17
|
+
}
|
|
18
|
+
interface FetchSearchResultsProps {
|
|
19
|
+
lang?: string;
|
|
20
|
+
q: string;
|
|
21
|
+
limit?: number;
|
|
22
|
+
astroRequest?: Request;
|
|
23
|
+
authToken?: string;
|
|
24
|
+
backendHost?: string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Fetches search results from the backend.
|
|
28
|
+
* Calls GET /api/v1/page/website_search/{lang}?q=...&limit=...
|
|
29
|
+
*/
|
|
30
|
+
export declare function fetchSearchResults({ lang, q, limit, astroRequest, authToken, backendHost, }: FetchSearchResultsProps): Promise<SearchResultsData>;
|
|
31
|
+
export {};
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { fetchPublicSettings } from './fetchPublicSettings.js';
|
|
2
|
+
/**
|
|
3
|
+
* Fetches search results from the backend.
|
|
4
|
+
* Calls GET /api/v1/page/website_search/{lang}?q=...&limit=...
|
|
5
|
+
*/
|
|
6
|
+
export async function fetchSearchResults({ lang = 'default', q, limit = 100, astroRequest, authToken, backendHost = 'http://localhost:8000/api/v1', }) {
|
|
7
|
+
// Build hostname for headers
|
|
8
|
+
let hostname = null;
|
|
9
|
+
if (astroRequest) {
|
|
10
|
+
const requestUrl = new URL(astroRequest.url);
|
|
11
|
+
hostname = requestUrl.hostname;
|
|
12
|
+
}
|
|
13
|
+
else if (typeof window !== 'undefined') {
|
|
14
|
+
hostname = window.location.hostname;
|
|
15
|
+
}
|
|
16
|
+
const headers = {
|
|
17
|
+
'Content-Type': 'application/json',
|
|
18
|
+
};
|
|
19
|
+
if (hostname) {
|
|
20
|
+
headers['X-Original-Host'] = hostname;
|
|
21
|
+
headers['X-Frontend-Host'] = hostname;
|
|
22
|
+
}
|
|
23
|
+
if (authToken) {
|
|
24
|
+
headers['Authorization'] = `Bearer ${authToken}`;
|
|
25
|
+
}
|
|
26
|
+
// Always fetch public_settings alongside the search call
|
|
27
|
+
const settingsPromise = fetchPublicSettings(null, astroRequest ?? null, lang, `http://localhost:8000`);
|
|
28
|
+
// If no query, skip the search call and return empty results
|
|
29
|
+
if (!q.trim()) {
|
|
30
|
+
const public_settings = await settingsPromise;
|
|
31
|
+
// Normalize lang: replace 'default' with the actual ISO code from settings
|
|
32
|
+
const resolvedLang = lang === 'default' ? public_settings.default_language?.iso_code || lang : lang;
|
|
33
|
+
return {
|
|
34
|
+
lang: resolvedLang,
|
|
35
|
+
query: q,
|
|
36
|
+
public_settings,
|
|
37
|
+
results: [],
|
|
38
|
+
total: 0,
|
|
39
|
+
suggestions: [],
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
const searchParams = new URLSearchParams({ q, limit: String(limit) });
|
|
43
|
+
const searchUrl = `${backendHost}/page/website_search/${lang}?${searchParams.toString()}`;
|
|
44
|
+
const [public_settings, searchResponse] = await Promise.allSettled([
|
|
45
|
+
settingsPromise,
|
|
46
|
+
fetch(searchUrl, { method: 'GET', headers }),
|
|
47
|
+
]);
|
|
48
|
+
const resolvedSettings = public_settings.status === 'fulfilled' ? public_settings.value : {};
|
|
49
|
+
// Normalize lang: replace 'default' with the actual ISO code from settings
|
|
50
|
+
const resolvedLang = lang === 'default' ? resolvedSettings.default_language?.iso_code || lang : lang;
|
|
51
|
+
if (searchResponse.status === 'rejected' || !searchResponse.value.ok) {
|
|
52
|
+
console.error('Error fetching search results:', searchResponse.status === 'rejected'
|
|
53
|
+
? searchResponse.reason
|
|
54
|
+
: searchResponse.value.statusText);
|
|
55
|
+
return {
|
|
56
|
+
lang: resolvedLang,
|
|
57
|
+
query: q,
|
|
58
|
+
public_settings: resolvedSettings,
|
|
59
|
+
results: [],
|
|
60
|
+
total: 0,
|
|
61
|
+
suggestions: [],
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
const apiData = await searchResponse.value.json();
|
|
65
|
+
return {
|
|
66
|
+
lang: resolvedLang,
|
|
67
|
+
query: q,
|
|
68
|
+
public_settings: resolvedSettings,
|
|
69
|
+
results: apiData.results ?? [],
|
|
70
|
+
total: apiData.total ?? 0,
|
|
71
|
+
suggestions: apiData.suggestions ?? [],
|
|
72
|
+
};
|
|
73
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { WebsiteDataTypes } from '../constants/index.js';
|
|
2
|
+
export function getPathType(path) {
|
|
3
|
+
let pathType = WebsiteDataTypes.Page;
|
|
4
|
+
let pagination = undefined;
|
|
5
|
+
// delete forward at the beginning
|
|
6
|
+
if (path.startsWith('/')) {
|
|
7
|
+
path = path.slice(1);
|
|
8
|
+
}
|
|
9
|
+
if (path === 'search' || path.startsWith('search?') || path.startsWith('search/')) {
|
|
10
|
+
return { pathType: WebsiteDataTypes.SearchResults };
|
|
11
|
+
}
|
|
12
|
+
if (path.startsWith('blog')) {
|
|
13
|
+
// split
|
|
14
|
+
const parts = path.split('/');
|
|
15
|
+
let pageSize = undefined;
|
|
16
|
+
// extract query parameters if any
|
|
17
|
+
const queryString = path.split('?')[1];
|
|
18
|
+
if (queryString) {
|
|
19
|
+
const params = new URLSearchParams(queryString);
|
|
20
|
+
const size = params.get('pageSize');
|
|
21
|
+
if (size && !isNaN(Number(size))) {
|
|
22
|
+
pageSize = Number(size);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
// check which blog list format, either /blog, /blog/page/2, or /blog/{slug}
|
|
26
|
+
if (parts.length > 1 && parts[1] !== '') {
|
|
27
|
+
// /blog/page/2
|
|
28
|
+
if (parts[1] === 'page' && parts[2] && !isNaN(Number(parts[2]))) {
|
|
29
|
+
pathType = WebsiteDataTypes.BlogList;
|
|
30
|
+
pagination = { page: Number(parts[2]), pageSize };
|
|
31
|
+
}
|
|
32
|
+
// /blog/{slug}
|
|
33
|
+
else {
|
|
34
|
+
pathType = WebsiteDataTypes.BlogPost;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
// /blog
|
|
39
|
+
pathType = WebsiteDataTypes.BlogList;
|
|
40
|
+
if (pageSize) {
|
|
41
|
+
pagination = { pageSize };
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return { pathType, pagination };
|
|
46
|
+
}
|
package/dist/page/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
export * from './
|
|
2
|
-
export * from './
|
|
3
|
-
export * from './
|
|
4
|
-
export * from './getAuthToken';
|
|
5
|
-
export * from './
|
|
6
|
-
export * from './types';
|
|
1
|
+
export * from './fetchPageData.js';
|
|
2
|
+
export * from './fetchPublicSettings.js';
|
|
3
|
+
export * from './fetchSearchResults.js';
|
|
4
|
+
export * from './getAuthToken.js';
|
|
5
|
+
export * from './parseSlug.js';
|
|
6
|
+
export * from './types.js';
|
|
7
|
+
export * from './isCrossingTemplateBoundary.js';
|
package/dist/page/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
export * from './
|
|
2
|
-
export * from './
|
|
3
|
-
export * from './
|
|
4
|
-
export * from './getAuthToken';
|
|
5
|
-
export * from './
|
|
6
|
-
export * from './types';
|
|
1
|
+
export * from './fetchPageData.js';
|
|
2
|
+
export * from './fetchPublicSettings.js';
|
|
3
|
+
export * from './fetchSearchResults.js';
|
|
4
|
+
export * from './getAuthToken.js';
|
|
5
|
+
export * from './parseSlug.js';
|
|
6
|
+
export * from './types.js';
|
|
7
|
+
export * from './isCrossingTemplateBoundary.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const isCrossingTemplateBoundary: (fromPath: string, toPath: string) => boolean;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Pagination } from './getPathType.js';
|
|
2
|
+
import type { WebsiteDataType } from '../constants/index.js';
|
|
3
|
+
export interface SlugParseResult {
|
|
4
|
+
lang?: string;
|
|
5
|
+
path: string;
|
|
6
|
+
pathType: WebsiteDataType;
|
|
7
|
+
pagination?: Pagination;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Parses a slug to determine language and path
|
|
11
|
+
*/
|
|
12
|
+
export declare function parseSlug(slug: string | null): SlugParseResult;
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { isValidLanguageCode } from '
|
|
1
|
+
import { isValidLanguageCode } from './isValidLanguageCode.js';
|
|
2
|
+
import { getPathType } from './getPathType.js';
|
|
2
3
|
/**
|
|
3
4
|
* Parses a slug to determine language and path
|
|
4
5
|
*/
|
|
5
|
-
export function
|
|
6
|
+
export function parseSlug(slug) {
|
|
6
7
|
const slugParts = slug ? slug.split('/').filter(Boolean) : [];
|
|
7
|
-
let lang
|
|
8
|
+
let lang;
|
|
8
9
|
let path = '/';
|
|
9
10
|
// Check if the first part is a valid language code
|
|
10
11
|
if (slugParts.length > 0 && isValidLanguageCode(slugParts[0])) {
|
|
@@ -15,8 +16,9 @@ export function parseSlugForLangAndPath(slug) {
|
|
|
15
16
|
}
|
|
16
17
|
}
|
|
17
18
|
else {
|
|
18
|
-
// No language in URL, use the path as is
|
|
19
|
-
path = slugParts.length > 0 ?
|
|
19
|
+
// No language in URL, use the path as is
|
|
20
|
+
path = slugParts.length > 0 ? slugParts.join('/') : '/';
|
|
20
21
|
}
|
|
21
|
-
|
|
22
|
+
const { pathType, pagination } = getPathType(path);
|
|
23
|
+
return { lang, path, pathType, pagination };
|
|
22
24
|
}
|
package/dist/page/types.d.ts
CHANGED
|
@@ -1,9 +1,5 @@
|
|
|
1
|
-
import type { SiteSettings } from '../types';
|
|
2
|
-
import type { MenuItem } from '../menus/types';
|
|
3
|
-
export interface SlugParseResult {
|
|
4
|
-
lang: string | null;
|
|
5
|
-
path: string;
|
|
6
|
-
}
|
|
1
|
+
import type { SiteSettings } from '../types.js';
|
|
2
|
+
import type { MenuItem } from '../menus/types.js';
|
|
7
3
|
export interface Language {
|
|
8
4
|
id: number;
|
|
9
5
|
name: string;
|
|
@@ -35,41 +31,17 @@ export interface LanguageAlternative {
|
|
|
35
31
|
slug: string;
|
|
36
32
|
locale: Language;
|
|
37
33
|
}
|
|
38
|
-
export interface BlogPostAuthor {
|
|
39
|
-
id: number;
|
|
40
|
-
display_name?: string;
|
|
41
|
-
username: string;
|
|
42
|
-
image?: string;
|
|
43
|
-
}
|
|
44
|
-
export interface BlogPostListItem {
|
|
45
|
-
id: number;
|
|
46
|
-
title: string;
|
|
47
|
-
slug: string;
|
|
48
|
-
excerpt?: string;
|
|
49
|
-
featured_image_id?: number;
|
|
50
|
-
publish_date?: string;
|
|
51
|
-
author?: BlogPostAuthor;
|
|
52
|
-
lang: string;
|
|
53
|
-
}
|
|
54
34
|
export interface PageData {
|
|
55
35
|
id?: number;
|
|
56
36
|
title?: string;
|
|
57
37
|
content?: Content;
|
|
58
|
-
|
|
38
|
+
slug?: string;
|
|
39
|
+
lang?: string;
|
|
59
40
|
public_settings: SiteSettings;
|
|
60
41
|
seo_metadata?: SeoMetadata;
|
|
61
42
|
language_alternatives?: LanguageAlternative[];
|
|
62
|
-
is_frontend_page?: boolean | null;
|
|
63
|
-
string_id?: string | null;
|
|
64
|
-
contents?: unknown;
|
|
65
43
|
page_custom_code?: string | null;
|
|
66
44
|
custom_code?: string | null;
|
|
67
45
|
require_login?: boolean;
|
|
68
|
-
blog_posts?: BlogPostListItem[];
|
|
69
|
-
featured_image_id?: number;
|
|
70
|
-
publish_date?: string;
|
|
71
|
-
author?: BlogPostAuthor;
|
|
72
46
|
notFound?: boolean;
|
|
73
|
-
status?: number;
|
|
74
|
-
detail?: string;
|
|
75
47
|
}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import type { MenuItem } from './menus/types';
|
|
2
2
|
import type { SpecialTemplate } from './page/types';
|
|
3
|
+
import type { WebsiteDataType } from './constants';
|
|
4
|
+
import type { PageData, SearchResultsData } from './page';
|
|
5
|
+
import type { BlogListData, BlogPostData } from './blog';
|
|
6
|
+
export type WebsiteData = {
|
|
7
|
+
type: WebsiteDataType;
|
|
8
|
+
data: PageData | BlogListData | BlogPostData | SearchResultsData;
|
|
9
|
+
settings?: SiteSettings;
|
|
10
|
+
};
|
|
3
11
|
export interface SiteSettings {
|
|
4
12
|
id: number;
|
|
5
13
|
name: string;
|
package/package.json
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deepsel/cms-utils",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.6",
|
|
4
4
|
"description": "Helper utilities for Deepsel CMS",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/DeepselSystems/deepsel-cms",
|
|
8
|
+
"directory": "packages/cms-utils"
|
|
9
|
+
},
|
|
5
10
|
"publishConfig": {
|
|
6
11
|
"access": "public"
|
|
7
12
|
},
|
|
@@ -21,69 +26,9 @@
|
|
|
21
26
|
"import": "./dist/index.js",
|
|
22
27
|
"types": "./dist/index.d.ts"
|
|
23
28
|
},
|
|
24
|
-
"./
|
|
25
|
-
"import": "./dist/
|
|
26
|
-
"types": "./dist/
|
|
27
|
-
},
|
|
28
|
-
"./language": {
|
|
29
|
-
"import": "./dist/language/index.js",
|
|
30
|
-
"types": "./dist/language/index.d.ts"
|
|
31
|
-
},
|
|
32
|
-
"./language/isValidLanguageCode": {
|
|
33
|
-
"import": "./dist/language/isValidLanguageCode.js",
|
|
34
|
-
"types": "./dist/language/isValidLanguageCode.d.ts"
|
|
35
|
-
},
|
|
36
|
-
"./menus": {
|
|
37
|
-
"import": "./dist/menus/index.js",
|
|
38
|
-
"types": "./dist/menus/index.d.ts"
|
|
39
|
-
},
|
|
40
|
-
"./menus/isActiveMenu": {
|
|
41
|
-
"import": "./dist/menus/isActiveMenu.js",
|
|
42
|
-
"types": "./dist/menus/isActiveMenu.d.ts"
|
|
43
|
-
},
|
|
44
|
-
"./menus/types": {
|
|
45
|
-
"import": "./dist/menus/types.js",
|
|
46
|
-
"types": "./dist/menus/types.d.ts"
|
|
47
|
-
},
|
|
48
|
-
"./page": {
|
|
49
|
-
"import": "./dist/page/index.js",
|
|
50
|
-
"types": "./dist/page/index.d.ts"
|
|
51
|
-
},
|
|
52
|
-
"./page/constants": {
|
|
53
|
-
"import": "./dist/page/constants.js",
|
|
54
|
-
"types": "./dist/page/constants.d.ts"
|
|
55
|
-
},
|
|
56
|
-
"./page/types": {
|
|
57
|
-
"import": "./dist/page/types.js",
|
|
58
|
-
"types": "./dist/page/types.d.ts"
|
|
59
|
-
},
|
|
60
|
-
"./page/fetchBlogListData": {
|
|
61
|
-
"import": "./dist/page/fetchBlogListData.js",
|
|
62
|
-
"types": "./dist/page/fetchBlogListData.d.ts"
|
|
63
|
-
},
|
|
64
|
-
"./page/fetchBlogPostData": {
|
|
65
|
-
"import": "./dist/page/fetchBlogPostData.js",
|
|
66
|
-
"types": "./dist/page/fetchBlogPostData.d.ts"
|
|
67
|
-
},
|
|
68
|
-
"./page/fetchFormData": {
|
|
69
|
-
"import": "./dist/page/fetchFormData.js",
|
|
70
|
-
"types": "./dist/page/fetchFormData.d.ts"
|
|
71
|
-
},
|
|
72
|
-
"./page/fetchPageData": {
|
|
73
|
-
"import": "./dist/page/fetchPageData.js",
|
|
74
|
-
"types": "./dist/page/fetchPageData.d.ts"
|
|
75
|
-
},
|
|
76
|
-
"./page/fetchPublicSettings": {
|
|
77
|
-
"import": "./dist/page/fetchPublicSettings.js",
|
|
78
|
-
"types": "./dist/page/fetchPublicSettings.d.ts"
|
|
79
|
-
},
|
|
80
|
-
"./page/getAuthToken": {
|
|
81
|
-
"import": "./dist/page/getAuthToken.js",
|
|
82
|
-
"types": "./dist/page/getAuthToken.d.ts"
|
|
83
|
-
},
|
|
84
|
-
"./page/parseSlugForLangAndPath": {
|
|
85
|
-
"import": "./dist/page/parseSlugForLangAndPath.js",
|
|
86
|
-
"types": "./dist/page/parseSlugForLangAndPath.d.ts"
|
|
29
|
+
"./common/utils": {
|
|
30
|
+
"import": "./dist/common/utils/index.js",
|
|
31
|
+
"types": "./dist/common/utils/index.d.ts"
|
|
87
32
|
}
|
|
88
33
|
},
|
|
89
34
|
"files": [
|
package/dist/language/index.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './isValidLanguageCode';
|
package/dist/language/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './isValidLanguageCode';
|
package/dist/page/constants.d.ts
DELETED
|
File without changes
|
package/dist/page/constants.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Fetches Form data from the backend by language and slug
|
|
3
|
-
*/
|
|
4
|
-
export async function fetchFormData(lang, slug, backendHost = 'http://localhost:8000') {
|
|
5
|
-
try {
|
|
6
|
-
// Format the slug properly
|
|
7
|
-
const formattedSlug = slug.replace(/^\/forms\//, '');
|
|
8
|
-
// Determine the URL based on whether a language is provided
|
|
9
|
-
const url = `${backendHost}/form/website/${lang}/${formattedSlug}`;
|
|
10
|
-
// Prepare fetch options
|
|
11
|
-
const fetchOptions = {
|
|
12
|
-
method: 'GET',
|
|
13
|
-
headers: {
|
|
14
|
-
'Content-Type': 'application/json',
|
|
15
|
-
},
|
|
16
|
-
};
|
|
17
|
-
// Fetch the page data from the backend
|
|
18
|
-
const response = await fetch(url, fetchOptions);
|
|
19
|
-
// Only treat actual 404 as not found
|
|
20
|
-
if (response.status === 404) {
|
|
21
|
-
const { detail } = await response.json();
|
|
22
|
-
console.warn('404', url, { detail });
|
|
23
|
-
return { notFound: true, status: 404, detail };
|
|
24
|
-
}
|
|
25
|
-
try {
|
|
26
|
-
// Parse the JSON
|
|
27
|
-
return await response.json();
|
|
28
|
-
}
|
|
29
|
-
catch (parseError) {
|
|
30
|
-
console.error(`Failed to parse response: ${parseError.message}`);
|
|
31
|
-
return { error: true, parseError: parseError.message };
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
catch (error) {
|
|
35
|
-
console.error('Error fetching page data:', error);
|
|
36
|
-
return { error: true, message: error.message };
|
|
37
|
-
}
|
|
38
|
-
}
|
|
File without changes
|
|
File without changes
|