@appsemble/cli 0.24.9 → 0.24.12
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/resource/publish.js +1 -1
- package/commands/serve.js +2 -1
- package/lib/app.js +16 -7
- package/lib/resource.d.ts +32 -2
- package/lib/resource.js +58 -6
- package/package.json +5 -5
- 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.24.12)
|
|
7
7
|
[](https://prettier.io)
|
|
8
8
|
|
|
9
9
|
## Table of Contents
|
|
@@ -304,5 +304,5 @@ appsemble run-cronjobs --interval 30
|
|
|
304
304
|
|
|
305
305
|
## License
|
|
306
306
|
|
|
307
|
-
[LGPL-3.0-only](https://gitlab.com/appsemble/appsemble/-/blob/0.24.
|
|
307
|
+
[LGPL-3.0-only](https://gitlab.com/appsemble/appsemble/-/blob/0.24.12/LICENSE.md) ©
|
|
308
308
|
[Appsemble](https://appsemble.com)
|
package/commands/serve.js
CHANGED
|
@@ -67,7 +67,8 @@ export async function handler(argv) {
|
|
|
67
67
|
const appSecurity = appsembleApp.definition.security;
|
|
68
68
|
const appMembers = [
|
|
69
69
|
{
|
|
70
|
-
|
|
70
|
+
userId: '1',
|
|
71
|
+
memberId: '1',
|
|
71
72
|
name: 'dev',
|
|
72
73
|
primaryEmail: 'dev@example.com',
|
|
73
74
|
role: passedUserRole || (appSecurity === null || appSecurity === void 0 ? void 0 : appSecurity.default.role),
|
package/lib/app.js
CHANGED
|
@@ -8,6 +8,7 @@ import axios from 'axios';
|
|
|
8
8
|
import fg from 'fast-glob';
|
|
9
9
|
import FormData from 'form-data';
|
|
10
10
|
import normalizePath from 'normalize-path';
|
|
11
|
+
import { parse as parseYaml } from 'yaml';
|
|
11
12
|
import { publishAsset } from './asset.js';
|
|
12
13
|
import { traverseBlockThemes } from './block.js';
|
|
13
14
|
import { coerceRemote } from './coercers.js';
|
|
@@ -15,7 +16,7 @@ import { getProjectBuildConfig } from './config.js';
|
|
|
15
16
|
import { printAxiosError } from './output.js';
|
|
16
17
|
import { processCss } from './processCss.js';
|
|
17
18
|
import { buildProject, makeProjectPayload } from './project.js';
|
|
18
|
-
import {
|
|
19
|
+
import { publishResourcesRecursively } from './resource.js';
|
|
19
20
|
/**
|
|
20
21
|
* Traverses an app directory and appends the files it finds to the given FormData object.
|
|
21
22
|
*
|
|
@@ -535,17 +536,20 @@ export async function publishApp({ assets, assetsClonable, clientCredentials, co
|
|
|
535
536
|
}
|
|
536
537
|
}
|
|
537
538
|
if (resources && existsSync(join(path, 'resources'))) {
|
|
539
|
+
const appDefinition = parseYaml(yaml, { maxAliasCount: 10000 });
|
|
538
540
|
const resourcePath = join(path, 'resources');
|
|
539
541
|
try {
|
|
540
542
|
const resourceFiles = await readdir(resourcePath, { withFileTypes: true });
|
|
543
|
+
const resourcesToPublish = [];
|
|
544
|
+
const publishedResourcesIds = {};
|
|
541
545
|
for (const resource of resourceFiles) {
|
|
542
546
|
if (resource.isFile()) {
|
|
543
547
|
const { name } = parse(resource.name);
|
|
544
|
-
|
|
548
|
+
resourcesToPublish.push({
|
|
545
549
|
appId: data.id,
|
|
546
550
|
path: join(resourcePath, resource.name),
|
|
547
|
-
|
|
548
|
-
|
|
551
|
+
definition: appDefinition.resources[name],
|
|
552
|
+
type: name,
|
|
549
553
|
});
|
|
550
554
|
}
|
|
551
555
|
else if (resource.isDirectory()) {
|
|
@@ -553,15 +557,20 @@ export async function publishApp({ assets, assetsClonable, clientCredentials, co
|
|
|
553
557
|
withFileTypes: true,
|
|
554
558
|
});
|
|
555
559
|
for (const subResource of subDirectoryResources.filter((s) => s.isFile())) {
|
|
556
|
-
|
|
560
|
+
resourcesToPublish.push({
|
|
557
561
|
appId: data.id,
|
|
558
562
|
path: join(resourcePath, resource.name, subResource.name),
|
|
559
|
-
|
|
560
|
-
|
|
563
|
+
definition: appDefinition.resources[resource.name],
|
|
564
|
+
type: resource.name,
|
|
561
565
|
});
|
|
562
566
|
}
|
|
563
567
|
}
|
|
564
568
|
}
|
|
569
|
+
await publishResourcesRecursively({
|
|
570
|
+
remote,
|
|
571
|
+
resourcesToPublish,
|
|
572
|
+
publishedResourcesIds,
|
|
573
|
+
});
|
|
565
574
|
}
|
|
566
575
|
catch (error) {
|
|
567
576
|
logger.error('Something went wrong when creating resources:');
|
package/lib/resource.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type ResourceDefinition } from '@appsemble/types';
|
|
1
2
|
interface UpdateResourceParams {
|
|
2
3
|
/**
|
|
3
4
|
* The name of the resource that a new entry is being created of.
|
|
@@ -20,7 +21,7 @@ interface PublishResourceParams {
|
|
|
20
21
|
/**
|
|
21
22
|
* The name of the resource that a new entry is being created of.
|
|
22
23
|
*/
|
|
23
|
-
|
|
24
|
+
type: string;
|
|
24
25
|
/**
|
|
25
26
|
* The path in which the resource JSON is located.
|
|
26
27
|
*/
|
|
@@ -33,7 +34,36 @@ interface PublishResourceParams {
|
|
|
33
34
|
* The remote server to publish the resource on.
|
|
34
35
|
*/
|
|
35
36
|
remote: string;
|
|
37
|
+
/**
|
|
38
|
+
* The definition of the resource.
|
|
39
|
+
*/
|
|
40
|
+
definition?: ResourceDefinition;
|
|
41
|
+
/**
|
|
42
|
+
* An array of property name to value maps of referenced resources.
|
|
43
|
+
*/
|
|
44
|
+
publishedResourcesIds?: Record<string, number[]>;
|
|
45
|
+
}
|
|
46
|
+
export interface ResourceToPublish {
|
|
47
|
+
appId: number;
|
|
48
|
+
path: string;
|
|
49
|
+
type: string;
|
|
50
|
+
definition: ResourceDefinition;
|
|
51
|
+
}
|
|
52
|
+
interface PublishResourcesRecursivelyParams {
|
|
53
|
+
/**
|
|
54
|
+
* The remote server to publish the resource on.
|
|
55
|
+
*/
|
|
56
|
+
remote: string;
|
|
57
|
+
/**
|
|
58
|
+
* All resources that need to be published.
|
|
59
|
+
*/
|
|
60
|
+
resourcesToPublish: ResourceToPublish[];
|
|
61
|
+
/**
|
|
62
|
+
* Already published resources.
|
|
63
|
+
*/
|
|
64
|
+
publishedResourcesIds: Record<string, number[]>;
|
|
36
65
|
}
|
|
37
|
-
export declare function publishResource({ appId, path, remote,
|
|
66
|
+
export declare function publishResource({ appId, definition, path, publishedResourcesIds, remote, type, }: PublishResourceParams): Promise<number[]>;
|
|
67
|
+
export declare function publishResourcesRecursively({ publishedResourcesIds, remote, resourcesToPublish, }: PublishResourcesRecursivelyParams): Promise<Record<string, number[]>>;
|
|
38
68
|
export declare function updateResource({ appId, path, remote, resourceName, }: UpdateResourceParams): Promise<void>;
|
|
39
69
|
export {};
|
package/lib/resource.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { readFile } from 'node:fs/promises';
|
|
2
2
|
import { AppsembleError, logger, readData } from '@appsemble/node-utils';
|
|
3
3
|
import axios from 'axios';
|
|
4
|
-
export async function publishResource({ appId, path, remote,
|
|
4
|
+
export async function publishResource({ appId, definition, path, publishedResourcesIds = {}, remote, type, }) {
|
|
5
5
|
const csv = path.endsWith('.csv');
|
|
6
6
|
let resources;
|
|
7
7
|
if (csv) {
|
|
@@ -15,15 +15,67 @@ export async function publishResource({ appId, path, remote, resourceName, }) {
|
|
|
15
15
|
resources = [].concat(file);
|
|
16
16
|
}
|
|
17
17
|
logger.info(`Publishing resource(s) from ${path}`);
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
18
|
+
let data;
|
|
19
|
+
if (csv) {
|
|
20
|
+
const response = await axios.post(`/api/apps/${appId}/resources/${type}`, resources, {
|
|
21
|
+
baseURL: remote,
|
|
22
|
+
headers: { 'content-type': 'text/csv' },
|
|
23
|
+
});
|
|
24
|
+
data = response.data;
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
const response = await axios.post(`/api/apps/${appId}/resources/${type}`, resources.map((resource) => {
|
|
28
|
+
var _a, _b, _c;
|
|
29
|
+
const resourceWithReferences = { ...resource };
|
|
30
|
+
for (const [referencedProperty, resourceReference] of Object.entries((_a = definition === null || definition === void 0 ? void 0 : definition.references) !== null && _a !== void 0 ? _a : {})) {
|
|
31
|
+
resourceWithReferences[referencedProperty] =
|
|
32
|
+
(_b = publishedResourcesIds[resourceReference.resource]) === null || _b === void 0 ? void 0 : _b[Number((_c = resource[`$${resourceReference.resource}`]) !== null && _c !== void 0 ? _c : -1)];
|
|
33
|
+
}
|
|
34
|
+
return resourceWithReferences;
|
|
35
|
+
}), {
|
|
36
|
+
baseURL: remote,
|
|
37
|
+
headers: { 'content-type': 'application/json' },
|
|
38
|
+
});
|
|
39
|
+
data = response.data;
|
|
40
|
+
}
|
|
22
41
|
const ids = [].concat(data).map((d) => d.id);
|
|
23
|
-
const url = new URL(`/apps/${appId}/resources/${
|
|
42
|
+
const url = new URL(`/apps/${appId}/resources/${type}/`, remote);
|
|
24
43
|
logger.info(`Successfully published ${ids.length} resource${resources.length === 1 ? '' : 's'} at: \n${ids
|
|
25
44
|
.map((id) => `${url}${id}`)
|
|
26
45
|
.join('\n')}`);
|
|
46
|
+
return ids;
|
|
47
|
+
}
|
|
48
|
+
export async function publishResourcesRecursively({ publishedResourcesIds, remote, resourcesToPublish, }) {
|
|
49
|
+
let updatedPublishedResourcesIds = { ...publishedResourcesIds };
|
|
50
|
+
for (const resourceToPublish of resourcesToPublish) {
|
|
51
|
+
const resourceReferences = resourceToPublish.definition.references;
|
|
52
|
+
if (resourceReferences) {
|
|
53
|
+
for (const resourceReference of Object.values(resourceReferences)) {
|
|
54
|
+
const referencedResourceType = resourceReference.resource;
|
|
55
|
+
const referencedResourcesToPublish = resourcesToPublish.filter((referencedResourceToPublish) => referencedResourceToPublish.type === referencedResourceType);
|
|
56
|
+
if (referencedResourcesToPublish.length &&
|
|
57
|
+
!updatedPublishedResourcesIds[referencedResourceType]) {
|
|
58
|
+
const referencedPublishedResourcesIds = await publishResourcesRecursively({
|
|
59
|
+
remote,
|
|
60
|
+
resourcesToPublish: referencedResourcesToPublish,
|
|
61
|
+
publishedResourcesIds: updatedPublishedResourcesIds,
|
|
62
|
+
});
|
|
63
|
+
updatedPublishedResourcesIds = {
|
|
64
|
+
...updatedPublishedResourcesIds,
|
|
65
|
+
...referencedPublishedResourcesIds,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
if (!updatedPublishedResourcesIds[resourceToPublish.type]) {
|
|
71
|
+
updatedPublishedResourcesIds[resourceToPublish.type] = await publishResource({
|
|
72
|
+
...resourceToPublish,
|
|
73
|
+
publishedResourcesIds: updatedPublishedResourcesIds,
|
|
74
|
+
remote,
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return updatedPublishedResourcesIds;
|
|
27
79
|
}
|
|
28
80
|
export async function updateResource({ appId, path, remote, resourceName, }) {
|
|
29
81
|
const [file] = await readData(path);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@appsemble/cli",
|
|
3
|
-
"version": "0.24.
|
|
3
|
+
"version": "0.24.12",
|
|
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.24.
|
|
46
|
-
"@appsemble/types": "0.24.
|
|
47
|
-
"@appsemble/utils": "0.24.
|
|
45
|
+
"@appsemble/node-utils": "0.24.12",
|
|
46
|
+
"@appsemble/types": "0.24.12",
|
|
47
|
+
"@appsemble/utils": "0.24.12",
|
|
48
48
|
"@fortawesome/fontawesome-common-types": "^6.0.0",
|
|
49
49
|
"@koa/cors": "^4.0.0",
|
|
50
50
|
"@odata/parser": "^0.2.0",
|
|
@@ -86,7 +86,7 @@
|
|
|
86
86
|
"yargs": "^17.0.0"
|
|
87
87
|
},
|
|
88
88
|
"devDependencies": {
|
|
89
|
-
"@appsemble/types": "0.24.
|
|
89
|
+
"@appsemble/types": "0.24.12",
|
|
90
90
|
"@types/concat-stream": "^2.0.0",
|
|
91
91
|
"@types/inquirer": "^9.0.0",
|
|
92
92
|
"@types/normalize-path": "^3.0.0",
|
|
@@ -6,7 +6,7 @@ pages:
|
|
|
6
6
|
- name: Example Page A
|
|
7
7
|
blocks:
|
|
8
8
|
- type: action-button
|
|
9
|
-
version: 0.24.
|
|
9
|
+
version: 0.24.12
|
|
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.24.
|
|
20
|
+
version: 0.24.12
|
|
21
21
|
parameters:
|
|
22
22
|
icon: arrow-left
|
|
23
23
|
actions:
|