@budibase/backend-core 3.2.4 → 3.2.6
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.map +1 -1
- package/dist/index.js.meta.json +1 -1
- package/dist/package.json +11 -4
- package/dist/plugins.js.meta.json +1 -1
- package/package.json +11 -4
- 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 -210
- 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 -150
- package/src/cache/docWritethrough.ts +0 -105
- package/src/cache/generic.ts +0 -33
- package/src/cache/index.ts +0 -8
- package/src/cache/invite.ts +0 -86
- package/src/cache/passwordReset.ts +0 -49
- package/src/cache/tests/docWritethrough.spec.ts +0 -296
- package/src/cache/tests/user.spec.ts +0 -145
- package/src/cache/tests/writethrough.spec.ts +0 -139
- package/src/cache/user.ts +0 -154
- package/src/cache/writethrough.ts +0 -133
- package/src/configs/configs.ts +0 -263
- package/src/configs/index.ts +0 -1
- package/src/configs/tests/configs.spec.ts +0 -184
- package/src/constants/db.ts +0 -75
- package/src/constants/index.ts +0 -2
- package/src/constants/misc.ts +0 -36
- 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 -422
- package/src/context/tests/index.spec.ts +0 -255
- package/src/context/types.ts +0 -26
- package/src/db/Replication.ts +0 -94
- package/src/db/couch/DatabaseImpl.ts +0 -511
- package/src/db/couch/connections.ts +0 -89
- package/src/db/couch/index.ts +0 -4
- package/src/db/couch/pouchDB.ts +0 -97
- package/src/db/couch/pouchDump.ts +0 -0
- package/src/db/couch/tests/DatabaseImpl.spec.ts +0 -118
- package/src/db/couch/utils.ts +0 -55
- package/src/db/db.ts +0 -34
- package/src/db/errors.ts +0 -14
- package/src/db/index.ts +0 -12
- package/src/db/instrumentation.ts +0 -199
- package/src/db/lucene.ts +0 -721
- package/src/db/searchIndexes/index.ts +0 -1
- package/src/db/searchIndexes/searchIndexes.ts +0 -62
- package/src/db/tests/DatabaseImpl.spec.ts +0 -55
- package/src/db/tests/connections.spec.ts +0 -22
- package/src/db/tests/index.spec.ts +0 -32
- package/src/db/tests/lucene.spec.ts +0 -400
- package/src/db/tests/pouch.spec.js +0 -62
- package/src/db/tests/utils.spec.ts +0 -63
- package/src/db/utils.ts +0 -208
- package/src/db/views.ts +0 -245
- package/src/docIds/conversions.ts +0 -60
- package/src/docIds/ids.ts +0 -126
- package/src/docIds/index.ts +0 -2
- package/src/docIds/newid.ts +0 -5
- package/src/docIds/params.ts +0 -189
- package/src/docUpdates/index.ts +0 -24
- package/src/environment.ts +0 -293
- 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 -47
- package/src/events/identification.ts +0 -311
- package/src/events/index.ts +0 -15
- package/src/events/processors/AnalyticsProcessor.ts +0 -64
- package/src/events/processors/AuditLogsProcessor.ts +0 -92
- package/src/events/processors/LoggingProcessor.ts +0 -36
- package/src/events/processors/Processors.ts +0 -52
- package/src/events/processors/async/DocumentUpdateProcessor.ts +0 -38
- 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 -3
- package/src/events/processors/posthog/rateLimiting.ts +0 -106
- package/src/events/processors/posthog/tests/PosthogProcessor.spec.ts +0 -164
- package/src/events/processors/types.ts +0 -1
- package/src/events/publishers/account.ts +0 -41
- package/src/events/publishers/ai.ts +0 -21
- package/src/events/publishers/app.ts +0 -168
- 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 -25
- 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 -89
- 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/features/features.ts +0 -277
- package/src/features/index.ts +0 -2
- package/src/features/tests/features.spec.ts +0 -267
- package/src/features/tests/utils.ts +0 -64
- package/src/helpers.ts +0 -9
- package/src/index.ts +0 -59
- package/src/installation.ts +0 -115
- package/src/logging/alerts.ts +0 -26
- package/src/logging/correlation/correlation.ts +0 -15
- package/src/logging/correlation/index.ts +0 -1
- package/src/logging/correlation/middleware.ts +0 -18
- package/src/logging/index.ts +0 -4
- package/src/logging/pino/logger.ts +0 -239
- package/src/logging/pino/middleware.ts +0 -48
- 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 -247
- package/src/middleware/builderOnly.ts +0 -21
- package/src/middleware/builderOrAdmin.ts +0 -21
- package/src/middleware/contentSecurityPolicy.ts +0 -113
- package/src/middleware/csrf.ts +0 -81
- package/src/middleware/errorHandling.ts +0 -43
- package/src/middleware/index.ts +0 -24
- package/src/middleware/internalApi.ts +0 -23
- package/src/middleware/ip.ts +0 -12
- package/src/middleware/joi-validator.ts +0 -58
- package/src/middleware/matchers.ts +0 -39
- package/src/middleware/passport/datasource/google.ts +0 -102
- 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 -152
- package/src/middleware/passport/sso/sso.ts +0 -138
- package/src/middleware/passport/sso/tests/google.spec.ts +0 -68
- package/src/middleware/passport/sso/tests/oidc.spec.ts +0 -144
- 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 -181
- package/src/middleware/tests/contentSecurityPolicy.spec.ts +0 -75
- package/src/middleware/tests/matchers.spec.ts +0 -100
- package/src/migrations/definitions.ts +0 -40
- package/src/migrations/index.ts +0 -2
- package/src/migrations/migrations.ts +0 -186
- 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 -53
- 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 -161
- 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 -585
- package/src/objectStore/utils.ts +0 -113
- 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 -129
- package/src/plugin/index.ts +0 -1
- package/src/plugin/tests/validation.spec.ts +0 -209
- package/src/plugin/utils.ts +0 -175
- package/src/queue/constants.ts +0 -8
- package/src/queue/inMemoryQueue.ts +0 -189
- package/src/queue/index.ts +0 -2
- package/src/queue/listeners.ts +0 -199
- package/src/queue/queue.ts +0 -84
- package/src/redis/index.ts +0 -6
- package/src/redis/init.ts +0 -118
- package/src/redis/redis.ts +0 -358
- package/src/redis/redlockImpl.ts +0 -155
- package/src/redis/tests/redis.spec.ts +0 -207
- package/src/redis/tests/redlockImpl.spec.ts +0 -105
- package/src/redis/utils.ts +0 -128
- package/src/security/auth.ts +0 -24
- package/src/security/encryption.ts +0 -185
- package/src/security/index.ts +0 -1
- package/src/security/permissions.ts +0 -166
- package/src/security/roles.ts +0 -655
- package/src/security/secrets.ts +0 -20
- package/src/security/sessions.ts +0 -123
- package/src/security/tests/auth.spec.ts +0 -45
- package/src/security/tests/encryption.spec.ts +0 -31
- package/src/security/tests/permissions.spec.ts +0 -146
- package/src/security/tests/secrets.spec.ts +0 -35
- package/src/security/tests/sessions.spec.ts +0 -12
- package/src/sql/designDoc.ts +0 -17
- package/src/sql/index.ts +0 -5
- package/src/sql/sql.ts +0 -1854
- package/src/sql/sqlTable.ts +0 -319
- package/src/sql/utils.ts +0 -193
- package/src/tenancy/db.ts +0 -6
- package/src/tenancy/index.ts +0 -2
- package/src/tenancy/tenancy.ts +0 -148
- 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 -582
- package/src/users/events.ts +0 -176
- package/src/users/index.ts +0 -4
- package/src/users/lookup.ts +0 -99
- package/src/users/test/db.spec.ts +0 -188
- package/src/users/test/utils.spec.ts +0 -67
- package/src/users/users.ts +0 -353
- package/src/users/utils.ts +0 -81
- package/src/utils/Duration.ts +0 -56
- package/src/utils/hashing.ts +0 -15
- package/src/utils/index.ts +0 -4
- package/src/utils/stringUtils.ts +0 -8
- package/src/utils/tests/Duration.spec.ts +0 -19
- package/src/utils/tests/utils.spec.ts +0 -204
- package/src/utils/utils.ts +0 -249
- package/tests/core/logging.ts +0 -34
- package/tests/core/users/users.spec.js +0 -53
- package/tests/core/utilities/index.ts +0 -7
- package/tests/core/utilities/jestUtils.ts +0 -33
- package/tests/core/utilities/mocks/alerts.ts +0 -4
- package/tests/core/utilities/mocks/date.ts +0 -3
- package/tests/core/utilities/mocks/events.ts +0 -132
- package/tests/core/utilities/mocks/index.ts +0 -9
- package/tests/core/utilities/mocks/licenses.ts +0 -119
- package/tests/core/utilities/queue.ts +0 -9
- package/tests/core/utilities/structures/Chance.ts +0 -20
- package/tests/core/utilities/structures/accounts.ts +0 -80
- 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 -3
- 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 -190
- package/tests/core/utilities/structures/plugins.ts +0 -19
- package/tests/core/utilities/structures/quotas.ts +0 -72
- package/tests/core/utilities/structures/scim.ts +0 -80
- package/tests/core/utilities/structures/sso.ts +0 -118
- 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 -89
- package/tests/core/utilities/testContainerUtils.ts +0 -165
- package/tests/core/utilities/utils/index.ts +0 -2
- package/tests/core/utilities/utils/queue.ts +0 -27
- 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 -2
- package/tests/jestEnv.ts +0 -10
- package/tests/jestSetup.ts +0 -36
package/src/db/utils.ts
DELETED
|
@@ -1,208 +0,0 @@
|
|
|
1
|
-
import env from "../environment"
|
|
2
|
-
import { DEFAULT_TENANT_ID, SEPARATOR, DocumentType } from "../constants"
|
|
3
|
-
import { getTenantId, getGlobalDBName } from "../context"
|
|
4
|
-
import { doWithDB, directCouchAllDbs } from "./db"
|
|
5
|
-
import { AppState, DeletedApp, getAppMetadata } from "../cache/appMetadata"
|
|
6
|
-
import { isDevApp, isDevAppID, getProdAppID } from "../docIds/conversions"
|
|
7
|
-
import { App, Database } from "@budibase/types"
|
|
8
|
-
import { getStartEndKeyURL } from "../docIds"
|
|
9
|
-
|
|
10
|
-
export * from "../docIds"
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* if in production this will use the CouchDB _all_dbs call to retrieve a list of databases. If testing
|
|
14
|
-
* when using Pouch it will use the pouchdb-all-dbs package.
|
|
15
|
-
* opts.efficient can be provided to make sure this call is always quick in a multi-tenant environment,
|
|
16
|
-
* but it may not be 100% accurate in full efficiency mode (some tenantless apps may be missed).
|
|
17
|
-
*/
|
|
18
|
-
export async function getAllDbs(opts = { efficient: false }) {
|
|
19
|
-
const efficient = opts && opts.efficient
|
|
20
|
-
|
|
21
|
-
let dbs: any[] = []
|
|
22
|
-
async function addDbs(queryString?: string) {
|
|
23
|
-
const json = await directCouchAllDbs(queryString)
|
|
24
|
-
dbs = dbs.concat(json)
|
|
25
|
-
}
|
|
26
|
-
let tenantId = getTenantId()
|
|
27
|
-
if (!env.MULTI_TENANCY || (!efficient && tenantId === DEFAULT_TENANT_ID)) {
|
|
28
|
-
// just get all DBs when:
|
|
29
|
-
// - single tenancy
|
|
30
|
-
// - default tenant
|
|
31
|
-
// - apps dbs don't contain tenant id
|
|
32
|
-
// - non-default tenant dbs are filtered out application side in getAllApps
|
|
33
|
-
await addDbs()
|
|
34
|
-
} else {
|
|
35
|
-
// get prod apps
|
|
36
|
-
await addDbs(getStartEndKeyURL(DocumentType.APP, tenantId))
|
|
37
|
-
// get dev apps
|
|
38
|
-
await addDbs(getStartEndKeyURL(DocumentType.APP_DEV, tenantId))
|
|
39
|
-
// add global db name
|
|
40
|
-
dbs.push(getGlobalDBName(tenantId))
|
|
41
|
-
}
|
|
42
|
-
return dbs
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Lots of different points in the system need to find the full list of apps, this will
|
|
47
|
-
* enumerate the entire CouchDB cluster and get the list of databases (every app).
|
|
48
|
-
*
|
|
49
|
-
* @return returns the app information document stored in each app database.
|
|
50
|
-
*/
|
|
51
|
-
export async function getAllApps({
|
|
52
|
-
dev,
|
|
53
|
-
all,
|
|
54
|
-
idsOnly,
|
|
55
|
-
efficient,
|
|
56
|
-
}: any = {}): Promise<App[] | string[]> {
|
|
57
|
-
let tenantId = getTenantId()
|
|
58
|
-
if (!env.MULTI_TENANCY && !tenantId) {
|
|
59
|
-
tenantId = DEFAULT_TENANT_ID
|
|
60
|
-
}
|
|
61
|
-
let dbs = await getAllDbs({ efficient })
|
|
62
|
-
const appDbNames = dbs.filter((dbName: any) => {
|
|
63
|
-
if (env.isTest() && !dbName) {
|
|
64
|
-
return false
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
const split = dbName.split(SEPARATOR)
|
|
68
|
-
// it is an app, check the tenantId
|
|
69
|
-
if (split[0] === DocumentType.APP) {
|
|
70
|
-
// tenantId is always right before the UUID
|
|
71
|
-
const possibleTenantId = split[split.length - 2]
|
|
72
|
-
|
|
73
|
-
const noTenantId =
|
|
74
|
-
split.length === 2 || possibleTenantId === DocumentType.DEV
|
|
75
|
-
|
|
76
|
-
return (
|
|
77
|
-
(tenantId === DEFAULT_TENANT_ID && noTenantId) ||
|
|
78
|
-
possibleTenantId === tenantId
|
|
79
|
-
)
|
|
80
|
-
}
|
|
81
|
-
return false
|
|
82
|
-
})
|
|
83
|
-
if (idsOnly) {
|
|
84
|
-
const devAppIds = appDbNames.filter(appId => isDevAppID(appId))
|
|
85
|
-
const prodAppIds = appDbNames.filter(appId => !isDevAppID(appId))
|
|
86
|
-
switch (dev) {
|
|
87
|
-
case true:
|
|
88
|
-
return devAppIds
|
|
89
|
-
case false:
|
|
90
|
-
return prodAppIds
|
|
91
|
-
default:
|
|
92
|
-
return appDbNames
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
const appPromises = appDbNames.map((app: any) =>
|
|
96
|
-
// skip setup otherwise databases could be re-created
|
|
97
|
-
getAppMetadata(app)
|
|
98
|
-
)
|
|
99
|
-
if (appPromises.length === 0) {
|
|
100
|
-
return []
|
|
101
|
-
} else {
|
|
102
|
-
const response = await Promise.allSettled(appPromises)
|
|
103
|
-
const apps = response
|
|
104
|
-
.filter(
|
|
105
|
-
(result: any) =>
|
|
106
|
-
result.status === "fulfilled" &&
|
|
107
|
-
result.value?.state !== AppState.INVALID
|
|
108
|
-
)
|
|
109
|
-
.map(({ value }: any) => value)
|
|
110
|
-
if (!all) {
|
|
111
|
-
return apps.filter((app: any) => {
|
|
112
|
-
if (dev) {
|
|
113
|
-
return isDevApp(app)
|
|
114
|
-
}
|
|
115
|
-
return !isDevApp(app)
|
|
116
|
-
})
|
|
117
|
-
} else {
|
|
118
|
-
return apps.map((app: any) => ({
|
|
119
|
-
...app,
|
|
120
|
-
status: isDevApp(app) ? "development" : "published",
|
|
121
|
-
}))
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
export async function getAppsByIDs(appIds: string[]) {
|
|
127
|
-
const settled = await Promise.allSettled(
|
|
128
|
-
appIds.map(appId => getAppMetadata(appId))
|
|
129
|
-
)
|
|
130
|
-
// have to list the apps which exist, some may have been deleted
|
|
131
|
-
return settled
|
|
132
|
-
.filter(
|
|
133
|
-
promise =>
|
|
134
|
-
promise.status === "fulfilled" &&
|
|
135
|
-
(promise.value as DeletedApp).state !== AppState.INVALID
|
|
136
|
-
)
|
|
137
|
-
.map(promise => (promise as PromiseFulfilledResult<App>).value)
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
/**
|
|
141
|
-
* Utility function for getAllApps but filters to production apps only.
|
|
142
|
-
*/
|
|
143
|
-
export async function getProdAppIDs() {
|
|
144
|
-
const apps = (await getAllApps({ idsOnly: true })) as string[]
|
|
145
|
-
return apps.filter((id: any) => !isDevAppID(id))
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
/**
|
|
149
|
-
* Utility function for the inverse of above.
|
|
150
|
-
*/
|
|
151
|
-
export async function getDevAppIDs() {
|
|
152
|
-
const apps = (await getAllApps({ idsOnly: true })) as string[]
|
|
153
|
-
return apps.filter((id: any) => isDevAppID(id))
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
export function isSameAppID(
|
|
157
|
-
appId1: string | undefined,
|
|
158
|
-
appId2: string | undefined
|
|
159
|
-
) {
|
|
160
|
-
if (appId1 == undefined || appId2 == undefined) {
|
|
161
|
-
return false
|
|
162
|
-
}
|
|
163
|
-
return getProdAppID(appId1) === getProdAppID(appId2)
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
export async function dbExists(dbName: any) {
|
|
167
|
-
return doWithDB(
|
|
168
|
-
dbName,
|
|
169
|
-
async (db: Database) => {
|
|
170
|
-
return await db.exists()
|
|
171
|
-
},
|
|
172
|
-
{ skip_setup: true }
|
|
173
|
-
)
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
export function pagination<T>(
|
|
177
|
-
data: T[],
|
|
178
|
-
pageSize: number,
|
|
179
|
-
{
|
|
180
|
-
paginate,
|
|
181
|
-
property,
|
|
182
|
-
getKey,
|
|
183
|
-
}: {
|
|
184
|
-
paginate: boolean
|
|
185
|
-
property: string
|
|
186
|
-
getKey?: (doc: T) => string | undefined
|
|
187
|
-
} = {
|
|
188
|
-
paginate: true,
|
|
189
|
-
property: "_id",
|
|
190
|
-
}
|
|
191
|
-
) {
|
|
192
|
-
if (!paginate) {
|
|
193
|
-
return { data, hasNextPage: false }
|
|
194
|
-
}
|
|
195
|
-
const hasNextPage = data.length > pageSize
|
|
196
|
-
let nextPage = undefined
|
|
197
|
-
if (!getKey) {
|
|
198
|
-
getKey = (doc: any) => (property ? doc?.[property] : doc?._id)
|
|
199
|
-
}
|
|
200
|
-
if (hasNextPage) {
|
|
201
|
-
nextPage = getKey(data[pageSize])
|
|
202
|
-
}
|
|
203
|
-
return {
|
|
204
|
-
data: data.slice(0, pageSize),
|
|
205
|
-
hasNextPage,
|
|
206
|
-
nextPage,
|
|
207
|
-
}
|
|
208
|
-
}
|
package/src/db/views.ts
DELETED
|
@@ -1,245 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
DeprecatedViews,
|
|
3
|
-
DocumentType,
|
|
4
|
-
SEPARATOR,
|
|
5
|
-
StaticDatabases,
|
|
6
|
-
ViewName,
|
|
7
|
-
} from "../constants"
|
|
8
|
-
import { getGlobalDB } from "../context"
|
|
9
|
-
import { doWithDB } from "./"
|
|
10
|
-
import {
|
|
11
|
-
AllDocsResponse,
|
|
12
|
-
Database,
|
|
13
|
-
DatabaseQueryOpts,
|
|
14
|
-
Document,
|
|
15
|
-
DesignDocument,
|
|
16
|
-
DBView,
|
|
17
|
-
} from "@budibase/types"
|
|
18
|
-
import env from "../environment"
|
|
19
|
-
|
|
20
|
-
const DESIGN_DB = "_design/database"
|
|
21
|
-
|
|
22
|
-
function DesignDoc(): DesignDocument {
|
|
23
|
-
return {
|
|
24
|
-
_id: DESIGN_DB,
|
|
25
|
-
// view collation information, read before writing any complex views:
|
|
26
|
-
// https://docs.couchdb.org/en/master/ddocs/views/collation.html#collation-specification
|
|
27
|
-
views: {},
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
async function removeDeprecated(db: Database, viewName: ViewName) {
|
|
32
|
-
if (!DeprecatedViews[viewName]) {
|
|
33
|
-
return
|
|
34
|
-
}
|
|
35
|
-
try {
|
|
36
|
-
const designDoc = await db.get<DesignDocument>(DESIGN_DB)
|
|
37
|
-
for (let deprecatedNames of DeprecatedViews[viewName]) {
|
|
38
|
-
delete designDoc.views?.[deprecatedNames]
|
|
39
|
-
}
|
|
40
|
-
await db.put(designDoc)
|
|
41
|
-
} catch (err) {
|
|
42
|
-
// doesn't exist, ignore
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export async function createView(
|
|
47
|
-
db: Database,
|
|
48
|
-
viewJs: string,
|
|
49
|
-
viewName: string
|
|
50
|
-
): Promise<void> {
|
|
51
|
-
let designDoc
|
|
52
|
-
try {
|
|
53
|
-
designDoc = await db.get<DesignDocument>(DESIGN_DB)
|
|
54
|
-
} catch (err) {
|
|
55
|
-
// no design doc, make one
|
|
56
|
-
designDoc = DesignDoc()
|
|
57
|
-
}
|
|
58
|
-
const view: DBView = {
|
|
59
|
-
map: viewJs,
|
|
60
|
-
}
|
|
61
|
-
designDoc.views = {
|
|
62
|
-
...designDoc.views,
|
|
63
|
-
[viewName]: view,
|
|
64
|
-
}
|
|
65
|
-
try {
|
|
66
|
-
await db.put(designDoc)
|
|
67
|
-
} catch (err: any) {
|
|
68
|
-
if (err.status === 409) {
|
|
69
|
-
return await createView(db, viewJs, viewName)
|
|
70
|
-
} else {
|
|
71
|
-
throw err
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
export const createNewUserEmailView = async () => {
|
|
77
|
-
const db = getGlobalDB()
|
|
78
|
-
const viewJs = `function(doc) {
|
|
79
|
-
if (doc._id.startsWith("${DocumentType.USER}${SEPARATOR}")) {
|
|
80
|
-
emit(doc.email.toLowerCase(), doc._id)
|
|
81
|
-
}
|
|
82
|
-
}`
|
|
83
|
-
await createView(db, viewJs, ViewName.USER_BY_EMAIL)
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
export const createUserAppView = async () => {
|
|
87
|
-
const db = getGlobalDB()
|
|
88
|
-
const viewJs = `function(doc) {
|
|
89
|
-
if (doc._id.startsWith("${DocumentType.USER}${SEPARATOR}") && doc.roles) {
|
|
90
|
-
for (let prodAppId of Object.keys(doc.roles)) {
|
|
91
|
-
let emitted = prodAppId + "${SEPARATOR}" + doc._id
|
|
92
|
-
emit(emitted, null)
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
}`
|
|
96
|
-
await createView(db, viewJs, ViewName.USER_BY_APP)
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
export const createApiKeyView = async () => {
|
|
100
|
-
const db = getGlobalDB()
|
|
101
|
-
const viewJs = `function(doc) {
|
|
102
|
-
if (doc._id.startsWith("${DocumentType.DEV_INFO}") && doc.apiKey) {
|
|
103
|
-
emit(doc.apiKey, doc.userId)
|
|
104
|
-
}
|
|
105
|
-
}`
|
|
106
|
-
await createView(db, viewJs, ViewName.BY_API_KEY)
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
export interface QueryViewOptions {
|
|
110
|
-
arrayResponse?: boolean
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
export async function queryViewRaw<T extends Document>(
|
|
114
|
-
viewName: ViewName,
|
|
115
|
-
params: DatabaseQueryOpts,
|
|
116
|
-
db: Database,
|
|
117
|
-
createFunc: any,
|
|
118
|
-
opts?: QueryViewOptions
|
|
119
|
-
): Promise<AllDocsResponse<T>> {
|
|
120
|
-
try {
|
|
121
|
-
const response = await db.query<T>(`database/${viewName}`, params)
|
|
122
|
-
// await to catch error
|
|
123
|
-
return response
|
|
124
|
-
} catch (err: any) {
|
|
125
|
-
const pouchNotFound = err && err.name === "not_found"
|
|
126
|
-
const couchNotFound = err && err.status === 404
|
|
127
|
-
if (pouchNotFound || couchNotFound) {
|
|
128
|
-
await removeDeprecated(db, viewName)
|
|
129
|
-
await createFunc()
|
|
130
|
-
return queryViewRaw(viewName, params, db, createFunc, opts)
|
|
131
|
-
} else if (err.status === 409) {
|
|
132
|
-
// can happen when multiple queries occur at once, view couldn't be created
|
|
133
|
-
// other design docs being updated, re-run
|
|
134
|
-
return queryViewRaw(viewName, params, db, createFunc, opts)
|
|
135
|
-
} else {
|
|
136
|
-
throw err
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
export const queryView = async <T extends Document>(
|
|
142
|
-
viewName: ViewName,
|
|
143
|
-
params: DatabaseQueryOpts,
|
|
144
|
-
db: Database,
|
|
145
|
-
createFunc: any,
|
|
146
|
-
opts?: QueryViewOptions
|
|
147
|
-
): Promise<T[] | T> => {
|
|
148
|
-
const response = await queryViewRaw<T>(viewName, params, db, createFunc, opts)
|
|
149
|
-
const rows = response.rows
|
|
150
|
-
const docs = rows.map(row => (params.include_docs ? row.doc! : row.value))
|
|
151
|
-
|
|
152
|
-
// if arrayResponse has been requested, always return array regardless of length
|
|
153
|
-
if (opts?.arrayResponse) {
|
|
154
|
-
return docs as T[]
|
|
155
|
-
} else {
|
|
156
|
-
// return the single document if there is only one
|
|
157
|
-
return docs.length <= 1 ? (docs[0] as T) : (docs as T[])
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
// PLATFORM
|
|
162
|
-
|
|
163
|
-
async function createPlatformView(viewJs: string, viewName: ViewName) {
|
|
164
|
-
try {
|
|
165
|
-
await doWithDB(StaticDatabases.PLATFORM_INFO.name, async (db: Database) => {
|
|
166
|
-
await createView(db, viewJs, viewName)
|
|
167
|
-
})
|
|
168
|
-
} catch (e: any) {
|
|
169
|
-
if (e.status === 409 && env.isTest()) {
|
|
170
|
-
// multiple tests can try to initialise platforms views
|
|
171
|
-
// at once - safe to exit on conflict
|
|
172
|
-
return
|
|
173
|
-
}
|
|
174
|
-
throw e
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
export const createPlatformAccountEmailView = async () => {
|
|
179
|
-
const viewJs = `function(doc) {
|
|
180
|
-
if (doc._id.startsWith("${DocumentType.ACCOUNT_METADATA}${SEPARATOR}")) {
|
|
181
|
-
emit(doc.email.toLowerCase(), doc._id)
|
|
182
|
-
}
|
|
183
|
-
}`
|
|
184
|
-
await createPlatformView(viewJs, ViewName.ACCOUNT_BY_EMAIL)
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
export const createPlatformUserView = async () => {
|
|
188
|
-
const viewJs = `function(doc) {
|
|
189
|
-
if (doc.tenantId) {
|
|
190
|
-
emit(doc._id.toLowerCase(), doc._id)
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
if (doc.ssoId) {
|
|
194
|
-
emit(doc.ssoId, doc._id)
|
|
195
|
-
}
|
|
196
|
-
}`
|
|
197
|
-
await createPlatformView(viewJs, ViewName.PLATFORM_USERS_LOWERCASE)
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
export const queryPlatformView = async <T extends Document>(
|
|
201
|
-
viewName: ViewName,
|
|
202
|
-
params: DatabaseQueryOpts
|
|
203
|
-
): Promise<T[]> => {
|
|
204
|
-
const CreateFuncByName: any = {
|
|
205
|
-
[ViewName.ACCOUNT_BY_EMAIL]: createPlatformAccountEmailView,
|
|
206
|
-
[ViewName.PLATFORM_USERS_LOWERCASE]: createPlatformUserView,
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
return doWithDB(StaticDatabases.PLATFORM_INFO.name, async (db: Database) => {
|
|
210
|
-
const createFn = CreateFuncByName[viewName]
|
|
211
|
-
return queryView(viewName, params, db, createFn, {
|
|
212
|
-
arrayResponse: true,
|
|
213
|
-
}) as Promise<T[]>
|
|
214
|
-
})
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
const CreateFuncByName: any = {
|
|
218
|
-
[ViewName.USER_BY_EMAIL]: createNewUserEmailView,
|
|
219
|
-
[ViewName.BY_API_KEY]: createApiKeyView,
|
|
220
|
-
[ViewName.USER_BY_APP]: createUserAppView,
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
export const queryGlobalView = async <T extends Document>(
|
|
224
|
-
viewName: ViewName,
|
|
225
|
-
params: DatabaseQueryOpts,
|
|
226
|
-
db?: Database,
|
|
227
|
-
opts?: QueryViewOptions
|
|
228
|
-
): Promise<T[] | T | undefined> => {
|
|
229
|
-
// can pass DB in if working with something specific
|
|
230
|
-
if (!db) {
|
|
231
|
-
db = getGlobalDB()
|
|
232
|
-
}
|
|
233
|
-
const createFn = CreateFuncByName[viewName]
|
|
234
|
-
return queryView<T>(viewName, params, db!, createFn, opts)
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
export async function queryGlobalViewRaw<T extends Document>(
|
|
238
|
-
viewName: ViewName,
|
|
239
|
-
params: DatabaseQueryOpts,
|
|
240
|
-
opts?: QueryViewOptions
|
|
241
|
-
) {
|
|
242
|
-
const db = getGlobalDB()
|
|
243
|
-
const createFn = CreateFuncByName[viewName]
|
|
244
|
-
return queryViewRaw<T>(viewName, params, db, createFn, opts)
|
|
245
|
-
}
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import { APP_DEV_PREFIX, APP_PREFIX } from "../constants"
|
|
2
|
-
import { App } from "@budibase/types"
|
|
3
|
-
|
|
4
|
-
const NO_APP_ERROR = "No app provided"
|
|
5
|
-
|
|
6
|
-
export function isDevAppID(appId?: string) {
|
|
7
|
-
if (!appId) {
|
|
8
|
-
throw NO_APP_ERROR
|
|
9
|
-
}
|
|
10
|
-
return appId.startsWith(APP_DEV_PREFIX)
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export function isProdAppID(appId?: string) {
|
|
14
|
-
if (!appId) {
|
|
15
|
-
throw NO_APP_ERROR
|
|
16
|
-
}
|
|
17
|
-
return appId.startsWith(APP_PREFIX) && !isDevAppID(appId)
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export function isDevApp(app: App) {
|
|
21
|
-
if (!app) {
|
|
22
|
-
throw NO_APP_ERROR
|
|
23
|
-
}
|
|
24
|
-
return isDevAppID(app.appId)
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Generates a development app ID from a real app ID.
|
|
29
|
-
* @returns the dev app ID which can be used for dev database.
|
|
30
|
-
*/
|
|
31
|
-
export function getDevelopmentAppID(appId: string) {
|
|
32
|
-
if (!appId || appId.startsWith(APP_DEV_PREFIX)) {
|
|
33
|
-
return appId
|
|
34
|
-
}
|
|
35
|
-
// split to take off the app_ element, then join it together incase any other app_ exist
|
|
36
|
-
const split = appId.split(APP_PREFIX)
|
|
37
|
-
split.shift()
|
|
38
|
-
const rest = split.join(APP_PREFIX)
|
|
39
|
-
return `${APP_DEV_PREFIX}${rest}`
|
|
40
|
-
}
|
|
41
|
-
export const getDevAppID = getDevelopmentAppID
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Convert a development app ID to a deployed app ID.
|
|
45
|
-
*/
|
|
46
|
-
export function getProdAppID(appId: string) {
|
|
47
|
-
if (!appId || !appId.startsWith(APP_DEV_PREFIX)) {
|
|
48
|
-
return appId
|
|
49
|
-
}
|
|
50
|
-
// split to take off the app_dev element, then join it together incase any other app_ exist
|
|
51
|
-
const split = appId.split(APP_DEV_PREFIX)
|
|
52
|
-
split.shift()
|
|
53
|
-
const rest = split.join(APP_DEV_PREFIX)
|
|
54
|
-
return `${APP_PREFIX}${rest}`
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export function extractAppUUID(id: string) {
|
|
58
|
-
const split = id?.split("_") || []
|
|
59
|
-
return split.length ? split[split.length - 1] : null
|
|
60
|
-
}
|
package/src/docIds/ids.ts
DELETED
|
@@ -1,126 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
APP_PREFIX,
|
|
3
|
-
DocumentType,
|
|
4
|
-
InternalTable,
|
|
5
|
-
SEPARATOR,
|
|
6
|
-
} from "../constants"
|
|
7
|
-
import { newid } from "./newid"
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Generates a new app ID.
|
|
11
|
-
* @returns The new app ID which the app doc can be stored under.
|
|
12
|
-
*/
|
|
13
|
-
export const generateAppID = (tenantId?: string | null) => {
|
|
14
|
-
let id = APP_PREFIX
|
|
15
|
-
if (tenantId) {
|
|
16
|
-
id += `${tenantId}${SEPARATOR}`
|
|
17
|
-
}
|
|
18
|
-
return `${id}${newid()}`
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Generates a new table ID.
|
|
23
|
-
* @returns The new table ID which the table doc can be stored under.
|
|
24
|
-
*/
|
|
25
|
-
export function generateTableID() {
|
|
26
|
-
return `${DocumentType.TABLE}${SEPARATOR}${newid()}`
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Gets a new row ID for the specified table.
|
|
31
|
-
* @param tableId The table which the row is being created for.
|
|
32
|
-
* @param id If an ID is to be used then the UUID can be substituted for this.
|
|
33
|
-
* @returns The new ID which a row doc can be stored under.
|
|
34
|
-
*/
|
|
35
|
-
export function generateRowID(tableId: string, id?: string) {
|
|
36
|
-
id = id || newid()
|
|
37
|
-
return `${DocumentType.ROW}${SEPARATOR}${tableId}${SEPARATOR}${id}`
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Generates a new workspace ID.
|
|
42
|
-
* @returns The new workspace ID which the workspace doc can be stored under.
|
|
43
|
-
*/
|
|
44
|
-
export function generateWorkspaceID() {
|
|
45
|
-
return `${DocumentType.WORKSPACE}${SEPARATOR}${newid()}`
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Generates a new global user ID.
|
|
50
|
-
* @returns The new user ID which the user doc can be stored under.
|
|
51
|
-
*/
|
|
52
|
-
export function generateGlobalUserID(id?: any) {
|
|
53
|
-
return `${DocumentType.USER}${SEPARATOR}${id || newid()}`
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
const isGlobalUserIDRegex = new RegExp(`^${DocumentType.USER}${SEPARATOR}.+`)
|
|
57
|
-
export function isGlobalUserID(id: string) {
|
|
58
|
-
return isGlobalUserIDRegex.test(id)
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Generates a new user ID based on the passed in global ID.
|
|
63
|
-
* @param globalId The ID of the global user.
|
|
64
|
-
* @returns The new user ID which the user doc can be stored under.
|
|
65
|
-
*/
|
|
66
|
-
export function generateUserMetadataID(globalId: string) {
|
|
67
|
-
return generateRowID(InternalTable.USER_METADATA, globalId)
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Breaks up the ID to get the global ID.
|
|
72
|
-
*/
|
|
73
|
-
export function getGlobalIDFromUserMetadataID(id: string) {
|
|
74
|
-
const prefix = `${DocumentType.ROW}${SEPARATOR}${InternalTable.USER_METADATA}${SEPARATOR}`
|
|
75
|
-
if (!id || !id.includes(prefix)) {
|
|
76
|
-
return id
|
|
77
|
-
}
|
|
78
|
-
return id.split(prefix)[1]
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* Generates a template ID.
|
|
83
|
-
* @param ownerId The owner/user of the template, this could be global or a workspace level.
|
|
84
|
-
*/
|
|
85
|
-
export function generateTemplateID(ownerId: string) {
|
|
86
|
-
return `${DocumentType.TEMPLATE}${SEPARATOR}${ownerId}${SEPARATOR}${newid()}`
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
export function generateAppUserID(prodAppId: string, userId: string) {
|
|
90
|
-
return `${prodAppId}${SEPARATOR}${userId}`
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* Generates a new role ID.
|
|
95
|
-
* @returns The new role ID which the role doc can be stored under.
|
|
96
|
-
*/
|
|
97
|
-
export function generateRoleID(name: string) {
|
|
98
|
-
const prefix = `${DocumentType.ROLE}${SEPARATOR}`
|
|
99
|
-
if (name.startsWith(prefix)) {
|
|
100
|
-
return name
|
|
101
|
-
}
|
|
102
|
-
return `${prefix}${name}`
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* Utility function to be more verbose.
|
|
107
|
-
*/
|
|
108
|
-
export function prefixRoleID(name: string) {
|
|
109
|
-
return generateRoleID(name)
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
* Generates a new dev info document ID - this is scoped to a user.
|
|
114
|
-
* @returns The new dev info ID which info for dev (like api key) can be stored under.
|
|
115
|
-
*/
|
|
116
|
-
export const generateDevInfoID = (userId: string) => {
|
|
117
|
-
return `${DocumentType.DEV_INFO}${SEPARATOR}${userId}`
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
/**
|
|
121
|
-
* Generates a new plugin ID - to be used in the global DB.
|
|
122
|
-
* @returns The new plugin ID which a plugin metadata document can be stored under.
|
|
123
|
-
*/
|
|
124
|
-
export const generatePluginID = (name: string) => {
|
|
125
|
-
return `${DocumentType.PLUGIN}${SEPARATOR}${name}`
|
|
126
|
-
}
|
package/src/docIds/index.ts
DELETED