@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
@@ -30,4 +30,4 @@ async function createConfigSecretEnumerator(options) {
30
30
  }
31
31
 
32
32
  exports.createConfigSecretEnumerator = createConfigSecretEnumerator;
33
- //# sourceMappingURL=createConfigSecretEnumerator-DShyoWWL.cjs.js.map
33
+ //# sourceMappingURL=createConfigSecretEnumerator.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createConfigSecretEnumerator.cjs.js","sources":["../../../src/entrypoints/rootConfig/createConfigSecretEnumerator.ts"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { LoggerService } from '@backstage/backend-plugin-api';\nimport type { Config } from '@backstage/config';\nimport { ConfigSchema, loadConfigSchema } from '@backstage/config-loader';\nimport { getPackages } from '@manypkg/get-packages';\n\n/** @public */\nexport async function createConfigSecretEnumerator(options: {\n logger: LoggerService;\n dir?: string;\n schema?: ConfigSchema;\n}): Promise<(config: Config) => Iterable<string>> {\n const { logger, dir = process.cwd() } = options;\n const { packages } = await getPackages(dir);\n const schema =\n options.schema ??\n (await loadConfigSchema({\n dependencies: packages.map(p => p.packageJson.name),\n }));\n\n return (config: Config) => {\n const [secretsData] = schema.process(\n [{ data: config.getOptional() ?? {}, context: 'schema-enumerator' }],\n {\n visibility: ['secret'],\n ignoreSchemaErrors: true,\n },\n );\n const secrets = new Set<string>();\n JSON.parse(\n JSON.stringify(secretsData.data),\n (_, v) => typeof v === 'string' && secrets.add(v),\n );\n logger.info(\n `Found ${secrets.size} new secrets in config that will be redacted`,\n );\n return secrets;\n };\n}\n"],"names":["getPackages","loadConfigSchema"],"mappings":";;;;;AAsBA,eAAsB,6BAA6B,OAID,EAAA;AAChD,EAAA,MAAM,EAAE,MAAQ,EAAA,GAAA,GAAM,OAAQ,CAAA,GAAA,IAAU,GAAA,OAAA,CAAA;AACxC,EAAA,MAAM,EAAE,QAAA,EAAa,GAAA,MAAMA,wBAAY,GAAG,CAAA,CAAA;AAC1C,EAAA,MAAM,MACJ,GAAA,OAAA,CAAQ,MACP,IAAA,MAAMC,6BAAiB,CAAA;AAAA,IACtB,cAAc,QAAS,CAAA,GAAA,CAAI,CAAK,CAAA,KAAA,CAAA,CAAE,YAAY,IAAI,CAAA;AAAA,GACnD,CAAA,CAAA;AAEH,EAAA,OAAO,CAAC,MAAmB,KAAA;AACzB,IAAM,MAAA,CAAC,WAAW,CAAA,GAAI,MAAO,CAAA,OAAA;AAAA,MAC3B,CAAC,EAAE,IAAA,EAAM,MAAO,CAAA,WAAA,MAAiB,EAAC,EAAG,OAAS,EAAA,mBAAA,EAAqB,CAAA;AAAA,MACnE;AAAA,QACE,UAAA,EAAY,CAAC,QAAQ,CAAA;AAAA,QACrB,kBAAoB,EAAA,IAAA;AAAA,OACtB;AAAA,KACF,CAAA;AACA,IAAM,MAAA,OAAA,uBAAc,GAAY,EAAA,CAAA;AAChC,IAAK,IAAA,CAAA,KAAA;AAAA,MACH,IAAA,CAAK,SAAU,CAAA,WAAA,CAAY,IAAI,CAAA;AAAA,MAC/B,CAAC,GAAG,CAAM,KAAA,OAAO,MAAM,QAAY,IAAA,OAAA,CAAQ,IAAI,CAAC,CAAA;AAAA,KAClD,CAAA;AACA,IAAO,MAAA,CAAA,IAAA;AAAA,MACL,CAAA,MAAA,EAAS,QAAQ,IAAI,CAAA,4CAAA,CAAA;AAAA,KACvB,CAAA;AACA,IAAO,OAAA,OAAA,CAAA;AAAA,GACT,CAAA;AACF;;;;"}
@@ -0,0 +1,26 @@
1
+ 'use strict';
2
+
3
+ var backendPluginApi = require('@backstage/backend-plugin-api');
4
+ var configLoader = require('@backstage/config-loader');
5
+
6
+ const rootConfigServiceFactoryWithOptions = (options) => backendPluginApi.createServiceFactory({
7
+ service: backendPluginApi.coreServices.rootConfig,
8
+ deps: {},
9
+ async factory() {
10
+ const source = configLoader.ConfigSources.default({
11
+ argv: options?.argv,
12
+ remote: options?.remote,
13
+ watch: options?.watch
14
+ });
15
+ console.log(`Loading config from ${source}`);
16
+ return await configLoader.ConfigSources.toConfig(source);
17
+ }
18
+ });
19
+ const rootConfigServiceFactory = Object.assign(
20
+ rootConfigServiceFactoryWithOptions,
21
+ rootConfigServiceFactoryWithOptions()
22
+ );
23
+
24
+ exports.rootConfigServiceFactory = rootConfigServiceFactory;
25
+ exports.rootConfigServiceFactoryWithOptions = rootConfigServiceFactoryWithOptions;
26
+ //# sourceMappingURL=rootConfigServiceFactory.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rootConfigServiceFactory.cjs.js","sources":["../../../src/entrypoints/rootConfig/rootConfigServiceFactory.ts"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n coreServices,\n createServiceFactory,\n} from '@backstage/backend-plugin-api';\nimport {\n ConfigSources,\n RemoteConfigSourceOptions,\n} from '@backstage/config-loader';\n\n/**\n * Access to static configuration.\n *\n * See {@link @backstage/code-plugin-api#RootConfigService}\n * and {@link https://backstage.io/docs/backend-system/core-services/root-config | the service docs}\n * for more information.\n *\n * @public\n */\nexport interface RootConfigFactoryOptions {\n /**\n * Process arguments to use instead of the default `process.argv()`.\n */\n argv?: string[];\n\n /**\n * Enables and sets options for remote configuration loading.\n */\n remote?: Pick<RemoteConfigSourceOptions, 'reloadInterval'>;\n watch?: boolean;\n}\n\nexport const rootConfigServiceFactoryWithOptions = (\n options?: RootConfigFactoryOptions,\n) =>\n createServiceFactory({\n service: coreServices.rootConfig,\n deps: {},\n async factory() {\n const source = ConfigSources.default({\n argv: options?.argv,\n remote: options?.remote,\n watch: options?.watch,\n });\n console.log(`Loading config from ${source}`);\n return await ConfigSources.toConfig(source);\n },\n });\n\n/**\n * @public\n */\nexport const rootConfigServiceFactory = Object.assign(\n rootConfigServiceFactoryWithOptions,\n rootConfigServiceFactoryWithOptions(),\n);\n"],"names":["createServiceFactory","coreServices","ConfigSources"],"mappings":";;;;;AA+Ca,MAAA,mCAAA,GAAsC,CACjD,OAAA,KAEAA,qCAAqB,CAAA;AAAA,EACnB,SAASC,6BAAa,CAAA,UAAA;AAAA,EACtB,MAAM,EAAC;AAAA,EACP,MAAM,OAAU,GAAA;AACd,IAAM,MAAA,MAAA,GAASC,2BAAc,OAAQ,CAAA;AAAA,MACnC,MAAM,OAAS,EAAA,IAAA;AAAA,MACf,QAAQ,OAAS,EAAA,MAAA;AAAA,MACjB,OAAO,OAAS,EAAA,KAAA;AAAA,KACjB,CAAA,CAAA;AACD,IAAQ,OAAA,CAAA,GAAA,CAAI,CAAuB,oBAAA,EAAA,MAAM,CAAE,CAAA,CAAA,CAAA;AAC3C,IAAO,OAAA,MAAMA,0BAAc,CAAA,QAAA,CAAS,MAAM,CAAA,CAAA;AAAA,GAC5C;AACF,CAAC,EAAA;AAKI,MAAM,2BAA2B,MAAO,CAAA,MAAA;AAAA,EAC7C,mCAAA;AAAA,EACA,mCAAoC,EAAA;AACtC;;;;;"}
@@ -0,0 +1,41 @@
1
+ 'use strict';
2
+
3
+ var backendPluginApi = require('@backstage/backend-plugin-api');
4
+
5
+ class DefaultRootHealthService {
6
+ constructor(options) {
7
+ this.options = options;
8
+ options.lifecycle.addStartupHook(() => {
9
+ this.#isRunning = true;
10
+ });
11
+ options.lifecycle.addShutdownHook(() => {
12
+ this.#isRunning = false;
13
+ });
14
+ }
15
+ #isRunning = false;
16
+ async getLiveness() {
17
+ return { status: 200, payload: { status: "ok" } };
18
+ }
19
+ async getReadiness() {
20
+ if (!this.#isRunning) {
21
+ return {
22
+ status: 503,
23
+ payload: { message: "Backend has not started yet", status: "error" }
24
+ };
25
+ }
26
+ return { status: 200, payload: { status: "ok" } };
27
+ }
28
+ }
29
+ const rootHealthServiceFactory = backendPluginApi.createServiceFactory({
30
+ service: backendPluginApi.coreServices.rootHealth,
31
+ deps: {
32
+ lifecycle: backendPluginApi.coreServices.rootLifecycle
33
+ },
34
+ async factory({ lifecycle }) {
35
+ return new DefaultRootHealthService({ lifecycle });
36
+ }
37
+ });
38
+
39
+ exports.DefaultRootHealthService = DefaultRootHealthService;
40
+ exports.rootHealthServiceFactory = rootHealthServiceFactory;
41
+ //# sourceMappingURL=rootHealthServiceFactory.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rootHealthServiceFactory.cjs.js","sources":["../../../src/entrypoints/rootHealth/rootHealthServiceFactory.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n RootHealthService,\n RootLifecycleService,\n coreServices,\n createServiceFactory,\n} from '@backstage/backend-plugin-api';\n\n/** @internal */\nexport class DefaultRootHealthService implements RootHealthService {\n #isRunning = false;\n\n constructor(readonly options: { lifecycle: RootLifecycleService }) {\n options.lifecycle.addStartupHook(() => {\n this.#isRunning = true;\n });\n options.lifecycle.addShutdownHook(() => {\n this.#isRunning = false;\n });\n }\n\n async getLiveness(): Promise<{ status: number; payload?: any }> {\n return { status: 200, payload: { status: 'ok' } };\n }\n\n async getReadiness(): Promise<{ status: number; payload?: any }> {\n if (!this.#isRunning) {\n return {\n status: 503,\n payload: { message: 'Backend has not started yet', status: 'error' },\n };\n }\n\n return { status: 200, payload: { status: 'ok' } };\n }\n}\n\n/**\n * @public\n */\nexport const rootHealthServiceFactory = createServiceFactory({\n service: coreServices.rootHealth,\n deps: {\n lifecycle: coreServices.rootLifecycle,\n },\n async factory({ lifecycle }) {\n return new DefaultRootHealthService({ lifecycle });\n },\n});\n"],"names":["createServiceFactory","coreServices"],"mappings":";;;;AAwBO,MAAM,wBAAsD,CAAA;AAAA,EAGjE,YAAqB,OAA8C,EAAA;AAA9C,IAAA,IAAA,CAAA,OAAA,GAAA,OAAA,CAAA;AACnB,IAAQ,OAAA,CAAA,SAAA,CAAU,eAAe,MAAM;AACrC,MAAA,IAAA,CAAK,UAAa,GAAA,IAAA,CAAA;AAAA,KACnB,CAAA,CAAA;AACD,IAAQ,OAAA,CAAA,SAAA,CAAU,gBAAgB,MAAM;AACtC,MAAA,IAAA,CAAK,UAAa,GAAA,KAAA,CAAA;AAAA,KACnB,CAAA,CAAA;AAAA,GACH;AAAA,EATA,UAAa,GAAA,KAAA,CAAA;AAAA,EAWb,MAAM,WAA0D,GAAA;AAC9D,IAAA,OAAO,EAAE,MAAQ,EAAA,GAAA,EAAK,SAAS,EAAE,MAAA,EAAQ,MAAO,EAAA,CAAA;AAAA,GAClD;AAAA,EAEA,MAAM,YAA2D,GAAA;AAC/D,IAAI,IAAA,CAAC,KAAK,UAAY,EAAA;AACpB,MAAO,OAAA;AAAA,QACL,MAAQ,EAAA,GAAA;AAAA,QACR,OAAS,EAAA,EAAE,OAAS,EAAA,6BAAA,EAA+B,QAAQ,OAAQ,EAAA;AAAA,OACrE,CAAA;AAAA,KACF;AAEA,IAAA,OAAO,EAAE,MAAQ,EAAA,GAAA,EAAK,SAAS,EAAE,MAAA,EAAQ,MAAO,EAAA,CAAA;AAAA,GAClD;AACF,CAAA;AAKO,MAAM,2BAA2BA,qCAAqB,CAAA;AAAA,EAC3D,SAASC,6BAAa,CAAA,UAAA;AAAA,EACtB,IAAM,EAAA;AAAA,IACJ,WAAWA,6BAAa,CAAA,aAAA;AAAA,GAC1B;AAAA,EACA,MAAM,OAAA,CAAQ,EAAE,SAAA,EAAa,EAAA;AAC3B,IAAA,OAAO,IAAI,wBAAA,CAAyB,EAAE,SAAA,EAAW,CAAA,CAAA;AAAA,GACnD;AACF,CAAC;;;;;"}
@@ -0,0 +1,77 @@
1
+ 'use strict';
2
+
3
+ var express = require('express');
4
+ var trimEnd = require('lodash/trimEnd');
5
+
6
+ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
7
+
8
+ var trimEnd__default = /*#__PURE__*/_interopDefaultCompat(trimEnd);
9
+
10
+ function normalizePath(path) {
11
+ return `${trimEnd__default.default(path, "/")}/`;
12
+ }
13
+ class DefaultRootHttpRouter {
14
+ #indexPath;
15
+ #router = express.Router();
16
+ #namedRoutes = express.Router();
17
+ #indexRouter = express.Router();
18
+ #existingPaths = new Array();
19
+ static create(options) {
20
+ let indexPath;
21
+ if (options?.indexPath === false) {
22
+ indexPath = void 0;
23
+ } else if (options?.indexPath === void 0) {
24
+ indexPath = "/api/app";
25
+ } else if (options?.indexPath === "") {
26
+ throw new Error("indexPath option may not be an empty string");
27
+ } else {
28
+ indexPath = options.indexPath;
29
+ }
30
+ return new DefaultRootHttpRouter(indexPath);
31
+ }
32
+ constructor(indexPath) {
33
+ this.#indexPath = indexPath;
34
+ this.#router.use(this.#namedRoutes);
35
+ this.#router.use("/api/", (_req, _res, next) => {
36
+ next("router");
37
+ });
38
+ if (this.#indexPath) {
39
+ this.#router.use(this.#indexRouter);
40
+ }
41
+ }
42
+ use(path, handler) {
43
+ if (path.match(/^[/\s]*$/)) {
44
+ throw new Error(`Root router path may not be empty`);
45
+ }
46
+ const conflictingPath = this.#findConflictingPath(path);
47
+ if (conflictingPath) {
48
+ throw new Error(
49
+ `Path ${path} conflicts with the existing path ${conflictingPath}`
50
+ );
51
+ }
52
+ this.#existingPaths.push(path);
53
+ this.#namedRoutes.use(path, handler);
54
+ if (this.#indexPath === path) {
55
+ this.#indexRouter.use(handler);
56
+ }
57
+ }
58
+ handler() {
59
+ return this.#router;
60
+ }
61
+ #findConflictingPath(newPath) {
62
+ const normalizedNewPath = normalizePath(newPath);
63
+ for (const path of this.#existingPaths) {
64
+ const normalizedPath = normalizePath(path);
65
+ if (normalizedPath.startsWith(normalizedNewPath)) {
66
+ return path;
67
+ }
68
+ if (normalizedNewPath.startsWith(normalizedPath)) {
69
+ return path;
70
+ }
71
+ }
72
+ return void 0;
73
+ }
74
+ }
75
+
76
+ exports.DefaultRootHttpRouter = DefaultRootHttpRouter;
77
+ //# sourceMappingURL=DefaultRootHttpRouter.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DefaultRootHttpRouter.cjs.js","sources":["../../../src/entrypoints/rootHttpRouter/DefaultRootHttpRouter.ts"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { RootHttpRouterService } from '@backstage/backend-plugin-api';\nimport { Handler, Router } from 'express';\nimport trimEnd from 'lodash/trimEnd';\n\nfunction normalizePath(path: string): string {\n return `${trimEnd(path, '/')}/`;\n}\n\n/**\n * Options for the {@link DefaultRootHttpRouter} class.\n *\n * @public\n */\nexport interface DefaultRootHttpRouterOptions {\n /**\n * The path to forward all unmatched requests to. Defaults to '/api/app' if\n * not given. Disables index path behavior if false is given.\n */\n indexPath?: string | false;\n}\n\n/**\n * The default implementation of the {@link @backstage/backend-plugin-api#RootHttpRouterService} interface for\n * {@link @backstage/backend-plugin-api#coreServices.rootHttpRouter}.\n *\n * @public\n */\nexport class DefaultRootHttpRouter implements RootHttpRouterService {\n #indexPath?: string;\n\n #router = Router();\n #namedRoutes = Router();\n #indexRouter = Router();\n #existingPaths = new Array<string>();\n\n static create(options?: DefaultRootHttpRouterOptions) {\n let indexPath;\n if (options?.indexPath === false) {\n indexPath = undefined;\n } else if (options?.indexPath === undefined) {\n indexPath = '/api/app';\n } else if (options?.indexPath === '') {\n throw new Error('indexPath option may not be an empty string');\n } else {\n indexPath = options.indexPath;\n }\n return new DefaultRootHttpRouter(indexPath);\n }\n\n private constructor(indexPath?: string) {\n this.#indexPath = indexPath;\n this.#router.use(this.#namedRoutes);\n\n // Any request with a /api/ prefix will skip the index router, even if no named router matches\n this.#router.use('/api/', (_req, _res, next) => {\n next('router');\n });\n\n if (this.#indexPath) {\n this.#router.use(this.#indexRouter);\n }\n }\n\n use(path: string, handler: Handler) {\n if (path.match(/^[/\\s]*$/)) {\n throw new Error(`Root router path may not be empty`);\n }\n const conflictingPath = this.#findConflictingPath(path);\n if (conflictingPath) {\n throw new Error(\n `Path ${path} conflicts with the existing path ${conflictingPath}`,\n );\n }\n this.#existingPaths.push(path);\n this.#namedRoutes.use(path, handler);\n\n if (this.#indexPath === path) {\n this.#indexRouter.use(handler);\n }\n }\n\n handler(): Handler {\n return this.#router;\n }\n\n #findConflictingPath(newPath: string): string | undefined {\n const normalizedNewPath = normalizePath(newPath);\n for (const path of this.#existingPaths) {\n const normalizedPath = normalizePath(path);\n if (normalizedPath.startsWith(normalizedNewPath)) {\n return path;\n }\n if (normalizedNewPath.startsWith(normalizedPath)) {\n return path;\n }\n }\n return undefined;\n }\n}\n"],"names":["trimEnd","Router"],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ 'use strict';
2
+
3
+ var Router = require('express-promise-router');
4
+
5
+ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
6
+
7
+ var Router__default = /*#__PURE__*/_interopDefaultCompat(Router);
8
+
9
+ function createHealthRouter(options) {
10
+ const router = Router__default.default();
11
+ router.get(
12
+ "/.backstage/health/v1/readiness",
13
+ async (_request, response) => {
14
+ const { status, payload } = await options.health.getReadiness();
15
+ response.status(status).json(payload);
16
+ }
17
+ );
18
+ router.get(
19
+ "/.backstage/health/v1/liveness",
20
+ async (_request, response) => {
21
+ const { status, payload } = await options.health.getLiveness();
22
+ response.status(status).json(payload);
23
+ }
24
+ );
25
+ return router;
26
+ }
27
+
28
+ exports.createHealthRouter = createHealthRouter;
29
+ //# sourceMappingURL=createHealthRouter.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createHealthRouter.cjs.js","sources":["../../../src/entrypoints/rootHttpRouter/createHealthRouter.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { RootHealthService } from '@backstage/backend-plugin-api';\nimport Router from 'express-promise-router';\nimport { Request, Response } from 'express';\n\n/**\n * @public\n */\nexport function createHealthRouter(options: { health: RootHealthService }) {\n const router = Router();\n\n router.get(\n '/.backstage/health/v1/readiness',\n async (_request: Request, response: Response) => {\n const { status, payload } = await options.health.getReadiness();\n response.status(status).json(payload);\n },\n );\n\n router.get(\n '/.backstage/health/v1/liveness',\n async (_request: Request, response: Response) => {\n const { status, payload } = await options.health.getLiveness();\n response.status(status).json(payload);\n },\n );\n\n return router;\n}\n"],"names":["Router"],"mappings":";;;;;;;;AAuBO,SAAS,mBAAmB,OAAwC,EAAA;AACzE,EAAA,MAAM,SAASA,uBAAO,EAAA,CAAA;AAEtB,EAAO,MAAA,CAAA,GAAA;AAAA,IACL,iCAAA;AAAA,IACA,OAAO,UAAmB,QAAuB,KAAA;AAC/C,MAAA,MAAM,EAAE,MAAQ,EAAA,OAAA,KAAY,MAAM,OAAA,CAAQ,OAAO,YAAa,EAAA,CAAA;AAC9D,MAAA,QAAA,CAAS,MAAO,CAAA,MAAM,CAAE,CAAA,IAAA,CAAK,OAAO,CAAA,CAAA;AAAA,KACtC;AAAA,GACF,CAAA;AAEA,EAAO,MAAA,CAAA,GAAA;AAAA,IACL,gCAAA;AAAA,IACA,OAAO,UAAmB,QAAuB,KAAA;AAC/C,MAAA,MAAM,EAAE,MAAQ,EAAA,OAAA,KAAY,MAAM,OAAA,CAAQ,OAAO,WAAY,EAAA,CAAA;AAC7D,MAAA,QAAA,CAAS,MAAO,CAAA,MAAM,CAAE,CAAA,IAAA,CAAK,OAAO,CAAA,CAAA;AAAA,KACtC;AAAA,GACF,CAAA;AAEA,EAAO,OAAA,MAAA,CAAA;AACT;;;;"}
@@ -0,0 +1,187 @@
1
+ 'use strict';
2
+
3
+ var cors = require('cors');
4
+ var helmet = require('helmet');
5
+ var morgan = require('morgan');
6
+ var compression = require('compression');
7
+ var readHelmetOptions = require('./readHelmetOptions.cjs.js');
8
+ var readCorsOptions = require('./readCorsOptions.cjs.js');
9
+ var errors = require('@backstage/errors');
10
+ var applyInternalErrorFilter = require('./applyInternalErrorFilter.cjs.js');
11
+
12
+ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
13
+
14
+ var cors__default = /*#__PURE__*/_interopDefaultCompat(cors);
15
+ var helmet__default = /*#__PURE__*/_interopDefaultCompat(helmet);
16
+ var morgan__default = /*#__PURE__*/_interopDefaultCompat(morgan);
17
+ var compression__default = /*#__PURE__*/_interopDefaultCompat(compression);
18
+
19
+ class MiddlewareFactory {
20
+ #config;
21
+ #logger;
22
+ /**
23
+ * Creates a new {@link MiddlewareFactory}.
24
+ */
25
+ static create(options) {
26
+ return new MiddlewareFactory(options);
27
+ }
28
+ constructor(options) {
29
+ this.#config = options.config;
30
+ this.#logger = options.logger;
31
+ }
32
+ /**
33
+ * Returns a middleware that unconditionally produces a 404 error response.
34
+ *
35
+ * @remarks
36
+ *
37
+ * Typically you want to place this middleware at the end of the chain, such
38
+ * that it's the last one attempted after no other routes matched.
39
+ *
40
+ * @returns An Express request handler
41
+ */
42
+ notFound() {
43
+ return (_req, res) => {
44
+ res.status(404).end();
45
+ };
46
+ }
47
+ /**
48
+ * Returns the compression middleware.
49
+ *
50
+ * @remarks
51
+ *
52
+ * The middleware will attempt to compress response bodies for all requests
53
+ * that traverse through the middleware.
54
+ */
55
+ compression() {
56
+ return compression__default.default();
57
+ }
58
+ /**
59
+ * Returns a request logging middleware.
60
+ *
61
+ * @remarks
62
+ *
63
+ * Typically you want to place this middleware at the start of the chain, such
64
+ * that it always logs requests whether they are "caught" by handlers farther
65
+ * down or not.
66
+ *
67
+ * @returns An Express request handler
68
+ */
69
+ logging() {
70
+ const logger = this.#logger.child({
71
+ type: "incomingRequest"
72
+ });
73
+ const customMorganFormat = '[:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent"';
74
+ return morgan__default.default(customMorganFormat, {
75
+ stream: {
76
+ write(message) {
77
+ logger.info(message.trimEnd());
78
+ }
79
+ }
80
+ });
81
+ }
82
+ /**
83
+ * Returns a middleware that implements the helmet library.
84
+ *
85
+ * @remarks
86
+ *
87
+ * This middleware applies security policies to incoming requests and outgoing
88
+ * responses. It is configured using config keys such as `backend.csp`.
89
+ *
90
+ * @see {@link https://helmetjs.github.io/}
91
+ *
92
+ * @returns An Express request handler
93
+ */
94
+ helmet() {
95
+ return helmet__default.default(readHelmetOptions.readHelmetOptions(this.#config.getOptionalConfig("backend")));
96
+ }
97
+ /**
98
+ * Returns a middleware that implements the cors library.
99
+ *
100
+ * @remarks
101
+ *
102
+ * This middleware handles CORS. It is configured using the config key
103
+ * `backend.cors`.
104
+ *
105
+ * @see {@link https://github.com/expressjs/cors}
106
+ *
107
+ * @returns An Express request handler
108
+ */
109
+ cors() {
110
+ return cors__default.default(readCorsOptions.readCorsOptions(this.#config.getOptionalConfig("backend")));
111
+ }
112
+ /**
113
+ * Express middleware to handle errors during request processing.
114
+ *
115
+ * @remarks
116
+ *
117
+ * This is commonly the very last middleware in the chain.
118
+ *
119
+ * Its primary purpose is not to do translation of business logic exceptions,
120
+ * but rather to be a global catch-all for uncaught "fatal" errors that are
121
+ * expected to result in a 500 error. However, it also does handle some common
122
+ * error types (such as http-error exceptions, and the well-known error types
123
+ * in the `@backstage/errors` package) and returns the enclosed status code
124
+ * accordingly.
125
+ *
126
+ * It will also produce a response body with a serialized form of the error,
127
+ * unless a previous handler already did send a body. See
128
+ * {@link @backstage/errors#ErrorResponseBody} for the response shape used.
129
+ *
130
+ * @returns An Express error request handler
131
+ */
132
+ error(options = {}) {
133
+ const showStackTraces = options.showStackTraces ?? process.env.NODE_ENV === "development";
134
+ const logger = this.#logger.child({
135
+ type: "errorHandler"
136
+ });
137
+ return (rawError, req, res, next) => {
138
+ const error = applyInternalErrorFilter.applyInternalErrorFilter(rawError, logger);
139
+ const statusCode = getStatusCode(error);
140
+ if (options.logAllErrors || statusCode >= 500) {
141
+ logger.error(`Request failed with status ${statusCode}`, error);
142
+ }
143
+ if (res.headersSent) {
144
+ next(error);
145
+ return;
146
+ }
147
+ const body = {
148
+ error: errors.serializeError(error, { includeStack: showStackTraces }),
149
+ request: { method: req.method, url: req.url },
150
+ response: { statusCode }
151
+ };
152
+ res.status(statusCode).json(body);
153
+ };
154
+ }
155
+ }
156
+ function getStatusCode(error) {
157
+ const knownStatusCodeFields = ["statusCode", "status"];
158
+ for (const field of knownStatusCodeFields) {
159
+ const statusCode = error[field];
160
+ if (typeof statusCode === "number" && (statusCode | 0) === statusCode && // is whole integer
161
+ statusCode >= 100 && statusCode <= 599) {
162
+ return statusCode;
163
+ }
164
+ }
165
+ switch (error.name) {
166
+ case errors.NotModifiedError.name:
167
+ return 304;
168
+ case errors.InputError.name:
169
+ return 400;
170
+ case errors.AuthenticationError.name:
171
+ return 401;
172
+ case errors.NotAllowedError.name:
173
+ return 403;
174
+ case errors.NotFoundError.name:
175
+ return 404;
176
+ case errors.ConflictError.name:
177
+ return 409;
178
+ case errors.NotImplementedError.name:
179
+ return 501;
180
+ case errors.ServiceUnavailableError.name:
181
+ return 503;
182
+ }
183
+ return 500;
184
+ }
185
+
186
+ exports.MiddlewareFactory = MiddlewareFactory;
187
+ //# sourceMappingURL=MiddlewareFactory.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MiddlewareFactory.cjs.js","sources":["../../../../src/entrypoints/rootHttpRouter/http/MiddlewareFactory.ts"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n RootConfigService,\n LoggerService,\n} from '@backstage/backend-plugin-api';\nimport {\n Request,\n Response,\n ErrorRequestHandler,\n NextFunction,\n RequestHandler,\n} from 'express';\nimport cors from 'cors';\nimport helmet from 'helmet';\nimport morgan from 'morgan';\nimport compression from 'compression';\nimport { readHelmetOptions } from './readHelmetOptions';\nimport { readCorsOptions } from './readCorsOptions';\nimport {\n AuthenticationError,\n ConflictError,\n ErrorResponseBody,\n InputError,\n NotAllowedError,\n NotFoundError,\n NotModifiedError,\n ServiceUnavailableError,\n serializeError,\n} from '@backstage/errors';\nimport { NotImplementedError } from '@backstage/errors';\nimport { applyInternalErrorFilter } from './applyInternalErrorFilter';\n\n/**\n * Options used to create a {@link MiddlewareFactory}.\n *\n * @public\n */\nexport interface MiddlewareFactoryOptions {\n config: RootConfigService;\n logger: LoggerService;\n}\n\n/**\n * Options passed to the {@link MiddlewareFactory.error} middleware.\n *\n * @public\n */\nexport interface MiddlewareFactoryErrorOptions {\n /**\n * Whether error response bodies should show error stack traces or not.\n *\n * If not specified, by default shows stack traces only in development mode.\n */\n showStackTraces?: boolean;\n\n /**\n * Whether any 4xx errors should be logged or not.\n *\n * If not specified, default to only logging 5xx errors.\n */\n logAllErrors?: boolean;\n}\n\n/**\n * A utility to configure common middleware.\n *\n * @public\n */\nexport class MiddlewareFactory {\n #config: RootConfigService;\n #logger: LoggerService;\n\n /**\n * Creates a new {@link MiddlewareFactory}.\n */\n static create(options: MiddlewareFactoryOptions) {\n return new MiddlewareFactory(options);\n }\n\n private constructor(options: MiddlewareFactoryOptions) {\n this.#config = options.config;\n this.#logger = options.logger;\n }\n\n /**\n * Returns a middleware that unconditionally produces a 404 error response.\n *\n * @remarks\n *\n * Typically you want to place this middleware at the end of the chain, such\n * that it's the last one attempted after no other routes matched.\n *\n * @returns An Express request handler\n */\n notFound(): RequestHandler {\n return (_req: Request, res: Response) => {\n res.status(404).end();\n };\n }\n\n /**\n * Returns the compression middleware.\n *\n * @remarks\n *\n * The middleware will attempt to compress response bodies for all requests\n * that traverse through the middleware.\n */\n compression(): RequestHandler {\n return compression();\n }\n\n /**\n * Returns a request logging middleware.\n *\n * @remarks\n *\n * Typically you want to place this middleware at the start of the chain, such\n * that it always logs requests whether they are \"caught\" by handlers farther\n * down or not.\n *\n * @returns An Express request handler\n */\n logging(): RequestHandler {\n const logger = this.#logger.child({\n type: 'incomingRequest',\n });\n const customMorganFormat =\n '[:date[clf]] \":method :url HTTP/:http-version\" :status :res[content-length] \":referrer\" \":user-agent\"';\n return morgan(customMorganFormat, {\n stream: {\n write(message: string) {\n logger.info(message.trimEnd());\n },\n },\n });\n }\n\n /**\n * Returns a middleware that implements the helmet library.\n *\n * @remarks\n *\n * This middleware applies security policies to incoming requests and outgoing\n * responses. It is configured using config keys such as `backend.csp`.\n *\n * @see {@link https://helmetjs.github.io/}\n *\n * @returns An Express request handler\n */\n helmet(): RequestHandler {\n return helmet(readHelmetOptions(this.#config.getOptionalConfig('backend')));\n }\n\n /**\n * Returns a middleware that implements the cors library.\n *\n * @remarks\n *\n * This middleware handles CORS. It is configured using the config key\n * `backend.cors`.\n *\n * @see {@link https://github.com/expressjs/cors}\n *\n * @returns An Express request handler\n */\n cors(): RequestHandler {\n return cors(readCorsOptions(this.#config.getOptionalConfig('backend')));\n }\n\n /**\n * Express middleware to handle errors during request processing.\n *\n * @remarks\n *\n * This is commonly the very last middleware in the chain.\n *\n * Its primary purpose is not to do translation of business logic exceptions,\n * but rather to be a global catch-all for uncaught \"fatal\" errors that are\n * expected to result in a 500 error. However, it also does handle some common\n * error types (such as http-error exceptions, and the well-known error types\n * in the `@backstage/errors` package) and returns the enclosed status code\n * accordingly.\n *\n * It will also produce a response body with a serialized form of the error,\n * unless a previous handler already did send a body. See\n * {@link @backstage/errors#ErrorResponseBody} for the response shape used.\n *\n * @returns An Express error request handler\n */\n error(options: MiddlewareFactoryErrorOptions = {}): ErrorRequestHandler {\n const showStackTraces =\n options.showStackTraces ?? process.env.NODE_ENV === 'development';\n\n const logger = this.#logger.child({\n type: 'errorHandler',\n });\n\n return (\n rawError: Error,\n req: Request,\n res: Response,\n next: NextFunction,\n ) => {\n const error = applyInternalErrorFilter(rawError, logger);\n\n const statusCode = getStatusCode(error);\n if (options.logAllErrors || statusCode >= 500) {\n logger.error(`Request failed with status ${statusCode}`, error);\n }\n\n if (res.headersSent) {\n // If the headers have already been sent, do not send the response again\n // as this will throw an error in the backend.\n next(error);\n return;\n }\n\n const body: ErrorResponseBody = {\n error: serializeError(error, { includeStack: showStackTraces }),\n request: { method: req.method, url: req.url },\n response: { statusCode },\n };\n\n res.status(statusCode).json(body);\n };\n }\n}\n\nfunction getStatusCode(error: Error): number {\n // Look for common http library status codes\n const knownStatusCodeFields = ['statusCode', 'status'];\n for (const field of knownStatusCodeFields) {\n const statusCode = (error as any)[field];\n if (\n typeof statusCode === 'number' &&\n (statusCode | 0) === statusCode && // is whole integer\n statusCode >= 100 &&\n statusCode <= 599\n ) {\n return statusCode;\n }\n }\n\n // Handle well-known error types\n switch (error.name) {\n case NotModifiedError.name:\n return 304;\n case InputError.name:\n return 400;\n case AuthenticationError.name:\n return 401;\n case NotAllowedError.name:\n return 403;\n case NotFoundError.name:\n return 404;\n case ConflictError.name:\n return 409;\n case NotImplementedError.name:\n return 501;\n case ServiceUnavailableError.name:\n return 503;\n default:\n break;\n }\n\n // Fall back to internal server error\n return 500;\n}\n"],"names":["compression","morgan","helmet","readHelmetOptions","cors","readCorsOptions","applyInternalErrorFilter","serializeError","NotModifiedError","InputError","AuthenticationError","NotAllowedError","NotFoundError","ConflictError","NotImplementedError","ServiceUnavailableError"],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ 'use strict';
2
+
3
+ var errors = require('@backstage/errors');
4
+ var crypto = require('crypto');
5
+
6
+ function handleBadError(error, logger) {
7
+ const logId = crypto.randomBytes(10).toString("hex");
8
+ logger.child({ logId }).error(`Filtered internal error with logId=${logId} from response`, error);
9
+ const newError = new Error(`An internal error occurred logId=${logId}`);
10
+ delete newError.stack;
11
+ return newError;
12
+ }
13
+ function applyInternalErrorFilter(error, logger) {
14
+ try {
15
+ errors.assertError(error);
16
+ } catch (assertionError) {
17
+ errors.assertError(assertionError);
18
+ return handleBadError(assertionError, logger);
19
+ }
20
+ const constructorName = error.constructor.name;
21
+ if (constructorName === "DatabaseError") {
22
+ return handleBadError(error, logger);
23
+ }
24
+ return error;
25
+ }
26
+
27
+ exports.applyInternalErrorFilter = applyInternalErrorFilter;
28
+ //# sourceMappingURL=applyInternalErrorFilter.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"applyInternalErrorFilter.cjs.js","sources":["../../../../src/entrypoints/rootHttpRouter/http/applyInternalErrorFilter.ts"],"sourcesContent":["/*\n * Copyright 2024 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { LoggerService } from '@backstage/backend-plugin-api';\nimport { assertError } from '@backstage/errors';\nimport { randomBytes } from 'crypto';\n\nfunction handleBadError(error: Error, logger: LoggerService) {\n const logId = randomBytes(10).toString('hex');\n logger\n .child({ logId })\n .error(`Filtered internal error with logId=${logId} from response`, error);\n const newError = new Error(`An internal error occurred logId=${logId}`);\n delete newError.stack; // Trim the stack since it's not particularly useful\n return newError;\n}\n\n/**\n * Filters out certain known error types that should never be returned in responses.\n *\n * @internal\n */\nexport function applyInternalErrorFilter(\n error: unknown,\n logger: LoggerService,\n): Error {\n try {\n assertError(error);\n } catch (assertionError: unknown) {\n assertError(assertionError);\n return handleBadError(assertionError, logger);\n }\n\n const constructorName = error.constructor.name;\n\n // DatabaseError are thrown by the pg-protocol module\n if (constructorName === 'DatabaseError') {\n return handleBadError(error, logger);\n }\n\n return error;\n}\n"],"names":["randomBytes","assertError"],"mappings":";;;;;AAoBA,SAAS,cAAA,CAAe,OAAc,MAAuB,EAAA;AAC3D,EAAA,MAAM,KAAQ,GAAAA,kBAAA,CAAY,EAAE,CAAA,CAAE,SAAS,KAAK,CAAA,CAAA;AAC5C,EACG,MAAA,CAAA,KAAA,CAAM,EAAE,KAAM,EAAC,EACf,KAAM,CAAA,CAAA,mCAAA,EAAsC,KAAK,CAAA,cAAA,CAAA,EAAkB,KAAK,CAAA,CAAA;AAC3E,EAAA,MAAM,QAAW,GAAA,IAAI,KAAM,CAAA,CAAA,iCAAA,EAAoC,KAAK,CAAE,CAAA,CAAA,CAAA;AACtE,EAAA,OAAO,QAAS,CAAA,KAAA,CAAA;AAChB,EAAO,OAAA,QAAA,CAAA;AACT,CAAA;AAOgB,SAAA,wBAAA,CACd,OACA,MACO,EAAA;AACP,EAAI,IAAA;AACF,IAAAC,kBAAA,CAAY,KAAK,CAAA,CAAA;AAAA,WACV,cAAyB,EAAA;AAChC,IAAAA,kBAAA,CAAY,cAAc,CAAA,CAAA;AAC1B,IAAO,OAAA,cAAA,CAAe,gBAAgB,MAAM,CAAA,CAAA;AAAA,GAC9C;AAEA,EAAM,MAAA,eAAA,GAAkB,MAAM,WAAY,CAAA,IAAA,CAAA;AAG1C,EAAA,IAAI,oBAAoB,eAAiB,EAAA;AACvC,IAAO,OAAA,cAAA,CAAe,OAAO,MAAM,CAAA,CAAA;AAAA,GACrC;AAEA,EAAO,OAAA,KAAA,CAAA;AACT;;;;"}
@@ -61,4 +61,4 @@ function readHttpsOptions(config) {
61
61
  }
62
62
 
63
63
  exports.readHttpServerOptions = readHttpServerOptions;
64
- //# sourceMappingURL=config-BDOwXIyo.cjs.js.map
64
+ //# sourceMappingURL=config.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.cjs.js","sources":["../../../../src/entrypoints/rootHttpRouter/http/config.ts"],"sourcesContent":["/*\n * Copyright 2023 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Config } from '@backstage/config';\nimport { HttpServerOptions } from './types';\n\nconst DEFAULT_PORT = 7007;\nconst DEFAULT_HOST = '';\n\n/**\n * Reads {@link HttpServerOptions} from a {@link @backstage/config#Config} object.\n *\n * @public\n * @remarks\n *\n * The provided configuration object should contain the `listen` and\n * additional keys directly.\n *\n * @example\n * ```ts\n * const opts = readHttpServerOptions(config.getConfig('backend'));\n * ```\n */\nexport function readHttpServerOptions(config?: Config): HttpServerOptions {\n return {\n listen: readHttpListenOptions(config),\n https: readHttpsOptions(config),\n };\n}\n\nfunction readHttpListenOptions(config?: Config): HttpServerOptions['listen'] {\n const listen = config?.getOptional('listen');\n if (typeof listen === 'string') {\n const parts = String(listen).split(':');\n const port = parseInt(parts[parts.length - 1], 10);\n if (!isNaN(port)) {\n if (parts.length === 1) {\n return { port, host: DEFAULT_HOST };\n }\n if (parts.length === 2) {\n return { host: parts[0], port };\n }\n }\n throw new Error(\n `Unable to parse listen address ${listen}, expected <port> or <host>:<port>`,\n );\n }\n\n // Workaround to allow empty string\n const host = config?.getOptional('listen.host') ?? DEFAULT_HOST;\n if (typeof host !== 'string') {\n config?.getOptionalString('listen.host'); // will throw\n throw new Error('unreachable');\n }\n\n return {\n port: config?.getOptionalNumber('listen.port') ?? DEFAULT_PORT,\n host,\n };\n}\n\nfunction readHttpsOptions(config?: Config): HttpServerOptions['https'] {\n const https = config?.getOptional('https');\n if (https === true) {\n const baseUrl = config!.getString('baseUrl');\n let hostname;\n try {\n hostname = new URL(baseUrl).hostname;\n } catch (error) {\n throw new Error(`Invalid baseUrl \"${baseUrl}\"`);\n }\n\n return { certificate: { type: 'generated', hostname } };\n }\n\n const cc = config?.getOptionalConfig('https');\n if (!cc) {\n return undefined;\n }\n\n return {\n certificate: {\n type: 'pem',\n cert: cc.getString('certificate.cert'),\n key: cc.getString('certificate.key'),\n },\n };\n}\n"],"names":[],"mappings":";;AAmBA,MAAM,YAAe,GAAA,IAAA,CAAA;AACrB,MAAM,YAAe,GAAA,EAAA,CAAA;AAgBd,SAAS,sBAAsB,MAAoC,EAAA;AACxE,EAAO,OAAA;AAAA,IACL,MAAA,EAAQ,sBAAsB,MAAM,CAAA;AAAA,IACpC,KAAA,EAAO,iBAAiB,MAAM,CAAA;AAAA,GAChC,CAAA;AACF,CAAA;AAEA,SAAS,sBAAsB,MAA8C,EAAA;AAC3E,EAAM,MAAA,MAAA,GAAS,MAAQ,EAAA,WAAA,CAAY,QAAQ,CAAA,CAAA;AAC3C,EAAI,IAAA,OAAO,WAAW,QAAU,EAAA;AAC9B,IAAA,MAAM,KAAQ,GAAA,MAAA,CAAO,MAAM,CAAA,CAAE,MAAM,GAAG,CAAA,CAAA;AACtC,IAAA,MAAM,OAAO,QAAS,CAAA,KAAA,CAAM,MAAM,MAAS,GAAA,CAAC,GAAG,EAAE,CAAA,CAAA;AACjD,IAAI,IAAA,CAAC,KAAM,CAAA,IAAI,CAAG,EAAA;AAChB,MAAI,IAAA,KAAA,CAAM,WAAW,CAAG,EAAA;AACtB,QAAO,OAAA,EAAE,IAAM,EAAA,IAAA,EAAM,YAAa,EAAA,CAAA;AAAA,OACpC;AACA,MAAI,IAAA,KAAA,CAAM,WAAW,CAAG,EAAA;AACtB,QAAA,OAAO,EAAE,IAAA,EAAM,KAAM,CAAA,CAAC,GAAG,IAAK,EAAA,CAAA;AAAA,OAChC;AAAA,KACF;AACA,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,kCAAkC,MAAM,CAAA,kCAAA,CAAA;AAAA,KAC1C,CAAA;AAAA,GACF;AAGA,EAAA,MAAM,IAAO,GAAA,MAAA,EAAQ,WAAY,CAAA,aAAa,CAAK,IAAA,YAAA,CAAA;AACnD,EAAI,IAAA,OAAO,SAAS,QAAU,EAAA;AAC5B,IAAA,MAAA,EAAQ,kBAAkB,aAAa,CAAA,CAAA;AACvC,IAAM,MAAA,IAAI,MAAM,aAAa,CAAA,CAAA;AAAA,GAC/B;AAEA,EAAO,OAAA;AAAA,IACL,IAAM,EAAA,MAAA,EAAQ,iBAAkB,CAAA,aAAa,CAAK,IAAA,YAAA;AAAA,IAClD,IAAA;AAAA,GACF,CAAA;AACF,CAAA;AAEA,SAAS,iBAAiB,MAA6C,EAAA;AACrE,EAAM,MAAA,KAAA,GAAQ,MAAQ,EAAA,WAAA,CAAY,OAAO,CAAA,CAAA;AACzC,EAAA,IAAI,UAAU,IAAM,EAAA;AAClB,IAAM,MAAA,OAAA,GAAU,MAAQ,CAAA,SAAA,CAAU,SAAS,CAAA,CAAA;AAC3C,IAAI,IAAA,QAAA,CAAA;AACJ,IAAI,IAAA;AACF,MAAW,QAAA,GAAA,IAAI,GAAI,CAAA,OAAO,CAAE,CAAA,QAAA,CAAA;AAAA,aACrB,KAAO,EAAA;AACd,MAAA,MAAM,IAAI,KAAA,CAAM,CAAoB,iBAAA,EAAA,OAAO,CAAG,CAAA,CAAA,CAAA,CAAA;AAAA,KAChD;AAEA,IAAA,OAAO,EAAE,WAAa,EAAA,EAAE,IAAM,EAAA,WAAA,EAAa,UAAW,EAAA,CAAA;AAAA,GACxD;AAEA,EAAM,MAAA,EAAA,GAAK,MAAQ,EAAA,iBAAA,CAAkB,OAAO,CAAA,CAAA;AAC5C,EAAA,IAAI,CAAC,EAAI,EAAA;AACP,IAAO,OAAA,KAAA,CAAA,CAAA;AAAA,GACT;AAEA,EAAO,OAAA;AAAA,IACL,WAAa,EAAA;AAAA,MACX,IAAM,EAAA,KAAA;AAAA,MACN,IAAA,EAAM,EAAG,CAAA,SAAA,CAAU,kBAAkB,CAAA;AAAA,MACrC,GAAA,EAAK,EAAG,CAAA,SAAA,CAAU,iBAAiB,CAAA;AAAA,KACrC;AAAA,GACF,CAAA;AACF;;;;"}
@@ -0,0 +1,88 @@
1
+ 'use strict';
2
+
3
+ var http = require('http');
4
+ var https = require('https');
5
+ var stoppableServer = require('stoppable');
6
+ var getGeneratedCertificate = require('./getGeneratedCertificate.cjs.js');
7
+
8
+ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
9
+
10
+ function _interopNamespaceCompat(e) {
11
+ if (e && typeof e === 'object' && 'default' in e) return e;
12
+ var n = Object.create(null);
13
+ if (e) {
14
+ Object.keys(e).forEach(function (k) {
15
+ if (k !== 'default') {
16
+ var d = Object.getOwnPropertyDescriptor(e, k);
17
+ Object.defineProperty(n, k, d.get ? d : {
18
+ enumerable: true,
19
+ get: function () { return e[k]; }
20
+ });
21
+ }
22
+ });
23
+ }
24
+ n.default = e;
25
+ return Object.freeze(n);
26
+ }
27
+
28
+ var http__namespace = /*#__PURE__*/_interopNamespaceCompat(http);
29
+ var https__namespace = /*#__PURE__*/_interopNamespaceCompat(https);
30
+ var stoppableServer__default = /*#__PURE__*/_interopDefaultCompat(stoppableServer);
31
+
32
+ async function createHttpServer(listener, options, deps) {
33
+ const server = await createServer(listener, options, deps);
34
+ const stopper = stoppableServer__default.default(server, 0);
35
+ const stopServer = stopper.stop.bind(stopper);
36
+ return Object.assign(server, {
37
+ start() {
38
+ return new Promise((resolve, reject) => {
39
+ const handleStartupError = (error) => {
40
+ server.close();
41
+ reject(error);
42
+ };
43
+ server.on("error", handleStartupError);
44
+ const { host, port } = options.listen;
45
+ server.listen(port, host, () => {
46
+ server.off("error", handleStartupError);
47
+ deps.logger.info(`Listening on ${host}:${port}`);
48
+ resolve();
49
+ });
50
+ });
51
+ },
52
+ stop() {
53
+ return new Promise((resolve, reject) => {
54
+ stopServer((error) => {
55
+ if (error) {
56
+ reject(error);
57
+ } else {
58
+ resolve();
59
+ }
60
+ });
61
+ });
62
+ },
63
+ port() {
64
+ const address = server.address();
65
+ if (typeof address === "string" || address === null) {
66
+ throw new Error(`Unexpected server address '${address}'`);
67
+ }
68
+ return address.port;
69
+ }
70
+ });
71
+ }
72
+ async function createServer(listener, options, deps) {
73
+ if (options.https) {
74
+ const { certificate } = options.https;
75
+ if (certificate.type === "generated") {
76
+ const credentials = await getGeneratedCertificate.getGeneratedCertificate(
77
+ certificate.hostname,
78
+ deps.logger
79
+ );
80
+ return https__namespace.createServer(credentials, listener);
81
+ }
82
+ return https__namespace.createServer(certificate, listener);
83
+ }
84
+ return http__namespace.createServer(listener);
85
+ }
86
+
87
+ exports.createHttpServer = createHttpServer;
88
+ //# sourceMappingURL=createHttpServer.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createHttpServer.cjs.js","sources":["../../../../src/entrypoints/rootHttpRouter/http/createHttpServer.ts"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport * as http from 'http';\nimport * as https from 'https';\nimport stoppableServer from 'stoppable';\nimport { RequestListener } from 'http';\nimport { LoggerService } from '@backstage/backend-plugin-api';\nimport { HttpServerOptions, ExtendedHttpServer } from './types';\nimport { getGeneratedCertificate } from './getGeneratedCertificate';\n\n/**\n * Creates a Node.js HTTP or HTTPS server instance.\n *\n * @public\n */\nexport async function createHttpServer(\n listener: RequestListener,\n options: HttpServerOptions,\n deps: { logger: LoggerService },\n): Promise<ExtendedHttpServer> {\n const server = await createServer(listener, options, deps);\n\n const stopper = stoppableServer(server, 0);\n // The stopper here is actually the server itself, so if we try\n // to call stopper.stop() down in the stop implementation, we'll\n // be calling ourselves.\n const stopServer = stopper.stop.bind(stopper);\n\n return Object.assign(server, {\n start() {\n return new Promise<void>((resolve, reject) => {\n const handleStartupError = (error: Error) => {\n server.close();\n reject(error);\n };\n\n server.on('error', handleStartupError);\n\n const { host, port } = options.listen;\n server.listen(port, host, () => {\n server.off('error', handleStartupError);\n deps.logger.info(`Listening on ${host}:${port}`);\n resolve();\n });\n });\n },\n\n stop() {\n return new Promise<void>((resolve, reject) => {\n stopServer((error?: Error) => {\n if (error) {\n reject(error);\n } else {\n resolve();\n }\n });\n });\n },\n\n port() {\n const address = server.address();\n if (typeof address === 'string' || address === null) {\n throw new Error(`Unexpected server address '${address}'`);\n }\n return address.port;\n },\n });\n}\n\nasync function createServer(\n listener: RequestListener,\n options: HttpServerOptions,\n deps: { logger: LoggerService },\n): Promise<http.Server> {\n if (options.https) {\n const { certificate } = options.https;\n if (certificate.type === 'generated') {\n const credentials = await getGeneratedCertificate(\n certificate.hostname,\n deps.logger,\n );\n return https.createServer(credentials, listener);\n }\n return https.createServer(certificate, listener);\n }\n\n return http.createServer(listener);\n}\n"],"names":["stoppableServer","getGeneratedCertificate","https","http"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6BsB,eAAA,gBAAA,CACpB,QACA,EAAA,OAAA,EACA,IAC6B,EAAA;AAC7B,EAAA,MAAM,MAAS,GAAA,MAAM,YAAa,CAAA,QAAA,EAAU,SAAS,IAAI,CAAA,CAAA;AAEzD,EAAM,MAAA,OAAA,GAAUA,gCAAgB,CAAA,MAAA,EAAQ,CAAC,CAAA,CAAA;AAIzC,EAAA,MAAM,UAAa,GAAA,OAAA,CAAQ,IAAK,CAAA,IAAA,CAAK,OAAO,CAAA,CAAA;AAE5C,EAAO,OAAA,MAAA,CAAO,OAAO,MAAQ,EAAA;AAAA,IAC3B,KAAQ,GAAA;AACN,MAAA,OAAO,IAAI,OAAA,CAAc,CAAC,OAAA,EAAS,MAAW,KAAA;AAC5C,QAAM,MAAA,kBAAA,GAAqB,CAAC,KAAiB,KAAA;AAC3C,UAAA,MAAA,CAAO,KAAM,EAAA,CAAA;AACb,UAAA,MAAA,CAAO,KAAK,CAAA,CAAA;AAAA,SACd,CAAA;AAEA,QAAO,MAAA,CAAA,EAAA,CAAG,SAAS,kBAAkB,CAAA,CAAA;AAErC,QAAA,MAAM,EAAE,IAAA,EAAM,IAAK,EAAA,GAAI,OAAQ,CAAA,MAAA,CAAA;AAC/B,QAAO,MAAA,CAAA,MAAA,CAAO,IAAM,EAAA,IAAA,EAAM,MAAM;AAC9B,UAAO,MAAA,CAAA,GAAA,CAAI,SAAS,kBAAkB,CAAA,CAAA;AACtC,UAAA,IAAA,CAAK,OAAO,IAAK,CAAA,CAAA,aAAA,EAAgB,IAAI,CAAA,CAAA,EAAI,IAAI,CAAE,CAAA,CAAA,CAAA;AAC/C,UAAQ,OAAA,EAAA,CAAA;AAAA,SACT,CAAA,CAAA;AAAA,OACF,CAAA,CAAA;AAAA,KACH;AAAA,IAEA,IAAO,GAAA;AACL,MAAA,OAAO,IAAI,OAAA,CAAc,CAAC,OAAA,EAAS,MAAW,KAAA;AAC5C,QAAA,UAAA,CAAW,CAAC,KAAkB,KAAA;AAC5B,UAAA,IAAI,KAAO,EAAA;AACT,YAAA,MAAA,CAAO,KAAK,CAAA,CAAA;AAAA,WACP,MAAA;AACL,YAAQ,OAAA,EAAA,CAAA;AAAA,WACV;AAAA,SACD,CAAA,CAAA;AAAA,OACF,CAAA,CAAA;AAAA,KACH;AAAA,IAEA,IAAO,GAAA;AACL,MAAM,MAAA,OAAA,GAAU,OAAO,OAAQ,EAAA,CAAA;AAC/B,MAAA,IAAI,OAAO,OAAA,KAAY,QAAY,IAAA,OAAA,KAAY,IAAM,EAAA;AACnD,QAAA,MAAM,IAAI,KAAA,CAAM,CAA8B,2BAAA,EAAA,OAAO,CAAG,CAAA,CAAA,CAAA,CAAA;AAAA,OAC1D;AACA,MAAA,OAAO,OAAQ,CAAA,IAAA,CAAA;AAAA,KACjB;AAAA,GACD,CAAA,CAAA;AACH,CAAA;AAEA,eAAe,YAAA,CACb,QACA,EAAA,OAAA,EACA,IACsB,EAAA;AACtB,EAAA,IAAI,QAAQ,KAAO,EAAA;AACjB,IAAM,MAAA,EAAE,WAAY,EAAA,GAAI,OAAQ,CAAA,KAAA,CAAA;AAChC,IAAI,IAAA,WAAA,CAAY,SAAS,WAAa,EAAA;AACpC,MAAA,MAAM,cAAc,MAAMC,+CAAA;AAAA,QACxB,WAAY,CAAA,QAAA;AAAA,QACZ,IAAK,CAAA,MAAA;AAAA,OACP,CAAA;AACA,MAAO,OAAAC,gBAAA,CAAM,YAAa,CAAA,WAAA,EAAa,QAAQ,CAAA,CAAA;AAAA,KACjD;AACA,IAAO,OAAAA,gBAAA,CAAM,YAAa,CAAA,WAAA,EAAa,QAAQ,CAAA,CAAA;AAAA,GACjD;AAEA,EAAO,OAAAC,eAAA,CAAK,aAAa,QAAQ,CAAA,CAAA;AACnC;;;;"}