@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.
Files changed (272) hide show
  1. package/dist/index.js.map +1 -1
  2. package/dist/index.js.meta.json +1 -1
  3. package/dist/package.json +11 -4
  4. package/dist/plugins.js.meta.json +1 -1
  5. package/package.json +11 -4
  6. package/src/accounts/accounts.ts +0 -82
  7. package/src/accounts/api.ts +0 -59
  8. package/src/accounts/index.ts +0 -1
  9. package/src/auth/auth.ts +0 -210
  10. package/src/auth/index.ts +0 -1
  11. package/src/auth/tests/auth.spec.ts +0 -14
  12. package/src/blacklist/blacklist.ts +0 -54
  13. package/src/blacklist/index.ts +0 -1
  14. package/src/blacklist/tests/blacklist.spec.ts +0 -46
  15. package/src/cache/appMetadata.ts +0 -88
  16. package/src/cache/base/index.ts +0 -150
  17. package/src/cache/docWritethrough.ts +0 -105
  18. package/src/cache/generic.ts +0 -33
  19. package/src/cache/index.ts +0 -8
  20. package/src/cache/invite.ts +0 -86
  21. package/src/cache/passwordReset.ts +0 -49
  22. package/src/cache/tests/docWritethrough.spec.ts +0 -296
  23. package/src/cache/tests/user.spec.ts +0 -145
  24. package/src/cache/tests/writethrough.spec.ts +0 -139
  25. package/src/cache/user.ts +0 -154
  26. package/src/cache/writethrough.ts +0 -133
  27. package/src/configs/configs.ts +0 -263
  28. package/src/configs/index.ts +0 -1
  29. package/src/configs/tests/configs.spec.ts +0 -184
  30. package/src/constants/db.ts +0 -75
  31. package/src/constants/index.ts +0 -2
  32. package/src/constants/misc.ts +0 -36
  33. package/src/context/Context.ts +0 -14
  34. package/src/context/identity.ts +0 -58
  35. package/src/context/index.ts +0 -3
  36. package/src/context/mainContext.ts +0 -422
  37. package/src/context/tests/index.spec.ts +0 -255
  38. package/src/context/types.ts +0 -26
  39. package/src/db/Replication.ts +0 -94
  40. package/src/db/couch/DatabaseImpl.ts +0 -511
  41. package/src/db/couch/connections.ts +0 -89
  42. package/src/db/couch/index.ts +0 -4
  43. package/src/db/couch/pouchDB.ts +0 -97
  44. package/src/db/couch/pouchDump.ts +0 -0
  45. package/src/db/couch/tests/DatabaseImpl.spec.ts +0 -118
  46. package/src/db/couch/utils.ts +0 -55
  47. package/src/db/db.ts +0 -34
  48. package/src/db/errors.ts +0 -14
  49. package/src/db/index.ts +0 -12
  50. package/src/db/instrumentation.ts +0 -199
  51. package/src/db/lucene.ts +0 -721
  52. package/src/db/searchIndexes/index.ts +0 -1
  53. package/src/db/searchIndexes/searchIndexes.ts +0 -62
  54. package/src/db/tests/DatabaseImpl.spec.ts +0 -55
  55. package/src/db/tests/connections.spec.ts +0 -22
  56. package/src/db/tests/index.spec.ts +0 -32
  57. package/src/db/tests/lucene.spec.ts +0 -400
  58. package/src/db/tests/pouch.spec.js +0 -62
  59. package/src/db/tests/utils.spec.ts +0 -63
  60. package/src/db/utils.ts +0 -208
  61. package/src/db/views.ts +0 -245
  62. package/src/docIds/conversions.ts +0 -60
  63. package/src/docIds/ids.ts +0 -126
  64. package/src/docIds/index.ts +0 -2
  65. package/src/docIds/newid.ts +0 -5
  66. package/src/docIds/params.ts +0 -189
  67. package/src/docUpdates/index.ts +0 -24
  68. package/src/environment.ts +0 -293
  69. package/src/errors/errors.ts +0 -119
  70. package/src/errors/index.ts +0 -1
  71. package/src/events/analytics.ts +0 -6
  72. package/src/events/asyncEvents/index.ts +0 -2
  73. package/src/events/asyncEvents/publisher.ts +0 -12
  74. package/src/events/asyncEvents/queue.ts +0 -22
  75. package/src/events/backfill.ts +0 -183
  76. package/src/events/documentId.ts +0 -56
  77. package/src/events/events.ts +0 -47
  78. package/src/events/identification.ts +0 -311
  79. package/src/events/index.ts +0 -15
  80. package/src/events/processors/AnalyticsProcessor.ts +0 -64
  81. package/src/events/processors/AuditLogsProcessor.ts +0 -92
  82. package/src/events/processors/LoggingProcessor.ts +0 -36
  83. package/src/events/processors/Processors.ts +0 -52
  84. package/src/events/processors/async/DocumentUpdateProcessor.ts +0 -38
  85. package/src/events/processors/index.ts +0 -19
  86. package/src/events/processors/posthog/PosthogProcessor.ts +0 -118
  87. package/src/events/processors/posthog/index.ts +0 -3
  88. package/src/events/processors/posthog/rateLimiting.ts +0 -106
  89. package/src/events/processors/posthog/tests/PosthogProcessor.spec.ts +0 -164
  90. package/src/events/processors/types.ts +0 -1
  91. package/src/events/publishers/account.ts +0 -41
  92. package/src/events/publishers/ai.ts +0 -21
  93. package/src/events/publishers/app.ts +0 -168
  94. package/src/events/publishers/auditLog.ts +0 -26
  95. package/src/events/publishers/auth.ts +0 -73
  96. package/src/events/publishers/automation.ts +0 -110
  97. package/src/events/publishers/backfill.ts +0 -74
  98. package/src/events/publishers/backup.ts +0 -42
  99. package/src/events/publishers/datasource.ts +0 -48
  100. package/src/events/publishers/email.ts +0 -17
  101. package/src/events/publishers/environmentVariable.ts +0 -38
  102. package/src/events/publishers/group.ts +0 -99
  103. package/src/events/publishers/index.ts +0 -25
  104. package/src/events/publishers/installation.ts +0 -38
  105. package/src/events/publishers/layout.ts +0 -26
  106. package/src/events/publishers/license.ts +0 -84
  107. package/src/events/publishers/org.ts +0 -37
  108. package/src/events/publishers/plugin.ts +0 -47
  109. package/src/events/publishers/query.ts +0 -89
  110. package/src/events/publishers/role.ts +0 -62
  111. package/src/events/publishers/rows.ts +0 -29
  112. package/src/events/publishers/screen.ts +0 -36
  113. package/src/events/publishers/serve.ts +0 -43
  114. package/src/events/publishers/table.ts +0 -70
  115. package/src/events/publishers/user.ts +0 -202
  116. package/src/events/publishers/view.ts +0 -107
  117. package/src/features/features.ts +0 -277
  118. package/src/features/index.ts +0 -2
  119. package/src/features/tests/features.spec.ts +0 -267
  120. package/src/features/tests/utils.ts +0 -64
  121. package/src/helpers.ts +0 -9
  122. package/src/index.ts +0 -59
  123. package/src/installation.ts +0 -115
  124. package/src/logging/alerts.ts +0 -26
  125. package/src/logging/correlation/correlation.ts +0 -15
  126. package/src/logging/correlation/index.ts +0 -1
  127. package/src/logging/correlation/middleware.ts +0 -18
  128. package/src/logging/index.ts +0 -4
  129. package/src/logging/pino/logger.ts +0 -239
  130. package/src/logging/pino/middleware.ts +0 -48
  131. package/src/logging/system.ts +0 -81
  132. package/src/logging/tests/system.spec.ts +0 -61
  133. package/src/middleware/adminOnly.ts +0 -9
  134. package/src/middleware/auditLog.ts +0 -6
  135. package/src/middleware/authenticated.ts +0 -247
  136. package/src/middleware/builderOnly.ts +0 -21
  137. package/src/middleware/builderOrAdmin.ts +0 -21
  138. package/src/middleware/contentSecurityPolicy.ts +0 -113
  139. package/src/middleware/csrf.ts +0 -81
  140. package/src/middleware/errorHandling.ts +0 -43
  141. package/src/middleware/index.ts +0 -24
  142. package/src/middleware/internalApi.ts +0 -23
  143. package/src/middleware/ip.ts +0 -12
  144. package/src/middleware/joi-validator.ts +0 -58
  145. package/src/middleware/matchers.ts +0 -39
  146. package/src/middleware/passport/datasource/google.ts +0 -102
  147. package/src/middleware/passport/local.ts +0 -54
  148. package/src/middleware/passport/sso/google.ts +0 -77
  149. package/src/middleware/passport/sso/oidc.ts +0 -152
  150. package/src/middleware/passport/sso/sso.ts +0 -138
  151. package/src/middleware/passport/sso/tests/google.spec.ts +0 -68
  152. package/src/middleware/passport/sso/tests/oidc.spec.ts +0 -144
  153. package/src/middleware/passport/sso/tests/sso.spec.ts +0 -197
  154. package/src/middleware/passport/utils.ts +0 -38
  155. package/src/middleware/querystringToBody.ts +0 -28
  156. package/src/middleware/tenancy.ts +0 -36
  157. package/src/middleware/tests/builder.spec.ts +0 -181
  158. package/src/middleware/tests/contentSecurityPolicy.spec.ts +0 -75
  159. package/src/middleware/tests/matchers.spec.ts +0 -100
  160. package/src/migrations/definitions.ts +0 -40
  161. package/src/migrations/index.ts +0 -2
  162. package/src/migrations/migrations.ts +0 -186
  163. package/src/migrations/tests/__snapshots__/migrations.spec.ts.snap +0 -11
  164. package/src/migrations/tests/migrations.spec.ts +0 -64
  165. package/src/objectStore/buckets/app.ts +0 -53
  166. package/src/objectStore/buckets/global.ts +0 -29
  167. package/src/objectStore/buckets/index.ts +0 -3
  168. package/src/objectStore/buckets/plugins.ts +0 -71
  169. package/src/objectStore/buckets/tests/app.spec.ts +0 -161
  170. package/src/objectStore/buckets/tests/global.spec.ts +0 -74
  171. package/src/objectStore/buckets/tests/plugins.spec.ts +0 -111
  172. package/src/objectStore/cloudfront.ts +0 -41
  173. package/src/objectStore/index.ts +0 -3
  174. package/src/objectStore/objectStore.ts +0 -585
  175. package/src/objectStore/utils.ts +0 -113
  176. package/src/platform/index.ts +0 -3
  177. package/src/platform/platformDb.ts +0 -6
  178. package/src/platform/tenants.ts +0 -101
  179. package/src/platform/tests/tenants.spec.ts +0 -26
  180. package/src/platform/users.ts +0 -129
  181. package/src/plugin/index.ts +0 -1
  182. package/src/plugin/tests/validation.spec.ts +0 -209
  183. package/src/plugin/utils.ts +0 -175
  184. package/src/queue/constants.ts +0 -8
  185. package/src/queue/inMemoryQueue.ts +0 -189
  186. package/src/queue/index.ts +0 -2
  187. package/src/queue/listeners.ts +0 -199
  188. package/src/queue/queue.ts +0 -84
  189. package/src/redis/index.ts +0 -6
  190. package/src/redis/init.ts +0 -118
  191. package/src/redis/redis.ts +0 -358
  192. package/src/redis/redlockImpl.ts +0 -155
  193. package/src/redis/tests/redis.spec.ts +0 -207
  194. package/src/redis/tests/redlockImpl.spec.ts +0 -105
  195. package/src/redis/utils.ts +0 -128
  196. package/src/security/auth.ts +0 -24
  197. package/src/security/encryption.ts +0 -185
  198. package/src/security/index.ts +0 -1
  199. package/src/security/permissions.ts +0 -166
  200. package/src/security/roles.ts +0 -655
  201. package/src/security/secrets.ts +0 -20
  202. package/src/security/sessions.ts +0 -123
  203. package/src/security/tests/auth.spec.ts +0 -45
  204. package/src/security/tests/encryption.spec.ts +0 -31
  205. package/src/security/tests/permissions.spec.ts +0 -146
  206. package/src/security/tests/secrets.spec.ts +0 -35
  207. package/src/security/tests/sessions.spec.ts +0 -12
  208. package/src/sql/designDoc.ts +0 -17
  209. package/src/sql/index.ts +0 -5
  210. package/src/sql/sql.ts +0 -1854
  211. package/src/sql/sqlTable.ts +0 -319
  212. package/src/sql/utils.ts +0 -193
  213. package/src/tenancy/db.ts +0 -6
  214. package/src/tenancy/index.ts +0 -2
  215. package/src/tenancy/tenancy.ts +0 -148
  216. package/src/tenancy/tests/tenancy.spec.ts +0 -184
  217. package/src/timers/index.ts +0 -1
  218. package/src/timers/timers.ts +0 -22
  219. package/src/users/db.ts +0 -582
  220. package/src/users/events.ts +0 -176
  221. package/src/users/index.ts +0 -4
  222. package/src/users/lookup.ts +0 -99
  223. package/src/users/test/db.spec.ts +0 -188
  224. package/src/users/test/utils.spec.ts +0 -67
  225. package/src/users/users.ts +0 -353
  226. package/src/users/utils.ts +0 -81
  227. package/src/utils/Duration.ts +0 -56
  228. package/src/utils/hashing.ts +0 -15
  229. package/src/utils/index.ts +0 -4
  230. package/src/utils/stringUtils.ts +0 -8
  231. package/src/utils/tests/Duration.spec.ts +0 -19
  232. package/src/utils/tests/utils.spec.ts +0 -204
  233. package/src/utils/utils.ts +0 -249
  234. package/tests/core/logging.ts +0 -34
  235. package/tests/core/users/users.spec.js +0 -53
  236. package/tests/core/utilities/index.ts +0 -7
  237. package/tests/core/utilities/jestUtils.ts +0 -33
  238. package/tests/core/utilities/mocks/alerts.ts +0 -4
  239. package/tests/core/utilities/mocks/date.ts +0 -3
  240. package/tests/core/utilities/mocks/events.ts +0 -132
  241. package/tests/core/utilities/mocks/index.ts +0 -9
  242. package/tests/core/utilities/mocks/licenses.ts +0 -119
  243. package/tests/core/utilities/queue.ts +0 -9
  244. package/tests/core/utilities/structures/Chance.ts +0 -20
  245. package/tests/core/utilities/structures/accounts.ts +0 -80
  246. package/tests/core/utilities/structures/apps.ts +0 -21
  247. package/tests/core/utilities/structures/common.ts +0 -7
  248. package/tests/core/utilities/structures/db.ts +0 -12
  249. package/tests/core/utilities/structures/documents/index.ts +0 -1
  250. package/tests/core/utilities/structures/documents/platform/index.ts +0 -1
  251. package/tests/core/utilities/structures/documents/platform/installation.ts +0 -12
  252. package/tests/core/utilities/structures/generator.ts +0 -3
  253. package/tests/core/utilities/structures/index.ts +0 -15
  254. package/tests/core/utilities/structures/koa.ts +0 -16
  255. package/tests/core/utilities/structures/licenses.ts +0 -190
  256. package/tests/core/utilities/structures/plugins.ts +0 -19
  257. package/tests/core/utilities/structures/quotas.ts +0 -72
  258. package/tests/core/utilities/structures/scim.ts +0 -80
  259. package/tests/core/utilities/structures/sso.ts +0 -118
  260. package/tests/core/utilities/structures/tenants.ts +0 -5
  261. package/tests/core/utilities/structures/userGroups.ts +0 -10
  262. package/tests/core/utilities/structures/users.ts +0 -89
  263. package/tests/core/utilities/testContainerUtils.ts +0 -165
  264. package/tests/core/utilities/utils/index.ts +0 -2
  265. package/tests/core/utilities/utils/queue.ts +0 -27
  266. package/tests/core/utilities/utils/time.ts +0 -3
  267. package/tests/extra/DBTestConfiguration.ts +0 -36
  268. package/tests/extra/index.ts +0 -2
  269. package/tests/extra/testEnv.ts +0 -95
  270. package/tests/index.ts +0 -2
  271. package/tests/jestEnv.ts +0 -10
  272. package/tests/jestSetup.ts +0 -36
