@budibase/server 2.5.5-alpha.4 → 2.5.5

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.
Files changed (49) hide show
  1. package/builder/assets/{index.841e62d8.css → index.7f9a008b.css} +3 -3
  2. package/builder/assets/index.f493a2b3.js +1817 -0
  3. package/builder/index.html +2 -2
  4. package/dist/api/routes/index.js +0 -2
  5. package/dist/app.js +11 -2
  6. package/dist/elasticApm.js +14 -0
  7. package/dist/environment.js +1 -0
  8. package/dist/integrations/microsoftSqlServer.js +2 -5
  9. package/dist/integrations/mysql.js +3 -5
  10. package/dist/integrations/postgres.js +5 -7
  11. package/dist/integrations/redis.js +0 -7
  12. package/dist/integrations/rest.js +0 -4
  13. package/dist/migrations/functions/usageQuotas/syncApps.js +1 -1
  14. package/dist/migrations/functions/usageQuotas/syncRows.js +2 -1
  15. package/dist/package.json +14 -13
  16. package/dist/startup.js +27 -29
  17. package/dist/threads/automation.js +3 -14
  18. package/dist/tsconfig.build.tsbuildinfo +1 -1
  19. package/package.json +15 -14
  20. package/scripts/dev/manage.js +0 -2
  21. package/scripts/integrations/mssql/data/entrypoint.sh +0 -1
  22. package/scripts/integrations/mssql/data/setup.sql +17 -17
  23. package/scripts/integrations/mysql/init.sql +1 -1
  24. package/scripts/integrations/postgres/init.sql +0 -1
  25. package/scripts/likeCypress.ts +35 -0
  26. package/src/api/routes/index.ts +0 -2
  27. package/src/api/routes/tests/automation.spec.js +2 -5
  28. package/src/api/routes/tests/user.spec.js +13 -61
  29. package/src/app.ts +13 -2
  30. package/src/elasticApm.ts +10 -0
  31. package/src/environment.ts +1 -0
  32. package/src/integrations/microsoftSqlServer.ts +2 -5
  33. package/src/integrations/mysql.ts +3 -5
  34. package/src/integrations/postgres.ts +5 -7
  35. package/src/integrations/redis.ts +0 -8
  36. package/src/integrations/rest.ts +0 -3
  37. package/src/migrations/functions/usageQuotas/syncApps.ts +1 -1
  38. package/src/migrations/functions/usageQuotas/syncRows.ts +3 -2
  39. package/src/migrations/functions/usageQuotas/tests/syncRows.spec.ts +2 -2
  40. package/src/startup.ts +33 -34
  41. package/src/tests/jestEnv.ts +1 -0
  42. package/src/tests/jestSetup.ts +1 -0
  43. package/src/tests/logging.ts +34 -0
  44. package/src/threads/automation.ts +4 -16
  45. package/builder/assets/index.c176beea.js +0 -1776
  46. package/dist/api/controllers/ops.js +0 -40
  47. package/dist/api/routes/ops.js +0 -52
  48. package/src/api/controllers/ops.ts +0 -32
  49. package/src/api/routes/ops.ts +0 -30
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@budibase/server",
3
3
  "email": "hi@budibase.com",
4
- "version": "2.5.5-alpha.4",
4
+ "version": "2.5.5",
5
5
  "description": "Budibase Web Server",
6
6
  "main": "src/index.ts",
