@appsemble/cli 0.24.12 → 0.25.0

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.12/config/assets/logo.svg) Appsemble CLI
1
+ # ![](https://gitlab.com/appsemble/appsemble/-/raw/0.25.0/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.12/pipeline.svg)](https://gitlab.com/appsemble/appsemble/-/releases/0.24.12)
6
+ [![GitLab CI](https://gitlab.com/appsemble/appsemble/badges/0.25.0/pipeline.svg)](https://gitlab.com/appsemble/appsemble/-/releases/0.25.0)
7
7
  [![Prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg)](https://prettier.io)
8
8
 
9
9
  ## Table of Contents
@@ -180,7 +180,7 @@ appsemble app import <path-of-zip-file> --organization <organizationId>
180
180
  ```
181
181
 
182
182
  For a more in depth explanation of how to build apps, use our
183
- [app building guide](https://appsemble.app/docs/guide).
183
+ [app building guide](https://appsemble.app/docs/03-guide).
184
184
 
185
185
  ### Blocks
186
186
 
@@ -229,7 +229,7 @@ npm install webpack@webpack-4 @appsemble/webpack-config
229
229
  ```
230
230
 
231
231
  For a more in-depth explanation of how to build apps, use our
232
- [block development guide](https://appsemble.app/docs/development/developing-blocks).
232
+ [block development guide](https://appsemble.app/docs/02-development/developing-blocks).
233
233
 
234
234
  ### Teams
235
235
 
@@ -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.12/LICENSE.md) ©
307
+ [LGPL-3.0-only](https://gitlab.com/appsemble/appsemble/-/blob/0.25.0/LICENSE.md) ©
308
308
  [Appsemble](https://appsemble.com)
@@ -8,6 +8,10 @@ interface AppArgs {
8
8
  template?: string;
9
9
  languages?: string[];
10
10
  description?: string;
11
+ resource?: string;
12
+ security?: boolean;
13
+ cronJobs?: boolean;
14
+ teams?: boolean;
11
15
  }
12
16
  export declare function builder(yargs: Argv): Promise<Argv<any>>;
13
17
  export declare function handler(args: AppArgs): Promise<void>;
@@ -1,9 +1,10 @@
1
- import { cp, readdir } from 'node:fs/promises';
1
+ import { cp, readdir, readFile, writeFile } from 'node:fs/promises';
2
2
  import { join } from 'node:path';
3
3
  import { logger, readData, writeData } from '@appsemble/node-utils';
4
4
  import inquirer from 'inquirer';
5
- import { parse, stringify } from 'yaml';
6
- const templatesDir = new URL('../../templates/apps/', import.meta.url);
5
+ import { format } from 'prettier';
6
+ import { parse, parseDocument, stringify } from 'yaml';
7
+ const templatesDir = new URL('../../templates/apps/', import.meta.url).pathname;
7
8
  export const command = 'create';
8
9
  export const description = 'Scaffold a new app with a basic app-definition and styling.';
9
10
  export async function builder(yargs) {
@@ -29,6 +30,16 @@ export async function builder(yargs) {
29
30
  .option('languages', {
30
31
  describe: 'Languages in which the app will be translated.',
31
32
  choices: languageChoices,
33
+ })
34
+ .option('resource', {
35
+ describe: 'Name of a demo resource to be added to the app definition.',
36
+ })
37
+ .option('security', {
38
+ describe: 'Whether to append a default security definition to app',
39
+ type: 'boolean',
40
+ })
41
+ .option('cron-jobs', {
42
+ describe: 'Whether to append default cron-jobs to the app definition',
32
43
  });
33
44
  }
34
45
  function validateAppName(input) {
@@ -67,6 +78,29 @@ export async function handler(args) {
67
78
  choices: languageChoices,
68
79
  message: 'Please select the languages for your app.',
69
80
  },
81
+ !args.resource && {
82
+ name: 'resource',
83
+ message: 'Please enter the name of sample resource to be added to the app definition.(leave empty for none)',
84
+ },
85
+ !args.security && {
86
+ name: 'security',
87
+ message: 'Would you like to add a security definition to the app.',
88
+ type: 'confirm',
89
+ default: false,
90
+ },
91
+ {
92
+ name: 'teams',
93
+ message: 'Will you be using teams in your app.',
94
+ type: 'confirm',
95
+ default: false,
96
+ when: (appOptions) => appOptions.security,
97
+ },
98
+ !args.cronJobs && {
99
+ name: 'cron-jobs',
100
+ message: 'Would you like to add a cron-job to the definition of the app.',
101
+ type: 'confirm',
102
+ default: false,
103
+ },
70
104
  !args.path && {
71
105
  name: 'path',
72
106
  message: 'Please enter the path for where you want the app folder to go (default "apps").',
@@ -78,21 +112,74 @@ export async function handler(args) {
78
112
  const appDescription = answers.description || args.description || '';
79
113
  const template = answers.template || args.template;
80
114
  const languages = answers.languages || args.languages;
115
+ const resource = answers.resource || args.resource;
116
+ const security = answers.security || args.security;
117
+ const cronJobs = answers['cron-jobs'] || args.cronJobs;
118
+ const { teams } = answers;
81
119
  const outputDirectory = join(path, name);
82
- const inputDirectory = new URL(`${template}/`, templatesDir);
83
- const appsembleRcPath = new URL('.appsemblerc.yaml', inputDirectory);
120
+ const inputDirectory = join(`${templatesDir}/`, template);
121
+ const appsembleRcPath = join(inputDirectory, '.appsemblerc.yaml');
84
122
  const [appsembleRc] = await readData(appsembleRcPath);
85
123
  const outputAppsembleRcObject = { ...appsembleRc };
86
124
  for (const key of Object.keys(appsembleRc.context)) {
87
125
  outputAppsembleRcObject.context[key].organization = organization;
88
126
  }
89
127
  const outputAppsembleRc = parse(stringify(outputAppsembleRcObject));
90
- const appDefinitionPath = new URL('app-definition.yaml', inputDirectory);
91
- const [appDefinition] = await readData(appDefinitionPath);
92
- const outputAppDefinitionObject = { ...appDefinition };
93
- outputAppDefinitionObject.name = name;
94
- outputAppDefinitionObject.description = appDescription;
95
- const outputAppDefinition = parse(stringify(outputAppDefinitionObject));
128
+ const appDefinitionPath = join(inputDirectory, 'app-definition.yaml');
129
+ const yaml = await readFile(appDefinitionPath, 'utf8');
130
+ const appDefinition = parseDocument(yaml);
131
+ appDefinition.set('name', name);
132
+ appDefinition.set('description', appDescription);
133
+ if (resource) {
134
+ appDefinition.set('resources', {
135
+ [resource]: {
136
+ roles: ['$public'],
137
+ schema: {
138
+ type: 'object',
139
+ additionalProperties: false,
140
+ },
141
+ },
142
+ });
143
+ }
144
+ if (security) {
145
+ appDefinition.set('security', {
146
+ default: {
147
+ role: 'User',
148
+ policy: 'everyone',
149
+ },
150
+ roles: {
151
+ User: {
152
+ description: 'A sample user to be included in the app definition',
153
+ },
154
+ },
155
+ teams: teams
156
+ ? {
157
+ join: 'invite',
158
+ invite: ['$team:member'],
159
+ }
160
+ : undefined,
161
+ });
162
+ appDefinition.set('roles', ['User']);
163
+ }
164
+ if (cronJobs) {
165
+ appDefinition.set('cron', {
166
+ dailyLogs: {
167
+ action: {
168
+ type: 'noop',
169
+ },
170
+ schedule: '0 12 * * *',
171
+ },
172
+ });
173
+ }
174
+ const outputAppDefinition = await format(String(appDefinition), {
175
+ tabWidth: 2,
176
+ useTabs: false,
177
+ endOfLine: 'lf',
178
+ singleQuote: true,
179
+ proseWrap: 'preserve',
180
+ printWidth: 100,
181
+ parser: 'yaml',
182
+ });
96
183
  await cp(inputDirectory, outputDirectory, {
97
184
  errorOnExist: true,
98
185
  filter: (src) => !src.endsWith('.appsemblerc.yaml') || !src.endsWith('app-definition.yaml'),
@@ -103,9 +190,7 @@ export async function handler(args) {
103
190
  await writeData(join(outputDirectory, 'i18n', `${language}.json`), {});
104
191
  }
105
192
  await writeData(join(outputDirectory, '.appsemblerc.yaml'), outputAppsembleRc);
106
- await writeData(join(outputDirectory, 'app-definition.yaml'), outputAppDefinition, {
107
- sort: false,
108
- });
193
+ await writeFile(join(outputDirectory, 'app-definition.yaml'), outputAppDefinition);
109
194
  logger.info(`Successfully created ${name} at ${outputDirectory}`);
110
195
  }
111
196
  //# sourceMappingURL=create.js.map
@@ -13,6 +13,7 @@ interface PublishAppArguments extends BaseArguments {
13
13
  organization: string;
14
14
  template: boolean;
15
15
  demoMode: boolean;
16
+ seed: boolean;
16
17
  dryRun: boolean;
17
18
  resources: boolean;
18
19
  assets: boolean;
@@ -40,6 +40,10 @@ export function builder(yargs) {
40
40
  .option('demo-mode', {
41
41
  describe: 'Whether the app should be used in demo mode.',
42
42
  type: 'boolean',
43
+ })
44
+ .option('seed', {
45
+ describe: 'Whether to enable seeding for an app or not.',
46
+ implies: ['demo-mode'],
43
47
  })
44
48
  .option('dry-run', {
45
49
  describe: 'Whether the API should be called to run without actually creating the app.',
@@ -13,6 +13,7 @@ interface UpdateAppArguments extends BaseArguments {
13
13
  id: number;
14
14
  template: boolean;
15
15
  demoMode: boolean;
16
+ seed: boolean;
16
17
  force: boolean;
17
18
  visibility: AppVisibility;
18
19
  sentryDsn: string;
@@ -43,6 +43,10 @@ export function builder(yargs) {
43
43
  .option('demo-mode', {
44
44
  describe: 'Whether the app should be used in demo mode.',
45
45
  type: 'boolean',
46
+ })
47
+ .option('seed', {
48
+ describe: 'Whether to enable seeding for an app or not.',
49
+ implies: ['demo-mode'],
46
50
  })
47
51
  .option('force', {
48
52
  describe: 'Whether the lock property should be ignored.',
package/lib/app.d.ts CHANGED
@@ -36,6 +36,10 @@ interface PublishAppParams {
36
36
  * Whether the App should be used in demo mode.
37
37
  */
38
38
  demoMode: boolean;
39
+ /**
40
+ * Whether the App should seed resources and assets in demo mode.
41
+ */
42
+ seed: boolean;
39
43
  /**
40
44
  * The icon to upload.
41
45
  */
@@ -115,6 +119,10 @@ interface UpdateAppParams {
115
119
  * Whether the App should be used in demo mode.
116
120
  */
117
121
  demoMode: boolean;
122
+ /**
123
+ * Whether the App should seed resources and assets in demo mode.
124
+ */
125
+ seed: boolean;
118
126
  /**
119
127
  * Whether the locked property should be ignored.
120
128
  */
package/lib/app.js CHANGED
@@ -331,7 +331,7 @@ This block version is not used in the app`);
331
331
  * @param argv The command line options used for updating the app.
332
332
  */
333
333
  export async function updateApp({ clientCredentials, context, force, path, ...options }) {
334
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s;
334
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v;
335
335
  const file = await stat(path);
336
336
  const formData = new FormData();
337
337
  let appsembleContext;
@@ -346,13 +346,17 @@ export async function updateApp({ clientCredentials, context, force, path, ...op
346
346
  const id = (_b = appsembleContext.id) !== null && _b !== void 0 ? _b : options.id;
347
347
  const template = (_d = (_c = appsembleContext.template) !== null && _c !== void 0 ? _c : options.template) !== null && _d !== void 0 ? _d : false;
348
348
  const demoMode = (_f = (_e = appsembleContext.demoMode) !== null && _e !== void 0 ? _e : options.demoMode) !== null && _f !== void 0 ? _f : false;
349
- const visibility = (_g = appsembleContext.visibility) !== null && _g !== void 0 ? _g : options.visibility;
350
- const iconBackground = (_h = appsembleContext.iconBackground) !== null && _h !== void 0 ? _h : options.iconBackground;
351
- const icon = (_j = options.icon) !== null && _j !== void 0 ? _j : appsembleContext.icon;
352
- const maskableIcon = (_k = options.maskableIcon) !== null && _k !== void 0 ? _k : appsembleContext.maskableIcon;
353
- const sentryDsn = (_l = appsembleContext.sentryDsn) !== null && _l !== void 0 ? _l : options.sentryDsn;
354
- const sentryEnvironment = (_m = appsembleContext.sentryEnvironment) !== null && _m !== void 0 ? _m : options.sentryEnvironment;
355
- const googleAnalyticsId = (_o = appsembleContext.googleAnalyticsId) !== null && _o !== void 0 ? _o : options.googleAnalyticsId;
349
+ // TODO: seed depends on demoMode, this is caused by bad database normalization.
350
+ // Consider using a property called `type` on the App model instead.
351
+ const seed = (_j = (_h = (_g = appsembleContext.seed) !== null && _g !== void 0 ? _g : options.seed) !== null && _h !== void 0 ? _h : options.demoMode) !== null && _j !== void 0 ? _j : false;
352
+ const visibility = (_k = appsembleContext.visibility) !== null && _k !== void 0 ? _k : options.visibility;
353
+ const iconBackground = (_l = appsembleContext.iconBackground) !== null && _l !== void 0 ? _l : options.iconBackground;
354
+ const icon = (_m = options.icon) !== null && _m !== void 0 ? _m : appsembleContext.icon;
355
+ const maskableIcon = (_o = options.maskableIcon) !== null && _o !== void 0 ? _o : appsembleContext.maskableIcon;
356
+ const sentryDsn = (_p = appsembleContext.sentryDsn) !== null && _p !== void 0 ? _p : options.sentryDsn;
357
+ const sentryEnvironment = (_q = appsembleContext.sentryEnvironment) !== null && _q !== void 0 ? _q : options.sentryEnvironment;
358
+ const googleAnalyticsId = (_r = appsembleContext.googleAnalyticsId) !== null && _r !== void 0 ? _r : options.googleAnalyticsId;
359
+ const { appLock } = appsembleContext;
356
360
  logger.info(`App id: ${id}`);
357
361
  logger.verbose(`App remote: ${remote}`);
358
362
  logger.verbose(`App is template: ${inspect(template, { colors: true })}`);
@@ -365,16 +369,17 @@ export async function updateApp({ clientCredentials, context, force, path, ...op
365
369
  formData.append('force', String(force));
366
370
  formData.append('template', String(template));
367
371
  formData.append('demoMode', String(demoMode));
372
+ formData.append('demoMode', String(seed));
368
373
  formData.append('visibility', visibility);
369
374
  formData.append('iconBackground', iconBackground);
370
375
  if (icon) {
371
376
  const realIcon = typeof icon === 'string' ? createReadStream(icon) : icon;
372
- logger.info(`Using icon from ${(_p = realIcon.path) !== null && _p !== void 0 ? _p : 'stdin'}`);
377
+ logger.info(`Using icon from ${(_s = realIcon.path) !== null && _s !== void 0 ? _s : 'stdin'}`);
373
378
  formData.append('icon', realIcon);
374
379
  }
375
380
  if (maskableIcon) {
376
381
  const realIcon = typeof maskableIcon === 'string' ? createReadStream(maskableIcon) : maskableIcon;
377
- logger.info(`Using maskable icon from ${(_q = realIcon.path) !== null && _q !== void 0 ? _q : 'stdin'}`);
382
+ logger.info(`Using maskable icon from ${(_t = realIcon.path) !== null && _t !== void 0 ? _t : 'stdin'}`);
378
383
  formData.append('maskableIcon', realIcon);
379
384
  }
380
385
  if (sentryDsn) {
@@ -389,6 +394,18 @@ export async function updateApp({ clientCredentials, context, force, path, ...op
389
394
  formData.append('googleAnalyticsID', googleAnalyticsId);
390
395
  }
391
396
  await authenticate(remote, 'apps:write', clientCredentials);
397
+ if (appLock) {
398
+ logger.info(`Setting AppLock to ${appLock}`);
399
+ try {
400
+ await axios.post(`/api/apps/${id}/lock`, {
401
+ locked: appLock,
402
+ });
403
+ }
404
+ catch (error) {
405
+ logger.error(error);
406
+ process.exit(1);
407
+ }
408
+ }
392
409
  let data;
393
410
  try {
394
411
  data = await axios
@@ -399,7 +416,7 @@ export async function updateApp({ clientCredentials, context, force, path, ...op
399
416
  if (!axios.isAxiosError(error)) {
400
417
  throw error;
401
418
  }
402
- if (((_s = (_r = error.response) === null || _r === void 0 ? void 0 : _r.data) === null || _s === void 0 ? void 0 : _s.message) !== 'App validation failed') {
419
+ if (((_v = (_u = error.response) === null || _u === void 0 ? void 0 : _u.data) === null || _v === void 0 ? void 0 : _v.message) !== 'App validation failed') {
403
420
  throw error;
404
421
  }
405
422
  logger.error(error.response.data);
@@ -421,7 +438,7 @@ export async function updateApp({ clientCredentials, context, force, path, ...op
421
438
  * @param options The options to use for publishing an app.
422
439
  */
423
440
  export async function publishApp({ assets, assetsClonable, clientCredentials, context, dryRun, modifyContext, path, resources, ...options }) {
424
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s;
441
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v;
425
442
  const file = await stat(path);
426
443
  const formData = new FormData();
427
444
  let appsembleContext;
@@ -442,13 +459,17 @@ export async function publishApp({ assets, assetsClonable, clientCredentials, co
442
459
  const organizationId = (_b = appsembleContext.organization) !== null && _b !== void 0 ? _b : options.organization;
443
460
  const template = (_d = (_c = appsembleContext.template) !== null && _c !== void 0 ? _c : options.template) !== null && _d !== void 0 ? _d : false;
444
461
  const demoMode = (_f = (_e = appsembleContext.demoMode) !== null && _e !== void 0 ? _e : options.demoMode) !== null && _f !== void 0 ? _f : false;
445
- const visibility = (_g = appsembleContext.visibility) !== null && _g !== void 0 ? _g : options.visibility;
446
- const iconBackground = (_h = appsembleContext.iconBackground) !== null && _h !== void 0 ? _h : options.iconBackground;
447
- const icon = (_j = options.icon) !== null && _j !== void 0 ? _j : appsembleContext.icon;
448
- const maskableIcon = (_k = options.maskableIcon) !== null && _k !== void 0 ? _k : appsembleContext.maskableIcon;
449
- const sentryDsn = (_l = appsembleContext.sentryDsn) !== null && _l !== void 0 ? _l : options.sentryDsn;
450
- const sentryEnvironment = (_m = appsembleContext.sentryEnvironment) !== null && _m !== void 0 ? _m : options.sentryEnvironment;
451
- const googleAnalyticsId = (_o = appsembleContext.googleAnalyticsId) !== null && _o !== void 0 ? _o : options.googleAnalyticsId;
462
+ // TODO: seed depends on demoMode, this is caused by bad database normalization.
463
+ // Consider using a property called `type` on the App model instead.
464
+ const seed = (_j = (_h = (_g = appsembleContext.seed) !== null && _g !== void 0 ? _g : options.seed) !== null && _h !== void 0 ? _h : options.demoMode) !== null && _j !== void 0 ? _j : false;
465
+ const visibility = (_k = appsembleContext.visibility) !== null && _k !== void 0 ? _k : options.visibility;
466
+ const iconBackground = (_l = appsembleContext.iconBackground) !== null && _l !== void 0 ? _l : options.iconBackground;
467
+ const icon = (_m = options.icon) !== null && _m !== void 0 ? _m : appsembleContext.icon;
468
+ const maskableIcon = (_o = options.maskableIcon) !== null && _o !== void 0 ? _o : appsembleContext.maskableIcon;
469
+ const sentryDsn = (_p = appsembleContext.sentryDsn) !== null && _p !== void 0 ? _p : options.sentryDsn;
470
+ const sentryEnvironment = (_q = appsembleContext.sentryEnvironment) !== null && _q !== void 0 ? _q : options.sentryEnvironment;
471
+ const googleAnalyticsId = (_r = appsembleContext.googleAnalyticsId) !== null && _r !== void 0 ? _r : options.googleAnalyticsId;
472
+ const appLock = appsembleContext.appLock || 'unlocked';
452
473
  logger.verbose(`App remote: ${remote}`);
453
474
  logger.verbose(`App organization: ${organizationId}`);
454
475
  logger.verbose(`App is template: ${inspect(template, { colors: true })}`);
@@ -460,16 +481,18 @@ export async function publishApp({ assets, assetsClonable, clientCredentials, co
460
481
  formData.append('OrganizationId', organizationId);
461
482
  formData.append('template', String(template));
462
483
  formData.append('demoMode', String(demoMode));
484
+ formData.append('seed', String(seed));
463
485
  formData.append('visibility', visibility);
464
486
  formData.append('iconBackground', iconBackground);
487
+ formData.append('locked', appLock);
465
488
  if (icon) {
466
489
  const realIcon = typeof icon === 'string' ? createReadStream(icon) : icon;
467
- logger.info(`Using icon from ${(_p = realIcon.path) !== null && _p !== void 0 ? _p : 'stdin'}`);
490
+ logger.info(`Using icon from ${(_s = realIcon.path) !== null && _s !== void 0 ? _s : 'stdin'}`);
468
491
  formData.append('icon', realIcon);
469
492
  }
470
493
  if (maskableIcon) {
471
494
  const realIcon = typeof maskableIcon === 'string' ? createReadStream(maskableIcon) : maskableIcon;
472
- logger.info(`Using maskable icon from ${(_q = realIcon.path) !== null && _q !== void 0 ? _q : 'stdin'}`);
495
+ logger.info(`Using maskable icon from ${(_t = realIcon.path) !== null && _t !== void 0 ? _t : 'stdin'}`);
473
496
  formData.append('maskableIcon', realIcon);
474
497
  }
475
498
  if (sentryDsn) {
@@ -499,7 +522,7 @@ export async function publishApp({ assets, assetsClonable, clientCredentials, co
499
522
  if (!axios.isAxiosError(error)) {
500
523
  throw error;
501
524
  }
502
- if (((_s = (_r = error.response) === null || _r === void 0 ? void 0 : _r.data) === null || _s === void 0 ? void 0 : _s.message) !== 'App validation failed') {
525
+ if (((_v = (_u = error.response) === null || _u === void 0 ? void 0 : _u.data) === null || _v === void 0 ? void 0 : _v.message) !== 'App validation failed') {
503
526
  throw error;
504
527
  }
505
528
  throw new AppsembleError(printAxiosError(filename, yaml, error.response.data.data.errors));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@appsemble/cli",
3
- "version": "0.24.12",
3
+ "version": "0.25.0",
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.12",
46
- "@appsemble/types": "0.24.12",
47
- "@appsemble/utils": "0.24.12",
45
+ "@appsemble/node-utils": "0.25.0",
46
+ "@appsemble/types": "0.25.0",
47
+ "@appsemble/utils": "0.25.0",
48
48
  "@fortawesome/fontawesome-common-types": "^6.0.0",
49
49
  "@koa/cors": "^4.0.0",
50
50
  "@odata/parser": "^0.2.0",
@@ -76,6 +76,7 @@
76
76
  "postcss-import": "^15.0.0",
77
77
  "postcss-load-config": "^4.0.0",
78
78
  "postcss-url": "^10.0.0",
79
+ "prettier": "^3.0.0",
79
80
  "raw-body": "^2.0.0",
80
81
  "read-package-up": "^11.0.0",
81
82
  "sharp": "^0.32.0",
@@ -86,7 +87,7 @@
86
87
  "yargs": "^17.0.0"
87
88
  },
88
89
  "devDependencies": {
89
- "@appsemble/types": "0.24.12",
90
+ "@appsemble/types": "0.25.0",
90
91
  "@types/concat-stream": "^2.0.0",
91
92
  "@types/inquirer": "^9.0.0",
92
93
  "@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.12
9
+ version: 0.25.0
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.12
20
+ version: 0.25.0
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.12",
5
+ "@appsemble/sdk": "0.25.0",
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.12",
6
- "@appsemble/sdk": "0.24.12",
5
+ "@appsemble/preact": "0.25.0",
6
+ "@appsemble/sdk": "0.25.0",
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.12"
5
+ "@appsemble/sdk": "0.25.0"
6
6
  }
7
7
  }