@appsemble/cli 0.29.11 → 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.
Files changed (156) hide show
  1. package/README.md +10 -10
  2. package/commands/app/create.d.ts +1 -1
  3. package/commands/app/create.js +5 -5
  4. package/commands/{team → group}/create.d.ts +3 -3
  5. package/commands/{team → group}/create.js +5 -5
  6. package/commands/{team → group}/delete.d.ts +3 -3
  7. package/commands/{team → group}/delete.js +5 -5
  8. package/commands/{team → group}/index.d.ts +2 -2
  9. package/commands/{team → group}/index.js +4 -4
  10. package/commands/{team → group}/member/delete.d.ts +3 -3
  11. package/commands/{team → group}/member/delete.js +5 -5
  12. package/commands/{team → group}/member/index.d.ts +1 -1
  13. package/commands/{team → group}/member/index.js +1 -3
  14. package/commands/{team → group}/member/invite.d.ts +3 -3
  15. package/commands/{team → group}/member/invite.js +5 -5
  16. package/commands/{team → group}/update.d.ts +3 -3
  17. package/commands/{team → group}/update.js +7 -7
  18. package/commands/migrateAppDefinitions.d.ts +13 -0
  19. package/commands/migrateAppDefinitions.js +73 -0
  20. package/commands/serve.d.ts +1 -1
  21. package/commands/serve.js +16 -16
  22. package/index.js +4 -2
  23. package/lib/app.js +13 -3
  24. package/lib/app.test.js +1266 -1262
  25. package/lib/asset.js +4 -2
  26. package/lib/asset.test.js +70 -67
  27. package/lib/block.test.js +144 -142
  28. package/lib/config.test.js +205 -203
  29. package/lib/createServers.js +3 -1
  30. package/lib/group.d.ts +61 -0
  31. package/lib/group.js +55 -0
  32. package/lib/group.test.js +610 -0
  33. package/lib/organization.test.js +189 -187
  34. package/lib/resource.js +3 -1
  35. package/lib/resource.test.js +322 -320
  36. package/lib/serverImport.d.ts +1 -1
  37. package/package.json +8 -7
  38. package/server/argv.d.ts +4 -4
  39. package/server/argv.js +1 -1
  40. package/server/controllers/apps/actions/index.d.ts +5 -0
  41. package/server/controllers/apps/actions/index.js +6 -0
  42. package/server/controllers/apps/actions/proxyDelete.d.ts +2 -0
  43. package/server/controllers/apps/actions/proxyDelete.js +4 -0
  44. package/server/controllers/apps/actions/proxyGet.d.ts +2 -0
  45. package/server/controllers/apps/actions/proxyGet.js +4 -0
  46. package/server/controllers/apps/actions/proxyPatch.d.ts +2 -0
  47. package/server/controllers/apps/actions/proxyPatch.js +4 -0
  48. package/server/controllers/apps/actions/proxyPost.d.ts +2 -0
  49. package/server/controllers/apps/actions/proxyPost.js +4 -0
  50. package/server/controllers/apps/actions/proxyPut.d.ts +2 -0
  51. package/server/controllers/apps/actions/proxyPut.js +4 -0
  52. package/server/controllers/apps/index.d.ts +2 -0
  53. package/server/controllers/apps/index.js +3 -0
  54. package/server/controllers/apps/members/current/getCurrentAppMember.d.ts +2 -0
  55. package/server/controllers/apps/members/current/getCurrentAppMember.js +4 -0
  56. package/server/controllers/apps/members/current/index.d.ts +1 -0
  57. package/server/controllers/apps/members/current/index.js +2 -0
  58. package/server/controllers/apps/members/index.d.ts +1 -0
  59. package/server/controllers/apps/members/index.js +2 -0
  60. package/server/controllers/common/apps/assets/getAppAssetById.d.ts +2 -0
  61. package/server/controllers/common/apps/assets/getAppAssetById.js +4 -0
  62. package/server/controllers/common/apps/assets/index.d.ts +1 -0
  63. package/server/controllers/common/apps/assets/index.js +2 -0
  64. package/server/controllers/common/apps/groups/getAppGroups.d.ts +2 -0
  65. package/server/controllers/common/apps/groups/getAppGroups.js +4 -0
  66. package/server/controllers/common/apps/groups/index.d.ts +1 -0
  67. package/server/controllers/common/apps/groups/index.js +2 -0
  68. package/server/controllers/common/apps/index.d.ts +5 -0
  69. package/server/controllers/common/apps/index.js +6 -0
  70. package/server/controllers/common/apps/messages/getAppMessages.d.ts +2 -0
  71. package/server/controllers/common/apps/messages/getAppMessages.js +4 -0
  72. package/server/controllers/common/apps/messages/index.d.ts +1 -0
  73. package/server/controllers/common/apps/messages/index.js +2 -0
  74. package/server/controllers/common/apps/resources/countAppResources.d.ts +2 -0
  75. package/server/controllers/common/apps/resources/countAppResources.js +4 -0
  76. package/server/controllers/common/apps/resources/createAppResource.d.ts +2 -0
  77. package/server/controllers/common/apps/resources/createAppResource.js +4 -0
  78. package/server/controllers/common/apps/resources/deleteAppResource.d.ts +2 -0
  79. package/server/controllers/common/apps/resources/deleteAppResource.js +4 -0
  80. package/server/controllers/common/apps/resources/getAppResourceById.d.ts +2 -0
  81. package/server/controllers/common/apps/resources/getAppResourceById.js +4 -0
  82. package/server/controllers/common/apps/resources/index.d.ts +6 -0
  83. package/server/controllers/common/apps/resources/index.js +7 -0
  84. package/server/controllers/common/apps/resources/queryAppResources.d.ts +2 -0
  85. package/server/controllers/common/apps/resources/queryAppResources.js +4 -0
  86. package/server/controllers/common/apps/resources/updateAppResource.d.ts +2 -0
  87. package/server/controllers/common/apps/resources/updateAppResource.js +4 -0
  88. package/server/controllers/common/apps/variables/getAppVariables.js +4 -0
  89. package/server/controllers/common/apps/variables/index.d.ts +1 -0
  90. package/server/controllers/common/apps/variables/index.js +2 -0
  91. package/server/controllers/common/index.d.ts +1 -0
  92. package/server/controllers/common/index.js +2 -0
  93. package/server/controllers/index.d.ts +3 -8
  94. package/server/controllers/index.js +3 -8
  95. package/server/controllers/main/apps/assets/createAppAsset.d.ts +2 -0
  96. package/server/controllers/main/apps/assets/createAppAsset.js +4 -0
  97. package/server/controllers/main/apps/assets/index.d.ts +1 -0
  98. package/server/controllers/main/apps/assets/index.js +2 -0
  99. package/server/controllers/main/apps/index.d.ts +1 -0
  100. package/server/controllers/main/apps/index.js +2 -0
  101. package/server/controllers/main/index.d.ts +1 -0
  102. package/server/controllers/main/index.js +2 -0
  103. package/server/options/checkAppMemberAppPermissions.d.ts +1 -0
  104. package/server/options/checkAppMemberAppPermissions.js +4 -0
  105. package/server/options/checkAppPermissions.d.ts +1 -0
  106. package/server/options/checkAppPermissions.js +4 -0
  107. package/server/options/checkAuthSubjectAppPermissions.d.ts +1 -0
  108. package/server/options/checkAuthSubjectAppPermissions.js +4 -0
  109. package/server/options/checkUserOrganizationPermissions.d.ts +1 -0
  110. package/server/options/checkUserOrganizationPermissions.js +4 -0
  111. package/server/options/getAppGroups.d.ts +2 -0
  112. package/server/options/getAppGroups.js +4 -0
  113. package/server/options/getCurrentAppMember.d.ts +3 -0
  114. package/server/options/getCurrentAppMember.js +4 -0
  115. package/server/options/index.d.ts +6 -5
  116. package/server/options/index.js +6 -5
  117. package/server/options/options.js +7 -6
  118. package/templates/apps/empty/app-definition.yaml +2 -2
  119. package/templates/blocks/mini-jsx/package.json +1 -1
  120. package/templates/blocks/preact/package.json +2 -2
  121. package/templates/blocks/vanilla/package.json +1 -1
  122. package/vitest.setup.js +11 -0
  123. package/commands/team/member/update.d.ts +0 -16
  124. package/commands/team/member/update.js +0 -46
  125. package/lib/team.d.ts +0 -61
  126. package/lib/team.js +0 -83
  127. package/lib/team.test.js +0 -625
  128. package/server/controllers/action.d.ts +0 -6
  129. package/server/controllers/action.js +0 -8
  130. package/server/controllers/appMembers.d.ts +0 -2
  131. package/server/controllers/appMembers.js +0 -4
  132. package/server/controllers/appMessages.d.ts +0 -2
  133. package/server/controllers/appMessages.js +0 -4
  134. package/server/controllers/appVariables.js +0 -4
  135. package/server/controllers/assets.d.ts +0 -4
  136. package/server/controllers/assets.js +0 -6
  137. package/server/controllers/oauth2Provider.d.ts +0 -2
  138. package/server/controllers/oauth2Provider.js +0 -4
  139. package/server/controllers/resources.d.ts +0 -7
  140. package/server/controllers/resources.js +0 -9
  141. package/server/controllers/teams.d.ts +0 -2
  142. package/server/controllers/teams.js +0 -4
  143. package/server/options/checkRole.d.ts +0 -1
  144. package/server/options/checkRole.js +0 -2
  145. package/server/options/checkRole.test.d.ts +0 -1
  146. package/server/options/checkRole.test.js +0 -13
  147. package/server/options/getAppMembers.d.ts +0 -3
  148. package/server/options/getAppMembers.js +0 -4
  149. package/server/options/getAppTeams.d.ts +0 -2
  150. package/server/options/getAppTeams.js +0 -4
  151. package/server/options/getAppUserInfo.d.ts +0 -3
  152. package/server/options/getAppUserInfo.js +0 -4
  153. package/server/options/verifyResourceActionPermission.d.ts +0 -1
  154. package/server/options/verifyResourceActionPermission.js +0 -2
  155. /package/lib/{team.test.d.ts → group.test.d.ts} +0 -0
  156. /package/server/controllers/{appVariables.d.ts → common/apps/variables/getAppVariables.d.ts} +0 -0
