@contrast/agent-bundle 5.39.1 → 5.41.0

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 (279) hide show
  1. package/node_modules/@contrast/agent/lib/start-agent.js +50 -40
  2. package/node_modules/@contrast/agent/package.json +11 -11
  3. package/node_modules/@contrast/agent-swc-plugin/index.js +9 -3
  4. package/node_modules/@contrast/agent-swc-plugin/methods.js +15 -1
  5. package/node_modules/@contrast/agent-swc-plugin/package.json +5 -8
  6. package/node_modules/@contrast/agent-swc-plugin/rewriter.wasm +0 -0
  7. package/node_modules/@contrast/agentify/lib/index.js +2 -2
  8. package/node_modules/@contrast/agentify/package.json +15 -14
  9. package/node_modules/@contrast/architecture-components/package.json +5 -5
  10. package/node_modules/@contrast/assess/lib/dataflow/propagation/install/string/replace.js +6 -3
  11. package/node_modules/@contrast/assess/lib/dataflow/propagation/install/util-format.js +44 -21
  12. package/node_modules/@contrast/assess/lib/dataflow/sources/index.js +1 -1
  13. package/node_modules/@contrast/assess/lib/dataflow/sources/install/{body-parser1.js → body-parser.js} +2 -2
  14. package/node_modules/@contrast/assess/lib/dataflow/sources/install/koa/koa-bodyparsers.js +3 -1
  15. package/node_modules/@contrast/assess/lib/dataflow/sources/install/qs6.js +5 -5
  16. package/node_modules/@contrast/assess/lib/dataflow/sources/install/querystring.js +2 -1
  17. package/node_modules/@contrast/assess/lib/index.d.ts +0 -1
  18. package/node_modules/@contrast/assess/lib/make-source-context.js +7 -37
  19. package/node_modules/@contrast/assess/lib/sampler/common.js +7 -11
  20. package/node_modules/@contrast/assess/package.json +12 -11
  21. package/node_modules/@contrast/common/lib/constants.d.ts +6 -0
  22. package/node_modules/@contrast/common/lib/constants.js +8 -1
  23. package/node_modules/@contrast/common/lib/types.d.ts +7 -1
  24. package/node_modules/@contrast/common/package.json +1 -1
  25. package/node_modules/@contrast/config/lib/common.js +1 -1
  26. package/node_modules/@contrast/config/lib/config.js +49 -27
  27. package/node_modules/@contrast/config/lib/index.d.ts +3 -2
  28. package/node_modules/@contrast/config/lib/options.js +4 -4
  29. package/node_modules/@contrast/config/package.json +4 -3
  30. package/node_modules/@contrast/core/lib/sensitive-data-masking/protect-listener.js +15 -15
  31. package/node_modules/@contrast/core/package.json +6 -6
  32. package/node_modules/@contrast/deadzones/package.json +5 -5
  33. package/node_modules/@contrast/dep-hooks/package.json +3 -3
  34. package/node_modules/@contrast/esm-hooks/package.json +6 -6
  35. package/node_modules/@contrast/instrumentation/lib/index.js +0 -1
  36. package/node_modules/@contrast/instrumentation/package.json +5 -5
  37. package/node_modules/@contrast/library-analysis/lib/install/library-reporting/dep.json +300 -152
  38. package/node_modules/@contrast/library-analysis/lib/install/library-reporting/index.js +9 -2
  39. package/node_modules/@contrast/library-analysis/lib/install/library-reporting/utils.js +54 -43
  40. package/node_modules/@contrast/library-analysis/package.json +4 -4
  41. package/node_modules/@contrast/logger/lib/serializers.js +2 -2
  42. package/node_modules/@contrast/logger/package.json +3 -3
  43. package/node_modules/@contrast/metrics/package.json +6 -6
  44. package/node_modules/@contrast/patcher/package.json +2 -2
  45. package/node_modules/@contrast/protect/lib/get-source-context.js +3 -1
  46. package/node_modules/@contrast/protect/lib/index.js +6 -1
  47. package/node_modules/@contrast/protect/lib/input-analysis/handlers.js +7 -9
  48. package/node_modules/@contrast/protect/lib/input-analysis/index.js +1 -1
  49. package/node_modules/@contrast/protect/lib/input-analysis/install/{body-parser1.js → body-parser.js} +1 -1
  50. package/node_modules/@contrast/protect/lib/input-analysis/install/http.js +18 -19
  51. package/node_modules/@contrast/protect/lib/input-analysis/install/qs6.js +18 -17
  52. package/node_modules/@contrast/protect/lib/input-analysis/install/universal-cookie4.js +2 -3
  53. package/node_modules/@contrast/protect/lib/make-source-context.js +22 -66
  54. package/node_modules/@contrast/protect/lib/semantic-analysis/handlers.js +73 -72
  55. package/node_modules/@contrast/protect/package.json +11 -11
  56. package/node_modules/@contrast/reporter/lib/reporters/contrast-ui/endpoints/application-activity/index.js +7 -7
  57. package/node_modules/@contrast/reporter/lib/reporters/contrast-ui/endpoints/application-activity/translations.d.ts +3 -3
  58. package/node_modules/@contrast/reporter/lib/reporters/contrast-ui/endpoints/application-activity/translations.js +24 -21
  59. package/node_modules/@contrast/reporter/lib/reporters/contrast-ui/endpoints/routes-observed.js +2 -1
  60. package/node_modules/@contrast/reporter/lib/reporters/contrast-ui/endpoints/traces/index.js +1 -1
  61. package/node_modules/@contrast/reporter/lib/reporters/contrast-ui/endpoints/traces/translations.d.ts +1 -2
  62. package/node_modules/@contrast/reporter/lib/reporters/contrast-ui/endpoints/traces/translations.js +8 -2
  63. package/node_modules/@contrast/reporter/lib/reporters/security-logger/index.d.ts +2 -2
  64. package/node_modules/@contrast/reporter/lib/reporters/security-logger/index.js +22 -20
  65. package/node_modules/@contrast/reporter/package.json +7 -7
  66. package/node_modules/@contrast/rewriter/lib/index.js +2 -2
  67. package/node_modules/@contrast/rewriter/package.json +6 -6
  68. package/node_modules/@contrast/route-coverage/lib/index.d.ts +2 -0
  69. package/node_modules/@contrast/route-coverage/lib/index.js +15 -17
  70. package/node_modules/@contrast/route-coverage/lib/install/express/express5.js +489 -202
  71. package/node_modules/@contrast/route-coverage/package.json +9 -9
  72. package/node_modules/@contrast/scopes/package.json +5 -5
  73. package/node_modules/@contrast/sec-obs/lib/traces/http.js +2 -2
  74. package/node_modules/@contrast/sec-obs/lib/traces/http.test.js +17 -0
  75. package/node_modules/@contrast/sec-obs/lib/traces/outbound-service-call.js +2 -2
  76. package/node_modules/@contrast/sec-obs/lib/traces/outbound-service-call.test.js +17 -0
  77. package/node_modules/@contrast/sec-obs/package.json +9 -9
  78. package/node_modules/@contrast/sources/lib/index.js +109 -0
  79. package/node_modules/@contrast/sources/lib/index.test.js +120 -0
  80. package/node_modules/@contrast/{route-coverage/lib/normalized-url-mapper.js → sources/lib/normalized-uri-mapper.js} +10 -3
  81. package/node_modules/@contrast/sources/lib/normalized-uri-mapper.test.js +59 -0
  82. package/node_modules/@contrast/{sec-obs/node_modules/@contrast/core/lib/sensitive-data-masking/constants.js → sources/lib/req-data.js} +0 -6
  83. package/node_modules/@contrast/sources/lib/source-info.js +183 -0
  84. package/node_modules/@contrast/sources/lib/source-info.test.js +68 -0
  85. package/node_modules/@contrast/sources/package.json +16 -0
  86. package/node_modules/@contrast/telemetry/package.json +6 -6
  87. package/node_modules/@opentelemetry/semantic-conventions/build/esm/experimental_attributes.d.ts +2831 -77
  88. package/node_modules/@opentelemetry/semantic-conventions/build/esm/experimental_attributes.js +2831 -77
  89. package/node_modules/@opentelemetry/semantic-conventions/build/esm/experimental_attributes.js.map +1 -1
  90. package/node_modules/@opentelemetry/semantic-conventions/build/esm/experimental_metrics.d.ts +415 -98
  91. package/node_modules/@opentelemetry/semantic-conventions/build/esm/experimental_metrics.js +415 -98
  92. package/node_modules/@opentelemetry/semantic-conventions/build/esm/experimental_metrics.js.map +1 -1
  93. package/node_modules/@opentelemetry/semantic-conventions/build/esm/stable_attributes.d.ts +106 -0
  94. package/node_modules/@opentelemetry/semantic-conventions/build/esm/stable_attributes.js +106 -0
  95. package/node_modules/@opentelemetry/semantic-conventions/build/esm/stable_attributes.js.map +1 -1
  96. package/node_modules/@opentelemetry/semantic-conventions/build/esm/version.d.ts +1 -1
  97. package/node_modules/@opentelemetry/semantic-conventions/build/esm/version.js +1 -1
  98. package/node_modules/@opentelemetry/semantic-conventions/build/esm/version.js.map +1 -1
  99. package/node_modules/@opentelemetry/semantic-conventions/build/esnext/experimental_attributes.d.ts +2831 -77
  100. package/node_modules/@opentelemetry/semantic-conventions/build/esnext/experimental_attributes.js +2831 -77
  101. package/node_modules/@opentelemetry/semantic-conventions/build/esnext/experimental_attributes.js.map +1 -1
  102. package/node_modules/@opentelemetry/semantic-conventions/build/esnext/experimental_metrics.d.ts +415 -98
  103. package/node_modules/@opentelemetry/semantic-conventions/build/esnext/experimental_metrics.js +415 -98
  104. package/node_modules/@opentelemetry/semantic-conventions/build/esnext/experimental_metrics.js.map +1 -1
  105. package/node_modules/@opentelemetry/semantic-conventions/build/esnext/stable_attributes.d.ts +106 -0
  106. package/node_modules/@opentelemetry/semantic-conventions/build/esnext/stable_attributes.js +106 -0
  107. package/node_modules/@opentelemetry/semantic-conventions/build/esnext/stable_attributes.js.map +1 -1
  108. package/node_modules/@opentelemetry/semantic-conventions/build/esnext/version.d.ts +1 -1
  109. package/node_modules/@opentelemetry/semantic-conventions/build/esnext/version.js +1 -1
  110. package/node_modules/@opentelemetry/semantic-conventions/build/esnext/version.js.map +1 -1
  111. package/node_modules/@opentelemetry/semantic-conventions/build/src/experimental_attributes.d.ts +2831 -77
  112. package/node_modules/@opentelemetry/semantic-conventions/build/src/experimental_attributes.js +2858 -103
  113. package/node_modules/@opentelemetry/semantic-conventions/build/src/experimental_attributes.js.map +1 -1
  114. package/node_modules/@opentelemetry/semantic-conventions/build/src/experimental_metrics.d.ts +415 -98
  115. package/node_modules/@opentelemetry/semantic-conventions/build/src/experimental_metrics.js +420 -102
  116. package/node_modules/@opentelemetry/semantic-conventions/build/src/experimental_metrics.js.map +1 -1
  117. package/node_modules/@opentelemetry/semantic-conventions/build/src/stable_attributes.d.ts +106 -0
  118. package/node_modules/@opentelemetry/semantic-conventions/build/src/stable_attributes.js +106 -0
  119. package/node_modules/@opentelemetry/semantic-conventions/build/src/stable_attributes.js.map +1 -1
  120. package/node_modules/@opentelemetry/semantic-conventions/build/src/version.d.ts +1 -1
  121. package/node_modules/@opentelemetry/semantic-conventions/build/src/version.js +1 -1
  122. package/node_modules/@opentelemetry/semantic-conventions/build/src/version.js.map +1 -1
  123. package/node_modules/@opentelemetry/semantic-conventions/package.json +3 -3
  124. package/node_modules/@types/node/README.md +2 -2
  125. package/node_modules/@types/node/buffer.d.ts +5 -0
  126. package/node_modules/@types/node/dns/promises.d.ts +11 -10
  127. package/node_modules/@types/node/dns.d.ts +18 -19
  128. package/node_modules/@types/node/fs.d.ts +13 -1
  129. package/node_modules/@types/node/http.d.ts +4 -19
  130. package/node_modules/@types/node/inspector.d.ts +53 -0
  131. package/node_modules/@types/node/package.json +2 -82
  132. package/node_modules/@types/node/stream/web.d.ts +4 -0
  133. package/node_modules/axios/CHANGELOG.md +17 -0
  134. package/node_modules/axios/README.md +1 -4
  135. package/node_modules/axios/dist/axios.js +39 -5
  136. package/node_modules/axios/dist/axios.js.map +1 -1
  137. package/node_modules/axios/dist/axios.min.js +2 -2
  138. package/node_modules/axios/dist/axios.min.js.map +1 -1
  139. package/node_modules/axios/dist/browser/axios.cjs +46 -9
  140. package/node_modules/axios/dist/browser/axios.cjs.map +1 -1
  141. package/node_modules/axios/dist/esm/axios.js +46 -9
  142. package/node_modules/axios/dist/esm/axios.js.map +1 -1
  143. package/node_modules/axios/dist/esm/axios.min.js +2 -2
  144. package/node_modules/axios/dist/esm/axios.min.js.map +1 -1
  145. package/node_modules/axios/dist/node/axios.cjs +46 -9
  146. package/node_modules/axios/dist/node/axios.cjs.map +1 -1
  147. package/node_modules/axios/index.d.cts +13 -2
  148. package/node_modules/axios/lib/core/Axios.js +2 -2
  149. package/node_modules/axios/lib/core/mergeConfig.js +1 -1
  150. package/node_modules/axios/lib/env/data.js +1 -1
  151. package/node_modules/axios/lib/helpers/throttle.js +1 -1
  152. package/node_modules/axios/lib/helpers/toURLEncodedForm.js +4 -3
  153. package/node_modules/axios/lib/utils.js +36 -0
  154. package/node_modules/axios/package.json +5 -5
  155. package/node_modules/deepmerge/.editorconfig +7 -0
  156. package/node_modules/deepmerge/.eslintcache +1 -0
  157. package/node_modules/deepmerge/changelog.md +167 -0
  158. package/node_modules/deepmerge/dist/cjs.js +133 -0
  159. package/node_modules/deepmerge/dist/umd.js +139 -0
  160. package/node_modules/deepmerge/index.d.ts +20 -0
  161. package/node_modules/deepmerge/index.js +106 -0
  162. package/node_modules/{path-to-regexp/LICENSE → deepmerge/license.txt} +1 -1
  163. package/node_modules/deepmerge/package.json +42 -0
  164. package/node_modules/deepmerge/readme.md +264 -0
  165. package/node_modules/deepmerge/rollup.config.js +22 -0
  166. package/node_modules/follow-redirects/package.json +1 -1
  167. package/node_modules/form-data/CHANGELOG.md +601 -0
  168. package/node_modules/form-data/{Readme.md → README.md} +4 -4
  169. package/node_modules/form-data/lib/form_data.js +2 -6
  170. package/node_modules/form-data/package.json +22 -6
  171. package/node_modules/nan/.github/workflows/ci.yml +8 -10
  172. package/node_modules/nan/.pre-commit-config.yaml +8 -0
  173. package/node_modules/nan/CHANGELOG.md +5 -1
  174. package/node_modules/nan/README.md +4 -4
  175. package/node_modules/nan/nan.h +16 -12
  176. package/node_modules/nan/nan_callbacks.h +13 -0
  177. package/node_modules/nan/nan_callbacks_12_inl.h +16 -2
  178. package/node_modules/nan/nan_callbacks_pre_12_inl.h +6 -2
  179. package/node_modules/nan/nan_maybe_43_inl.h +1 -1
  180. package/node_modules/nan/nan_maybe_pre_43_inl.h +1 -1
  181. package/node_modules/nan/nan_scriptorigin.h +11 -9
  182. package/node_modules/nan/nan_typedarray_contents.h +1 -1
  183. package/node_modules/nan/package.json +2 -2
  184. package/package.json +5 -3
  185. package/node_modules/@contrast/agentify/lib/sources.js +0 -94
  186. package/node_modules/@contrast/route-coverage/lib/install/http.js +0 -44
  187. package/node_modules/@contrast/sec-obs/node_modules/@contrast/common/LICENSE +0 -12
  188. package/node_modules/@contrast/sec-obs/node_modules/@contrast/common/lib/constants.d.ts +0 -385
  189. package/node_modules/@contrast/sec-obs/node_modules/@contrast/common/lib/constants.js +0 -270
  190. package/node_modules/@contrast/sec-obs/node_modules/@contrast/common/lib/index.d.ts +0 -40
  191. package/node_modules/@contrast/sec-obs/node_modules/@contrast/common/lib/index.js +0 -228
  192. package/node_modules/@contrast/sec-obs/node_modules/@contrast/common/lib/primordials.d.ts +0 -65
  193. package/node_modules/@contrast/sec-obs/node_modules/@contrast/common/lib/primordials.js +0 -66
  194. package/node_modules/@contrast/sec-obs/node_modules/@contrast/common/lib/types.d.ts +0 -383
  195. package/node_modules/@contrast/sec-obs/node_modules/@contrast/common/lib/types.js +0 -30
  196. package/node_modules/@contrast/sec-obs/node_modules/@contrast/common/package.json +0 -23
  197. package/node_modules/@contrast/sec-obs/node_modules/@contrast/config/LICENSE +0 -12
  198. package/node_modules/@contrast/sec-obs/node_modules/@contrast/config/README.md +0 -44
  199. package/node_modules/@contrast/sec-obs/node_modules/@contrast/config/lib/common.js +0 -131
  200. package/node_modules/@contrast/sec-obs/node_modules/@contrast/config/lib/config.js +0 -290
  201. package/node_modules/@contrast/sec-obs/node_modules/@contrast/config/lib/index.d.ts +0 -328
  202. package/node_modules/@contrast/sec-obs/node_modules/@contrast/config/lib/index.js +0 -29
  203. package/node_modules/@contrast/sec-obs/node_modules/@contrast/config/lib/options.js +0 -836
  204. package/node_modules/@contrast/sec-obs/node_modules/@contrast/config/lib/validators.js +0 -23
  205. package/node_modules/@contrast/sec-obs/node_modules/@contrast/config/package.json +0 -27
  206. package/node_modules/@contrast/sec-obs/node_modules/@contrast/core/LICENSE +0 -12
  207. package/node_modules/@contrast/sec-obs/node_modules/@contrast/core/README.md +0 -98
  208. package/node_modules/@contrast/sec-obs/node_modules/@contrast/core/lib/agent-info.js +0 -36
  209. package/node_modules/@contrast/sec-obs/node_modules/@contrast/core/lib/app-info.js +0 -233
  210. package/node_modules/@contrast/sec-obs/node_modules/@contrast/core/lib/build-id.js +0 -51
  211. package/node_modules/@contrast/sec-obs/node_modules/@contrast/core/lib/capture-stacktrace.js +0 -256
  212. package/node_modules/@contrast/sec-obs/node_modules/@contrast/core/lib/contrast-methods.js +0 -155
  213. package/node_modules/@contrast/sec-obs/node_modules/@contrast/core/lib/index.d.ts +0 -52
  214. package/node_modules/@contrast/sec-obs/node_modules/@contrast/core/lib/ioc/core.js +0 -95
  215. package/node_modules/@contrast/sec-obs/node_modules/@contrast/core/lib/is-agent-path.js +0 -37
  216. package/node_modules/@contrast/sec-obs/node_modules/@contrast/core/lib/messages.js +0 -28
  217. package/node_modules/@contrast/sec-obs/node_modules/@contrast/core/lib/sensitive-data-masking/index.js +0 -63
  218. package/node_modules/@contrast/sec-obs/node_modules/@contrast/core/lib/sensitive-data-masking/protect-listener.js +0 -111
  219. package/node_modules/@contrast/sec-obs/node_modules/@contrast/core/lib/sensitive-data-masking/server-settings-listener.js +0 -44
  220. package/node_modules/@contrast/sec-obs/node_modules/@contrast/core/lib/system-info/cloud-provider-metadata.js +0 -146
  221. package/node_modules/@contrast/sec-obs/node_modules/@contrast/core/lib/system-info/index.js +0 -225
  222. package/node_modules/@contrast/sec-obs/node_modules/@contrast/core/lib/system-info/linux-os-info.js +0 -137
  223. package/node_modules/@contrast/sec-obs/node_modules/@contrast/core/lib/system-info/utils.js +0 -35
  224. package/node_modules/@contrast/sec-obs/node_modules/@contrast/core/package.json +0 -33
  225. package/node_modules/@contrast/sec-obs/node_modules/@contrast/dep-hooks/LICENSE +0 -12
  226. package/node_modules/@contrast/sec-obs/node_modules/@contrast/dep-hooks/README.md +0 -94
  227. package/node_modules/@contrast/sec-obs/node_modules/@contrast/dep-hooks/lib/export-handler-registry.d.ts +0 -121
  228. package/node_modules/@contrast/sec-obs/node_modules/@contrast/dep-hooks/lib/export-handler-registry.js +0 -206
  229. package/node_modules/@contrast/sec-obs/node_modules/@contrast/dep-hooks/lib/export-hook-descriptor.d.ts +0 -72
  230. package/node_modules/@contrast/sec-obs/node_modules/@contrast/dep-hooks/lib/export-hook-descriptor.js +0 -88
  231. package/node_modules/@contrast/sec-obs/node_modules/@contrast/dep-hooks/lib/handler-invoker.d.ts +0 -46
  232. package/node_modules/@contrast/sec-obs/node_modules/@contrast/dep-hooks/lib/handler-invoker.js +0 -106
  233. package/node_modules/@contrast/sec-obs/node_modules/@contrast/dep-hooks/lib/helpers.d.ts +0 -28
  234. package/node_modules/@contrast/sec-obs/node_modules/@contrast/dep-hooks/lib/helpers.js +0 -66
  235. package/node_modules/@contrast/sec-obs/node_modules/@contrast/dep-hooks/lib/index.d.ts +0 -115
  236. package/node_modules/@contrast/sec-obs/node_modules/@contrast/dep-hooks/lib/index.js +0 -208
  237. package/node_modules/@contrast/sec-obs/node_modules/@contrast/dep-hooks/lib/package-finder.d.ts +0 -43
  238. package/node_modules/@contrast/sec-obs/node_modules/@contrast/dep-hooks/lib/package-finder.js +0 -79
  239. package/node_modules/@contrast/sec-obs/node_modules/@contrast/dep-hooks/package.json +0 -29
  240. package/node_modules/@contrast/sec-obs/node_modules/@contrast/logger/LICENSE +0 -12
  241. package/node_modules/@contrast/sec-obs/node_modules/@contrast/logger/README.md +0 -270
  242. package/node_modules/@contrast/sec-obs/node_modules/@contrast/logger/lib/index.d.ts +0 -16
  243. package/node_modules/@contrast/sec-obs/node_modules/@contrast/logger/lib/index.js +0 -132
  244. package/node_modules/@contrast/sec-obs/node_modules/@contrast/logger/lib/serializers.d.ts +0 -33
  245. package/node_modules/@contrast/sec-obs/node_modules/@contrast/logger/lib/serializers.js +0 -75
  246. package/node_modules/@contrast/sec-obs/node_modules/@contrast/logger/lib/utils.d.ts +0 -15
  247. package/node_modules/@contrast/sec-obs/node_modules/@contrast/logger/lib/utils.js +0 -34
  248. package/node_modules/@contrast/sec-obs/node_modules/@contrast/logger/package.json +0 -28
  249. package/node_modules/@contrast/sec-obs/node_modules/@contrast/patcher/LICENSE +0 -12
  250. package/node_modules/@contrast/sec-obs/node_modules/@contrast/patcher/README.md +0 -51
  251. package/node_modules/@contrast/sec-obs/node_modules/@contrast/patcher/lib/index.d.ts +0 -101
  252. package/node_modules/@contrast/sec-obs/node_modules/@contrast/patcher/lib/index.js +0 -544
  253. package/node_modules/@contrast/sec-obs/node_modules/@contrast/patcher/package.json +0 -25
  254. package/node_modules/@contrast/sec-obs/node_modules/@contrast/rewriter/LICENSE +0 -12
  255. package/node_modules/@contrast/sec-obs/node_modules/@contrast/rewriter/README.md +0 -6
  256. package/node_modules/@contrast/sec-obs/node_modules/@contrast/rewriter/lib/cache.js +0 -318
  257. package/node_modules/@contrast/sec-obs/node_modules/@contrast/rewriter/lib/index.js +0 -216
  258. package/node_modules/@contrast/sec-obs/node_modules/@contrast/rewriter/lib/rewrite-is-deadzoned.js +0 -143
  259. package/node_modules/@contrast/sec-obs/node_modules/@contrast/rewriter/package.json +0 -30
  260. package/node_modules/@contrast/sec-obs/node_modules/@contrast/scopes/LICENSE +0 -12
  261. package/node_modules/@contrast/sec-obs/node_modules/@contrast/scopes/lib/constants.js +0 -26
  262. package/node_modules/@contrast/sec-obs/node_modules/@contrast/scopes/lib/index.d.ts +0 -46
  263. package/node_modules/@contrast/sec-obs/node_modules/@contrast/scopes/lib/index.js +0 -70
  264. package/node_modules/@contrast/sec-obs/node_modules/@contrast/scopes/lib/install/bluebird.js +0 -128
  265. package/node_modules/@contrast/sec-obs/node_modules/@contrast/scopes/lib/install/index.js +0 -34
  266. package/node_modules/@contrast/sec-obs/node_modules/@contrast/scopes/lib/install/mongodb-core.js +0 -83
  267. package/node_modules/@contrast/sec-obs/node_modules/@contrast/scopes/lib/install/mongodb3.js +0 -89
  268. package/node_modules/@contrast/sec-obs/node_modules/@contrast/scopes/lib/install/mongodb4.js +0 -80
  269. package/node_modules/@contrast/sec-obs/node_modules/@contrast/scopes/lib/install/mongodb6.js +0 -46
  270. package/node_modules/@contrast/sec-obs/node_modules/@contrast/scopes/lib/install/mysql.js +0 -151
  271. package/node_modules/@contrast/sec-obs/node_modules/@contrast/scopes/lib/install/redis.js +0 -79
  272. package/node_modules/@contrast/sec-obs/node_modules/@contrast/scopes/lib/utils.js +0 -35
  273. package/node_modules/@contrast/sec-obs/node_modules/@contrast/scopes/package.json +0 -28
  274. package/node_modules/form-data/README.md.bak +0 -355
  275. package/node_modules/path-to-regexp/Readme.md +0 -216
  276. package/node_modules/path-to-regexp/dist/index.d.ts +0 -136
  277. package/node_modules/path-to-regexp/dist/index.js +0 -403
  278. package/node_modules/path-to-regexp/dist/index.js.map +0 -1
  279. package/node_modules/path-to-regexp/package.json +0 -62
