@backstage/backend-defaults 0.5.1-next.1 → 0.5.1-next.2

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 (248) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/auth/package.json +1 -1
  3. package/cache/package.json +1 -1
  4. package/database/package.json +1 -1
  5. package/discovery/package.json +1 -1
  6. package/dist/CreateBackend.cjs.js +49 -0
  7. package/dist/CreateBackend.cjs.js.map +1 -0
  8. package/dist/PackageDiscoveryService.cjs.js +109 -0
  9. package/dist/PackageDiscoveryService.cjs.js.map +1 -0
  10. package/dist/auth.cjs.js +2 -996
  11. package/dist/auth.cjs.js.map +1 -1
  12. package/dist/cache.cjs.js +4 -204
  13. package/dist/cache.cjs.js.map +1 -1
  14. package/dist/database.cjs.js +4 -957
  15. package/dist/database.cjs.js.map +1 -1
  16. package/dist/database.d.ts +4 -1
  17. package/dist/discovery.cjs.js +4 -92
  18. package/dist/discovery.cjs.js.map +1 -1
  19. package/dist/discoveryFeatureLoader.cjs.js +19 -0
  20. package/dist/discoveryFeatureLoader.cjs.js.map +1 -0
  21. package/dist/entrypoints/auth/DefaultAuthService.cjs.js +130 -0
  22. package/dist/entrypoints/auth/DefaultAuthService.cjs.js.map +1 -0
  23. package/dist/entrypoints/auth/JwksClient.cjs.js +49 -0
  24. package/dist/entrypoints/auth/JwksClient.cjs.js.map +1 -0
  25. package/dist/entrypoints/auth/authServiceFactory.cjs.js +57 -0
  26. package/dist/entrypoints/auth/authServiceFactory.cjs.js.map +1 -0
  27. package/dist/entrypoints/auth/external/ExternalTokenHandler.cjs.js +78 -0
  28. package/dist/entrypoints/auth/external/ExternalTokenHandler.cjs.js.map +1 -0
  29. package/dist/entrypoints/auth/external/helpers.cjs.js +92 -0
  30. package/dist/entrypoints/auth/external/helpers.cjs.js.map +1 -0
  31. package/dist/entrypoints/auth/external/jwks.cjs.js +63 -0
  32. package/dist/entrypoints/auth/external/jwks.cjs.js.map +1 -0
  33. package/dist/entrypoints/auth/external/legacy.cjs.js +73 -0
  34. package/dist/entrypoints/auth/external/legacy.cjs.js.map +1 -0
  35. package/dist/entrypoints/auth/external/static.cjs.js +33 -0
  36. package/dist/entrypoints/auth/external/static.cjs.js.map +1 -0
  37. package/dist/{cjs/helpers-D2f1CG0o.cjs.js → entrypoints/auth/helpers.cjs.js} +1 -1
  38. package/dist/entrypoints/auth/helpers.cjs.js.map +1 -0
  39. package/dist/entrypoints/auth/plugin/PluginTokenHandler.cjs.js +147 -0
  40. package/dist/entrypoints/auth/plugin/PluginTokenHandler.cjs.js.map +1 -0
  41. package/dist/entrypoints/auth/plugin/keys/DatabaseKeyStore.cjs.js +73 -0
  42. package/dist/entrypoints/auth/plugin/keys/DatabaseKeyStore.cjs.js.map +1 -0
  43. package/dist/entrypoints/auth/plugin/keys/DatabasePluginKeySource.cjs.js +75 -0
  44. package/dist/entrypoints/auth/plugin/keys/DatabasePluginKeySource.cjs.js.map +1 -0
  45. package/dist/entrypoints/auth/plugin/keys/StaticConfigPluginKeySource.cjs.js +91 -0
  46. package/dist/entrypoints/auth/plugin/keys/StaticConfigPluginKeySource.cjs.js.map +1 -0
  47. package/dist/entrypoints/auth/plugin/keys/createPluginKeySource.cjs.js +29 -0
  48. package/dist/entrypoints/auth/plugin/keys/createPluginKeySource.cjs.js.map +1 -0
  49. package/dist/entrypoints/auth/user/UserTokenHandler.cjs.js +110 -0
  50. package/dist/entrypoints/auth/user/UserTokenHandler.cjs.js.map +1 -0
  51. package/dist/entrypoints/cache/CacheClient.cjs.js +50 -0
  52. package/dist/entrypoints/cache/CacheClient.cjs.js.map +1 -0
  53. package/dist/entrypoints/cache/CacheManager.cjs.js +147 -0
  54. package/dist/entrypoints/cache/CacheManager.cjs.js.map +1 -0
  55. package/dist/entrypoints/cache/cacheServiceFactory.cjs.js +22 -0
  56. package/dist/entrypoints/cache/cacheServiceFactory.cjs.js.map +1 -0
  57. package/dist/entrypoints/cache/types.cjs.js +10 -0
  58. package/dist/entrypoints/cache/types.cjs.js.map +1 -0
  59. package/dist/entrypoints/database/DatabaseManager.cjs.js +173 -0
  60. package/dist/entrypoints/database/DatabaseManager.cjs.js.map +1 -0
  61. package/dist/entrypoints/database/connectors/defaultNameOverride.cjs.js +14 -0
  62. package/dist/entrypoints/database/connectors/defaultNameOverride.cjs.js.map +1 -0
  63. package/dist/entrypoints/database/connectors/defaultSchemaOverride.cjs.js +12 -0
  64. package/dist/entrypoints/database/connectors/defaultSchemaOverride.cjs.js.map +1 -0
  65. package/dist/entrypoints/database/connectors/mergeDatabaseConfig.cjs.js +10 -0
  66. package/dist/entrypoints/database/connectors/mergeDatabaseConfig.cjs.js.map +1 -0
  67. package/dist/entrypoints/database/connectors/mysql.cjs.js +278 -0
  68. package/dist/entrypoints/database/connectors/mysql.cjs.js.map +1 -0
  69. package/dist/entrypoints/database/connectors/postgres.cjs.js +304 -0
  70. package/dist/entrypoints/database/connectors/postgres.cjs.js.map +1 -0
  71. package/dist/entrypoints/database/connectors/sqlite3.cjs.js +251 -0
  72. package/dist/entrypoints/database/connectors/sqlite3.cjs.js.map +1 -0
  73. package/dist/entrypoints/database/databaseServiceFactory.cjs.js +36 -0
  74. package/dist/entrypoints/database/databaseServiceFactory.cjs.js.map +1 -0
  75. package/dist/entrypoints/discovery/HostDiscovery.cjs.js +86 -0
  76. package/dist/entrypoints/discovery/HostDiscovery.cjs.js.map +1 -0
  77. package/dist/entrypoints/discovery/discoveryServiceFactory.cjs.js +17 -0
  78. package/dist/entrypoints/discovery/discoveryServiceFactory.cjs.js.map +1 -0
  79. package/dist/entrypoints/httpAuth/httpAuthServiceFactory.cjs.js +192 -0
  80. package/dist/entrypoints/httpAuth/httpAuthServiceFactory.cjs.js.map +1 -0
  81. package/dist/entrypoints/httpRouter/createAuthIntegrationRouter.cjs.js +19 -0
  82. package/dist/entrypoints/httpRouter/createAuthIntegrationRouter.cjs.js.map +1 -0
  83. package/dist/entrypoints/httpRouter/createCookieAuthRefreshMiddleware.cjs.js +26 -0
  84. package/dist/entrypoints/httpRouter/createCookieAuthRefreshMiddleware.cjs.js.map +1 -0
  85. package/dist/entrypoints/httpRouter/createCredentialsBarrier.cjs.js +63 -0
  86. package/dist/entrypoints/httpRouter/createCredentialsBarrier.cjs.js.map +1 -0
  87. package/dist/entrypoints/httpRouter/createLifecycleMiddleware.cjs.js +52 -0
  88. package/dist/entrypoints/httpRouter/createLifecycleMiddleware.cjs.js.map +1 -0
  89. package/dist/entrypoints/httpRouter/httpRouterServiceFactory.cjs.js +48 -0
  90. package/dist/entrypoints/httpRouter/httpRouterServiceFactory.cjs.js.map +1 -0
  91. package/dist/entrypoints/lifecycle/lifecycleServiceFactory.cjs.js +88 -0
  92. package/dist/entrypoints/lifecycle/lifecycleServiceFactory.cjs.js.map +1 -0
  93. package/dist/entrypoints/logger/loggerServiceFactory.cjs.js +17 -0
  94. package/dist/entrypoints/logger/loggerServiceFactory.cjs.js.map +1 -0
  95. package/dist/entrypoints/permissions/permissionsServiceFactory.cjs.js +22 -0
  96. package/dist/entrypoints/permissions/permissionsServiceFactory.cjs.js.map +1 -0
  97. package/dist/{cjs/createConfigSecretEnumerator-DShyoWWL.cjs.js → entrypoints/rootConfig/createConfigSecretEnumerator.cjs.js} +1 -1
  98. package/dist/entrypoints/rootConfig/createConfigSecretEnumerator.cjs.js.map +1 -0
  99. package/dist/entrypoints/rootConfig/rootConfigServiceFactory.cjs.js +26 -0
  100. package/dist/entrypoints/rootConfig/rootConfigServiceFactory.cjs.js.map +1 -0
  101. package/dist/entrypoints/rootHealth/rootHealthServiceFactory.cjs.js +41 -0
  102. package/dist/entrypoints/rootHealth/rootHealthServiceFactory.cjs.js.map +1 -0
  103. package/dist/entrypoints/rootHttpRouter/DefaultRootHttpRouter.cjs.js +77 -0
  104. package/dist/entrypoints/rootHttpRouter/DefaultRootHttpRouter.cjs.js.map +1 -0
  105. package/dist/entrypoints/rootHttpRouter/createHealthRouter.cjs.js +29 -0
  106. package/dist/entrypoints/rootHttpRouter/createHealthRouter.cjs.js.map +1 -0
  107. package/dist/entrypoints/rootHttpRouter/http/MiddlewareFactory.cjs.js +187 -0
  108. package/dist/entrypoints/rootHttpRouter/http/MiddlewareFactory.cjs.js.map +1 -0
  109. package/dist/entrypoints/rootHttpRouter/http/applyInternalErrorFilter.cjs.js +28 -0
  110. package/dist/entrypoints/rootHttpRouter/http/applyInternalErrorFilter.cjs.js.map +1 -0
  111. package/dist/{cjs/config-BDOwXIyo.cjs.js → entrypoints/rootHttpRouter/http/config.cjs.js} +1 -1
  112. package/dist/entrypoints/rootHttpRouter/http/config.cjs.js.map +1 -0
  113. package/dist/entrypoints/rootHttpRouter/http/createHttpServer.cjs.js +88 -0
  114. package/dist/entrypoints/rootHttpRouter/http/createHttpServer.cjs.js.map +1 -0
  115. package/dist/entrypoints/rootHttpRouter/http/getGeneratedCertificate.cjs.js +130 -0
  116. package/dist/entrypoints/rootHttpRouter/http/getGeneratedCertificate.cjs.js.map +1 -0
  117. package/dist/entrypoints/rootHttpRouter/http/readCorsOptions.cjs.js +51 -0
  118. package/dist/entrypoints/rootHttpRouter/http/readCorsOptions.cjs.js.map +1 -0
  119. package/dist/entrypoints/rootHttpRouter/http/readHelmetOptions.cjs.js +62 -0
  120. package/dist/entrypoints/rootHttpRouter/http/readHelmetOptions.cjs.js.map +1 -0
  121. package/dist/entrypoints/rootHttpRouter/rootHttpRouterServiceFactory.cjs.js +73 -0
  122. package/dist/entrypoints/rootHttpRouter/rootHttpRouterServiceFactory.cjs.js.map +1 -0
  123. package/dist/entrypoints/rootLifecycle/rootLifecycleServiceFactory.cjs.js +76 -0
  124. package/dist/entrypoints/rootLifecycle/rootLifecycleServiceFactory.cjs.js.map +1 -0
  125. package/dist/entrypoints/rootLogger/WinstonLogger.cjs.js +114 -0
  126. package/dist/entrypoints/rootLogger/WinstonLogger.cjs.js.map +1 -0
  127. package/dist/entrypoints/rootLogger/rootLoggerServiceFactory.cjs.js +30 -0
  128. package/dist/entrypoints/rootLogger/rootLoggerServiceFactory.cjs.js.map +1 -0
  129. package/dist/entrypoints/scheduler/database/migrateBackendTasks.cjs.js +18 -0
  130. package/dist/entrypoints/scheduler/database/migrateBackendTasks.cjs.js.map +1 -0
  131. package/dist/entrypoints/scheduler/database/tables.cjs.js +8 -0
  132. package/dist/entrypoints/scheduler/database/tables.cjs.js.map +1 -0
  133. package/dist/entrypoints/scheduler/lib/DefaultSchedulerService.cjs.js +37 -0
  134. package/dist/entrypoints/scheduler/lib/DefaultSchedulerService.cjs.js.map +1 -0
  135. package/dist/entrypoints/scheduler/lib/LocalTaskWorker.cjs.js +105 -0
  136. package/dist/entrypoints/scheduler/lib/LocalTaskWorker.cjs.js.map +1 -0
  137. package/dist/entrypoints/scheduler/lib/PluginTaskSchedulerImpl.cjs.js +138 -0
  138. package/dist/entrypoints/scheduler/lib/PluginTaskSchedulerImpl.cjs.js.map +1 -0
  139. package/dist/entrypoints/scheduler/lib/PluginTaskSchedulerJanitor.cjs.js +59 -0
  140. package/dist/entrypoints/scheduler/lib/PluginTaskSchedulerJanitor.cjs.js.map +1 -0
  141. package/dist/entrypoints/scheduler/lib/TaskWorker.cjs.js +275 -0
  142. package/dist/entrypoints/scheduler/lib/TaskWorker.cjs.js.map +1 -0
  143. package/dist/entrypoints/scheduler/lib/types.cjs.js +60 -0
  144. package/dist/entrypoints/scheduler/lib/types.cjs.js.map +1 -0
  145. package/dist/entrypoints/scheduler/lib/util.cjs.js +66 -0
  146. package/dist/entrypoints/scheduler/lib/util.cjs.js.map +1 -0
  147. package/dist/entrypoints/scheduler/schedulerServiceFactory.cjs.js +19 -0
  148. package/dist/entrypoints/scheduler/schedulerServiceFactory.cjs.js.map +1 -0
  149. package/dist/entrypoints/urlReader/lib/AwsCodeCommitUrlReader.cjs.js +274 -0
  150. package/dist/entrypoints/urlReader/lib/AwsCodeCommitUrlReader.cjs.js.map +1 -0
  151. package/dist/entrypoints/urlReader/lib/AwsS3UrlReader.cjs.js +261 -0
  152. package/dist/entrypoints/urlReader/lib/AwsS3UrlReader.cjs.js.map +1 -0
  153. package/dist/entrypoints/urlReader/lib/AzureUrlReader.cjs.js +148 -0
  154. package/dist/entrypoints/urlReader/lib/AzureUrlReader.cjs.js.map +1 -0
  155. package/dist/entrypoints/urlReader/lib/BitbucketCloudUrlReader.cjs.js +174 -0
  156. package/dist/entrypoints/urlReader/lib/BitbucketCloudUrlReader.cjs.js.map +1 -0
  157. package/dist/entrypoints/urlReader/lib/BitbucketServerUrlReader.cjs.js +170 -0
  158. package/dist/entrypoints/urlReader/lib/BitbucketServerUrlReader.cjs.js.map +1 -0
  159. package/dist/entrypoints/urlReader/lib/BitbucketUrlReader.cjs.js +182 -0
  160. package/dist/entrypoints/urlReader/lib/BitbucketUrlReader.cjs.js.map +1 -0
  161. package/dist/entrypoints/urlReader/lib/FetchUrlReader.cjs.js +132 -0
  162. package/dist/entrypoints/urlReader/lib/FetchUrlReader.cjs.js.map +1 -0
  163. package/dist/entrypoints/urlReader/lib/GerritUrlReader.cjs.js +147 -0
  164. package/dist/entrypoints/urlReader/lib/GerritUrlReader.cjs.js.map +1 -0
  165. package/dist/entrypoints/urlReader/lib/GiteaUrlReader.cjs.js +122 -0
  166. package/dist/entrypoints/urlReader/lib/GiteaUrlReader.cjs.js.map +1 -0
  167. package/dist/entrypoints/urlReader/lib/GithubUrlReader.cjs.js +226 -0
  168. package/dist/entrypoints/urlReader/lib/GithubUrlReader.cjs.js.map +1 -0
  169. package/dist/entrypoints/urlReader/lib/GitlabUrlReader.cjs.js +277 -0
  170. package/dist/entrypoints/urlReader/lib/GitlabUrlReader.cjs.js.map +1 -0
  171. package/dist/entrypoints/urlReader/lib/GoogleGcsUrlReader.cjs.js +129 -0
  172. package/dist/entrypoints/urlReader/lib/GoogleGcsUrlReader.cjs.js.map +1 -0
  173. package/dist/entrypoints/urlReader/lib/HarnessUrlReader.cjs.js +120 -0
  174. package/dist/entrypoints/urlReader/lib/HarnessUrlReader.cjs.js.map +1 -0
  175. package/dist/entrypoints/urlReader/lib/ReadUrlResponseFactory.cjs.js +49 -0
  176. package/dist/entrypoints/urlReader/lib/ReadUrlResponseFactory.cjs.js.map +1 -0
  177. package/dist/entrypoints/urlReader/lib/UrlReaderPredicateMux.cjs.js +46 -0
  178. package/dist/entrypoints/urlReader/lib/UrlReaderPredicateMux.cjs.js.map +1 -0
  179. package/dist/entrypoints/urlReader/lib/UrlReaders.cjs.js +68 -0
  180. package/dist/entrypoints/urlReader/lib/UrlReaders.cjs.js.map +1 -0
  181. package/dist/entrypoints/urlReader/lib/tree/ReadTreeResponseFactory.cjs.js +46 -0
  182. package/dist/entrypoints/urlReader/lib/tree/ReadTreeResponseFactory.cjs.js.map +1 -0
  183. package/dist/entrypoints/urlReader/lib/tree/ReadableArrayResponse.cjs.js +78 -0
  184. package/dist/entrypoints/urlReader/lib/tree/ReadableArrayResponse.cjs.js.map +1 -0
  185. package/dist/entrypoints/urlReader/lib/tree/TarArchiveResponse.cjs.js +147 -0
  186. package/dist/entrypoints/urlReader/lib/tree/TarArchiveResponse.cjs.js.map +1 -0
  187. package/dist/entrypoints/urlReader/lib/tree/ZipArchiveResponse.cjs.js +161 -0
  188. package/dist/entrypoints/urlReader/lib/tree/ZipArchiveResponse.cjs.js.map +1 -0
  189. package/dist/entrypoints/urlReader/lib/tree/util.cjs.js +28 -0
  190. package/dist/entrypoints/urlReader/lib/tree/util.cjs.js.map +1 -0
  191. package/dist/entrypoints/urlReader/lib/util.cjs.js +11 -0
  192. package/dist/entrypoints/urlReader/lib/util.cjs.js.map +1 -0
  193. package/dist/entrypoints/urlReader/urlReaderServiceFactory.cjs.js +29 -0
  194. package/dist/entrypoints/urlReader/urlReaderServiceFactory.cjs.js.map +1 -0
  195. package/dist/entrypoints/userInfo/DefaultUserInfoService.cjs.js +59 -0
  196. package/dist/entrypoints/userInfo/DefaultUserInfoService.cjs.js.map +1 -0
  197. package/dist/entrypoints/userInfo/userInfoServiceFactory.cjs.js +17 -0
  198. package/dist/entrypoints/userInfo/userInfoServiceFactory.cjs.js.map +1 -0
  199. package/dist/httpAuth.cjs.js +3 -187
  200. package/dist/httpAuth.cjs.js.map +1 -1
  201. package/dist/httpRouter.cjs.js +2 -166
  202. package/dist/httpRouter.cjs.js.map +1 -1
  203. package/dist/index.cjs.js +4 -160
  204. package/dist/index.cjs.js.map +1 -1
  205. package/dist/lib/escapeRegExp.cjs.js +8 -0
  206. package/dist/lib/escapeRegExp.cjs.js.map +1 -0
  207. package/dist/lifecycle.cjs.js +3 -58
  208. package/dist/lifecycle.cjs.js.map +1 -1
  209. package/dist/logger.cjs.js +3 -12
  210. package/dist/logger.cjs.js.map +1 -1
  211. package/dist/package.json.cjs.js +252 -0
  212. package/dist/package.json.cjs.js.map +1 -0
  213. package/dist/permissions.cjs.js +3 -17
  214. package/dist/permissions.cjs.js.map +1 -1
  215. package/dist/rootConfig.cjs.js +4 -22
  216. package/dist/rootConfig.cjs.js.map +1 -1
  217. package/dist/rootHealth.cjs.js +3 -35
  218. package/dist/rootHealth.cjs.js.map +1 -1
  219. package/dist/rootHttpRouter.cjs.js +15 -651
  220. package/dist/rootHttpRouter.cjs.js.map +1 -1
  221. package/dist/rootLifecycle.cjs.js +3 -70
  222. package/dist/rootLifecycle.cjs.js.map +1 -1
  223. package/dist/rootLogger.cjs.js +4 -137
  224. package/dist/rootLogger.cjs.js.map +1 -1
  225. package/dist/scheduler.cjs.js +4 -693
  226. package/dist/scheduler.cjs.js.map +1 -1
  227. package/dist/scheduler.d.ts +2 -1
  228. package/dist/urlReader.cjs.js +32 -2962
  229. package/dist/urlReader.cjs.js.map +1 -1
  230. package/dist/userInfo.cjs.js +2 -64
  231. package/dist/userInfo.cjs.js.map +1 -1
  232. package/httpAuth/package.json +1 -1
  233. package/httpRouter/package.json +1 -1
  234. package/lifecycle/package.json +1 -1
  235. package/logger/package.json +1 -1
  236. package/package.json +13 -13
  237. package/permissions/package.json +1 -1
  238. package/rootConfig/package.json +1 -1
  239. package/rootHealth/package.json +1 -1
  240. package/rootHttpRouter/package.json +1 -1
  241. package/rootLifecycle/package.json +1 -1
  242. package/rootLogger/package.json +1 -1
  243. package/scheduler/package.json +1 -1
  244. package/urlReader/package.json +1 -1
  245. package/userInfo/package.json +1 -1
  246. package/dist/cjs/config-BDOwXIyo.cjs.js.map +0 -1
  247. package/dist/cjs/createConfigSecretEnumerator-DShyoWWL.cjs.js.map +0 -1
  248. package/dist/cjs/helpers-D2f1CG0o.cjs.js.map +0 -1
