@appsemble/utils 0.32.2-test.7 → 0.32.3-test.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/README.md CHANGED
@@ -1,9 +1,9 @@
1
- # ![](https://gitlab.com/appsemble/appsemble/-/raw/0.32.2-test.7/config/assets/logo.svg) Appsemble Utilities
1
+ # ![](https://gitlab.com/appsemble/appsemble/-/raw/0.32.3-test.0/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.32.2-test.7/pipeline.svg)](https://gitlab.com/appsemble/appsemble/-/releases/0.32.2-test.7)
6
+ [![GitLab CI](https://gitlab.com/appsemble/appsemble/badges/0.32.3-test.0/pipeline.svg)](https://gitlab.com/appsemble/appsemble/-/releases/0.32.3-test.0)
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.32.2-test.7/LICENSE.md) ©
29
+ [LGPL-3.0-only](https://gitlab.com/appsemble/appsemble/-/blob/0.32.3-test.0/LICENSE.md) ©
30
30
  [Appsemble](https://appsemble.com)
@@ -28,6 +28,7 @@ export const ActionDefinition = {
28
28
  { $ref: '#/components/schemas/AnalyticsActionDefinition' },
29
29
  { $ref: '#/components/schemas/ControllerActionDefinition' },
30
30
  { $ref: '#/components/schemas/ConditionActionDefinition' },
31
+ { $ref: '#/components/schemas/CsvParseActionDefinition' },
31
32
  { $ref: '#/components/schemas/DialogActionDefinition' },
32
33
  { $ref: '#/components/schemas/DialogErrorActionDefinition' },
33
34
  { $ref: '#/components/schemas/DialogOkActionDefinition' },
@@ -0,0 +1 @@
1
+ export declare const CsvParseActionDefinition: import("openapi-types").OpenAPIV3.SchemaObject;
@@ -0,0 +1,22 @@
1
+ import { BaseActionDefinition } from './BaseActionDefinition.js';
2
+ import { extendJSONSchema } from './utils.js';
3
+ export const CsvParseActionDefinition = extendJSONSchema(BaseActionDefinition, {
4
+ type: 'object',
5
+ additionalProperties: false,
6
+ required: ['type', 'file'],
7
+ properties: {
8
+ type: {
9
+ description: 'An action to parse the CSV files',
10
+ enum: ['csv.parse'],
11
+ },
12
+ file: {
13
+ description: 'The CSV file to be parsed',
14
+ $ref: '#/components/schemas/RemapperDefinition',
15
+ },
16
+ delimiter: {
17
+ description: 'The delimiter to be used, defaults to comma(",")',
18
+ $ref: '#/components/schemas/RemapperDefinition',
19
+ },
20
+ },
21
+ });
22
+ //# sourceMappingURL=CsvParseActionDefinition.js.map
@@ -149,3 +149,4 @@ export * from './PageActionsDefinition.js';
149
149
  export * from './FilterParametersDefinition.js';
150
150
  export * from './WebhookDefinition.js';
151
151
  export * from './AppWebhookSecret.js';
152
+ export * from './CsvParseActionDefinition.js';
@@ -149,4 +149,5 @@ export * from './PageActionsDefinition.js';
149
149
  export * from './FilterParametersDefinition.js';
150
150
  export * from './WebhookDefinition.js';
151
151
  export * from './AppWebhookSecret.js';
152
+ export * from './CsvParseActionDefinition.js';
152
153
  //# sourceMappingURL=index.js.map
package/appMessages.js CHANGED
@@ -55,10 +55,13 @@ export function extractAppMessages(app, onBlock) {
55
55
  }
56
56
  },
57
57
  onAction(action) {
58
- Object.assign(messages.messageIds, findMessageIds(action.remap));
58
+ Object.assign(messages.messageIds, findMessageIds(action.remapBefore));
59
+ Object.assign(messages.messageIds, findMessageIds(action.remapAfter));
59
60
  switch (action.type) {
60
61
  case 'condition':
61
62
  Object.assign(messages.messageIds, findMessageIds(action.if));
63
+ Object.assign(messages.messageIds, findMessageIds(action.then));
64
+ Object.assign(messages.messageIds, findMessageIds(action.else));
62
65
  break;
63
66
  case 'dialog':
64
67
  Object.assign(messages.messageIds, findMessageIds(action.title));
package/examples.js CHANGED
@@ -85,6 +85,16 @@ export const examples = {
85
85
  },
86
86
  ],
87
87
  },
88
+ 'array.contains': {
89
+ input: [1, 2, 3, 4, 5],
90
+ remapper: { 'array.contains': { static: 6 } },
91
+ result: false,
92
+ },
93
+ 'string.contains': {
94
+ input: 'Input string',
95
+ remapper: { 'string.contains': 'string' },
96
+ result: true,
97
+ },
88
98
  len: {
89
99
  input: 'string',
90
100
  remapper: { len: null },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@appsemble/utils",
3
- "version": "0.32.2-test.7",
3
+ "version": "0.32.3-test.0",
4
4
  "description": "Utility functions used in Appsemble internally",
5
5
  "keywords": [
6
6
  "app",
@@ -39,7 +39,7 @@
39
39
  "test": "vitest"
40
40
  },
41
41
  "dependencies": {
42
- "@appsemble/types": "0.32.2-test.7",
42
+ "@appsemble/types": "0.32.3-test.0",
43
43
  "@odata/parser": "^0.2.14",
44
44
  "axios": "^1.0.0",
45
45
  "cron-parser": "^4.0.0",
@@ -1,6 +1,7 @@
1
1
  import { AnalyticsActionDefinition } from '../../api/components/schemas/AnalyticsActionDefinition.js';
2
2
  import { ConditionActionDefinition } from '../../api/components/schemas/ConditionActionDefinition.js';
3
3
  import { ControllerActionDefinition } from '../../api/components/schemas/ControllerActionDefinition.js';
4
+ import { CsvParseActionDefinition } from '../../api/components/schemas/CsvParseActionDefinition.js';
4
5
  import { DialogActionDefinition } from '../../api/components/schemas/DialogActionDefinition.js';
5
6
  import { DialogErrorActionDefinition } from '../../api/components/schemas/DialogErrorActionDefinition.js';
6
7
  import { DialogOkActionDefinition } from '../../api/components/schemas/DialogOkActionDefinition.js';
@@ -21,6 +22,7 @@ export const miscellaneousActions = {
21
22
  analytics: AnalyticsActionDefinition,
22
23
  condition: ConditionActionDefinition,
23
24
  controller: ControllerActionDefinition,
25
+ 'csv.parse': CsvParseActionDefinition,
24
26
  download: DownloadActionDefinition,
25
27
  dialog: DialogActionDefinition,
26
28
  'dialog.ok': DialogOkActionDefinition,
@@ -284,6 +284,13 @@ Flatten an array. Accepts an array of static or remapper values.
284
284
  Say for example that each person has some pets. We could get an array of all pets like so:
285
285
 
286
286
  ${schemaExample('array.flatten', { input: 'pretty', exclude: ['remapper'] })}
287
+ `,
288
+ },
289
+ 'array.contains': {
290
+ $ref: '#/components/schemas/RemapperDefinition',
291
+ description: `
292
+ Checks if the input array includes the provided item.
293
+ ${schemaExample('array.contains')}
287
294
  `,
288
295
  },
289
296
  };
@@ -288,7 +288,7 @@ ${schemaExample('static', { exclude: ['input'] })}
288
288
  `,
289
289
  },
290
290
  translate: {
291
- type: 'string',
291
+ $ref: '#/components/schemas/RemapperDefinition',
292
292
  description: `> **Note:** This is explained much more in depth at [Translating](/docs/guides/translating)
293
293
 
294
294
  This remapper allows you to easily add translations to your app. To make this remapper work, replace
@@ -80,6 +80,13 @@ ${schemaExample('string.format')}
80
80
  Uses RegEx to find a value in a string and replace it with a given value.
81
81
 
82
82
  ${schemaExample('string.replace')}
83
+ `,
84
+ },
85
+ 'string.contains': {
86
+ type: 'string',
87
+ description: `
88
+ Checks if the provided string is a substring of the input string.
89
+ ${schemaExample('string.contains')}
83
90
  `,
84
91
  },
85
92
  };
package/remap.js CHANGED
@@ -24,6 +24,14 @@ function isEqualArray(a, b) {
24
24
  }
25
25
  return a.every((val, i) => val === b[i]);
26
26
  }
27
+ function isEqualObject(a, b) {
28
+ const aKeys = Object.keys(a);
29
+ const bKeys = Object.keys(b);
30
+ if (aKeys.length !== bKeys.length) {
31
+ return false;
32
+ }
33
+ return aKeys.every((key) => bKeys.includes(key) && equal(a[key], b[key]));
34
+ }
27
35
  function isNumber(a) {
28
36
  return a !== undefined && a != null && a !== '' && !Number.isNaN(Number(a));
29
37
  }
@@ -299,6 +307,19 @@ const mapperImplementations = {
299
307
  nextItem: input[index + 1],
300
308
  },
301
309
  })) ?? [],