7
7
  "repository": {
@@ -26,7 +26,6 @@
26
26
  "dev:stack:down": "node scripts/dev/manage.js down",
27
27
  "dev:stack:nuke": "node scripts/dev/manage.js nuke",
28
28
  "dev:builder": "yarn run dev:stack:up && nodemon",
29
- "dev:built": "yarn run dev:stack:up && yarn run run:docker",
30
29
  "specs": "ts-node specs/generate.ts && openapi-typescript specs/openapi.yaml --output src/definitions/openapi.ts",
31
30
  "initialise": "node scripts/initialise.js",
32
31
  "env:multi:enable": "node scripts/multiTenancy.js enable",
@@ -45,12 +44,12 @@
45
44
  "license": "GPL-3.0",
46
45
  "dependencies": {
47
46
  "@apidevtools/swagger-parser": "10.0.3",
48
- "@budibase/backend-core": "2.5.5-alpha.4",
49
- "@budibase/client": "2.5.5-alpha.4",
50
- "@budibase/pro": "2.5.5-alpha.2",
51
- "@budibase/shared-core": "2.5.5-alpha.4",
52
- "@budibase/string-templates": "2.5.5-alpha.4",
53
- "@budibase/types": "2.5.5-alpha.4",
47
+ "@budibase/backend-core": "^2.5.5",
48
+ "@budibase/client": "^2.5.5",
49
+ "@budibase/pro": "2.5.4",
50
+ "@budibase/shared-core": "^2.5.5",
51
+ "@budibase/string-templates": "^2.5.5",
52
+ "@budibase/types": "^2.5.5",
54
53
  "@bull-board/api": "3.7.0",
55
54
  "@bull-board/koa": "3.9.4",
56
55
  "@elastic/elasticsearch": "7.10.0",
@@ -86,6 +85,7 @@
86
85
  "koa-body": "4.2.0",
87
86
  "koa-compress": "4.0.1",
88
87
  "koa-connect": "2.1.0",
88
+ "koa-pino-logger": "3.0.0",
89
89
  "koa-send": "5.0.0",
90
90
  "koa-session": "5.12.0",
91
91
  "koa-static": "5.0.0",
@@ -99,6 +99,7 @@
99
99
  "node-fetch": "2.6.7",
100
100
  "open": "8.4.0",
101
101
  "pg": "8.5.1",
102
+ "pino-pretty": "4.0.0",
102
103
  "posthog-node": "1.3.0",
103
104
  "pouchdb": "7.3.0",
104
105
  "pouchdb-adapter-memory": "7.2.2",
@@ -115,10 +116,11 @@
115
116
  "to-json-schema": "0.2.5",
116
117
  "uuid": "3.3.2",
117
118
  "validate.js": "0.13.1",
118
- "vm2": "3.9.16",
119
+ "vm2": "^3.9.15",
119
120
  "worker-farm": "1.7.0",
120
- "xml2js": "0.5.0",
121
- "yargs": "13.2.4"
121
+ "xml2js": "0.4.23",
122
+ "yargs": "13.2.4",
123
+ "zlib": "1.0.5"
122
124
  },
123
125
  "devDependencies": {
124
126
  "@babel/core": "7.17.4",
@@ -147,7 +149,7 @@
147
149
  "@types/tar": "6.1.3",
148
150
  "@typescript-eslint/parser": "5.45.0",
149
151
  "apidoc": "0.50.4",
150
- "babel-jest": "29.5.0",
152
+ "babel-jest": "27.5.1",
151
153
  "copyfiles": "2.4.1",
152
154
  "docker-compose": "0.23.17",
153
155
  "eslint": "6.8.0",
@@ -155,7 +157,6 @@
155
157
  "is-wsl": "2.2.0",
156
158
  "jest": "29.5.0",
157
159
  "jest-openapi": "0.14.2",
158
- "jest-runner": "29.5.0",
159
160
  "jest-serial-runner": "^1.2.1",
160
161
  "nodemon": "2.0.15",
161
162
  "openapi-types": "9.3.1",
@@ -175,5 +176,5 @@
175
176
  "optionalDependencies": {
176
177
  "oracledb": "5.3.0"
177
178
  },
178
- "gitHead": "ee3c525f17f68904ac7a992d245f6ef57568146b"
179
+ "gitHead": "ed22164a05a38f41d3327b2ad18f23ddf857a062"
179
180
  }
@@ -45,8 +45,6 @@ async function init() {
45
45
  BB_ADMIN_USER_PASSWORD: "",
46
46
  PLUGINS_DIR: "",
47
47
  TENANT_FEATURE_FLAGS: "*:LICENSING,*:USER_GROUPS,*:ONBOARDING_TOUR",
48
- HTTP_MIGRATIONS: "0",
49
- HTTP_LOGGING: "0",
50
48
  }
51
49
  let envFile = ""
52
50
  Object.keys(envFileJson).forEach(key => {
@@ -11,7 +11,6 @@ if [ "$1" = '/opt/mssql/bin/sqlservr' ]; then
11
11
 
12
12
  echo "RUNNING BUDIBASE SETUP"
13
13
 
14
- cat setup.sql
15
14
  #run the setup script to create the DB and the schema in the DB
16
15
  /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P Passw0rd -i setup.sql
17
16
 
@@ -34,7 +34,7 @@ GO
34
34
  CREATE TABLE people
35
35
  (
36
36
  name varchar(30) NOT NULL,
37
- age int default 20 NOT NULL,
37
+ age varchar(20),
38
38
  CONSTRAINT pk_people PRIMARY KEY NONCLUSTERED (name, age)
39
39
  );
40
40
 
@@ -50,22 +50,22 @@ VALUES
50
50
  ('Processing', 1);
51
51
 
52
52
  INSERT INTO people (name, age)
53
- VALUES ('Bob', 30),
54
- ('Bert', 10),
55
- ('Jack', 12),
56
- ('Mike', 31),
57
- ('Dave', 44),
58
- ('Jim', 43),
59
- ('Kerry', 32),
60
- ('Julie', 12),
61
- ('Kim', 55),
62
- ('Andy', 33),
63
- ('John', 22),
64
- ('Ruth', 66),
65
- ('Robert', 88),
66
- ('Bobert', 99),
67
- ('Jan', 22),
68
- ('Megan', 11);
53
+ VALUES ('Bob', '30'),
54
+ ('Bert', '10'),
55
+ ('Jack', '12'),
56
+ ('Mike', '31'),
57
+ ('Dave', '44'),
58
+ ('Jim', '43'),
59
+ ('Kerry', '32'),
60
+ ('Julie', '12'),
61
+ ('Kim', '55'),
62
+ ('Andy', '33'),
63
+ ('John', '22'),
64
+ ('Ruth', '66'),
65
+ ('Robert', '88'),
66
+ ('Bobert', '99'),
67
+ ('Jan', '22'),
68
+ ('Megan', '11');
69
69
 
70
70
 
71
71
  IF OBJECT_ID ('Chains.sizes', 'U') IS NOT NULL
@@ -3,7 +3,7 @@ USE main;
3
3
  CREATE TABLE Persons (
4
4
  PersonID int NOT NULL AUTO_INCREMENT,
5
5
  CreatedAt datetime,
6
- Age float DEFAULT 20 NOT NULL,
6
+ Age float,
7
7
  LastName varchar(255),
8
8
  FirstName varchar(255),
9
9
  Address varchar(255),
@@ -8,7 +8,6 @@ CREATE TABLE Persons (
8
8
  FirstName varchar(255),
9
9
  Address varchar(255),
10
10
  City varchar(255) DEFAULT 'Belfast',
11
- Age INTEGER DEFAULT 20 NOT NULL,
12
11
  Type person_job
13
12
  );
14
13
  CREATE TABLE Tasks (
@@ -0,0 +1,35 @@
1
+ /******************************************************
2
+ * This script just makes it easy to re-create *
3
+ * a cypress like environment for testing the backend *
4
+ ******************************************************/
5
+ import path from "path"
6
+ const tmpdir = path.join(require("os").tmpdir(), ".budibase")
7
+
8
+ const SERVER_PORT = "4100"
9
+ const WORKER_PORT = "4200"
10
+
11
+ // @ts-ignore
12
+ process.env.NODE_ENV = "cypress"
13
+ process.env.ENABLE_ANALYTICS = "0"
14
+ process.env.JWT_SECRET = "budibase"
15
+ process.env.COUCH_URL = `leveldb://${tmpdir}/.data/`
16
+ process.env.SELF_HOSTED = "1"
17
+ process.env.WORKER_URL = `http://localhost:${WORKER_PORT}/`
18
+ process.env.MINIO_URL = `http://localhost:4004`
19
+ process.env.MINIO_ACCESS_KEY = "budibase"
20
+ process.env.MINIO_SECRET_KEY = "budibase"
21
+ process.env.COUCH_DB_USER = "budibase"
22
+ process.env.COUCH_DB_PASSWORD = "budibase"
23
+ process.env.INTERNAL_API_KEY = "budibase"
24
+ process.env.ALLOW_DEV_AUTOMATIONS = "1"
25
+
26
+ // don't make this a variable or top level require
27
+ // it will cause environment module to be loaded prematurely
28
+
29
+ // override the port with the worker port temporarily
30
+ process.env.PORT = WORKER_PORT
31
+ const worker = require("../../worker/src/index")
32
+
33
+ // override the port with the server port
34
+ process.env.PORT = SERVER_PORT
35
+ const server = require("../src/app")
@@ -25,7 +25,6 @@ import devRoutes from "./dev"
25
25
  import cloudRoutes from "./cloud"
26
26
  import migrationRoutes from "./migrations"
27
27
  import pluginRoutes from "./plugin"
28
- import opsRoutes from "./ops"
29
28
  import Router from "@koa/router"
30
29
  import { api as pro } from "@budibase/pro"
31
30
 
@@ -64,7 +63,6 @@ export const mainRoutes: Router[] = [
64
63
  rowRoutes,
65
64
  migrationRoutes,
66
65
  pluginRoutes,
67
- opsRoutes,
68
66
  scheduleRoutes,
69
67
  environmentVariableRoutes,
70
68
  // these need to be handled last as they still use /api/:tableId
@@ -19,14 +19,11 @@ describe("/automations", () => {
19
19
 
20
20
  afterAll(setup.afterAll)
21
21
 
22
- beforeAll(async () => {
22
+ // For some reason this cannot be a beforeAll or the test "tests the automation successfully" fail
23
+ beforeEach(async () => {
23
24
  await config.init()
24
25
  })
25
26
 
26
- beforeEach(() => {
27
- events.automation.deleted.mockClear()
28
- })
29
-
30
27
  describe("get definitions", () => {
31
28
  it("returns a list of definitions for actions", async () => {
32
29
  const res = await request
@@ -57,7 +57,6 @@ describe("/users", () => {
57
57
  it("should be able to update the user", async () => {
58
58
  const user = await config.createUser({ id: `us_update${utils.newid()}` })
59
59
  user.roleId = BUILTIN_ROLE_IDS.BASIC
60
- delete user._rev
61
60
  const res = await request
62
61
  .put(`/api/users/metadata`)
63
62
  .set(config.defaultHeaders())
@@ -66,46 +65,6 @@ describe("/users", () => {
66
65
  .expect("Content-Type", /json/)
67
66
  expect(res.body.ok).toEqual(true)
68
67
  })
69
-
70
- it("should be able to update the user multiple times", async () => {
71
- const user = await config.createUser()
72
- delete user._rev
73
-
74
- const res1 = await request
75
- .put(`/api/users/metadata`)
76
- .set(config.defaultHeaders())
77
- .send({ ...user, roleId: BUILTIN_ROLE_IDS.BASIC })
78
- .expect(200)
79
- .expect("Content-Type", /json/)
80
-
81
- const res = await request
82
- .put(`/api/users/metadata`)
83
- .set(config.defaultHeaders())
84
- .send({ ...user, _rev: res1.body.rev, roleId: BUILTIN_ROLE_IDS.POWER })
85
- .expect(200)
86
- .expect("Content-Type", /json/)
87
-
88
- expect(res.body.ok).toEqual(true)
89
- })
90
-
91
- it("should require the _rev field for multiple updates", async () => {
92
- const user = await config.createUser()
93
- delete user._rev
94
-
95
- await request
96
- .put(`/api/users/metadata`)
97
- .set(config.defaultHeaders())
98
- .send({ ...user, roleId: BUILTIN_ROLE_IDS.BASIC })
99
- .expect(200)
100
- .expect("Content-Type", /json/)
101
-
102
- await request
103
- .put(`/api/users/metadata`)
104
- .set(config.defaultHeaders())
105
- .send({ ...user, roleId: BUILTIN_ROLE_IDS.POWER })
106
- .expect(409)
107
- .expect("Content-Type", /json/)
108
- })
109
68
  })
110
69
 
111
70
  describe("destroy", () => {
@@ -133,7 +92,6 @@ describe("/users", () => {
133
92
  expect(res.body.tableId).toBeDefined()
134
93
  })
135
94
  })
136
-
137
95
  describe("setFlag", () => {
138
96
  it("should throw an error if a flag is not provided", async () => {
139
97
  await config.createUser()
@@ -143,9 +101,8 @@ describe("/users", () => {
143
101
  .send({ value: "test" })
144
102
  .expect(400)
145
103
  .expect("Content-Type", /json/)
146
- expect(res.body.message).toEqual(
147
- "Must supply a 'flag' field in request body."
148
- )
104
+ expect(res.body.message).toEqual("Must supply a 'flag' field in request body.")
105
+
149
106
  })
150
107
 
151
108
  it("should be able to set a flag on the user", async () => {
@@ -189,9 +146,8 @@ describe("/users", () => {
189
146
  .send({ value: "test" })
190
147
  .expect(400)
191
148
  .expect("Content-Type", /json/)
192
- expect(res.body.message).toEqual(
193
- "Must supply a 'flag' field in request body."
194
- )
149
+ expect(res.body.message).toEqual("Must supply a 'flag' field in request body.")
150
+
195
151
  })
196
152
 
197
153
  it("should be able to set a flag on the user", async () => {
@@ -209,37 +165,33 @@ describe("/users", () => {
209
165
  describe("syncUser", () => {
210
166
  it("should sync the user", async () => {
211
167
  let user = await config.createUser()
212
- await config.createApp("New App")
168
+ await config.createApp('New App')
213
169
  let res = await request
214
170
  .post(`/api/users/metadata/sync/${user._id}`)
215
171
  .set(config.defaultHeaders())
216
172
  .expect(200)
217
173
  .expect("Content-Type", /json/)
218
- expect(res.body.message).toEqual("User synced.")
174
+ expect(res.body.message).toEqual('User synced.')
219
175
  })
220
176
 
177
+
221
178
  it("should sync the user when a previous user is specified", async () => {
222
- const app1 = await config.createApp("App 1")
223
- const app2 = await config.createApp("App 2")
179
+ const app1 = await config.createApp('App 1')
180
+ const app2 = await config.createApp('App 2')
224
181
 
225
182
  let user = await config.createUser({
226
183
  builder: false,
227
184
  admin: true,
228
- roles: { [app1.appId]: "ADMIN" },
229
- })
185
+ roles: { [app1.appId]: 'ADMIN' }
186
+ })
230
187
  let res = await request
231
188
  .post(`/api/users/metadata/sync/${user._id}`)
232
189
  .set(config.defaultHeaders())
233
- .send({
234
- previousUser: {
235
- ...user,
236
- roles: { ...user.roles, [app2.appId]: "BASIC" },
237
- },
238
- })
190
+ .send({ previousUser: { ...user, roles: { ...user.roles, [app2.appId]: 'BASIC' } } })
239
191
  .expect(200)
240
192
  .expect("Content-Type", /json/)
241
193
 
242
- expect(res.body.message).toEqual("User synced.")
194
+ expect(res.body.message).toEqual('User synced.')
243
195
  })
244
196
  })
245
197
  })
package/src/app.ts CHANGED
@@ -2,9 +2,21 @@ if (process.env.DD_APM_ENABLED) {
2
2
  require("./ddApm")
3
3
  }
4
4
 
5
+ if (process.env.ELASTIC_APM_ENABLED) {
6
+ require("./elasticApm")
7
+ }
8
+
5
9
  // need to load environment first
6
10
  import env from "./environment"
7
11
 
12
+ // enable APM if configured
13
+ if (process.env.ELASTIC_APM_ENABLED) {
14
+ const apm = require("elastic-apm-node").start({
15
+ serviceName: process.env.SERVICE,
16
+ environment: process.env.BUDIBASE_ENVIRONMENT,
17
+ })
18
+ }
19
+
8
20
  import { ExtendableContext } from "koa"
9
21
  import * as db from "./db"
10
22
  db.init()
@@ -41,8 +53,7 @@ app.use(
41
53
  })
42
54
  )
43
55
 
44
- app.use(middleware.correlation)
45
- app.use(middleware.pino)
56
+ app.use(middleware.logging)
46
57
  app.use(userAgent)
47
58
 
48
59
  if (env.isProd()) {
@@ -0,0 +1,10 @@
1
+ import apm from "elastic-apm-node"
2
+
3
+ // enable APM if configured
4
+ if (process.env.ELASTIC_APM_ENABLED) {
5
+ console.log("Starting elastic-apm-node")
6
+ apm.start({
7
+ serviceName: process.env.SERVICE,
8
+ environment: process.env.BUDIBASE_ENVIRONMENT,
9
+ })
10
+ }
@@ -62,6 +62,7 @@ const environment = {
62
62
  // minor
63
63
  SALT_ROUNDS: process.env.SALT_ROUNDS,
64
64
  LOGGER: process.env.LOGGER,
65
+ LOG_LEVEL: process.env.LOG_LEVEL,
65
66
  ACCOUNT_PORTAL_URL: process.env.ACCOUNT_PORTAL_URL,
66
67
  AUTOMATION_MAX_ITERATIONS:
67
68
  parseIntSafe(process.env.AUTOMATION_MAX_ITERATIONS) || 200,
@@ -243,14 +243,11 @@ class SqlServerIntegration extends Sql implements DatasourcePlus {
243
243
  if (typeof name !== "string") {
244
244
  continue
245
245
  }
246
- const hasDefault = def.COLUMN_DEFAULT
247
- const isAuto = !!autoColumns.find(col => col === name)
248
- const required = !!requiredColumns.find(col => col === name)
249
246
  schema[name] = {
250
- autocolumn: isAuto,
247
+ autocolumn: !!autoColumns.find(col => col === name),
251
248
  name: name,
252
249
  constraints: {
253
- presence: required && !isAuto && !hasDefault,
250
+ presence: requiredColumns.find(col => col === name),
254
251
  },
255
252
  ...convertSqlType(def.DATA_TYPE),
256
253
  externalType: def.DATA_TYPE,
@@ -229,15 +229,13 @@ class MySQLIntegration extends Sql implements DatasourcePlus {
229
229
  if (column.Key === "PRI" && primaryKeys.indexOf(column.Key) === -1) {
230
230
  primaryKeys.push(columnName)
231
231
  }
232
- const hasDefault = column.Default != null
232
+ const constraints = {
233
+ presence: column.Null !== "YES",
234
+ }
233
235
  const isAuto: boolean =
234
236
  typeof column.Extra === "string" &&
235
237
  (column.Extra === "auto_increment" ||
236
238
  column.Extra.toLowerCase().includes("generated"))
237
- const required = column.Null !== "YES"
238
- const constraints = {
239
- presence: required && !isAuto && !hasDefault,
240
- }
241
239
  schema[columnName] = {
242
240
  name: columnName,
243
241
  autocolumn: isAuto,
@@ -262,17 +262,15 @@ class PostgresIntegration extends Sql implements DatasourcePlus {
262
262
  column.identity_start ||
263
263
  column.identity_increment
264
264
  )
265
- const hasDefault = column.column_default != null
266
- const hasNextVal =
265
+ const constraints = {
266
+ presence: column.is_nullable === "NO",
267
+ }
268
+ const hasDefault =
267
269
  typeof column.column_default === "string" &&
268
270
  column.column_default.startsWith("nextval")
269
271
  const isGenerated =
270
272
  column.is_generated && column.is_generated !== "NEVER"
271
- const isAuto: boolean = hasNextVal || identity || isGenerated
272
- const required = column.is_nullable === "NO"
273
- const constraints = {
274
- presence: required && !hasDefault && !isGenerated,
275
- }
273
+ const isAuto: boolean = hasDefault || identity || isGenerated
276
274
  tables[tableName].schema[columnName] = {
277
275
  autocolumn: isAuto,
278
276
  name: columnName,
@@ -6,7 +6,6 @@ interface RedisConfig {
6
6
  port: number
7
7
  username: string
8
8
  password?: string
9
- db?: number
10
9
  }
11
10
 
12
11
  const SCHEMA: Integration = {
@@ -33,12 +32,6 @@ const SCHEMA: Integration = {
33
32
  type: "password",
34
33
  required: false,
35
34
  },
36
- db: {
37
- type: "number",
38
- required: false,
39
- display: "DB",
40
- default: 0,
41
- },
42
35
  },
43
36
  query: {
44
37
  create: {
@@ -95,7 +88,6 @@ class RedisIntegration {
95
88
  port: this.config.port,
96
89
  username: this.config.username,
97
90
  password: this.config.password,
98
- db: this.config.db,
99
91
  })
100
92
  }
101
93
 
@@ -151,9 +151,6 @@ class RestIntegration implements IntegrationBase {
151
151
  data = data[keys[0]]
152
152
  }
153
153
  raw = rawXml
154
- } else if (contentType.includes("application/pdf")) {
155
- data = await response.arrayBuffer() // Save PDF as ArrayBuffer
156
- raw = Buffer.from(data)
157
154
  } else {
158
155
  data = await response.text()
159
156
  raw = data
@@ -9,6 +9,6 @@ export const run = async () => {
9
9
 
10
10
  // sync app count
11
11
  const tenantId = tenancy.getTenantId()
12
- console.log(`Syncing app count: ${appCount}`)
12
+ console.log(`[Tenant: ${tenantId}] Syncing app count: ${appCount}`)
13
13
  await quotas.setUsage(appCount, StaticQuotaName.APPS, QuotaUsageType.STATIC)
14
14
  }
@@ -1,4 +1,4 @@
1
- import { db as dbCore } from "@budibase/backend-core"
1
+ import { tenancy, db as dbCore } from "@budibase/backend-core"
2
2
  import { getUniqueRows } from "../../../utilities/usageQuota/rows"
3
3
  import { quotas } from "@budibase/pro"
4
4
  import { StaticQuotaName, QuotaUsageType, App } from "@budibase/types"
@@ -18,7 +18,8 @@ export const run = async () => {
18
18
  })
19
19
 
20
20
  // sync row count
21
- console.log(`Syncing row count: ${rowCount}`)
21
+ const tenantId = tenancy.getTenantId()
22
+ console.log(`[Tenant: ${tenantId}] Syncing row count: ${rowCount}`)
22
23
  await quotas.setUsagePerApp(
23
24
  counts,
24
25
  StaticQuotaName.ROWS,
@@ -24,7 +24,7 @@ describe("syncRows", () => {
24
24
 
25
25
  // app 1
26
26
  const app1 = config.app
27
- await context.doInAppContext(app1!.appId, async () => {
27
+ await context.doInAppContext(app1.appId, async () => {
28
28
  await config.createTable()
29
29
  await config.createRow()
30
30
  })
@@ -43,7 +43,7 @@ describe("syncRows", () => {
43
43
  usageDoc = await quotas.getQuotaUsage()
44
44
  expect(usageDoc.usageQuota.rows).toEqual(3)
45
45
  expect(
46
- usageDoc.apps?.[dbCore.getProdAppID(app1!.appId)].usageQuota.rows
46
+ usageDoc.apps?.[dbCore.getProdAppID(app1.appId)].usageQuota.rows
47
47
  ).toEqual(1)
48
48
  expect(
49
49
  usageDoc.apps?.[dbCore.getProdAppID(app2.appId)].usageQuota.rows