@@ -1,963 +1,10 @@
1
1
  'use strict';
2
2
 
3
- var backendPluginApi = require('@backstage/backend-plugin-api');
4
- var config = require('@backstage/config');
5
- var errors = require('@backstage/errors');
6
- var knexFactory = require('knex');
7
- var lodash = require('lodash');
8
- var limiterFactory = require('p-limit');
9
- var yn = require('yn');
10
- var format = require('pg-format');
11
- var backendDevUtils = require('@backstage/backend-dev-utils');
12
- var fs = require('fs-extra');
13
- var platformPath = require('path');
3
+ var databaseServiceFactory = require('./entrypoints/database/databaseServiceFactory.cjs.js');
4
+ var DatabaseManager = require('./entrypoints/database/DatabaseManager.cjs.js');
14
5
 
15
- function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
16
6
 
17
- var knexFactory__default = /*#__PURE__*/_interopDefaultCompat(knexFactory);
18
- var limiterFactory__default = /*#__PURE__*/_interopDefaultCompat(limiterFactory);
19
- var yn__default = /*#__PURE__*/_interopDefaultCompat(yn);
20
- var format__default = /*#__PURE__*/_interopDefaultCompat(format);
21
- var platformPath__default = /*#__PURE__*/_interopDefaultCompat(platformPath);
22
7
 
