@budibase/backend-core 2.9.19 → 2.9.21-alpha.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/dist/index.js +266 -324
- package/dist/index.js.map +4 -4
- package/dist/index.js.meta.json +1 -1
- package/dist/package.json +19 -4
- package/dist/plugins.js +1 -1
- package/dist/plugins.js.map +1 -1
- package/dist/plugins.js.meta.json +1 -1
- package/dist/src/security/permissions.d.ts +1 -1
- package/dist/tests.js +222 -260
- package/dist/tests.js.map +4 -4
- package/dist/tests.js.meta.json +1 -1
- package/package.json +19 -4
- package/dist/tsconfig.build.tsbuildinfo +0 -1
- package/src/accounts/accounts.ts +0 -82
- package/src/accounts/api.ts +0 -59
- package/src/accounts/index.ts +0 -1
- package/src/auth/auth.ts +0 -208
- package/src/auth/index.ts +0 -1
- package/src/auth/tests/auth.spec.ts +0 -14
- package/src/blacklist/blacklist.ts +0 -54
- package/src/blacklist/index.ts +0 -1
- package/src/blacklist/tests/blacklist.spec.ts +0 -46
- package/src/cache/appMetadata.ts +0 -88
- package/src/cache/base/index.ts +0 -92
- package/src/cache/generic.ts +0 -30
- package/src/cache/index.ts +0 -5
- package/src/cache/tests/writethrough.spec.ts +0 -138
- package/src/cache/user.ts +0 -69
- package/src/cache/writethrough.ts +0 -133
- package/src/configs/configs.ts +0 -257
- package/src/configs/index.ts +0 -1
- package/src/configs/tests/configs.spec.ts +0 -184
- package/src/constants/db.ts +0 -63
- package/src/constants/index.ts +0 -2
- package/src/constants/misc.ts +0 -50
- package/src/context/Context.ts +0 -14
- package/src/context/identity.ts +0 -58
- package/src/context/index.ts +0 -3
- package/src/context/mainContext.ts +0 -310
- package/src/context/tests/index.spec.ts +0 -147
- package/src/context/types.ts +0 -11
- package/src/db/Replication.ts +0 -84
- package/src/db/constants.ts +0 -10
- package/src/db/couch/DatabaseImpl.ts +0 -238
- package/src/db/couch/connections.ts +0 -77
- package/src/db/couch/index.ts +0 -5
- package/src/db/couch/pouchDB.ts +0 -97
- package/src/db/couch/pouchDump.ts +0 -0
- package/src/db/couch/utils.ts +0 -50
- package/src/db/db.ts +0 -39
- package/src/db/errors.ts +0 -14
- package/src/db/index.ts +0 -12
- package/src/db/lucene.ts +0 -732
- package/src/db/searchIndexes/index.ts +0 -1
- package/src/db/searchIndexes/searchIndexes.ts +0 -62
- package/src/db/tests/index.spec.js +0 -25
- package/src/db/tests/lucene.spec.ts +0 -298
- package/src/db/tests/pouch.spec.js +0 -62
- package/src/db/tests/utils.spec.ts +0 -63
- package/src/db/utils.ts +0 -207
- package/src/db/views.ts +0 -241
- package/src/docIds/conversions.ts +0 -59
- package/src/docIds/ids.ts +0 -113
- package/src/docIds/index.ts +0 -2
- package/src/docIds/newid.ts +0 -5
- package/src/docIds/params.ts +0 -174
- package/src/docUpdates/index.ts +0 -29
- package/src/environment.ts +0 -201
- package/src/errors/errors.ts +0 -119
- package/src/errors/index.ts +0 -1
- package/src/events/analytics.ts +0 -6
- package/src/events/asyncEvents/index.ts +0 -2
- package/src/events/asyncEvents/publisher.ts +0 -12
- package/src/events/asyncEvents/queue.ts +0 -22
- package/src/events/backfill.ts +0 -183
- package/src/events/documentId.ts +0 -56
- package/src/events/events.ts +0 -40
- package/src/events/identification.ts +0 -310
- package/src/events/index.ts +0 -14
- package/src/events/processors/AnalyticsProcessor.ts +0 -64
- package/src/events/processors/AuditLogsProcessor.ts +0 -93
- package/src/events/processors/LoggingProcessor.ts +0 -37
- package/src/events/processors/Processors.ts +0 -52
- package/src/events/processors/async/DocumentUpdateProcessor.ts +0 -43
- package/src/events/processors/index.ts +0 -19
- package/src/events/processors/posthog/PosthogProcessor.ts +0 -118
- package/src/events/processors/posthog/index.ts +0 -2
- package/src/events/processors/posthog/rateLimiting.ts +0 -106
- package/src/events/processors/posthog/tests/PosthogProcessor.spec.ts +0 -168
- package/src/events/processors/types.ts +0 -1
- package/src/events/publishers/account.ts +0 -35
- package/src/events/publishers/app.ts +0 -155
- package/src/events/publishers/auditLog.ts +0 -26
- package/src/events/publishers/auth.ts +0 -73
- package/src/events/publishers/automation.ts +0 -110
- package/src/events/publishers/backfill.ts +0 -74
- package/src/events/publishers/backup.ts +0 -42
- package/src/events/publishers/datasource.ts +0 -48
- package/src/events/publishers/email.ts +0 -17
- package/src/events/publishers/environmentVariable.ts +0 -38
- package/src/events/publishers/group.ts +0 -99
- package/src/events/publishers/index.ts +0 -24
- package/src/events/publishers/installation.ts +0 -38
- package/src/events/publishers/layout.ts +0 -26
- package/src/events/publishers/license.ts +0 -84
- package/src/events/publishers/org.ts +0 -37
- package/src/events/publishers/plugin.ts +0 -47
- package/src/events/publishers/query.ts +0 -88
- package/src/events/publishers/role.ts +0 -62
- package/src/events/publishers/rows.ts +0 -29
- package/src/events/publishers/screen.ts +0 -36
- package/src/events/publishers/serve.ts +0 -43
- package/src/events/publishers/table.ts +0 -70
- package/src/events/publishers/user.ts +0 -202
- package/src/events/publishers/view.ts +0 -107
- package/src/featureFlags/index.ts +0 -77
- package/src/featureFlags/tests/featureFlags.spec.ts +0 -85
- package/src/helpers.ts +0 -9
- package/src/index.ts +0 -53
- package/src/installation.ts +0 -107
- package/src/logging/alerts.ts +0 -26
- package/src/logging/correlation/correlation.ts +0 -13
- package/src/logging/correlation/index.ts +0 -1
- package/src/logging/correlation/middleware.ts +0 -17
- package/src/logging/index.ts +0 -4
- package/src/logging/pino/logger.ts +0 -232
- package/src/logging/pino/middleware.ts +0 -45
- package/src/logging/system.ts +0 -81
- package/src/logging/tests/system.spec.ts +0 -61
- package/src/middleware/adminOnly.ts +0 -9
- package/src/middleware/auditLog.ts +0 -6
- package/src/middleware/authenticated.ts +0 -193
- package/src/middleware/builderOnly.ts +0 -20
- package/src/middleware/builderOrAdmin.ts +0 -20
- package/src/middleware/csrf.ts +0 -81
- package/src/middleware/errorHandling.ts +0 -29
- package/src/middleware/index.ts +0 -21
- package/src/middleware/internalApi.ts +0 -23
- package/src/middleware/joi-validator.ts +0 -45
- package/src/middleware/matchers.ts +0 -47
- package/src/middleware/passport/datasource/google.ts +0 -95
- package/src/middleware/passport/local.ts +0 -54
- package/src/middleware/passport/sso/google.ts +0 -77
- package/src/middleware/passport/sso/oidc.ts +0 -154
- package/src/middleware/passport/sso/sso.ts +0 -165
- package/src/middleware/passport/sso/tests/google.spec.ts +0 -67
- package/src/middleware/passport/sso/tests/oidc.spec.ts +0 -152
- package/src/middleware/passport/sso/tests/sso.spec.ts +0 -197
- package/src/middleware/passport/utils.ts +0 -38
- package/src/middleware/querystringToBody.ts +0 -28
- package/src/middleware/tenancy.ts +0 -36
- package/src/middleware/tests/builder.spec.ts +0 -180
- package/src/middleware/tests/matchers.spec.ts +0 -134
- package/src/migrations/definitions.ts +0 -40
- package/src/migrations/index.ts +0 -2
- package/src/migrations/migrations.ts +0 -191
- package/src/migrations/tests/__snapshots__/migrations.spec.ts.snap +0 -11
- package/src/migrations/tests/migrations.spec.ts +0 -64
- package/src/objectStore/buckets/app.ts +0 -40
- package/src/objectStore/buckets/global.ts +0 -29
- package/src/objectStore/buckets/index.ts +0 -3
- package/src/objectStore/buckets/plugins.ts +0 -71
- package/src/objectStore/buckets/tests/app.spec.ts +0 -171
- package/src/objectStore/buckets/tests/global.spec.ts +0 -74
- package/src/objectStore/buckets/tests/plugins.spec.ts +0 -111
- package/src/objectStore/cloudfront.ts +0 -41
- package/src/objectStore/index.ts +0 -3
- package/src/objectStore/objectStore.ts +0 -440
- package/src/objectStore/utils.ts +0 -27
- package/src/platform/index.ts +0 -3
- package/src/platform/platformDb.ts +0 -6
- package/src/platform/tenants.ts +0 -101
- package/src/platform/tests/tenants.spec.ts +0 -26
- package/src/platform/users.ts +0 -90
- package/src/plugin/index.ts +0 -1
- package/src/plugin/tests/validation.spec.ts +0 -83
- package/src/plugin/utils.ts +0 -156
- package/src/queue/constants.ts +0 -6
- package/src/queue/inMemoryQueue.ts +0 -141
- package/src/queue/index.ts +0 -2
- package/src/queue/listeners.ts +0 -195
- package/src/queue/queue.ts +0 -54
- package/src/redis/index.ts +0 -6
- package/src/redis/init.ts +0 -86
- package/src/redis/redis.ts +0 -308
- package/src/redis/redlockImpl.ts +0 -139
- package/src/redis/utils.ts +0 -117
- package/src/security/encryption.ts +0 -179
- package/src/security/permissions.ts +0 -159
- package/src/security/roles.ts +0 -420
- package/src/security/sessions.ts +0 -120
- package/src/security/tests/encryption.spec.ts +0 -31
- package/src/security/tests/permissions.spec.ts +0 -145
- package/src/security/tests/sessions.spec.ts +0 -12
- package/src/tenancy/db.ts +0 -6
- package/src/tenancy/index.ts +0 -2
- package/src/tenancy/tenancy.ts +0 -140
- package/src/tenancy/tests/tenancy.spec.ts +0 -184
- package/src/timers/index.ts +0 -1
- package/src/timers/timers.ts +0 -22
- package/src/users/db.ts +0 -460
- package/src/users/events.ts +0 -176
- package/src/users/index.ts +0 -4
- package/src/users/lookup.ts +0 -102
- package/src/users/users.ts +0 -276
- package/src/users/utils.ts +0 -55
- package/src/utils/hashing.ts +0 -14
- package/src/utils/index.ts +0 -3
- package/src/utils/stringUtils.ts +0 -8
- package/src/utils/tests/utils.spec.ts +0 -191
- package/src/utils/utils.ts +0 -239
- package/tests/core/logging.ts +0 -34
- package/tests/core/utilities/index.ts +0 -6
- package/tests/core/utilities/jestUtils.ts +0 -30
- package/tests/core/utilities/mocks/alerts.ts +0 -3
- package/tests/core/utilities/mocks/date.ts +0 -2
- package/tests/core/utilities/mocks/events.ts +0 -131
- package/tests/core/utilities/mocks/fetch.ts +0 -17
- package/tests/core/utilities/mocks/index.ts +0 -10
- package/tests/core/utilities/mocks/licenses.ts +0 -107
- package/tests/core/utilities/mocks/posthog.ts +0 -7
- package/tests/core/utilities/structures/Chance.ts +0 -20
- package/tests/core/utilities/structures/accounts.ts +0 -115
- package/tests/core/utilities/structures/apps.ts +0 -21
- package/tests/core/utilities/structures/common.ts +0 -7
- package/tests/core/utilities/structures/db.ts +0 -12
- package/tests/core/utilities/structures/documents/index.ts +0 -1
- package/tests/core/utilities/structures/documents/platform/index.ts +0 -1
- package/tests/core/utilities/structures/documents/platform/installation.ts +0 -12
- package/tests/core/utilities/structures/generator.ts +0 -2
- package/tests/core/utilities/structures/index.ts +0 -15
- package/tests/core/utilities/structures/koa.ts +0 -16
- package/tests/core/utilities/structures/licenses.ts +0 -167
- package/tests/core/utilities/structures/plugins.ts +0 -19
- package/tests/core/utilities/structures/quotas.ts +0 -67
- package/tests/core/utilities/structures/scim.ts +0 -80
- package/tests/core/utilities/structures/shared.ts +0 -19
- package/tests/core/utilities/structures/sso.ts +0 -119
- package/tests/core/utilities/structures/tenants.ts +0 -5
- package/tests/core/utilities/structures/userGroups.ts +0 -10
- package/tests/core/utilities/structures/users.ts +0 -73
- package/tests/core/utilities/testContainerUtils.ts +0 -98
- package/tests/core/utilities/utils/index.ts +0 -1
- package/tests/core/utilities/utils/time.ts +0 -3
- package/tests/extra/DBTestConfiguration.ts +0 -36
- package/tests/extra/index.ts +0 -2
- package/tests/extra/testEnv.ts +0 -95
- package/tests/index.ts +0 -1
- package/tests/jestEnv.ts +0 -6
- package/tests/jestSetup.ts +0 -28
|
@@ -1,147 +0,0 @@
|
|
|
1
|
-
import { testEnv } from "../../../tests/extra"
|
|
2
|
-
import * as context from "../"
|
|
3
|
-
import { DEFAULT_TENANT_ID } from "../../constants"
|
|
4
|
-
|
|
5
|
-
describe("context", () => {
|
|
6
|
-
describe("doInTenant", () => {
|
|
7
|
-
describe("single-tenancy", () => {
|
|
8
|
-
beforeAll(() => {
|
|
9
|
-
testEnv.singleTenant()
|
|
10
|
-
})
|
|
11
|
-
|
|
12
|
-
it("defaults to the default tenant", () => {
|
|
13
|
-
const tenantId = context.getTenantId()
|
|
14
|
-
expect(tenantId).toBe(DEFAULT_TENANT_ID)
|
|
15
|
-
})
|
|
16
|
-
|
|
17
|
-
it("defaults to the default tenant db", async () => {
|
|
18
|
-
await context.doInTenant(DEFAULT_TENANT_ID, () => {
|
|
19
|
-
const db = context.getGlobalDB()
|
|
20
|
-
expect(db.name).toBe("global-db")
|
|
21
|
-
})
|
|
22
|
-
})
|
|
23
|
-
})
|
|
24
|
-
|
|
25
|
-
describe("multi-tenancy", () => {
|
|
26
|
-
beforeAll(() => {
|
|
27
|
-
testEnv.multiTenant()
|
|
28
|
-
})
|
|
29
|
-
|
|
30
|
-
it("fails when no tenant id is set", () => {
|
|
31
|
-
const test = () => {
|
|
32
|
-
let error: any
|
|
33
|
-
try {
|
|
34
|
-
context.getTenantId()
|
|
35
|
-
} catch (e) {
|
|
36
|
-
error = e
|
|
37
|
-
}
|
|
38
|
-
expect(error.message).toBe("Tenant id not found")
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
// test under no tenancy
|
|
42
|
-
test()
|
|
43
|
-
|
|
44
|
-
// test after tenancy has been accessed to ensure cleanup
|
|
45
|
-
context.doInTenant("test", () => {})
|
|
46
|
-
test()
|
|
47
|
-
})
|
|
48
|
-
|
|
49
|
-
it("fails when no tenant db is set", () => {
|
|
50
|
-
const test = () => {
|
|
51
|
-
let error: any
|
|
52
|
-
try {
|
|
53
|
-
context.getGlobalDB()
|
|
54
|
-
} catch (e) {
|
|
55
|
-
error = e
|
|
56
|
-
}
|
|
57
|
-
expect(error.message).toBe("Global DB not found")
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// test under no tenancy
|
|
61
|
-
test()
|
|
62
|
-
|
|
63
|
-
// test after tenancy has been accessed to ensure cleanup
|
|
64
|
-
context.doInTenant("test", () => {})
|
|
65
|
-
test()
|
|
66
|
-
})
|
|
67
|
-
|
|
68
|
-
it("sets tenant id", () => {
|
|
69
|
-
context.doInTenant("test", () => {
|
|
70
|
-
const tenantId = context.getTenantId()
|
|
71
|
-
expect(tenantId).toBe("test")
|
|
72
|
-
})
|
|
73
|
-
})
|
|
74
|
-
|
|
75
|
-
it("initialises the tenant db", async () => {
|
|
76
|
-
await context.doInTenant("test", () => {
|
|
77
|
-
const db = context.getGlobalDB()
|
|
78
|
-
expect(db.name).toBe("test_global-db")
|
|
79
|
-
})
|
|
80
|
-
})
|
|
81
|
-
|
|
82
|
-
it("sets the tenant id when nested with same tenant id", async () => {
|
|
83
|
-
await context.doInTenant("test", async () => {
|
|
84
|
-
const tenantId = context.getTenantId()
|
|
85
|
-
expect(tenantId).toBe("test")
|
|
86
|
-
|
|
87
|
-
await context.doInTenant("test", async () => {
|
|
88
|
-
const tenantId = context.getTenantId()
|
|
89
|
-
expect(tenantId).toBe("test")
|
|
90
|
-
|
|
91
|
-
await context.doInTenant("test", () => {
|
|
92
|
-
const tenantId = context.getTenantId()
|
|
93
|
-
expect(tenantId).toBe("test")
|
|
94
|
-
})
|
|
95
|
-
})
|
|
96
|
-
})
|
|
97
|
-
})
|
|
98
|
-
|
|
99
|
-
it("initialises the tenant db when nested with same tenant id", async () => {
|
|
100
|
-
await context.doInTenant("test", async () => {
|
|
101
|
-
const db = context.getGlobalDB()
|
|
102
|
-
expect(db.name).toBe("test_global-db")
|
|
103
|
-
|
|
104
|
-
await context.doInTenant("test", async () => {
|
|
105
|
-
const db = context.getGlobalDB()
|
|
106
|
-
expect(db.name).toBe("test_global-db")
|
|
107
|
-
|
|
108
|
-
await context.doInTenant("test", () => {
|
|
109
|
-
const db = context.getGlobalDB()
|
|
110
|
-
expect(db.name).toBe("test_global-db")
|
|
111
|
-
})
|
|
112
|
-
})
|
|
113
|
-
})
|
|
114
|
-
})
|
|
115
|
-
|
|
116
|
-
it("sets different tenant id inside another context", () => {
|
|
117
|
-
context.doInTenant("test", () => {
|
|
118
|
-
const tenantId = context.getTenantId()
|
|
119
|
-
expect(tenantId).toBe("test")
|
|
120
|
-
|
|
121
|
-
context.doInTenant("nested", () => {
|
|
122
|
-
const tenantId = context.getTenantId()
|
|
123
|
-
expect(tenantId).toBe("nested")
|
|
124
|
-
|
|
125
|
-
context.doInTenant("double-nested", () => {
|
|
126
|
-
const tenantId = context.getTenantId()
|
|
127
|
-
expect(tenantId).toBe("double-nested")
|
|
128
|
-
})
|
|
129
|
-
})
|
|
130
|
-
})
|
|
131
|
-
})
|
|
132
|
-
})
|
|
133
|
-
})
|
|
134
|
-
|
|
135
|
-
describe("doInScimContext", () => {
|
|
136
|
-
it("returns true when set", () => {
|
|
137
|
-
context.doInScimContext(() => {
|
|
138
|
-
const isScim = context.isScim()
|
|
139
|
-
expect(isScim).toBe(true)
|
|
140
|
-
})
|
|
141
|
-
})
|
|
142
|
-
it("returns false when not set", () => {
|
|
143
|
-
const isScim = context.isScim()
|
|
144
|
-
expect(isScim).toBe(false)
|
|
145
|
-
})
|
|
146
|
-
})
|
|
147
|
-
})
|
package/src/context/types.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { IdentityContext } from "@budibase/types"
|
|
2
|
-
|
|
3
|
-
// keep this out of Budibase types, don't want to expose context info
|
|
4
|
-
export type ContextMap = {
|
|
5
|
-
tenantId?: string
|
|
6
|
-
appId?: string
|
|
7
|
-
identity?: IdentityContext
|
|
8
|
-
environmentVariables?: Record<string, string>
|
|
9
|
-
isScim?: boolean
|
|
10
|
-
automationId?: string
|
|
11
|
-
}
|
package/src/db/Replication.ts
DELETED
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
import { getPouchDB, closePouchDB } from "./couch"
|
|
2
|
-
import { DocumentType } from "../constants"
|
|
3
|
-
|
|
4
|
-
class Replication {
|
|
5
|
-
source: any
|
|
6
|
-
target: any
|
|
7
|
-
replication: any
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
*
|
|
11
|
-
* @param {String} source - the DB you want to replicate or rollback to
|
|
12
|
-
* @param {String} target - the DB you want to replicate to, or rollback from
|
|
13
|
-
*/
|
|
14
|
-
constructor({ source, target }: any) {
|
|
15
|
-
this.source = getPouchDB(source)
|
|
16
|
-
this.target = getPouchDB(target)
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
close() {
|
|
20
|
-
return Promise.all([closePouchDB(this.source), closePouchDB(this.target)])
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
promisify(operation: any, opts = {}) {
|
|
24
|
-
return new Promise(resolve => {
|
|
25
|
-
operation(this.target, opts)
|
|
26
|
-
.on("denied", function (err: any) {
|
|
27
|
-
// a document failed to replicate (e.g. due to permissions)
|
|
28
|
-
throw new Error(`Denied: Document failed to replicate ${err}`)
|
|
29
|
-
})
|
|
30
|
-
.on("complete", function (info: any) {
|
|
31
|
-
return resolve(info)
|
|
32
|
-
})
|
|
33
|
-
.on("error", function (err: any) {
|
|
34
|
-
throw new Error(`Replication Error: ${err}`)
|
|
35
|
-
})
|
|
36
|
-
})
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Two way replication operation, intended to be promise based.
|
|
41
|
-
* @param {Object} opts - PouchDB replication options
|
|
42
|
-
*/
|
|
43
|
-
sync(opts = {}) {
|
|
44
|
-
this.replication = this.promisify(this.source.sync, opts)
|
|
45
|
-
return this.replication
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* One way replication operation, intended to be promise based.
|
|
50
|
-
* @param {Object} opts - PouchDB replication options
|
|
51
|
-
*/
|
|
52
|
-
replicate(opts = {}) {
|
|
53
|
-
this.replication = this.promisify(this.source.replicate.to, opts)
|
|
54
|
-
return this.replication
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
appReplicateOpts() {
|
|
58
|
-
return {
|
|
59
|
-
filter: (doc: any) => {
|
|
60
|
-
if (doc._id && doc._id.startsWith(DocumentType.AUTOMATION_LOG)) {
|
|
61
|
-
return false
|
|
62
|
-
}
|
|
63
|
-
return doc._id !== DocumentType.APP_METADATA
|
|
64
|
-
},
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Rollback the target DB back to the state of the source DB
|
|
70
|
-
*/
|
|
71
|
-
async rollback() {
|
|
72
|
-
await this.target.destroy()
|
|
73
|
-
// Recreate the DB again
|
|
74
|
-
this.target = getPouchDB(this.target.name)
|
|
75
|
-
// take the opportunity to remove deleted tombstones
|
|
76
|
-
await this.replicate()
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
cancel() {
|
|
80
|
-
this.replication.cancel()
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
export default Replication
|
package/src/db/constants.ts
DELETED
|
@@ -1,238 +0,0 @@
|
|
|
1
|
-
import Nano from "@budibase/nano"
|
|
2
|
-
import {
|
|
3
|
-
AllDocsResponse,
|
|
4
|
-
AnyDocument,
|
|
5
|
-
Database,
|
|
6
|
-
DatabaseOpts,
|
|
7
|
-
DatabaseQueryOpts,
|
|
8
|
-
DatabasePutOpts,
|
|
9
|
-
DatabaseCreateIndexOpts,
|
|
10
|
-
DatabaseDeleteIndexOpts,
|
|
11
|
-
Document,
|
|
12
|
-
isDocument,
|
|
13
|
-
} from "@budibase/types"
|
|
14
|
-
import { getCouchInfo } from "./connections"
|
|
15
|
-
import { directCouchUrlCall } from "./utils"
|
|
16
|
-
import { getPouchDB } from "./pouchDB"
|
|
17
|
-
import { WriteStream, ReadStream } from "fs"
|
|
18
|
-
import { newid } from "../../docIds/newid"
|
|
19
|
-
|
|
20
|
-
function buildNano(couchInfo: { url: string; cookie: string }) {
|
|
21
|
-
return Nano({
|
|
22
|
-
url: couchInfo.url,
|
|
23
|
-
requestDefaults: {
|
|
24
|
-
headers: {
|
|
25
|
-
Authorization: couchInfo.cookie,
|
|
26
|
-
},
|
|
27
|
-
},
|
|
28
|
-
parseUrl: false,
|
|
29
|
-
})
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export function DatabaseWithConnection(
|
|
33
|
-
dbName: string,
|
|
34
|
-
connection: string,
|
|
35
|
-
opts?: DatabaseOpts
|
|
36
|
-
) {
|
|
37
|
-
if (!connection) {
|
|
38
|
-
throw new Error("Must provide connection details")
|
|
39
|
-
}
|
|
40
|
-
return new DatabaseImpl(dbName, opts, connection)
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export class DatabaseImpl implements Database {
|
|
44
|
-
public readonly name: string
|
|
45
|
-
private static nano: Nano.ServerScope
|
|
46
|
-
private readonly instanceNano?: Nano.ServerScope
|
|
47
|
-
private readonly pouchOpts: DatabaseOpts
|
|
48
|
-
|
|
49
|
-
private readonly couchInfo = getCouchInfo()
|
|
50
|
-
|
|
51
|
-
constructor(dbName?: string, opts?: DatabaseOpts, connection?: string) {
|
|
52
|
-
if (dbName == null) {
|
|
53
|
-
throw new Error("Database name cannot be undefined.")
|
|
54
|
-
}
|
|
55
|
-
this.name = dbName
|
|
56
|
-
this.pouchOpts = opts || {}
|
|
57
|
-
if (connection) {
|
|
58
|
-
this.couchInfo = getCouchInfo(connection)
|
|
59
|
-
this.instanceNano = buildNano(this.couchInfo)
|
|
60
|
-
}
|
|
61
|
-
if (!DatabaseImpl.nano) {
|
|
62
|
-
DatabaseImpl.init()
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
static init() {
|
|
67
|
-
const couchInfo = getCouchInfo()
|
|
68
|
-
DatabaseImpl.nano = buildNano(couchInfo)
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
async exists() {
|
|
72
|
-
const response = await directCouchUrlCall({
|
|
73
|
-
url: `${this.couchInfo.url}/${this.name}`,
|
|
74
|
-
method: "HEAD",
|
|
75
|
-
cookie: this.couchInfo.cookie,
|
|
76
|
-
})
|
|
77
|
-
return response.status === 200
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
private nano() {
|
|
81
|
-
return this.instanceNano || DatabaseImpl.nano
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
async checkSetup() {
|
|
85
|
-
let shouldCreate = !this.pouchOpts?.skip_setup
|
|
86
|
-
// check exists in a lightweight fashion
|
|
87
|
-
let exists = await this.exists()
|
|
88
|
-
if (!shouldCreate && !exists) {
|
|
89
|
-
throw new Error("DB does not exist")
|
|
90
|
-
}
|
|
91
|
-
if (!exists) {
|
|
92
|
-
try {
|
|
93
|
-
await this.nano().db.create(this.name)
|
|
94
|
-
} catch (err: any) {
|
|
95
|
-
// Handling race conditions
|
|
96
|
-
if (err.statusCode !== 412) {
|
|
97
|
-
throw err
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
return this.nano().db.use(this.name)
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
private async updateOutput(fnc: any) {
|
|
105
|
-
try {
|
|
106
|
-
return await fnc()
|
|
107
|
-
} catch (err: any) {
|
|
108
|
-
if (err.statusCode) {
|
|
109
|
-
err.status = err.statusCode
|
|
110
|
-
}
|
|
111
|
-
throw err
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
async get<T>(id?: string): Promise<T | any> {
|
|
116
|
-
const db = await this.checkSetup()
|
|
117
|
-
if (!id) {
|
|
118
|
-
throw new Error("Unable to get doc without a valid _id.")
|
|
119
|
-
}
|
|
120
|
-
return this.updateOutput(() => db.get(id))
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
async remove(idOrDoc: string | Document, rev?: string) {
|
|
124
|
-
const db = await this.checkSetup()
|
|
125
|
-
let _id: string
|
|
126
|
-
let _rev: string
|
|
127
|
-
|
|
128
|
-
if (isDocument(idOrDoc)) {
|
|
129
|
-
_id = idOrDoc._id!
|
|
130
|
-
_rev = idOrDoc._rev!
|
|
131
|
-
} else {
|
|
132
|
-
_id = idOrDoc
|
|
133
|
-
_rev = rev!
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
if (!_id || !_rev) {
|
|
137
|
-
throw new Error("Unable to remove doc without a valid _id and _rev.")
|
|
138
|
-
}
|
|
139
|
-
return this.updateOutput(() => db.destroy(_id, _rev))
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
async post(document: AnyDocument, opts?: DatabasePutOpts) {
|
|
143
|
-
if (!document._id) {
|
|
144
|
-
document._id = newid()
|
|
145
|
-
}
|
|
146
|
-
return this.put(document, opts)
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
async put(document: AnyDocument, opts?: DatabasePutOpts) {
|
|
150
|
-
if (!document._id) {
|
|
151
|
-
throw new Error("Cannot store document without _id field.")
|
|
152
|
-
}
|
|
153
|
-
const db = await this.checkSetup()
|
|
154
|
-
if (!document.createdAt) {
|
|
155
|
-
document.createdAt = new Date().toISOString()
|
|
156
|
-
}
|
|
157
|
-
document.updatedAt = new Date().toISOString()
|
|
158
|
-
if (opts?.force && document._id) {
|
|
159
|
-
try {
|
|
160
|
-
const existing = await this.get(document._id)
|
|
161
|
-
if (existing) {
|
|
162
|
-
document._rev = existing._rev
|
|
163
|
-
}
|
|
164
|
-
} catch (err: any) {
|
|
165
|
-
if (err.status !== 404) {
|
|
166
|
-
throw err
|
|
167
|
-
}
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
return this.updateOutput(() => db.insert(document))
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
async bulkDocs(documents: AnyDocument[]) {
|
|
174
|
-
const db = await this.checkSetup()
|
|
175
|
-
return this.updateOutput(() => db.bulk({ docs: documents }))
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
async allDocs<T>(params: DatabaseQueryOpts): Promise<AllDocsResponse<T>> {
|
|
179
|
-
const db = await this.checkSetup()
|
|
180
|
-
return this.updateOutput(() => db.list(params))
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
async query<T>(
|
|
184
|
-
viewName: string,
|
|
185
|
-
params: DatabaseQueryOpts
|
|
186
|
-
): Promise<AllDocsResponse<T>> {
|
|
187
|
-
const db = await this.checkSetup()
|
|
188
|
-
const [database, view] = viewName.split("/")
|
|
189
|
-
return this.updateOutput(() => db.view(database, view, params))
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
async destroy() {
|
|
193
|
-
try {
|
|
194
|
-
return await this.nano().db.destroy(this.name)
|
|
195
|
-
} catch (err: any) {
|
|
196
|
-
// didn't exist, don't worry
|
|
197
|
-
if (err.statusCode === 404) {
|
|
198
|
-
return
|
|
199
|
-
} else {
|
|
200
|
-
throw { ...err, status: err.statusCode }
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
async compact() {
|
|
206
|
-
const db = await this.checkSetup()
|
|
207
|
-
return this.updateOutput(() => db.compact())
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
// All below functions are in-frequently called, just utilise PouchDB
|
|
211
|
-
// for them as it implements them better than we can
|
|
212
|
-
async dump(stream: WriteStream, opts?: { filter?: any }) {
|
|
213
|
-
const pouch = getPouchDB(this.name)
|
|
214
|
-
// @ts-ignore
|
|
215
|
-
return pouch.dump(stream, opts)
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
async load(stream: ReadStream) {
|
|
219
|
-
const pouch = getPouchDB(this.name)
|
|
220
|
-
// @ts-ignore
|
|
221
|
-
return pouch.load(stream)
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
async createIndex(opts: DatabaseCreateIndexOpts) {
|
|
225
|
-
const pouch = getPouchDB(this.name)
|
|
226
|
-
return pouch.createIndex(opts)
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
async deleteIndex(opts: DatabaseDeleteIndexOpts) {
|
|
230
|
-
const pouch = getPouchDB(this.name)
|
|
231
|
-
return pouch.deleteIndex(opts)
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
async getIndexes() {
|
|
235
|
-
const pouch = getPouchDB(this.name)
|
|
236
|
-
return pouch.getIndexes()
|
|
237
|
-
}
|
|
238
|
-
}
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
import env from "../../environment"
|
|
2
|
-
|
|
3
|
-
export const getCouchInfo = (connection?: string) => {
|
|
4
|
-
const urlInfo = getUrlInfo(connection)
|
|
5
|
-
let username
|
|
6
|
-
let password
|
|
7
|
-
if (urlInfo.auth?.username) {
|
|
8
|
-
// set from url
|
|
9
|
-
username = urlInfo.auth.username
|
|
10
|
-
} else if (env.COUCH_DB_USERNAME) {
|
|
11
|
-
// set from env
|
|
12
|
-
username = env.COUCH_DB_USERNAME
|
|
13
|
-
} else if (!env.isTest()) {
|
|
14
|
-
throw new Error("CouchDB username not set")
|
|
15
|
-
}
|
|
16
|
-
if (urlInfo.auth?.password) {
|
|
17
|
-
// set from url
|
|
18
|
-
password = urlInfo.auth.password
|
|
19
|
-
} else if (env.COUCH_DB_PASSWORD) {
|
|
20
|
-
// set from env
|
|
21
|
-
password = env.COUCH_DB_PASSWORD
|
|
22
|
-
} else if (!env.isTest()) {
|
|
23
|
-
throw new Error("CouchDB password not set")
|
|
24
|
-
}
|
|
25
|
-
const authCookie = Buffer.from(`${username}:${password}`).toString("base64")
|
|
26
|
-
return {
|
|
27
|
-
url: urlInfo.url!,
|
|
28
|
-
auth: {
|
|
29
|
-
username: username,
|
|
30
|
-
password: password,
|
|
31
|
-
},
|
|
32
|
-
cookie: `Basic ${authCookie}`,
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export const getUrlInfo = (url = env.COUCH_DB_URL) => {
|
|
37
|
-
let cleanUrl, username, password, host
|
|
38
|
-
if (url) {
|
|
39
|
-
// Ensure the URL starts with a protocol
|
|
40
|
-
const protoRegex = /^https?:\/\//i
|
|
41
|
-
if (!protoRegex.test(url)) {
|
|
42
|
-
url = `http://${url}`
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
// Split into protocol and remainder
|
|
46
|
-
const split = url.split("://")
|
|
47
|
-
const protocol = split[0]
|
|
48
|
-
const rest = split.slice(1).join("://")
|
|
49
|
-
|
|
50
|
-
// Extract auth if specified
|
|
51
|
-
if (url.includes("@")) {
|
|
52
|
-
// Split into host and remainder
|
|
53
|
-
let parts = rest.split("@")
|
|
54
|
-
host = parts[parts.length - 1]
|
|
55
|
-
let auth = parts.slice(0, -1).join("@")
|
|
56
|
-
|
|
57
|
-
// Split auth into username and password
|
|
58
|
-
if (auth.includes(":")) {
|
|
59
|
-
const authParts = auth.split(":")
|
|
60
|
-
username = authParts[0]
|
|
61
|
-
password = authParts.slice(1).join(":")
|
|
62
|
-
} else {
|
|
63
|
-
username = auth
|
|
64
|
-
}
|
|
65
|
-
} else {
|
|
66
|
-
host = rest
|
|
67
|
-
}
|
|
68
|
-
cleanUrl = `${protocol}://${host}`
|
|
69
|
-
}
|
|
70
|
-
return {
|
|
71
|
-
url: cleanUrl,
|
|
72
|
-
auth: {
|
|
73
|
-
username,
|
|
74
|
-
password,
|
|
75
|
-
},
|
|
76
|
-
}
|
|
77
|
-
}
|
package/src/db/couch/index.ts
DELETED
package/src/db/couch/pouchDB.ts
DELETED
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
import PouchDB from "pouchdb"
|
|
2
|
-
import env from "../../environment"
|
|
3
|
-
import { PouchOptions } from "@budibase/types"
|
|
4
|
-
import { getCouchInfo } from "./connections"
|
|
5
|
-
|
|
6
|
-
let Pouch: any
|
|
7
|
-
let initialised = false
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Return a constructor for PouchDB.
|
|
11
|
-
* This should be rarely used outside of the main application config.
|
|
12
|
-
* Exposed for exceptional cases such as in-memory views.
|
|
13
|
-
*/
|
|
14
|
-
export const getPouch = (opts: PouchOptions = {}) => {
|
|
15
|
-
let { url, cookie } = getCouchInfo()
|
|
16
|
-
let POUCH_DB_DEFAULTS = {
|
|
17
|
-
prefix: url,
|
|
18
|
-
fetch: (url: string, opts: any) => {
|
|
19
|
-
// use a specific authorization cookie - be very explicit about how we authenticate
|
|
20
|
-
opts.headers.set("Authorization", cookie)
|
|
21
|
-
return PouchDB.fetch(url, opts)
|
|
22
|
-
},
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
if (opts.inMemory) {
|
|
26
|
-
const inMemory = require("pouchdb-adapter-memory")
|
|
27
|
-
PouchDB.plugin(inMemory)
|
|
28
|
-
POUCH_DB_DEFAULTS = {
|
|
29
|
-
// @ts-ignore
|
|
30
|
-
adapter: "memory",
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
if (opts.onDisk) {
|
|
35
|
-
POUCH_DB_DEFAULTS = {
|
|
36
|
-
// @ts-ignore
|
|
37
|
-
adapter: "leveldb",
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
if (opts.replication) {
|
|
42
|
-
const replicationStream = require("@budibase/pouchdb-replication-stream")
|
|
43
|
-
PouchDB.plugin(replicationStream.plugin)
|
|
44
|
-
// @ts-ignore
|
|
45
|
-
PouchDB.adapter("writableStream", replicationStream.adapters.writableStream)
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
if (opts.find) {
|
|
49
|
-
const find = require("pouchdb-find")
|
|
50
|
-
PouchDB.plugin(find)
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
return PouchDB.defaults(POUCH_DB_DEFAULTS)
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
export function init(opts?: PouchOptions) {
|
|
57
|
-
Pouch = getPouch(opts)
|
|
58
|
-
initialised = true
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
const checkInitialised = () => {
|
|
62
|
-
if (!initialised) {
|
|
63
|
-
throw new Error("init has not been called")
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
export function getPouchDB(dbName: string, opts?: any): PouchDB.Database {
|
|
68
|
-
checkInitialised()
|
|
69
|
-
const db = new Pouch(dbName, opts)
|
|
70
|
-
const dbPut = db.put
|
|
71
|
-
db.put = async (doc: any, options = {}) => {
|
|
72
|
-
if (!doc.createdAt) {
|
|
73
|
-
doc.createdAt = new Date().toISOString()
|
|
74
|
-
}
|
|
75
|
-
doc.updatedAt = new Date().toISOString()
|
|
76
|
-
return dbPut(doc, options)
|
|
77
|
-
}
|
|
78
|
-
db.exists = async () => {
|
|
79
|
-
const info = await db.info()
|
|
80
|
-
return !info.error
|
|
81
|
-
}
|
|
82
|
-
return db
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
// use this function if you have called getPouchDB - close
|
|
86
|
-
// the databases you've opened once finished
|
|
87
|
-
export async function closePouchDB(db: PouchDB.Database) {
|
|
88
|
-
if (!db || env.isTest()) {
|
|
89
|
-
return
|
|
90
|
-
}
|
|
91
|
-
try {
|
|
92
|
-
// specifically await so that if there is an error, it can be ignored
|
|
93
|
-
return await db.close()
|
|
94
|
-
} catch (err) {
|
|
95
|
-
// ignore error, already closed
|
|
96
|
-
}
|
|
97
|
-
}
|
|
File without changes
|