@deepsel/cms-utils 1.0.0 → 1.1.3
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 +12 -8
- package/dist/menus/index.d.ts +2 -1
- package/dist/menus/index.js +2 -1
- package/dist/menus/isActiveMenu.d.ts +3 -0
- package/dist/menus/isActiveMenu.js +23 -0
- package/dist/menus/types.d.ts +1 -15
- package/dist/page/fetchFormData.d.ts +1 -2
- package/dist/page/fetchPageData.d.ts +2 -2
- package/dist/page/fetchPageData.js +7 -19
- package/dist/page/fetchPublicSettings.d.ts +1 -1
- package/dist/page/fetchPublicSettings.js +1 -1
- package/dist/page/getAuthToken.d.ts +1 -1
- package/dist/page/index.d.ts +6 -8
- package/dist/page/index.js +6 -8
- package/dist/page/types.d.ts +68 -14
- package/dist/types.d.ts +14 -0
- package/package.json +76 -10
- package/dist/menus/getCurrentLangMenus.d.ts +0 -3
- package/dist/menus/getCurrentLangMenus.js +0 -41
- package/dist/page/fetchBlogListData.d.ts +0 -5
- package/dist/page/fetchBlogListData.js +0 -75
- package/dist/page/fetchBlogPostData.d.ts +0 -5
- package/dist/page/fetchBlogPostData.js +0 -76
package/README.md
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
# @deepsel/cms-utils
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Framework-agnostic utilities for building DeepCMS themes in any JavaScript framework.
|
|
4
4
|
|
|
5
5
|
`@deepsel/cms-utils` is designed to be:
|
|
6
6
|
|
|
7
|
-
- **Framework-agnostic** – works with
|
|
7
|
+
- **Framework-agnostic** – works with React, Vue, Angular, Astro, Next.js, etc.
|
|
8
8
|
- **TypeScript-friendly** – fully typed helpers.
|
|
9
|
-
- **CMS-oriented** – utilities for menus, slugs, URLs, localization,
|
|
9
|
+
- **CMS-oriented** – utilities for menus, slugs, URLs, localization, page data fetching, etc.
|
|
10
|
+
|
|
11
|
+
> **Note:** For React-specific hooks and components, use [`@deepsel/deep-cms-react`](https://github.com/DeepselSystems/deep-cms-react)
|
|
10
12
|
|
|
11
13
|
---
|
|
12
14
|
|
|
@@ -21,11 +23,11 @@ npm install @deepsel/cms-utils
|
|
|
21
23
|
Example (TypeScript / ESM):
|
|
22
24
|
|
|
23
25
|
```typescript
|
|
24
|
-
import {
|
|
26
|
+
import { isValidLanguageCode } from '@deepsel/cms-utils';
|
|
25
27
|
|
|
26
|
-
const
|
|
28
|
+
const isValidLanguageCode = isValidLanguageCode('en');
|
|
27
29
|
|
|
28
|
-
console.log(
|
|
30
|
+
console.log({ isValidLanguageCode });
|
|
29
31
|
```
|
|
30
32
|
|
|
31
33
|
## Local Development
|
|
@@ -89,9 +91,11 @@ In your app (`my-app`), import from `@deepsel/cms-utils` as if it were a regular
|
|
|
89
91
|
|
|
90
92
|
```typescript
|
|
91
93
|
// inside my-app
|
|
92
|
-
import {
|
|
94
|
+
import { isValidLanguageCode } from '@deepsel/cms-utils';
|
|
95
|
+
|
|
96
|
+
const isValidLanguageCode = isValidLanguageCode('en');
|
|
93
97
|
|
|
94
|
-
|
|
98
|
+
console.log({ isValidLanguageCode });
|
|
95
99
|
```
|
|
96
100
|
|
|
97
101
|
### 5. Build the Package for Production
|
package/dist/menus/index.d.ts
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export * from './
|
|
1
|
+
export * from './isActiveMenu';
|
|
2
|
+
export * from './types';
|
package/dist/menus/index.js
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export * from './
|
|
1
|
+
export * from './isActiveMenu';
|
|
2
|
+
export * from './types';
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// Check if a menu item should be marked as active
|
|
2
|
+
export const isActiveMenu = (menuItem, pageData) => {
|
|
3
|
+
// return if not browser
|
|
4
|
+
if (typeof window === 'undefined') {
|
|
5
|
+
return false;
|
|
6
|
+
}
|
|
7
|
+
const location = window.location;
|
|
8
|
+
const currentLang = pageData.lang;
|
|
9
|
+
let result;
|
|
10
|
+
if (menuItem.url === '/') {
|
|
11
|
+
result =
|
|
12
|
+
location.pathname === '/' ||
|
|
13
|
+
location.pathname === `/${currentLang}` ||
|
|
14
|
+
location.pathname === `/${currentLang}/`;
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
result =
|
|
18
|
+
location.pathname === menuItem?.url ||
|
|
19
|
+
location.pathname === `/${currentLang}${menuItem.url}` ||
|
|
20
|
+
location.pathname === `/${currentLang}${menuItem.url}/`;
|
|
21
|
+
}
|
|
22
|
+
return result;
|
|
23
|
+
};
|
package/dist/menus/types.d.ts
CHANGED
|
@@ -1,22 +1,8 @@
|
|
|
1
1
|
export interface MenuItem {
|
|
2
|
-
id: number;
|
|
3
|
-
parent_id: number | null;
|
|
4
|
-
position: number;
|
|
5
|
-
translations: Record<string, {
|
|
6
|
-
open_in_new_tab: boolean;
|
|
7
|
-
page_content_id: number;
|
|
8
|
-
title: string;
|
|
9
|
-
url: string | null;
|
|
10
|
-
use_custom_url: boolean;
|
|
11
|
-
use_page_title: boolean;
|
|
12
|
-
}>;
|
|
13
|
-
children: MenuItem[];
|
|
14
|
-
}
|
|
15
|
-
export interface ProcessedMenuItem {
|
|
16
2
|
id: number;
|
|
17
3
|
position: number;
|
|
18
4
|
title: string;
|
|
19
5
|
url: string | null;
|
|
20
6
|
open_in_new_tab: boolean;
|
|
21
|
-
children:
|
|
7
|
+
children: MenuItem[];
|
|
22
8
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import type { ApiResponse } from './types';
|
|
2
1
|
/**
|
|
3
2
|
* Fetches Form data from the backend by language and slug
|
|
4
3
|
*/
|
|
5
|
-
export declare function fetchFormData(lang: string, slug: string, backendHost?: string): Promise<
|
|
4
|
+
export declare function fetchFormData(lang: string, slug: string, backendHost?: string): Promise<Record<string, unknown>>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { PageData } from './types';
|
|
2
2
|
/**
|
|
3
3
|
* Fetches page data from the backend by language and slug
|
|
4
4
|
*/
|
|
5
|
-
export declare function fetchPageData(lang: string | null, slug: string, isPreview?: boolean, authToken?: string | null, astroRequest?: Request | null, backendHost?: string): Promise<
|
|
5
|
+
export declare function fetchPageData(lang: string | null, slug: string, isPreview?: boolean, authToken?: string | null, astroRequest?: Request | null, backendHost?: string): Promise<PageData>;
|
|
@@ -46,26 +46,14 @@ export async function fetchPageData(lang, slug, isPreview = false, authToken = n
|
|
|
46
46
|
// Note: Cannot override Host header due to browser security restrictions
|
|
47
47
|
}
|
|
48
48
|
// Add authentication headers if token exists (for both preview and protected content)
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
if (!token && typeof window !== 'undefined') {
|
|
52
|
-
try {
|
|
53
|
-
const { Preferences } = await import('@capacitor/preferences');
|
|
54
|
-
const tokenResult = await Preferences.get({ key: 'token' });
|
|
55
|
-
token = tokenResult.value;
|
|
56
|
-
}
|
|
57
|
-
catch (e) {
|
|
58
|
-
console.warn('Could not get token from Preferences:', e);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
if (token) {
|
|
62
|
-
fetchOptions.headers['Authorization'] = `Bearer ${token}`;
|
|
49
|
+
if (authToken) {
|
|
50
|
+
fetchOptions.headers['Authorization'] = `Bearer ${authToken}`;
|
|
63
51
|
}
|
|
64
52
|
// Fetch the page data from the backend
|
|
65
53
|
const response = await fetch(url, fetchOptions);
|
|
66
54
|
// Handle authentication errors
|
|
67
55
|
if (response.status === 401) {
|
|
68
|
-
|
|
56
|
+
throw new Error('Authentication required');
|
|
69
57
|
}
|
|
70
58
|
// Only treat actual 404 as not found
|
|
71
59
|
if (response.status === 404) {
|
|
@@ -79,12 +67,12 @@ export async function fetchPageData(lang, slug, isPreview = false, authToken = n
|
|
|
79
67
|
status: 404,
|
|
80
68
|
detail,
|
|
81
69
|
public_settings: siteSettings,
|
|
82
|
-
lang: lang || siteSettings
|
|
70
|
+
lang: lang || siteSettings.default_language?.iso_code || 'en',
|
|
83
71
|
};
|
|
84
72
|
}
|
|
85
73
|
catch (settingsError) {
|
|
86
74
|
console.warn('Could not fetch site settings for 404 page:', settingsError);
|
|
87
|
-
|
|
75
|
+
throw new Error(`Page not found: ${detail}`);
|
|
88
76
|
}
|
|
89
77
|
}
|
|
90
78
|
try {
|
|
@@ -94,11 +82,11 @@ export async function fetchPageData(lang, slug, isPreview = false, authToken = n
|
|
|
94
82
|
}
|
|
95
83
|
catch (parseError) {
|
|
96
84
|
console.error(`Failed to parse response: ${parseError.message}`);
|
|
97
|
-
|
|
85
|
+
throw new Error(`Failed to parse response: ${parseError.message}`);
|
|
98
86
|
}
|
|
99
87
|
}
|
|
100
88
|
catch (error) {
|
|
101
89
|
console.error('Error fetching page data:', error);
|
|
102
|
-
|
|
90
|
+
throw error;
|
|
103
91
|
}
|
|
104
92
|
}
|
|
@@ -2,4 +2,4 @@ import type { SiteSettings } from '../types';
|
|
|
2
2
|
/**
|
|
3
3
|
* Fetches public settings from the backend
|
|
4
4
|
*/
|
|
5
|
-
export declare function fetchPublicSettings(orgId?: number | null, astroRequest?: Request | null, lang?: string | null, backendHost?: string): Promise<SiteSettings
|
|
5
|
+
export declare function fetchPublicSettings(orgId?: number | null, astroRequest?: Request | null, lang?: string | null, backendHost?: string): Promise<SiteSettings>;
|
package/dist/page/index.d.ts
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
export * from './
|
|
2
|
-
export * from './
|
|
3
|
-
export * from './
|
|
4
|
-
export * from './
|
|
5
|
-
export * from './
|
|
6
|
-
export * from './
|
|
7
|
-
export * from './parseSlugForLangAndPath.js';
|
|
8
|
-
export * from './types.js';
|
|
1
|
+
export * from './fetchFormData';
|
|
2
|
+
export * from './fetchPageData';
|
|
3
|
+
export * from './fetchPublicSettings';
|
|
4
|
+
export * from './getAuthToken';
|
|
5
|
+
export * from './parseSlugForLangAndPath';
|
|
6
|
+
export * from './types';
|
package/dist/page/index.js
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
export * from './
|
|
2
|
-
export * from './
|
|
3
|
-
export * from './
|
|
4
|
-
export * from './
|
|
5
|
-
export * from './
|
|
6
|
-
export * from './
|
|
7
|
-
export * from './parseSlugForLangAndPath.js';
|
|
8
|
-
export * from './types.js';
|
|
1
|
+
export * from './fetchFormData';
|
|
2
|
+
export * from './fetchPageData';
|
|
3
|
+
export * from './fetchPublicSettings';
|
|
4
|
+
export * from './getAuthToken';
|
|
5
|
+
export * from './parseSlugForLangAndPath';
|
|
6
|
+
export * from './types';
|
package/dist/page/types.d.ts
CHANGED
|
@@ -1,21 +1,75 @@
|
|
|
1
|
+
import type { SiteSettings } from '../types';
|
|
2
|
+
import type { MenuItem } from '../menus/types';
|
|
1
3
|
export interface SlugParseResult {
|
|
2
4
|
lang: string | null;
|
|
3
5
|
path: string;
|
|
4
6
|
}
|
|
5
|
-
export interface
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
export interface Language {
|
|
8
|
+
id: number;
|
|
9
|
+
name: string;
|
|
10
|
+
iso_code: string;
|
|
11
|
+
svg_flag: string;
|
|
12
|
+
}
|
|
13
|
+
export interface SpecialTemplate {
|
|
14
|
+
name: string;
|
|
15
|
+
html?: string;
|
|
16
|
+
component_name?: string;
|
|
17
|
+
}
|
|
18
|
+
export type Menus = MenuItem[];
|
|
19
|
+
export interface ContentField {
|
|
20
|
+
'ds-label': string;
|
|
21
|
+
'ds-type': string;
|
|
22
|
+
'ds-value': string;
|
|
23
|
+
}
|
|
24
|
+
export interface Content {
|
|
25
|
+
main: ContentField;
|
|
10
26
|
}
|
|
11
|
-
export interface
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
27
|
+
export interface SeoMetadata {
|
|
28
|
+
title: string;
|
|
29
|
+
description: string | null;
|
|
30
|
+
featured_image_id: number | null;
|
|
31
|
+
featured_image_name: string | null;
|
|
32
|
+
allow_indexing: boolean;
|
|
17
33
|
}
|
|
18
|
-
export interface
|
|
19
|
-
|
|
34
|
+
export interface LanguageAlternative {
|
|
35
|
+
slug: string;
|
|
36
|
+
locale: Language;
|
|
37
|
+
}
|
|
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
|
+
export interface PageData {
|
|
55
|
+
id?: number;
|
|
56
|
+
title?: string;
|
|
57
|
+
content?: Content;
|
|
58
|
+
lang: string;
|
|
59
|
+
public_settings: SiteSettings;
|
|
60
|
+
seo_metadata?: SeoMetadata;
|
|
61
|
+
language_alternatives?: LanguageAlternative[];
|
|
62
|
+
is_frontend_page?: boolean | null;
|
|
63
|
+
string_id?: string | null;
|
|
64
|
+
contents?: unknown;
|
|
65
|
+
page_custom_code?: string | null;
|
|
66
|
+
custom_code?: string | null;
|
|
67
|
+
require_login?: boolean;
|
|
68
|
+
blog_posts?: BlogPostListItem[];
|
|
69
|
+
featured_image_id?: number;
|
|
70
|
+
publish_date?: string;
|
|
71
|
+
author?: BlogPostAuthor;
|
|
72
|
+
notFound?: boolean;
|
|
73
|
+
status?: number;
|
|
74
|
+
detail?: string;
|
|
20
75
|
}
|
|
21
|
-
export type ApiResponse = Record<string, unknown> | ErrorResponse | NotFoundResponse | BlogListResponse;
|
package/dist/types.d.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import type { MenuItem } from './menus/types';
|
|
2
|
+
import type { SpecialTemplate } from './page/types';
|
|
2
3
|
export interface SiteSettings {
|
|
4
|
+
id: number;
|
|
5
|
+
name: string;
|
|
3
6
|
domains: string[];
|
|
4
7
|
available_languages: Array<{
|
|
5
8
|
id: number;
|
|
@@ -22,4 +25,15 @@ export interface SiteSettings {
|
|
|
22
25
|
show_chatbox: boolean;
|
|
23
26
|
website_custom_code: string | null;
|
|
24
27
|
menus: MenuItem[];
|
|
28
|
+
access_token_expire_minutes: number;
|
|
29
|
+
require_2fa_all_users: boolean;
|
|
30
|
+
allow_public_signup: boolean;
|
|
31
|
+
is_enabled_google_sign_in: boolean;
|
|
32
|
+
is_enabled_saml: boolean;
|
|
33
|
+
saml_sp_entity_id: string | null;
|
|
34
|
+
auto_translate_components: boolean;
|
|
35
|
+
has_openai_api_key: boolean;
|
|
36
|
+
ai_default_writing_model_id: number;
|
|
37
|
+
special_templates: Record<string, SpecialTemplate>;
|
|
38
|
+
selected_theme: string;
|
|
25
39
|
}
|
package/package.json
CHANGED
|
@@ -1,24 +1,91 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deepsel/cms-utils",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "Helper utilities for
|
|
3
|
+
"version": "1.1.3",
|
|
4
|
+
"description": "Helper utilities for Deepsel CMS",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
8
|
-
"repository": {
|
|
9
|
-
"type": "git",
|
|
10
|
-
"url": "git+https://github.com/DeepselSystems/cms-utils.git"
|
|
11
|
-
},
|
|
12
8
|
"author": "Tim Tran <tim.tran@deepsel.com> (https://deepsel.com)",
|
|
13
9
|
"license": "MIT",
|
|
14
10
|
"bugs": {
|
|
15
|
-
"url": "https://github.com/DeepselSystems/cms
|
|
11
|
+
"url": "https://github.com/DeepselSystems/deepsel-cms/issues"
|
|
16
12
|
},
|
|
17
|
-
"homepage": "https://github.com/DeepselSystems/cms-utils#readme",
|
|
13
|
+
"homepage": "https://github.com/DeepselSystems/deepsel-cms/tree/main/packages/cms-utils#readme",
|
|
18
14
|
"type": "module",
|
|
19
15
|
"main": "dist/index.js",
|
|
20
16
|
"module": "dist/index.js",
|
|
21
17
|
"types": "dist/index.d.ts",
|
|
18
|
+
"sideEffects": false,
|
|
19
|
+
"exports": {
|
|
20
|
+
".": {
|
|
21
|
+
"import": "./dist/index.js",
|
|
22
|
+
"types": "./dist/index.d.ts"
|
|
23
|
+
},
|
|
24
|
+
"./types": {
|
|
25
|
+
"import": "./dist/types.js",
|
|
26
|
+
"types": "./dist/types.d.ts"
|
|
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"
|
|
87
|
+
}
|
|
88
|
+
},
|
|
22
89
|
"files": [
|
|
23
90
|
"dist"
|
|
24
91
|
],
|
|
@@ -31,8 +98,7 @@
|
|
|
31
98
|
"lint:fix": "eslint \"{src,tests}/**/*.ts\" --fix",
|
|
32
99
|
"format": "prettier --write .",
|
|
33
100
|
"format:check": "prettier --check .",
|
|
34
|
-
"prepush": "npm run test && npm run build && npm run lint && npm run format:check"
|
|
35
|
-
"publish": "npm publish --access public"
|
|
101
|
+
"prepush": "npm run test && npm run build && npm run lint && npm run format:check"
|
|
36
102
|
},
|
|
37
103
|
"keywords": [
|
|
38
104
|
"cms",
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
Get menus based on the current selected language
|
|
3
|
-
*/
|
|
4
|
-
export const getCurrentLangMenus = (settings) => {
|
|
5
|
-
if (!settings || !settings.menus || !settings.menus.length)
|
|
6
|
-
return null;
|
|
7
|
-
let currentLang = localStorage.getItem('i18nextLng');
|
|
8
|
-
// If no language is selected, use the default language
|
|
9
|
-
if (!currentLang) {
|
|
10
|
-
currentLang = settings.default_language.iso_code;
|
|
11
|
-
}
|
|
12
|
-
return settings.menus
|
|
13
|
-
.map((menu) => processMenuItem(menu, currentLang))
|
|
14
|
-
.filter((item) => item !== null);
|
|
15
|
-
};
|
|
16
|
-
/*
|
|
17
|
-
Process a menu item and its children recursively:
|
|
18
|
-
- Remove null items
|
|
19
|
-
- Only keep fields that are needed from the translation for the current language
|
|
20
|
-
- Remove other translations
|
|
21
|
-
*/
|
|
22
|
-
function processMenuItem(menuItem, currentLang) {
|
|
23
|
-
const translation = menuItem.translations[currentLang];
|
|
24
|
-
if (!translation) {
|
|
25
|
-
return null;
|
|
26
|
-
}
|
|
27
|
-
// Process children recursively and filter out null items
|
|
28
|
-
const children = menuItem.children && menuItem.children.length > 0
|
|
29
|
-
? menuItem.children
|
|
30
|
-
.map((child) => processMenuItem(child, currentLang))
|
|
31
|
-
.filter((item) => item !== null)
|
|
32
|
-
: [];
|
|
33
|
-
return {
|
|
34
|
-
id: menuItem.id,
|
|
35
|
-
position: menuItem.position,
|
|
36
|
-
title: translation.title,
|
|
37
|
-
url: translation.url,
|
|
38
|
-
open_in_new_tab: translation.open_in_new_tab,
|
|
39
|
-
children,
|
|
40
|
-
};
|
|
41
|
-
}
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Fetches blog list data from the backend by language
|
|
3
|
-
*/
|
|
4
|
-
export async function fetchBlogListData(lang, authToken = null, astroRequest = null, backendHost = 'http://localhost:8000') {
|
|
5
|
-
try {
|
|
6
|
-
// Determine the URL based on whether a language is provided
|
|
7
|
-
const url = lang && lang !== 'default'
|
|
8
|
-
? `${backendHost}/blog_post/website/${lang}`
|
|
9
|
-
: `${backendHost}/blog_post/website/default`;
|
|
10
|
-
// Prepare fetch options
|
|
11
|
-
const fetchOptions = {
|
|
12
|
-
method: 'GET',
|
|
13
|
-
headers: {
|
|
14
|
-
'Content-Type': 'application/json',
|
|
15
|
-
},
|
|
16
|
-
};
|
|
17
|
-
// Send the current hostname to the backend for proper domain detection
|
|
18
|
-
let hostname = null;
|
|
19
|
-
// Server-side: Extract hostname from Astro request
|
|
20
|
-
if (astroRequest) {
|
|
21
|
-
const url = new URL(astroRequest.url);
|
|
22
|
-
hostname = url.hostname;
|
|
23
|
-
}
|
|
24
|
-
// Client-side: Extract hostname from window
|
|
25
|
-
else if (typeof window !== 'undefined') {
|
|
26
|
-
hostname = window.location.hostname;
|
|
27
|
-
}
|
|
28
|
-
if (hostname) {
|
|
29
|
-
fetchOptions.headers['X-Original-Host'] = hostname;
|
|
30
|
-
fetchOptions.headers['X-Frontend-Host'] = hostname;
|
|
31
|
-
// Note: Cannot override Host header due to browser security restrictions
|
|
32
|
-
}
|
|
33
|
-
// Add authentication headers if token exists (for both preview and protected content)
|
|
34
|
-
let token = authToken;
|
|
35
|
-
// If no token provided and we're in browser environment, try Capacitor Preferences
|
|
36
|
-
if (!token && typeof window !== 'undefined') {
|
|
37
|
-
try {
|
|
38
|
-
const { Preferences } = await import('@capacitor/preferences');
|
|
39
|
-
const tokenResult = await Preferences.get({ key: 'token' });
|
|
40
|
-
token = tokenResult.value;
|
|
41
|
-
}
|
|
42
|
-
catch (e) {
|
|
43
|
-
console.warn('Could not get token from Preferences:', e);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
if (token) {
|
|
47
|
-
fetchOptions.headers['Authorization'] = `Bearer ${token}`;
|
|
48
|
-
}
|
|
49
|
-
// Fetch the blog list data from the backend
|
|
50
|
-
const response = await fetch(url, fetchOptions);
|
|
51
|
-
// Handle authentication errors
|
|
52
|
-
if (response.status === 401) {
|
|
53
|
-
return { error: true, status: 401, message: 'Authentication required' };
|
|
54
|
-
}
|
|
55
|
-
// Only treat actual 404 as not found
|
|
56
|
-
if (response.status === 404) {
|
|
57
|
-
const { detail } = await response.json();
|
|
58
|
-
console.warn('404', url, { detail });
|
|
59
|
-
return { notFound: true, status: 404, detail };
|
|
60
|
-
}
|
|
61
|
-
try {
|
|
62
|
-
// Parse the JSON
|
|
63
|
-
const posts = await response.json();
|
|
64
|
-
return { posts };
|
|
65
|
-
}
|
|
66
|
-
catch (parseError) {
|
|
67
|
-
console.error(`Failed to parse response: ${parseError.message}`);
|
|
68
|
-
return { error: true, parseError: parseError.message };
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
catch (error) {
|
|
72
|
-
console.error('Error fetching blog list data:', error);
|
|
73
|
-
return { error: true, message: error.message };
|
|
74
|
-
}
|
|
75
|
-
}
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import type { ApiResponse } from './types';
|
|
2
|
-
/**
|
|
3
|
-
* Fetches Blog-Post-Content data from the backend by language and slug
|
|
4
|
-
*/
|
|
5
|
-
export declare function fetchBlogPostData(lang: string, slug: string, authToken?: string | null, astroRequest?: Request | null, backendHost?: string): Promise<ApiResponse>;
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Fetches Blog-Post-Content data from the backend by language and slug
|
|
3
|
-
*/
|
|
4
|
-
export async function fetchBlogPostData(lang, slug, authToken = null, astroRequest = null, backendHost = 'http://localhost:8000') {
|
|
5
|
-
try {
|
|
6
|
-
// Format the slug properly
|
|
7
|
-
const formattedSlug = slug.replace(/^\/blog\//, '');
|
|
8
|
-
// Determine the URL based on whether a language is provided
|
|
9
|
-
const url = lang && lang !== 'default'
|
|
10
|
-
? `${backendHost}/blog_post/website/${lang}/${formattedSlug}`
|
|
11
|
-
: `${backendHost}/blog_post/website/default/${formattedSlug}`;
|
|
12
|
-
// Prepare fetch options
|
|
13
|
-
const fetchOptions = {
|
|
14
|
-
method: 'GET',
|
|
15
|
-
headers: {
|
|
16
|
-
'Content-Type': 'application/json',
|
|
17
|
-
},
|
|
18
|
-
};
|
|
19
|
-
// Send the current hostname to the backend for proper domain detection
|
|
20
|
-
let hostname = null;
|
|
21
|
-
// Server-side: Extract hostname from Astro request
|
|
22
|
-
if (astroRequest) {
|
|
23
|
-
const url = new URL(astroRequest.url);
|
|
24
|
-
hostname = url.hostname;
|
|
25
|
-
}
|
|
26
|
-
// Client-side: Extract hostname from window
|
|
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
|
-
// Note: Cannot override Host header due to browser security restrictions
|
|
34
|
-
}
|
|
35
|
-
// Add authentication headers if token exists (for both preview and protected content)
|
|
36
|
-
let token = authToken;
|
|
37
|
-
// If no token provided and we're in browser environment, try Capacitor Preferences
|
|
38
|
-
if (!token && typeof window !== 'undefined') {
|
|
39
|
-
try {
|
|
40
|
-
const { Preferences } = await import('@capacitor/preferences');
|
|
41
|
-
const tokenResult = await Preferences.get({ key: 'token' });
|
|
42
|
-
token = tokenResult.value;
|
|
43
|
-
}
|
|
44
|
-
catch (e) {
|
|
45
|
-
console.warn('Could not get token from Preferences:', e);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
if (token) {
|
|
49
|
-
fetchOptions.headers['Authorization'] = `Bearer ${token}`;
|
|
50
|
-
}
|
|
51
|
-
// Fetch the page data from the backend
|
|
52
|
-
const response = await fetch(url, fetchOptions);
|
|
53
|
-
// Handle authentication errors
|
|
54
|
-
if (response.status === 401) {
|
|
55
|
-
return { error: true, status: 401, message: 'Authentication required' };
|
|
56
|
-
}
|
|
57
|
-
// Only treat actual 404 as not found
|
|
58
|
-
if (response.status === 404) {
|
|
59
|
-
const { detail } = await response.json();
|
|
60
|
-
console.warn('404', url, { detail });
|
|
61
|
-
return { notFound: true, status: 404, detail };
|
|
62
|
-
}
|
|
63
|
-
try {
|
|
64
|
-
// Parse the JSON
|
|
65
|
-
return await response.json();
|
|
66
|
-
}
|
|
67
|
-
catch (parseError) {
|
|
68
|
-
console.error(`Failed to parse response: ${parseError.message}`);
|
|
69
|
-
return { error: true, parseError: parseError.message };
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
catch (error) {
|
|
73
|
-
console.error('Error fetching page data:', error);
|
|
74
|
-
return { error: true, message: error.message };
|
|
75
|
-
}
|
|
76
|
-
}
|