@budibase/backend-core 3.2.5 → 3.2.7

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 (276) hide show
  1. package/dist/index.js +7 -1
  2. package/dist/index.js.map +2 -2
  3. package/dist/index.js.meta.json +1 -1
  4. package/dist/package.json +11 -4
  5. package/dist/plugins.js.meta.json +1 -1
  6. package/dist/src/environment.d.ts +1 -0
  7. package/dist/src/environment.js +6 -1
  8. package/dist/src/environment.js.map +1 -1
  9. package/package.json +11 -4
  10. package/src/accounts/accounts.ts +0 -82
  11. package/src/accounts/api.ts +0 -59
  12. package/src/accounts/index.ts +0 -1
  13. package/src/auth/auth.ts +0 -210
  14. package/src/auth/index.ts +0 -1
  15. package/src/auth/tests/auth.spec.ts +0 -14
  16. package/src/blacklist/blacklist.ts +0 -54
  17. package/src/blacklist/index.ts +0 -1
  18. package/src/blacklist/tests/blacklist.spec.ts +0 -46
  19. package/src/cache/appMetadata.ts +0 -88
  20. package/src/cache/base/index.ts +0 -150
  21. package/src/cache/docWritethrough.ts +0 -105
  22. package/src/cache/generic.ts +0 -33
  23. package/src/cache/index.ts +0 -8
  24. package/src/cache/invite.ts +0 -86
  25. package/src/cache/passwordReset.ts +0 -49
  26. package/src/cache/tests/docWritethrough.spec.ts +0 -296
  27. package/src/cache/tests/user.spec.ts +0 -145
  28. package/src/cache/tests/writethrough.spec.ts +0 -139
  29. package/src/cache/user.ts +0 -154
  30. package/src/cache/writethrough.ts +0 -133
  31. package/src/configs/configs.ts +0 -263
  32. package/src/configs/index.ts +0 -1
  33. package/src/configs/tests/configs.spec.ts +0 -184
  34. package/src/constants/db.ts +0 -75
  35. package/src/constants/index.ts +0 -2
  36. package/src/constants/misc.ts +0 -36
  37. package/src/context/Context.ts +0 -14
  38. package/src/context/identity.ts +0 -58
  39. package/src/context/index.ts +0 -3
  40. package/src/context/mainContext.ts +0 -422
  41. package/src/context/tests/index.spec.ts +0 -255
  42. package/src/context/types.ts +0 -26
  43. package/src/db/Replication.ts +0 -94
  44. package/src/db/couch/DatabaseImpl.ts +0 -511
  45. package/src/db/couch/connections.ts +0 -89
  46. package/src/db/couch/index.ts +0 -4
  47. package/src/db/couch/pouchDB.ts +0 -97
  48. package/src/db/couch/pouchDump.ts +0 -0
  49. package/src/db/couch/tests/DatabaseImpl.spec.ts +0 -118
  50. package/src/db/couch/utils.ts +0 -55
  51. package/src/db/db.ts +0 -34
  52. package/src/db/errors.ts +0 -14
  53. package/src/db/index.ts +0 -12
  54. package/src/db/instrumentation.ts +0 -199
  55. package/src/db/lucene.ts +0 -721
  56. package/src/db/searchIndexes/index.ts +0 -1
  57. package/src/db/searchIndexes/searchIndexes.ts +0 -62
  58. package/src/db/tests/DatabaseImpl.spec.ts +0 -55
  59. package/src/db/tests/connections.spec.ts +0 -22
  60. package/src/db/tests/index.spec.ts +0 -32
  61. package/src/db/tests/lucene.spec.ts +0 -400
  62. package/src/db/tests/pouch.spec.js +0 -62
  63. package/src/db/tests/utils.spec.ts +0 -63
  64. package/src/db/utils.ts +0 -208
  65. package/src/db/views.ts +0 -245
  66. package/src/docIds/conversions.ts +0 -60
  67. package/src/docIds/ids.ts +0 -126
  68. package/src/docIds/index.ts +0 -2
  69. package/src/docIds/newid.ts +0 -5
  70. package/src/docIds/params.ts +0 -189
  71. package/src/docUpdates/index.ts +0 -24
  72. package/src/environment.ts +0 -293
  73. package/src/errors/errors.ts +0 -119
  74. package/src/errors/index.ts +0 -1
  75. package/src/events/analytics.ts +0 -6
  76. package/src/events/asyncEvents/index.ts +0 -2
  77. package/src/events/asyncEvents/publisher.ts +0 -12
  78. package/src/events/asyncEvents/queue.ts +0 -22
  79. package/src/events/backfill.ts +0 -183
  80. package/src/events/documentId.ts +0 -56
  81. package/src/events/events.ts +0 -47
  82. package/src/events/identification.ts +0 -311
  83. package/src/events/index.ts +0 -15
  84. package/src/events/processors/AnalyticsProcessor.ts +0 -64
  85. package/src/events/processors/AuditLogsProcessor.ts +0 -92
  86. package/src/events/processors/LoggingProcessor.ts +0 -36
  87. package/src/events/processors/Processors.ts +0 -52
  88. package/src/events/processors/async/DocumentUpdateProcessor.ts +0 -38
  89. package/src/events/processors/index.ts +0 -19
  90. package/src/events/processors/posthog/PosthogProcessor.ts +0 -118
  91. package/src/events/processors/posthog/index.ts +0 -3
  92. package/src/events/processors/posthog/rateLimiting.ts +0 -106
  93. package/src/events/processors/posthog/tests/PosthogProcessor.spec.ts +0 -164
  94. package/src/events/processors/types.ts +0 -1
  95. package/src/events/publishers/account.ts +0 -41
  96. package/src/events/publishers/ai.ts +0 -21
  97. package/src/events/publishers/app.ts +0 -168
  98. package/src/events/publishers/auditLog.ts +0 -26
  99. package/src/events/publishers/auth.ts +0 -73
  100. package/src/events/publishers/automation.ts +0 -110
  101. package/src/events/publishers/backfill.ts +0 -74
  102. package/src/events/publishers/backup.ts +0 -42
  103. package/src/events/publishers/datasource.ts +0 -48
  104. package/src/events/publishers/email.ts +0 -17
  105. package/src/events/publishers/environmentVariable.ts +0 -38
  106. package/src/events/publishers/group.ts +0 -99
  107. package/src/events/publishers/index.ts +0 -25
  108. package/src/events/publishers/installation.ts +0 -38
  109. package/src/events/publishers/layout.ts +0 -26
  110. package/src/events/publishers/license.ts +0 -84
  111. package/src/events/publishers/org.ts +0 -37
  112. package/src/events/publishers/plugin.ts +0 -47
  113. package/src/events/publishers/query.ts +0 -89
  114. package/src/events/publishers/role.ts +0 -62
  115. package/src/events/publishers/rows.ts +0 -29
  116. package/src/events/publishers/screen.ts +0 -36
  117. package/src/events/publishers/serve.ts +0 -43
  118. package/src/events/publishers/table.ts +0 -70
  119. package/src/events/publishers/user.ts +0 -202
  120. package/src/events/publishers/view.ts +0 -107
  121. package/src/features/features.ts +0 -277
  122. package/src/features/index.ts +0 -2
  123. package/src/features/tests/features.spec.ts +0 -267
  124. package/src/features/tests/utils.ts +0 -64
  125. package/src/helpers.ts +0 -9
  126. package/src/index.ts +0 -59
  127. package/src/installation.ts +0 -115
  128. package/src/logging/alerts.ts +0 -26
  129. package/src/logging/correlation/correlation.ts +0 -15
  130. package/src/logging/correlation/index.ts +0 -1
  131. package/src/logging/correlation/middleware.ts +0 -18
  132. package/src/logging/index.ts +0 -4
  133. package/src/logging/pino/logger.ts +0 -239
  134. package/src/logging/pino/middleware.ts +0 -48
  135. package/src/logging/system.ts +0 -81
  136. package/src/logging/tests/system.spec.ts +0 -61
  137. package/src/middleware/adminOnly.ts +0 -9
  138. package/src/middleware/auditLog.ts +0 -6
  139. package/src/middleware/authenticated.ts +0 -247
  140. package/src/middleware/builderOnly.ts +0 -21
  141. package/src/middleware/builderOrAdmin.ts +0 -21
  142. package/src/middleware/contentSecurityPolicy.ts +0 -113
  143. package/src/middleware/csrf.ts +0 -81
  144. package/src/middleware/errorHandling.ts +0 -43
  145. package/src/middleware/index.ts +0 -24
  146. package/src/middleware/internalApi.ts +0 -23
  147. package/src/middleware/ip.ts +0 -12
  148. package/src/middleware/joi-validator.ts +0 -58
  149. package/src/middleware/matchers.ts +0 -39
  150. package/src/middleware/passport/datasource/google.ts +0 -102
  151. package/src/middleware/passport/local.ts +0 -54
  152. package/src/middleware/passport/sso/google.ts +0 -77
  153. package/src/middleware/passport/sso/oidc.ts +0 -152
  154. package/src/middleware/passport/sso/sso.ts +0 -138
  155. package/src/middleware/passport/sso/tests/google.spec.ts +0 -68
  156. package/src/middleware/passport/sso/tests/oidc.spec.ts +0 -144
  157. package/src/middleware/passport/sso/tests/sso.spec.ts +0 -197
  158. package/src/middleware/passport/utils.ts +0 -38
  159. package/src/middleware/querystringToBody.ts +0 -28
  160. package/src/middleware/tenancy.ts +0 -36
  161. package/src/middleware/tests/builder.spec.ts +0 -181
  162. package/src/middleware/tests/contentSecurityPolicy.spec.ts +0 -75
  163. package/src/middleware/tests/matchers.spec.ts +0 -100
  164. package/src/migrations/definitions.ts +0 -40
  165. package/src/migrations/index.ts +0 -2
  166. package/src/migrations/migrations.ts +0 -186
  167. package/src/migrations/tests/__snapshots__/migrations.spec.ts.snap +0 -11
  168. package/src/migrations/tests/migrations.spec.ts +0 -64
  169. package/src/objectStore/buckets/app.ts +0 -53
  170. package/src/objectStore/buckets/global.ts +0 -29
  171. package/src/objectStore/buckets/index.ts +0 -3
  172. package/src/objectStore/buckets/plugins.ts +0 -71
  173. package/src/objectStore/buckets/tests/app.spec.ts +0 -161
  174. package/src/objectStore/buckets/tests/global.spec.ts +0 -74
  175. package/src/objectStore/buckets/tests/plugins.spec.ts +0 -111
  176. package/src/objectStore/cloudfront.ts +0 -41
  177. package/src/objectStore/index.ts +0 -3
  178. package/src/objectStore/objectStore.ts +0 -585
  179. package/src/objectStore/utils.ts +0 -113
  180. package/src/platform/index.ts +0 -3
  181. package/src/platform/platformDb.ts +0 -6
  182. package/src/platform/tenants.ts +0 -101
  183. package/src/platform/tests/tenants.spec.ts +0 -26
  184. package/src/platform/users.ts +0 -129
  185. package/src/plugin/index.ts +0 -1
  186. package/src/plugin/tests/validation.spec.ts +0 -209
  187. package/src/plugin/utils.ts +0 -175
  188. package/src/queue/constants.ts +0 -8
  189. package/src/queue/inMemoryQueue.ts +0 -189
  190. package/src/queue/index.ts +0 -2
  191. package/src/queue/listeners.ts +0 -199
  192. package/src/queue/queue.ts +0 -84
  193. package/src/redis/index.ts +0 -6
  194. package/src/redis/init.ts +0 -118
  195. package/src/redis/redis.ts +0 -358
  196. package/src/redis/redlockImpl.ts +0 -155
  197. package/src/redis/tests/redis.spec.ts +0 -207
  198. package/src/redis/tests/redlockImpl.spec.ts +0 -105
  199. package/src/redis/utils.ts +0 -128
  200. package/src/security/auth.ts +0 -24
  201. package/src/security/encryption.ts +0 -185
  202. package/src/security/index.ts +0 -1
  203. package/src/security/permissions.ts +0 -166
  204. package/src/security/roles.ts +0 -655
  205. package/src/security/secrets.ts +0 -20
  206. package/src/security/sessions.ts +0 -123
  207. package/src/security/tests/auth.spec.ts +0 -45
  208. package/src/security/tests/encryption.spec.ts +0 -31
  209. package/src/security/tests/permissions.spec.ts +0 -146
  210. package/src/security/tests/secrets.spec.ts +0 -35
  211. package/src/security/tests/sessions.spec.ts +0 -12
  212. package/src/sql/designDoc.ts +0 -17
  213. package/src/sql/index.ts +0 -5
  214. package/src/sql/sql.ts +0 -1854
  215. package/src/sql/sqlTable.ts +0 -319
  216. package/src/sql/utils.ts +0 -193
  217. package/src/tenancy/db.ts +0 -6
  218. package/src/tenancy/index.ts +0 -2
  219. package/src/tenancy/tenancy.ts +0 -148
  220. package/src/tenancy/tests/tenancy.spec.ts +0 -184
  221. package/src/timers/index.ts +0 -1
  222. package/src/timers/timers.ts +0 -22
  223. package/src/users/db.ts +0 -582
  224. package/src/users/events.ts +0 -176
  225. package/src/users/index.ts +0 -4
  226. package/src/users/lookup.ts +0 -99
  227. package/src/users/test/db.spec.ts +0 -188
  228. package/src/users/test/utils.spec.ts +0 -67
  229. package/src/users/users.ts +0 -353
  230. package/src/users/utils.ts +0 -81
  231. package/src/utils/Duration.ts +0 -56
  232. package/src/utils/hashing.ts +0 -15
  233. package/src/utils/index.ts +0 -4
  234. package/src/utils/stringUtils.ts +0 -8
  235. package/src/utils/tests/Duration.spec.ts +0 -19
  236. package/src/utils/tests/utils.spec.ts +0 -204
  237. package/src/utils/utils.ts +0 -249
  238. package/tests/core/logging.ts +0 -34
  239. package/tests/core/users/users.spec.js +0 -53
  240. package/tests/core/utilities/index.ts +0 -7
  241. package/tests/core/utilities/jestUtils.ts +0 -33
  242. package/tests/core/utilities/mocks/alerts.ts +0 -4
  243. package/tests/core/utilities/mocks/date.ts +0 -3
  244. package/tests/core/utilities/mocks/events.ts +0 -132
  245. package/tests/core/utilities/mocks/index.ts +0 -9
  246. package/tests/core/utilities/mocks/licenses.ts +0 -119
  247. package/tests/core/utilities/queue.ts +0 -9
  248. package/tests/core/utilities/structures/Chance.ts +0 -20
  249. package/tests/core/utilities/structures/accounts.ts +0 -80
  250. package/tests/core/utilities/structures/apps.ts +0 -21
  251. package/tests/core/utilities/structures/common.ts +0 -7
  252. package/tests/core/utilities/structures/db.ts +0 -12
  253. package/tests/core/utilities/structures/documents/index.ts +0 -1
  254. package/tests/core/utilities/structures/documents/platform/index.ts +0 -1
  255. package/tests/core/utilities/structures/documents/platform/installation.ts +0 -12
  256. package/tests/core/utilities/structures/generator.ts +0 -3
  257. package/tests/core/utilities/structures/index.ts +0 -15
  258. package/tests/core/utilities/structures/koa.ts +0 -16
  259. package/tests/core/utilities/structures/licenses.ts +0 -190
  260. package/tests/core/utilities/structures/plugins.ts +0 -19
  261. package/tests/core/utilities/structures/quotas.ts +0 -72
  262. package/tests/core/utilities/structures/scim.ts +0 -80
  263. package/tests/core/utilities/structures/sso.ts +0 -118
  264. package/tests/core/utilities/structures/tenants.ts +0 -5
  265. package/tests/core/utilities/structures/userGroups.ts +0 -10
  266. package/tests/core/utilities/structures/users.ts +0 -89
  267. package/tests/core/utilities/testContainerUtils.ts +0 -165
  268. package/tests/core/utilities/utils/index.ts +0 -2
  269. package/tests/core/utilities/utils/queue.ts +0 -27
  270. package/tests/core/utilities/utils/time.ts +0 -3
  271. package/tests/extra/DBTestConfiguration.ts +0 -36
  272. package/tests/extra/index.ts +0 -2
  273. package/tests/extra/testEnv.ts +0 -95
  274. package/tests/index.ts +0 -2
  275. package/tests/jestEnv.ts +0 -10
  276. 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
- }