@appsemble/cli 0.29.8 → 0.29.9
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.js +38 -20
- package/lib/asset.js +15 -9
- package/lib/block.js +18 -6
- package/lib/organization.js +16 -4
- package/lib/resource.js +36 -24
- package/lib/team.js +46 -16
- 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/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.29.9)
|
|
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.29.
|
|
326
|
+
[LGPL-3.0-only](https://gitlab.com/appsemble/appsemble/-/blob/0.29.9/LICENSE.md) ©
|
|
327
327
|
[Appsemble](https://appsemble.com)
|
package/lib/app.js
CHANGED
|
@@ -206,14 +206,20 @@ async function retrieveContext(path, context) {
|
|
|
206
206
|
*/
|
|
207
207
|
export async function exportAppAsZip(clientCredentials, appId, assets, resources, path, remote) {
|
|
208
208
|
await authenticate(remote, 'apps:export', clientCredentials);
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
209
|
+
try {
|
|
210
|
+
const response = await axios.get(`/api/apps/${appId}/export?resources=${resources}&assets=${assets}`, {
|
|
211
|
+
baseURL: remote,
|
|
212
|
+
responseType: 'stream',
|
|
213
|
+
});
|
|
214
|
+
const zipFileName = join(path, String(extractFilenameFromContentDisposition(response.headers['content-disposition'])));
|
|
215
|
+
const writeStream = createWriteStream(zipFileName);
|
|
216
|
+
response.data.pipe(writeStream);
|
|
217
|
+
logger.info(`Successfully downloaded file: ${zipFileName}`);
|
|
218
|
+
}
|
|
219
|
+
catch (error) {
|
|
220
|
+
logger.error(error);
|
|
221
|
+
throw error;
|
|
222
|
+
}
|
|
217
223
|
}
|
|
218
224
|
/**
|
|
219
225
|
* Upload messages for an app.
|
|
@@ -238,20 +244,32 @@ export async function uploadMessages(path, appId, remote, force) {
|
|
|
238
244
|
if (!result.length) {
|
|
239
245
|
logger.info('No translations found 🤷');
|
|
240
246
|
}
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
247
|
+
try {
|
|
248
|
+
for (const language of result) {
|
|
249
|
+
await axios.post(`/api/apps/${appId}/messages`, language, { baseURL: remote });
|
|
250
|
+
logger.info(`Successfully uploaded messages for language “${language.language}” 🎉`);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
catch (error) {
|
|
254
|
+
logger.error(error);
|
|
255
|
+
throw error;
|
|
244
256
|
}
|
|
245
257
|
}
|
|
246
258
|
export async function deleteApp({ clientCredentials, id, remote }) {
|
|
247
259
|
await authenticate(remote, 'apps:delete', clientCredentials);
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
260
|
+
try {
|
|
261
|
+
const response = await axios.get(`/api/apps/${id}`);
|
|
262
|
+
const { name } = response.data;
|
|
263
|
+
logger.warn(`Deleting app: ${name}`);
|
|
264
|
+
await axios.delete(`/api/apps/${id}`, {
|
|
265
|
+
baseURL: remote,
|
|
266
|
+
});
|
|
267
|
+
logger.info(`Successfully deleted app with id ${id}`);
|
|
268
|
+
}
|
|
269
|
+
catch (error) {
|
|
270
|
+
logger.error(error);
|
|
271
|
+
throw error;
|
|
272
|
+
}
|
|
255
273
|
}
|
|
256
274
|
export async function publishSeedResources(path, app, remote) {
|
|
257
275
|
var _a, _b;
|
|
@@ -610,7 +628,7 @@ export async function writeAppMessages(path, languages, verify, format) {
|
|
|
610
628
|
}));
|
|
611
629
|
const appMessagePrefixes = Object.keys(newAppMessages);
|
|
612
630
|
for (const [key, message] of Object.entries(oldMessages.app)) {
|
|
613
|
-
const match = /^(pages
|
|
631
|
+
const match = /^(pages\.[\dA-Za-z-]+(\..+)?)\.blocks\.\d+.+/.exec(key);
|
|
614
632
|
if (!match) {
|
|
615
633
|
continue;
|
|
616
634
|
}
|
|
@@ -953,7 +971,7 @@ export async function updateApp({ clientCredentials, context, force, path, ...op
|
|
|
953
971
|
}
|
|
954
972
|
catch (error) {
|
|
955
973
|
logger.error(error);
|
|
956
|
-
|
|
974
|
+
throw error;
|
|
957
975
|
}
|
|
958
976
|
}
|
|
959
977
|
let data;
|
package/lib/asset.js
CHANGED
|
@@ -4,15 +4,21 @@ import { normalize } from '@appsemble/utils';
|
|
|
4
4
|
import axios from 'axios';
|
|
5
5
|
import FormData from 'form-data';
|
|
6
6
|
export async function publishAsset({ appId, clonable, name, path, remote, seed, }) {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
7
|
+
try {
|
|
8
|
+
const formData = new FormData();
|
|
9
|
+
const file = createReadStream(path);
|
|
10
|
+
formData.append('file', file);
|
|
11
|
+
formData.append('clonable', String(clonable));
|
|
12
|
+
if (name) {
|
|
13
|
+
formData.append('name', normalize(name));
|
|
14
|
+
}
|
|
15
|
+
const endpoint = `/api/apps/${appId}/${seed ? 'seed-' : ''}assets`;
|
|
16
|
+
const { data: { id }, } = await axios.post(endpoint, formData, { baseURL: remote });
|
|
17
|
+
logger.info(`Published asset ${id}${name ? ` with name ${normalize(name)}` : ''}`);
|
|
18
|
+
}
|
|
19
|
+
catch (error) {
|
|
20
|
+
logger.error(error);
|
|
21
|
+
throw error;
|
|
13
22
|
}
|
|
14
|
-
const endpoint = `/api/apps/${appId}/${seed ? 'seed-' : ''}assets`;
|
|
15
|
-
const { data: { id }, } = await axios.post(endpoint, formData, { baseURL: remote });
|
|
16
|
-
logger.info(`Published asset ${id}${name ? ` with name ${normalize(name)}` : ''}`);
|
|
17
23
|
}
|
|
18
24
|
//# sourceMappingURL=asset.js.map
|
package/lib/block.js
CHANGED
|
@@ -49,11 +49,17 @@ export async function buildBlock(buildConfig, env) {
|
|
|
49
49
|
});
|
|
50
50
|
}
|
|
51
51
|
export async function deleteBlock({ blockName, blockVersion, clientCredentials, organization, remote, }) {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
52
|
+
try {
|
|
53
|
+
await authenticate(remote, 'blocks:delete', clientCredentials);
|
|
54
|
+
await axios.delete(`/api/blocks/@${organization}/${blockName}/versions/${blockVersion}`, {
|
|
55
|
+
baseURL: remote,
|
|
56
|
+
});
|
|
57
|
+
logger.info(`Successfully deleted ${blockName} block version.`);
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
logger.error(error);
|
|
61
|
+
throw error;
|
|
62
|
+
}
|
|
57
63
|
}
|
|
58
64
|
/**
|
|
59
65
|
* Uploads an app block theme
|
|
@@ -68,7 +74,13 @@ export async function deleteBlock({ blockName, blockVersion, clientCredentials,
|
|
|
68
74
|
export async function uploadAppBlockTheme(filePath, organization, appId, block, remote, force) {
|
|
69
75
|
logger.info(`Upload ${organization}/${block} stylesheet for app ${appId}`);
|
|
70
76
|
const style = await processCss(filePath);
|
|
71
|
-
|
|
77
|
+
try {
|
|
78
|
+
await axios.post(`/api/apps/${appId}/style/block/${organization}/${block}`, { force, style }, { baseURL: remote });
|
|
79
|
+
}
|
|
80
|
+
catch (error) {
|
|
81
|
+
logger.error(error);
|
|
82
|
+
throw error;
|
|
83
|
+
}
|
|
72
84
|
logger.info(`Upload of ${organization}/${block} stylesheet successful! 🎉`);
|
|
73
85
|
}
|
|
74
86
|
/**
|
package/lib/organization.js
CHANGED
|
@@ -25,8 +25,14 @@ export async function createOrganization({ description, email, icon, id, name, w
|
|
|
25
25
|
formData.append('website', website);
|
|
26
26
|
}
|
|
27
27
|
logger.info(`Creating organization ${id}${name ? ` (${name})` : ''}`);
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
try {
|
|
29
|
+
await axios.post('/api/organizations', formData);
|
|
30
|
+
logger.info(`Successfully created organization ${id}${name ? ` (${name})` : ''}`);
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
logger.error(error);
|
|
34
|
+
throw error;
|
|
35
|
+
}
|
|
30
36
|
}
|
|
31
37
|
export async function updateOrganization({ description, email, icon, id, name, website, }) {
|
|
32
38
|
logger.info(`Updating organization ${id}${name ? ` (${name})` : ''}`);
|
|
@@ -51,8 +57,14 @@ export async function updateOrganization({ description, email, icon, id, name, w
|
|
|
51
57
|
logger.info(`Setting website to ${website}`);
|
|
52
58
|
formData.append('website', website);
|
|
53
59
|
}
|
|
54
|
-
|
|
55
|
-
|
|
60
|
+
try {
|
|
61
|
+
await axios.patch(`/api/organizations/${id}`, formData);
|
|
62
|
+
logger.info(`Successfully updated organization ${id}${name ? ` (${name})` : ''}`);
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
logger.error(error);
|
|
66
|
+
throw error;
|
|
67
|
+
}
|
|
56
68
|
}
|
|
57
69
|
export async function upsertOrganization({ description, email, icon, id, name, website, }) {
|
|
58
70
|
var _a;
|
package/lib/resource.js
CHANGED
|
@@ -17,27 +17,33 @@ export async function publishResource({ appId, definition, path, publishedResour
|
|
|
17
17
|
logger.info(`Publishing resource(s) from ${path}`);
|
|
18
18
|
let data;
|
|
19
19
|
const endpoint = `/api/apps/${appId}/${seed ? 'seed-' : ''}resources/${type}`;
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
20
|
+
try {
|
|
21
|
+
if (csv) {
|
|
22
|
+
const response = await axios.post(endpoint, resources, {
|
|
23
|
+
baseURL: remote,
|
|
24
|
+
headers: { 'content-type': 'text/csv' },
|
|
25
|
+
});
|
|
26
|
+
data = response.data;
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
const response = await axios.post(endpoint, resources.map((resource) => {
|
|
30
|
+
var _a, _b, _c;
|
|
31
|
+
const resourceWithReferences = { ...resource };
|
|
32
|
+
for (const [referencedProperty, resourceReference] of Object.entries((_a = definition === null || definition === void 0 ? void 0 : definition.references) !== null && _a !== void 0 ? _a : {})) {
|
|
33
|
+
resourceWithReferences[referencedProperty] =
|
|
34
|
+
(_b = publishedResourcesIds[resourceReference.resource]) === null || _b === void 0 ? void 0 : _b[Number((_c = resource[`$${resourceReference.resource}`]) !== null && _c !== void 0 ? _c : -1)];
|
|
35
|
+
}
|
|
36
|
+
return resourceWithReferences;
|
|
37
|
+
}), {
|
|
38
|
+
baseURL: remote,
|
|
39
|
+
headers: { 'content-type': 'application/json' },
|
|
40
|
+
});
|
|
41
|
+
data = response.data;
|
|
42
|
+
}
|
|
26
43
|
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
const resourceWithReferences = { ...resource };
|
|
31
|
-
for (const [referencedProperty, resourceReference] of Object.entries((_a = definition === null || definition === void 0 ? void 0 : definition.references) !== null && _a !== void 0 ? _a : {})) {
|
|
32
|
-
resourceWithReferences[referencedProperty] =
|
|
33
|
-
(_b = publishedResourcesIds[resourceReference.resource]) === null || _b === void 0 ? void 0 : _b[Number((_c = resource[`$${resourceReference.resource}`]) !== null && _c !== void 0 ? _c : -1)];
|
|
34
|
-
}
|
|
35
|
-
return resourceWithReferences;
|
|
36
|
-
}), {
|
|
37
|
-
baseURL: remote,
|
|
38
|
-
headers: { 'content-type': 'application/json' },
|
|
39
|
-
});
|
|
40
|
-
data = response.data;
|
|
44
|
+
catch (error) {
|
|
45
|
+
logger.error(error);
|
|
46
|
+
throw error;
|
|
41
47
|
}
|
|
42
48
|
const ids = [].concat(data).map((d) => d.id);
|
|
43
49
|
const url = new URL(`/apps/${appId}/resources/${type}/`, remote);
|
|
@@ -92,10 +98,16 @@ export async function updateResource({ appId, path, remote, resourceName, }) {
|
|
|
92
98
|
logger.info(`Skipping resource ${resources.indexOf(resource)} because it has no ID.`);
|
|
93
99
|
continue;
|
|
94
100
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
101
|
+
try {
|
|
102
|
+
const { data: { id }, } = await axios.put(`/api/apps/${appId}/resources/${resourceName}/${resource.id}`, resource, {
|
|
103
|
+
baseURL: remote,
|
|
104
|
+
});
|
|
105
|
+
logger.info(`Successfully updated resource ${id} at ${new URL(`/apps/${appId}/resources/${resourceName}/${id}`, remote)}`);
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
logger.error(error);
|
|
109
|
+
throw error;
|
|
110
|
+
}
|
|
99
111
|
}
|
|
100
112
|
}
|
|
101
113
|
//# sourceMappingURL=resource.js.map
|
package/lib/team.js
CHANGED
|
@@ -15,35 +15,65 @@ export function resolveAnnotations(annotations) {
|
|
|
15
15
|
export async function createTeam({ annotations = [], appId, clientCredentials, name, remote, }) {
|
|
16
16
|
logger.info(`Creating team ${name}`);
|
|
17
17
|
await authenticate(remote, 'teams:write', clientCredentials);
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
18
|
+
try {
|
|
19
|
+
const { data: { id }, } = await axios.post(`/api/apps/${appId}/teams`, {
|
|
20
|
+
name,
|
|
21
|
+
annotations: resolveAnnotations(annotations),
|
|
22
|
+
}, { baseURL: remote });
|
|
23
|
+
logger.info(`Successfully created team ${name} with ID ${id}`);
|
|
24
|
+
}
|
|
25
|
+
catch (error) {
|
|
26
|
+
logger.error(error);
|
|
27
|
+
throw error;
|
|
28
|
+
}
|
|
23
29
|
}
|
|
24
30
|
export async function deleteTeam({ appId, clientCredentials, id, remote, }) {
|
|
25
31
|
await authenticate(remote, 'teams:write', clientCredentials);
|
|
26
32
|
logger.info(`Deleting team ${id}`);
|
|
27
|
-
|
|
28
|
-
|
|
33
|
+
try {
|
|
34
|
+
await axios.delete(`/api/apps/${appId}/teams/${id}`, { baseURL: remote });
|
|
35
|
+
logger.info(`Successfully deleted team ${id}`);
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
logger.error(error);
|
|
39
|
+
throw error;
|
|
40
|
+
}
|
|
29
41
|
}
|
|
30
42
|
export async function updateTeam({ annotations = [], appId, id, name, remote, }) {
|
|
31
43
|
logger.info(`Updating team ${id}`);
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
44
|
+
try {
|
|
45
|
+
await axios.patch(`/api/apps/${appId}/teams/${id}`, {
|
|
46
|
+
name,
|
|
47
|
+
annotations: resolveAnnotations(annotations),
|
|
48
|
+
}, { baseURL: remote });
|
|
49
|
+
logger.info(`Successfully updated team ${id}`);
|
|
50
|
+
}
|
|
51
|
+
catch (error) {
|
|
52
|
+
logger.error(error);
|
|
53
|
+
throw error;
|
|
54
|
+
}
|
|
37
55
|
}
|
|
38
56
|
export async function inviteMember({ appId, id, remote, user, }) {
|
|
39
57
|
logger.info(`Inviting ${user} to team ${id}`);
|
|
40
|
-
|
|
41
|
-
|
|
58
|
+
try {
|
|
59
|
+
await axios.post(`/api/apps/${appId}/teams/${id}/members`, { id: user }, { baseURL: remote });
|
|
60
|
+
logger.info(`Successfully invited ${user} to team ${id}`);
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
logger.error(error);
|
|
64
|
+
throw error;
|
|
65
|
+
}
|
|
42
66
|
}
|
|
43
67
|
export async function updateMember({ appId, id, remote, role, user, }) {
|
|
44
68
|
logger.info(`Updating ${user}’s role in team ${id} to ${role}`);
|
|
45
|
-
|
|
46
|
-
|
|
69
|
+
try {
|
|
70
|
+
await axios.put(`/api/apps/${appId}/teams/${id}/members/${user}`, { role }, { baseURL: remote });
|
|
71
|
+
logger.info(`Successfully updated ${user} in team ${id}`);
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
logger.error(error);
|
|
75
|
+
throw error;
|
|
76
|
+
}
|
|
47
77
|
}
|
|
48
78
|
export async function deleteMember({ appId, id, user }) {
|
|
49
79
|
logger.info(`Deleting ${user} to team ${id}`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@appsemble/cli",
|
|
3
|
-
"version": "0.29.
|
|
3
|
+
"version": "0.29.9",
|
|
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.29.
|
|
46
|
-
"@appsemble/types": "0.29.
|
|
47
|
-
"@appsemble/utils": "0.29.
|
|
45
|
+
"@appsemble/node-utils": "0.29.9",
|
|
46
|
+
"@appsemble/types": "0.29.9",
|
|
47
|
+
"@appsemble/utils": "0.29.9",
|
|
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.29.
|
|
91
|
-
"@appsemble/server": "0.29.
|
|
90
|
+
"@appsemble/types": "0.29.9",
|
|
91
|
+
"@appsemble/server": "0.29.9",
|
|
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.29.
|
|
9
|
+
version: 0.29.9
|
|
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.29.
|
|
20
|
+
version: 0.29.9
|
|
21
21
|
parameters:
|
|
22
22
|
icon: arrow-left
|
|
23
23
|
actions:
|