@soleil-se/app-util
Version:
Utility functions for WebApps, RESTApps and Widgets in Sitevision.
189 lines (163 loc) • 5.62 kB
JavaScript
import router from '@sitevision/api/common/router';
import app from '@sitevision/api/common/app';
import { nativeRequire } from '../server';
import getLegacyRouteUri from './legacy/getRouteUri';
import { localizedCompare, localizedCompareBy } from './localized-compare';
/**
* Regex for selecting leading slashes
* @constant {Regex}
*/
const leadingSlashes = /^(\/)*/g;
/**
* Regex for selecting trailing slashes
* @constant {Regex}
*/
const trailingSlashes = /(\/)*$/g;
/**
* If the current code is running on the server.
* @constant {boolean}
*/
export const isServer = typeof process !== 'undefined' ? process.server : typeof window === 'undefined';
/**
* If the current code is running in the browser.
* @constant {boolean}
*/
export const isBrowser = !isServer;
/**
* DOM friendly unique identifier for the WebApp.
* @constant {string}
*/
export const appId = (app?.portletId || 'preview').replace('.', '_');
/**
* If the WebApp is running in offline mode or not.
* @constant {boolean}
*/
export const isOffline = isServer
? nativeRequire('VersionUtil').getCurrentVersion() === nativeRequire('VersionUtil').OFFLINE_VERSION
: document.documentElement.classList.contains('sv-edit-mode');
/**
* If the WebApp is running in online mode or not.
* @constant {boolean}
*/
export const isOnline = !isOffline;
/**
* Get a prefixed namespace unique for app.
* @param {string} [prefix='app']
* @return {string} - Prefixed namespace.
*/
export function getNamespace(prefix = 'app') {
return `${prefix}_${appId}`;
}
/**
* Generate a unique identifier with a random UUID without dashes.
* @param {string} prefix Prefix for the identifier.
* @returns {string} Unique identifier.
*/
export function generateId(prefix = 'id') {
const uuid = isServer
? Packages.java.util.UUID.randomUUID().toString()
: window.crypto.randomUUID();
return `${prefix}_${uuid}`.replace(/-/g, '');
}
/**
* Stringify an object to a query string compatible with Sitevision.
* @param {Object} params Object with parameters to stringify.
* @param {Object} [options] Optional options.
* @param {Boolean} [options.addQueryPrefix = false] If a leading ? should be added to the string.
* @returns Stringified parameters.
*/
export function stringifyParams(params = {}, { addQueryPrefix = false } = {}) {
const qs = Object.keys(params).map((key) => {
const value = params[key];
if (value === undefined || value === null || value === '') return undefined;
if (Array.isArray(value)) {
return value.map((v) => `${encodeURIComponent(`${key}[]`)}=${encodeURIComponent(v)}`).join('&');
}
return `${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
}).filter((value) => !!value).join('&');
if (!qs) return '';
return addQueryPrefix ? `?${qs}` : qs;
}
/**
* Parse an URL or URI to an object containing its query parameters.
* @param {String} url URL or URI to be parsed, must start with or contain "?".
* @returns Object with parsed parameters.
*/
export function parseParams(url = '') {
const hasQuestion = url.indexOf('?') > -1;
if (!hasQuestion) return {};
let query = url.split('?')[1];
const hasHash = url.indexOf('#') > -1;
query = hasHash ? url.split('#')[0] : query;
return query.split('&').reduce((params, part) => {
let [key, value] = part.split('+').join(' ').split('=');
key = decodeURIComponent(key);
value = decodeURIComponent(value);
const isArray = key.endsWith('[]');
if (isArray) {
key = key.replace('[]', '');
value = params[key] ? [...params[key], value] : [value];
}
return {
...params,
[key]: value,
};
}, {});
}
/**
* Get URI for a route, same as `getStandaloneUrl` in Sitevision router.
* @param {string} route A route.
* @param {object} params Query parameters.
* @returns {string} URI for route.
*/
export function getRouteUri(route = '', params = undefined) {
const path = route.replace(leadingSlashes, '');
const qs = stringifyParams({
version: isOffline ? '0' : undefined,
...params,
}, { addQueryPrefix: true });
if (router?.getStandaloneUrl) {
return router.getStandaloneUrl((path !== '' ? `/${path}` : path).replace(trailingSlashes, ''))
.replace('?version=0', '') + qs;
}
/* Import of @sitevision/api/common/router is not avaliable in hooks, need to build the route URI
* manually instead of using router.getStandaloneUri */
return getLegacyRouteUri(path).replace(trailingSlashes, '') + qs;
}
/**
* Get URI for a view, same as `getUrl` in Sitevision router.
* @deprecated Not used in WebApps 2.
* @param {string} route A route.
* @returns {string} URI for view.
*/
export function getViewUri(route = '', params = undefined) {
if (!router?.getUrl) {
console.warn('[@soleil-se/app-util] getViewUri requires router.getUrl support.');
return undefined;
}
return router.getUrl(route, params);
}
/**
* Get URI for a resource.
* @param {string} resource A resource.
* @returns {string} URI for a resource.
*/
export function getResourceUri(resource = '') {
const { webAppId: id, webAppVersion: version } = app;
const path = resource.replace(leadingSlashes, '');
return `/webapp-files/${id}/${version}/${path}`;
}
let appProps = {};
export function setAppProps(data) {
appProps = data;
}
/**
* Get appData value or object that is passed to app when rendering.
* @export
* @param {string} [key] - Key for value.
* @return {*|object} - Value or object.
*/
export function getAppProps(key) {
return key ? appProps[key] : appProps;
}
export { localizedCompare, localizedCompareBy };