@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 CHANGED
@@ -1,9 +1,9 @@
1
- # ![](https://gitlab.com/appsemble/appsemble/-/raw/0.24.9/config/assets/logo.svg) Appsemble CLI
1
+ # ![](https://gitlab.com/appsemble/appsemble/-/raw/0.24.12/config/assets/logo.svg) Appsemble CLI
2
2
 
3
3
  > Manage apps and blocks from the command line.
4
4
 
5
5
  [![npm](https://img.shields.io/npm/v/@appsemble/cli)](https://www.npmjs.com/package/@appsemble/cli)
6
- [![GitLab CI](https://gitlab.com/appsemble/appsemble/badges/0.24.9/pipeline.svg)](https://gitlab.com/appsemble/appsemble/-/releases/0.24.9)
6
+ [![GitLab CI](https://gitlab.com/appsemble/appsemble/badges/0.24.12/pipeline.svg)](https://gitlab.com/appsemble/appsemble/-/releases/0.24.12)
7
7
  [![Prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg)](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.9/LICENSE.md) ©
307
+ [LGPL-3.0-only](https://gitlab.com/appsemble/appsemble/-/blob/0.24.12/LICENSE.md) ©
308
308
  [Appsemble](https://appsemble.com)
@@ -41,7 +41,7 @@ export async function handler({ app, appId, clientCredentials, context, paths, r
41
41
  for (const path of files) {
42
42
  logger.info('');
43
43
  await publishResource({
44
- resourceName,
44
+ type: resourceName,
45
45
  appId: resolvedAppId,
46
46
  path,
47
47
  remote: resolvedRemote,
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
- id: '1',
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 { publishResource } from './resource.js';
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
- await publishResource({
548
+ resourcesToPublish.push({
545
549
  appId: data.id,
546
550
  path: join(resourcePath, resource.name),
547
- remote,
548
- resourceName: name,
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
- await publishResource({
560
+ resourcesToPublish.push({
557
561
  appId: data.id,
558
562
  path: join(resourcePath, resource.name, subResource.name),
559
- remote,
560
- resourceName: resource.name,
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
- resourceName: string;
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, resourceName, }: PublishResourceParams): Promise<void>;
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, resourceName, }) {
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
- const { data } = await axios.post(`/api/apps/${appId}/resources/${resourceName}`, resources, {
19
- baseURL: remote,
20
- headers: { 'content-type': csv ? 'text/csv' : 'application/json' },
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/${resourceName}/`, remote);
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.9",
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.9",
46
- "@appsemble/types": "0.24.9",
47
- "@appsemble/utils": "0.24.9",
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.9",
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
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.9
20
+ version: 0.24.12
21
21
  parameters:
22
22
  icon: arrow-left
23
23
  actions:
@@ -2,7 +2,7 @@
2
2
  "private": true,
3
3
  "type": "module",
4
4
  "dependencies": {
5
- "@appsemble/sdk": "0.24.9",
5
+ "@appsemble/sdk": "0.24.12",
6
6
  "mini-jsx": "^4.0.0"
7
7
  }
8
8
  }
@@ -2,8 +2,8 @@
2
2
  "private": true,
3
3
  "type": "module",
4
4
  "dependencies": {
5
- "@appsemble/preact": "0.24.9",
6
- "@appsemble/sdk": "0.24.9",
5
+ "@appsemble/preact": "0.24.12",
6
+ "@appsemble/sdk": "0.24.12",
7
7
  "preact": "^10.0.0"
8
8
  }
9
9
  }
@@ -2,6 +2,6 @@
2
2
  "private": true,
3
3
  "type": "module",
4
4
  "dependencies": {
5
- "@appsemble/sdk": "0.24.9"
5
+ "@appsemble/sdk": "0.24.12"
6
6
  }
7
7
  }