@appsemble/cli 0.28.6 → 0.28.7

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.28.6/config/assets/logo.svg) Appsemble CLI
1
+ # ![](https://gitlab.com/appsemble/appsemble/-/raw/0.28.7/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.28.6/pipeline.svg)](https://gitlab.com/appsemble/appsemble/-/releases/0.28.6)
6
+ [![GitLab CI](https://gitlab.com/appsemble/appsemble/badges/0.28.7/pipeline.svg)](https://gitlab.com/appsemble/appsemble/-/releases/0.28.7)
7
7
  [![Prettier](https://img.shields.io/badge/code_style-prettier-ff69b4.svg)](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.6/LICENSE.md) ©
326
+ [LGPL-3.0-only](https://gitlab.com/appsemble/appsemble/-/blob/0.28.7/LICENSE.md) ©
327
327
  [Appsemble](https://appsemble.com)
@@ -18,11 +18,11 @@ export function builder(yargs) {
18
18
  })
19
19
  .option('app', {
20
20
  describe: 'The path to the app.',
21
- demandOption: 'context',
21
+ implies: 'context',
22
22
  })
23
23
  .option('context', {
24
24
  describe: 'If specified, use the specified context from .appsemblerc.yaml',
25
- demandOption: 'app',
25
+ implies: 'app',
26
26
  });
27
27
  }
28
28
  export async function handler({ annotation, app, appId, clientCredentials, context, name, remote, }) {
@@ -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 (!defaultAppId) {
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('blocks:write resources:write', testApp);
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('write EPIPE');
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
- const { BlockVersion, Organization, OrganizationMember } = models;
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
@@ -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: null,
36
+ icon: createFixtureStream('apps/tux.png'),
36
37
  website: 'https://example.com',
37
38
  });
38
39
  const organization = await Organization.findOne();
39
- expect(organization).toMatchInlineSnapshot(`
40
- {
41
- "created": 1970-01-01T00:00:00.000Z,
42
- "deleted": null,
43
- "description": "test description",
44
- "email": "test@example.com",
45
- "icon": null,
46
- "id": "test",
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: null,
82
+ description: 'Description Changed',
87
83
  email: 'test@example.com',
88
84
  website: null,
89
- icon: null,
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": null,
94
+ "description": "Description Changed",
97
95
  "email": "test@example.com",
98
- "icon": null,
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.6",
3
+ "version": "0.28.7",
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.6",
46
- "@appsemble/types": "0.28.6",
47
- "@appsemble/utils": "0.28.6",
45
+ "@appsemble/node-utils": "0.28.7",
46
+ "@appsemble/types": "0.28.7",
47
+ "@appsemble/utils": "0.28.7",
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.6",
91
- "@appsemble/server": "0.28.6",
90
+ "@appsemble/types": "0.28.7",
91
+ "@appsemble/server": "0.28.7",
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.6
9
+ version: 0.28.7
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.6
20
+ version: 0.28.7
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.28.6",
5
+ "@appsemble/sdk": "0.28.7",
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.28.6",
6
- "@appsemble/sdk": "0.28.6",
5
+ "@appsemble/preact": "0.28.7",
6
+ "@appsemble/sdk": "0.28.7",
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.28.6"
5
+ "@appsemble/sdk": "0.28.7"
6
6
  }
7
7
  }
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