@deepsel/cms-utils 1.1.5 → 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.
@@ -1,5 +1,5 @@
1
- import type { BlogListData } from './types';
2
- import type { Pagination } from '../page/getPathType';
1
+ import type { BlogListData } from './types.js';
2
+ import type { Pagination } from '../page/getPathType.js';
3
3
  interface FetchBlogListProps {
4
4
  lang?: string;
5
5
  pagination?: Pagination;
@@ -1,4 +1,4 @@
1
- import type { BlogPostData } from './types';
1
+ import type { BlogPostData } from './types.js';
2
2
  interface FetchBlogPostProps {
3
3
  path: string;
4
4
  lang?: string;
@@ -1,4 +1,4 @@
1
- import { fetchPublicSettings } from '../page';
1
+ import { fetchPublicSettings } from '../page/index.js';
2
2
  /**
3
3
  * Fetches a single blog post from the backend by language and path
4
4
  * Corresponds to GET /blog_post/website/{lang}/{path}
@@ -1,3 +1,3 @@
1
- export * from './fetchBlogList';
2
- export * from './fetchBlogPost';
3
- export * from './types';
1
+ export * from './fetchBlogList.js';
2
+ export * from './fetchBlogPost.js';
3
+ export * from './types.js';
@@ -1,3 +1,3 @@
1
- export * from './fetchBlogList';
2
- export * from './fetchBlogPost';
3
- export * from './types';
1
+ export * from './fetchBlogList.js';
2
+ export * from './fetchBlogPost.js';
3
+ export * from './types.js';
@@ -1,5 +1,5 @@
1
- import type { SiteSettings } from '../types';
2
- import type { SeoMetadata, LanguageAlternative } from '../page/types';
1
+ import type { SiteSettings } from '../types.js';
2
+ import type { SeoMetadata, LanguageAlternative } from '../page/types.js';
3
3
  export interface BlogPostAuthor {
4
4
  id: number;
5
5
  display_name?: string;
@@ -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,4 @@
1
+ /**
2
+ * Returns true if value is a plain object or array (not null)
3
+ */
4
+ export declare function isObjectOrArray(value: unknown): boolean;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Returns true if value is a plain object or array (not null)
3
+ */
4
+ export function isObjectOrArray(value) {
5
+ return (value !== null &&
6
+ (Array.isArray(value) || Object.prototype.toString.call(value) === '[object Object]'));
7
+ }
@@ -1 +1,2 @@
1
- export * from './websiteDataTypes';
1
+ export * from './websiteDataTypes.js';
2
+ export * from './pagingTableParams.js';
@@ -1 +1,2 @@
1
- export * from './websiteDataTypes';
1
+ export * from './websiteDataTypes.js';
2
+ export * from './pagingTableParams.js';
@@ -0,0 +1,8 @@
1
+ /**
2
+ * URL search parameter keys used for paging and searching in list views
3
+ */
4
+ export declare const PagingTableParams: {
5
+ readonly Search: "search";
6
+ readonly Limit: "limit";
7
+ readonly Page: "page";
8
+ };
@@ -0,0 +1,8 @@
1
+ /**
2
+ * URL search parameter keys used for paging and searching in list views
3
+ */
4
+ export const PagingTableParams = {
5
+ Search: 'search',
6
+ Limit: 'limit',
7
+ Page: 'page',
8
+ };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
- export * from './page';
2
- export * from './menus';
3
- export * from './blog';
4
- export * from './types';
5
- export * from './constants';
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,5 +1,6 @@
1
- export * from './page';
2
- export * from './menus';
3
- export * from './blog';
4
- export * from './types';
5
- export * from './constants';
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';
@@ -1,2 +1,2 @@
1
- export * from './isActiveMenu';
2
- export * from './types';
1
+ export * from './isActiveMenu.js';
2
+ export * from './types.js';
@@ -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 { WebsiteData } from '../types';
1
+ import type { MenuItem } from './types.js';
2
+ import type { WebsiteData } from '../types.js';
3
3
  export declare const isActiveMenu: (menuItem: MenuItem, websiteData: WebsiteData) => boolean;
@@ -1,4 +1,4 @@
1
- import type { PageData } from './types';
1
+ import type { PageData } from './types.js';
2
2
  interface FetchPageDataProps {
3
3
  path: string;
4
4
  lang?: string;
@@ -1,4 +1,4 @@
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
  */
@@ -1,4 +1,4 @@
1
- import type { SiteSettings } from '../types';
1
+ import type { SiteSettings } from '../types.js';
2
2
  /**
3
3
  * Fetches public settings from the backend
4
4
  */
@@ -1,4 +1,4 @@
1
- import type { SiteSettings } from '../types';
1
+ import type { SiteSettings } from '../types.js';
2
2
  export interface SearchResultItem {
3
3
  id: string;
4
4
  title: string;
@@ -1,4 +1,4 @@
1
- import { fetchPublicSettings } from './fetchPublicSettings';
1
+ import { fetchPublicSettings } from './fetchPublicSettings.js';
2
2
  /**
3
3
  * Fetches search results from the backend.
4
4
  * Calls GET /api/v1/page/website_search/{lang}?q=...&limit=...
@@ -1,4 +1,4 @@
1
- import { type WebsiteDataType } from '../constants';
1
+ import { type WebsiteDataType } from '../constants/index.js';
2
2
  export interface Pagination {
3
3
  page?: number;
4
4
  pageSize?: number;
@@ -1,4 +1,4 @@
1
- import { WebsiteDataTypes } from '../constants';
1
+ import { WebsiteDataTypes } from '../constants/index.js';
2
2
  export function getPathType(path) {
3
3
  let pathType = WebsiteDataTypes.Page;
4
4
  let pagination = undefined;
@@ -1,7 +1,7 @@
1
- export * from './fetchPageData';
2
- export * from './fetchPublicSettings';
3
- export * from './fetchSearchResults';
4
- export * from './getAuthToken';
5
- export * from './parseSlug';
6
- export * from './types';
7
- export * from './isCrossingTemplateBoundary';
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';
@@ -1,7 +1,7 @@
1
- export * from './fetchPageData';
2
- export * from './fetchPublicSettings';
3
- export * from './fetchSearchResults';
4
- export * from './getAuthToken';
5
- export * from './parseSlug';
6
- export * from './types';
7
- export * from './isCrossingTemplateBoundary';
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';
@@ -1,5 +1,5 @@
1
- import type { Pagination } from './getPathType';
2
- import type { WebsiteDataType } from '../constants';
1
+ import type { Pagination } from './getPathType.js';
2
+ import type { WebsiteDataType } from '../constants/index.js';
3
3
  export interface SlugParseResult {
4
4
  lang?: string;
5
5
  path: string;
@@ -1,5 +1,5 @@
1
- import { isValidLanguageCode } from './isValidLanguageCode';
2
- import { getPathType } from './getPathType';
1
+ import { isValidLanguageCode } from './isValidLanguageCode.js';
2
+ import { getPathType } from './getPathType.js';
3
3
  /**
4
4
  * Parses a slug to determine language and path
5
5
  */
@@ -1,5 +1,5 @@
1
- import type { SiteSettings } from '../types';
2
- import type { MenuItem } from '../menus/types';
1
+ import type { SiteSettings } from '../types.js';
2
+ import type { MenuItem } from '../menus/types.js';
3
3
  export interface Language {
4
4
  id: number;
5
5
  name: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@deepsel/cms-utils",
3
- "version": "1.1.5",
3
+ "version": "1.1.6",
4
4
  "description": "Helper utilities for Deepsel CMS",
5
5
  "repository": {
6
6
  "type": "git",
@@ -25,6 +25,10 @@
25
25
  ".": {
26
26
  "import": "./dist/index.js",
27
27
  "types": "./dist/index.d.ts"
28
+ },
29
+ "./common/utils": {
30
+ "import": "./dist/common/utils/index.js",
31
+ "types": "./dist/common/utils/index.d.ts"
28
32
  }
29
33
  },
30
34
  "files": [