@@ -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
- beforeEach(() => {
9
- vi.spyOn(process, 'cwd').mockReturnValue(resolveFixture('.'));
10
- });
11
- describe('getProjectImplementations', () => {
12
- it('should extract configuration from a TypeScript project', () => {
13
- const result = getProjectImplementations({
14
- name: '',
15
- layout: 'float',
16
- version: '1.33.7',
17
- webpack: '',
18
- output: '',
19
- dir: resolveFixture('getProjectImplementations/valid'),
20
- });
21
- expect(result).toStrictEqual({
22
- actions: { testAction: { description: undefined } },
23
- events: {
24
- emit: { testEmit: { description: undefined } },
25
- listen: { testListener: { description: undefined } },
26
- },
27
- messages: undefined,
28
- parameters: {
29
- $schema: 'http://json-schema.org/draft-07/schema#',
30
- additionalProperties: false,
31
- properties: {
32
- param1: { type: 'string' },
33
- param2: { type: 'number' },
34
- param3: { type: 'boolean' },
35
- param4: { type: 'string' },
36
- param5: {
37
- additionalProperties: false,
38
- properties: {
39
- nested1: { type: 'string' },
40
- nested2: { type: 'number' },
41
- nested3: { type: 'boolean' },
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
- required: ['nested1', 'nested2', 'nested3'],
44
- type: 'object',
47
+ param6: { items: { type: 'string' }, type: 'array' },
45
48
  },
46
- param6: { items: { type: 'string' }, type: 'array' },
49
+ required: ['param1', 'param2', 'param3', 'param5', 'param6'],
50
+ type: 'object',
47
51
  },
48
- required: ['param1', 'param2', 'param3', 'param5', 'param6'],
49
- type: 'object',
50
- },
52
+ });
51
53
  });
52
- });
53
- // Spying on TypeScript functions no longer works.
54
- // eslint-disable-next-line vitest/no-disabled-tests
55
- it.skip('should not use TypeScript if all metadata is present in the original config', () => {
56
- vi.spyOn(ts, 'createProgram');
57
- const input = {
58
- actions: {},
59
- events: { emit: { foo: {} }, listen: { bar: {} } },
60
- layout: 'float',
61
- parameters: { type: 'object' },
62
- version: '1.33.7',
63
- webpack: '',
64
- output: '',
65
- dir: resolveFixture('getProjectImplementations/valid'),
66
- name: '',
67
- };
68
- const result = getProjectImplementations(input);
69
- expect(result).toBe(input);
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
- expect(result.actions).toStrictEqual({});
82
- });
83
- it('should prefer events overrides over TypeScript events', () => {
84
- const result = getProjectImplementations({
85
- events: { emit: { onSuccess: {} } },
86
- version: '1.33.7',
87
- webpack: '',
88
- output: '',
89
- dir: resolveFixture('getProjectImplementations/valid'),
90
- name: '',
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
- expect(result.events).toStrictEqual({ emit: { onSuccess: {} } });
93
- });
94
- it('should prefer parameters overrides over TypeScript parameters', () => {
95
- const result = getProjectImplementations({
96
- parameters: { type: 'object' },
97
- version: '1.33.7',
98
- webpack: '',
99
- output: '',
100
- dir: resolveFixture('getProjectImplementations/valid'),
101
- name: '',
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
- expect(result.parameters).toStrictEqual({ type: 'object' });
104
- });
105
- it('should throw if duplicate Actions are found', () => {
106
- expect(() => getProjectImplementations({
107
- webpack: '',
108
- output: '',
109
- dir: resolveFixture('getProjectImplementations/duplicateActions'),
110
- name: '',
111
- version: '1.33.7',
112
- })).toThrow(new AppsembleError("Found duplicate interface 'Actions' in 'getProjectImplementations/duplicateActions/index.ts:31'"));
113
- });
114
- it('should throw if duplicate EventEmitters are found', () => {
115
- expect(() => getProjectImplementations({
116
- webpack: '',
117
- output: '',
118
- dir: resolveFixture('getProjectImplementations/duplicateEventEmitters'),
119
- name: '',
120
- version: '1.33.7',
121
- })).toThrow(new AppsembleError("Found duplicate interface 'EventEmitters' in 'getProjectImplementations/duplicateEventEmitters/index.ts:31'"));
122
- });
123
- it('should throw if duplicate EventListeners are found', () => {
124
- expect(() => getProjectImplementations({
125
- webpack: '',
126
- output: '',
127
- dir: resolveFixture('getProjectImplementations/duplicateEventListeners'),
128
- name: '',
129
- version: '1.33.7',
130
- })).toThrow(new AppsembleError("Found duplicate interface 'EventListeners' in 'getProjectImplementations/duplicateEventListeners/index.ts:31'"));
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
- expect(result).toStrictEqual({
150
- actions: undefined,
151
- events: undefined,
152
- messages: undefined,
153
- parameters: {
154
- $schema: 'http://json-schema.org/draft-07/schema#',
155
- additionalProperties: false,
156
- properties: {
157
- icon: { description: 'This is an icon.', format: 'fontawesome', type: 'string' },
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
- type: 'object',
160
- },
162
+ });
161
163
  });
162
- });
163
- it('should handle TypeScript pre emit diagnostics', () => {
164
- function fn() {
165
- getProjectImplementations({
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/tsError'),
185
+ dir: resolveFixture('getProjectImplementations/comments'),
172
186
  });
173
- }
174
- expect(fn).toThrow(AppsembleError);
175
- expect(fn).toThrow(/'unused' is declared but its value is never read/);
176
- });
177
- it('should extract comments', () => {
178
- const result = getProjectImplementations({
179
- name: '',
180
- layout: 'float',
181
- version: '1.33.7',
182
- webpack: '',
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
- listen: {
205
- testListener: {
206
- description: 'Test event listener.',
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
- messages: undefined,
211
- parameters: {
212
- $schema: 'http://json-schema.org/draft-07/schema#',
213
- additionalProperties: false,
214
- properties: {
215
- param: {},
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
- required: ['param'],
218
- type: 'object',
219
- },
221
+ });
220
222
  });
221
- });
222
- describe('official blocks', () => {
223
- const blocksDir = new URL('../../../blocks/', import.meta.url);
224
- it.each(readdirSync(blocksDir))('%s', (name) => {
225
- const dir = fileURLToPath(new URL(name, blocksDir));
226
- const result = getProjectImplementations({
227
- name,
228
- version: '',
229
- output: '',
230
- webpack: undefined,
231
- dir,
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
  });
@@ -36,7 +36,9 @@ export function createApiServer({ context }) {
36
36
  app.use(compress());
37
37
  }
38
38
  app.use(compose([
39
- conditional((ctx) => ctx.path.startsWith('/api') || ctx.path === '/oauth2/token', cors()),
39
+ conditional((ctx) => ctx.path.startsWith('/api') ||
40
+ ctx.path === '/auth/oauth2/token' ||
41
+ /\/apps\/\d+\/auth\/oauth2\/token/.test(ctx.path), cors()),
40
42
  koas(api(version, argv), [
41
43
  parameters(),
42
44
  bodyParser(),
package/lib/group.d.ts ADDED
@@ -0,0 +1,61 @@
1
+ import { type AppRole } from '@appsemble/types';
2
+ interface SharedGroupParams {
3
+ /**
4
+ * The ID of the app to create the group for.
5
+ */
6
+ appId: number;
7
+ /**
8
+ * The remote server to create the group on.
9
+ */
10
+ remote: string;
11
+ /**
12
+ * The client credentials used to authenticate
13
+ */
14
+ clientCredentials?: string;
15
+ }
16
+ interface SharedExistingGroupParams extends SharedGroupParams {
17
+ /**
18
+ * The ID of the group.
19
+ */
20
+ id: number;
21
+ }
22
+ interface SharedGroupMemberParams extends SharedExistingGroupParams {
23
+ /**
24
+ * The ID or email address of the group member.
25
+ */
26
+ user: string;
27
+ }
28
+ interface UpdateGroupMemberParams extends SharedGroupMemberParams {
29
+ /**
30
+ * The new role of the group member.
31
+ */
32
+ role: AppRole;
33
+ }
34
+ interface UpdateGroupParams extends SharedExistingGroupParams {
35
+ /**
36
+ * The new name of the group.
37
+ */
38
+ name?: string;
39
+ /**
40
+ * The list of annotations to apply in key=value format.
41
+ */
42
+ annotations?: string[];
43
+ }
44
+ interface CreateGroupParams extends SharedGroupParams {
45
+ /**
46
+ * The name of the group.
47
+ */
48
+ name: string;
49
+ /**
50
+ * The list of annotations to apply in key=value format.
51
+ */
52
+ annotations?: string[];
53
+ }
54
+ export declare function resolveAnnotations(annotations: string[]): Record<string, string>;
55
+ export declare function createGroup({ annotations, appId, clientCredentials, name, remote, }: CreateGroupParams): Promise<void>;
56
+ export declare function deleteGroup({ clientCredentials, id, remote, }: SharedExistingGroupParams): Promise<void>;
57
+ export declare function updateGroup({ annotations, id, name, remote, }: UpdateGroupParams): Promise<void>;
58
+ export declare function inviteMember({ id, remote, user }: SharedGroupMemberParams): Promise<void>;
59
+ export declare function updateMember({ id, remote, role, user, }: UpdateGroupMemberParams): Promise<void>;
60
+ export declare function deleteMember({ id, user }: SharedGroupMemberParams): Promise<void>;
61
+ export {};
package/lib/group.js ADDED
@@ -0,0 +1,55 @@
1
+ import { AppsembleError, authenticate, logger } from '@appsemble/node-utils';
2
+ import axios from 'axios';
3
+ export function resolveAnnotations(annotations) {
4
+ const annotationRegex = /^\w+=.+$/;
5
+ if (annotations.some((a) => !annotationRegex.test(a))) {
6
+ throw new AppsembleError('One of the annotations did not follow the pattern of key=value');
7
+ }
8
+ return annotations.length
9
+ ? Object.fromEntries(annotations.map((annotation) => {
10
+ const [key, ...value] = annotation.split('=');
11
+ return [key, value.join('=')];
12
+ }))
13
+ : undefined;
14
+ }
15
+ export async function createGroup({ annotations = [], appId, clientCredentials, name, remote, }) {
16
+ logger.info(`Creating group ${name}`);
17
+ await authenticate(remote, 'groups:write', clientCredentials);
18
+ const { data: { id }, } = await axios.post(`/api/apps/${appId}/groups`, {
19
+ name,
20
+ annotations: resolveAnnotations(annotations),
21
+ }, { baseURL: remote });
22
+ logger.info(`Successfully created group ${name} with ID ${id}`);
23
+ }
24
+ export async function deleteGroup({ clientCredentials, id, remote, }) {
25
+ await authenticate(remote, 'groups:write', clientCredentials);
26
+ logger.info(`Deleting group ${id}`);
27
+ await axios.delete(`/api/groups/${id}`, { baseURL: remote });
28
+ logger.info(`Successfully deleted group ${id}`);
29
+ }
30
+ export async function updateGroup({ annotations = [], id, name, remote, }) {
31
+ logger.info(`Updating group ${id}`);
32
+ await axios.patch(`/api/groups/${id}`, {
33
+ name,
34
+ annotations: resolveAnnotations(annotations),
35
+ }, { baseURL: remote });
36
+ logger.info(`Successfully updated group ${id}`);
37
+ }
38
+ export async function inviteMember({ id, remote, user }) {
39
+ logger.info(`Inviting ${user} to group ${id}`);
40
+ await axios.post(`/api/groups/${id}/invites`, [{ email: user, role: 'Member' }], {
41
+ baseURL: remote,
42
+ });
43
+ logger.info(`Successfully invited ${user} to group ${id}`);
44
+ }
45
+ export async function updateMember({ id, remote, role, user, }) {
46
+ logger.info(`Updating ${user}’s role in group ${id} to ${role}`);
47
+ await axios.put(`/api/group-members/${user}/role`, { role }, { baseURL: remote });
48
+ logger.info(`Successfully updated ${user} in group ${id}`);
49
+ }
50
+ export async function deleteMember({ id, user }) {
51
+ logger.info(`Deleting ${user} to group ${id}`);
52
+ await axios.delete(`/api/group-members/${user}?selectedGroupId=${id}`);
53
+ logger.info(`Successfully deleted ${user} from group ${id}`);
54
+ }
55
+ //# sourceMappingURL=group.js.map