@appsemble/utils 0.28.2 → 0.28.4

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 CHANGED
@@ -1,9 +1,9 @@
1
- # ![](https://gitlab.com/appsemble/appsemble/-/raw/0.28.2/config/assets/logo.svg) Appsemble Utilities
1
+ # ![](https://gitlab.com/appsemble/appsemble/-/raw/0.28.4/config/assets/logo.svg) Appsemble Utilities
2
2
 
3
3
  > Internal utility functions used across multiple Appsemble projects.
4
4
 
5
5
  [![npm](https://img.shields.io/npm/v/@appsemble/utils)](https://www.npmjs.com/package/@appsemble/utils)
6
- [![GitLab CI](https://gitlab.com/appsemble/appsemble/badges/0.28.2/pipeline.svg)](https://gitlab.com/appsemble/appsemble/-/releases/0.28.2)
6
+ [![GitLab CI](https://gitlab.com/appsemble/appsemble/badges/0.28.4/pipeline.svg)](https://gitlab.com/appsemble/appsemble/-/releases/0.28.4)
7
7
  [![Prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg)](https://prettier.io)
8
8
 
9
9
  ## Table of Contents
@@ -26,5 +26,5 @@ not guaranteed.
26
26
 
27
27
  ## License
28
28
 
29
- [LGPL-3.0-only](https://gitlab.com/appsemble/appsemble/-/blob/0.28.2/LICENSE.md) ©
29
+ [LGPL-3.0-only](https://gitlab.com/appsemble/appsemble/-/blob/0.28.4/LICENSE.md) ©
30
30
  [Appsemble](https://appsemble.com)
@@ -19,7 +19,8 @@ This value will be generated automatically by the API.
19
19
  path: {
20
20
  type: 'string',
21
21
  minLength: 1,
22
- maxLength: 30,
22
+ // Max app name size + appended random data by [`setAppPath`](./packages/server/utils/app.ts)
23
+ maxLength: 41,
23
24
  pattern: normalized.source,
24
25
  description: `The URL path segment on which this app is reachable.
25
26
 
@@ -10,6 +10,21 @@ export const SubPage = {
10
10
  minLength: 1,
11
11
  maxLength: 50,
12
12
  },
13
+ roles: {
14
+ type: 'array',
15
+ description: `The list of roles that are allowed to view this page.
16
+
17
+ If the user doesn’t have any of the roles in the list the page will be unavailable to them. An empty
18
+ list can be used to specify that users need to log in but do not need a specific role.
19
+
20
+ Users trying to visit a page without having the correct roles will be redirected to the first page
21
+ that they are allowed to view. If there aren’t any accessible pages, the user will be logged out and
22
+ instructed to contact the app owner to get permissions.
23
+ `,
24
+ items: {
25
+ type: 'string',
26
+ },
27
+ },
13
28
  blocks: {
14
29
  type: 'array',
15
30
  minItems: 1,
package/api/paths/apps.js CHANGED
@@ -162,6 +162,7 @@ export const paths = {
162
162
  $ref: '#/components/responses/app',
163
163
  },
164
164
  },
165
+ security: [{ studio: [] }, {}],
165
166
  },
166
167
  },
167
168
  '/api/apps/{appId}': {
package/examples.js CHANGED
@@ -44,6 +44,9 @@ export const examples = {
44
44
  length: {
45
45
  array: 'length',
46
46
  },
47
+ item: {
48
+ array: 'item',
49
+ },
47
50
  },
48
51
  },
49
52
  },
@@ -51,14 +54,17 @@ export const examples = {
51
54
  {
52
55
  index: 0,
53
56
  length: 3,
57
+ item: 'a',
54
58
  },
55
59
  {
56
60
  index: 1,
57
61
  length: 3,
62
+ item: 'b',
58
63
  },
59
64
  {
60
65
  index: 2,
61
66
  length: 3,
67
+ item: 'c',
62
68
  },
63
69
  ],
64
70
  },
@@ -281,8 +287,14 @@ export const examples = {
281
287
  },
282
288
  variable: {
283
289
  input: null,
284
- remapper: {},
285
- result: {},
290
+ remapper: { variable: 'MY_VARIABLE' },
291
+ result: 'variable value',
292
+ skip: true,
293
+ },
294
+ 'number.parse': {
295
+ input: '42',
296
+ remapper: { 'number.parse': null },
297
+ result: 42,
286
298
  skip: true,
287
299
  },
288
300
  'date.add': {
@@ -655,7 +667,7 @@ export function schemaExample(remapper, options) {
655
667
  export function createExampleContext(url, lang, userInfo, history) {
656
668
  return {
657
669
  getMessage: ({ defaultMessage }) => new IntlMessageFormat(defaultMessage, lang, undefined),
658
- getVariable: () => null,
670
+ getVariable: (name) => (name === 'MY_VARIABLE' ? 'variable value' : null),
659
671
  url: String(url),
660
672
  appUrl: `${url.protocol}//example-app.example-organization.${url.host}`,
661
673
  userInfo: userInfo !== null && userInfo !== void 0 ? userInfo : {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@appsemble/utils",
3
- "version": "0.28.2",
3
+ "version": "0.28.4",
4
4
  "description": "Utility functions used in Appsemble internally",
5
5
  "keywords": [
6
6
  "app",
@@ -37,7 +37,7 @@
37
37
  "test": "vitest"
38
38
  },
39
39
  "dependencies": {
40
- "@appsemble/types": "0.28.2",
40
+ "@appsemble/types": "0.28.4",
41
41
  "axios": "^1.0.0",
42
42
  "cron-parser": "^4.0.0",
43
43
  "date-fns": "^2.0.0",
@@ -1,7 +1,13 @@
1
+ import { schemaExample } from '../../examples.js';
1
2
  export const configRemappers = {
2
3
  variable: {
3
4
  type: 'string',
4
- description: 'Get a predefined app variable by name',
5
+ description: `Get a predefined app variable by name
6
+
7
+ For example:
8
+
9
+ ${schemaExample('variable', { exclude: ['input'] })}
10
+ `,
5
11
  },
6
12
  };
7
13
  //# sourceMappingURL=config.js.map
@@ -1,8 +1,8 @@
1
1
  import { schemaExample } from '../../examples.js';
2
2
  export const dataRemappers = {
3
3
  array: {
4
- enum: ['index', 'length'],
5
- description: `Get the current array.map’s index or length.
4
+ enum: ['index', 'length', 'item'],
5
+ description: `Get the current array.map’s index, length or the current item.
6
6
 
7
7
  Returns nothing when not in the context of \`array.map’s\`.
8
8
 
@@ -8,3 +8,4 @@ export * from './randoms.js';
8
8
  export * from './strings.js';
9
9
  export * from './unsorted.js';
10
10
  export * from './config.js';
11
+ export * from './numbers.js';
@@ -8,4 +8,5 @@ export * from './randoms.js';
8
8
  export * from './strings.js';
9
9
  export * from './unsorted.js';
10
10
  export * from './config.js';
11
+ export * from './numbers.js';
11
12
  //# sourceMappingURL=index.js.map
@@ -0,0 +1,2 @@
1
+ import { type OpenAPIV3 } from 'openapi-types';
2
+ export declare const numberRemappers: Record<string, OpenAPIV3.ReferenceObject | OpenAPIV3.SchemaObject>;
@@ -0,0 +1,30 @@
1
+ import { schemaExample } from '../../examples.js';
2
+ export const numberRemappers = {
3
+ 'number.parse': {
4
+ anyOf: [
5
+ { enum: [null] },
6
+ { type: 'string' },
7
+ { $ref: '#/components/schemas/ArrayRemapperDefinition' },
8
+ { $ref: '#/components/schemas/ObjectRemapperDefinition' },
9
+ ],
10
+ description: `Convert a string into a number.
11
+
12
+ If there is no remapper passed and the input can be converted, this will return the converted input.
13
+
14
+ If there is no remapper passed and the input is null, this will return 0.
15
+
16
+ If there is no remapper passed and the input cannot be converted, this will return the input.
17
+
18
+ If there is a remapper passed and the remapped value can be converted, this will return the converted remapped value.
19
+
20
+ If there is a remapper passed and the remapped value is null, this will return 0.
21
+
22
+ If there is a remapper passed and the remapped value cannot be converted, this will return the remapped value.
23
+
24
+ For example:
25
+
26
+ ${schemaExample('number.parse')}
27
+ `,
28
+ },
29
+ };
30
+ //# sourceMappingURL=numbers.js.map
package/remap.d.ts CHANGED
@@ -63,6 +63,7 @@ interface InternalContext extends RemapperContext {
63
63
  array?: {
64
64
  index: number;
65
65
  length: number;
66
+ item: unknown;
66
67
  };
67
68
  stepRef?: {
68
69
  current: Record<string, any>;
package/remap.js CHANGED
@@ -195,16 +195,19 @@ const mapperImplementations = {
195
195
  var _a;
196
196
  return (_a = input === null || input === void 0 ? void 0 : input.map((item, index) => remap(mapper, item, {
197
197
  ...context,
198
- array: { index, length: input.length },
198
+ array: { index, length: input.length, item },
199
199
  }))) !== null && _a !== void 0 ? _a : [];
200
200
  },
201
201
  'array.unique'(mapper, input, context) {
202
202
  if (!Array.isArray(input)) {
203
203
  return input;
204
204
  }
205
- const remapped = input.map((value, index) => mapper == null
206
- ? value
207
- : remap(mapper, value, { ...context, array: { index, length: input.length } }));
205
+ const remapped = input.map((item, index) => mapper == null
206
+ ? item
207
+ : remap(mapper, item, {
208
+ ...context,
209
+ array: { index, length: input.length, item },
210
+ }));
208
211
  return input.filter((value, index) => {
209
212
  for (let i = 0; i < index; i += 1) {
210
213
  if (equal(remapped[index], remapped[i])) {
@@ -287,6 +290,21 @@ const mapperImplementations = {
287
290
  }
288
291
  return result;
289
292
  },
293
+ 'number.parse'(remapper, input, context) {
294
+ if (!remapper) {
295
+ const inputConverted = Number(input);
296
+ if (!Number.isNaN(inputConverted)) {
297
+ return inputConverted;
298
+ }
299
+ return input;
300
+ }
301
+ const remapped = remap(remapper, input, context);
302
+ const remappedConverted = Number(remapped);
303
+ if (!Number.isNaN(remappedConverted)) {
304
+ return remappedConverted;
305
+ }
306
+ return remapped;
307
+ },
290
308
  'date.parse': (fmt, input) => (fmt ? parse(input, fmt, new Date()) : parseISO(input)),
291
309
  'date.now': () => new Date(),
292
310
  'date.add'(time, input) {
package/remap.test.js CHANGED
@@ -137,6 +137,50 @@ describe('variable', () => {
137
137
  },
138
138
  });
139
139
  });
140
+ describe('number.parse', () => {
141
+ runTests({
142
+ 'return the parsed number': {
143
+ input: '42',
144
+ mappers: { 'number.parse': null },
145
+ expected: 42,
146
+ },
147
+ 'return the parsed decimal number': {
148
+ input: '42.5',
149
+ mappers: { 'number.parse': null },
150
+ expected: 42.5,
151
+ },
152
+ 'return 0 if there is no input': {
153
+ input: null,
154
+ mappers: { 'number.parse': null },
155
+ expected: 0,
156
+ },
157
+ 'return the input if it can not be converted': {
158
+ input: 'test',
159
+ mappers: { 'number.parse': null },
160
+ expected: 'test',
161
+ },
162
+ 'return the parsed integer from a remapper': {
163
+ input: { number: '42' },
164
+ mappers: { 'number.parse': { prop: 'number' } },
165
+ expected: 42,
166
+ },
167
+ 'return the parsed decimal from a remapper': {
168
+ input: { number: '42.5' },
169
+ mappers: { 'number.parse': { prop: 'number' } },
170
+ expected: 42.5,
171
+ },
172
+ 'return 0 if the remapped value is null': {
173
+ input: { number: null },
174
+ mappers: { 'number.parse': { prop: 'number' } },
175
+ expected: 0,
176
+ },
177
+ 'return the remapped value if it can not be parsed': {
178
+ input: { number: 'test' },
179
+ mappers: { 'number.parse': { prop: 'number' } },
180
+ expected: 'test',
181
+ },
182
+ });
183
+ });
140
184
  describe('date.now', () => {
141
185
  beforeEach(() => {
142
186
  vi.useFakeTimers({ now: 0 });
@@ -756,12 +800,13 @@ describe('array', () => {
756
800
  'object.from': {
757
801
  index: [{ array: 'index' }],
758
802
  length: [{ array: 'length' }],
803
+ item: [{ array: 'item' }],
759
804
  },
760
805
  },
761
806
  ],
762
- expected: { index: undefined, length: undefined },
807
+ expected: { index: undefined, length: undefined, item: undefined },
763
808
  },
764
- 'return the index and length if in the context of array.map': {
809
+ 'return the index, length and item if in the context of array.map': {
765
810
  input: { array: [{ value: 'a' }, { value: 'b' }, { value: 'c' }] },
766
811
  mappers: [
767
812
  { prop: 'array' },
@@ -772,15 +817,16 @@ describe('array', () => {
772
817
  value: [{ prop: 'value' }],
773
818
  index: [{ array: 'index' }],
774
819
  length: [{ array: 'length' }],
820
+ item: [{ array: 'item' }],
775
821
  },
776
822
  },
777
823
  ],
778
824
  },
779
825
  ],
780
826
  expected: [
781
- { value: 'a', index: 0, length: 3 },
782
- { value: 'b', index: 1, length: 3 },
783
- { value: 'c', index: 2, length: 3 },
827
+ { value: 'a', index: 0, length: 3, item: { value: 'a' } },
828
+ { value: 'b', index: 1, length: 3, item: { value: 'b' } },
829
+ { value: 'c', index: 2, length: 3, item: { value: 'c' } },
784
830
  ],
785
831
  },
786
832
  });