23
- function defaultNameOverride(name) {
24
- return {
25
- connection: {
26
- database: name
27
- }
28
- };
29
- }
30
-
31
- function mergeDatabaseConfig(config, ...overrides) {
32
- return lodash.merge({}, config, ...overrides);
33
- }
34
-
35
- const ddlLimiter$1 = limiterFactory__default.default(1);
36
- function createMysqlDatabaseClient(dbConfig, overrides) {
37
- const knexConfig = buildMysqlDatabaseConfig(dbConfig, overrides);
38
- const database = knexFactory__default.default(knexConfig);
39
- return database;
40
- }
41
- function buildMysqlDatabaseConfig(dbConfig, overrides) {
42
- return mergeDatabaseConfig(
43
- dbConfig.get(),
44
- {
45
- connection: getMysqlConnectionConfig(dbConfig, !!overrides),
46
- useNullAsDefault: true
47
- },
48
- overrides
49
- );
50
- }
51
- function getMysqlConnectionConfig(dbConfig, parseConnectionString) {
52
- const connection = dbConfig.get("connection");
53
- const isConnectionString = typeof connection === "string" || connection instanceof String;
54
- const autoParse = typeof parseConnectionString !== "boolean";
55
- const shouldParseConnectionString = autoParse ? isConnectionString : parseConnectionString && isConnectionString;
56
- return shouldParseConnectionString ? parseMysqlConnectionString(connection) : connection;
57
- }
58
- function parseMysqlConnectionString(connectionString) {
59
- try {
60
- const {
61
- protocol,
62
- username,
63
- password,
64
- port,
65
- hostname,
66
- pathname,
67
- searchParams
68
- } = new URL(connectionString);
69
- if (protocol !== "mysql:") {
70
- throw new Error(`Unknown protocol ${protocol}`);
71
- } else if (!username || !password) {
72
- throw new Error(`Missing username/password`);
73
- } else if (!pathname.match(/^\/[^/]+$/)) {
74
- throw new Error(`Expected single path segment`);
75
- }
76
- const result = {
77
- user: username,
78
- password,
79
- host: hostname,
80
- port: Number(port || 3306),
81
- database: decodeURIComponent(pathname.substring(1))
82
- };
83
- const ssl = searchParams.get("ssl");
84
- if (ssl) {
85
- result.ssl = ssl;
86
- }
87
- const debug = searchParams.get("debug");
88
- if (debug) {
89
- result.debug = yn__default.default(debug);
90
- }
91
- return result;
92
- } catch (e) {
93
- throw new errors.InputError(
94
- `Error while parsing MySQL connection string, ${e}`,
95
- e
96
- );
97
- }
98
- }
99
- async function ensureMysqlDatabaseExists(dbConfig, ...databases) {
100
- const admin = createMysqlDatabaseClient(dbConfig, {
101
- connection: {
102
- database: null
103
- },
104
- pool: {
105
- min: 0,
106
- acquireTimeoutMillis: 1e4
107
- }
108
- });
109
- try {
110
- const ensureDatabase = async (database) => {
111
- await admin.raw(`CREATE DATABASE IF NOT EXISTS ??`, [database]);
112
- };
113
- await Promise.all(
114
- databases.map(async (database) => {
115
- let lastErr = void 0;
116
- for (let i = 0; i < 3; i++) {
117
- try {
118
- return await ddlLimiter$1(() => ensureDatabase(database));
119
- } catch (err) {
120
- lastErr = err;
121
- }
122
- await new Promise((resolve) => setTimeout(resolve, 100));
123
- }
124
- throw lastErr;
125
- })
126
- );
127
- } finally {
128
- await admin.destroy();
129
- }
130
- }
131
- function pluginPath$3(pluginId) {
132
- return `plugin.${pluginId}`;
133
- }
134
- function normalizeConnection$2(connection) {
135
- if (typeof connection === "undefined" || connection === null) {
136
- return {};
137
- }
138
- return typeof connection === "string" || connection instanceof String ? parseMysqlConnectionString(connection) : connection;
139
- }
140
- class MysqlConnector {
141
- constructor(config, prefix) {
142
- this.config = config;
143
- this.prefix = prefix;
144
- }
145
- async getClient(pluginId, _deps) {
146
- const pluginConfig = new config.ConfigReader(
147
- this.getConfigForPlugin(pluginId)
148
- );
149
- const databaseName = this.getDatabaseName(pluginId);
150
- if (databaseName && this.getEnsureExistsConfig(pluginId)) {
151
- try {
152
- await ensureMysqlDatabaseExists(pluginConfig, databaseName);
153
- } catch (error) {
154
- throw new Error(
155
- `Failed to connect to the database to make sure that '${databaseName}' exists, ${error}`
156
- );
157
- }
158
- }
159
- const pluginDivisionMode = this.getPluginDivisionModeConfig();
160
- if (pluginDivisionMode !== "database") {
161
- throw new Error(
162
- `The MySQL driver does not support plugin division mode '${pluginDivisionMode}'`
163
- );
164
- }
165
- const databaseClientOverrides = mergeDatabaseConfig(
166
- {},
167
- this.getDatabaseOverrides(pluginId)
168
- );
169
- const client = createMysqlDatabaseClient(
170
- pluginConfig,
171
- databaseClientOverrides
172
- );
173
- return client;
174
- }
175
- /**
176
- * Provides the canonical database name for a given plugin.
177
- *
178
- * This method provides the effective database name which is determined using
179
- * global and plugin specific database config. If no explicit database name,
180
- * this method will provide a generated name which is the pluginId prefixed
181
- * with 'backstage_plugin_'.
182
- *
183
- * @param pluginId - Lookup the database name for given plugin
184
- * @returns String representing the plugin's database name
185
- */
186
- getDatabaseName(pluginId) {
187
- const connection = this.getConnectionConfig(pluginId);
188
- const databaseName = connection?.database;
189
- return databaseName ?? `${this.prefix}${pluginId}`;
190
- }
191
- /**
192
- * Provides the client type which should be used for a given plugin.
193
- *
194
- * The client type is determined by plugin specific config if present.
195
- * Otherwise the base client is used as the fallback.
196
- *
197
- * @param pluginId - Plugin to get the client type for
198
- * @returns Object with client type returned as `client` and boolean
199
- * representing whether or not the client was overridden as
200
- * `overridden`
201
- */
202
- getClientType(pluginId) {
203
- const pluginClient = this.config.getOptionalString(
204
- `${pluginPath$3(pluginId)}.client`
205
- );
206
- const baseClient = this.config.getString("client");
207
- const client = pluginClient ?? baseClient;
208
- return {
209
- client,
210
- overridden: client !== baseClient
211
- };
212
- }
213
- getRoleConfig(pluginId) {
214
- return this.config.getOptionalString(`${pluginPath$3(pluginId)}.role`) ?? this.config.getOptionalString("role");
215
- }
216
- /**
217
- * Provides the knexConfig which should be used for a given plugin.
218
- *
219
- * @param pluginId - Plugin to get the knexConfig for
220
- * @returns The merged knexConfig value or undefined if it isn't specified
221
- */
222
- getAdditionalKnexConfig(pluginId) {
223
- const pluginConfig = this.config.getOptionalConfig(`${pluginPath$3(pluginId)}.knexConfig`)?.get();
224
- const baseConfig = this.config.getOptionalConfig("knexConfig")?.get();
225
- return lodash.merge(baseConfig, pluginConfig);
226
- }
227
- getEnsureExistsConfig(pluginId) {
228
- const baseConfig = this.config.getOptionalBoolean("ensureExists") ?? true;
229
- return this.config.getOptionalBoolean(`${pluginPath$3(pluginId)}.ensureExists`) ?? baseConfig;
230
- }
231
- getPluginDivisionModeConfig() {
232
- return this.config.getOptionalString("pluginDivisionMode") ?? "database";
233
- }
234
- /**
235
- * Provides a Knex connection plugin config by combining base and plugin
236
- * config.
237
- *
238
- * This method provides a baseConfig for a plugin database connector. If the
239
- * client type has not been overridden, the global connection config will be
240
- * included with plugin specific config as the base. Values from the plugin
241
- * connection take precedence over the base. Base database name is omitted
242
- * unless `pluginDivisionMode` is set to `schema`.
243
- */
244
- getConnectionConfig(pluginId) {
245
- const { overridden } = this.getClientType(pluginId);
246
- let baseConnection = normalizeConnection$2(this.config.get("connection"));
247
- if (this.getPluginDivisionModeConfig() !== "schema") {
248
- baseConnection = lodash.omit(baseConnection, "database");
249
- }
250
- const connection = normalizeConnection$2(
251
- this.config.getOptional(`${pluginPath$3(pluginId)}.connection`)
252
- );
253
- return {
254
- // include base connection if client type has not been overridden
255
- ...overridden ? {} : baseConnection,
256
- ...connection
257
- };
258
- }
259
- /**
260
- * Provides a Knex database config for a given plugin.
261
- *
262
- * This method provides a Knex configuration object along with the plugin's
263
- * client type.
264
- *
265
- * @param pluginId - The plugin that the database config should correspond with
266
- */
267
- getConfigForPlugin(pluginId) {
268
- const { client } = this.getClientType(pluginId);
269
- const role = this.getRoleConfig(pluginId);
270
- return {
271
- ...this.getAdditionalKnexConfig(pluginId),
272
- client,
273
- connection: this.getConnectionConfig(pluginId),
274
- ...role && { role }
275
- };
276
- }
277
- /**
278
- * Provides a partial `Knex.Config`• database name override for a given plugin.
279
- *
280
- * @param pluginId - Target plugin to get database name override
281
- * @returns Partial `Knex.Config` with database name override
282
- */
283
- getDatabaseOverrides(pluginId) {
284
- const databaseName = this.getDatabaseName(pluginId);
285
- return databaseName ? defaultNameOverride(databaseName) : {};
286
- }
287
- }
288
-
289
- function defaultSchemaOverride(name) {
290
- return {
291
- searchPath: [name]
292
- };
293
- }
294
-
295
- const ddlLimiter = limiterFactory__default.default(1);
296
- function createPgDatabaseClient(dbConfig, overrides) {
297
- const knexConfig = buildPgDatabaseConfig(dbConfig, overrides);
298
- const database = knexFactory__default.default(knexConfig);
299
- const role = dbConfig.getOptionalString("role");
300
- if (role) {
301
- database.client.pool.on(
302
- "createSuccess",
303
- async (_event, pgClient) => {
304
- const query = format__default.default("SET ROLE %I", role);
305
- await pgClient.query(query);
306
- }
307
- );
308
- }
309
- return database;
310
- }
311
- function buildPgDatabaseConfig(dbConfig, overrides) {
312
- return mergeDatabaseConfig(
313
- dbConfig.get(),
314
- {
315
- connection: getPgConnectionConfig(dbConfig, !!overrides),
316
- useNullAsDefault: true
317
- },
318
- overrides
319
- );
320
- }
321
- function getPgConnectionConfig(dbConfig, parseConnectionString) {
322
- const connection = dbConfig.get("connection");
323
- const isConnectionString = typeof connection === "string" || connection instanceof String;
324
- const autoParse = typeof parseConnectionString !== "boolean";
325
- const shouldParseConnectionString = autoParse ? isConnectionString : parseConnectionString && isConnectionString;
326
- return shouldParseConnectionString ? parsePgConnectionString(connection) : connection;
327
- }
328
- function parsePgConnectionString(connectionString) {
329
- const parse = requirePgConnectionString();
330
- return parse(connectionString);
331
- }
332
- function requirePgConnectionString() {
333
- try {
334
- return require("pg-connection-string").parse;
335
- } catch (e) {
336
- throw new errors.ForwardedError("Postgres: Install 'pg-connection-string'", e);
337
- }
338
- }
339
- async function ensurePgDatabaseExists(dbConfig, ...databases) {
340
- const admin = createPgDatabaseClient(dbConfig, {
341
- connection: {
342
- database: "postgres"
343
- },
344
- pool: {
345
- min: 0,
346
- acquireTimeoutMillis: 1e4
347
- }
348
- });
349
- try {
350
- const ensureDatabase = async (database) => {
351
- const result = await admin.from("pg_database").where("datname", database).count();
352
- if (parseInt(result[0].count, 10) > 0) {
353
- return;
354
- }
355
- await admin.raw(`CREATE DATABASE ??`, [database]);
356
- };
357
- await Promise.all(
358
- databases.map(async (database) => {
359
- let lastErr = void 0;
360
- for (let i = 0; i < 3; i++) {
361
- try {
362
- return await ddlLimiter(() => ensureDatabase(database));
363
- } catch (err) {
364
- lastErr = err;
365
- }
366
- await new Promise((resolve) => setTimeout(resolve, 100));
367
- }
368
- throw lastErr;
369
- })
370
- );
371
- } finally {
372
- await admin.destroy();
373
- }
374
- }
375
- async function ensurePgSchemaExists(dbConfig, ...schemas) {
376
- const admin = createPgDatabaseClient(dbConfig);
377
- const role = dbConfig.getOptionalString("role");
378
- try {
379
- const ensureSchema = async (database) => {
380
- if (role) {
381
- await admin.raw(`CREATE SCHEMA IF NOT EXISTS ?? AUTHORIZATION ??`, [
382
- database,
383
- role
384
- ]);
385
- } else {
386
- await admin.raw(`CREATE SCHEMA IF NOT EXISTS ??`, [database]);
387
- }
388
- };
389
- await Promise.all(
390
- schemas.map((database) => ddlLimiter(() => ensureSchema(database)))
391
- );
392
- } finally {
393
- await admin.destroy();
394
- }
395
- }
396
- function pluginPath$2(pluginId) {
397
- return `plugin.${pluginId}`;
398
- }
399
- function normalizeConnection$1(connection) {
400
- if (typeof connection === "undefined" || connection === null) {
401
- return {};
402
- }
403
- return typeof connection === "string" || connection instanceof String ? parsePgConnectionString(connection) : connection;
404
- }
405
- class PgConnector {
406
- constructor(config, prefix) {
407
- this.config = config;
408
- this.prefix = prefix;
409
- }
410
- async getClient(pluginId, _deps) {
411
- const pluginConfig = new config.ConfigReader(
412
- this.getConfigForPlugin(pluginId)
413
- );
414
- const databaseName = this.getDatabaseName(pluginId);
415
- if (databaseName && this.getEnsureExistsConfig(pluginId)) {
416
- try {
417
- await ensurePgDatabaseExists(pluginConfig, databaseName);
418
- } catch (error) {
419
- throw new Error(
420
- `Failed to connect to the database to make sure that '${databaseName}' exists, ${error}`
421
- );
422
- }
423
- }
424
- let schemaOverrides;
425
- if (this.getPluginDivisionModeConfig() === "schema") {
426
- schemaOverrides = defaultSchemaOverride(pluginId);
427
- if (this.getEnsureSchemaExistsConfig(pluginId) || this.getEnsureExistsConfig(pluginId)) {
428
- try {
429
- await ensurePgSchemaExists(pluginConfig, pluginId);
430
- } catch (error) {
431
- throw new Error(
432
- `Failed to connect to the database to make sure that schema for plugin '${pluginId}' exists, ${error}`
433
- );
434
- }
435
- }
436
- }
437
- const databaseClientOverrides = mergeDatabaseConfig(
438
- {},
439
- this.getDatabaseOverrides(pluginId),
440
- schemaOverrides
441
- );
442
- const client = createPgDatabaseClient(
443
- pluginConfig,
444
- databaseClientOverrides
445
- );
446
- return client;
447
- }
448
- /**
449
- * Provides the canonical database name for a given plugin.
450
- *
451
- * This method provides the effective database name which is determined using global
452
- * and plugin specific database config. If no explicit database name is configured
453
- * and `pluginDivisionMode` is not `schema`, this method will provide a generated name
454
- * which is the pluginId prefixed with 'backstage_plugin_'. If `pluginDivisionMode` is
455
- * `schema`, it will fallback to using the default database for the knex instance.
456
- *
457
- * @param pluginId - Lookup the database name for given plugin
458
- * @returns String representing the plugin's database name
459
- */
460
- getDatabaseName(pluginId) {
461
- const connection = this.getConnectionConfig(pluginId);
462
- const databaseName = connection?.database;
463
- if (this.getPluginDivisionModeConfig() === "schema") {
464
- return databaseName;
465
- }
466
- return databaseName ?? `${this.prefix}${pluginId}`;
467
- }
468
- /**
469
- * Provides the client type which should be used for a given plugin.
470
- *
471
- * The client type is determined by plugin specific config if present.
472
- * Otherwise the base client is used as the fallback.
473
- *
474
- * @param pluginId - Plugin to get the client type for
475
- * @returns Object with client type returned as `client` and boolean
476
- * representing whether or not the client was overridden as
477
- * `overridden`
478
- */
479
- getClientType(pluginId) {
480
- const pluginClient = this.config.getOptionalString(
481
- `${pluginPath$2(pluginId)}.client`
482
- );
483
- const baseClient = this.config.getString("client");
484
- const client = pluginClient ?? baseClient;
485
- return {
486
- client,
487
- overridden: client !== baseClient
488
- };
489
- }
490
- getRoleConfig(pluginId) {
491
- return this.config.getOptionalString(`${pluginPath$2(pluginId)}.role`) ?? this.config.getOptionalString("role");
492
- }
493
- /**
494
- * Provides the knexConfig which should be used for a given plugin.
495
- *
496
- * @param pluginId - Plugin to get the knexConfig for
497
- * @returns The merged knexConfig value or undefined if it isn't specified
498
- */
499
- getAdditionalKnexConfig(pluginId) {
500
- const pluginConfig = this.config.getOptionalConfig(`${pluginPath$2(pluginId)}.knexConfig`)?.get();
501
- const baseConfig = this.config.getOptionalConfig("knexConfig")?.get();
502
- return lodash.merge(baseConfig, pluginConfig);
503
- }
504
- getEnsureExistsConfig(pluginId) {
505
- const baseConfig = this.config.getOptionalBoolean("ensureExists") ?? true;
506
- return this.config.getOptionalBoolean(`${pluginPath$2(pluginId)}.ensureExists`) ?? baseConfig;
507
- }
508
- getEnsureSchemaExistsConfig(pluginId) {
509
- const baseConfig = this.config.getOptionalBoolean("ensureSchemaExists") ?? false;
510
- return this.config.getOptionalBoolean(
511
- `${pluginPath$2(pluginId)}.getEnsureSchemaExistsConfig`
512
- ) ?? baseConfig;
513
- }
514
- getPluginDivisionModeConfig() {
515
- return this.config.getOptionalString("pluginDivisionMode") ?? "database";
516
- }
517
- /**
518
- * Provides a Knex connection plugin config by combining base and plugin
519
- * config.
520
- *
521
- * This method provides a baseConfig for a plugin database connector. If the
522
- * client type has not been overridden, the global connection config will be
523
- * included with plugin specific config as the base. Values from the plugin
524
- * connection take precedence over the base. Base database name is omitted
525
- * unless `pluginDivisionMode` is set to `schema`.
526
- */
527
- getConnectionConfig(pluginId) {
528
- const { overridden } = this.getClientType(pluginId);
529
- let baseConnection = normalizeConnection$1(this.config.get("connection"));
530
- if (this.getPluginDivisionModeConfig() !== "schema") {
531
- baseConnection = lodash.omit(baseConnection, "database");
532
- }
533
- const connection = normalizeConnection$1(
534
- this.config.getOptional(`${pluginPath$2(pluginId)}.connection`)
535
- );
536
- baseConnection.application_name ||= `backstage_plugin_${pluginId}`;
537
- return {
538
- // include base connection if client type has not been overridden
539
- ...overridden ? {} : baseConnection,
540
- ...connection
541
- };
542
- }
543
- /**
544
- * Provides a Knex database config for a given plugin.
545
- *
546
- * This method provides a Knex configuration object along with the plugin's
547
- * client type.
548
- *
549
- * @param pluginId - The plugin that the database config should correspond with
550
- */
551
- getConfigForPlugin(pluginId) {
552
- const { client } = this.getClientType(pluginId);
553
- const role = this.getRoleConfig(pluginId);
554
- return {
555
- ...this.getAdditionalKnexConfig(pluginId),
556
- client,
557
- connection: this.getConnectionConfig(pluginId),
558
- ...role && { role }
559
- };
560
- }
561
- /**
562
- * Provides a partial `Knex.Config`• database name override for a given plugin.
563
- *
564
- * @param pluginId - Target plugin to get database name override
565
- * @returns Partial `Knex.Config` with database name override
566
- */
567
- getDatabaseOverrides(pluginId) {
568
- const databaseName = this.getDatabaseName(pluginId);
569
- return databaseName ? defaultNameOverride(databaseName) : {};
570
- }
571
- }
572
-
573
- function createSqliteDatabaseClient(pluginId, dbConfig, deps, overrides) {
574
- const knexConfig = buildSqliteDatabaseConfig(dbConfig, overrides);
575
- const connConfig = knexConfig.connection;
576
- const filename = connConfig.filename ?? ":memory:";
577
- if (filename !== ":memory:") {
578
- const directory = platformPath__default.default.dirname(filename);
579
- fs.ensureDirSync(directory);
580
- }
581
- let database;
582
- if (deps && filename === ":memory:") {
583
- const devStore = backendDevUtils.DevDataStore.get();
584
- if (devStore) {
585
- const dataKey = `sqlite3-db-${pluginId}`;
586
- const connectionLoader = async () => {
587
- const { data: seedData } = await devStore.load(dataKey);
588
- return {
589
- ...knexConfig.connection,
590
- filename: seedData ?? ":memory:"
591
- };
592
- };
593
- database = knexFactory__default.default({
594
- ...knexConfig,
595
- connection: Object.assign(connectionLoader, {
596
- // This is a workaround for the knex SQLite driver always warning when using a config loader
597
- filename: ":memory:"
598
- })
599
- });
600
- deps.lifecycle.addShutdownHook(async () => {
601
- const connection = await database.client.acquireConnection();
602
- const data = connection.serialize();
603
- await devStore.save(dataKey, data);
604
- });
605
- } else {
606
- database = knexFactory__default.default(knexConfig);
607
- }
608
- } else {
609
- database = knexFactory__default.default(knexConfig);
610
- }
611
- database.client.pool.on("createSuccess", (_eventId, resource) => {
612
- resource.run("PRAGMA foreign_keys = ON", () => {
613
- });
614
- });
615
- return database;
616
- }
617
- function buildSqliteDatabaseConfig(dbConfig, overrides) {
618
- const baseConfig = dbConfig.get();
619
- if (typeof baseConfig.connection === "string") {
620
- baseConfig.connection = { filename: baseConfig.connection };
621
- }
622
- if (overrides && typeof overrides.connection === "string") {
623
- overrides.connection = { filename: overrides.connection };
624
- }
625
- const config = mergeDatabaseConfig(
626
- {
627
- connection: {}
628
- },
629
- baseConfig,
630
- {
631
- useNullAsDefault: true
632
- },
633
- overrides
634
- );
635
- return config;
636
- }
637
- function createSqliteNameOverride(name) {
638
- return {
639
- connection: parseSqliteConnectionString(name)
640
- };
641
- }
642
- function parseSqliteConnectionString(name) {
643
- return {
644
- filename: name
645
- };
646
- }
647
- function pluginPath$1(pluginId) {
648
- return `plugin.${pluginId}`;
649
- }
650
- function normalizeConnection(connection) {
651
- if (typeof connection === "undefined" || connection === null) {
652
- return {};
653
- }
654
- return typeof connection === "string" || connection instanceof String ? parseSqliteConnectionString(connection) : connection;
655
- }
656
- class Sqlite3Connector {
657
- constructor(config) {
658
- this.config = config;
659
- }
660
- async getClient(pluginId, deps) {
661
- const pluginConfig = new config.ConfigReader(
662
- this.getConfigForPlugin(pluginId)
663
- );
664
- const pluginDivisionMode = this.getPluginDivisionModeConfig();
665
- if (pluginDivisionMode !== "database") {
666
- throw new Error(
667
- `The SQLite driver does not support plugin division mode '${pluginDivisionMode}'`
668
- );
669
- }
670
- const databaseClientOverrides = mergeDatabaseConfig(
671
- {},
672
- this.getDatabaseOverrides(pluginId)
673
- );
674
- const client = createSqliteDatabaseClient(
675
- pluginId,
676
- pluginConfig,
677
- deps,
678
- databaseClientOverrides
679
- );
680
- return client;
681
- }
682
- /**
683
- * Provides the canonical database name for a given plugin.
684
- *
685
- * This method provides the effective database name which is determined using global
686
- * and plugin specific database config. If no explicit database name is configured
687
- * and `pluginDivisionMode` is not `schema`, this method will provide a generated name
688
- * which is the pluginId prefixed with 'backstage_plugin_'. If `pluginDivisionMode` is
689
- * `schema`, it will fallback to using the default database for the knex instance.
690
- *
691
- * @param pluginId - Lookup the database name for given plugin
692
- * @returns String representing the plugin's database name
693
- */
694
- getDatabaseName(pluginId) {
695
- const connection = this.getConnectionConfig(pluginId);
696
- const sqliteFilename = connection.filename;
697
- if (sqliteFilename === ":memory:") {
698
- return sqliteFilename;
699
- }
700
- const sqliteDirectory = connection.directory ?? ".";
701
- return platformPath__default.default.join(sqliteDirectory, sqliteFilename ?? `${pluginId}.sqlite`);
702
- }
703
- /**
704
- * Provides the client type which should be used for a given plugin.
705
- *
706
- * The client type is determined by plugin specific config if present.
707
- * Otherwise the base client is used as the fallback.
708
- *
709
- * @param pluginId - Plugin to get the client type for
710
- * @returns Object with client type returned as `client` and boolean
711
- * representing whether or not the client was overridden as
712
- * `overridden`
713
- */
714
- getClientType(pluginId) {
715
- const pluginClient = this.config.getOptionalString(
716
- `${pluginPath$1(pluginId)}.client`
717
- );
718
- const baseClient = this.config.getString("client");
719
- const client = pluginClient ?? baseClient;
720
- return {
721
- client,
722
- overridden: client !== baseClient
723
- };
724
- }
725
- getRoleConfig(pluginId) {
726
- return this.config.getOptionalString(`${pluginPath$1(pluginId)}.role`) ?? this.config.getOptionalString("role");
727
- }
728
- /**
729
- * Provides the knexConfig which should be used for a given plugin.
730
- *
731
- * @param pluginId - Plugin to get the knexConfig for
732
- * @returns The merged knexConfig value or undefined if it isn't specified
733
- */
734
- getAdditionalKnexConfig(pluginId) {
735
- const pluginConfig = this.config.getOptionalConfig(`${pluginPath$1(pluginId)}.knexConfig`)?.get();
736
- const baseConfig = this.config.getOptionalConfig("knexConfig")?.get();
737
- return lodash.merge(baseConfig, pluginConfig);
738
- }
739
- getPluginDivisionModeConfig() {
740
- return this.config.getOptionalString("pluginDivisionMode") ?? "database";
741
- }
742
- /**
743
- * Provides a Knex connection plugin config by combining base and plugin
744
- * config.
745
- *
746
- * This method provides a baseConfig for a plugin database connector. If the
747
- * client type has not been overridden, the global connection config will be
748
- * included with plugin specific config as the base. Values from the plugin
749
- * connection take precedence over the base. Base database name is omitted for
750
- * all supported databases excluding SQLite unless `pluginDivisionMode` is set
751
- * to `schema`.
752
- */
753
- getConnectionConfig(pluginId) {
754
- const { client, overridden } = this.getClientType(pluginId);
755
- let baseConnection = normalizeConnection(this.config.get("connection"));
756
- if (client.includes("sqlite3") && "filename" in baseConnection && baseConnection.filename !== ":memory:") {
757
- throw new Error(
758
- "`connection.filename` is not supported for the base sqlite connection. Prefer `connection.directory` or provide a filename for the plugin connection instead."
759
- );
760
- }
761
- if (this.getPluginDivisionModeConfig() !== "schema") {
762
- baseConnection = lodash.omit(baseConnection, "database");
763
- }
764
- const connection = normalizeConnection(
765
- this.config.getOptional(`${pluginPath$1(pluginId)}.connection`)
766
- );
767
- return {
768
- // include base connection if client type has not been overridden
769
- ...overridden ? {} : baseConnection,
770
- ...connection
771
- };
772
- }
773
- /**
774
- * Provides a Knex database config for a given plugin.
775
- *
776
- * This method provides a Knex configuration object along with the plugin's
777
- * client type.
778
- *
779
- * @param pluginId - The plugin that the database config should correspond with
780
- */
781
- getConfigForPlugin(pluginId) {
782
- const { client } = this.getClientType(pluginId);
783
- const role = this.getRoleConfig(pluginId);
784
- return {
785
- ...this.getAdditionalKnexConfig(pluginId),
786
- client,
787
- connection: this.getConnectionConfig(pluginId),
788
- ...role && { role }
789
- };
790
- }
791
- /**
792
- * Provides a partial `Knex.Config`• database name override for a given plugin.
793
- *
794
- * @param pluginId - Target plugin to get database name override
795
- * @returns Partial `Knex.Config` with database name override
796
- */
797
- getDatabaseOverrides(pluginId) {
798
- const databaseName = this.getDatabaseName(pluginId);
799
- return databaseName ? createSqliteNameOverride(databaseName) : {};
800
- }
801
- }
802
-
803
- function pluginPath(pluginId) {
804
- return `plugin.${pluginId}`;
805
- }
806
- class DatabaseManagerImpl {
807
- constructor(config, connectors, options, databaseCache = /* @__PURE__ */ new Map()) {
808
- this.config = config;
809
- this.connectors = connectors;
810
- this.options = options;
811
- this.databaseCache = databaseCache;
812
- }
813
- /**
814
- * Generates a PluginDatabaseManager for consumption by plugins.
815
- *
816
- * @param pluginId - The plugin that the database manager should be created for. Plugin names
817
- * should be unique as they are used to look up database config overrides under
818
- * `backend.database.plugin`.
819
- */
820
- forPlugin(pluginId, deps) {
821
- const client = this.getClientType(pluginId).client;
822
- const connector = this.connectors[client];
823
- if (!connector) {
824
- throw new Error(
825
- `Unsupported database client type '${client}' specified for plugin '${pluginId}'`
826
- );
827
- }
828
- const getClient = () => this.getDatabase(pluginId, connector, deps);
829
- const skip = this.options?.migrations?.skip ?? this.config.getOptionalBoolean(
830
- `backend.database.plugin.${pluginId}.skipMigrations`
831
- ) ?? this.config.getOptionalBoolean("backend.database.skipMigrations") ?? false;
832
- return { getClient, migrations: { skip } };
833
- }
834
- /**
835
- * Provides the client type which should be used for a given plugin.
836
- *
837
- * The client type is determined by plugin specific config if present.
838
- * Otherwise the base client is used as the fallback.
839
- *
840
- * @param pluginId - Plugin to get the client type for
841
- * @returns Object with client type returned as `client` and boolean
842
- * representing whether or not the client was overridden as
843
- * `overridden`
844
- */
845
- getClientType(pluginId) {
846
- const pluginClient = this.config.getOptionalString(
847
- `${pluginPath(pluginId)}.client`
848
- );
849
- const baseClient = this.config.getString("client");
850
- const client = pluginClient ?? baseClient;
851
- return {
852
- client,
853
- overridden: client !== baseClient
854
- };
855
- }
856
- /**
857
- * Provides a scoped Knex client for a plugin as per application config.
858
- *
859
- * @param pluginId - Plugin to get a Knex client for
860
- * @returns Promise which resolves to a scoped Knex database client for a
861
- * plugin
862
- */
863
- async getDatabase(pluginId, connector, deps) {
864
- if (this.databaseCache.has(pluginId)) {
865
- return this.databaseCache.get(pluginId);
866
- }
867
- const clientPromise = connector.getClient(pluginId, deps);
868
- this.databaseCache.set(pluginId, clientPromise);
869
- if (process.env.NODE_ENV !== "test") {
870
- clientPromise.then(
871
- (client) => this.startKeepaliveLoop(pluginId, client, deps.logger)
872
- );
873
- }
874
- return clientPromise;
875
- }
876
- startKeepaliveLoop(pluginId, client, logger) {
877
- let lastKeepaliveFailed = false;
878
- setInterval(() => {
879
- client?.raw("select 1").then(
880
- () => {
881
- lastKeepaliveFailed = false;
882
- },
883
- (error) => {
884
- if (!lastKeepaliveFailed) {
885
- lastKeepaliveFailed = true;
886
- logger.warn(
887
- `Database keepalive failed for plugin ${pluginId}, ${errors.stringifyError(
888
- error
889
- )}`
890
- );
891
- }
892
- }
893
- );
894
- }, 60 * 1e3);
895
- }
896
- }
897
- class DatabaseManager {
898
- constructor(impl) {
899
- this.impl = impl;
900
- }
901
- /**
902
- * Creates a {@link DatabaseManager} from `backend.database` config.
903
- *
904
- * @param config - The loaded application configuration.
905
- * @param options - An optional configuration object.
906
- */
907
- static fromConfig(config, options) {
908
- const databaseConfig = config.getConfig("backend.database");
909
- const prefix = databaseConfig.getOptionalString("prefix") || "backstage_plugin_";
910
- return new DatabaseManager(
911
- new DatabaseManagerImpl(
912
- databaseConfig,
913
- {
914
- pg: new PgConnector(databaseConfig, prefix),
915
- sqlite3: new Sqlite3Connector(databaseConfig),
916
- "better-sqlite3": new Sqlite3Connector(databaseConfig),
917
- mysql: new MysqlConnector(databaseConfig, prefix),
918
- mysql2: new MysqlConnector(databaseConfig, prefix)
919
- },
920
- options
921
- )
922
- );
923
- }
924
- /**
925
- * Generates a PluginDatabaseManager for consumption by plugins.
926
- *
927
- * @param pluginId - The plugin that the database manager should be created for. Plugin names
928
- * should be unique as they are used to look up database config overrides under
929
- * `backend.database.plugin`.
930
- */
931
- forPlugin(pluginId, deps) {
932
- return this.impl.forPlugin(pluginId, deps);
933
- }
934
- }
935
-
936
- const databaseServiceFactory = backendPluginApi.createServiceFactory({
937
- service: backendPluginApi.coreServices.database,
938
- deps: {
939
- config: backendPluginApi.coreServices.rootConfig,
940
- lifecycle: backendPluginApi.coreServices.lifecycle,
941
- logger: backendPluginApi.coreServices.logger,
942
- pluginMetadata: backendPluginApi.coreServices.pluginMetadata
943
- },
944
- async createRootContext({ config: config$1 }) {
945
- return config$1.getOptional("backend.database") ? DatabaseManager.fromConfig(config$1) : DatabaseManager.fromConfig(
946
- new config.ConfigReader({
947
- backend: {
948
- database: { client: "better-sqlite3", connection: ":memory:" }
949
- }
950
- })
951
- );
952
- },
953
- async factory({ pluginMetadata, lifecycle, logger }, databaseManager) {
954
- return databaseManager.forPlugin(pluginMetadata.getId(), {
955
- lifecycle,
956
- logger
957
- });
958
- }
959
- });
960
-
961
- exports.DatabaseManager = DatabaseManager;
962
- exports.databaseServiceFactory = databaseServiceFactory;
8
+ exports.databaseServiceFactory = databaseServiceFactory.databaseServiceFactory;
9
+ exports.DatabaseManager = DatabaseManager.DatabaseManager;
963
10
  //# sourceMappingURL=database.cjs.js.map