@@ -1,319 +0,0 @@
1
- import { Knex, knex } from "knex"
2
- import {
3
- FieldType,
4
- NumberFieldMetadata,
5
- Operation,
6
- QueryJson,
7
- RelationshipType,
8
- RenameColumn,
9
- SqlQuery,
10
- Table,
11
- TableSourceType,
12
- SqlClient,
13
- } from "@budibase/types"
14
- import { breakExternalTableId, getNativeSql } from "./utils"
15
- import { helpers, utils } from "@budibase/shared-core"
16
- import SchemaBuilder = Knex.SchemaBuilder
17
- import CreateTableBuilder = Knex.CreateTableBuilder
18
-
19
- function isIgnoredType(type: FieldType) {
20
- const ignored = [FieldType.LINK, FieldType.FORMULA, FieldType.AI]
21
- return ignored.indexOf(type) !== -1
22
- }
23
-
24
- function generateSchema(
25
- schema: CreateTableBuilder,
26
- table: Table,
27
- tables: Record<string, Table>,
28
- oldTable: null | Table = null,
29
- renamed?: RenameColumn
30
- ) {
31
- let primaryKeys = table && table.primary ? table.primary : []
32
- const columns = Object.values(table.schema)
33
- // all columns in a junction table will be meta
34
- let metaCols = columns.filter(col => (col as NumberFieldMetadata).meta)
35
- let isJunction = metaCols.length === columns.length
36
- let columnTypeSet: string[] = []
37
-
38
- // can't change primary once its set for now
39
- if (!oldTable) {
40
- // junction tables are special - we have an expected format
41
- if (isJunction) {
42
- schema.primary(metaCols.map(col => col.name))
43
- } else if (primaryKeys.length === 1) {
44
- schema.increments(primaryKeys[0]).primary()
45
- // note that we've set its type
46
- columnTypeSet.push(primaryKeys[0])
47
- } else {
48
- schema.primary(primaryKeys)
49
- }
50
- }
51
-
52
- // check if any columns need added
53
- const foreignKeys = Object.values(table.schema).map(
54
- col => (col as any).foreignKey
55
- )
56
- for (let [key, column] of Object.entries(table.schema)) {
57
- // skip things that are already correct
58
- const oldColumn = oldTable ? oldTable.schema[key] : null
59
- if (
60
- (oldColumn && oldColumn.type) ||
61
- columnTypeSet.includes(key) ||
62
- renamed?.updated === key
63
- ) {
64
- continue
65
- }
66
- const columnType = column.type
67
- switch (columnType) {
68
- case FieldType.STRING:
69
- case FieldType.OPTIONS:
70
- case FieldType.LONGFORM:
71
- case FieldType.BARCODEQR:
72
- case FieldType.BB_REFERENCE_SINGLE:
73
- // primary key strings have to have a length in some DBs
74
- if (primaryKeys.includes(key)) {
75
- schema.string(key, 255)
76
- } else {
77
- schema.text(key)
78
- }
79
- break
80
- case FieldType.NUMBER:
81
- // if meta is specified then this is a junction table entry
82
- if (column.meta && column.meta.toKey && column.meta.toTable) {
83
- const { toKey, toTable } = column.meta
84
- schema.integer(key).unsigned()
85
- schema.foreign(key).references(`${toTable}.${toKey}`)
86
- } else if (foreignKeys.indexOf(key) === -1) {
87
- schema.float(key)
88
- }
89
- break
90
- case FieldType.BIGINT:
91
- schema.bigint(key)
92
- break
93
- case FieldType.BOOLEAN:
94
- schema.boolean(key)
95
- break
96
- case FieldType.DATETIME:
97
- if (!column.timeOnly) {
98
- schema.datetime(key, {
99
- useTz: !column.ignoreTimezones,
100
- })
101
- } else {
102
- schema.time(key)
103
- }
104
- break
105
- case FieldType.ARRAY:
106
- case FieldType.BB_REFERENCE:
107
- if (helpers.schema.isDeprecatedSingleUserColumn(column)) {
108
- // This is still required for unit testing, in order to create "deprecated" schemas
109
- schema.text(key)
110
- } else {
111
- schema.json(key)
112
- }
113
- break
114
- case FieldType.LINK:
115
- // this side of the relationship doesn't need any SQL work
116
- if (
117
- column.relationshipType !== RelationshipType.MANY_TO_ONE &&
118
- column.relationshipType !== RelationshipType.MANY_TO_MANY
119
- ) {
120
- if (!column.foreignKey || !column.tableId) {
121
- throw new Error("Invalid relationship schema")
122
- }
123
- const { tableName } = breakExternalTableId(column.tableId)
124
- // @ts-ignore
125
- const relatedTable = tables[tableName]
126
- if (!relatedTable || !relatedTable.primary) {
127
- throw new Error(
128
- "Referenced table doesn't exist or has no primary keys"
129
- )
130
- }
131
- const relatedPrimary = relatedTable.primary[0]
132
- const externalType = relatedTable.schema[relatedPrimary].externalType
133
- if (externalType) {
134
- schema.specificType(column.foreignKey, externalType)
135
- } else {
136
- schema.integer(column.foreignKey).unsigned()
137
- }
138
-
139
- schema
140
- .foreign(column.foreignKey)
141
- .references(`${tableName}.${relatedPrimary}`)
142
- }
143
- break
144
- case FieldType.FORMULA:
145
- // This is allowed, but nothing to do on the external datasource
146
- break
147
- case FieldType.AI:
148
- // This is allowed, but nothing to do on the external datasource
149
- break
150
- case FieldType.ATTACHMENTS:
151
- case FieldType.ATTACHMENT_SINGLE:
152
- case FieldType.SIGNATURE_SINGLE:
153
- case FieldType.AUTO:
154
- case FieldType.JSON:
155
- case FieldType.INTERNAL:
156
- throw `${column.type} is not a valid SQL type`
157
-
158
- default:
159
- utils.unreachable(columnType)
160
- }
161
- }
162
-
163
- const oldType = renamed ? oldTable?.schema[renamed.old].type : undefined
164
- if (renamed && oldType && !isIgnoredType(oldType)) {
165
- schema.renameColumn(renamed.old, renamed.updated)
166
- }
167
-
168
- // need to check if any columns have been deleted
169
- if (oldTable) {
170
- const deletedColumns = Object.entries(oldTable.schema).filter(
171
- ([key, column]) =>
172
- !isIgnoredType(column.type) && table.schema[key] == null
173
- )
174
- deletedColumns.forEach(([key, column]) => {
175
- if (renamed?.old === key || isIgnoredType(column.type)) {
176
- return
177
- }
178
- if (oldTable.constrained && oldTable.constrained.indexOf(key) !== -1) {
179
- schema.dropForeign(key)
180
- }
181
- schema.dropColumn(key)
182
- })
183
- }
184
-
185
- return schema
186
- }
187
-
188
- function buildCreateTable(
189
- knex: SchemaBuilder,
190
- table: Table,
191
- tables: Record<string, Table>
192
- ): SchemaBuilder {
193
- return knex.createTable(table.name, schema => {
194
- generateSchema(schema, table, tables)
195
- })
196
- }
197
-
198
- function buildUpdateTable(
199
- knex: SchemaBuilder,
200
- table: Table,
201
- tables: Record<string, Table>,
202
- oldTable: Table,
203
- renamed: RenameColumn
204
- ): SchemaBuilder {
205
- return knex.alterTable(table.name, schema => {
206
- generateSchema(schema, table, tables, oldTable, renamed)
207
- })
208
- }
209
-
210
- function buildDeleteTable(knex: SchemaBuilder, table: Table): SchemaBuilder {
211
- return knex.dropTable(table.name)
212
- }
213
-
214
- class SqlTableQueryBuilder {
215
- private readonly sqlClient: SqlClient
216
- private extendedSqlClient: SqlClient | undefined
217
-
218
- // pass through client to get flavour of SQL
219
- constructor(client: SqlClient) {
220
- this.sqlClient = client
221
- }
222
-
223
- getBaseSqlClient(): SqlClient {
224
- return this.sqlClient
225
- }
226
-
227
- getSqlClient(): SqlClient {
228
- return this.extendedSqlClient || this.sqlClient
229
- }
230
-
231
- // if working in a database like MySQL with many variants (MariaDB)
232
- // we can set another client which overrides the base one
233
- setExtendedSqlClient(client: SqlClient) {
234
- this.extendedSqlClient = client
235
- }
236
-
237
- /**
238
- * @param json the input JSON structure from which an SQL query will be built.
239
- * @return the operation that was found in the JSON.
240
- */
241
- _operation(json: QueryJson): Operation {
242
- return json.endpoint.operation
243
- }
244
-
245
- _tableQuery(json: QueryJson): SqlQuery | SqlQuery[] {
246
- let client = knex({ client: this.sqlClient }).schema
247
- let schemaName = json?.endpoint?.schema
248
- if (schemaName) {
249
- client = client.withSchema(schemaName)
250
- }
251
-
252
- let query: Knex.SchemaBuilder
253
- if (!json.table || !json.meta || !json.meta.tables) {
254
- throw new Error("Cannot execute without table being specified")
255
- }
256
- if (json.table.sourceType === TableSourceType.INTERNAL) {
257
- throw new Error("Cannot perform table actions for SQS.")
258
- }
259
-
260
- switch (this._operation(json)) {
261
- case Operation.CREATE_TABLE:
262
- query = buildCreateTable(client, json.table, json.meta.tables)
263
- break
264
- case Operation.UPDATE_TABLE:
265
- if (!json.meta || !json.meta.table) {
266
- throw new Error("Must specify old table for update")
267
- }
268
- // renameColumn does not work for MySQL, so return a raw query
269
- if (this.sqlClient === SqlClient.MY_SQL && json.meta.renamed) {
270
- const updatedColumn = json.meta.renamed.updated
271
- const tableName = schemaName
272
- ? `\`${schemaName}\`.\`${json.table.name}\``
273
- : `\`${json.table.name}\``
274
- return {
275
- sql: `alter table ${tableName} rename column \`${json.meta.renamed.old}\` to \`${updatedColumn}\`;`,
276
- bindings: [],
277
- }
278
- }
279
-
280
- query = buildUpdateTable(
281
- client,
282
- json.table,
283
- json.meta.tables,
284
- json.meta.table,
285
- json.meta.renamed!
286
- )
287
-
288
- // renameColumn for SQL Server returns a parameterised `sp_rename` query,
289
- // which is not supported by SQL Server and gives a syntax error.
290
- if (this.sqlClient === SqlClient.MS_SQL && json.meta.renamed) {
291
- const oldColumn = json.meta.renamed.old
292
- const updatedColumn = json.meta.renamed.updated
293
- const tableName = schemaName
294
- ? `${schemaName}.${json.table.name}`
295
- : `${json.table.name}`
296
- const sql = getNativeSql(query)
297
- if (Array.isArray(sql)) {
298
- for (const query of sql) {
299
- if (query.sql.startsWith("exec sp_rename")) {
300
- query.sql = `exec sp_rename '${tableName}.${oldColumn}', '${updatedColumn}', 'COLUMN'`
301
- query.bindings = []
302
- }
303
- }
304
- }
305
-
306
- return sql
307
- }
308
- break
309
- case Operation.DELETE_TABLE:
310
- query = buildDeleteTable(client, json.table)
311
- break
312
- default:
313
- throw new Error("Table operation is of unknown type")
314
- }
315
- return getNativeSql(query)
316
- }
317
- }
318
-
319
- export default SqlTableQueryBuilder
package/src/sql/utils.ts DELETED
@@ -1,193 +0,0 @@
1
- import {
2
- DocumentType,
3
- ManyToManyRelationshipJson,
4
- RelationshipsJson,
5
- SqlQuery,
6
- Table,
7
- TableSourceType,
8
- } from "@budibase/types"
9
- import { DEFAULT_BB_DATASOURCE_ID } from "../constants"
10
- import { Knex } from "knex"
11
- import { SEPARATOR } from "../db"
12
- import environment from "../environment"
13
-
14
- const DOUBLE_SEPARATOR = `${SEPARATOR}${SEPARATOR}`
15
- const ROW_ID_REGEX = /^\[.*]$/g
16
- const ENCODED_SPACE = encodeURIComponent(" ")
17
- const ISO_DATE_REGEX = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z$/
18
- const TIME_REGEX = /^(?:\d{2}:)?(?:\d{2}:)(?:\d{2})$/
19
-
20
- export function isExternalTableID(tableId: string) {
21
- return tableId.startsWith(DocumentType.DATASOURCE + SEPARATOR)
22
- }
23
-
24
- export function isInternalTableID(tableId: string) {
25
- return !isExternalTableID(tableId)
26
- }
27
-
28
- export function getNativeSql(
29
- query: Knex.SchemaBuilder | Knex.QueryBuilder
30
- ): SqlQuery | SqlQuery[] {
31
- let sql = query.toSQL()
32
-
33
- if (Array.isArray(sql)) {
34
- return sql as SqlQuery[]
35
- }
36
- let native: Knex.SqlNative | undefined
37
- if (sql.toNative) {
38
- native = sql.toNative()
39
- }
40
- return {
41
- sql: native?.sql || sql.sql,
42
- bindings: native?.bindings || sql.bindings,
43
- } as SqlQuery
44
- }
45
-
46
- export function isExternalTable(table: Table) {
47
- if (
48
- table?.sourceId &&
49
- table.sourceId.includes(DocumentType.DATASOURCE + SEPARATOR) &&
50
- table?.sourceId !== DEFAULT_BB_DATASOURCE_ID
51
- ) {
52
- return true
53
- } else if (table?.sourceType === TableSourceType.EXTERNAL) {
54
- return true
55
- } else if (table?._id && isExternalTableID(table._id)) {
56
- return true
57
- }
58
- return false
59
- }
60
-
61
- export function buildExternalTableId(datasourceId: string, tableName: string) {
62
- // encode spaces
63
- if (tableName.includes(" ")) {
64
- tableName = encodeURIComponent(tableName)
65
- }
66
- return `${datasourceId}${DOUBLE_SEPARATOR}${tableName}`
67
- }
68
-
69
- export function breakExternalTableId(tableId: string) {
70
- const parts = tableId.split(DOUBLE_SEPARATOR)
71
- let datasourceId = parts.shift()
72
- // if they need joined
73
- let tableName = parts.join(DOUBLE_SEPARATOR)
74
- // if contains encoded spaces, decode it
75
- if (tableName.includes(ENCODED_SPACE)) {
76
- tableName = decodeURIComponent(tableName)
77
- }
78
- if (!datasourceId || !tableName) {
79
- throw new Error("Unable to get datasource/table name from table ID")
80
- }
81
- return { datasourceId, tableName }
82
- }
83
-
84
- export function generateRowIdField(keyProps: any[] = []) {
85
- if (!Array.isArray(keyProps)) {
86
- keyProps = [keyProps]
87
- }
88
- for (let index in keyProps) {
89
- if (keyProps[index] instanceof Buffer) {
90
- keyProps[index] = keyProps[index].toString()
91
- }
92
- }
93
- // this conserves order and types
94
- // we have to swap the double quotes to single quotes for use in HBS statements
95
- // when using the literal helper the double quotes can break things
96
- return encodeURIComponent(JSON.stringify(keyProps).replace(/"/g, "'"))
97
- }
98
-
99
- export function isRowId(field: any) {
100
- return (
101
- Array.isArray(field) ||
102
- (typeof field === "string" && field.match(ROW_ID_REGEX) != null)
103
- )
104
- }
105
-
106
- export function convertRowId(field: any) {
107
- if (Array.isArray(field)) {
108
- return field[0]
109
- }
110
- if (typeof field === "string" && field.match(ROW_ID_REGEX) != null) {
111
- return field.substring(1, field.length - 1)
112
- }
113
- return field
114
- }
115
-
116
- // should always return an array
117
- export function breakRowIdField(_id: string | { _id: string }): any[] {
118
- if (!_id) {
119
- return []
120
- }
121
- // have to replace on the way back as we swapped out the double quotes
122
- // when encoding, but JSON can't handle the single quotes
123
- const id = typeof _id === "string" ? _id : _id._id
124
- const decoded: string = decodeURIComponent(id).replace(/'/g, '"')
125
- try {
126
- const parsed = JSON.parse(decoded)
127
- return Array.isArray(parsed) ? parsed : [parsed]
128
- } catch (err) {
129
- // wasn't json - likely was handlebars for a many to many
130
- return [_id]
131
- }
132
- }
133
-
134
- export function isInvalidISODateString(str: string) {
135
- const trimmedValue = str.trim()
136
- if (!ISO_DATE_REGEX.test(trimmedValue)) {
137
- return false
138
- }
139
- let d = new Date(trimmedValue)
140
- return isNaN(d.getTime())
141
- }
142
-
143
- export function isValidISODateString(str: string) {
144
- const trimmedValue = str.trim()
145
- if (!ISO_DATE_REGEX.test(trimmedValue)) {
146
- return false
147
- }
148
- let d = new Date(trimmedValue)
149
- if (isNaN(d.getTime())) {
150
- return false
151
- }
152
- return d.toISOString() === trimmedValue
153
- }
154
-
155
- export function isValidFilter(value: any) {
156
- return value != null && value !== ""
157
- }
158
-
159
- export function isValidTime(value: string) {
160
- return TIME_REGEX.test(value)
161
- }
162
-
163
- export function sqlLog(client: string, query: string, values?: any[]) {
164
- if (!environment.SQL_LOGGING_ENABLE) {
165
- return
166
- }
167
- let string = `[SQL] [${client.toUpperCase()}] query="${query}"`
168
- if (values) {
169
- string += ` values="${values.join(", ")}"`
170
- }
171
- console.log(string)
172
- }
173
-
174
- function isValidManyToManyRelationship(
175
- relationship: RelationshipsJson
176
- ): relationship is ManyToManyRelationshipJson {
177
- return (
178
- !!relationship.through &&
179
- !!relationship.fromPrimary &&
180
- !!relationship.from &&
181
- !!relationship.toPrimary &&
182
- !!relationship.to
183
- )
184
- }
185
-
186
- export function validateManyToMany(
187
- relationship: RelationshipsJson
188
- ): ManyToManyRelationshipJson | undefined {
189
- if (isValidManyToManyRelationship(relationship)) {
190
- return relationship
191
- }
192
- return undefined
193
- }
package/src/tenancy/db.ts DELETED
@@ -1,6 +0,0 @@
1
- import { getDB } from "../db/db"
2
- import { getGlobalDBName } from "../context"
3
-
4
- export function getTenantDB(tenantId: string) {
5
- return getDB(getGlobalDBName(tenantId))
6
- }
@@ -1,2 +0,0 @@
1
- export * from "./db"
2
- export * from "./tenancy"
@@ -1,148 +0,0 @@
1
- import {
2
- DEFAULT_TENANT_ID,
3
- getTenantId,
4
- getTenantIDFromAppID,
5
- isMultiTenant,
6
- getPlatformURL,
7
- } from "../context"
8
- import {
9
- BBContext,
10
- TenantResolutionStrategy,
11
- GetTenantIdOptions,
12
- } from "@budibase/types"
13
- import { Header } from "../constants"
14
-
15
- export function addTenantToUrl(url: string) {
16
- const tenantId = getTenantId()
17
-
18
- if (isMultiTenant()) {
19
- const char = url.indexOf("?") === -1 ? "?" : "&"
20
- url += `${char}tenantId=${tenantId}`
21
- }
22
-
23
- return url
24
- }
25
-
26
- export const isUserInAppTenant = (appId: string, user?: any) => {
27
- let userTenantId
28
- if (user) {
29
- userTenantId = user.tenantId || DEFAULT_TENANT_ID
30
- } else {
31
- userTenantId = getTenantId()
32
- }
33
- const tenantId = getTenantIDFromAppID(appId) || DEFAULT_TENANT_ID
34
- return tenantId === userTenantId
35
- }
36
-
37
- const ALL_STRATEGIES = Object.values(TenantResolutionStrategy)
38
-
39
- export const getTenantIDFromCtx = (
40
- ctx: BBContext,
41
- opts: GetTenantIdOptions
42
- ): string | undefined => {
43
- // exit early if not multi-tenant
44
- if (!isMultiTenant()) {
45
- return DEFAULT_TENANT_ID
46
- }
47
-
48
- // opt defaults
49
- if (opts.allowNoTenant === undefined) {
50
- opts.allowNoTenant = false
51
- }
52
- if (!opts.includeStrategies) {
53
- opts.includeStrategies = ALL_STRATEGIES
54
- }
55
- if (!opts.excludeStrategies) {
56
- opts.excludeStrategies = []
57
- }
58
-
59
- const isAllowed = (strategy: TenantResolutionStrategy) => {
60
- // excluded takes precedence
61
- if (opts.excludeStrategies?.includes(strategy)) {
62
- return false
63
- }
64
- if (opts.includeStrategies?.includes(strategy)) {
65
- return true
66
- }
67
- }
68
-
69
- // always use user first
70
- if (isAllowed(TenantResolutionStrategy.USER)) {
71
- const userTenantId = ctx.user?.tenantId
72
- if (userTenantId) {
73
- return userTenantId
74
- }
75
- }
76
-
77
- // header
78
- if (isAllowed(TenantResolutionStrategy.HEADER)) {
79
- const headerTenantId = ctx.request.headers[Header.TENANT_ID]
80
- if (headerTenantId) {
81
- return headerTenantId as string
82
- }
83
- }
84
-
85
- // query param
86
- if (isAllowed(TenantResolutionStrategy.QUERY)) {
87
- const queryTenantId = ctx.request.query.tenantId
88
- if (queryTenantId) {
89
- return queryTenantId as string
90
- }
91
- }
92
-
93
- // subdomain
94
- if (isAllowed(TenantResolutionStrategy.SUBDOMAIN)) {
95
- // e.g. budibase.app or local.com:10000
96
- let platformHost
97
- try {
98
- platformHost = new URL(getPlatformURL()).host.split(":")[0]
99
- } catch (err: any) {
100
- // if invalid URL, just don't try to process subdomain
101
- if (err.code !== "ERR_INVALID_URL") {
102
- throw err
103
- }
104
- }
105
- // e.g. tenant.budibase.app or tenant.local.com
106
- const requestHost = ctx.host
107
- // parse the tenant id from the difference
108
- if (platformHost && requestHost.includes(platformHost)) {
109
- const tenantId = requestHost.substring(
110
- 0,
111
- requestHost.indexOf(`.${platformHost}`)
112
- )
113
- if (tenantId) {
114
- return tenantId
115
- }
116
- }
117
- }
118
-
119
- // path
120
- if (isAllowed(TenantResolutionStrategy.PATH)) {
121
- // params - have to parse manually due to koa-router not run yet
122
- const match = ctx.matched.find(
123
- (m: any) => !!m.paramNames.find((p: any) => p.name === "tenantId")
124
- )
125
-
126
- // get the raw path url - without any query params
127
- const ctxUrl = ctx.originalUrl
128
- let url
129
- if (ctxUrl.includes("?")) {
130
- url = ctxUrl.split("?")[0]
131
- } else {
132
- url = ctxUrl
133
- }
134
-
135
- if (match) {
136
- const params = match.params(url, match.captures(url), {})
137
- if (params.tenantId) {
138
- return params.tenantId
139
- }
140
- }
141
- }
142
-
143
- if (!opts.allowNoTenant) {
144
- ctx.throw(403, "Tenant id not set")
145
- }
146
-
147
- return undefined
148
- }