@budibase/server 2.6.23 → 2.6.24-alpha.1
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/.dockerignore +7 -6
- package/Dockerfile +16 -8
- package/builder/assets/index.b33e8ad5.css +6 -0
- package/builder/assets/index.c0b0be95.js +1869 -0
- package/builder/index.html +2 -2
- package/client/manifest.json +5229 -0
- package/dist/automation.js +32576 -0
- package/dist/automation.js.map +7 -0
- package/dist/index.js +45065 -13
- package/dist/index.js.map +7 -0
- package/dist/query.js +24462 -0
- package/dist/query.js.map +7 -0
- package/jest.config.ts +6 -3
- package/nodemon.json +8 -4
- package/package.json +35 -16
- package/pm2.config.js +1 -1
- package/scripts/build.js +48 -0
- package/src/api/controllers/application.ts +21 -22
- package/src/api/controllers/automation.ts +37 -9
- package/src/api/controllers/datasource.ts +114 -49
- package/src/api/controllers/deploy/index.ts +1 -0
- package/src/api/controllers/integration.ts +3 -3
- package/src/api/controllers/plugin/index.ts +1 -1
- package/src/api/controllers/row/external.ts +39 -15
- package/src/api/controllers/row/index.ts +18 -24
- package/src/api/controllers/row/internal.ts +1 -1
- package/src/api/controllers/row/staticFormula.ts +6 -1
- package/src/api/controllers/row/utils.ts +12 -0
- package/src/api/controllers/static/index.ts +3 -3
- package/src/api/controllers/table/index.ts +3 -0
- package/src/api/controllers/table/internal.ts +2 -6
- package/src/api/controllers/table/utils.ts +32 -1
- package/src/api/controllers/view/index.ts +5 -5
- package/src/api/controllers/webhook.ts +33 -9
- package/src/api/routes/application.ts +5 -0
- package/src/api/routes/automation.ts +0 -1
- package/src/api/routes/datasource.ts +10 -0
- package/src/api/routes/static.ts +3 -1
- package/src/api/routes/tests/{automation.spec.js → automation.spec.ts} +106 -31
- package/src/api/routes/tests/datasource.spec.ts +1 -1
- package/src/api/routes/tests/view.spec.js +4 -3
- package/src/api/routes/tests/{webhook.spec.js → webhook.spec.ts} +33 -11
- package/src/app.ts +0 -1
- package/src/automations/actions.ts +8 -0
- package/src/automations/logging/index.ts +21 -0
- package/src/automations/steps/bash.ts +4 -0
- package/src/automations/steps/collect.ts +58 -0
- package/src/automations/steps/createRow.ts +4 -0
- package/src/automations/steps/delay.ts +1 -0
- package/src/automations/steps/deleteRow.ts +4 -0
- package/src/automations/steps/discord.ts +4 -0
- package/src/automations/steps/executeQuery.ts +4 -0
- package/src/automations/steps/executeScript.ts +4 -0
- package/src/automations/steps/filter.ts +1 -0
- package/src/automations/steps/loop.ts +1 -0
- package/src/automations/steps/make.ts +22 -1
- package/src/automations/steps/openai.ts +106 -0
- package/src/automations/steps/outgoingWebhook.ts +4 -0
- package/src/automations/steps/queryRows.ts +4 -0
- package/src/automations/steps/sendSmtpEmail.ts +4 -0
- package/src/automations/steps/serverLog.ts +4 -0
- package/src/automations/steps/slack.ts +4 -0
- package/src/automations/steps/updateRow.ts +4 -0
- package/src/automations/steps/zapier.ts +22 -1
- package/src/automations/tests/make.spec.ts +54 -0
- package/src/automations/tests/openai.spec.ts +86 -0
- package/src/automations/tests/zapier.spec.ts +56 -0
- package/src/automations/triggers.ts +3 -2
- package/src/constants/index.ts +17 -16
- package/src/db/dynamoClient.ts +1 -1
- package/src/db/inMemoryView.ts +1 -0
- package/src/db/linkedRows/index.ts +5 -3
- package/src/environment.ts +3 -0
- package/src/integration-test/postgres.spec.ts +47 -5
- package/src/integrations/airtable.ts +33 -4
- package/src/integrations/arangodb.ts +20 -2
- package/src/integrations/base/sqlTable.ts +0 -1
- package/src/integrations/couchdb.ts +20 -4
- package/src/integrations/dynamodb.ts +36 -5
- package/src/integrations/elasticsearch.ts +18 -1
- package/src/integrations/firebase.ts +17 -0
- package/src/integrations/googlesheets.ts +66 -5
- package/src/integrations/index.ts +12 -7
- package/src/integrations/microsoftSqlServer.ts +33 -1
- package/src/integrations/mongodb.ts +18 -0
- package/src/integrations/mysql.ts +53 -26
- package/src/integrations/oracle.ts +38 -6
- package/src/integrations/postgres.ts +47 -12
- package/src/integrations/redis.ts +35 -4
- package/src/integrations/s3.ts +21 -3
- package/src/integrations/snowflake.ts +22 -1
- package/src/integrations/tests/googlesheets.spec.ts +41 -9
- package/src/middleware/builder.ts +26 -18
- package/src/migrations/functions/backfill/app/queries.ts +1 -1
- package/src/sdk/app/automations/index.ts +2 -0
- package/src/sdk/app/automations/utils.ts +7 -0
- package/src/sdk/app/datasources/datasources.ts +7 -1
- package/src/sdk/plugins/plugins.ts +1 -1
- package/src/startup.ts +2 -0
- package/src/tests/utilities/TestConfiguration.ts +4 -2
- package/src/tests/utilities/structures.ts +42 -0
- package/src/threads/automation.ts +91 -23
- package/src/threads/index.ts +9 -3
- package/src/threads/utils.ts +2 -0
- package/src/utilities/fileSystem/app.ts +14 -4
- package/src/utilities/fileSystem/clientLibrary.ts +8 -3
- package/src/utilities/fileSystem/filesystem.ts +3 -1
- package/src/utilities/redis.ts +25 -3
- package/src/utilities/rowProcessor/index.ts +4 -1
- package/src/utilities/rowProcessor/map.ts +1 -1
- package/src/websockets/builder.ts +95 -0
- package/src/websockets/client.ts +2 -2
- package/src/websockets/grid.ts +44 -44
- package/src/websockets/index.ts +13 -6
- package/src/websockets/websocket.ts +211 -7
- package/tsconfig.build.json +9 -1
- package/tsconfig.json +1 -14
- package/builder/assets/index.86c992bf.css +0 -6
- package/builder/assets/index.c16c35ca.js +0 -1794
- package/dist/api/controllers/analytics.js +0 -46
- package/dist/api/controllers/apikeys.js +0 -72
- package/dist/api/controllers/application.js +0 -574
- package/dist/api/controllers/auth.js +0 -80
- package/dist/api/controllers/automation.js +0 -303
- package/dist/api/controllers/backup.js +0 -37
- package/dist/api/controllers/component.js +0 -59
- package/dist/api/controllers/datasource.js +0 -306
- package/dist/api/controllers/deploy/Deployment.js +0 -53
- package/dist/api/controllers/deploy/index.js +0 -198
- package/dist/api/controllers/dev.js +0 -146
- package/dist/api/controllers/integration.js +0 -28
- package/dist/api/controllers/layout.js +0 -49
- package/dist/api/controllers/metadata.js +0 -63
- package/dist/api/controllers/migrations.js +0 -29
- package/dist/api/controllers/ops.js +0 -40
- package/dist/api/controllers/permission.js +0 -162
- package/dist/api/controllers/plugin/file.js +0 -24
- package/dist/api/controllers/plugin/github.js +0 -69
- package/dist/api/controllers/plugin/index.js +0 -112
- package/dist/api/controllers/plugin/npm.js +0 -58
- package/dist/api/controllers/plugin/uploaders.js +0 -11
- package/dist/api/controllers/plugin/url.js +0 -24
- package/dist/api/controllers/plugin/utils.js +0 -27
- package/dist/api/controllers/public/applications.js +0 -146
- package/dist/api/controllers/public/mapping/applications.js +0 -29
- package/dist/api/controllers/public/mapping/index.js +0 -11
- package/dist/api/controllers/public/mapping/queries.js +0 -36
- package/dist/api/controllers/public/mapping/rows.js +0 -24
- package/dist/api/controllers/public/mapping/tables.js +0 -23
- package/dist/api/controllers/public/mapping/types.js +0 -2
- package/dist/api/controllers/public/mapping/users.js +0 -29
- package/dist/api/controllers/public/metrics.js +0 -113
- package/dist/api/controllers/public/queries.js +0 -58
- package/dist/api/controllers/public/rows.js +0 -120
- package/dist/api/controllers/public/tables.js +0 -95
- package/dist/api/controllers/public/users.js +0 -93
- package/dist/api/controllers/public/utils.js +0 -56
- package/dist/api/controllers/query/import/index.js +0 -87
- package/dist/api/controllers/query/import/sources/base/index.js +0 -75
- package/dist/api/controllers/query/import/sources/base/openapi.js +0 -42
- package/dist/api/controllers/query/import/sources/curl.js +0 -99
- package/dist/api/controllers/query/import/sources/openapi2.js +0 -145
- package/dist/api/controllers/query/import/sources/openapi3.js +0 -177
- package/dist/api/controllers/query/import/sources/tests/openapi2/data/crud/crud.json +0 -253
- package/dist/api/controllers/query/import/sources/tests/openapi2/data/petstore/petstore.json +0 -1054
- package/dist/api/controllers/query/import/sources/tests/openapi3/data/crud/crud.json +0 -253
- package/dist/api/controllers/query/import/sources/tests/openapi3/data/petstore/petstore.json +0 -1225
- package/dist/api/controllers/query/index.js +0 -299
- package/dist/api/controllers/query/validation.js +0 -53
- package/dist/api/controllers/role.js +0 -109
- package/dist/api/controllers/routing.js +0 -105
- package/dist/api/controllers/row/ExternalRequest.js +0 -683
- package/dist/api/controllers/row/external.js +0 -339
- package/dist/api/controllers/row/index.js +0 -203
- package/dist/api/controllers/row/internal.js +0 -509
- package/dist/api/controllers/row/internalSearch.js +0 -28
- package/dist/api/controllers/row/staticFormula.js +0 -165
- package/dist/api/controllers/row/utils.js +0 -183
- package/dist/api/controllers/screen.js +0 -110
- package/dist/api/controllers/script.js +0 -30
- package/dist/api/controllers/static/index.js +0 -268
- package/dist/api/controllers/table/bulkFormula.js +0 -173
- package/dist/api/controllers/table/external.js +0 -279
- package/dist/api/controllers/table/index.js +0 -179
- package/dist/api/controllers/table/internal.js +0 -197
- package/dist/api/controllers/table/utils.js +0 -379
- package/dist/api/controllers/templates.js +0 -56
- package/dist/api/controllers/user.js +0 -124
- package/dist/api/controllers/view/exporters.js +0 -46
- package/dist/api/controllers/view/index.js +0 -193
- package/dist/api/controllers/view/utils.js +0 -177
- package/dist/api/controllers/view/viewBuilder.js +0 -158
- package/dist/api/controllers/webhook.js +0 -134
- package/dist/api/index.js +0 -55
- package/dist/api/routes/analytics.js +0 -34
- package/dist/api/routes/apikeys.js +0 -37
- package/dist/api/routes/application.js +0 -48
- package/dist/api/routes/auth.js +0 -33
- package/dist/api/routes/automation.js +0 -50
- package/dist/api/routes/backup.js +0 -35
- package/dist/api/routes/component.js +0 -35
- package/dist/api/routes/datasource.js +0 -43
- package/dist/api/routes/deploy.js +0 -37
- package/dist/api/routes/dev.js +0 -49
- package/dist/api/routes/index.js +0 -75
- package/dist/api/routes/integration.js +0 -37
- package/dist/api/routes/layout.js +0 -37
- package/dist/api/routes/metadata.js +0 -40
- package/dist/api/routes/migrations.js +0 -36
- package/dist/api/routes/ops.js +0 -52
- package/dist/api/routes/permission.js +0 -44
- package/dist/api/routes/plugin.js +0 -39
- package/dist/api/routes/public/applications.js +0 -174
- package/dist/api/routes/public/index.js +0 -140
- package/dist/api/routes/public/metrics.js +0 -30
- package/dist/api/routes/public/middleware/mapper.js +0 -97
- package/dist/api/routes/public/queries.js +0 -72
- package/dist/api/routes/public/rows.js +0 -158
- package/dist/api/routes/public/tables.js +0 -152
- package/dist/api/routes/public/users.js +0 -135
- package/dist/api/routes/public/utils/Endpoint.js +0 -36
- package/dist/api/routes/query.js +0 -47
- package/dist/api/routes/role.js +0 -40
- package/dist/api/routes/routing.js +0 -39
- package/dist/api/routes/row.js +0 -239
- package/dist/api/routes/screen.js +0 -39
- package/dist/api/routes/script.js +0 -35
- package/dist/api/routes/static.js +0 -80
- package/dist/api/routes/table.js +0 -163
- package/dist/api/routes/templates.js +0 -37
- package/dist/api/routes/user.js +0 -43
- package/dist/api/routes/utils/validators.js +0 -238
- package/dist/api/routes/view.js +0 -42
- package/dist/api/routes/webhook.js +0 -43
- package/dist/app.js +0 -132
- package/dist/automations/actions.js +0 -137
- package/dist/automations/automationUtils.js +0 -173
- package/dist/automations/bullboard.js +0 -71
- package/dist/automations/index.js +0 -43
- package/dist/automations/logging/index.js +0 -53
- package/dist/automations/steps/bash.js +0 -111
- package/dist/automations/steps/createRow.js +0 -108
- package/dist/automations/steps/delay.js +0 -53
- package/dist/automations/steps/deleteRow.js +0 -96
- package/dist/automations/steps/discord.js +0 -116
- package/dist/automations/steps/executeQuery.js +0 -134
- package/dist/automations/steps/executeScript.js +0 -106
- package/dist/automations/steps/filter.js +0 -112
- package/dist/automations/steps/loop.js +0 -54
- package/dist/automations/steps/make.js +0 -120
- package/dist/automations/steps/outgoingWebhook.js +0 -166
- package/dist/automations/steps/queryRows.js +0 -220
- package/dist/automations/steps/sendSmtpEmail.js +0 -115
- package/dist/automations/steps/serverLog.js +0 -65
- package/dist/automations/steps/slack.js +0 -98
- package/dist/automations/steps/updateRow.js +0 -144
- package/dist/automations/steps/utils.js +0 -56
- package/dist/automations/steps/zapier.js +0 -117
- package/dist/automations/triggerInfo/app.js +0 -36
- package/dist/automations/triggerInfo/cron.js +0 -35
- package/dist/automations/triggerInfo/index.js +0 -40
- package/dist/automations/triggerInfo/rowDeleted.js +0 -36
- package/dist/automations/triggerInfo/rowSaved.js +0 -44
- package/dist/automations/triggerInfo/rowUpdated.js +0 -44
- package/dist/automations/triggerInfo/webhook.js +0 -40
- package/dist/automations/triggers.js +0 -181
- package/dist/automations/utils.js +0 -275
- package/dist/constants/definitions.js +0 -2
- package/dist/constants/index.js +0 -181
- package/dist/constants/layouts.js +0 -148
- package/dist/constants/screens.js +0 -51
- package/dist/db/defaultData/datasource_bb_default.js +0 -574
- package/dist/db/defaultData/employeeImport.js +0 -155
- package/dist/db/defaultData/expensesImport.js +0 -117
- package/dist/db/defaultData/inventoryImport.js +0 -109
- package/dist/db/defaultData/jobsImport.js +0 -152
- package/dist/db/dynamoClient.js +0 -124
- package/dist/db/inMemoryView.js +0 -62
- package/dist/db/index.js +0 -43
- package/dist/db/linkedRows/LinkController.js +0 -392
- package/dist/db/linkedRows/LinkDocument.js +0 -33
- package/dist/db/linkedRows/index.js +0 -206
- package/dist/db/linkedRows/linkUtils.js +0 -131
- package/dist/db/newid.js +0 -7
- package/dist/db/utils.js +0 -248
- package/dist/db/views/staticViews.js +0 -144
- package/dist/ddApm.js +0 -11
- package/dist/definitions/automations.js +0 -8
- package/dist/definitions/common.js +0 -2
- package/dist/definitions/datasource.js +0 -7
- package/dist/definitions/openapi.js +0 -6
- package/dist/environment.js +0 -109
- package/dist/events/AutomationEmitter.js +0 -53
- package/dist/events/BudibaseEmitter.js +0 -25
- package/dist/events/docUpdates/index.js +0 -17
- package/dist/events/docUpdates/processors.js +0 -18
- package/dist/events/docUpdates/syncUsers.js +0 -49
- package/dist/events/index.js +0 -11
- package/dist/events/utils.js +0 -43
- package/dist/integrations/airtable.js +0 -147
- package/dist/integrations/arangodb.js +0 -103
- package/dist/integrations/base/query.js +0 -32
- package/dist/integrations/base/sql.js +0 -600
- package/dist/integrations/base/sqlTable.js +0 -167
- package/dist/integrations/base/types.js +0 -2
- package/dist/integrations/couchdb.js +0 -125
- package/dist/integrations/dynamodb.js +0 -194
- package/dist/integrations/elasticsearch.js +0 -186
- package/dist/integrations/firebase.js +0 -174
- package/dist/integrations/googlesheets.js +0 -455
- package/dist/integrations/index.js +0 -135
- package/dist/integrations/microsoftSqlServer.js +0 -273
- package/dist/integrations/mongodb.js +0 -614
- package/dist/integrations/mysql.js +0 -256
- package/dist/integrations/oracle.js +0 -375
- package/dist/integrations/postgres.js +0 -300
- package/dist/integrations/queries/sql.js +0 -84
- package/dist/integrations/redis.js +0 -168
- package/dist/integrations/rest.js +0 -400
- package/dist/integrations/s3.js +0 -237
- package/dist/integrations/snowflake.js +0 -102
- package/dist/integrations/utils.js +0 -295
- package/dist/middleware/appInfo.js +0 -22
- package/dist/middleware/authorized.js +0 -112
- package/dist/middleware/builder.js +0 -93
- package/dist/middleware/currentapp.js +0 -103
- package/dist/middleware/joi-validator.js +0 -43
- package/dist/middleware/publicApi.js +0 -25
- package/dist/middleware/resourceId.js +0 -59
- package/dist/middleware/selfhost.js +0 -24
- package/dist/middleware/utils.js +0 -8
- package/dist/migrations/functions/appUrls.js +0 -42
- package/dist/migrations/functions/backfill/app/automations.js +0 -31
- package/dist/migrations/functions/backfill/app/datasources.js +0 -28
- package/dist/migrations/functions/backfill/app/layouts.js +0 -33
- package/dist/migrations/functions/backfill/app/queries.js +0 -50
- package/dist/migrations/functions/backfill/app/roles.js +0 -28
- package/dist/migrations/functions/backfill/app/screens.js +0 -28
- package/dist/migrations/functions/backfill/app/tables.js +0 -37
- package/dist/migrations/functions/backfill/app.js +0 -176
- package/dist/migrations/functions/backfill/global/configs.js +0 -67
- package/dist/migrations/functions/backfill/global/quotas.js +0 -60
- package/dist/migrations/functions/backfill/global/users.js +0 -50
- package/dist/migrations/functions/backfill/global.js +0 -205
- package/dist/migrations/functions/backfill/index.js +0 -32
- package/dist/migrations/functions/backfill/installation.js +0 -80
- package/dist/migrations/functions/syncQuotas.js +0 -52
- package/dist/migrations/functions/tableSettings.js +0 -130
- package/dist/migrations/functions/usageQuotas/index.js +0 -16
- package/dist/migrations/functions/usageQuotas/syncApps.js +0 -24
- package/dist/migrations/functions/usageQuotas/syncPlugins.js +0 -23
- package/dist/migrations/functions/usageQuotas/syncRows.js +0 -33
- package/dist/migrations/functions/usageQuotas/syncUsers.js +0 -21
- package/dist/migrations/functions/userEmailViewCasing.js +0 -24
- package/dist/migrations/index.js +0 -111
- package/dist/migrations/tests/helpers.js +0 -72
- package/dist/migrations/tests/structures.js +0 -37
- package/dist/sdk/app/applications/index.js +0 -28
- package/dist/sdk/app/applications/sync.js +0 -164
- package/dist/sdk/app/applications/utils.js +0 -21
- package/dist/sdk/app/automations/index.js +0 -29
- package/dist/sdk/app/automations/webhook.js +0 -54
- package/dist/sdk/app/backups/constants.js +0 -6
- package/dist/sdk/app/backups/exports.js +0 -160
- package/dist/sdk/app/backups/imports.js +0 -170
- package/dist/sdk/app/backups/index.js +0 -29
- package/dist/sdk/app/backups/statistics.js +0 -73
- package/dist/sdk/app/datasources/datasources.js +0 -166
- package/dist/sdk/app/datasources/index.js +0 -27
- package/dist/sdk/app/queries/index.js +0 -27
- package/dist/sdk/app/queries/queries.js +0 -60
- package/dist/sdk/app/rows/attachments.js +0 -61
- package/dist/sdk/app/rows/index.js +0 -28
- package/dist/sdk/app/rows/rows.js +0 -30
- package/dist/sdk/app/tables/index.js +0 -65
- package/dist/sdk/index.js +0 -27
- package/dist/sdk/plugins/index.js +0 -27
- package/dist/sdk/plugins/plugins.js +0 -53
- package/dist/sdk/users/index.js +0 -27
- package/dist/sdk/users/utils.js +0 -94
- package/dist/sdk/utils/index.js +0 -29
- package/dist/startup.js +0 -158
- package/dist/threads/automation.js +0 -450
- package/dist/threads/definitions.js +0 -2
- package/dist/threads/index.js +0 -140
- package/dist/threads/query.js +0 -265
- package/dist/threads/utils.js +0 -120
- package/dist/tsconfig.build.tsbuildinfo +0 -1
- package/dist/utilities/appDirectoryTemplate/package.json +0 -10
- package/dist/utilities/budibaseDir.js +0 -5
- package/dist/utilities/centralPath.js +0 -27
- package/dist/utilities/csv.js +0 -33
- package/dist/utilities/fileSystem/app.js +0 -88
- package/dist/utilities/fileSystem/clientLibrary.js +0 -138
- package/dist/utilities/fileSystem/filesystem.js +0 -180
- package/dist/utilities/fileSystem/index.js +0 -21
- package/dist/utilities/fileSystem/plugin.js +0 -76
- package/dist/utilities/fileSystem/processor.js +0 -34
- package/dist/utilities/fileSystem/template.js +0 -47
- package/dist/utilities/global.js +0 -146
- package/dist/utilities/index.js +0 -143
- package/dist/utilities/redis.js +0 -117
- package/dist/utilities/retry.js +0 -30
- package/dist/utilities/routing/index.js +0 -39
- package/dist/utilities/rowProcessor/index.js +0 -282
- package/dist/utilities/rowProcessor/map.js +0 -116
- package/dist/utilities/rowProcessor/utils.js +0 -87
- package/dist/utilities/schema.js +0 -112
- package/dist/utilities/scriptRunner.js +0 -26
- package/dist/utilities/security.js +0 -57
- package/dist/utilities/statusCodes.js +0 -9
- package/dist/utilities/usageQuota/rows.js +0 -88
- package/dist/utilities/usageQuota/usageQuoteReset.js +0 -16
- package/dist/utilities/users.js +0 -57
- package/dist/utilities/workerRequests.js +0 -171
- package/dist/watch.js +0 -53
- package/dist/websockets/client.js +0 -14
- package/dist/websockets/grid.js +0 -60
- package/dist/websockets/index.js +0 -17
- package/dist/websockets/websocket.js +0 -78
- package/src/automations/tests/zapier.spec.js +0 -27
- /package/dist/{api/controllers/static/templates/BudibaseApp.svelte → BudibaseApp-Y5NZEDTC.svelte} +0 -0
- /package/dist/{api/controllers/static/templates/app.hbs → app.hbs} +0 -0
- /package/dist/{api/controllers/static/templates/preview.hbs → preview.hbs} +0 -0
package/src/utilities/redis.ts
CHANGED
|
@@ -1,12 +1,19 @@
|
|
|
1
|
-
import { redis } from "@budibase/backend-core"
|
|
1
|
+
import { redis, RedisClient } from "@budibase/backend-core"
|
|
2
2
|
import { getGlobalIDFromUserMetadataID } from "../db/utils"
|
|
3
3
|
import { ContextUser } from "@budibase/types"
|
|
4
|
+
import env from "../environment"
|
|
4
5
|
|
|
5
6
|
const APP_DEV_LOCK_SECONDS = 600
|
|
6
7
|
const AUTOMATION_TEST_FLAG_SECONDS = 60
|
|
7
|
-
let devAppClient:
|
|
8
|
+
let devAppClient: RedisClient,
|
|
9
|
+
debounceClient: RedisClient,
|
|
10
|
+
flagClient: RedisClient
|
|
8
11
|
|
|
9
|
-
//
|
|
12
|
+
// We need to maintain a duplicate client for socket.io pub/sub
|
|
13
|
+
let socketClient: RedisClient
|
|
14
|
+
let socketSubClient: any
|
|
15
|
+
|
|
16
|
+
// We init this as we want to keep the connection open all the time
|
|
10
17
|
// reduces the performance hit
|
|
11
18
|
export async function init() {
|
|
12
19
|
devAppClient = new redis.Client(redis.utils.Databases.DEV_LOCKS)
|
|
@@ -15,12 +22,20 @@ export async function init() {
|
|
|
15
22
|
await devAppClient.init()
|
|
16
23
|
await debounceClient.init()
|
|
17
24
|
await flagClient.init()
|
|
25
|
+
|
|
26
|
+
// Duplicate the socket client for pub/sub
|
|
27
|
+
socketClient = await redis.clients.getSocketClient()
|
|
28
|
+
if (!env.isTest()) {
|
|
29
|
+
socketSubClient = socketClient.getClient().duplicate()
|
|
30
|
+
}
|
|
18
31
|
}
|
|
19
32
|
|
|
20
33
|
export async function shutdown() {
|
|
34
|
+
console.log("REDIS SHUTDOWN")
|
|
21
35
|
if (devAppClient) await devAppClient.finish()
|
|
22
36
|
if (debounceClient) await debounceClient.finish()
|
|
23
37
|
if (flagClient) await flagClient.finish()
|
|
38
|
+
if (socketSubClient) socketSubClient.disconnect()
|
|
24
39
|
// shutdown core clients
|
|
25
40
|
await redis.clients.shutdown()
|
|
26
41
|
console.log("Redis shutdown")
|
|
@@ -86,3 +101,10 @@ export async function checkTestFlag(id: string) {
|
|
|
86
101
|
export async function clearTestFlag(id: string) {
|
|
87
102
|
await devAppClient.delete(id)
|
|
88
103
|
}
|
|
104
|
+
|
|
105
|
+
export function getSocketPubSubClients() {
|
|
106
|
+
return {
|
|
107
|
+
pub: socketClient.getClient(),
|
|
108
|
+
sub: socketSubClient,
|
|
109
|
+
}
|
|
110
|
+
}
|
|
@@ -216,7 +216,10 @@ export async function outputProcessing(
|
|
|
216
216
|
}
|
|
217
217
|
}
|
|
218
218
|
if (opts.squash) {
|
|
219
|
-
enriched = await linkRows.squashLinksToPrimaryDisplay(
|
|
219
|
+
enriched = (await linkRows.squashLinksToPrimaryDisplay(
|
|
220
|
+
table,
|
|
221
|
+
enriched
|
|
222
|
+
)) as Row[]
|
|
220
223
|
}
|
|
221
224
|
return wasArray ? enriched : enriched[0]
|
|
222
225
|
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import authorized from "../middleware/authorized"
|
|
2
|
+
import { BaseSocket } from "./websocket"
|
|
3
|
+
import { permissions } from "@budibase/backend-core"
|
|
4
|
+
import http from "http"
|
|
5
|
+
import Koa from "koa"
|
|
6
|
+
import { Datasource, Table, SocketSession, ContextUser } from "@budibase/types"
|
|
7
|
+
import { gridSocket } from "./index"
|
|
8
|
+
import { clearLock, updateLock } from "../utilities/redis"
|
|
9
|
+
import { Socket } from "socket.io"
|
|
10
|
+
import { BuilderSocketEvent } from "@budibase/shared-core"
|
|
11
|
+
|
|
12
|
+
export default class BuilderSocket extends BaseSocket {
|
|
13
|
+
constructor(app: Koa, server: http.Server) {
|
|
14
|
+
super(app, server, "/socket/builder", [authorized(permissions.BUILDER)])
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
async onConnect(socket?: Socket) {
|
|
18
|
+
// Initial identification of selected app
|
|
19
|
+
socket?.on(BuilderSocketEvent.SelectApp, async ({ appId }, callback) => {
|
|
20
|
+
await this.joinRoom(socket, appId)
|
|
21
|
+
|
|
22
|
+
// Reply with all users in current room
|
|
23
|
+
const sessions = await this.getRoomSessions(appId)
|
|
24
|
+
callback({ users: sessions })
|
|
25
|
+
})
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
async onDisconnect(socket: Socket) {
|
|
29
|
+
// Remove app lock from this user if they have no other connections,
|
|
30
|
+
// and transfer it to someone else if possible
|
|
31
|
+
try {
|
|
32
|
+
// @ts-ignore
|
|
33
|
+
const session: SocketSession = socket.data
|
|
34
|
+
const { _id, sessionId, room } = session
|
|
35
|
+
const sessions = await this.getRoomSessions(room)
|
|
36
|
+
const hasOtherSession = sessions.some(otherSession => {
|
|
37
|
+
return _id === otherSession._id && sessionId !== otherSession.sessionId
|
|
38
|
+
})
|
|
39
|
+
if (!hasOtherSession && room) {
|
|
40
|
+
// Clear the lock from this user since they had no other sessions
|
|
41
|
+
// @ts-ignore
|
|
42
|
+
const user: ContextUser = { _id: socket.data._id }
|
|
43
|
+
await clearLock(room, user)
|
|
44
|
+
|
|
45
|
+
// Transfer lock ownership to the next oldest user
|
|
46
|
+
let otherSessions = sessions.filter(x => x._id !== _id).slice()
|
|
47
|
+
otherSessions.sort((a, b) => {
|
|
48
|
+
return a.connectedAt < b.connectedAt ? -1 : 1
|
|
49
|
+
})
|
|
50
|
+
const nextSession = otherSessions[0]
|
|
51
|
+
if (nextSession) {
|
|
52
|
+
const { _id, email, firstName, lastName } = nextSession
|
|
53
|
+
// @ts-ignore
|
|
54
|
+
const nextUser: ContextUser = { _id, email, firstName, lastName }
|
|
55
|
+
await updateLock(room, nextUser)
|
|
56
|
+
this.io.to(room).emit(BuilderSocketEvent.LockTransfer, {
|
|
57
|
+
userId: _id,
|
|
58
|
+
})
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
} catch (e) {
|
|
62
|
+
// This is fine, just means this user didn't hold the lock
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
emitTableUpdate(ctx: any, table: Table) {
|
|
67
|
+
this.emitToRoom(ctx, ctx.appId, BuilderSocketEvent.TableChange, {
|
|
68
|
+
id: table._id,
|
|
69
|
+
table,
|
|
70
|
+
})
|
|
71
|
+
gridSocket?.emitTableUpdate(ctx, table)
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
emitTableDeletion(ctx: any, id: string) {
|
|
75
|
+
this.emitToRoom(ctx, ctx.appId, BuilderSocketEvent.TableChange, {
|
|
76
|
+
id,
|
|
77
|
+
table: null,
|
|
78
|
+
})
|
|
79
|
+
gridSocket?.emitTableDeletion(ctx, id)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
emitDatasourceUpdate(ctx: any, datasource: Datasource) {
|
|
83
|
+
this.emitToRoom(ctx, ctx.appId, BuilderSocketEvent.DatasourceChange, {
|
|
84
|
+
id: datasource._id,
|
|
85
|
+
datasource,
|
|
86
|
+
})
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
emitDatasourceDeletion(ctx: any, id: string) {
|
|
90
|
+
this.emitToRoom(ctx, ctx.appId, BuilderSocketEvent.DatasourceChange, {
|
|
91
|
+
id,
|
|
92
|
+
datasource: null,
|
|
93
|
+
})
|
|
94
|
+
}
|
|
95
|
+
}
|
package/src/websockets/client.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { BaseSocket } from "./websocket"
|
|
2
2
|
import authorized from "../middleware/authorized"
|
|
3
3
|
import http from "http"
|
|
4
4
|
import Koa from "koa"
|
|
5
5
|
import { permissions } from "@budibase/backend-core"
|
|
6
6
|
|
|
7
|
-
export default class ClientAppWebsocket extends
|
|
7
|
+
export default class ClientAppWebsocket extends BaseSocket {
|
|
8
8
|
constructor(app: Koa, server: http.Server) {
|
|
9
9
|
super(app, server, "/socket/client", [authorized(permissions.BUILDER)])
|
|
10
10
|
}
|
package/src/websockets/grid.ts
CHANGED
|
@@ -1,55 +1,55 @@
|
|
|
1
1
|
import authorized from "../middleware/authorized"
|
|
2
|
-
import
|
|
2
|
+
import { BaseSocket } from "./websocket"
|
|
3
3
|
import { permissions } from "@budibase/backend-core"
|
|
4
4
|
import http from "http"
|
|
5
5
|
import Koa from "koa"
|
|
6
|
+
import { getTableId } from "../api/controllers/row/utils"
|
|
7
|
+
import { Row, Table } from "@budibase/types"
|
|
8
|
+
import { Socket } from "socket.io"
|
|
9
|
+
import { GridSocketEvent } from "@budibase/shared-core"
|
|
6
10
|
|
|
7
|
-
export default class GridSocket extends
|
|
11
|
+
export default class GridSocket extends BaseSocket {
|
|
8
12
|
constructor(app: Koa, server: http.Server) {
|
|
9
13
|
super(app, server, "/socket/grid", [authorized(permissions.BUILDER)])
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
async onConnect(socket: Socket) {
|
|
17
|
+
// Initial identification of connected spreadsheet
|
|
18
|
+
socket.on(GridSocketEvent.SelectTable, async ({ tableId }, callback) => {
|
|
19
|
+
await this.joinRoom(socket, tableId)
|
|
20
|
+
|
|
21
|
+
// Reply with all users in current room
|
|
22
|
+
const sessions = await this.getRoomSessions(tableId)
|
|
23
|
+
callback({ users: sessions })
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
// Handle users selecting a new cell
|
|
27
|
+
socket.on(GridSocketEvent.SelectCell, ({ cellId }) => {
|
|
28
|
+
this.updateUser(socket, { focusedCellId: cellId })
|
|
29
|
+
})
|
|
30
|
+
}
|
|
10
31
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
let currentRoom: string
|
|
17
|
-
|
|
18
|
-
// Initial identification of connected spreadsheet
|
|
19
|
-
socket.on("select-table", async (tableId, callback) => {
|
|
20
|
-
// Leave current room
|
|
21
|
-
if (currentRoom) {
|
|
22
|
-
socket.to(currentRoom).emit("user-disconnect", socket.data.user)
|
|
23
|
-
socket.leave(currentRoom)
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
// Join new room
|
|
27
|
-
currentRoom = tableId
|
|
28
|
-
socket.join(currentRoom)
|
|
29
|
-
socket.to(currentRoom).emit("user-update", socket.data.user)
|
|
30
|
-
|
|
31
|
-
// Reply with all users in current room
|
|
32
|
-
const sockets = await this.io.in(currentRoom).fetchSockets()
|
|
33
|
-
callback({
|
|
34
|
-
users: sockets.map(socket => socket.data.user),
|
|
35
|
-
id: user.id,
|
|
36
|
-
})
|
|
37
|
-
})
|
|
38
|
-
|
|
39
|
-
// Handle users selecting a new cell
|
|
40
|
-
socket.on("select-cell", cellId => {
|
|
41
|
-
socket.data.user.selectedCellId = cellId
|
|
42
|
-
if (currentRoom) {
|
|
43
|
-
socket.to(currentRoom).emit("user-update", socket.data.user)
|
|
44
|
-
}
|
|
45
|
-
})
|
|
46
|
-
|
|
47
|
-
// Disconnection cleanup
|
|
48
|
-
socket.on("disconnect", () => {
|
|
49
|
-
if (currentRoom) {
|
|
50
|
-
socket.to(currentRoom).emit("user-disconnect", socket.data.user)
|
|
51
|
-
}
|
|
52
|
-
})
|
|
32
|
+
emitRowUpdate(ctx: any, row: Row) {
|
|
33
|
+
const tableId = getTableId(ctx)
|
|
34
|
+
this.emitToRoom(ctx, tableId, GridSocketEvent.RowChange, {
|
|
35
|
+
id: row._id,
|
|
36
|
+
row,
|
|
53
37
|
})
|
|
54
38
|
}
|
|
39
|
+
|
|
40
|
+
emitRowDeletion(ctx: any, id: string) {
|
|
41
|
+
const tableId = getTableId(ctx)
|
|
42
|
+
this.emitToRoom(ctx, tableId, GridSocketEvent.RowChange, { id, row: null })
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
emitTableUpdate(ctx: any, table: Table) {
|
|
46
|
+
this.emitToRoom(ctx, table._id!, GridSocketEvent.TableChange, {
|
|
47
|
+
id: table._id,
|
|
48
|
+
table,
|
|
49
|
+
})
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
emitTableDeletion(ctx: any, id: string) {
|
|
53
|
+
this.emitToRoom(ctx, id, GridSocketEvent.TableChange, { id, table: null })
|
|
54
|
+
}
|
|
55
55
|
}
|
package/src/websockets/index.ts
CHANGED
|
@@ -1,14 +1,21 @@
|
|
|
1
1
|
import http from "http"
|
|
2
2
|
import Koa from "koa"
|
|
3
|
-
import GridSocket from "./grid"
|
|
4
3
|
import ClientAppSocket from "./client"
|
|
4
|
+
import GridSocket from "./grid"
|
|
5
|
+
import BuilderSocket from "./builder"
|
|
6
|
+
import env from "../environment"
|
|
5
7
|
|
|
6
|
-
let clientAppSocket: ClientAppSocket
|
|
7
|
-
let gridSocket: GridSocket
|
|
8
|
+
let clientAppSocket: ClientAppSocket | undefined
|
|
9
|
+
let gridSocket: GridSocket | undefined
|
|
10
|
+
let builderSocket: BuilderSocket | undefined
|
|
8
11
|
|
|
9
12
|
export const initialise = (app: Koa, server: http.Server) => {
|
|
10
|
-
|
|
11
|
-
|
|
13
|
+
// have to remove these for testing until ioredis-mock can be fully removed
|
|
14
|
+
if (!env.isTest()) {
|
|
15
|
+
clientAppSocket = new ClientAppSocket(app, server)
|
|
16
|
+
gridSocket = new GridSocket(app, server)
|
|
17
|
+
builderSocket = new BuilderSocket(app, server)
|
|
18
|
+
}
|
|
12
19
|
}
|
|
13
20
|
|
|
14
|
-
export { clientAppSocket, gridSocket }
|
|
21
|
+
export { clientAppSocket, gridSocket, builderSocket }
|
|
@@ -3,18 +3,26 @@ import http from "http"
|
|
|
3
3
|
import Koa from "koa"
|
|
4
4
|
import Cookies from "cookies"
|
|
5
5
|
import { userAgent } from "koa-useragent"
|
|
6
|
-
import { auth } from "@budibase/backend-core"
|
|
6
|
+
import { auth, Header, redis } from "@budibase/backend-core"
|
|
7
7
|
import currentApp from "../middleware/currentapp"
|
|
8
|
+
import { createAdapter } from "@socket.io/redis-adapter"
|
|
9
|
+
import { Socket } from "socket.io"
|
|
10
|
+
import { getSocketPubSubClients } from "../utilities/redis"
|
|
11
|
+
import { SocketEvent, SocketSessionTTL } from "@budibase/shared-core"
|
|
12
|
+
import { SocketSession } from "@budibase/types"
|
|
8
13
|
|
|
9
|
-
export
|
|
14
|
+
export class BaseSocket {
|
|
10
15
|
io: Server
|
|
16
|
+
path: string
|
|
17
|
+
redisClient?: redis.Client
|
|
11
18
|
|
|
12
19
|
constructor(
|
|
13
20
|
app: Koa,
|
|
14
21
|
server: http.Server,
|
|
15
|
-
path: string,
|
|
22
|
+
path: string = "/",
|
|
16
23
|
additionalMiddlewares?: any[]
|
|
17
24
|
) {
|
|
25
|
+
this.path = path
|
|
18
26
|
this.io = new Server(server, {
|
|
19
27
|
path,
|
|
20
28
|
})
|
|
@@ -59,12 +67,17 @@ export default class Socket {
|
|
|
59
67
|
for (let [idx, middleware] of middlewares.entries()) {
|
|
60
68
|
await middleware(ctx, () => {
|
|
61
69
|
if (idx === middlewares.length - 1) {
|
|
62
|
-
// Middlewares are finished
|
|
70
|
+
// Middlewares are finished
|
|
63
71
|
// Extract some data from our enriched koa context to persist
|
|
64
72
|
// as metadata for the socket
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
73
|
+
const { _id, email, firstName, lastName } = ctx.user
|
|
74
|
+
socket.data = {
|
|
75
|
+
_id,
|
|
76
|
+
email,
|
|
77
|
+
firstName,
|
|
78
|
+
lastName,
|
|
79
|
+
sessionId: socket.id,
|
|
80
|
+
connectedAt: Date.now(),
|
|
68
81
|
}
|
|
69
82
|
next()
|
|
70
83
|
}
|
|
@@ -74,10 +87,201 @@ export default class Socket {
|
|
|
74
87
|
next(error)
|
|
75
88
|
}
|
|
76
89
|
})
|
|
90
|
+
|
|
91
|
+
// Initialise redis before handling connections
|
|
92
|
+
this.initialise().then(() => {
|
|
93
|
+
this.io.on("connection", async socket => {
|
|
94
|
+
// Add built in handler for heartbeats
|
|
95
|
+
socket.on(SocketEvent.Heartbeat, async () => {
|
|
96
|
+
await this.extendSessionTTL(socket.data.sessionId)
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
// Add early disconnection handler to clean up and leave room
|
|
100
|
+
socket.on("disconnect", async () => {
|
|
101
|
+
// Run any custom disconnection logic before we leave the room,
|
|
102
|
+
// so that we have access to their room etc before disconnection
|
|
103
|
+
await this.onDisconnect(socket)
|
|
104
|
+
|
|
105
|
+
// Leave the current room when the user disconnects if we're in one
|
|
106
|
+
await this.leaveRoom(socket)
|
|
107
|
+
})
|
|
108
|
+
|
|
109
|
+
// Add handlers for this socket
|
|
110
|
+
await this.onConnect(socket)
|
|
111
|
+
})
|
|
112
|
+
})
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
async initialise() {
|
|
116
|
+
// Instantiate redis adapter.
|
|
117
|
+
// We use a fully qualified key name here as this bypasses the normal
|
|
118
|
+
// redis client#s key prefixing.
|
|
119
|
+
const { pub, sub } = getSocketPubSubClients()
|
|
120
|
+
const opts = {
|
|
121
|
+
key: `${redis.utils.Databases.SOCKET_IO}-${this.path}-pubsub`,
|
|
122
|
+
}
|
|
123
|
+
this.io.adapter(createAdapter(pub, sub, opts))
|
|
124
|
+
|
|
125
|
+
// Fetch redis client
|
|
126
|
+
this.redisClient = await redis.clients.getSocketClient()
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Gets the redis key for a certain session ID
|
|
130
|
+
getSessionKey(sessionId: string) {
|
|
131
|
+
return `${this.path}-session:${sessionId}`
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Gets the redis key for certain room name
|
|
135
|
+
getRoomKey(room: string) {
|
|
136
|
+
return `${this.path}-room:${room}`
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
async extendSessionTTL(sessionId: string) {
|
|
140
|
+
const key = this.getSessionKey(sessionId)
|
|
141
|
+
await this.redisClient?.setExpiry(key, SocketSessionTTL)
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Gets an array of all redis keys of users inside a certain room
|
|
145
|
+
async getRoomSessionIds(room: string): Promise<string[]> {
|
|
146
|
+
const keys = await this.redisClient?.get(this.getRoomKey(room))
|
|
147
|
+
return keys || []
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// Sets the list of redis keys for users inside a certain room.
|
|
151
|
+
// There is no TTL on the actual room key map itself.
|
|
152
|
+
async setRoomSessionIds(room: string, ids: string[]) {
|
|
153
|
+
await this.redisClient?.store(this.getRoomKey(room), ids)
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// Gets a list of all users inside a certain room
|
|
157
|
+
async getRoomSessions(room?: string): Promise<SocketSession[]> {
|
|
158
|
+
if (room) {
|
|
159
|
+
const sessionIds = await this.getRoomSessionIds(room)
|
|
160
|
+
const keys = sessionIds.map(this.getSessionKey.bind(this))
|
|
161
|
+
const sessions = await this.redisClient?.bulkGet(keys)
|
|
162
|
+
return Object.values(sessions || {})
|
|
163
|
+
} else {
|
|
164
|
+
return []
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Detects keys which have been pruned from redis due to TTL expiry in a certain
|
|
169
|
+
// room and broadcasts disconnection messages to ensure clients are aware
|
|
170
|
+
async pruneRoom(room: string) {
|
|
171
|
+
const sessionIds = await this.getRoomSessionIds(room)
|
|
172
|
+
const sessionsExist = await Promise.all(
|
|
173
|
+
sessionIds.map(id => this.redisClient?.exists(this.getSessionKey(id)))
|
|
174
|
+
)
|
|
175
|
+
const prunedSessionIds = sessionIds.filter((id, idx) => {
|
|
176
|
+
if (!sessionsExist[idx]) {
|
|
177
|
+
this.io.to(room).emit(SocketEvent.UserDisconnect, {
|
|
178
|
+
sessionId: sessionIds[idx],
|
|
179
|
+
})
|
|
180
|
+
return false
|
|
181
|
+
}
|
|
182
|
+
return true
|
|
183
|
+
})
|
|
184
|
+
|
|
185
|
+
// Store new pruned keys
|
|
186
|
+
await this.setRoomSessionIds(room, prunedSessionIds)
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// Adds a user to a certain room
|
|
190
|
+
async joinRoom(socket: Socket, room: string) {
|
|
191
|
+
if (!room) {
|
|
192
|
+
return
|
|
193
|
+
}
|
|
194
|
+
// Prune room before joining
|
|
195
|
+
await this.pruneRoom(room)
|
|
196
|
+
|
|
197
|
+
// Check if we're already in a room, as we'll need to leave if we are before we
|
|
198
|
+
// can join a different room
|
|
199
|
+
const oldRoom = socket.data.room
|
|
200
|
+
if (oldRoom && oldRoom !== room) {
|
|
201
|
+
await this.leaveRoom(socket)
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// Join new room
|
|
205
|
+
if (!oldRoom || oldRoom !== room) {
|
|
206
|
+
socket.join(room)
|
|
207
|
+
socket.data.room = room
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// Store in redis
|
|
211
|
+
// @ts-ignore
|
|
212
|
+
let user: SocketSession = socket.data
|
|
213
|
+
const { sessionId } = user
|
|
214
|
+
const key = this.getSessionKey(sessionId)
|
|
215
|
+
await this.redisClient?.store(key, user, SocketSessionTTL)
|
|
216
|
+
const sessionIds = await this.getRoomSessionIds(room)
|
|
217
|
+
if (!sessionIds.includes(sessionId)) {
|
|
218
|
+
await this.setRoomSessionIds(room, [...sessionIds, sessionId])
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// Notify other users
|
|
222
|
+
socket.to(room).emit(SocketEvent.UserUpdate, {
|
|
223
|
+
user,
|
|
224
|
+
})
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
// Disconnects a socket from its current room
|
|
228
|
+
async leaveRoom(socket: Socket) {
|
|
229
|
+
// @ts-ignore
|
|
230
|
+
let user: SocketSession = socket.data
|
|
231
|
+
const { room, sessionId } = user
|
|
232
|
+
if (!room) {
|
|
233
|
+
return
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// Leave room
|
|
237
|
+
socket.leave(room)
|
|
238
|
+
socket.data.room = undefined
|
|
239
|
+
|
|
240
|
+
// Delete from redis
|
|
241
|
+
const key = this.getSessionKey(sessionId)
|
|
242
|
+
await this.redisClient?.delete(key)
|
|
243
|
+
const sessionIds = await this.getRoomSessionIds(room)
|
|
244
|
+
await this.setRoomSessionIds(
|
|
245
|
+
room,
|
|
246
|
+
sessionIds.filter(id => id !== sessionId)
|
|
247
|
+
)
|
|
248
|
+
|
|
249
|
+
// Notify other users
|
|
250
|
+
socket.to(room).emit(SocketEvent.UserDisconnect, { sessionId })
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
// Updates a connected user's metadata, assuming a room change is not required.
|
|
254
|
+
async updateUser(socket: Socket, patch: Object) {
|
|
255
|
+
socket.data = {
|
|
256
|
+
...socket.data,
|
|
257
|
+
...patch,
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// If we're in a room, notify others of this change and update redis
|
|
261
|
+
if (socket.data.room) {
|
|
262
|
+
await this.joinRoom(socket, socket.data.room)
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
async onConnect(socket: Socket) {
|
|
267
|
+
// Override
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
async onDisconnect(socket: Socket) {
|
|
271
|
+
// Override
|
|
77
272
|
}
|
|
78
273
|
|
|
79
274
|
// Emit an event to all sockets
|
|
80
275
|
emit(event: string, payload: any) {
|
|
81
276
|
this.io.sockets.emit(event, payload)
|
|
82
277
|
}
|
|
278
|
+
|
|
279
|
+
// Emit an event to everyone in a room, including metadata of whom
|
|
280
|
+
// the originator of the request was
|
|
281
|
+
emitToRoom(ctx: any, room: string, event: string, payload: any) {
|
|
282
|
+
this.io.in(room).emit(event, {
|
|
283
|
+
...payload,
|
|
284
|
+
apiSessionId: ctx.headers?.[Header.SESSION_ID],
|
|
285
|
+
})
|
|
286
|
+
}
|
|
83
287
|
}
|
package/tsconfig.build.json
CHANGED
|
@@ -10,7 +10,15 @@
|
|
|
10
10
|
"incremental": true,
|
|
11
11
|
"types": ["node", "jest"],
|
|
12
12
|
"outDir": "dist/src",
|
|
13
|
-
"skipLibCheck": true
|
|
13
|
+
"skipLibCheck": true,
|
|
14
|
+
"baseUrl": ".",
|
|
15
|
+
"paths": {
|
|
16
|
+
"@budibase/types": ["../types/src"],
|
|
17
|
+
"@budibase/backend-core": ["../backend-core/src"],
|
|
18
|
+
"@budibase/backend-core/*": ["../backend-core/*"],
|
|
19
|
+
"@budibase/shared-core": ["../shared-core/src"],
|
|
20
|
+
"@budibase/pro": ["../pro/packages/pro/src"]
|
|
21
|
+
}
|
|
14
22
|
},
|
|
15
23
|
"include": ["src/**/*"],
|
|
16
24
|
"exclude": [
|
package/tsconfig.json
CHANGED
|
@@ -5,25 +5,12 @@
|
|
|
5
5
|
"declaration": true,
|
|
6
6
|
"sourceMap": true,
|
|
7
7
|
"baseUrl": ".",
|
|
8
|
-
"outDir": "dist"
|
|
9
|
-
"paths": {
|
|
10
|
-
"@budibase/types": ["../types/src"],
|
|
11
|
-
"@budibase/backend-core": ["../backend-core/src"],
|
|
12
|
-
"@budibase/backend-core/*": ["../backend-core/*"],
|
|
13
|
-
"@budibase/shared-core": ["../shared-core/src"],
|
|
14
|
-
"@budibase/pro": ["../../../budibase-pro/packages/pro/src"]
|
|
15
|
-
}
|
|
8
|
+
"outDir": "dist"
|
|
16
9
|
},
|
|
17
10
|
"ts-node": {
|
|
18
11
|
"require": ["tsconfig-paths/register"],
|
|
19
12
|
"swc": true
|
|
20
13
|
},
|
|
21
|
-
"references": [
|
|
22
|
-
{ "path": "../types" },
|
|
23
|
-
{ "path": "../backend-core" },
|
|
24
|
-
{ "path": "../shared-core" },
|
|
25
|
-
{ "path": "../../../budibase-pro/packages/pro" }
|
|
26
|
-
],
|
|
27
14
|
"include": ["src/**/*", "specs"],
|
|
28
15
|
"exclude": ["node_modules", "dist"]
|
|
29
16
|
}
|