@budibase/server 2.5.5-alpha.3 → 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.
- package/builder/assets/{index.841e62d8.css → index.7f9a008b.css} +3 -3
- package/builder/assets/index.f493a2b3.js +1817 -0
- package/builder/index.html +2 -2
- package/dist/api/routes/index.js +0 -2
- package/dist/app.js +11 -2
- package/dist/elasticApm.js +14 -0
- package/dist/environment.js +1 -0
- package/dist/integrations/microsoftSqlServer.js +2 -5
- package/dist/integrations/mysql.js +3 -5
- package/dist/integrations/postgres.js +5 -7
- package/dist/integrations/redis.js +0 -7
- package/dist/integrations/rest.js +0 -4
- package/dist/migrations/functions/usageQuotas/syncApps.js +1 -1
- package/dist/migrations/functions/usageQuotas/syncRows.js +2 -1
- package/dist/package.json +12 -12
- package/dist/startup.js +27 -29
- package/dist/threads/automation.js +3 -14
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +13 -13
- package/scripts/dev/manage.js +0 -2
- package/scripts/integrations/mssql/data/entrypoint.sh +0 -1
- package/scripts/integrations/mssql/data/setup.sql +17 -17
- package/scripts/integrations/mysql/init.sql +1 -1
- package/scripts/integrations/postgres/init.sql +0 -1
- package/scripts/likeCypress.ts +35 -0
- package/src/api/routes/index.ts +0 -2
- package/src/api/routes/tests/automation.spec.js +2 -5
- package/src/api/routes/tests/user.spec.js +13 -61
- package/src/app.ts +13 -2
- package/src/elasticApm.ts +10 -0
- package/src/environment.ts +1 -0
- package/src/integrations/microsoftSqlServer.ts +2 -5
- package/src/integrations/mysql.ts +3 -5
- package/src/integrations/postgres.ts +5 -7
- package/src/integrations/redis.ts +0 -8
- package/src/integrations/rest.ts +0 -3
- package/src/migrations/functions/usageQuotas/syncApps.ts +1 -1
- package/src/migrations/functions/usageQuotas/syncRows.ts +3 -2
- package/src/migrations/functions/usageQuotas/tests/syncRows.spec.ts +2 -2
- package/src/startup.ts +33 -34
- package/src/tests/jestEnv.ts +1 -0
- package/src/tests/jestSetup.ts +1 -0
- package/src/tests/logging.ts +34 -0
- package/src/threads/automation.ts +4 -16
- package/builder/assets/index.c409c736.js +0 -1776
- package/dist/api/controllers/ops.js +0 -40
- package/dist/api/routes/ops.js +0 -52
- package/src/api/controllers/ops.ts +0 -32
- 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
|
|
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
|
|
49
|
-
"@budibase/client": "2.5.5
|
|
50
|
-
"@budibase/pro": "2.5.
|
|
51
|
-
"@budibase/shared-core": "2.5.5
|
|
52
|
-
"@budibase/string-templates": "2.5.5
|
|
53
|
-
"@budibase/types": "2.5.5
|
|
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,9 +116,9 @@
|
|
|
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.
|
|
119
|
+
"vm2": "^3.9.15",
|
|
119
120
|
"worker-farm": "1.7.0",
|
|
120
|
-
"xml2js": "0.
|
|
121
|
+
"xml2js": "0.4.23",
|
|
121
122
|
"yargs": "13.2.4",
|
|
122
123
|
"zlib": "1.0.5"
|
|
123
124
|
},
|
|
@@ -148,7 +149,7 @@
|
|
|
148
149
|
"@types/tar": "6.1.3",
|
|
149
150
|
"@typescript-eslint/parser": "5.45.0",
|
|
150
151
|
"apidoc": "0.50.4",
|
|
151
|
-
"babel-jest": "
|
|
152
|
+
"babel-jest": "27.5.1",
|
|
152
153
|
"copyfiles": "2.4.1",
|
|
153
154
|
"docker-compose": "0.23.17",
|
|
154
155
|
"eslint": "6.8.0",
|
|
@@ -156,7 +157,6 @@
|
|
|
156
157
|
"is-wsl": "2.2.0",
|
|
157
158
|
"jest": "29.5.0",
|
|
158
159
|
"jest-openapi": "0.14.2",
|
|
159
|
-
"jest-runner": "29.5.0",
|
|
160
160
|
"jest-serial-runner": "^1.2.1",
|
|
161
161
|
"nodemon": "2.0.15",
|
|
162
162
|
"openapi-types": "9.3.1",
|
|
@@ -176,5 +176,5 @@
|
|
|
176
176
|
"optionalDependencies": {
|
|
177
177
|
"oracledb": "5.3.0"
|
|
178
178
|
},
|
|
179
|
-
"gitHead": "
|
|
179
|
+
"gitHead": "ed22164a05a38f41d3327b2ad18f23ddf857a062"
|
|
180
180
|
}
|
package/scripts/dev/manage.js
CHANGED
|
@@ -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 => {
|
|
@@ -34,7 +34,7 @@ GO
|
|
|
34
34
|
CREATE TABLE people
|
|
35
35
|
(
|
|
36
36
|
name varchar(30) NOT NULL,
|
|
37
|
-
age
|
|
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
|
|
@@ -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")
|
package/src/api/routes/index.ts
CHANGED
|
@@ -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
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
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(
|
|
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(
|
|
223
|
-
const app2 = await config.createApp(
|
|
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
|
-
|
|
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(
|
|
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.
|
|
45
|
-
app.use(middleware.pino)
|
|
56
|
+
app.use(middleware.logging)
|
|
46
57
|
app.use(userAgent)
|
|
47
58
|
|
|
48
59
|
if (env.isProd()) {
|
package/src/environment.ts
CHANGED
|
@@ -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:
|
|
247
|
+
autocolumn: !!autoColumns.find(col => col === name),
|
|
251
248
|
name: name,
|
|
252
249
|
constraints: {
|
|
253
|
-
presence:
|
|
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
|
|
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
|
|
266
|
-
|
|
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 =
|
|
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
|
|
package/src/integrations/rest.ts
CHANGED
|
@@ -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
|
-
|
|
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
|
|
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
|
|
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
|