@appsemble/cli 0.28.6 → 0.28.8
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/commands/team/create.js +2 -2
- package/commands/team/update.js +8 -0
- package/lib/app.js +5 -2
- package/lib/app.test.js +109 -3
- package/lib/block.test.js +110 -26
- package/lib/organization.test.js +17 -19
- package/lib/team.test.js +15 -1
- package/package.json +6 -6
- 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 +2 -1
package/README.md
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
#  Appsemble CLI
|
|
2
2
|
|
|
3
3
|
> Manage apps and blocks from the command line.
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/@appsemble/cli)
|
|
6
|
-
[](https://gitlab.com/appsemble/appsemble/-/releases/0.28.8)
|
|
7
7
|
[](https://prettier.io)
|
|
8
8
|
|
|
9
9
|
## Table of Contents
|
|
@@ -323,5 +323,5 @@ appsemble run-cronjobs --interval 30
|
|
|
323
323
|
|
|
324
324
|
## License
|
|
325
325
|
|
|
326
|
-
[LGPL-3.0-only](https://gitlab.com/appsemble/appsemble/-/blob/0.28.
|
|
326
|
+
[LGPL-3.0-only](https://gitlab.com/appsemble/appsemble/-/blob/0.28.8/LICENSE.md) ©
|
|
327
327
|
[Appsemble](https://appsemble.com)
|
package/commands/team/create.js
CHANGED
|
@@ -18,11 +18,11 @@ export function builder(yargs) {
|
|
|
18
18
|
})
|
|
19
19
|
.option('app', {
|
|
20
20
|
describe: 'The path to the app.',
|
|
21
|
-
|
|
21
|
+
implies: 'context',
|
|
22
22
|
})
|
|
23
23
|
.option('context', {
|
|
24
24
|
describe: 'If specified, use the specified context from .appsemblerc.yaml',
|
|
25
|
-
|
|
25
|
+
implies: 'app',
|
|
26
26
|
});
|
|
27
27
|
}
|
|
28
28
|
export async function handler({ annotation, app, appId, clientCredentials, context, name, remote, }) {
|
package/commands/team/update.js
CHANGED
|
@@ -15,6 +15,14 @@ export function builder(yargs) {
|
|
|
15
15
|
.option('annotation', {
|
|
16
16
|
type: 'array',
|
|
17
17
|
describe: 'The new list of annotations. The format is key=value.',
|
|
18
|
+
})
|
|
19
|
+
.option('app', {
|
|
20
|
+
describe: 'The path to the app.',
|
|
21
|
+
implies: 'context',
|
|
22
|
+
})
|
|
23
|
+
.option('context', {
|
|
24
|
+
describe: 'If specified, use the specified context from .appsemblerc.yaml to resolve appId and remote',
|
|
25
|
+
implies: 'app',
|
|
18
26
|
})
|
|
19
27
|
.option('app-id', {
|
|
20
28
|
describe: 'The ID of the app to delete the team from.',
|
package/lib/app.js
CHANGED
|
@@ -678,16 +678,19 @@ export async function resolveAppIdAndRemote(appPath, name, defaultRemote, defaul
|
|
|
678
678
|
const rcPath = join(appPath, '.appsemblerc.yaml');
|
|
679
679
|
const [rc] = await readData(rcPath);
|
|
680
680
|
const context = (_a = rc.context) === null || _a === void 0 ? void 0 : _a[name];
|
|
681
|
-
if (
|
|
681
|
+
if (context === null || context === void 0 ? void 0 : context.id) {
|
|
682
682
|
id = context === null || context === void 0 ? void 0 : context.id;
|
|
683
683
|
}
|
|
684
|
-
if (context.remote) {
|
|
684
|
+
if (context === null || context === void 0 ? void 0 : context.remote) {
|
|
685
685
|
resolvedRemote = context.remote;
|
|
686
686
|
}
|
|
687
687
|
}
|
|
688
688
|
if (id == null) {
|
|
689
689
|
throw new AppsembleError(`App ID was not found in context.${name}.id nor in --app-id`);
|
|
690
690
|
}
|
|
691
|
+
if (resolvedRemote == null) {
|
|
692
|
+
throw new AppsembleError(`App remote was not found in context.${name}.remote nor in --remote`);
|
|
693
|
+
}
|
|
691
694
|
return [id, coerceRemote(resolvedRemote)];
|
|
692
695
|
}
|
|
693
696
|
/**
|
package/lib/app.test.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import { writeFile } from 'node:fs/promises';
|
|
1
2
|
import { readFixture, resolveFixture } from '@appsemble/node-utils';
|
|
2
3
|
import { createServer, createTestUser, models, setArgv, useTestDatabase } from '@appsemble/server';
|
|
3
4
|
import { ISODateTimePattern } from '@appsemble/utils';
|
|
4
5
|
import { setTestApp } from 'axios-test-instance';
|
|
5
6
|
import FormData from 'form-data';
|
|
6
7
|
import { afterAll, beforeAll, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
7
|
-
import { deleteApp, patchApp, publishApp, traverseAppDirectory, updateApp } from './app.js';
|
|
8
|
+
import { deleteApp, patchApp, publishApp, resolveAppIdAndRemote, traverseAppDirectory, updateApp, writeAppMessages, } from './app.js';
|
|
8
9
|
import { initAxios } from './initAxios.js';
|
|
9
10
|
import { authorizeCLI } from './testUtils.js';
|
|
10
11
|
const { App, AppBlockStyle, AppCollection, AppCollectionApp, AppMessages, AppOAuth2Secret, AppSamlSecret, AppScreenshot, AppServiceSecret, AppVariable, Asset, BlockVersion, Organization, OrganizationMember, Resource, } = models;
|
|
@@ -179,7 +180,8 @@ describe('publishApp', () => {
|
|
|
179
180
|
expect(asset).toStrictEqual([]);
|
|
180
181
|
});
|
|
181
182
|
it('should throw an error if the user doesn’t have enough scope permissions', async () => {
|
|
182
|
-
const clientCredentials = await authorizeCLI('
|
|
183
|
+
const clientCredentials = await authorizeCLI('', testApp);
|
|
184
|
+
vi.useRealTimers();
|
|
183
185
|
await expect(() => publishApp({
|
|
184
186
|
path: resolveFixture('apps/test'),
|
|
185
187
|
organization: organization.id,
|
|
@@ -188,10 +190,26 @@ describe('publishApp', () => {
|
|
|
188
190
|
// Required defaults
|
|
189
191
|
visibility: 'unlisted',
|
|
190
192
|
iconBackground: '#ffffff',
|
|
191
|
-
})).rejects.toThrow('
|
|
193
|
+
})).rejects.toThrow('Request failed with status code 401');
|
|
194
|
+
vi.useFakeTimers();
|
|
192
195
|
const app = await App.findOne();
|
|
193
196
|
expect(app).toBeNull();
|
|
194
197
|
});
|
|
198
|
+
it('should not publish if dryRun is specified', async () => {
|
|
199
|
+
const clientCredentials = await authorizeCLI('apps:write resources:write', testApp);
|
|
200
|
+
await publishApp({
|
|
201
|
+
path: resolveFixture('apps/test'),
|
|
202
|
+
organization: organization.id,
|
|
203
|
+
remote: testApp.defaults.baseURL,
|
|
204
|
+
clientCredentials,
|
|
205
|
+
// Required defaults
|
|
206
|
+
visibility: 'unlisted',
|
|
207
|
+
iconBackground: '#ffffff',
|
|
208
|
+
dryRun: true,
|
|
209
|
+
});
|
|
210
|
+
const apps = await App.findAll();
|
|
211
|
+
expect(apps).toStrictEqual([]);
|
|
212
|
+
});
|
|
195
213
|
it('should publish app with resources and assets', async () => {
|
|
196
214
|
vi.useRealTimers();
|
|
197
215
|
const clientCredentials = await authorizeCLI('apps:write resources:write', testApp);
|
|
@@ -943,6 +961,30 @@ describe('updateApp', () => {
|
|
|
943
961
|
const asset = await Asset.findAll();
|
|
944
962
|
expect(asset).toStrictEqual([]);
|
|
945
963
|
});
|
|
964
|
+
it('should throw an error if the user doesn’t have enough scope permissions', async () => {
|
|
965
|
+
const clientCredentials = await authorizeCLI('', testApp);
|
|
966
|
+
vi.useRealTimers();
|
|
967
|
+
await expect(() => updateApp({
|
|
968
|
+
id: app.id,
|
|
969
|
+
force: false,
|
|
970
|
+
path: resolveFixture('apps/test'),
|
|
971
|
+
remote: testApp.defaults.baseURL,
|
|
972
|
+
clientCredentials,
|
|
973
|
+
// Required defaults
|
|
974
|
+
visibility: 'unlisted',
|
|
975
|
+
iconBackground: '#ffffff',
|
|
976
|
+
})).rejects.toThrow('Request failed with status code 401');
|
|
977
|
+
vi.useFakeTimers();
|
|
978
|
+
await app.reload();
|
|
979
|
+
expect(app).toMatchObject({
|
|
980
|
+
path: 'test-app',
|
|
981
|
+
definition: { name: 'Test App', defaultPage: 'Test Page' },
|
|
982
|
+
vapidPublicKey: 'a',
|
|
983
|
+
vapidPrivateKey: 'b',
|
|
984
|
+
visibility: 'public',
|
|
985
|
+
OrganizationId: organization.id,
|
|
986
|
+
});
|
|
987
|
+
});
|
|
946
988
|
it('should update app with resources and assets', async () => {
|
|
947
989
|
vi.useRealTimers();
|
|
948
990
|
const clientCredentials = await authorizeCLI('apps:write resources:write', testApp);
|
|
@@ -1973,6 +2015,13 @@ describe('traverseAppDirectory', () => {
|
|
|
1973
2015
|
}, `
|
|
1974
2016
|
{
|
|
1975
2017
|
"context": {
|
|
2018
|
+
"notFound": {
|
|
2019
|
+
"organization": "testorganization",
|
|
2020
|
+
},
|
|
2021
|
+
"resolve": {
|
|
2022
|
+
"id": 5,
|
|
2023
|
+
"remote": "http://localhost:5555",
|
|
2024
|
+
},
|
|
1976
2025
|
"test": {
|
|
1977
2026
|
"appLock": "studioLock",
|
|
1978
2027
|
"assets": true,
|
|
@@ -2072,6 +2121,32 @@ describe('traverseAppDirectory', () => {
|
|
|
2072
2121
|
await expect(() => traverseAppDirectory(resolveFixture('apps/empty'), null, formData)).rejects.toThrow('No app definition found');
|
|
2073
2122
|
});
|
|
2074
2123
|
});
|
|
2124
|
+
describe('resolveAppIdAndRemote', () => {
|
|
2125
|
+
it('should find and return app id and remote from appsembleRC', async () => {
|
|
2126
|
+
const [appId, remote] = await resolveAppIdAndRemote(resolveFixture('apps/test'), 'resolve', 'http://localhost:8888', 55);
|
|
2127
|
+
expect(appId).toBe(5);
|
|
2128
|
+
expect(remote).toBe('http://localhost:5555/');
|
|
2129
|
+
});
|
|
2130
|
+
it('should fallback to default appId and remote if not found in context', async () => {
|
|
2131
|
+
const [appId, remote] = await resolveAppIdAndRemote(resolveFixture('apps/test'), 'notFound', 'http://localhost:8888', 55);
|
|
2132
|
+
expect(appId).toBe(55);
|
|
2133
|
+
expect(remote).toBe('http://localhost:8888/');
|
|
2134
|
+
});
|
|
2135
|
+
it('should throw if the appId is not found in context and defaultAppId is not specified', async () => {
|
|
2136
|
+
await expect(() => resolveAppIdAndRemote(resolveFixture('apps/test'), 'notFound', 'http://localhost:8888', null)).rejects.toThrow('App ID was not found');
|
|
2137
|
+
});
|
|
2138
|
+
it('should throw if the remote is not found in context and defaultAppRemote is not specified', async () => {
|
|
2139
|
+
const app = await App.create({
|
|
2140
|
+
path: 'test-app',
|
|
2141
|
+
definition: { name: 'Test App', defaultPage: 'Test Page' },
|
|
2142
|
+
vapidPublicKey: 'a',
|
|
2143
|
+
vapidPrivateKey: 'b',
|
|
2144
|
+
visibility: 'public',
|
|
2145
|
+
OrganizationId: organization.id,
|
|
2146
|
+
});
|
|
2147
|
+
await expect(() => resolveAppIdAndRemote(resolveFixture('apps/test'), 'notFound', null, app.id)).rejects.toThrow('App remote was not found');
|
|
2148
|
+
});
|
|
2149
|
+
});
|
|
2075
2150
|
describe('deleteApp', () => {
|
|
2076
2151
|
it('should throw if an error occurs', async () => {
|
|
2077
2152
|
const clientCredentials = await authorizeCLI('apps:delete', testApp);
|
|
@@ -2092,4 +2167,35 @@ describe('deleteApp', () => {
|
|
|
2092
2167
|
expect(foundApps).toStrictEqual([]);
|
|
2093
2168
|
});
|
|
2094
2169
|
});
|
|
2170
|
+
describe('writeAppMessages', () => {
|
|
2171
|
+
it('should extract messages from app-definition and write to file in i18n directory', async () => {
|
|
2172
|
+
const initialMessages = JSON.parse(String(await readFixture('apps/test-messages/i18n/nl.json')));
|
|
2173
|
+
expect(initialMessages).toMatchObject({
|
|
2174
|
+
app: {},
|
|
2175
|
+
});
|
|
2176
|
+
await writeAppMessages(resolveFixture('apps/test-messages'), ['nl'], [], 'json');
|
|
2177
|
+
const messages = JSON.parse(String(await readFixture('apps/test-messages/i18n/nl.json')));
|
|
2178
|
+
expect(messages).toMatchObject({
|
|
2179
|
+
app: {
|
|
2180
|
+
description: '',
|
|
2181
|
+
name: '',
|
|
2182
|
+
'pages.test-page': '',
|
|
2183
|
+
},
|
|
2184
|
+
});
|
|
2185
|
+
await writeFile(resolveFixture('apps/test-messages/i18n/nl.json'), JSON.stringify(initialMessages, null, '\t'));
|
|
2186
|
+
});
|
|
2187
|
+
it('should throw if the language file does not exist', async () => {
|
|
2188
|
+
await expect(() => writeAppMessages(resolveFixture('apps/test-messages'), ['hr'], [], 'json')).rejects.toThrow('Missing translations file');
|
|
2189
|
+
});
|
|
2190
|
+
it('should throw if there are empty messages in a verified file', async () => {
|
|
2191
|
+
const initialMessages = JSON.parse(String(await readFixture('apps/test-messages/i18n/nl.json')));
|
|
2192
|
+
expect(initialMessages).toMatchObject({
|
|
2193
|
+
app: {},
|
|
2194
|
+
});
|
|
2195
|
+
await expect(() => writeAppMessages(resolveFixture('apps/test-messages'), ['nl'], ['nl'], 'json')).rejects.toThrow('Missing translation');
|
|
2196
|
+
});
|
|
2197
|
+
it('should throw if app definition does not exist in the app folder', async () => {
|
|
2198
|
+
await expect(() => writeAppMessages(resolveFixture('apps/empty'), ['nl'], [], 'json')).rejects.toThrow('Couldn’t find app definition');
|
|
2199
|
+
});
|
|
2200
|
+
});
|
|
2095
2201
|
//# sourceMappingURL=app.test.js.map
|
package/lib/block.test.js
CHANGED
|
@@ -2,15 +2,42 @@ import { resolveFixture } from '@appsemble/node-utils';
|
|
|
2
2
|
import { createServer, createTestUser, models, setArgv, useTestDatabase } from '@appsemble/server';
|
|
3
3
|
import { setTestApp } from 'axios-test-instance';
|
|
4
4
|
import concat from 'concat-stream';
|
|
5
|
-
import { beforeAll, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
6
|
-
import { deleteBlock } from './block.js';
|
|
5
|
+
import { afterAll, beforeAll, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
6
|
+
import { deleteBlock, traverseBlockThemes } from './block.js';
|
|
7
7
|
import { initAxios } from './initAxios.js';
|
|
8
8
|
import { makeProjectPayload } from './project.js';
|
|
9
9
|
import { authorizeCLI } from './testUtils.js';
|
|
10
10
|
useTestDatabase(import.meta);
|
|
11
11
|
const argv = { host: 'http://localhost', secret: 'test', aesSecret: 'testSecret' };
|
|
12
12
|
let testApp;
|
|
13
|
-
|
|
13
|
+
let user;
|
|
14
|
+
let organization;
|
|
15
|
+
const { App, AppBlockStyle, BlockVersion, Organization, OrganizationMember, Theme } = models;
|
|
16
|
+
beforeAll(() => {
|
|
17
|
+
vi.useFakeTimers();
|
|
18
|
+
setArgv(argv);
|
|
19
|
+
});
|
|
20
|
+
beforeEach(async () => {
|
|
21
|
+
vi.clearAllTimers();
|
|
22
|
+
vi.setSystemTime(0);
|
|
23
|
+
const server = await createServer();
|
|
24
|
+
testApp = await setTestApp(server);
|
|
25
|
+
initAxios({ remote: testApp.defaults.baseURL });
|
|
26
|
+
user = await createTestUser();
|
|
27
|
+
organization = await Organization.create({
|
|
28
|
+
id: 'testorganization',
|
|
29
|
+
name: 'Test Organization',
|
|
30
|
+
});
|
|
31
|
+
await OrganizationMember.create({
|
|
32
|
+
OrganizationId: organization.id,
|
|
33
|
+
UserId: user.id,
|
|
34
|
+
role: 'Owner',
|
|
35
|
+
});
|
|
36
|
+
await Organization.create({ id: 'appsemble', name: 'Appsemble' });
|
|
37
|
+
});
|
|
38
|
+
afterAll(() => {
|
|
39
|
+
vi.useRealTimers();
|
|
40
|
+
});
|
|
14
41
|
describe('makeProjectPayload', () => {
|
|
15
42
|
it('should create a form-data payload', async () => {
|
|
16
43
|
const payload = await makeProjectPayload({
|
|
@@ -105,29 +132,6 @@ export const string = 'with-icon';
|
|
|
105
132
|
});
|
|
106
133
|
});
|
|
107
134
|
describe('deleteBlock', () => {
|
|
108
|
-
let user;
|
|
109
|
-
let organization;
|
|
110
|
-
beforeAll(() => {
|
|
111
|
-
vi.useFakeTimers();
|
|
112
|
-
setArgv(argv);
|
|
113
|
-
});
|
|
114
|
-
beforeEach(async () => {
|
|
115
|
-
vi.clearAllTimers();
|
|
116
|
-
vi.setSystemTime(0);
|
|
117
|
-
const server = await createServer();
|
|
118
|
-
testApp = await setTestApp(server);
|
|
119
|
-
initAxios({ remote: testApp.defaults.baseURL });
|
|
120
|
-
user = await createTestUser();
|
|
121
|
-
organization = await Organization.create({
|
|
122
|
-
id: 'testorganization',
|
|
123
|
-
name: 'Test Organization',
|
|
124
|
-
});
|
|
125
|
-
await OrganizationMember.create({
|
|
126
|
-
OrganizationId: organization.id,
|
|
127
|
-
UserId: user.id,
|
|
128
|
-
role: 'Owner',
|
|
129
|
-
});
|
|
130
|
-
});
|
|
131
135
|
it('should delete a block', async () => {
|
|
132
136
|
const block = await BlockVersion.create({
|
|
133
137
|
OrganizationId: organization.id,
|
|
@@ -146,4 +150,84 @@ describe('deleteBlock', () => {
|
|
|
146
150
|
expect(foundBlocks).toStrictEqual([]);
|
|
147
151
|
});
|
|
148
152
|
});
|
|
153
|
+
describe('traverseBlockThemes', () => {
|
|
154
|
+
it('should upload css from a file in the app directory', async () => {
|
|
155
|
+
const app = await App.create({
|
|
156
|
+
path: 'test-app',
|
|
157
|
+
definition: { name: 'Test App', defaultPage: 'Test Page' },
|
|
158
|
+
vapidPublicKey: 'a',
|
|
159
|
+
vapidPrivateKey: 'b',
|
|
160
|
+
visibility: 'public',
|
|
161
|
+
OrganizationId: organization.id,
|
|
162
|
+
});
|
|
163
|
+
await BlockVersion.create({
|
|
164
|
+
name: 'test',
|
|
165
|
+
OrganizationId: 'appsemble',
|
|
166
|
+
version: '0.0.0',
|
|
167
|
+
parameters: {
|
|
168
|
+
type: 'object',
|
|
169
|
+
properties: {
|
|
170
|
+
foo: {
|
|
171
|
+
type: 'number',
|
|
172
|
+
},
|
|
173
|
+
},
|
|
174
|
+
},
|
|
175
|
+
});
|
|
176
|
+
await authorizeCLI('apps:write', testApp);
|
|
177
|
+
await traverseBlockThemes(resolveFixture('apps/test'), app.id, testApp.defaults.baseURL, false);
|
|
178
|
+
const style = await AppBlockStyle.findOne();
|
|
179
|
+
expect(style.dataValues).toMatchInlineSnapshot(`
|
|
180
|
+
{
|
|
181
|
+
"AppId": 1,
|
|
182
|
+
"block": "@appsemble/test",
|
|
183
|
+
"created": 1970-01-01T00:00:00.000Z,
|
|
184
|
+
"style": ".tux {
|
|
185
|
+
color: rgb(0 0 0);
|
|
186
|
+
}",
|
|
187
|
+
"updated": 1970-01-01T00:00:00.000Z,
|
|
188
|
+
}
|
|
189
|
+
`);
|
|
190
|
+
});
|
|
191
|
+
it('should throw if the block does not exist', async () => {
|
|
192
|
+
const app = await App.create({
|
|
193
|
+
path: 'test-app',
|
|
194
|
+
definition: { name: 'Test App', defaultPage: 'Test Page' },
|
|
195
|
+
vapidPublicKey: 'a',
|
|
196
|
+
vapidPrivateKey: 'b',
|
|
197
|
+
visibility: 'public',
|
|
198
|
+
OrganizationId: organization.id,
|
|
199
|
+
});
|
|
200
|
+
await authorizeCLI('apps:write', testApp);
|
|
201
|
+
await expect(() => traverseBlockThemes(resolveFixture('apps/test'), app.id, testApp.defaults.baseURL, false)).rejects.toThrow('Request failed with status code 404');
|
|
202
|
+
const style = await AppBlockStyle.findOne();
|
|
203
|
+
expect(style).toBeNull();
|
|
204
|
+
});
|
|
205
|
+
it('should not upload css from core and shared directories', async () => {
|
|
206
|
+
const app = await App.create({
|
|
207
|
+
path: 'test-app',
|
|
208
|
+
definition: { name: 'Test App', defaultPage: 'Test Page' },
|
|
209
|
+
vapidPublicKey: 'a',
|
|
210
|
+
vapidPrivateKey: 'b',
|
|
211
|
+
visibility: 'public',
|
|
212
|
+
OrganizationId: organization.id,
|
|
213
|
+
});
|
|
214
|
+
await BlockVersion.create({
|
|
215
|
+
name: 'test',
|
|
216
|
+
OrganizationId: 'appsemble',
|
|
217
|
+
version: '0.0.0',
|
|
218
|
+
parameters: {
|
|
219
|
+
type: 'object',
|
|
220
|
+
properties: {
|
|
221
|
+
foo: {
|
|
222
|
+
type: 'number',
|
|
223
|
+
},
|
|
224
|
+
},
|
|
225
|
+
},
|
|
226
|
+
});
|
|
227
|
+
await authorizeCLI('apps:write', testApp);
|
|
228
|
+
await traverseBlockThemes(resolveFixture('apps/test'), app.id, testApp.defaults.baseURL, false);
|
|
229
|
+
const style = await Theme.findAll();
|
|
230
|
+
expect(style).toStrictEqual([]);
|
|
231
|
+
});
|
|
232
|
+
});
|
|
149
233
|
//# sourceMappingURL=block.test.js.map
|
package/lib/organization.test.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { createFixtureStream, readFixture } from '@appsemble/node-utils';
|
|
1
2
|
import { createServer, createTestUser, models, setArgv, useTestDatabase } from '@appsemble/server';
|
|
2
3
|
import { setTestApp } from 'axios-test-instance';
|
|
3
4
|
import { afterAll, beforeAll, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
@@ -32,23 +33,18 @@ describe('createOrganization', () => {
|
|
|
32
33
|
id: 'test',
|
|
33
34
|
name: 'Test',
|
|
34
35
|
email: 'test@example.com',
|
|
35
|
-
icon:
|
|
36
|
+
icon: createFixtureStream('apps/tux.png'),
|
|
36
37
|
website: 'https://example.com',
|
|
37
38
|
});
|
|
38
39
|
const organization = await Organization.findOne();
|
|
39
|
-
expect(organization).
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
"name": "Test",
|
|
48
|
-
"updated": 1970-01-01T00:00:00.000Z,
|
|
49
|
-
"website": "https://example.com",
|
|
50
|
-
}
|
|
51
|
-
`);
|
|
40
|
+
expect(organization).toMatchObject({
|
|
41
|
+
description: 'test description',
|
|
42
|
+
email: 'test@example.com',
|
|
43
|
+
icon: await readFixture('apps/tux.png'),
|
|
44
|
+
id: 'test',
|
|
45
|
+
name: 'Test',
|
|
46
|
+
website: 'https://example.com',
|
|
47
|
+
});
|
|
52
48
|
});
|
|
53
49
|
it('should not create a new organization with duplicate id', async () => {
|
|
54
50
|
const organization = await Organization.create({
|
|
@@ -83,19 +79,21 @@ describe('updateOrganization', () => {
|
|
|
83
79
|
await updateOrganization({
|
|
84
80
|
id: organization.id,
|
|
85
81
|
name: 'Test changed',
|
|
86
|
-
description:
|
|
82
|
+
description: 'Description Changed',
|
|
87
83
|
email: 'test@example.com',
|
|
88
84
|
website: null,
|
|
89
|
-
icon:
|
|
85
|
+
icon: createFixtureStream('apps/tux.png'),
|
|
90
86
|
});
|
|
91
87
|
await organization.reload();
|
|
92
|
-
expect(organization.dataValues).toMatchInlineSnapshot(
|
|
88
|
+
expect(organization.dataValues).toMatchInlineSnapshot({
|
|
89
|
+
icon: expect.any(Buffer),
|
|
90
|
+
}, `
|
|
93
91
|
{
|
|
94
92
|
"created": 1970-01-01T00:00:00.000Z,
|
|
95
93
|
"deleted": null,
|
|
96
|
-
"description":
|
|
94
|
+
"description": "Description Changed",
|
|
97
95
|
"email": "test@example.com",
|
|
98
|
-
"icon":
|
|
96
|
+
"icon": Any<Buffer>,
|
|
99
97
|
"id": "test",
|
|
100
98
|
"name": "Test changed",
|
|
101
99
|
"updated": 1970-01-01T00:00:00.000Z,
|
package/lib/team.test.js
CHANGED
|
@@ -3,7 +3,7 @@ import { TeamRole } from '@appsemble/utils';
|
|
|
3
3
|
import { setTestApp } from 'axios-test-instance';
|
|
4
4
|
import { afterAll, beforeAll, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
5
5
|
import { initAxios } from './initAxios.js';
|
|
6
|
-
import { createTeam, deleteMember, deleteTeam, inviteMember, updateMember, updateTeam, } from './team.js';
|
|
6
|
+
import { createTeam, deleteMember, deleteTeam, inviteMember, resolveAnnotations, updateMember, updateTeam, } from './team.js';
|
|
7
7
|
import { authorizeCLI } from './testUtils.js';
|
|
8
8
|
const { App, AppMember, BlockVersion, Organization, OrganizationMember, Team, TeamMember } = models;
|
|
9
9
|
const argv = { host: 'http://localhost', secret: 'test', aesSecret: 'testSecret' };
|
|
@@ -603,4 +603,18 @@ describe('deleteMember', () => {
|
|
|
603
603
|
await expect(() => deleteMember({ appId: app.id, remote: testApp.defaults.baseURL, user: user.id, id: team.id })).rejects.toThrow('Request failed with status code 400');
|
|
604
604
|
});
|
|
605
605
|
});
|
|
606
|
+
describe('resolveAnnotations', () => {
|
|
607
|
+
it('should resolve team annotations', () => {
|
|
608
|
+
const unresolvedAnnotations = ['foo=bar', 'hello=world'];
|
|
609
|
+
const annotations = resolveAnnotations(unresolvedAnnotations);
|
|
610
|
+
expect(annotations).toMatchObject({
|
|
611
|
+
foo: 'bar',
|
|
612
|
+
hello: 'world',
|
|
613
|
+
});
|
|
614
|
+
});
|
|
615
|
+
it('should throw an error if annotations are not in right format', () => {
|
|
616
|
+
const unresolvedAnnotations = ['foo:bar', 'hello.world'];
|
|
617
|
+
expect(() => resolveAnnotations(unresolvedAnnotations)).toThrow('One of the annotations did not follow the pattern of key=value');
|
|
618
|
+
});
|
|
619
|
+
});
|
|
606
620
|
//# sourceMappingURL=team.test.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@appsemble/cli",
|
|
3
|
-
"version": "0.28.
|
|
3
|
+
"version": "0.28.8",
|
|
4
4
|
"description": "The CLI for developing with Appsemble apps and blocks",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"app",
|
|
@@ -42,9 +42,9 @@
|
|
|
42
42
|
"test": "vitest"
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@appsemble/node-utils": "0.28.
|
|
46
|
-
"@appsemble/types": "0.28.
|
|
47
|
-
"@appsemble/utils": "0.28.
|
|
45
|
+
"@appsemble/node-utils": "0.28.8",
|
|
46
|
+
"@appsemble/types": "0.28.8",
|
|
47
|
+
"@appsemble/utils": "0.28.8",
|
|
48
48
|
"@fortawesome/fontawesome-common-types": "^6.0.0",
|
|
49
49
|
"@koa/cors": "^4.0.0",
|
|
50
50
|
"@odata/parser": "^0.2.0",
|
|
@@ -87,8 +87,8 @@
|
|
|
87
87
|
"yargs": "^17.0.0"
|
|
88
88
|
},
|
|
89
89
|
"devDependencies": {
|
|
90
|
-
"@appsemble/types": "0.28.
|
|
91
|
-
"@appsemble/server": "0.28.
|
|
90
|
+
"@appsemble/types": "0.28.8",
|
|
91
|
+
"@appsemble/server": "0.28.8",
|
|
92
92
|
"bcrypt": "^5.0.0",
|
|
93
93
|
"axios-test-instance": "^7.0.0",
|
|
94
94
|
"@types/concat-stream": "^2.0.0",
|
|
@@ -6,7 +6,7 @@ pages:
|
|
|
6
6
|
- name: Example Page A
|
|
7
7
|
blocks:
|
|
8
8
|
- type: action-button
|
|
9
|
-
version: 0.28.
|
|
9
|
+
version: 0.28.8
|
|
10
10
|
parameters:
|
|
11
11
|
icon: arrow-right
|
|
12
12
|
actions:
|
|
@@ -17,7 +17,7 @@ pages:
|
|
|
17
17
|
- name: Example Page B
|
|
18
18
|
blocks:
|
|
19
19
|
- type: action-button
|
|
20
|
-
version: 0.28.
|
|
20
|
+
version: 0.28.8
|
|
21
21
|
parameters:
|
|
22
22
|
icon: arrow-left
|
|
23
23
|
actions:
|
package/vitest.setup.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { setFixtureBase, setLogLevel } from '@appsemble/node-utils';
|
|
1
|
+
import { CREDENTIALS_ENV_VAR, setFixtureBase, setLogLevel } from '@appsemble/node-utils';
|
|
2
2
|
setFixtureBase(import.meta);
|
|
3
|
+
delete process.env[CREDENTIALS_ENV_VAR];
|
|
3
4
|
setLogLevel(0);
|
|
4
5
|
//# sourceMappingURL=vitest.setup.js.map
|