@appsemble/utils 0.28.9 → 0.28.11
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 +3 -3
- package/api/components/schemas/SubPage.js +1 -3
- package/api/components/schemas/TabsPageActionsDefinition.d.ts +2 -0
- package/api/components/schemas/TabsPageActionsDefinition.js +12 -0
- package/api/components/schemas/TabsPageDefinition.js +25 -1
- package/api/components/schemas/index.d.ts +1 -0
- package/api/components/schemas/index.js +1 -0
- package/api/index.test.js +5 -1
- package/appMessages.js +5 -3
- package/examples.js +6 -0
- package/iterApp.js +8 -1
- package/package.json +2 -2
- package/reference-schemas/remappers/data.js +24 -0
- package/remap.d.ts +3 -0
- package/remap.js +3 -0
- package/validation.js +16 -1
package/README.md
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
#  Appsemble Utilities
|
|
2
2
|
|
|
3
3
|
> Internal utility functions used across multiple Appsemble projects.
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/@appsemble/utils)
|
|
6
|
-
[](https://gitlab.com/appsemble/appsemble/-/releases/0.28.11)
|
|
7
7
|
[](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.
|
|
29
|
+
[LGPL-3.0-only](https://gitlab.com/appsemble/appsemble/-/blob/0.28.11/LICENSE.md) ©
|
|
30
30
|
[Appsemble](https://appsemble.com)
|
|
@@ -5,10 +5,8 @@ export const SubPage = {
|
|
|
5
5
|
additionalProperties: false,
|
|
6
6
|
properties: {
|
|
7
7
|
name: {
|
|
8
|
-
|
|
8
|
+
$ref: '#/components/schemas/RemapperDefinition',
|
|
9
9
|
description: 'The name of the sub page.',
|
|
10
|
-
minLength: 1,
|
|
11
|
-
maxLength: 50,
|
|
12
10
|
},
|
|
13
11
|
roles: {
|
|
14
12
|
type: 'array',
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export const TabsPageActionsDefinition = {
|
|
2
|
+
type: 'object',
|
|
3
|
+
description: 'Action fired on page events',
|
|
4
|
+
additionalProperties: false,
|
|
5
|
+
properties: {
|
|
6
|
+
onLoad: {
|
|
7
|
+
$ref: '#/components/schemas/ActionDefinition',
|
|
8
|
+
description: '',
|
|
9
|
+
},
|
|
10
|
+
},
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=TabsPageActionsDefinition.js.map
|
|
@@ -3,7 +3,14 @@ import { extendJSONSchema } from './utils.js';
|
|
|
3
3
|
export const TabsPageDefinition = extendJSONSchema(BasePageDefinition, {
|
|
4
4
|
type: 'object',
|
|
5
5
|
description: 'This describes what a page will look like in the app.',
|
|
6
|
-
|
|
6
|
+
oneOf: [
|
|
7
|
+
{
|
|
8
|
+
required: ['type', 'tabs'],
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
required: ['type', 'definition'],
|
|
12
|
+
},
|
|
13
|
+
],
|
|
7
14
|
additionalProperties: true,
|
|
8
15
|
properties: {
|
|
9
16
|
type: {
|
|
@@ -17,6 +24,23 @@ export const TabsPageDefinition = extendJSONSchema(BasePageDefinition, {
|
|
|
17
24
|
$ref: '#/components/schemas/SubPage',
|
|
18
25
|
},
|
|
19
26
|
},
|
|
27
|
+
definition: {
|
|
28
|
+
type: 'object',
|
|
29
|
+
additionalProperties: false,
|
|
30
|
+
description: 'Generate tabs dynamically',
|
|
31
|
+
required: ['events', 'foreach'],
|
|
32
|
+
properties: {
|
|
33
|
+
events: {
|
|
34
|
+
$ref: '#/components/schemas/EventsDefinition',
|
|
35
|
+
},
|
|
36
|
+
foreach: {
|
|
37
|
+
$ref: '#/components/schemas/SubPage',
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
actions: {
|
|
42
|
+
$ref: '#/components/schemas/TabsPageActionsDefinition',
|
|
43
|
+
},
|
|
20
44
|
},
|
|
21
45
|
});
|
|
22
46
|
//# sourceMappingURL=TabsPageDefinition.js.map
|
|
@@ -129,5 +129,6 @@ export * from './UserQueryActionDefinition.js';
|
|
|
129
129
|
export * from './UserRemoveActionDefinition.js';
|
|
130
130
|
export * from './LoopPageDefinition.js';
|
|
131
131
|
export * from './LoopPageActionsDefinition.js';
|
|
132
|
+
export * from './TabsPageActionsDefinition.js';
|
|
132
133
|
export * from './UsersDefinition.js';
|
|
133
134
|
export * from './UserPropertyDefinition.js';
|
|
@@ -129,6 +129,7 @@ export * from './UserQueryActionDefinition.js';
|
|
|
129
129
|
export * from './UserRemoveActionDefinition.js';
|
|
130
130
|
export * from './LoopPageDefinition.js';
|
|
131
131
|
export * from './LoopPageActionsDefinition.js';
|
|
132
|
+
export * from './TabsPageActionsDefinition.js';
|
|
132
133
|
export * from './UsersDefinition.js';
|
|
133
134
|
export * from './UserPropertyDefinition.js';
|
|
134
135
|
//# sourceMappingURL=index.js.map
|
package/api/index.test.js
CHANGED
|
@@ -66,6 +66,7 @@ describe('schemas', () => {
|
|
|
66
66
|
it.each(entries.filter(([, schema]) => schema.type === 'object'))('%s', (path, schema) => {
|
|
67
67
|
// Action descriptions are defined on the type property.
|
|
68
68
|
const descriptionSchema = path.endsWith('ActionDefinition') ? schema.properties.type : schema;
|
|
69
|
+
const isTabsPageDefinition = path.endsWith('TabsPageDefinition');
|
|
69
70
|
expect(schema).not.toHaveProperty('additionalItems');
|
|
70
71
|
expect(schema).toHaveProperty('additionalProperties');
|
|
71
72
|
expect(schema).not.toHaveProperty('allOf');
|
|
@@ -85,7 +86,10 @@ describe('schemas', () => {
|
|
|
85
86
|
expect(schema).not.toHaveProperty('minItems');
|
|
86
87
|
expect(schema).not.toHaveProperty('minLength');
|
|
87
88
|
expect(schema).not.toHaveProperty('multipleOf');
|
|
88
|
-
|
|
89
|
+
if (!isTabsPageDefinition) {
|
|
90
|
+
// eslint-disable-next-line vitest/no-conditional-expect
|
|
91
|
+
expect(schema).not.toHaveProperty('oneOf');
|
|
92
|
+
}
|
|
89
93
|
expect(schema).not.toHaveProperty('then');
|
|
90
94
|
expect(schema).not.toHaveProperty('uniqueItems');
|
|
91
95
|
if (schema.required && !schema.additionalProperties) {
|
package/appMessages.js
CHANGED
|
@@ -93,14 +93,16 @@ export function extractAppMessages(app, onBlock) {
|
|
|
93
93
|
var _a, _b;
|
|
94
94
|
const prefix = `pages.${normalize(page.name)}`;
|
|
95
95
|
messages.app[prefix] = page.name;
|
|
96
|
-
if (page.type === 'tabs') {
|
|
96
|
+
if (page.type === 'tabs' && Array.isArray(page.tabs)) {
|
|
97
97
|
for (const [index, tab] of page.tabs.entries()) {
|
|
98
|
-
messages.app[`${prefix}.tabs.${index}`] =
|
|
98
|
+
messages.app[`${prefix}.tabs.${index}`] =
|
|
99
|
+
(_a = (typeof tab.name === 'string' ? tab.name : '')) !== null && _a !== void 0 ? _a : '';
|
|
99
100
|
}
|
|
100
101
|
}
|
|
101
102
|
if (page.type === 'flow') {
|
|
102
103
|
for (const [index, step] of page.steps.entries()) {
|
|
103
|
-
messages.app[`${prefix}.steps.${index}`] =
|
|
104
|
+
messages.app[`${prefix}.steps.${index}`] =
|
|
105
|
+
(_b = (typeof step.name === 'string' ? step.name : '')) !== null && _b !== void 0 ? _b : '';
|
|
104
106
|
}
|
|
105
107
|
}
|
|
106
108
|
if (page.type === 'loop') {
|
package/examples.js
CHANGED
package/iterApp.js
CHANGED
|
@@ -102,7 +102,14 @@ export function iterPage(page, callbacks, prefix = []) {
|
|
|
102
102
|
return (result ||
|
|
103
103
|
(page.type === 'flow'
|
|
104
104
|
? page.steps.some((step, index) => iterBlockList(step.blocks, callbacks, [...prefix, 'steps', index, 'blocks']))
|
|
105
|
-
: page.tabs
|
|
105
|
+
: page.tabs
|
|
106
|
+
? page.tabs.some((tab, index) => iterBlockList(tab.blocks, callbacks, [...prefix, 'tabs', index, 'blocks']))
|
|
107
|
+
: iterBlockList(page.definition.foreach.blocks, callbacks, [
|
|
108
|
+
...prefix,
|
|
109
|
+
'tabs',
|
|
110
|
+
0,
|
|
111
|
+
'blocks',
|
|
112
|
+
])));
|
|
106
113
|
}
|
|
107
114
|
if (page.type === 'loop') {
|
|
108
115
|
let result = false;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@appsemble/utils",
|
|
3
|
-
"version": "0.28.
|
|
3
|
+
"version": "0.28.11",
|
|
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.
|
|
40
|
+
"@appsemble/types": "0.28.11",
|
|
41
41
|
"axios": "^1.0.0",
|
|
42
42
|
"cron-parser": "^4.0.0",
|
|
43
43
|
"date-fns": "^2.0.0",
|
|
@@ -90,6 +90,30 @@ Result:
|
|
|
90
90
|
"title": "Most influential bands of all time",
|
|
91
91
|
"content": ...
|
|
92
92
|
}
|
|
93
|
+
\`\`\`
|
|
94
|
+
`,
|
|
95
|
+
},
|
|
96
|
+
'tab.name': {
|
|
97
|
+
enum: [null],
|
|
98
|
+
description: `
|
|
99
|
+
|
|
100
|
+
Returns the name of the current tab in a \`tabs\` page.
|
|
101
|
+
|
|
102
|
+
\`\`\`yaml
|
|
103
|
+
name: Example Page A
|
|
104
|
+
type: tabs
|
|
105
|
+
tabs:
|
|
106
|
+
- name: Tab2
|
|
107
|
+
blocks:
|
|
108
|
+
- type: action-button
|
|
109
|
+
version: "0.27.12"
|
|
110
|
+
parameters:
|
|
111
|
+
icon: chevron-right
|
|
112
|
+
actions:
|
|
113
|
+
onClick:
|
|
114
|
+
type: log
|
|
115
|
+
remapBefore:
|
|
116
|
+
{ tab.name: null }
|
|
93
117
|
\`\`\`
|
|
94
118
|
`,
|
|
95
119
|
},
|
package/remap.d.ts
CHANGED
|
@@ -68,6 +68,9 @@ interface InternalContext extends RemapperContext {
|
|
|
68
68
|
stepRef?: {
|
|
69
69
|
current: Record<string, any>;
|
|
70
70
|
};
|
|
71
|
+
tabRef?: {
|
|
72
|
+
current: Record<string, any>;
|
|
73
|
+
};
|
|
71
74
|
}
|
|
72
75
|
export declare function remap(remapper: Remapper, input: unknown, context: InternalContext | RemapperContext): unknown;
|
|
73
76
|
export {};
|
package/remap.js
CHANGED
|
@@ -107,6 +107,9 @@ const mapperImplementations = {
|
|
|
107
107
|
step(mapper, input, context) {
|
|
108
108
|
return context.stepRef.current[mapper];
|
|
109
109
|
},
|
|
110
|
+
'tab.name'(mapper, input, context) {
|
|
111
|
+
return context.tabRef.current.name;
|
|
112
|
+
},
|
|
110
113
|
gt: ([left, right], input, context) => remap(left, input, context) > remap(right, input, context),
|
|
111
114
|
lt: ([left, right], input, context) => remap(left, input, context) < remap(right, input, context),
|
|
112
115
|
ics(mappers, input, context) {
|
package/validation.js
CHANGED
|
@@ -619,7 +619,7 @@ function validateActions(definition, report) {
|
|
|
619
619
|
]);
|
|
620
620
|
return;
|
|
621
621
|
}
|
|
622
|
-
if (toPage.type === 'tabs' && toSub) {
|
|
622
|
+
if (toPage.type === 'tabs' && toSub && Array.isArray(toPage.tabs)) {
|
|
623
623
|
const subPage = toPage.tabs.find(({ name }) => name === toSub);
|
|
624
624
|
if (!subPage) {
|
|
625
625
|
report(toSub, 'refers to a tab that doesn’t exist', [...path, 'to', 1]);
|
|
@@ -705,6 +705,21 @@ function validateEvents(definition, blockVersions, report) {
|
|
|
705
705
|
collect([...path, 'waitFor'], action.waitFor, false);
|
|
706
706
|
}
|
|
707
707
|
},
|
|
708
|
+
onPage(page, path) {
|
|
709
|
+
if (!(page.type === 'tabs') || page.tabs) {
|
|
710
|
+
return;
|
|
711
|
+
}
|
|
712
|
+
if (page.definition.events.emit) {
|
|
713
|
+
for (const [prefix, name] of Object.entries(page.definition.events.emit)) {
|
|
714
|
+
collect([...path, 'events', 'emit', prefix], name, true);
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
if (page.definition.events.listen) {
|
|
718
|
+
for (const [prefix, name] of Object.entries(page.definition.events.listen)) {
|
|
719
|
+
collect([...path, 'events', 'listen', prefix], name, false);
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
},
|
|
708
723
|
onBlock(block, path) {
|
|
709
724
|
if (!block.events) {
|
|
710
725
|
return;
|