310
+ 'array.contains'(mapper, input, context) {
311
+ if (!Array.isArray(input)) {
312
+ return false;
313
+ }
314
+ const remapped = remap(mapper, input, context);
315
+ if (isPlainObject(remapped)) {
316
+ return input.some((item) => isEqualObject(item, remapped ?? {}));
317
+ }
318
+ if (Array.isArray(remapped)) {
319
+ return input.some((item) => isEqualArray(item, remapped));
320
+ }
321
+ return input.includes(remapped);
322
+ },
302
323
  'array.unique'(mapper, input, context) {
303
324
  if (!Array.isArray(input)) {
304
325
  return input;
@@ -528,6 +549,12 @@ const mapperImplementations = {
528
549
  }
529
550
  return input;
530
551
  },
552
+ 'string.contains'(stringToCheck, input) {
553
+ if (!(typeof input === 'string')) {
554
+ return false;
555
+ }
556
+ return input.includes(stringToCheck);
557
+ },
531
558
  // eslint-disable-next-line @typescript-eslint/prefer-ts-expect-error
532
559
  // @ts-ignore 2322 ... is not assignable to type (strictNullChecks)
533
560
  'string.startsWith'(substring, input) {
@@ -582,8 +609,12 @@ const mapperImplementations = {
582
609
  return String(input).replaceAll(new RegExp(regex, 'gm'), replacer);
583
610
  },
584
611
  translate(messageId, input, context) {
585
- const message = context.getMessage({ id: messageId });
586
- return message.format() || `{${messageId}}`;
612
+ const remappedId = remap(messageId, input, context);
613
+ if (typeof remappedId !== 'string') {
614
+ return null;
615
+ }
616
+ const message = context.getMessage({ id: remappedId });
617
+ return message.format() || `{${remappedId}}`;
587
618
  },
588
619
  'app.member': (property, input, context) => context.appMemberInfo?.[property],
589
620
  container(property, input, context) {
@@ -29,8 +29,11 @@ export function validateMessages(messages, app) {
29
29
  }
30
30
  if (messages.app) {
31
31
  Object.keys(messages.app).map((key) => {
32
- const match = /^(pages\.[\dA-Za-z-]+(\..+)?)\.blocks\.\d+.+/.exec(key);
33
- if ((!has(extractedMessages?.app, key) || typeof messages.app[key] !== 'string') && !match) {
32
+ const blockMatch = /^(pages\.[\dA-Za-z-]+(\..+)?)\.blocks\.\d+.+/.exec(key);
33
+ const emailMatch = /emails\.(appInvite|appMemberEmailChange|emailAdded|groupInvite|resend|reset|welcome)\.(body|subject)/.exec(key);
34
+ if ((!has(extractedMessages?.app, key) || typeof messages.app[key] !== 'string') &&
35
+ !blockMatch &&
36
+ !emailMatch) {
34
37
  throw new AppMessageValidationError(`Invalid key ${key}`);
35
38
  }
36
39
  });