@soleil-se/app-util 5.0.0 → 5.2.0

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/CHANGELOG.md CHANGED
@@ -5,7 +5,22 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
- ## [5.0.0] - 2021-xx-xx
8
+ ## [5.2.0] - 2023-01-31
9
+
10
+ ### Changed
11
+
12
+ - New function `parseParams` to parse query parameters from an URL, URI or query string.
13
+
14
+ ## [5.1.0] - 2022-05-27
15
+
16
+ ### Changed
17
+
18
+ - New function `stringifyParams` to stringify query parameters to a Sitevision compatible format.
19
+ - Possible to pass a parameters object to `getRouteUri`.
20
+ - All common constants and functions are now usable in hooks.
21
+ - Deprecate `getViewUri` since it's not used in WebApps 2.
22
+
23
+ ## [5.0.0] - 2022-02-08
9
24
 
10
25
  ### Changed
11
26
 
package/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
 
4
4
  Utility functions for WebApps.
5
5
 
6
- [GitHub](https://github.com/soleilit/server-monorepo/tree/master/packages/webapp-util)
6
+ [GitHub](https://github.com/soleilit/server-monorepo/tree/master/packages/webapp-util)
7
7
  [NPM](https://www.npmjs.com/package/@soleil-se/webapp-util)
8
8
 
9
9
 
@@ -29,58 +29,33 @@ Utility functions for WebApps.
29
29
  "type": "WebApp",
30
30
  "bundled": true
31
31
  }
32
-
33
32
  ```
34
33
 
35
34
  ## Install
36
35
 
37
- `yarn add @soleil-se/webapp-util`
36
+ ```sh
37
+ > npm install @soleil-se/webapp-util
38
+ > yarn add @soleil-se/webapp-util
39
+ ```
40
+
41
+ :::details Integrity check failed
42
+ If the following error occurs when installing with Yarn run `yarn install --update-checksums`.
43
+
44
+ ```
45
+ Integrity check failed for "@soleil-se/webapp-util" (computed integrity doesn...
46
+ ```
47
+
48
+ :::
38
49
 
39
50
  ## Migration
40
51
 
41
- Migrating from version 4?
52
+ Migrating from version 4?
42
53
  See [MIGRATION](./MIGRATION.md).
43
54
 
44
55
  ## API
45
56
 
46
57
  All imports from base package are available both on the server and client.
47
58
 
48
- ### Constants
49
-
50
- <dl>
51
- <dt><a href="#appId">appId</a> : <code>String</code></dt>
52
- <dd><p>DOM friendly unique identifier for the WebApp.</p>
53
- </dd>
54
- <dt><a href="#isOffline">isOffline</a> : <code>Boolean</code></dt>
55
- <dd><p>If the WebApp is running in offline mode or not.</p>
56
- </dd>
57
- <dt><a href="#isOnline">isOnline</a> : <code>Boolean</code></dt>
58
- <dd><p>If the WebApp is running in online mode or not.</p>
59
- </dd>
60
- </dl>
61
-
62
- ### Functions
63
-
64
- <dl>
65
- <dt><a href="#getNamespace">getNamespace([prefix])</a> ⇒ <code>String</code></dt>
66
- <dd><p>Get a prefixed namespace unique for app.</p>
67
- </dd>
68
- <dt><a href="#getRouteUri">getRouteUri(route)</a> ⇒ <code>String</code></dt>
69
- <dd><p>Get URI for a route.
70
- </dd>
71
- <dt><a href="#getViewUri">getViewUri(route)</a> ⇒ <code>String</code></dt>
72
- <dd><p>Get URI for a view.
73
- </dd>
74
- <dt><a href="#getResourceUri">getResourceUri(resource)</a> ⇒ <code>String</code></dt>
75
- <dd><p>Get URI for a resource.</p>
76
- </dd>
77
- <dt><a href="#getAppProps">getAppProps([key])</a> ⇒ <code>*</code> | <code>Object</code></dt>
78
- <dd><p>Get props that are passed to app when rendering.</p>
79
- </dd>
80
- </dl>
81
-
82
- <a name="appId"></a>
83
-
84
59
  ### appId : `String`
85
60
 
86
61
  DOM friendly unique identifier for the WebApp.
@@ -91,8 +66,6 @@ import { appId } from '@soleil-se/webapp-util';
91
66
  console.log(appId); // For example: 12_682d461b1708a9bb1ea13efd
92
67
  ```
93
68
 
94
- <a name="isOffline"></a>
95
-
96
69
  ### isOffline : `Boolean`
97
70
 
98
71
  If the WebApp is running in offline mode or not.
@@ -103,8 +76,6 @@ import { isOffline } from '@soleil-se/webapp-util';
103
76
  console.log(isOffline); // true or false
104
77
  ```
105
78
 
106
- <a name="isOnline"></a>
107
-
108
79
  ### isOnline : `Boolean`
109
80
 
110
81
  If the WebApp is running in online mode or not.
@@ -139,9 +110,7 @@ console.log(getNamespace('decoration'));
139
110
  // For example: decoration_10_3871c02f1754f3aa8f9d4eb_12_70c3d424173b4900fc550e1c
140
111
  ```
141
112
 
142
- <a name="getRouteUri"></a>
143
-
144
- ### getRouteUri(route) ⇒ `String`
113
+ ### getRouteUri(route, [query]) ⇒ `String`
145
114
 
146
115
  Get URI for a route.
147
116
 
@@ -150,35 +119,22 @@ Get URI for a route.
150
119
  | Param | Type | Description |
151
120
  | --- | --- | --- |
152
121
  | route | `String` | A route. |
122
+ | query | `Object` | Object with query string parameters |
153
123
 
154
124
  ```js
155
125
  import { getRouteUri } from '@soleil-se/webapp-util';
156
126
 
157
127
  console.log(getRouteUri('/items'));
158
- // URI structure: /appresource/<pageId>/<portletId>/items
128
+ // URI structure: /appresource/{pageId}/{portletId}>/items
159
129
  ```
160
130
 
161
- <a name="getViewUri"></a>
162
-
163
- ### getViewUri(route) ⇒ `String`
164
-
165
- Get URI for a view.
166
-
167
- **Returns**: `String` - URI for view.
168
-
169
- | Param | Type | Description |
170
- | --- | --- | --- |
171
- | route | `String` | A route. |
172
-
173
131
  ```js
174
- import { getViewUri } from '@soleil-se/webapp-util';
132
+ import { getRouteUri } from '@soleil-se/webapp-util';
175
133
 
176
- console.log(getViewUri('/items'));
177
- // URI structure: ?sv.target=<id>&sv.<id>.route=/items
134
+ console.log(getRouteUri('/items', { foo: 'bar' }));
135
+ // URI structure: /appresource/{pageId}/{portletId}>/items?foo=bar
178
136
  ```
179
137
 
180
- <a name="getResourceUri"></a>
181
-
182
138
  ### getResourceUri(resource) ⇒ `String`
183
139
 
184
140
  Get URI for a resource.
@@ -196,8 +152,6 @@ console.log(getResourceUri('/image.png'));
196
152
  // URI structure: /webapp-files/<webappname>/<webappversion>/image.png
197
153
  ```
198
154
 
199
- <a name="getAppProps"></a>
200
-
201
155
  ### getAppProps([key]) ⇒ `*` | `Object`
202
156
 
203
157
  Get props that are passed to app when rendering.
@@ -217,7 +171,45 @@ const myValue = getAppProps('myValue');
217
171
  const { myValue } = getAppProps();
218
172
  ```
219
173
 
174
+ ### stringifyParams(params [, options]) ⇒ `String`
175
+
176
+ Stringify an object to a query string compatible with Sitevision.
177
+
178
+ **Returns**: `String` - Stringified parameters.
179
+
180
+ | Param | Type | Default | Description |
181
+ | --- | --- | --- | --- |
182
+ | params | `Object` | | Object with parameters to stringify. |
183
+ | [options] | `Object` | `{}` | Settings object. |
184
+ | [options.addQueryPrefix] | `Boolean` | `false` | If a leading `?` should be added to the string. |
185
+
186
+ ```js
187
+ import { stringifyParams } from '@soleil-se/webapp-util';
188
+
189
+ const queryString = stringifyParams({ foo: 'bar', num: 1 });
190
+ // foo=bar&num=1
191
+
192
+ const queryString = stringifyParams({ foo: 'bar', num: 1 }, { addQueryPrefix: true });
193
+ // ?foo=bar&num=1
194
+ ```
195
+
196
+ ### parseParams(url) ⇒ `Object`
197
+
198
+ Parse an URL, URI or query string to an object containing its query parameters.
199
+
200
+ **Returns**: `Object` - Parsed parameters.
201
+
202
+ | Param | Type | Default | Description |
203
+ | --- | --- | --- | --- |
204
+ | url | `String` | | URL, URI or query string to be parsed, must start with or contain "?" |
205
+
206
+ ```js
207
+ import { parseParams } from '@soleil-se/webapp-util';
208
+
209
+ const params = parseParams('?foo=bar&arr[]=1&arr[]=2');
210
+ // { foo: 'bar', arr: [1, 2] }
211
+ ```
212
+
220
213
  ## Rendering
221
214
 
222
215
  * [Svelte](./docs/1.svelte.md)
223
- * [Vue (DEPRECATED)](./docs/2.vue.md)
package/common/index.js CHANGED
@@ -1,14 +1,21 @@
1
- /* global document */
1
+ /* global document console */
2
2
  /* eslint-disable global-require */
3
-
4
3
  import router from '@sitevision/api/common/router';
5
4
  import app from '@sitevision/api/common/app';
6
5
 
6
+ import getLegacyRouteUri from './legacy/getRouteUri';
7
+
7
8
  /**
8
9
  * Get an ID for the app.
9
10
  * @return {String} ID
10
11
  */
11
- const getAppId = () => app.portletId.replace('.', '_');
12
+ const getAppId = () => {
13
+ const id = (process.server
14
+ ? require('PortletContextUtil')?.getCurrentPortlet()?.getIdentifier()
15
+ : app?.portletId) || 'preview';
16
+
17
+ return id.replace('.', '_');
18
+ };
12
19
 
13
20
  /**
14
21
  * Regex for selecting leading slashes
@@ -51,24 +58,88 @@ export function getNamespace(prefix = 'app') {
51
58
  return `${prefix}_${appId}`;
52
59
  }
53
60
 
61
+ /**
62
+ * Stringify an object to a query string compatible with Sitevision.
63
+ * @param {Object} params Object with parameters to stringify.
64
+ * @param {Object} [options] Optional options.
65
+ * @param {Boolean} [options.addQueryPrefix = false] If a leading ? should be added to the string.
66
+ * @returns Stringified parameters.
67
+ */
68
+ export function stringifyParams(params = {}, { addQueryPrefix = false } = {}) {
69
+ const qs = Object.keys(params).map((key) => {
70
+ const value = params[key];
71
+ if (!value) return undefined;
72
+ if (Array.isArray(value)) {
73
+ return value.map((v) => `${encodeURIComponent(`${key}[]`)}=${encodeURIComponent(v)}`).join('&');
74
+ }
75
+ return `${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
76
+ }).filter((value) => !!value).join('&');
77
+
78
+ if (!qs) return '';
79
+ return addQueryPrefix ? `?${qs}` : qs;
80
+ }
81
+
82
+ /**
83
+ * Parse an URL or URI to an object containing its query parameters.
84
+ * @param {String} url URL or URI to be parsed, must start with or contain "?".
85
+ * @returns Object with parsed parameters.
86
+ */
87
+ export default function parseParams(url = '') {
88
+ const hasQuestion = url.indexOf('?') > -1;
89
+ if (!hasQuestion) return {};
90
+
91
+ let query = url.split('?')[1];
92
+ const hasHash = url.indexOf('#') > -1;
93
+ query = hasHash ? url.split('#')[0] : query;
94
+
95
+ return query.split('&').reduce((params, part) => {
96
+ let [key, value] = part.split('+').join(' ').split('=');
97
+ key = decodeURIComponent(key);
98
+ value = decodeURIComponent(value);
99
+
100
+ const isArray = key.endsWith('[]');
101
+ if (isArray) {
102
+ key = key.replace('[]', '');
103
+ value = params[key] ? [...params[key], value] : [value];
104
+ }
105
+
106
+ return {
107
+ ...params,
108
+ [key]: value,
109
+ };
110
+ }, {});
111
+ }
112
+
54
113
  /**
55
114
  * Get URI for a route, same as `getStandaloneUrl` in Sitevision router.
56
115
  * @param {string} route A route.
57
- * @param {object} query Query parameters.
116
+ * @param {object} params Query parameters.
58
117
  * @returns {string} URI for route.
59
118
  */
60
- export function getRouteUri(route = '', query) {
119
+ export function getRouteUri(route = '', params) {
61
120
  const path = route.replace(leadingSlashes, '');
62
- return router.getStandaloneUrl(path !== '' ? `/${path}` : path, query).replace(trailingSlashes, '');
121
+ const qs = stringifyParams(params, { addQueryPrefix: true });
122
+ if (router?.getStandaloneUrl) {
123
+ return router.getStandaloneUrl((path !== '' ? `/${path}` : path).replace(trailingSlashes, '')) + qs;
124
+ }
125
+ /* Import of @sitevision/api/common/router is not avaliable in hooks, need to build the route URI
126
+ * manually instead of using router.getStandaloneUri */
127
+ return getLegacyRouteUri(path).replace(trailingSlashes, '') + qs;
63
128
  }
64
129
 
65
130
  /**
66
131
  * Get URI for a view, same as `getUrl` in Sitevision router.
132
+ * @deprecated Not used in WebApps 2.
67
133
  * @param {string} route A route.
68
134
  * @returns {string} URI for view.
69
135
  */
70
- export function getViewUri(route = '') {
71
- return router.getUrl(route);
136
+ export function getViewUri(route = '', query) {
137
+ if (!router?.getUrl) {
138
+ console.warn('[@soleil-api/webapp-util] getViewUri requires router.getUrl support.');
139
+ return undefined;
140
+ }
141
+
142
+ return router.getUrl(route, query);
72
143
  }
73
144
 
74
145
  /**
@@ -77,9 +148,17 @@ export function getViewUri(route = '') {
77
148
  * @returns {string} URI for a resource.
78
149
  */
79
150
  export function getResourceUri(resource = '') {
80
- const { webAppId, webAppVersion } = app;
151
+ let id;
152
+ let version;
153
+
154
+ if (process.server) {
155
+ ({ appIdentifier: id, appVersion: version } = require('appInfo'));
156
+ } else {
157
+ ({ webAppId: id, webAppVersion: version } = app);
158
+ }
159
+
81
160
  const path = resource.replace(leadingSlashes, '');
82
- return `/webapp-files/${webAppId}/${webAppVersion}/${path}`;
161
+ return `/webapp-files/${id}/${version}/${path}`;
83
162
  }
84
163
 
85
164
  let appProps = {};
@@ -0,0 +1,12 @@
1
+ /* eslint-disable global-require */
2
+ export default function getRouteUri(route) {
3
+ const PortletContextUtil = require('PortletContextUtil');
4
+ const currentPage = PortletContextUtil.getCurrentPage();
5
+ const currentPortlet = PortletContextUtil.getCurrentPortlet();
6
+ if (currentPage && currentPortlet) {
7
+ const currentPageId = currentPage.getIdentifier().replace('_sitePage', '');
8
+ const currentPortletId = currentPortlet.getIdentifier();
9
+ return `/appresource/${currentPageId}/${currentPortletId}/${route}`;
10
+ }
11
+ return '/';
12
+ }
package/package.json CHANGED
@@ -1,13 +1,9 @@
1
1
  {
2
2
  "name": "@soleil-se/app-util",
3
- "version": "5.0.0",
3
+ "version": "5.2.0",
4
4
  "description": "Utility and rendering functions for WebApps.",
5
5
  "main": "./common/index.js",
6
6
  "author": "Soleil AB",
7
- "contributors": [
8
- "Kimmy Monassar",
9
- "Jonas Gällman"
10
- ],
11
7
  "license": "UNLICENSED",
12
8
  "private": false,
13
9
  "homepage": "https://docs.soleilit.se/03.packages/@soleil-api&app-util",
@@ -18,5 +14,6 @@
18
14
  "peerDependencies": {
19
15
  "@sitevision/api": "^1.0.10"
20
16
  },
17
+ "gitHead": "903884ec52e502707ab62483d5f01b739a8f33c9",
21
18
  "dependencies": {}
22
19
  }