@appsemble/cli 0.30.1 → 0.30.2
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/lib/app.test.js +1265 -1264
- package/lib/asset.test.js +68 -67
- package/lib/block.test.js +143 -142
- package/lib/config.test.js +205 -203
- package/lib/group.test.js +543 -542
- package/lib/organization.test.js +188 -187
- package/lib/resource.test.js +321 -320
- package/package.json +8 -7
- package/templates/apps/empty/app-definition.yaml +2 -2
- package/templates/blocks/mini-jsx/package.json +1 -1
- package/templates/blocks/preact/package.json +2 -2
- package/templates/blocks/vanilla/package.json +1 -1
- package/vitest.setup.js +11 -0
package/lib/config.test.js
CHANGED
|
@@ -5,232 +5,234 @@ import { AppsembleError, resolveFixture } from '@appsemble/node-utils';
|
|
|
5
5
|
import { ts } from 'ts-json-schema-generator';
|
|
6
6
|
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
7
7
|
import { getProjectImplementations } from './config.js';
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
8
|
+
describe('config', () => {
|
|
9
|
+
beforeEach(() => {
|
|
10
|
+
vi.spyOn(process, 'cwd').mockReturnValue(resolveFixture('.'));
|
|
11
|
+
});
|
|
12
|
+
describe('getProjectImplementations', () => {
|
|
13
|
+
it('should extract configuration from a TypeScript project', () => {
|
|
14
|
+
const result = getProjectImplementations({
|
|
15
|
+
name: '',
|
|
16
|
+
layout: 'float',
|
|
17
|
+
version: '1.33.7',
|
|
18
|
+
webpack: '',
|
|
19
|
+
output: '',
|
|
20
|
+
dir: resolveFixture('getProjectImplementations/valid'),
|
|
21
|
+
});
|
|
22
|
+
expect(result).toStrictEqual({
|
|
23
|
+
actions: { testAction: { description: undefined } },
|
|
24
|
+
events: {
|
|
25
|
+
emit: { testEmit: { description: undefined } },
|
|
26
|
+
listen: { testListener: { description: undefined } },
|
|
27
|
+
},
|
|
28
|
+
messages: undefined,
|
|
29
|
+
parameters: {
|
|
30
|
+
$schema: 'http://json-schema.org/draft-07/schema#',
|
|
31
|
+
additionalProperties: false,
|
|
32
|
+
properties: {
|
|
33
|
+
param1: { type: 'string' },
|
|
34
|
+
param2: { type: 'number' },
|
|
35
|
+
param3: { type: 'boolean' },
|
|
36
|
+
param4: { type: 'string' },
|
|
37
|
+
param5: {
|
|
38
|
+
additionalProperties: false,
|
|
39
|
+
properties: {
|
|
40
|
+
nested1: { type: 'string' },
|
|
41
|
+
nested2: { type: 'number' },
|
|
42
|
+
nested3: { type: 'boolean' },
|
|
43
|
+
},
|
|
44
|
+
required: ['nested1', 'nested2', 'nested3'],
|
|
45
|
+
type: 'object',
|
|
42
46
|
},
|
|
43
|
-
|
|
44
|
-
type: 'object',
|
|
47
|
+
param6: { items: { type: 'string' }, type: 'array' },
|
|
45
48
|
},
|
|
46
|
-
|
|
49
|
+
required: ['param1', 'param2', 'param3', 'param5', 'param6'],
|
|
50
|
+
type: 'object',
|
|
47
51
|
},
|
|
48
|
-
|
|
49
|
-
type: 'object',
|
|
50
|
-
},
|
|
52
|
+
});
|
|
51
53
|
});
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
expect(ts.createProgram).not.toHaveBeenCalled();
|
|
71
|
-
});
|
|
72
|
-
it('should prefer actions overrides over TypeScript actions', () => {
|
|
73
|
-
const result = getProjectImplementations({
|
|
74
|
-
actions: {},
|
|
75
|
-
version: '1.33.7',
|
|
76
|
-
webpack: '',
|
|
77
|
-
output: '',
|
|
78
|
-
dir: resolveFixture('getProjectImplementations/valid'),
|
|
79
|
-
name: '',
|
|
54
|
+
// Spying on TypeScript functions no longer works.
|
|
55
|
+
// eslint-disable-next-line vitest/no-disabled-tests
|
|
56
|
+
it.skip('should not use TypeScript if all metadata is present in the original config', () => {
|
|
57
|
+
vi.spyOn(ts, 'createProgram');
|
|
58
|
+
const input = {
|
|
59
|
+
actions: {},
|
|
60
|
+
events: { emit: { foo: {} }, listen: { bar: {} } },
|
|
61
|
+
layout: 'float',
|
|
62
|
+
parameters: { type: 'object' },
|
|
63
|
+
version: '1.33.7',
|
|
64
|
+
webpack: '',
|
|
65
|
+
output: '',
|
|
66
|
+
dir: resolveFixture('getProjectImplementations/valid'),
|
|
67
|
+
name: '',
|
|
68
|
+
};
|
|
69
|
+
const result = getProjectImplementations(input);
|
|
70
|
+
expect(result).toBe(input);
|
|
71
|
+
expect(ts.createProgram).not.toHaveBeenCalled();
|
|
80
72
|
});
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
73
|
+
it('should prefer actions overrides over TypeScript actions', () => {
|
|
74
|
+
const result = getProjectImplementations({
|
|
75
|
+
actions: {},
|
|
76
|
+
version: '1.33.7',
|
|
77
|
+
webpack: '',
|
|
78
|
+
output: '',
|
|
79
|
+
dir: resolveFixture('getProjectImplementations/valid'),
|
|
80
|
+
name: '',
|
|
81
|
+
});
|
|
82
|
+
expect(result.actions).toStrictEqual({});
|
|
91
83
|
});
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
84
|
+
it('should prefer events overrides over TypeScript events', () => {
|
|
85
|
+
const result = getProjectImplementations({
|
|
86
|
+
events: { emit: { onSuccess: {} } },
|
|
87
|
+
version: '1.33.7',
|
|
88
|
+
webpack: '',
|
|
89
|
+
output: '',
|
|
90
|
+
dir: resolveFixture('getProjectImplementations/valid'),
|
|
91
|
+
name: '',
|
|
92
|
+
});
|
|
93
|
+
expect(result.events).toStrictEqual({ emit: { onSuccess: {} } });
|
|
102
94
|
});
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
});
|
|
132
|
-
it('should throw if duplicate Parameters are found', () => {
|
|
133
|
-
expect(() => getProjectImplementations({
|
|
134
|
-
webpack: '',
|
|
135
|
-
output: '',
|
|
136
|
-
dir: resolveFixture('getProjectImplementations/duplicateParameters'),
|
|
137
|
-
name: '',
|
|
138
|
-
version: '1.33.7',
|
|
139
|
-
})).toThrow(new AppsembleError("Found duplicate interface 'Parameters' in 'getProjectImplementations/duplicateParameters/index.ts:31'"));
|
|
140
|
-
});
|
|
141
|
-
it('should handle fontawesome icons', () => {
|
|
142
|
-
const result = getProjectImplementations({
|
|
143
|
-
webpack: '',
|
|
144
|
-
output: '',
|
|
145
|
-
dir: resolveFixture('getProjectImplementations/fontawesomeParameters'),
|
|
146
|
-
name: '',
|
|
147
|
-
version: '1.33.7',
|
|
95
|
+
it('should prefer parameters overrides over TypeScript parameters', () => {
|
|
96
|
+
const result = getProjectImplementations({
|
|
97
|
+
parameters: { type: 'object' },
|
|
98
|
+
version: '1.33.7',
|
|
99
|
+
webpack: '',
|
|
100
|
+
output: '',
|
|
101
|
+
dir: resolveFixture('getProjectImplementations/valid'),
|
|
102
|
+
name: '',
|
|
103
|
+
});
|
|
104
|
+
expect(result.parameters).toStrictEqual({ type: 'object' });
|
|
105
|
+
});
|
|
106
|
+
it('should throw if duplicate Actions are found', () => {
|
|
107
|
+
expect(() => getProjectImplementations({
|
|
108
|
+
webpack: '',
|
|
109
|
+
output: '',
|
|
110
|
+
dir: resolveFixture('getProjectImplementations/duplicateActions'),
|
|
111
|
+
name: '',
|
|
112
|
+
version: '1.33.7',
|
|
113
|
+
})).toThrow(new AppsembleError("Found duplicate interface 'Actions' in 'getProjectImplementations/duplicateActions/index.ts:31'"));
|
|
114
|
+
});
|
|
115
|
+
it('should throw if duplicate EventEmitters are found', () => {
|
|
116
|
+
expect(() => getProjectImplementations({
|
|
117
|
+
webpack: '',
|
|
118
|
+
output: '',
|
|
119
|
+
dir: resolveFixture('getProjectImplementations/duplicateEventEmitters'),
|
|
120
|
+
name: '',
|
|
121
|
+
version: '1.33.7',
|
|
122
|
+
})).toThrow(new AppsembleError("Found duplicate interface 'EventEmitters' in 'getProjectImplementations/duplicateEventEmitters/index.ts:31'"));
|
|
148
123
|
});
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
124
|
+
it('should throw if duplicate EventListeners are found', () => {
|
|
125
|
+
expect(() => getProjectImplementations({
|
|
126
|
+
webpack: '',
|
|
127
|
+
output: '',
|
|
128
|
+
dir: resolveFixture('getProjectImplementations/duplicateEventListeners'),
|
|
129
|
+
name: '',
|
|
130
|
+
version: '1.33.7',
|
|
131
|
+
})).toThrow(new AppsembleError("Found duplicate interface 'EventListeners' in 'getProjectImplementations/duplicateEventListeners/index.ts:31'"));
|
|
132
|
+
});
|
|
133
|
+
it('should throw if duplicate Parameters are found', () => {
|
|
134
|
+
expect(() => getProjectImplementations({
|
|
135
|
+
webpack: '',
|
|
136
|
+
output: '',
|
|
137
|
+
dir: resolveFixture('getProjectImplementations/duplicateParameters'),
|
|
138
|
+
name: '',
|
|
139
|
+
version: '1.33.7',
|
|
140
|
+
})).toThrow(new AppsembleError("Found duplicate interface 'Parameters' in 'getProjectImplementations/duplicateParameters/index.ts:31'"));
|
|
141
|
+
});
|
|
142
|
+
it('should handle fontawesome icons', () => {
|
|
143
|
+
const result = getProjectImplementations({
|
|
144
|
+
webpack: '',
|
|
145
|
+
output: '',
|
|
146
|
+
dir: resolveFixture('getProjectImplementations/fontawesomeParameters'),
|
|
147
|
+
name: '',
|
|
148
|
+
version: '1.33.7',
|
|
149
|
+
});
|
|
150
|
+
expect(result).toStrictEqual({
|
|
151
|
+
actions: undefined,
|
|
152
|
+
events: undefined,
|
|
153
|
+
messages: undefined,
|
|
154
|
+
parameters: {
|
|
155
|
+
$schema: 'http://json-schema.org/draft-07/schema#',
|
|
156
|
+
additionalProperties: false,
|
|
157
|
+
properties: {
|
|
158
|
+
icon: { description: 'This is an icon.', format: 'fontawesome', type: 'string' },
|
|
159
|
+
},
|
|
160
|
+
type: 'object',
|
|
158
161
|
},
|
|
159
|
-
|
|
160
|
-
},
|
|
162
|
+
});
|
|
161
163
|
});
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
164
|
+
it('should handle TypeScript pre emit diagnostics', () => {
|
|
165
|
+
function fn() {
|
|
166
|
+
getProjectImplementations({
|
|
167
|
+
name: '',
|
|
168
|
+
layout: 'float',
|
|
169
|
+
version: '1.33.7',
|
|
170
|
+
webpack: '',
|
|
171
|
+
output: '',
|
|
172
|
+
dir: resolveFixture('getProjectImplementations/tsError'),
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
expect(fn).toThrow(AppsembleError);
|
|
176
|
+
expect(fn).toThrow(/'unused' is declared but its value is never read/);
|
|
177
|
+
});
|
|
178
|
+
it('should extract comments', () => {
|
|
179
|
+
const result = getProjectImplementations({
|
|
166
180
|
name: '',
|
|
167
181
|
layout: 'float',
|
|
168
182
|
version: '1.33.7',
|
|
169
183
|
webpack: '',
|
|
170
184
|
output: '',
|
|
171
|
-
dir: resolveFixture('getProjectImplementations/
|
|
185
|
+
dir: resolveFixture('getProjectImplementations/comments'),
|
|
172
186
|
});
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
output: '',
|
|
184
|
-
dir: resolveFixture('getProjectImplementations/comments'),
|
|
185
|
-
});
|
|
186
|
-
expect(result).toStrictEqual({
|
|
187
|
-
actions: {
|
|
188
|
-
comment: {
|
|
189
|
-
description: 'Valid action comment',
|
|
190
|
-
},
|
|
191
|
-
duplicate: {
|
|
192
|
-
description: 'Expected comment',
|
|
193
|
-
},
|
|
194
|
-
line: {
|
|
195
|
-
description: undefined,
|
|
196
|
-
},
|
|
197
|
-
},
|
|
198
|
-
events: {
|
|
199
|
-
emit: {
|
|
200
|
-
testEmit: {
|
|
201
|
-
description: 'Test event emitter.',
|
|
187
|
+
expect(result).toStrictEqual({
|
|
188
|
+
actions: {
|
|
189
|
+
comment: {
|
|
190
|
+
description: 'Valid action comment',
|
|
191
|
+
},
|
|
192
|
+
duplicate: {
|
|
193
|
+
description: 'Expected comment',
|
|
194
|
+
},
|
|
195
|
+
line: {
|
|
196
|
+
description: undefined,
|
|
202
197
|
},
|
|
203
198
|
},
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
199
|
+
events: {
|
|
200
|
+
emit: {
|
|
201
|
+
testEmit: {
|
|
202
|
+
description: 'Test event emitter.',
|
|
203
|
+
},
|
|
204
|
+
},
|
|
205
|
+
listen: {
|
|
206
|
+
testListener: {
|
|
207
|
+
description: 'Test event listener.',
|
|
208
|
+
},
|
|
207
209
|
},
|
|
208
210
|
},
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
211
|
+
messages: undefined,
|
|
212
|
+
parameters: {
|
|
213
|
+
$schema: 'http://json-schema.org/draft-07/schema#',
|
|
214
|
+
additionalProperties: false,
|
|
215
|
+
properties: {
|
|
216
|
+
param: {},
|
|
217
|
+
},
|
|
218
|
+
required: ['param'],
|
|
219
|
+
type: 'object',
|
|
216
220
|
},
|
|
217
|
-
|
|
218
|
-
type: 'object',
|
|
219
|
-
},
|
|
221
|
+
});
|
|
220
222
|
});
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
223
|
+
describe('official blocks', () => {
|
|
224
|
+
const blocksDir = new URL('../../../blocks/', import.meta.url);
|
|
225
|
+
it.each(readdirSync(blocksDir))('%s', (name) => {
|
|
226
|
+
const dir = fileURLToPath(new URL(name, blocksDir));
|
|
227
|
+
const result = getProjectImplementations({
|
|
228
|
+
name,
|
|
229
|
+
version: '',
|
|
230
|
+
output: '',
|
|
231
|
+
webpack: undefined,
|
|
232
|
+
dir,
|
|
233
|
+
});
|
|
234
|
+
expect(result).toMatchSnapshot();
|
|
232
235
|
});
|
|
233
|
-
expect(result).toMatchSnapshot();
|
|
234
236
|
});
|
|
235
237
|
});
|
|
236
238
|
});
|