@@ -14,6 +14,22 @@
14
14
  */
15
15
  'use strict';
16
16
 
17
+ const { AsyncLocalStorage } = require('node:async_hooks');
18
+ const {
19
+ get,
20
+ set,
21
+ isString,
22
+ Event,
23
+ primordials: {
24
+ ArrayPrototypeJoin,
25
+ StringPrototypeSubstring,
26
+ StringPrototypeToLowerCase,
27
+ StringPrototypeReplace,
28
+ }
29
+ } = require('@contrast/common');
30
+ const { funcInfo } = require('@contrast/fn-inspect');
31
+ const Core = require('@contrast/core/lib/ioc/core');
32
+
17
33
  const METHODS = [
18
34
  'all',
19
35
  'get',
@@ -24,233 +40,504 @@ const METHODS = [
24
40
  'options',
25
41
  'head',
26
42
  ];
27
- const framework = 'express';
28
- const { patchType, createSignature } = require('../../utils/route-info');
29
- const {
30
- isString,
31
- primordials: {
32
- ArrayPrototypeJoin,
33
- ArrayPrototypeSlice,
34
- StringPrototypeSplit,
35
- StringPrototypeToLowerCase,
36
- StringPrototypeReplace,
37
- StringPrototypeSlice,
38
- PathBasename
39
- }
40
- } = require('@contrast/common');
41
- const { match } = require('path-to-regexp');
42
- const fnInspect = require('@contrast/fn-inspect');
43
-
44
- module.exports = function init(core) {
45
-
46
- const discovered = [];
47
- const routerMap = new Map();
48
- const { patcher, depHooks, routeCoverage } = core;
49
-
50
- const removeTrailingSlash = (url) => (url.endsWith('/') && url !== '/') ? StringPrototypeSlice.call(url, 0, -1) : url;
51
- const format = (url) => Array.isArray(url)
52
- ? `/[${ArrayPrototypeJoin.call(url)}]`
53
- : removeTrailingSlash(url); // remove trailing slash
54
- const isRouter = (layer) => layer?.name && StringPrototypeToLowerCase.call(layer.name) === 'router';
55
-
56
- function getFnName({ method, file, lineNumber, column }) {
57
- if (method) return method;
58
- if (!file) return '(anonymous)';
59
- const base = PathBasename(file);
60
- return `(anonymous ${base} ${lineNumber}:${column})`;
61
- }
43
+ const componentName = 'routeCoverage.express5';
44
+ const kMetaKey = Symbol('cs_meta');
45
+ const enumerable = false;
62
46
 
63
- function createRouteInfo(url, method, obj, fn) {
64
- const fnInfo = fnInspect.funcInfo(fn);
65
- const fnName = getFnName(fnInfo);
66
- const originalUrl = url;
67
- url = format(url);
68
- return {
69
- url,
70
- method,
71
- fnName,
72
- framework,
73
- originalUrl,
74
- normalizedUrl: url,
75
- signature: createSignature(url, method, obj, fnName)
76
- };
77
- }
47
+ module.exports = Core.makeComponent({
48
+ name: componentName,
49
+ factory: (core) => new ExpressInstrumentation(core),
50
+ });
51
+
52
+ class ExpressInstrumentation {
53
+ constructor(core) {
54
+ // decorate
55
+ set(core, componentName, this);
78
56
 
79
- function updateRouteInfo(prefix, routeInfo) {
80
- const { url, normalizedUrl, fnName, method, addedPrefix = '' } = routeInfo;
81
- const updatedUrl = removeTrailingSlash(prefix + url);
82
- const updatedNormalizedUrl = removeTrailingSlash(prefix + normalizedUrl);
83
- const updatedAddedPrefix = removeTrailingSlash(prefix + addedPrefix);
84
- const updatedSignature = createSignature(updatedUrl, method, 'router', fnName);
85
- return {
86
- ...routeInfo,
87
- url: updatedUrl,
88
- addedPrefix: updatedAddedPrefix,
89
- normalizedUrl: updatedNormalizedUrl,
90
- signature: updatedSignature
91
- };
57
+ this.core = core;
58
+ this.methodScope = new AsyncLocalStorage();
59
+ this.handleScope = new AsyncLocalStorage();
92
60
  }
93
61
 
94
- function discover(routeInfo) {
95
- const { url, normalizedUrl, signature, method, framework } = routeInfo;
96
- if (!url || !normalizedUrl || !signature || !method || !framework) return;
97
- routeCoverage.discover({
98
- url,
99
- normalizedUrl,
100
- signature,
101
- method,
102
- framework
103
- });
62
+ install() {
63
+ const self = this;
64
+ const { core, handleScope, methodScope } = this;
65
+ const patchType = 'route-coverage-express';
66
+ const name = 'express-5';
104
67
 
105
- // Used to match urls during route observation
106
- let urlToMatch = routeInfo.normalizedUrl;
107
- if (Array.isArray(routeInfo.originalUrl)) {
108
- const prefix = routeInfo?.addedPrefix || '';
109
- urlToMatch = routeInfo.originalUrl.map(seg => prefix + seg);
110
- }
111
- const matchUrl = match(urlToMatch);
112
- routeInfo.match = matchUrl;
68
+ //
69
+ // discovery instrumentation
70
+ //
113
71
 
114
- discovered.push(routeInfo);
115
- }
72
+ core.depHooks.resolve({ name: 'express', version: '5' }, (express) => {
73
+ // wrap router and app methods in "method scope" to capture info to help build signatures.
74
+ // express has a number of APIs that work at different levels of abstraction, and we need to patch
75
+ // all of them. the scopes let us know what top-level APIs are being called by application code.
76
+ [...METHODS, 'use', 'route'].forEach((method) => {
77
+ // then setup app and router to run in method scopes
78
+ core.patcher.patch(express.application, method, {
79
+ name: `express.application.${method}`,
80
+ patchType: `${patchType}-discovery`,
81
+ around(next, data) {
82
+ if (methodScope.getStore()) return next();
83
+ return methodScope.run({ method, args: data.args, type: 'app' }, next);
84
+ }
85
+ });
116
86
 
117
- function wrapForObservation(handler, routeInfo, isRouter = false) {
118
- const handlerInfo = fnInspect.funcInfo(handler);
119
- const handlerName = getFnName(handlerInfo);
120
- return patcher.patch(handler, {
121
- name: 'handler',
122
- patchType,
123
- post(data) {
124
- const [req] = data.args;
125
- const [url] = StringPrototypeSplit.call(req.originalUrl, '?');
126
- const method = StringPrototypeToLowerCase.call(req.method);
127
- if (url && method) {
128
- if (isRouter) {
129
- for (const route of discovered) {
130
- if (route.match(url) && route.fnName === handlerName) {
131
- const { signature, normalizedUrl } = route;
132
- routeCoverage.observe({ url, method, signature, framework, normalizedUrl });
133
- break;
134
- }
135
- }
136
- } else {
137
- const { signature, normalizedUrl } = routeInfo;
138
- routeCoverage.observe({ url, method, signature, framework, normalizedUrl });
87
+ core.patcher.patch(express.Router.prototype, method, {
88
+ name: `express.Router.prototype.${method}`,
89
+ patchType: `${patchType}-discovery`,
90
+ around(next, data) {
91
+ if (methodScope.getStore()) return next();
92
+ return methodScope.run({ method, args: data.args, type: 'router' }, next);
139
93
  }
140
- }
141
- }
142
- });
143
- }
94
+ });
95
+ });
144
96
 
145
- return core.routeCoverage.express5 = {
146
- install() {
147
- depHooks.resolve({ name: 'express', version: '5' }, (express) => {
148
- METHODS.forEach((method) => {
149
- patcher.patch(express.application, method, {
150
- name: `express.application.${method}`,
151
- patchType,
152
- pre(data) {
153
- const [path, ...args] = data.args;
154
- if ((!isString(path) && !Array.isArray(path)) || path === '') return;
97
+ // app[method] and router[method] end up calling this
98
+ // Append metadata to the created Route object at layer.route.
99
+ // we also patch the returned Route's methods for building signatures
100
+ core.patcher.patch(express.Router.prototype, 'route', {
101
+ name: 'express.Route',
102
+ patchType: `${patchType}-discovery`,
103
+ post(data) {
104
+ const { result } = data;
105
+ const methodStore = methodScope.getStore();
106
+ const meta = {
107
+ paths: ExpressInstrumentation.normalizePaths(data.args[0]),
108
+ method: methodStore?.method,
109
+ type: methodStore?.type || 'route',
110
+ };
155
111
 
156
- const fns = args.flat(Infinity);
157
- for (let i = 0; i < fns.length; i++) {
158
- if (typeof fns[i] !== 'function') continue;
159
- const routeInfo = createRouteInfo(path, method, 'app', fns[i]);
112
+ Object.defineProperty(result, kMetaKey, {
113
+ enumerable,
114
+ value: meta
115
+ });
160
116
 
161
- discover(routeInfo);
162
- fns[i] = wrapForObservation(fns[i], routeInfo);
163
- }
164
- data.args.splice(1, fns.length, ...fns);
117
+ // patch route instance methods we do that here when we have
118
+ // todo move to prototype to help w/ memory
119
+ METHODS.forEach((method) => {
120
+ if (result[method]) {
121
+ core.patcher.patch(result, method, {
122
+ name: `express.Router.prototype.route${method}`,
123
+ patchType: `${patchType}-discovery`,
124
+ pre(data) {
125
+ data._stackIdx = data.obj.stack?.length;
126
+ },
127
+ post(data) {
128
+ if (data.obj.stack?.length > data._stackIdx) {
129
+ for (let i = data._stackIdx; i < data.obj.stack.length; i++) {
130
+ const layer = data.obj.stack[i];
131
+ const methodStore = methodScope.getStore();
132
+ const meta = {
133
+ type: methodStore?.type || 'route',
134
+ method: methodStore?.method == 'all' ? 'all' : method,
135
+ };
136
+
137
+ Object.defineProperty(layer, kMetaKey, {
138
+ enumerable,
139
+ value: meta,
140
+ });
141
+ }
142
+ }
143
+ },
144
+ });
165
145
  }
166
146
  });
167
147
 
168
- patcher.patch(express.Router.prototype, method, {
169
- name: `express.Router.prototype.${method}`,
170
- patchType,
171
- pre(data) {
172
- const Router = data.obj;
173
- const [path, ...args] = data.args;
174
- if (!isString(path) && !Array.isArray(path)) return;
175
-
176
- const fns = args.flat(Infinity);
177
- const routes = routerMap.get(Router) || [];
178
- for (let i = 0; i < fns.length; i++) {
179
- if (typeof fns[i] !== 'function') continue;
180
- const routeInfo = createRouteInfo(path, method, 'router', fns[i]);
148
+ return result;
149
+ },
150
+ });
181
151
 
182
- fns[i] = wrapForObservation(fns[i], routeInfo, true);
152
+ core.patcher.patch(express.Router.prototype, 'use', {
153
+ name: `${name}.Router.prototype.use`,
154
+ patchType: `${patchType}-discovery`,
155
+ pre(data) {
156
+ data._stackLength = data.obj.stack?.length;
157
+ },
158
+ post(data) {
159
+ if (data.obj.stack.length > data._stackLength) {
160
+ for (let i = data._stackLength; i < data.obj.stack.length; i++) {
161
+ const layer = data.obj.stack[i];
162
+ const paths = ExpressInstrumentation.normalizePaths(data.args[0]);
163
+ const methodStore = methodScope.getStore();
164
+ const meta = {
165
+ paths,
166
+ method: 'use',
167
+ type: methodStore?.type || 'router',
168
+ };
183
169
 
184
- routes.push(routeInfo);
185
- data.args.splice(1, fns.length, ...fns);
170
+ if (layer) {
171
+ Object.defineProperty(layer, kMetaKey, {
172
+ enumerable: false,
173
+ value: meta
174
+ });
186
175
  }
187
- routerMap.set(Router, routes);
188
176
  }
177
+ }
178
+ },
179
+ });
180
+
181
+ return core.patcher.patch(express, {
182
+ name: 'express-5.application',
183
+ patchType: `${patchType}-discovery`,
184
+ post(data) {
185
+ const app = data.result;
186
+ core.messages.on(Event.SERVER_LISTENING, () => {
187
+ if (!app.router.stack[0]) {
188
+ core.logger.debug('no routes detected in express router stack');
189
+ return;
190
+ }
191
+ self.handleDiscovery(app);
189
192
  });
190
- });
193
+ return app;
194
+ }
195
+ });
196
+ });
191
197
 
192
- let appRouter;
193
- patcher.patch(express.application, 'use', {
194
- name: 'express.application.use',
195
- patchType,
196
- pre(data) {
197
- appRouter = data.obj.router;
198
-
199
- const arg0 = data.args[0];
200
- const prefix = (Array.isArray(arg0) || isString(arg0)) ? arg0 : undefined;
201
- const args = prefix ? ArrayPrototypeSlice.call(data.args, 1) : data.args;
202
- const fns = args.flat(Infinity);
203
- for (let i = 0; i < fns.length; i++) {
204
- if (isRouter(fns[i])) {
205
- let routes = routerMap.get(fns[i]);
206
- if (routes) {
207
- if (prefix) routes = routes.map(route => updateRouteInfo(prefix, route));
208
- routes.forEach((route) => discover(route));
198
+ core.depHooks.resolve({ name: 'express', version: '5' }, (express) => {
199
+ core.patcher.patch(express.application, 'handle', {
200
+ name: 'express.application.handle',
201
+ patchType: `${patchType}-discovery`,
202
+ around(next, data) {
203
+ // wrap request handling in "handle scope". the scope's store data
204
+ // helps for building observation templates as routing occurs
205
+ const store = {
206
+ matchIdx: -1,
207
+ templateSegments: [],
208
+ };
209
+ return handleScope.run(store, next);
210
+ }
211
+ });
212
+ });
213
+
214
+ //
215
+ // observation instrumentation
216
+ //
217
+
218
+ // when Layer.match gets called, matchers functions run underneath. the API doesn't present a really clean
219
+ // way to instrument, so we're using scopes. we reference the scope's store in the instrumented matcher
220
+ // functions so we can correlate a matcher that succeeds to its corresponding route template segment.
221
+ core.depHooks.resolve({ name: 'router', file: 'lib/layer.js', version: '2' }, (Layer) => {
222
+ core.patcher.patch(Layer.prototype, 'match', {
223
+ name: 'Layer.prototype.match',
224
+ patchType: `${patchType}-observation`,
225
+ pre(data) {
226
+ data._store = handleScope.getStore();
227
+ if (!data._store) return;
228
+
229
+ // we check in post hook whether any matcher instrumentation reset this in scope.
230
+ // matchers will set this to a number only if multiple matchers run and one succeeds.
231
+ // use the index of that matcher to get associated template segment from the metadata.
232
+ data._store.matcherIdx = null;
233
+ // save reference to metadata source
234
+ data[kMetaKey] = data.obj[kMetaKey] || data.obj.route?.[kMetaKey];
235
+ },
236
+ post(data) {
237
+ // whenever a layer matches, save the corresponding
238
+ // template segment metadata in the handle scope store
239
+ const { result } = data;
240
+ if (!result || !data._store || !data[kMetaKey]?.paths) return;
241
+
242
+ let template;
243
+ if (data._store.matcherIdx != null) {
244
+ template = data[kMetaKey].paths[data._store.matcherIdx];
245
+ } else {
246
+ template = data[kMetaKey].paths[0];
247
+ }
248
+
249
+ // if the layer matches, we know to push corresponding path to store's template segments.
250
+ // we pop this value from the array in hook to all `next` callbacks below.
251
+ data._store.templateSegments.push(template);
252
+ }
253
+ });
254
+
255
+ // patch the `next` callback of every Layer's request handler.
256
+ // we pop the value from the stack of route template segments being managed.
257
+ core.patcher.patch(Layer.prototype, 'handleRequest', {
258
+ name: 'Layer.prototype.handleRequest',
259
+ patchType: `${patchType}-observation`,
260
+ pre(data) {
261
+ const next = data.args[2];
262
+ const meta = data.obj[kMetaKey] || data.obj.route?.[kMetaKey];
263
+ if (meta?.paths) {
264
+ const store = handleScope.getStore();
265
+ // this runs often and there's no need to use patcher here. monkey patch directly to optimize
266
+ data.args[2] = function(...args) {
267
+ if (store) store.templateSegments.pop();
268
+ const ret = next(...args);
269
+ return ret;
270
+ };
271
+ }
272
+ }
273
+ });
274
+
275
+ // instrument the Layer constructor. this will allow us to patch
276
+ // created matchers to help us build observation template from metadata.
277
+ // if matcher was successful we store index of it in handle scope.
278
+ return core.patcher.patch(Layer, {
279
+ name: 'router.Layer',
280
+ patchType: `${patchType}-observation`,
281
+ pre(data) {
282
+ data._methodScope = methodScope.getStore();
283
+ },
284
+ post(data) {
285
+ const instance = data.result;
286
+ // only instrument matchers if the Layer is being instantiated within method scope, and
287
+ // if there are multiple matchers and we need the index to correlate to tempate segment
288
+ if (data._methodScope && instance.matchers.length > 1) {
289
+ for (let i = 0; i < instance.matchers.length; i++) {
290
+ const matcher = instance.matchers[i];
291
+ instance.matchers[i] = function(...args) {
292
+ const result = matcher.apply(this, args);
293
+ if (result) {
294
+ const store = handleScope.getStore();
295
+ if (store) store.matcherIdx = i;
209
296
  }
210
- } else if (prefix && typeof fns[i] === 'function') {
211
- const routeInfo = createRouteInfo(prefix, 'use', 'app', fns[i]);
212
- discover(routeInfo);
213
- fns[i] = wrapForObservation(fns[i], routeInfo);
214
- }
297
+ return result;
298
+ };
215
299
  }
216
- data.args.splice(prefix ? 1 : 0, fns.length, ...fns);
217
300
  }
218
- });
219
- patcher.patch(express.Router.prototype, 'use', {
220
- name: 'express.Router.prototype.use',
221
- patchType,
222
- pre(data) {
223
- const Router = data.obj;
224
- const isAppRouter = Router === appRouter;
225
- if (isAppRouter) return;
226
-
227
- let routerRoutes = routerMap.get(Router) || [];
228
-
229
- const arg0 = data.args[0];
230
- let prefix = (Array.isArray(arg0) || isString(arg0)) ? arg0 : undefined;
231
- const args = prefix ? ArrayPrototypeSlice.call(data.args, 1) : data.args;
232
- const fns = args.flat(Infinity);
233
-
234
- for (let i = 0; i < fns.length; i++) {
235
- const selfNested = fns[i] === Router;
236
- if (isRouter(fns[i])) {
237
- let routes = routerMap.get(fns[i]) || [];
238
- if (prefix) {
239
- if (selfNested) prefix = StringPrototypeReplace.call(prefix, '/', '/*');
240
- routes = routes.map(route => updateRouteInfo(prefix, route));
301
+ // patch handle to report observation when called. it checks handle
302
+ // scope to get current request's template to match with discovery info
303
+ core.patcher.patch(instance, 'handle', {
304
+ name: 'router.Layer.handle',
305
+ patchType: `${patchType}-observation`,
306
+ pre(data) {
307
+ if (instance[kMetaKey]?.observables) {
308
+ const store = handleScope.getStore();
309
+ if (store) {
310
+ const method = StringPrototypeToLowerCase.call(data.args[0].method || '');
311
+ const template = ArrayPrototypeJoin.call(store.templateSegments, '') || '/';
312
+
313
+ if (instance[kMetaKey]?.observables?.[template]) {
314
+ self.observe({
315
+ url: data.args[0].originalUrl,
316
+ normalizedUrl: template,
317
+ method,
318
+ signature: instance[kMetaKey].observables[template],
319
+ });
320
+ } else {
321
+ core.logger.error({
322
+ // url: data.args[0].originalUrl, // this would need masking to log
323
+ method,
324
+ template,
325
+ observables: instance[kMetaKey]?.observables,
326
+ }, 'unable to map route template to signature');
327
+ }
241
328
  }
242
- routerRoutes = selfNested ? routes : routerRoutes.concat(routes);
243
- } else if (prefix && typeof fns[i] === 'function') {
244
- const routeInfo = createRouteInfo(prefix, 'use', 'router', fns[i]);
245
- routerRoutes.push(routeInfo);
246
- fns[i] = wrapForObservation(fns[i], routeInfo);
247
329
  }
330
+ },
331
+ });
332
+ },
333
+ });
334
+ });
335
+ }
336
+
337
+ discover(info) {
338
+ const { method, observables } = info;
339
+ if (!method || !observables) return;
340
+
341
+ for (const [normalizedUrl, signature] of Object.entries(observables)) {
342
+ this.core.routeCoverage.discover({
343
+ url: normalizedUrl,
344
+ normalizedUrl,
345
+ method,
346
+ signature,
347
+ framework: 'express',
348
+ });
349
+ }
350
+ }
351
+
352
+ observe(info) {
353
+ this.core.routeCoverage.observe({ framework: 'express', ...info });
354
+ }
355
+
356
+ /**
357
+ * Traverse the application's router "stack" and generate route discovery events
358
+ * using layer/route metadata that was appended by methods like router.post().
359
+ * @param {object} app express instance
360
+ */
361
+ handleDiscovery(app) {
362
+ const self = this;
363
+ const router = app.router || app._router;
364
+
365
+ // traverse fn executes this callback when visiting Layer instances
366
+ this.traverse(router, (path, key, value, target, state) => {
367
+ if (value.stack?.length > 0 || value.route) return;
368
+
369
+ // get metadata for this Layer
370
+ // metadata is on Layers within stacks and on Routes instances.
371
+ const metas = [];
372
+ for (let i = 0; i < path.length; i++) {
373
+ const seg = path[i];
374
+ if (Number.isFinite((Number(seg))) || seg == 'route') {
375
+ const metaPath = ArrayPrototypeJoin.call(path.slice(0, i + 1), '.');
376
+ const layerOrRoute = get(router, metaPath);
377
+ if (layerOrRoute?.[kMetaKey]) {
378
+ metas.push(layerOrRoute[kMetaKey]);
379
+ }
380
+ }
381
+ }
382
+
383
+ // mounted routers aren't discoverable since they themselves don't
384
+ // represent routes, they dispatch to sub routers/route handlers.
385
+ if (value.name != 'router' && value.handle?.name != 'router') {
386
+ // `value` is a terminal Layer with observable signatures.
387
+ // emit discovery after appending metadata.
388
+ if (value[kMetaKey]) {
389
+ const observables = this.generateObservables(metas, value.handle);
390
+ if (observables) {
391
+ if (!value[kMetaKey].observables) {
392
+ value[kMetaKey].observables = observables;
393
+ } else {
394
+ Object.assign(value[kMetaKey].observables, observables);
248
395
  }
249
- routerMap.set(Router, routerRoutes);
250
- data.args.splice(prefix ? 1 : 0, fns.length, ...fns);
251
396
  }
252
- });
253
- });
397
+ self.discover(value[kMetaKey]);
398
+ }
399
+ }
400
+ });
401
+ }
402
+
403
+ /**
404
+ * Traverses the top-level app's routing stack and executes the provided callback when
405
+ * visiting nodes. The callback is invoked only to visit Layer instances, objects and
406
+ * functions, since these are the only 2 types that could have our metadata attached.
407
+ */
408
+ traverse(target, cb, path = [], data = new Map()) {
409
+ loopKeys: for (const key in target) {
410
+ path.push(key);
411
+
412
+ // only visit Layer instances
413
+ const maybeLayer = target[key];
414
+ if (
415
+ maybeLayer?.constructor?.name == 'Layer' &&
416
+ !maybeLayer?.stack?.length
417
+ ) {
418
+ let _data = data.get(maybeLayer);
419
+
420
+ if (!_data) {
421
+ _data = { paths: [] };
422
+ data.set(maybeLayer, _data);
423
+ }
424
+
425
+ // you can mount a router on itself
426
+ // prevent infinitely recursing into self-mounted routers
427
+ for (const visitedPath of _data.paths) {
428
+ // these conditions indicate recursive nesting at particular path
429
+ if (
430
+ path.length > visitedPath.length &&
431
+ visitedPath.every((el, i) => path[i] == el)
432
+ ) {
433
+ path.pop();
434
+ continue loopKeys;
435
+ }
436
+ }
437
+
438
+ _data.paths.push([...path]); // copy because path argument mutates
439
+
440
+ const halt = cb(path, key, maybeLayer, target) === false;
441
+ if (halt) return;
442
+ }
443
+
444
+ // might be able to fine-tune this a bit more
445
+ if (typeof maybeLayer == 'object' || typeof maybeLayer == 'function') {
446
+ this.traverse(maybeLayer, cb, path, data);
447
+ }
448
+
449
+ path.pop();
254
450
  }
255
- };
256
- };
451
+ }
452
+
453
+ generateObservables(metas, handler) {
454
+ const { core } = this;
455
+ handler = core.patcher.unwrap(handler);
456
+
457
+ let type = '';
458
+ let method = '';
459
+ let templates = [];
460
+ const info = funcInfo(handler);
461
+
462
+ // ignore 3rd-party mw/handlers
463
+ if (info.file?.includes?.('node_modules')) {
464
+ return null;
465
+ }
466
+
467
+ let file = info.file ?
468
+ StringPrototypeReplace.call(info.file, core.appInfo.app_dir, '') :
469
+ '';
470
+ if (file.length > 30) {
471
+ file = `...${StringPrototypeSubstring.call(file, file.length - 40)}`;
472
+ }
473
+ const handlerName = info.method || handler.name || 'anonymous';
474
+ const formattedHandler = (file && Number.isFinite(info.lineNumber) && Number.isFinite(info.column)) ?
475
+ `[${handlerName} ${file} ${info.lineNumber}:${info.column}]` :
476
+ `[Function: ${handlerName}]`; // what util.inspect(handler) would return
477
+
478
+ // loop backwards
479
+ for (let i = metas.length - 1; i >= 0; i--) {
480
+ const meta = metas[i];
481
+ // use the most recent `type` and `method` used when building routes, so don't overwrite if set
482
+ if (!type && meta.type) type = meta.type;
483
+ if (!method && meta.method) method = meta.method;
484
+
485
+ // builds out all possible template combinations that the Layer is able to handle during routing
486
+ if (Array.isArray(meta.paths)) {
487
+ if (!templates.length) {
488
+ templates = [...meta.paths];
489
+ } else {
490
+ const _t = [];
491
+ for (const templateSegment of meta.paths) {
492
+ for (const templateAcc of templates) {
493
+ _t.push(`${templateSegment}${templateAcc}`);
494
+ }
495
+ }
496
+ templates = [..._t];
497
+ }
498
+ }
499
+ }
500
+
501
+ // build signature lookup based on each template (normalizeUri)
502
+ const map = templates.reduce((acc, routeTemplate) => {
503
+ if (!routeTemplate) routeTemplate = '/';
504
+ acc[routeTemplate] = `${type}.${method}('${routeTemplate}', ${formattedHandler})`;
505
+ return acc;
506
+ }, {});
507
+
508
+ return map;
509
+ }
510
+
511
+ static normalizePathSegment(value) {
512
+ if (!value || value == '/') {
513
+ // app.[method](handler) and app.[method]('/', handler) are the same so default to empty string
514
+ return '';
515
+ }
516
+ if (value instanceof RegExp) {
517
+ const rxString = value.toString();
518
+ // todo: figure out best way to represent regexp in route template
519
+ return `/[${StringPrototypeSubstring.call(rxString, 1, rxString.length - 1)}]`;
520
+ }
521
+ return value;
522
+ }
523
+
524
+ static normalizePaths(paths) {
525
+ const ret = [];
526
+
527
+ // same as mounting as /
528
+ if (typeof paths == 'function') {
529
+ // default to ''
530
+ ret.push('');
531
+ } else if (isString(paths)) {
532
+ ret.push(ExpressInstrumentation.normalizePathSegment(paths));
533
+ } else if (Array.isArray(paths)) {
534
+ paths = paths.flat(Infinity).filter((v) => typeof v !== 'function');
535
+ if (paths.length) ret.push(...paths.map(ExpressInstrumentation.normalizePathSegment));
536
+ else ret.push('');
537
+ } else if (paths instanceof RegExp) {
538
+ ret.push(ExpressInstrumentation.normalizePathSegment(paths));
539
+ }
540
+
541
+ return ret;
542
+ }
543
+ }