@appsemble/utils 0.27.11 → 0.28.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 +3 -3
- package/api/components/parameters/appPath.d.ts +2 -0
- package/api/components/parameters/appPath.js +8 -0
- package/api/components/parameters/appVariableId.d.ts +2 -0
- package/api/components/parameters/appVariableId.js +8 -0
- package/api/components/parameters/index.d.ts +2 -0
- package/api/components/parameters/index.js +2 -0
- package/api/components/schemas/AppVariable.d.ts +2 -0
- package/api/components/schemas/AppVariable.js +22 -0
- package/api/components/schemas/index.d.ts +1 -0
- package/api/components/schemas/index.js +1 -0
- package/api/paths/appOAuth2Secrets.js +11 -1
- package/api/paths/appSSLSecrets.js +1 -1
- package/api/paths/appSamlSecrets.js +11 -1
- package/api/paths/appScimSecrets.js +1 -1
- package/api/paths/appServiceSecrets.js +12 -2
- package/api/paths/appVariables.d.ts +2 -0
- package/api/paths/appVariables.js +93 -0
- package/api/paths/apps.js +23 -1
- package/api/paths/index.js +2 -0
- package/api/paths/templates.js +8 -0
- package/examples.js +7 -0
- package/package.json +2 -2
- package/reference-schemas/remappers/config.d.ts +2 -0
- package/reference-schemas/remappers/config.js +7 -0
- package/reference-schemas/remappers/data.js +6 -0
- package/reference-schemas/remappers/dates.js +6 -1
- package/reference-schemas/remappers/index.d.ts +1 -0
- package/reference-schemas/remappers/index.js +1 -0
- package/remap.d.ts +6 -1
- package/remap.js +42 -4
- package/remap.test.js +38 -2
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.0)
|
|
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.
|
|
29
|
+
[LGPL-3.0-only](https://gitlab.com/appsemble/appsemble/-/blob/0.28.0/LICENSE.md) ©
|
|
30
30
|
[Appsemble](https://appsemble.com)
|
|
@@ -5,6 +5,7 @@ export * from './$team.js';
|
|
|
5
5
|
export * from './$top.js';
|
|
6
6
|
export * from './$skip.js';
|
|
7
7
|
export * from './appId.js';
|
|
8
|
+
export * from './appPath.js';
|
|
8
9
|
export * from './appOAuth2SecretId.js';
|
|
9
10
|
export * from './appSamlSecretId.js';
|
|
10
11
|
export * from './assetId.js';
|
|
@@ -18,6 +19,7 @@ export * from './resourceType.js';
|
|
|
18
19
|
export * from './screenshotId.js';
|
|
19
20
|
export * from './readmeId.js';
|
|
20
21
|
export * from './appServiceId.js';
|
|
22
|
+
export * from './appVariableId.js';
|
|
21
23
|
export * from './view.js';
|
|
22
24
|
export * from './trainingId.js';
|
|
23
25
|
export * from './trainingBlockId.js';
|
|
@@ -5,6 +5,7 @@ export * from './$team.js';
|
|
|
5
5
|
export * from './$top.js';
|
|
6
6
|
export * from './$skip.js';
|
|
7
7
|
export * from './appId.js';
|
|
8
|
+
export * from './appPath.js';
|
|
8
9
|
export * from './appOAuth2SecretId.js';
|
|
9
10
|
export * from './appSamlSecretId.js';
|
|
10
11
|
export * from './assetId.js';
|
|
@@ -18,6 +19,7 @@ export * from './resourceType.js';
|
|
|
18
19
|
export * from './screenshotId.js';
|
|
19
20
|
export * from './readmeId.js';
|
|
20
21
|
export * from './appServiceId.js';
|
|
22
|
+
export * from './appVariableId.js';
|
|
21
23
|
export * from './view.js';
|
|
22
24
|
export * from './trainingId.js';
|
|
23
25
|
export * from './trainingBlockId.js';
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export const AppVariable = {
|
|
2
|
+
type: 'object',
|
|
3
|
+
description: 'App variable',
|
|
4
|
+
required: ['name'],
|
|
5
|
+
additionalProperties: false,
|
|
6
|
+
properties: {
|
|
7
|
+
id: {
|
|
8
|
+
type: 'number',
|
|
9
|
+
description: 'An autogenerated ID.',
|
|
10
|
+
readOnly: true,
|
|
11
|
+
},
|
|
12
|
+
name: {
|
|
13
|
+
type: 'string',
|
|
14
|
+
description: 'The name of the variable, that will be accessible from clients.',
|
|
15
|
+
},
|
|
16
|
+
value: {
|
|
17
|
+
description: 'The value of the variable.',
|
|
18
|
+
anyOf: [{ type: 'string' }, { type: 'boolean' }, { type: 'number' }],
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
};
|
|
22
|
+
//# sourceMappingURL=AppVariable.js.map
|
|
@@ -12,6 +12,7 @@ export * from './AppMessages.js';
|
|
|
12
12
|
export * from './AppOAuth2Secret.js';
|
|
13
13
|
export * from './AppsembleMessages.js';
|
|
14
14
|
export * from './AppServiceSecret.js';
|
|
15
|
+
export * from './AppVariable.js';
|
|
15
16
|
export * from './ArrayRemapperDefinition.js';
|
|
16
17
|
export * from './Asset.js';
|
|
17
18
|
export * from './BlockDefinition.js';
|
|
@@ -12,6 +12,7 @@ export * from './AppMessages.js';
|
|
|
12
12
|
export * from './AppOAuth2Secret.js';
|
|
13
13
|
export * from './AppsembleMessages.js';
|
|
14
14
|
export * from './AppServiceSecret.js';
|
|
15
|
+
export * from './AppVariable.js';
|
|
15
16
|
export * from './ArrayRemapperDefinition.js';
|
|
16
17
|
export * from './Asset.js';
|
|
17
18
|
export * from './BlockDefinition.js';
|
|
@@ -11,7 +11,7 @@ export const paths = {
|
|
|
11
11
|
},
|
|
12
12
|
},
|
|
13
13
|
},
|
|
14
|
-
security: [{ studio: [] }],
|
|
14
|
+
security: [{ studio: [] }, { cli: ['apps:write'] }],
|
|
15
15
|
responses: {
|
|
16
16
|
201: {
|
|
17
17
|
description: 'A list of the OAuth2 secrets for the app.',
|
|
@@ -41,6 +41,16 @@ export const paths = {
|
|
|
41
41
|
},
|
|
42
42
|
},
|
|
43
43
|
},
|
|
44
|
+
delete: {
|
|
45
|
+
tags: ['secret'],
|
|
46
|
+
operationId: 'deleteAppOAuth2Secrets',
|
|
47
|
+
security: [{ studio: [] }, { cli: ['apps:write'] }],
|
|
48
|
+
responses: {
|
|
49
|
+
204: {
|
|
50
|
+
description: 'The deleted app OAuth2 secrets.',
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
},
|
|
44
54
|
},
|
|
45
55
|
'/api/apps/{appId}/secrets/oauth2/{appOAuth2SecretId}': {
|
|
46
56
|
parameters: [
|
|
@@ -11,7 +11,7 @@ export const paths = {
|
|
|
11
11
|
},
|
|
12
12
|
},
|
|
13
13
|
},
|
|
14
|
-
security: [{ studio: [] }],
|
|
14
|
+
security: [{ studio: [] }, { cli: ['apps:write'] }],
|
|
15
15
|
responses: {
|
|
16
16
|
201: {
|
|
17
17
|
description: 'A list of the SAML secrets for the app.',
|
|
@@ -41,6 +41,16 @@ export const paths = {
|
|
|
41
41
|
},
|
|
42
42
|
},
|
|
43
43
|
},
|
|
44
|
+
delete: {
|
|
45
|
+
tags: ['secret'],
|
|
46
|
+
operationId: 'deleteAppSamlSecrets',
|
|
47
|
+
security: [{ studio: [] }, { cli: ['apps:write'] }],
|
|
48
|
+
responses: {
|
|
49
|
+
204: {
|
|
50
|
+
description: 'The deleted app saml secrets.',
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
},
|
|
44
54
|
},
|
|
45
55
|
'/api/apps/{appId}/secrets/saml/{appSamlSecretId}': {
|
|
46
56
|
parameters: [
|
|
@@ -3,7 +3,7 @@ export const paths = {
|
|
|
3
3
|
parameters: [{ $ref: '#/components/parameters/appId' }],
|
|
4
4
|
post: {
|
|
5
5
|
tags: ['secret'],
|
|
6
|
-
operationId: '
|
|
6
|
+
operationId: 'createAppServiceSecret',
|
|
7
7
|
requestBody: {
|
|
8
8
|
content: {
|
|
9
9
|
'application/json': {
|
|
@@ -11,7 +11,7 @@ export const paths = {
|
|
|
11
11
|
},
|
|
12
12
|
},
|
|
13
13
|
},
|
|
14
|
-
security: [{ studio: [] }],
|
|
14
|
+
security: [{ studio: [] }, { cli: ['apps:write'] }],
|
|
15
15
|
responses: {
|
|
16
16
|
201: {
|
|
17
17
|
description: 'The created app service secret.',
|
|
@@ -41,6 +41,16 @@ export const paths = {
|
|
|
41
41
|
},
|
|
42
42
|
},
|
|
43
43
|
},
|
|
44
|
+
delete: {
|
|
45
|
+
tags: ['secret'],
|
|
46
|
+
operationId: 'deleteAppServiceSecrets',
|
|
47
|
+
security: [{ studio: [] }, { cli: ['apps:write'] }],
|
|
48
|
+
responses: {
|
|
49
|
+
204: {
|
|
50
|
+
description: 'The deleted app service secrets.',
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
},
|
|
44
54
|
},
|
|
45
55
|
'/api/apps/{appId}/secrets/service/{appServiceId}': {
|
|
46
56
|
parameters: [
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
export const paths = {
|
|
2
|
+
'/api/apps/{appId}/variables': {
|
|
3
|
+
parameters: [{ $ref: '#/components/parameters/appId' }],
|
|
4
|
+
post: {
|
|
5
|
+
tags: ['variable'],
|
|
6
|
+
operationId: 'createAppVariable',
|
|
7
|
+
requestBody: {
|
|
8
|
+
content: {
|
|
9
|
+
'application/json': {
|
|
10
|
+
schema: { $ref: '#/components/schemas/AppVariable' },
|
|
11
|
+
},
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
security: [{ studio: [] }, { cli: ['apps:write'] }],
|
|
15
|
+
responses: {
|
|
16
|
+
201: {
|
|
17
|
+
description: 'The created app variable.',
|
|
18
|
+
content: {
|
|
19
|
+
'application/json': {
|
|
20
|
+
schema: { $ref: '#/components/schemas/AppVariable' },
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
get: {
|
|
27
|
+
tags: ['variable'],
|
|
28
|
+
operationId: 'getAppVariables',
|
|
29
|
+
responses: {
|
|
30
|
+
200: {
|
|
31
|
+
description: 'The list of app variables.',
|
|
32
|
+
content: {
|
|
33
|
+
'application/json': {
|
|
34
|
+
schema: {
|
|
35
|
+
type: 'array',
|
|
36
|
+
items: { $ref: '#/components/schemas/AppVariable' },
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
delete: {
|
|
44
|
+
tags: ['variable'],
|
|
45
|
+
operationId: 'deleteAppVariables',
|
|
46
|
+
security: [{ studio: [] }, { cli: ['apps:write'] }],
|
|
47
|
+
responses: {
|
|
48
|
+
204: {
|
|
49
|
+
description: 'The deleted app variables.',
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
'/api/apps/{appId}/variables/{appVariableId}': {
|
|
55
|
+
parameters: [
|
|
56
|
+
{ $ref: '#/components/parameters/appId' },
|
|
57
|
+
{ $ref: '#/components/parameters/appVariableId' },
|
|
58
|
+
],
|
|
59
|
+
put: {
|
|
60
|
+
tags: ['secret'],
|
|
61
|
+
operationId: 'updateAppVariable',
|
|
62
|
+
requestBody: {
|
|
63
|
+
content: {
|
|
64
|
+
'application/json': {
|
|
65
|
+
schema: { $ref: '#/components/schemas/AppVariable' },
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
security: [{ studio: [] }],
|
|
70
|
+
responses: {
|
|
71
|
+
200: {
|
|
72
|
+
description: 'The updated app variable.',
|
|
73
|
+
content: {
|
|
74
|
+
'application/json': {
|
|
75
|
+
schema: { $ref: '#/components/schemas/AppVariable' },
|
|
76
|
+
},
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
delete: {
|
|
82
|
+
tags: ['secret'],
|
|
83
|
+
operationId: 'deleteAppVariable',
|
|
84
|
+
security: [{ studio: [] }],
|
|
85
|
+
responses: {
|
|
86
|
+
204: {
|
|
87
|
+
description: 'The deleted app variable.',
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
};
|
|
93
|
+
//# sourceMappingURL=appVariables.js.map
|
package/api/paths/apps.js
CHANGED
|
@@ -142,6 +142,28 @@ export const paths = {
|
|
|
142
142
|
security: [{ studio: [] }, {}],
|
|
143
143
|
},
|
|
144
144
|
},
|
|
145
|
+
'/api/apps/path/{appPath}': {
|
|
146
|
+
parameters: [{ $ref: '#/components/parameters/appPath' }],
|
|
147
|
+
get: {
|
|
148
|
+
tags: ['app', 'app-path'],
|
|
149
|
+
parameters: [
|
|
150
|
+
{
|
|
151
|
+
name: 'language',
|
|
152
|
+
schema: { type: 'string' },
|
|
153
|
+
description: 'The language to include the translations of, if available',
|
|
154
|
+
in: 'query',
|
|
155
|
+
},
|
|
156
|
+
],
|
|
157
|
+
description: 'Get an app by app-path',
|
|
158
|
+
operationId: 'getAppByPath',
|
|
159
|
+
responses: {
|
|
160
|
+
200: {
|
|
161
|
+
description: 'The app that matches the given app path.',
|
|
162
|
+
$ref: '#/components/responses/app',
|
|
163
|
+
},
|
|
164
|
+
},
|
|
165
|
+
},
|
|
166
|
+
},
|
|
145
167
|
'/api/apps/{appId}': {
|
|
146
168
|
parameters: [{ $ref: '#/components/parameters/appId' }],
|
|
147
169
|
get: {
|
|
@@ -340,7 +362,7 @@ export const paths = {
|
|
|
340
362
|
parameters: [{ $ref: '#/components/parameters/appId' }],
|
|
341
363
|
get: {
|
|
342
364
|
tags: ['app', 'export', 'zip'],
|
|
343
|
-
description: 'Export
|
|
365
|
+
description: 'Export an app as a zip file',
|
|
344
366
|
operationId: 'exportApp',
|
|
345
367
|
parameters: [
|
|
346
368
|
{
|
package/api/paths/index.js
CHANGED
|
@@ -10,6 +10,7 @@ import { paths as appScimSecrets } from './appScimSecrets.js';
|
|
|
10
10
|
import { paths as appsembleMessages } from './appsembleMessages.js';
|
|
11
11
|
import { paths as appServiceSecrets } from './appServiceSecrets.js';
|
|
12
12
|
import { paths as appSSLSecrets } from './appSSLSecrets.js';
|
|
13
|
+
import { paths as appVariables } from './appVariables.js';
|
|
13
14
|
import { paths as assets } from './assets.js';
|
|
14
15
|
import { paths as blocks } from './blocks.js';
|
|
15
16
|
import { paths as emails } from './emails.js';
|
|
@@ -33,6 +34,7 @@ export const paths = {
|
|
|
33
34
|
...scimEndpoints,
|
|
34
35
|
...appsembleMessages,
|
|
35
36
|
...appSSLSecrets,
|
|
37
|
+
...appVariables,
|
|
36
38
|
...appCollections,
|
|
37
39
|
...appQuotas,
|
|
38
40
|
...assets,
|
package/api/paths/templates.js
CHANGED
|
@@ -68,6 +68,14 @@ export const paths = {
|
|
|
68
68
|
type: 'boolean',
|
|
69
69
|
description: 'Include example assets.',
|
|
70
70
|
},
|
|
71
|
+
variables: {
|
|
72
|
+
type: 'boolean',
|
|
73
|
+
description: 'Include example variables.',
|
|
74
|
+
},
|
|
75
|
+
secrets: {
|
|
76
|
+
type: 'boolean',
|
|
77
|
+
description: 'Include example secrets.',
|
|
78
|
+
},
|
|
71
79
|
visibility: {
|
|
72
80
|
$ref: '#/components/schemas/App/properties/visibility',
|
|
73
81
|
},
|
package/examples.js
CHANGED
|
@@ -279,6 +279,12 @@ export const examples = {
|
|
|
279
279
|
result: {},
|
|
280
280
|
skip: true,
|
|
281
281
|
},
|
|
282
|
+
variable: {
|
|
283
|
+
input: null,
|
|
284
|
+
remapper: {},
|
|
285
|
+
result: {},
|
|
286
|
+
skip: true,
|
|
287
|
+
},
|
|
282
288
|
'date.add': {
|
|
283
289
|
input: '2023-06-30T14:50:19.601Z',
|
|
284
290
|
remapper: [
|
|
@@ -649,6 +655,7 @@ export function schemaExample(remapper, options) {
|
|
|
649
655
|
export function createExampleContext(url, lang, userInfo, history) {
|
|
650
656
|
return {
|
|
651
657
|
getMessage: ({ defaultMessage }) => new IntlMessageFormat(defaultMessage, lang, undefined),
|
|
658
|
+
getVariable: () => null,
|
|
652
659
|
url: String(url),
|
|
653
660
|
appUrl: `${url.protocol}//example-app.example-organization.${url.host}`,
|
|
654
661
|
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.
|
|
3
|
+
"version": "0.28.0",
|
|
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.
|
|
40
|
+
"@appsemble/types": "0.28.0",
|
|
41
41
|
"axios": "^1.0.0",
|
|
42
42
|
"cron-parser": "^4.0.0",
|
|
43
43
|
"date-fns": "^2.0.0",
|
|
@@ -203,6 +203,12 @@ The result of the final page’s log would then be:
|
|
|
203
203
|
{ type: 'string' },
|
|
204
204
|
{ type: 'integer' },
|
|
205
205
|
{ type: 'array', minItems: 1, items: { anyOf: [{ type: 'string' }, { type: 'integer' }] } },
|
|
206
|
+
{
|
|
207
|
+
type: 'array',
|
|
208
|
+
minItems: 1,
|
|
209
|
+
items: { $ref: '#/components/schemas/ObjectRemapperDefinition' },
|
|
210
|
+
},
|
|
211
|
+
{ $ref: '#/components/schemas/ObjectRemapperDefinition' },
|
|
206
212
|
],
|
|
207
213
|
description: `Gets the chosen property from an object.
|
|
208
214
|
|
|
@@ -26,7 +26,12 @@ ${schemaExample('date.add')}
|
|
|
26
26
|
`,
|
|
27
27
|
},
|
|
28
28
|
'date.format': {
|
|
29
|
-
|
|
29
|
+
oneOf: [
|
|
30
|
+
{ enum: [null] },
|
|
31
|
+
{
|
|
32
|
+
type: 'string',
|
|
33
|
+
},
|
|
34
|
+
],
|
|
30
35
|
description: `Format a date according to the RFC3339 format.
|
|
31
36
|
|
|
32
37
|
Here is an example of a RFC3339 complicit date:
|
package/remap.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type AppMember, type Remapper, type UserInfo } from '@appsemble/types';
|
|
1
|
+
import { type AppMember, type Remapper, type UserInfo, type ValueFromProcess } from '@appsemble/types';
|
|
2
2
|
import { type IntlMessageFormat } from 'intl-messageformat';
|
|
3
3
|
export interface IntlMessage {
|
|
4
4
|
id?: string;
|
|
@@ -11,6 +11,7 @@ export interface IntlMessage {
|
|
|
11
11
|
* @returns A message format instance.
|
|
12
12
|
*/
|
|
13
13
|
export type MessageGetter = (msg: IntlMessage) => IntlMessageFormat;
|
|
14
|
+
export type AppConfigEntryGetter = (name: string) => ValueFromProcess;
|
|
14
15
|
export interface RemapperContext {
|
|
15
16
|
/**
|
|
16
17
|
* The id of the app whose context the remapper is run in.
|
|
@@ -28,6 +29,10 @@ export interface RemapperContext {
|
|
|
28
29
|
* @see MessageGetter
|
|
29
30
|
*/
|
|
30
31
|
getMessage: MessageGetter;
|
|
32
|
+
/**
|
|
33
|
+
* @see VariableGetter
|
|
34
|
+
*/
|
|
35
|
+
getVariable: AppConfigEntryGetter;
|
|
31
36
|
/**
|
|
32
37
|
* The history stack containing the states before an action was called.
|
|
33
38
|
*/
|
package/remap.js
CHANGED
|
@@ -84,6 +84,12 @@ const mapperImplementations = {
|
|
|
84
84
|
}
|
|
85
85
|
return result !== null && result !== void 0 ? result : null;
|
|
86
86
|
},
|
|
87
|
+
variable(name, input, context) {
|
|
88
|
+
if (context.getVariable) {
|
|
89
|
+
return context.getVariable(name);
|
|
90
|
+
}
|
|
91
|
+
return { variable: name };
|
|
92
|
+
},
|
|
87
93
|
equals(mappers, input, context) {
|
|
88
94
|
if (mappers.length <= 1) {
|
|
89
95
|
return true;
|
|
@@ -239,13 +245,45 @@ const mapperImplementations = {
|
|
|
239
245
|
return Array.isArray(input) ? input.filter((value, i) => !indices.has(i)) : [];
|
|
240
246
|
},
|
|
241
247
|
static: (input) => input,
|
|
242
|
-
prop(prop, obj) {
|
|
248
|
+
prop(prop, obj, context) {
|
|
243
249
|
let result = obj;
|
|
244
|
-
|
|
245
|
-
|
|
250
|
+
if (result == null) {
|
|
251
|
+
return result;
|
|
252
|
+
}
|
|
253
|
+
if (Array.isArray(prop)) {
|
|
254
|
+
if (prop.every((item) => typeof item === 'number' || typeof item === 'string')) {
|
|
255
|
+
// This runs if the provided value is an array of property names or indexes
|
|
256
|
+
for (const p of [prop].flat()) {
|
|
257
|
+
result = result[p];
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
else if (prop.every((item) => typeof item === 'object' && !Array.isArray(item))) {
|
|
261
|
+
// This runs if the provided value is an array of remappers
|
|
262
|
+
const remapped = remap(prop, obj, context);
|
|
263
|
+
if (typeof remapped === 'number' || typeof remapped === 'string') {
|
|
264
|
+
result = result[remapped];
|
|
265
|
+
}
|
|
266
|
+
else {
|
|
267
|
+
console.error(`Invalid remapper ${JSON.stringify(prop)}`);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
else if (typeof prop === 'object') {
|
|
272
|
+
if (prop == null) {
|
|
273
|
+
result = result.null;
|
|
246
274
|
return result;
|
|
247
275
|
}
|
|
248
|
-
|
|
276
|
+
// This runs if the provided value is a remapper
|
|
277
|
+
const remapped = remap(prop, result, context);
|
|
278
|
+
if (typeof remapped === 'number' || typeof remapped === 'string') {
|
|
279
|
+
result = result[remapped];
|
|
280
|
+
}
|
|
281
|
+
else {
|
|
282
|
+
console.error(`Invalid remapper ${JSON.stringify(prop)}`);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
else if (typeof prop === 'number' || typeof prop === 'string') {
|
|
286
|
+
result = result[prop];
|
|
249
287
|
}
|
|
250
288
|
return result;
|
|
251
289
|
},
|
package/remap.test.js
CHANGED
|
@@ -3,9 +3,10 @@ import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
|
3
3
|
import { createExampleContext, examples } from './examples.js';
|
|
4
4
|
import { remap } from './remap.js';
|
|
5
5
|
function runTests(tests) {
|
|
6
|
-
it.each(Object.entries(tests))('should %s', (name, { context, expected, history, input, mappers, messages, userInfo }) => {
|
|
6
|
+
it.each(Object.entries(tests))('should %s', (name, { context, expected, history, input, mappers, messages, userInfo, variables }) => {
|
|
7
7
|
const result = remap(mappers, input, {
|
|
8
8
|
getMessage: ({ defaultMessage, id }) => { var _a, _b; return new IntlMessageFormat((_b = (_a = messages === null || messages === void 0 ? void 0 : messages.messageIds) === null || _a === void 0 ? void 0 : _a[id]) !== null && _b !== void 0 ? _b : defaultMessage); },
|
|
9
|
+
getVariable: (variableName) => { var _a; return (_a = variables.find((variable) => variable.name === variableName)) === null || _a === void 0 ? void 0 : _a.value; },
|
|
9
10
|
url: 'https://example.com/en/example',
|
|
10
11
|
appUrl: 'https://example.com',
|
|
11
12
|
userInfo,
|
|
@@ -120,6 +121,22 @@ describe('context', () => {
|
|
|
120
121
|
},
|
|
121
122
|
});
|
|
122
123
|
});
|
|
124
|
+
describe('variable', () => {
|
|
125
|
+
runTests({
|
|
126
|
+
'get a variable': {
|
|
127
|
+
input: {},
|
|
128
|
+
mappers: { variable: 'my-variable' },
|
|
129
|
+
expected: 'my-variable-value',
|
|
130
|
+
variables: [{ id: 0, name: 'my-variable', value: 'my-variable-value' }],
|
|
131
|
+
},
|
|
132
|
+
'get an undefined variable': {
|
|
133
|
+
input: {},
|
|
134
|
+
mappers: { variable: 'my-variable' },
|
|
135
|
+
expected: undefined,
|
|
136
|
+
variables: [],
|
|
137
|
+
},
|
|
138
|
+
});
|
|
139
|
+
});
|
|
123
140
|
describe('date.now', () => {
|
|
124
141
|
beforeEach(() => {
|
|
125
142
|
vi.useFakeTimers({ now: 0 });
|
|
@@ -210,7 +227,7 @@ describe('log', () => {
|
|
|
210
227
|
vi.spyOn(console, 'warn').mockImplementation(null);
|
|
211
228
|
});
|
|
212
229
|
function runLogTests(tests) {
|
|
213
|
-
it.each(Object.entries(tests))('should %s', (name, { context, expected: expectedInput, history, input, mappers, messages, userInfo }) => {
|
|
230
|
+
it.each(Object.entries(tests))('should %s', (name, { context, expected: expectedInput, history, input, mappers, messages, userInfo, variables, }) => {
|
|
214
231
|
const expected = JSON.stringify({
|
|
215
232
|
input: expectedInput,
|
|
216
233
|
context: {
|
|
@@ -228,6 +245,7 @@ describe('log', () => {
|
|
|
228
245
|
}, null, 2);
|
|
229
246
|
remap(mappers, input, {
|
|
230
247
|
getMessage: ({ defaultMessage, id }) => { var _a, _b; return new IntlMessageFormat((_b = (_a = messages === null || messages === void 0 ? void 0 : messages.messageIds) === null || _a === void 0 ? void 0 : _a[id]) !== null && _b !== void 0 ? _b : defaultMessage); },
|
|
248
|
+
getVariable: (variableName) => variables.find((variable) => variable.name === variableName).value,
|
|
231
249
|
url: 'https://example.com/en/example',
|
|
232
250
|
appUrl: 'https://example.com',
|
|
233
251
|
userInfo,
|
|
@@ -870,6 +888,24 @@ describe('prop', () => {
|
|
|
870
888
|
mappers: [{ prop: 'names' }, { prop: 0 }],
|
|
871
889
|
expected: 'foo',
|
|
872
890
|
},
|
|
891
|
+
'handle a single remapper': {
|
|
892
|
+
input: { en: 'English', nl: 'Dutch' },
|
|
893
|
+
mappers: [{ prop: { app: 'locale' } }],
|
|
894
|
+
expected: 'English',
|
|
895
|
+
},
|
|
896
|
+
'handle an array of remappers': {
|
|
897
|
+
input: { address: { town: 'Bikini Bottom' } },
|
|
898
|
+
mappers: [{ prop: [{ 'object.from': { prop: 'address' } }, { prop: 'prop' }] }],
|
|
899
|
+
expected: { town: 'Bikini Bottom' },
|
|
900
|
+
},
|
|
901
|
+
'handle an array of remappers with numbers': {
|
|
902
|
+
input: { languages: ['English', 'Dutch'] },
|
|
903
|
+
mappers: [
|
|
904
|
+
{ prop: [{ 'object.from': { prop: 'languages' } }, { prop: 'prop' }] },
|
|
905
|
+
{ prop: 0 },
|
|
906
|
+
],
|
|
907
|
+
expected: 'English',
|
|
908
|
+
},
|
|
873
909
|
'handle null': {
|
|
874
910
|
input: { name: 'Spongebob' },
|
|
875
911
|
mappers: { prop: null },
|