appmap 0.60.0 → 0.62.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (998) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +6 -16
  3. data/ARCHITECTURE.md +68 -0
  4. data/CHANGELOG.md +33 -0
  5. data/exe/appmap-index +7 -0
  6. data/lib/appmap.rb +2 -0
  7. data/lib/appmap/agent.rb +0 -11
  8. data/lib/appmap/command/agent_setup/status.rb +1 -1
  9. data/lib/appmap/command/index.rb +25 -0
  10. data/lib/appmap/command/inspect.rb +0 -1
  11. data/lib/appmap/config.rb +8 -1
  12. data/lib/appmap/depends.rb +2 -0
  13. data/lib/appmap/depends/api.rb +84 -0
  14. data/lib/appmap/depends/configuration.rb +59 -0
  15. data/lib/appmap/depends/node_cli.rb +44 -0
  16. data/lib/appmap/depends/rake_tasks.rb +58 -0
  17. data/lib/appmap/depends/test_file_inspector.rb +89 -0
  18. data/lib/appmap/depends/test_runner.rb +106 -0
  19. data/lib/appmap/depends/util.rb +34 -0
  20. data/lib/appmap/service/integration_test_path_finder.rb +29 -25
  21. data/lib/appmap/service/test_command_provider.rb +5 -7
  22. data/lib/appmap/service/validator/config_validator.rb +9 -0
  23. data/lib/appmap/version.rb +1 -1
  24. data/node_modules/@appland/cli/CHANGELOG.md +96 -0
  25. data/node_modules/@appland/cli/package.json +49 -0
  26. data/node_modules/@appland/cli/src/appMapCatalog.js +39 -0
  27. data/node_modules/@appland/cli/src/appland/getAppMap.js +55 -0
  28. data/node_modules/@appland/cli/src/appland/listAppMaps.js +58 -0
  29. data/node_modules/@appland/cli/src/appland/settings.js +62 -0
  30. data/node_modules/@appland/cli/src/appland/types.d.ts +16 -0
  31. data/node_modules/@appland/cli/src/cli.js +576 -0
  32. data/node_modules/@appland/cli/src/database.js +197 -0
  33. data/node_modules/@appland/cli/src/depends.js +157 -0
  34. data/node_modules/@appland/cli/src/fingerprint/algorithms.js +71 -0
  35. data/node_modules/@appland/cli/src/fingerprint/canonicalize.js +70 -0
  36. data/node_modules/@appland/cli/src/fingerprint/canonicalize/base.js +58 -0
  37. data/node_modules/@appland/cli/src/fingerprint/canonicalize/classDependencies.js +36 -0
  38. data/node_modules/@appland/cli/src/fingerprint/canonicalize/classes.js +14 -0
  39. data/node_modules/@appland/cli/src/fingerprint/canonicalize/eventTree.js +19 -0
  40. data/node_modules/@appland/cli/src/fingerprint/canonicalize/httpClientRequests.js +18 -0
  41. data/node_modules/@appland/cli/src/fingerprint/canonicalize/httpServerRequests.js +18 -0
  42. data/node_modules/@appland/cli/src/fingerprint/canonicalize/info.js +55 -0
  43. data/node_modules/@appland/cli/src/fingerprint/canonicalize/labels.js +10 -0
  44. data/node_modules/@appland/cli/src/fingerprint/canonicalize/packageDependencies.js +36 -0
  45. data/node_modules/@appland/cli/src/fingerprint/canonicalize/packages.js +14 -0
  46. data/node_modules/@appland/cli/src/fingerprint/canonicalize/sqlNormalized.js +19 -0
  47. data/node_modules/@appland/cli/src/fingerprint/canonicalize/sqlTables.js +24 -0
  48. data/node_modules/@appland/cli/src/fingerprint/canonicalize/trace.js +57 -0
  49. data/node_modules/@appland/cli/src/fingerprint/canonicalize/unique.js +8 -0
  50. data/node_modules/@appland/cli/src/fingerprint/canonicalize/update.js +85 -0
  51. data/node_modules/@appland/cli/src/fingerprint/fingerprintDirectoryCommand.js +30 -0
  52. data/node_modules/@appland/cli/src/fingerprint/fingerprintQueue.js +30 -0
  53. data/node_modules/@appland/cli/src/fingerprint/fingerprintWatchCommand.js +64 -0
  54. data/node_modules/@appland/cli/src/fingerprint/fingerprinter.js +186 -0
  55. data/node_modules/@appland/cli/src/fingerprint/index.js +24 -0
  56. data/node_modules/@appland/cli/src/functionStats.js +168 -0
  57. data/node_modules/@appland/cli/src/inspect.js +7 -0
  58. data/node_modules/@appland/cli/src/inspect/fields.js +66 -0
  59. data/node_modules/@appland/cli/src/inspect/filter.js +105 -0
  60. data/node_modules/@appland/cli/src/inspect/home.js +64 -0
  61. data/node_modules/@appland/cli/src/inspect/print.js +231 -0
  62. data/node_modules/@appland/cli/src/inspect/reset.js +10 -0
  63. data/node_modules/@appland/cli/src/inspect/types.d.ts +11 -0
  64. data/node_modules/@appland/cli/src/inspect/undoFilter.js +10 -0
  65. data/node_modules/@appland/cli/src/inventoryCommand.js +59 -0
  66. data/node_modules/@appland/cli/src/search/codeObjectMatcher.js +75 -0
  67. data/node_modules/@appland/cli/src/search/constants.js +5 -0
  68. data/node_modules/@appland/cli/src/search/findCodeObjects.js +293 -0
  69. data/node_modules/@appland/cli/src/search/findEvents.js +184 -0
  70. data/node_modules/@appland/cli/src/search/matchFilter.js +65 -0
  71. data/node_modules/@appland/cli/src/search/matchSpec.js +198 -0
  72. data/node_modules/@appland/cli/src/search/trigram.js +107 -0
  73. data/node_modules/@appland/cli/src/search/types.d.ts +107 -0
  74. data/node_modules/@appland/cli/src/search/utils.js +4 -0
  75. data/node_modules/@appland/cli/src/swagger/README.md +75 -0
  76. data/node_modules/@appland/cli/src/swagger/command.js +42 -0
  77. data/node_modules/@appland/cli/src/swagger/method.js +173 -0
  78. data/node_modules/@appland/cli/src/swagger/model.js +54 -0
  79. data/node_modules/@appland/cli/src/swagger/path.js +38 -0
  80. data/node_modules/@appland/cli/src/swagger/response.js +34 -0
  81. data/node_modules/@appland/cli/src/swagger/schema.js +38 -0
  82. data/node_modules/@appland/cli/src/swagger/securitySchemes.js +60 -0
  83. data/node_modules/@appland/cli/src/swagger/settings.js +9 -0
  84. data/node_modules/@appland/cli/src/swagger/util.js +79 -0
  85. data/node_modules/@appland/cli/src/utils.js +164 -0
  86. data/node_modules/@appland/cli/tests/unit/depends.spec.js +55 -0
  87. data/node_modules/@appland/cli/tests/unit/fingerprint/canonicalize.spec.js +42 -0
  88. data/node_modules/@appland/cli/tests/unit/fingerprint/sql.spec.js +40 -0
  89. data/node_modules/@appland/cli/tests/unit/fixtures/app/controllers/organizations_controller.rb +1 -0
  90. data/node_modules/@appland/cli/tests/unit/fixtures/app/models/configuration.rb +1 -0
  91. data/node_modules/@appland/cli/tests/unit/fixtures/app/models/show.rb +1 -0
  92. data/node_modules/@appland/cli/tests/unit/fixtures/app/models/user.rb +1 -0
  93. data/node_modules/@appland/cli/tests/unit/fixtures/canonicalize/revoke_api_key.info.json +246 -0
  94. data/node_modules/@appland/cli/tests/unit/fixtures/canonicalize/revoke_api_key.trace.json +289 -0
  95. data/node_modules/@appland/cli/tests/unit/fixtures/canonicalize/revoke_api_key.update.json +78 -0
  96. data/node_modules/@appland/cli/tests/unit/fixtures/revoke_api_key.appmap.json +899 -0
  97. data/node_modules/@appland/cli/tests/unit/fixtures/user_page_scenario.appmap.json +1774 -0
  98. data/node_modules/@appland/cli/tests/unit/inspect.spec.js +94 -0
  99. data/node_modules/@appland/models/CHANGELOG.md +83 -0
  100. data/node_modules/@appland/models/README.md +8 -0
  101. data/node_modules/@appland/models/dist/index.cjs +4250 -0
  102. data/node_modules/@appland/models/dist/index.js +4193 -0
  103. data/node_modules/@appland/models/package.json +50 -0
  104. data/node_modules/@rollup/plugin-alias/CHANGELOG.md +92 -0
  105. data/node_modules/@rollup/plugin-alias/LICENSE +21 -0
  106. data/node_modules/@rollup/plugin-alias/README.md +174 -0
  107. data/node_modules/@rollup/plugin-alias/dist/index.es.js +95 -0
  108. data/node_modules/@rollup/plugin-alias/dist/index.js +101 -0
  109. data/node_modules/@rollup/plugin-alias/package.json +78 -0
  110. data/node_modules/@rollup/plugin-alias/types/index.d.ts +36 -0
  111. data/node_modules/ansi-regex/index.d.ts +37 -0
  112. data/node_modules/ansi-regex/index.js +10 -0
  113. data/node_modules/ansi-regex/license +9 -0
  114. data/node_modules/ansi-regex/package.json +55 -0
  115. data/node_modules/ansi-regex/readme.md +78 -0
  116. data/node_modules/ansi-styles/index.d.ts +345 -0
  117. data/node_modules/ansi-styles/index.js +163 -0
  118. data/node_modules/ansi-styles/license +9 -0
  119. data/node_modules/ansi-styles/package.json +56 -0
  120. data/node_modules/ansi-styles/readme.md +152 -0
  121. data/node_modules/anymatch/LICENSE +15 -0
  122. data/node_modules/anymatch/README.md +87 -0
  123. data/node_modules/anymatch/index.d.ts +19 -0
  124. data/node_modules/anymatch/index.js +104 -0
  125. data/node_modules/anymatch/package.json +48 -0
  126. data/node_modules/argparse/CHANGELOG.md +185 -0
  127. data/node_modules/argparse/LICENSE +21 -0
  128. data/node_modules/argparse/README.md +257 -0
  129. data/node_modules/argparse/index.js +3 -0
  130. data/node_modules/argparse/lib/action.js +146 -0
  131. data/node_modules/argparse/lib/action/append.js +53 -0
  132. data/node_modules/argparse/lib/action/append/constant.js +47 -0
  133. data/node_modules/argparse/lib/action/count.js +40 -0
  134. data/node_modules/argparse/lib/action/help.js +47 -0
  135. data/node_modules/argparse/lib/action/store.js +50 -0
  136. data/node_modules/argparse/lib/action/store/constant.js +43 -0
  137. data/node_modules/argparse/lib/action/store/false.js +27 -0
  138. data/node_modules/argparse/lib/action/store/true.js +26 -0
  139. data/node_modules/argparse/lib/action/subparsers.js +149 -0
  140. data/node_modules/argparse/lib/action/version.js +47 -0
  141. data/node_modules/argparse/lib/action_container.js +482 -0
  142. data/node_modules/argparse/lib/argparse.js +14 -0
  143. data/node_modules/argparse/lib/argument/error.js +50 -0
  144. data/node_modules/argparse/lib/argument/exclusive.js +54 -0
  145. data/node_modules/argparse/lib/argument/group.js +75 -0
  146. data/node_modules/argparse/lib/argument_parser.js +1161 -0
  147. data/node_modules/argparse/lib/const.js +21 -0
  148. data/node_modules/argparse/lib/help/added_formatters.js +87 -0
  149. data/node_modules/argparse/lib/help/formatter.js +795 -0
  150. data/node_modules/argparse/lib/namespace.js +76 -0
  151. data/node_modules/argparse/lib/utils.js +57 -0
  152. data/node_modules/argparse/package.json +34 -0
  153. data/node_modules/async/CHANGELOG.md +331 -0
  154. data/node_modules/async/LICENSE +19 -0
  155. data/node_modules/async/README.md +60 -0
  156. data/node_modules/async/all.js +54 -0
  157. data/node_modules/async/allLimit.js +46 -0
  158. data/node_modules/async/allSeries.js +45 -0
  159. data/node_modules/async/any.js +56 -0
  160. data/node_modules/async/anyLimit.js +47 -0
  161. data/node_modules/async/anySeries.js +46 -0
  162. data/node_modules/async/apply.js +55 -0
  163. data/node_modules/async/applyEach.js +57 -0
  164. data/node_modules/async/applyEachSeries.js +37 -0
  165. data/node_modules/async/asyncify.js +118 -0
  166. data/node_modules/async/auto.js +267 -0
  167. data/node_modules/async/autoInject.js +156 -0
  168. data/node_modules/async/bower.json +17 -0
  169. data/node_modules/async/cargo.js +63 -0
  170. data/node_modules/async/cargoQueue.js +71 -0
  171. data/node_modules/async/compose.js +55 -0
  172. data/node_modules/async/concat.js +47 -0
  173. data/node_modules/async/concatLimit.js +60 -0
  174. data/node_modules/async/concatSeries.js +41 -0
  175. data/node_modules/async/constant.js +55 -0
  176. data/node_modules/async/detect.js +61 -0
  177. data/node_modules/async/detectLimit.js +48 -0
  178. data/node_modules/async/detectSeries.js +47 -0
  179. data/node_modules/async/dir.js +43 -0
  180. data/node_modules/async/dist/async.js +4846 -0
  181. data/node_modules/async/dist/async.min.js +1 -0
  182. data/node_modules/async/dist/async.mjs +4734 -0
  183. data/node_modules/async/doDuring.js +68 -0
  184. data/node_modules/async/doUntil.js +46 -0
  185. data/node_modules/async/doWhilst.js +68 -0
  186. data/node_modules/async/during.js +78 -0
  187. data/node_modules/async/each.js +88 -0
  188. data/node_modules/async/eachLimit.js +50 -0
  189. data/node_modules/async/eachOf.js +116 -0
  190. data/node_modules/async/eachOfLimit.js +47 -0
  191. data/node_modules/async/eachOfSeries.js +39 -0
  192. data/node_modules/async/eachSeries.js +44 -0
  193. data/node_modules/async/ensureAsync.js +67 -0
  194. data/node_modules/async/every.js +54 -0
  195. data/node_modules/async/everyLimit.js +46 -0
  196. data/node_modules/async/everySeries.js +45 -0
  197. data/node_modules/async/filter.js +53 -0
  198. data/node_modules/async/filterLimit.js +45 -0
  199. data/node_modules/async/filterSeries.js +43 -0
  200. data/node_modules/async/find.js +61 -0
  201. data/node_modules/async/findLimit.js +48 -0
  202. data/node_modules/async/findSeries.js +47 -0
  203. data/node_modules/async/flatMap.js +47 -0
  204. data/node_modules/async/flatMapLimit.js +60 -0
  205. data/node_modules/async/flatMapSeries.js +41 -0
  206. data/node_modules/async/foldl.js +77 -0
  207. data/node_modules/async/foldr.js +41 -0
  208. data/node_modules/async/forEach.js +88 -0
  209. data/node_modules/async/forEachLimit.js +50 -0
  210. data/node_modules/async/forEachOf.js +116 -0
  211. data/node_modules/async/forEachOfLimit.js +47 -0
  212. data/node_modules/async/forEachOfSeries.js +39 -0
  213. data/node_modules/async/forEachSeries.js +44 -0
  214. data/node_modules/async/forever.js +68 -0
  215. data/node_modules/async/groupBy.js +54 -0
  216. data/node_modules/async/groupByLimit.js +71 -0
  217. data/node_modules/async/groupBySeries.js +36 -0
  218. data/node_modules/async/index.js +588 -0
  219. data/node_modules/async/inject.js +77 -0
  220. data/node_modules/async/internal/DoublyLinkedList.js +92 -0
  221. data/node_modules/async/internal/Heap.js +120 -0
  222. data/node_modules/async/internal/applyEach.js +29 -0
  223. data/node_modules/async/internal/asyncEachOfLimit.js +75 -0
  224. data/node_modules/async/internal/awaitify.js +27 -0
  225. data/node_modules/async/internal/breakLoop.js +10 -0
  226. data/node_modules/async/internal/consoleFunc.js +27 -0
  227. data/node_modules/async/internal/createTester.js +40 -0
  228. data/node_modules/async/internal/eachOfLimit.js +90 -0
  229. data/node_modules/async/internal/filter.js +55 -0
  230. data/node_modules/async/internal/getIterator.js +11 -0
  231. data/node_modules/async/internal/initialParams.js +14 -0
  232. data/node_modules/async/internal/isArrayLike.js +10 -0
  233. data/node_modules/async/internal/iterator.js +54 -0
  234. data/node_modules/async/internal/map.js +30 -0
  235. data/node_modules/async/internal/once.js +17 -0
  236. data/node_modules/async/internal/onlyOnce.js +15 -0
  237. data/node_modules/async/internal/parallel.js +34 -0
  238. data/node_modules/async/internal/promiseCallback.js +23 -0
  239. data/node_modules/async/internal/queue.js +291 -0
  240. data/node_modules/async/internal/range.js +14 -0
  241. data/node_modules/async/internal/reject.js +26 -0
  242. data/node_modules/async/internal/setImmediate.js +30 -0
  243. data/node_modules/async/internal/withoutIndex.js +10 -0
  244. data/node_modules/async/internal/wrapAsync.js +34 -0
  245. data/node_modules/async/log.js +41 -0
  246. data/node_modules/async/map.js +62 -0
  247. data/node_modules/async/mapLimit.js +45 -0
  248. data/node_modules/async/mapSeries.js +44 -0
  249. data/node_modules/async/mapValues.js +62 -0
  250. data/node_modules/async/mapValuesLimit.js +61 -0
  251. data/node_modules/async/mapValuesSeries.js +37 -0
  252. data/node_modules/async/memoize.js +91 -0
  253. data/node_modules/async/nextTick.js +52 -0
  254. data/node_modules/async/package.json +82 -0
  255. data/node_modules/async/parallel.js +91 -0
  256. data/node_modules/async/parallelLimit.js +41 -0
  257. data/node_modules/async/priorityQueue.js +84 -0
  258. data/node_modules/async/queue.js +167 -0
  259. data/node_modules/async/race.js +67 -0
  260. data/node_modules/async/reduce.js +77 -0
  261. data/node_modules/async/reduceRight.js +41 -0
  262. data/node_modules/async/reflect.js +78 -0
  263. data/node_modules/async/reflectAll.js +93 -0
  264. data/node_modules/async/reject.js +53 -0
  265. data/node_modules/async/rejectLimit.js +45 -0
  266. data/node_modules/async/rejectSeries.js +43 -0
  267. data/node_modules/async/retry.js +159 -0
  268. data/node_modules/async/retryable.js +77 -0
  269. data/node_modules/async/select.js +53 -0
  270. data/node_modules/async/selectLimit.js +45 -0
  271. data/node_modules/async/selectSeries.js +43 -0
  272. data/node_modules/async/seq.js +79 -0
  273. data/node_modules/async/series.js +86 -0
  274. data/node_modules/async/setImmediate.js +45 -0
  275. data/node_modules/async/some.js +56 -0
  276. data/node_modules/async/someLimit.js +47 -0
  277. data/node_modules/async/someSeries.js +46 -0
  278. data/node_modules/async/sortBy.js +88 -0
  279. data/node_modules/async/timeout.js +89 -0
  280. data/node_modules/async/times.js +50 -0
  281. data/node_modules/async/timesLimit.js +43 -0
  282. data/node_modules/async/timesSeries.js +32 -0
  283. data/node_modules/async/transform.js +81 -0
  284. data/node_modules/async/tryEach.js +78 -0
  285. data/node_modules/async/unmemoize.js +25 -0
  286. data/node_modules/async/until.js +61 -0
  287. data/node_modules/async/waterfall.js +105 -0
  288. data/node_modules/async/whilst.js +78 -0
  289. data/node_modules/async/wrapSync.js +118 -0
  290. data/node_modules/at-least-node/LICENSE +6 -0
  291. data/node_modules/at-least-node/README.md +25 -0
  292. data/node_modules/at-least-node/index.js +5 -0
  293. data/node_modules/at-least-node/package.json +32 -0
  294. data/node_modules/balanced-match/LICENSE.md +21 -0
  295. data/node_modules/balanced-match/README.md +97 -0
  296. data/node_modules/balanced-match/index.js +62 -0
  297. data/node_modules/balanced-match/package.json +48 -0
  298. data/node_modules/binary-extensions/binary-extensions.json +260 -0
  299. data/node_modules/binary-extensions/binary-extensions.json.d.ts +3 -0
  300. data/node_modules/binary-extensions/index.d.ts +14 -0
  301. data/node_modules/binary-extensions/index.js +1 -0
  302. data/node_modules/binary-extensions/license +9 -0
  303. data/node_modules/binary-extensions/package.json +38 -0
  304. data/node_modules/binary-extensions/readme.md +41 -0
  305. data/node_modules/brace-expansion/LICENSE +21 -0
  306. data/node_modules/brace-expansion/README.md +129 -0
  307. data/node_modules/brace-expansion/index.js +201 -0
  308. data/node_modules/brace-expansion/package.json +47 -0
  309. data/node_modules/braces/CHANGELOG.md +184 -0
  310. data/node_modules/braces/LICENSE +21 -0
  311. data/node_modules/braces/README.md +593 -0
  312. data/node_modules/braces/index.js +170 -0
  313. data/node_modules/braces/lib/compile.js +57 -0
  314. data/node_modules/braces/lib/constants.js +57 -0
  315. data/node_modules/braces/lib/expand.js +113 -0
  316. data/node_modules/braces/lib/parse.js +333 -0
  317. data/node_modules/braces/lib/stringify.js +32 -0
  318. data/node_modules/braces/lib/utils.js +112 -0
  319. data/node_modules/braces/package.json +77 -0
  320. data/node_modules/chokidar/LICENSE +21 -0
  321. data/node_modules/chokidar/README.md +308 -0
  322. data/node_modules/chokidar/index.js +973 -0
  323. data/node_modules/chokidar/lib/constants.js +65 -0
  324. data/node_modules/chokidar/lib/fsevents-handler.js +524 -0
  325. data/node_modules/chokidar/lib/nodefs-handler.js +646 -0
  326. data/node_modules/chokidar/package.json +78 -0
  327. data/node_modules/chokidar/types/index.d.ts +187 -0
  328. data/node_modules/cli-progress/CHANGES.md +169 -0
  329. data/node_modules/cli-progress/LICENSE.md +24 -0
  330. data/node_modules/cli-progress/README.md +446 -0
  331. data/node_modules/cli-progress/cli-progress.js +21 -0
  332. data/node_modules/cli-progress/lib/eta.js +73 -0
  333. data/node_modules/cli-progress/lib/format-bar.js +11 -0
  334. data/node_modules/cli-progress/lib/format-time.js +34 -0
  335. data/node_modules/cli-progress/lib/format-value.js +22 -0
  336. data/node_modules/cli-progress/lib/formatter.js +80 -0
  337. data/node_modules/cli-progress/lib/generic-bar.js +212 -0
  338. data/node_modules/cli-progress/lib/multi-bar.js +201 -0
  339. data/node_modules/cli-progress/lib/options.js +95 -0
  340. data/node_modules/cli-progress/lib/single-bar.js +124 -0
  341. data/node_modules/cli-progress/lib/terminal.js +159 -0
  342. data/node_modules/cli-progress/package.json +46 -0
  343. data/node_modules/cli-progress/presets/index.js +11 -0
  344. data/node_modules/cli-progress/presets/legacy.js +6 -0
  345. data/node_modules/cli-progress/presets/rect.js +5 -0
  346. data/node_modules/cli-progress/presets/shades-classic.js +6 -0
  347. data/node_modules/cli-progress/presets/shades-grey.js +8 -0
  348. data/node_modules/cliui/CHANGELOG.md +121 -0
  349. data/node_modules/cliui/LICENSE.txt +14 -0
  350. data/node_modules/cliui/README.md +141 -0
  351. data/node_modules/cliui/build/index.cjs +302 -0
  352. data/node_modules/cliui/build/lib/index.js +287 -0
  353. data/node_modules/cliui/build/lib/string-utils.js +27 -0
  354. data/node_modules/cliui/index.mjs +13 -0
  355. data/node_modules/cliui/package.json +83 -0
  356. data/node_modules/color-convert/CHANGELOG.md +54 -0
  357. data/node_modules/color-convert/LICENSE +21 -0
  358. data/node_modules/color-convert/README.md +68 -0
  359. data/node_modules/color-convert/conversions.js +839 -0
  360. data/node_modules/color-convert/index.js +81 -0
  361. data/node_modules/color-convert/package.json +48 -0
  362. data/node_modules/color-convert/route.js +97 -0
  363. data/node_modules/color-name/LICENSE +8 -0
  364. data/node_modules/color-name/README.md +11 -0
  365. data/node_modules/color-name/index.js +152 -0
  366. data/node_modules/color-name/package.json +28 -0
  367. data/node_modules/colors/LICENSE +25 -0
  368. data/node_modules/colors/README.md +221 -0
  369. data/node_modules/colors/examples/normal-usage.js +82 -0
  370. data/node_modules/colors/examples/safe-string.js +79 -0
  371. data/node_modules/colors/index.d.ts +136 -0
  372. data/node_modules/colors/lib/colors.js +211 -0
  373. data/node_modules/colors/lib/custom/trap.js +46 -0
  374. data/node_modules/colors/lib/custom/zalgo.js +110 -0
  375. data/node_modules/colors/lib/extendStringPrototype.js +110 -0
  376. data/node_modules/colors/lib/index.js +13 -0
  377. data/node_modules/colors/lib/maps/america.js +10 -0
  378. data/node_modules/colors/lib/maps/rainbow.js +12 -0
  379. data/node_modules/colors/lib/maps/random.js +11 -0
  380. data/node_modules/colors/lib/maps/zebra.js +5 -0
  381. data/node_modules/colors/lib/styles.js +95 -0
  382. data/node_modules/colors/lib/system/has-flag.js +35 -0
  383. data/node_modules/colors/lib/system/supports-colors.js +151 -0
  384. data/node_modules/colors/package.json +45 -0
  385. data/node_modules/colors/safe.d.ts +48 -0
  386. data/node_modules/colors/safe.js +10 -0
  387. data/node_modules/colors/themes/generic-logging.js +12 -0
  388. data/node_modules/concat-map/LICENSE +18 -0
  389. data/node_modules/concat-map/README.markdown +62 -0
  390. data/node_modules/concat-map/example/map.js +6 -0
  391. data/node_modules/concat-map/index.js +13 -0
  392. data/node_modules/concat-map/package.json +43 -0
  393. data/node_modules/concat-map/test/map.js +39 -0
  394. data/node_modules/console-table-printer/CHANGELOG.md +96 -0
  395. data/node_modules/console-table-printer/LICENSE +21 -0
  396. data/node_modules/console-table-printer/README.md +180 -0
  397. data/node_modules/console-table-printer/dist/index.d.ts +4 -0
  398. data/node_modules/console-table-printer/dist/index.js +10 -0
  399. data/node_modules/console-table-printer/dist/src/console-table-printer.d.ts +14 -0
  400. data/node_modules/console-table-printer/dist/src/console-table-printer.js +32 -0
  401. data/node_modules/console-table-printer/dist/src/internalTable/input-converter.d.ts +6 -0
  402. data/node_modules/console-table-printer/dist/src/internalTable/input-converter.js +15 -0
  403. data/node_modules/console-table-printer/dist/src/internalTable/internal-table-printer.d.ts +4 -0
  404. data/node_modules/console-table-printer/dist/src/internalTable/internal-table-printer.js +115 -0
  405. data/node_modules/console-table-printer/dist/src/internalTable/internal-table.d.ts +25 -0
  406. data/node_modules/console-table-printer/dist/src/internalTable/internal-table.js +80 -0
  407. data/node_modules/console-table-printer/dist/src/internalTable/table-pre-processors.d.ts +3 -0
  408. data/node_modules/console-table-printer/dist/src/internalTable/table-pre-processors.js +43 -0
  409. data/node_modules/console-table-printer/dist/src/models/common.d.ts +10 -0
  410. data/node_modules/console-table-printer/dist/src/models/common.js +2 -0
  411. data/node_modules/console-table-printer/dist/src/models/external-table.d.ts +26 -0
  412. data/node_modules/console-table-printer/dist/src/models/external-table.js +2 -0
  413. data/node_modules/console-table-printer/dist/src/models/internal-table.d.ts +21 -0
  414. data/node_modules/console-table-printer/dist/src/models/internal-table.js +2 -0
  415. data/node_modules/console-table-printer/dist/src/utils/colored-console-line.d.ts +8 -0
  416. data/node_modules/console-table-printer/dist/src/utils/colored-console-line.js +29 -0
  417. data/node_modules/console-table-printer/dist/src/utils/console-utils.d.ts +2 -0
  418. data/node_modules/console-table-printer/dist/src/utils/console-utils.js +8 -0
  419. data/node_modules/console-table-printer/dist/src/utils/string-utils.d.ts +4 -0
  420. data/node_modules/console-table-printer/dist/src/utils/string-utils.js +54 -0
  421. data/node_modules/console-table-printer/dist/src/utils/table-constants.d.ts +10 -0
  422. data/node_modules/console-table-printer/dist/src/utils/table-constants.js +49 -0
  423. data/node_modules/console-table-printer/dist/src/utils/table-helpers.d.ts +26 -0
  424. data/node_modules/console-table-printer/dist/src/utils/table-helpers.js +91 -0
  425. data/node_modules/console-table-printer/package.json +51 -0
  426. data/node_modules/cross-env/CHANGELOG.md +5 -0
  427. data/node_modules/cross-env/LICENSE +20 -0
  428. data/node_modules/cross-env/README.md +291 -0
  429. data/node_modules/cross-env/package.json +54 -0
  430. data/node_modules/cross-env/src/bin/cross-env-shell.js +5 -0
  431. data/node_modules/cross-env/src/bin/cross-env.js +5 -0
  432. data/node_modules/cross-env/src/command.js +32 -0
  433. data/node_modules/cross-env/src/index.js +95 -0
  434. data/node_modules/cross-env/src/is-windows.js +2 -0
  435. data/node_modules/cross-env/src/variable.js +69 -0
  436. data/node_modules/cross-spawn/CHANGELOG.md +130 -0
  437. data/node_modules/cross-spawn/LICENSE +21 -0
  438. data/node_modules/cross-spawn/README.md +96 -0
  439. data/node_modules/cross-spawn/index.js +39 -0
  440. data/node_modules/cross-spawn/lib/enoent.js +59 -0
  441. data/node_modules/cross-spawn/lib/parse.js +91 -0
  442. data/node_modules/cross-spawn/lib/util/escape.js +45 -0
  443. data/node_modules/cross-spawn/lib/util/readShebang.js +23 -0
  444. data/node_modules/cross-spawn/lib/util/resolveCommand.js +52 -0
  445. data/node_modules/cross-spawn/package.json +73 -0
  446. data/node_modules/crypto-js/CONTRIBUTING.md +28 -0
  447. data/node_modules/crypto-js/LICENSE +24 -0
  448. data/node_modules/crypto-js/README.md +249 -0
  449. data/node_modules/crypto-js/aes.js +234 -0
  450. data/node_modules/crypto-js/bower.json +35 -0
  451. data/node_modules/crypto-js/cipher-core.js +890 -0
  452. data/node_modules/crypto-js/core.js +797 -0
  453. data/node_modules/crypto-js/crypto-js.js +6059 -0
  454. data/node_modules/crypto-js/docs/QuickStartGuide.wiki +470 -0
  455. data/node_modules/crypto-js/enc-base64.js +136 -0
  456. data/node_modules/crypto-js/enc-hex.js +18 -0
  457. data/node_modules/crypto-js/enc-latin1.js +18 -0
  458. data/node_modules/crypto-js/enc-utf16.js +149 -0
  459. data/node_modules/crypto-js/enc-utf8.js +18 -0
  460. data/node_modules/crypto-js/evpkdf.js +134 -0
  461. data/node_modules/crypto-js/format-hex.js +66 -0
  462. data/node_modules/crypto-js/format-openssl.js +18 -0
  463. data/node_modules/crypto-js/hmac-md5.js +18 -0
  464. data/node_modules/crypto-js/hmac-ripemd160.js +18 -0
  465. data/node_modules/crypto-js/hmac-sha1.js +18 -0
  466. data/node_modules/crypto-js/hmac-sha224.js +18 -0
  467. data/node_modules/crypto-js/hmac-sha256.js +18 -0
  468. data/node_modules/crypto-js/hmac-sha3.js +18 -0
  469. data/node_modules/crypto-js/hmac-sha384.js +18 -0
  470. data/node_modules/crypto-js/hmac-sha512.js +18 -0
  471. data/node_modules/crypto-js/hmac.js +143 -0
  472. data/node_modules/crypto-js/index.js +18 -0
  473. data/node_modules/crypto-js/lib-typedarrays.js +76 -0
  474. data/node_modules/crypto-js/md5.js +268 -0
  475. data/node_modules/crypto-js/mode-cfb.js +80 -0
  476. data/node_modules/crypto-js/mode-ctr-gladman.js +116 -0
  477. data/node_modules/crypto-js/mode-ctr.js +58 -0
  478. data/node_modules/crypto-js/mode-ecb.js +40 -0
  479. data/node_modules/crypto-js/mode-ofb.js +54 -0
  480. data/node_modules/crypto-js/package.json +38 -0
  481. data/node_modules/crypto-js/pad-ansix923.js +49 -0
  482. data/node_modules/crypto-js/pad-iso10126.js +44 -0
  483. data/node_modules/crypto-js/pad-iso97971.js +40 -0
  484. data/node_modules/crypto-js/pad-nopadding.js +30 -0
  485. data/node_modules/crypto-js/pad-pkcs7.js +18 -0
  486. data/node_modules/crypto-js/pad-zeropadding.js +47 -0
  487. data/node_modules/crypto-js/pbkdf2.js +145 -0
  488. data/node_modules/crypto-js/rabbit-legacy.js +190 -0
  489. data/node_modules/crypto-js/rabbit.js +192 -0
  490. data/node_modules/crypto-js/rc4.js +139 -0
  491. data/node_modules/crypto-js/ripemd160.js +267 -0
  492. data/node_modules/crypto-js/sha1.js +150 -0
  493. data/node_modules/crypto-js/sha224.js +80 -0
  494. data/node_modules/crypto-js/sha256.js +199 -0
  495. data/node_modules/crypto-js/sha3.js +326 -0
  496. data/node_modules/crypto-js/sha384.js +83 -0
  497. data/node_modules/crypto-js/sha512.js +326 -0
  498. data/node_modules/crypto-js/tripledes.js +779 -0
  499. data/node_modules/crypto-js/x64-core.js +304 -0
  500. data/node_modules/diff/CONTRIBUTING.md +39 -0
  501. data/node_modules/diff/LICENSE +31 -0
  502. data/node_modules/diff/README.md +208 -0
  503. data/node_modules/diff/dist/diff.js +1582 -0
  504. data/node_modules/diff/lib/convert/dmp.js +32 -0
  505. data/node_modules/diff/lib/convert/xml.js +42 -0
  506. data/node_modules/diff/lib/diff/array.js +45 -0
  507. data/node_modules/diff/lib/diff/base.js +304 -0
  508. data/node_modules/diff/lib/diff/character.js +37 -0
  509. data/node_modules/diff/lib/diff/css.js +41 -0
  510. data/node_modules/diff/lib/diff/json.js +163 -0
  511. data/node_modules/diff/lib/diff/line.js +89 -0
  512. data/node_modules/diff/lib/diff/sentence.js +41 -0
  513. data/node_modules/diff/lib/diff/word.js +108 -0
  514. data/node_modules/diff/lib/index.es6.js +1553 -0
  515. data/node_modules/diff/lib/index.js +216 -0
  516. data/node_modules/diff/lib/index.mjs +1553 -0
  517. data/node_modules/diff/lib/patch/apply.js +238 -0
  518. data/node_modules/diff/lib/patch/create.js +267 -0
  519. data/node_modules/diff/lib/patch/merge.js +613 -0
  520. data/node_modules/diff/lib/patch/parse.js +167 -0
  521. data/node_modules/diff/lib/util/array.js +32 -0
  522. data/node_modules/diff/lib/util/distance-iterator.js +57 -0
  523. data/node_modules/diff/lib/util/params.js +24 -0
  524. data/node_modules/diff/package.json +87 -0
  525. data/node_modules/diff/release-notes.md +303 -0
  526. data/node_modules/diff/runtime.js +3 -0
  527. data/node_modules/emoji-regex/LICENSE-MIT.txt +20 -0
  528. data/node_modules/emoji-regex/README.md +73 -0
  529. data/node_modules/emoji-regex/es2015/index.js +6 -0
  530. data/node_modules/emoji-regex/es2015/text.js +6 -0
  531. data/node_modules/emoji-regex/index.d.ts +23 -0
  532. data/node_modules/emoji-regex/index.js +6 -0
  533. data/node_modules/emoji-regex/package.json +50 -0
  534. data/node_modules/emoji-regex/text.js +6 -0
  535. data/node_modules/escalade/dist/index.js +22 -0
  536. data/node_modules/escalade/dist/index.mjs +22 -0
  537. data/node_modules/escalade/index.d.ts +3 -0
  538. data/node_modules/escalade/license +9 -0
  539. data/node_modules/escalade/package.json +61 -0
  540. data/node_modules/escalade/readme.md +211 -0
  541. data/node_modules/escalade/sync/index.d.ts +2 -0
  542. data/node_modules/escalade/sync/index.js +18 -0
  543. data/node_modules/escalade/sync/index.mjs +18 -0
  544. data/node_modules/esprima/ChangeLog +235 -0
  545. data/node_modules/esprima/LICENSE.BSD +21 -0
  546. data/node_modules/esprima/README.md +46 -0
  547. data/node_modules/esprima/bin/esparse.js +139 -0
  548. data/node_modules/esprima/bin/esvalidate.js +236 -0
  549. data/node_modules/esprima/dist/esprima.js +6709 -0
  550. data/node_modules/esprima/package.json +112 -0
  551. data/node_modules/fill-range/LICENSE +21 -0
  552. data/node_modules/fill-range/README.md +237 -0
  553. data/node_modules/fill-range/index.js +249 -0
  554. data/node_modules/fill-range/package.json +69 -0
  555. data/node_modules/fs-extra/CHANGELOG.md +902 -0
  556. data/node_modules/fs-extra/LICENSE +15 -0
  557. data/node_modules/fs-extra/README.md +264 -0
  558. data/node_modules/fs-extra/lib/copy-sync/copy-sync.js +166 -0
  559. data/node_modules/fs-extra/lib/copy-sync/index.js +5 -0
  560. data/node_modules/fs-extra/lib/copy/copy.js +232 -0
  561. data/node_modules/fs-extra/lib/copy/index.js +6 -0
  562. data/node_modules/fs-extra/lib/empty/index.js +48 -0
  563. data/node_modules/fs-extra/lib/ensure/file.js +69 -0
  564. data/node_modules/fs-extra/lib/ensure/index.js +23 -0
  565. data/node_modules/fs-extra/lib/ensure/link.js +61 -0
  566. data/node_modules/fs-extra/lib/ensure/symlink-paths.js +99 -0
  567. data/node_modules/fs-extra/lib/ensure/symlink-type.js +31 -0
  568. data/node_modules/fs-extra/lib/ensure/symlink.js +63 -0
  569. data/node_modules/fs-extra/lib/fs/index.js +130 -0
  570. data/node_modules/fs-extra/lib/index.js +27 -0
  571. data/node_modules/fs-extra/lib/json/index.js +16 -0
  572. data/node_modules/fs-extra/lib/json/jsonfile.js +11 -0
  573. data/node_modules/fs-extra/lib/json/output-json-sync.js +12 -0
  574. data/node_modules/fs-extra/lib/json/output-json.js +12 -0
  575. data/node_modules/fs-extra/lib/mkdirs/index.js +14 -0
  576. data/node_modules/fs-extra/lib/mkdirs/make-dir.js +141 -0
  577. data/node_modules/fs-extra/lib/move-sync/index.js +5 -0
  578. data/node_modules/fs-extra/lib/move-sync/move-sync.js +47 -0
  579. data/node_modules/fs-extra/lib/move/index.js +6 -0
  580. data/node_modules/fs-extra/lib/move/move.js +65 -0
  581. data/node_modules/fs-extra/lib/output/index.js +40 -0
  582. data/node_modules/fs-extra/lib/path-exists/index.js +12 -0
  583. data/node_modules/fs-extra/lib/remove/index.js +9 -0
  584. data/node_modules/fs-extra/lib/remove/rimraf.js +302 -0
  585. data/node_modules/fs-extra/lib/util/stat.js +139 -0
  586. data/node_modules/fs-extra/lib/util/utimes.js +26 -0
  587. data/node_modules/fs-extra/package.json +70 -0
  588. data/node_modules/fs.realpath/LICENSE +43 -0
  589. data/node_modules/fs.realpath/README.md +33 -0
  590. data/node_modules/fs.realpath/index.js +66 -0
  591. data/node_modules/fs.realpath/old.js +303 -0
  592. data/node_modules/fs.realpath/package.json +26 -0
  593. data/node_modules/fsevents/LICENSE +22 -0
  594. data/node_modules/fsevents/README.md +83 -0
  595. data/node_modules/fsevents/fsevents.d.ts +46 -0
  596. data/node_modules/fsevents/fsevents.js +82 -0
  597. data/node_modules/fsevents/fsevents.node +0 -0
  598. data/node_modules/fsevents/package.json +62 -0
  599. data/node_modules/get-caller-file/LICENSE.md +6 -0
  600. data/node_modules/get-caller-file/README.md +41 -0
  601. data/node_modules/get-caller-file/index.d.ts +2 -0
  602. data/node_modules/get-caller-file/index.js +22 -0
  603. data/node_modules/get-caller-file/index.js.map +1 -0
  604. data/node_modules/get-caller-file/package.json +42 -0
  605. data/node_modules/glob-parent/CHANGELOG.md +110 -0
  606. data/node_modules/glob-parent/LICENSE +15 -0
  607. data/node_modules/glob-parent/README.md +137 -0
  608. data/node_modules/glob-parent/index.js +42 -0
  609. data/node_modules/glob-parent/package.json +48 -0
  610. data/node_modules/glob/LICENSE +21 -0
  611. data/node_modules/glob/README.md +375 -0
  612. data/node_modules/glob/changelog.md +67 -0
  613. data/node_modules/glob/common.js +234 -0
  614. data/node_modules/glob/glob.js +788 -0
  615. data/node_modules/glob/package.json +51 -0
  616. data/node_modules/glob/sync.js +484 -0
  617. data/node_modules/graceful-fs/LICENSE +15 -0
  618. data/node_modules/graceful-fs/README.md +133 -0
  619. data/node_modules/graceful-fs/clone.js +23 -0
  620. data/node_modules/graceful-fs/graceful-fs.js +373 -0
  621. data/node_modules/graceful-fs/legacy-streams.js +118 -0
  622. data/node_modules/graceful-fs/package.json +50 -0
  623. data/node_modules/graceful-fs/polyfills.js +346 -0
  624. data/node_modules/inflight/LICENSE +15 -0
  625. data/node_modules/inflight/README.md +37 -0
  626. data/node_modules/inflight/inflight.js +54 -0
  627. data/node_modules/inflight/package.json +29 -0
  628. data/node_modules/inherits/LICENSE +16 -0
  629. data/node_modules/inherits/README.md +42 -0
  630. data/node_modules/inherits/inherits.js +9 -0
  631. data/node_modules/inherits/inherits_browser.js +27 -0
  632. data/node_modules/inherits/package.json +29 -0
  633. data/node_modules/is-binary-path/index.d.ts +17 -0
  634. data/node_modules/is-binary-path/index.js +7 -0
  635. data/node_modules/is-binary-path/license +9 -0
  636. data/node_modules/is-binary-path/package.json +40 -0
  637. data/node_modules/is-binary-path/readme.md +34 -0
  638. data/node_modules/is-extglob/LICENSE +21 -0
  639. data/node_modules/is-extglob/README.md +107 -0
  640. data/node_modules/is-extglob/index.js +20 -0
  641. data/node_modules/is-extglob/package.json +69 -0
  642. data/node_modules/is-fullwidth-code-point/index.d.ts +17 -0
  643. data/node_modules/is-fullwidth-code-point/index.js +50 -0
  644. data/node_modules/is-fullwidth-code-point/license +9 -0
  645. data/node_modules/is-fullwidth-code-point/package.json +42 -0
  646. data/node_modules/is-fullwidth-code-point/readme.md +39 -0
  647. data/node_modules/is-glob/LICENSE +21 -0
  648. data/node_modules/is-glob/README.md +206 -0
  649. data/node_modules/is-glob/index.js +48 -0
  650. data/node_modules/is-glob/package.json +81 -0
  651. data/node_modules/is-number/LICENSE +21 -0
  652. data/node_modules/is-number/README.md +187 -0
  653. data/node_modules/is-number/index.js +18 -0
  654. data/node_modules/is-number/package.json +82 -0
  655. data/node_modules/isexe/LICENSE +15 -0
  656. data/node_modules/isexe/README.md +51 -0
  657. data/node_modules/isexe/index.js +57 -0
  658. data/node_modules/isexe/mode.js +41 -0
  659. data/node_modules/isexe/package.json +31 -0
  660. data/node_modules/isexe/test/basic.js +221 -0
  661. data/node_modules/isexe/windows.js +42 -0
  662. data/node_modules/js-yaml/CHANGELOG.md +557 -0
  663. data/node_modules/js-yaml/LICENSE +21 -0
  664. data/node_modules/js-yaml/README.md +299 -0
  665. data/node_modules/js-yaml/bin/js-yaml.js +132 -0
  666. data/node_modules/js-yaml/dist/js-yaml.js +3989 -0
  667. data/node_modules/js-yaml/dist/js-yaml.min.js +1 -0
  668. data/node_modules/js-yaml/index.js +7 -0
  669. data/node_modules/js-yaml/lib/js-yaml.js +39 -0
  670. data/node_modules/js-yaml/lib/js-yaml/common.js +59 -0
  671. data/node_modules/js-yaml/lib/js-yaml/dumper.js +850 -0
  672. data/node_modules/js-yaml/lib/js-yaml/exception.js +43 -0
  673. data/node_modules/js-yaml/lib/js-yaml/loader.js +1644 -0
  674. data/node_modules/js-yaml/lib/js-yaml/mark.js +76 -0
  675. data/node_modules/js-yaml/lib/js-yaml/schema.js +108 -0
  676. data/node_modules/js-yaml/lib/js-yaml/schema/core.js +18 -0
  677. data/node_modules/js-yaml/lib/js-yaml/schema/default_full.js +25 -0
  678. data/node_modules/js-yaml/lib/js-yaml/schema/default_safe.js +28 -0
  679. data/node_modules/js-yaml/lib/js-yaml/schema/failsafe.js +17 -0
  680. data/node_modules/js-yaml/lib/js-yaml/schema/json.js +25 -0
  681. data/node_modules/js-yaml/lib/js-yaml/type.js +61 -0
  682. data/node_modules/js-yaml/lib/js-yaml/type/binary.js +138 -0
  683. data/node_modules/js-yaml/lib/js-yaml/type/bool.js +35 -0
  684. data/node_modules/js-yaml/lib/js-yaml/type/float.js +116 -0
  685. data/node_modules/js-yaml/lib/js-yaml/type/int.js +173 -0
  686. data/node_modules/js-yaml/lib/js-yaml/type/js/function.js +93 -0
  687. data/node_modules/js-yaml/lib/js-yaml/type/js/regexp.js +60 -0
  688. data/node_modules/js-yaml/lib/js-yaml/type/js/undefined.js +28 -0
  689. data/node_modules/js-yaml/lib/js-yaml/type/map.js +8 -0
  690. data/node_modules/js-yaml/lib/js-yaml/type/merge.js +12 -0
  691. data/node_modules/js-yaml/lib/js-yaml/type/null.js +34 -0
  692. data/node_modules/js-yaml/lib/js-yaml/type/omap.js +44 -0
  693. data/node_modules/js-yaml/lib/js-yaml/type/pairs.js +53 -0
  694. data/node_modules/js-yaml/lib/js-yaml/type/seq.js +8 -0
  695. data/node_modules/js-yaml/lib/js-yaml/type/set.js +29 -0
  696. data/node_modules/js-yaml/lib/js-yaml/type/str.js +8 -0
  697. data/node_modules/js-yaml/lib/js-yaml/type/timestamp.js +88 -0
  698. data/node_modules/js-yaml/package.json +49 -0
  699. data/node_modules/jsonfile/CHANGELOG.md +171 -0
  700. data/node_modules/jsonfile/LICENSE +15 -0
  701. data/node_modules/jsonfile/README.md +230 -0
  702. data/node_modules/jsonfile/index.js +88 -0
  703. data/node_modules/jsonfile/package.json +40 -0
  704. data/node_modules/jsonfile/utils.js +14 -0
  705. data/node_modules/lru-cache/LICENSE +15 -0
  706. data/node_modules/lru-cache/README.md +166 -0
  707. data/node_modules/lru-cache/index.js +334 -0
  708. data/node_modules/lru-cache/package.json +34 -0
  709. data/node_modules/minimatch/LICENSE +15 -0
  710. data/node_modules/minimatch/README.md +209 -0
  711. data/node_modules/minimatch/minimatch.js +923 -0
  712. data/node_modules/minimatch/package.json +30 -0
  713. data/node_modules/normalize-path/LICENSE +21 -0
  714. data/node_modules/normalize-path/README.md +127 -0
  715. data/node_modules/normalize-path/index.js +35 -0
  716. data/node_modules/normalize-path/package.json +77 -0
  717. data/node_modules/once/LICENSE +15 -0
  718. data/node_modules/once/README.md +79 -0
  719. data/node_modules/once/once.js +42 -0
  720. data/node_modules/once/package.json +33 -0
  721. data/node_modules/path-is-absolute/index.js +20 -0
  722. data/node_modules/path-is-absolute/license +21 -0
  723. data/node_modules/path-is-absolute/package.json +43 -0
  724. data/node_modules/path-is-absolute/readme.md +59 -0
  725. data/node_modules/path-key/index.d.ts +40 -0
  726. data/node_modules/path-key/index.js +16 -0
  727. data/node_modules/path-key/license +9 -0
  728. data/node_modules/path-key/package.json +39 -0
  729. data/node_modules/path-key/readme.md +61 -0
  730. data/node_modules/picomatch/CHANGELOG.md +126 -0
  731. data/node_modules/picomatch/LICENSE +21 -0
  732. data/node_modules/picomatch/README.md +707 -0
  733. data/node_modules/picomatch/index.js +3 -0
  734. data/node_modules/picomatch/lib/constants.js +179 -0
  735. data/node_modules/picomatch/lib/parse.js +1084 -0
  736. data/node_modules/picomatch/lib/picomatch.js +342 -0
  737. data/node_modules/picomatch/lib/scan.js +391 -0
  738. data/node_modules/picomatch/lib/utils.js +64 -0
  739. data/node_modules/picomatch/package.json +81 -0
  740. data/node_modules/readdirp/LICENSE +21 -0
  741. data/node_modules/readdirp/README.md +122 -0
  742. data/node_modules/readdirp/index.d.ts +43 -0
  743. data/node_modules/readdirp/index.js +287 -0
  744. data/node_modules/readdirp/package.json +122 -0
  745. data/node_modules/require-directory/LICENSE +22 -0
  746. data/node_modules/require-directory/README.markdown +184 -0
  747. data/node_modules/require-directory/index.js +86 -0
  748. data/node_modules/require-directory/package.json +40 -0
  749. data/node_modules/semver/CHANGELOG.md +111 -0
  750. data/node_modules/semver/LICENSE +15 -0
  751. data/node_modules/semver/README.md +566 -0
  752. data/node_modules/semver/bin/semver.js +173 -0
  753. data/node_modules/semver/classes/comparator.js +135 -0
  754. data/node_modules/semver/classes/index.js +5 -0
  755. data/node_modules/semver/classes/range.js +510 -0
  756. data/node_modules/semver/classes/semver.js +287 -0
  757. data/node_modules/semver/functions/clean.js +6 -0
  758. data/node_modules/semver/functions/cmp.js +48 -0
  759. data/node_modules/semver/functions/coerce.js +51 -0
  760. data/node_modules/semver/functions/compare-build.js +7 -0
  761. data/node_modules/semver/functions/compare-loose.js +3 -0
  762. data/node_modules/semver/functions/compare.js +5 -0
  763. data/node_modules/semver/functions/diff.js +23 -0
  764. data/node_modules/semver/functions/eq.js +3 -0
  765. data/node_modules/semver/functions/gt.js +3 -0
  766. data/node_modules/semver/functions/gte.js +3 -0
  767. data/node_modules/semver/functions/inc.js +15 -0
  768. data/node_modules/semver/functions/lt.js +3 -0
  769. data/node_modules/semver/functions/lte.js +3 -0
  770. data/node_modules/semver/functions/major.js +3 -0
  771. data/node_modules/semver/functions/minor.js +3 -0
  772. data/node_modules/semver/functions/neq.js +3 -0
  773. data/node_modules/semver/functions/parse.js +33 -0
  774. data/node_modules/semver/functions/patch.js +3 -0
  775. data/node_modules/semver/functions/prerelease.js +6 -0
  776. data/node_modules/semver/functions/rcompare.js +3 -0
  777. data/node_modules/semver/functions/rsort.js +3 -0
  778. data/node_modules/semver/functions/satisfies.js +10 -0
  779. data/node_modules/semver/functions/sort.js +3 -0
  780. data/node_modules/semver/functions/valid.js +6 -0
  781. data/node_modules/semver/index.js +48 -0
  782. data/node_modules/semver/internal/constants.js +17 -0
  783. data/node_modules/semver/internal/debug.js +9 -0
  784. data/node_modules/semver/internal/identifiers.js +23 -0
  785. data/node_modules/semver/internal/parse-options.js +11 -0
  786. data/node_modules/semver/internal/re.js +182 -0
  787. data/node_modules/semver/package.json +41 -0
  788. data/node_modules/semver/preload.js +2 -0
  789. data/node_modules/semver/range.bnf +16 -0
  790. data/node_modules/semver/ranges/gtr.js +4 -0
  791. data/node_modules/semver/ranges/intersects.js +7 -0
  792. data/node_modules/semver/ranges/ltr.js +4 -0
  793. data/node_modules/semver/ranges/max-satisfying.js +25 -0
  794. data/node_modules/semver/ranges/min-satisfying.js +24 -0
  795. data/node_modules/semver/ranges/min-version.js +60 -0
  796. data/node_modules/semver/ranges/outside.js +80 -0
  797. data/node_modules/semver/ranges/simplify.js +44 -0
  798. data/node_modules/semver/ranges/subset.js +222 -0
  799. data/node_modules/semver/ranges/to-comparators.js +8 -0
  800. data/node_modules/semver/ranges/valid.js +11 -0
  801. data/node_modules/shebang-command/index.js +19 -0
  802. data/node_modules/shebang-command/license +9 -0
  803. data/node_modules/shebang-command/package.json +34 -0
  804. data/node_modules/shebang-command/readme.md +34 -0
  805. data/node_modules/shebang-regex/index.d.ts +22 -0
  806. data/node_modules/shebang-regex/index.js +2 -0
  807. data/node_modules/shebang-regex/license +9 -0
  808. data/node_modules/shebang-regex/package.json +35 -0
  809. data/node_modules/shebang-regex/readme.md +33 -0
  810. data/node_modules/simple-wcswidth/CHANGELOG.md +13 -0
  811. data/node_modules/simple-wcswidth/LICENSE +21 -0
  812. data/node_modules/simple-wcswidth/README.md +100 -0
  813. data/node_modules/simple-wcswidth/dist/index.d.ts +3 -0
  814. data/node_modules/simple-wcswidth/dist/index.js +10 -0
  815. data/node_modules/simple-wcswidth/dist/src/binary-search.d.ts +3 -0
  816. data/node_modules/simple-wcswidth/dist/src/binary-search.js +24 -0
  817. data/node_modules/simple-wcswidth/dist/src/models.d.ts +4 -0
  818. data/node_modules/simple-wcswidth/dist/src/models.js +2 -0
  819. data/node_modules/simple-wcswidth/dist/src/non-spacing-chars.d.ts +3 -0
  820. data/node_modules/simple-wcswidth/dist/src/non-spacing-chars.js +149 -0
  821. data/node_modules/simple-wcswidth/dist/src/wcswidth.d.ts +2 -0
  822. data/node_modules/simple-wcswidth/dist/src/wcswidth.js +20 -0
  823. data/node_modules/simple-wcswidth/dist/src/wcwidth.d.ts +2 -0
  824. data/node_modules/simple-wcswidth/dist/src/wcwidth.js +67 -0
  825. data/node_modules/simple-wcswidth/package.json +44 -0
  826. data/node_modules/slash/index.d.ts +25 -0
  827. data/node_modules/slash/index.js +11 -0
  828. data/node_modules/slash/license +9 -0
  829. data/node_modules/slash/package.json +35 -0
  830. data/node_modules/slash/readme.md +44 -0
  831. data/node_modules/sprintf-js/LICENSE +24 -0
  832. data/node_modules/sprintf-js/README.md +88 -0
  833. data/node_modules/sprintf-js/bower.json +14 -0
  834. data/node_modules/sprintf-js/demo/angular.html +20 -0
  835. data/node_modules/sprintf-js/dist/angular-sprintf.min.js +4 -0
  836. data/node_modules/sprintf-js/dist/angular-sprintf.min.js.map +1 -0
  837. data/node_modules/sprintf-js/dist/angular-sprintf.min.map +1 -0
  838. data/node_modules/sprintf-js/dist/sprintf.min.js +4 -0
  839. data/node_modules/sprintf-js/dist/sprintf.min.js.map +1 -0
  840. data/node_modules/sprintf-js/dist/sprintf.min.map +1 -0
  841. data/node_modules/sprintf-js/gruntfile.js +36 -0
  842. data/node_modules/sprintf-js/package.json +22 -0
  843. data/node_modules/sprintf-js/src/angular-sprintf.js +18 -0
  844. data/node_modules/sprintf-js/src/sprintf.js +208 -0
  845. data/node_modules/sprintf-js/test/test.js +82 -0
  846. data/node_modules/sqlite-parser/CHANGELOG.md +1263 -0
  847. data/node_modules/sqlite-parser/LICENSE +22 -0
  848. data/node_modules/sqlite-parser/README.md +187 -0
  849. data/node_modules/sqlite-parser/bin/sqlite-parser +7 -0
  850. data/node_modules/sqlite-parser/dist/sqlite-parser.js +19 -0
  851. data/node_modules/sqlite-parser/lib/index.js +6 -0
  852. data/node_modules/sqlite-parser/lib/parser.js +6 -0
  853. data/node_modules/sqlite-parser/lib/streaming-shim.js +6 -0
  854. data/node_modules/sqlite-parser/lib/streaming.js +6 -0
  855. data/node_modules/sqlite-parser/lib/tracer.js +6 -0
  856. data/node_modules/sqlite-parser/package.json +75 -0
  857. data/node_modules/string-width/index.d.ts +29 -0
  858. data/node_modules/string-width/index.js +47 -0
  859. data/node_modules/string-width/license +9 -0
  860. data/node_modules/string-width/package.json +56 -0
  861. data/node_modules/string-width/readme.md +50 -0
  862. data/node_modules/strip-ansi/index.d.ts +17 -0
  863. data/node_modules/strip-ansi/index.js +4 -0
  864. data/node_modules/strip-ansi/license +9 -0
  865. data/node_modules/strip-ansi/package.json +54 -0
  866. data/node_modules/strip-ansi/readme.md +46 -0
  867. data/node_modules/to-regex-range/LICENSE +21 -0
  868. data/node_modules/to-regex-range/README.md +305 -0
  869. data/node_modules/to-regex-range/index.js +288 -0
  870. data/node_modules/to-regex-range/package.json +88 -0
  871. data/node_modules/universalify/LICENSE +20 -0
  872. data/node_modules/universalify/README.md +76 -0
  873. data/node_modules/universalify/index.js +24 -0
  874. data/node_modules/universalify/package.json +34 -0
  875. data/node_modules/which/CHANGELOG.md +166 -0
  876. data/node_modules/which/LICENSE +15 -0
  877. data/node_modules/which/README.md +54 -0
  878. data/node_modules/which/bin/node-which +52 -0
  879. data/node_modules/which/package.json +43 -0
  880. data/node_modules/which/which.js +125 -0
  881. data/node_modules/wrap-ansi/index.js +216 -0
  882. data/node_modules/wrap-ansi/license +9 -0
  883. data/node_modules/wrap-ansi/package.json +62 -0
  884. data/node_modules/wrap-ansi/readme.md +91 -0
  885. data/node_modules/wrappy/LICENSE +15 -0
  886. data/node_modules/wrappy/README.md +36 -0
  887. data/node_modules/wrappy/package.json +29 -0
  888. data/node_modules/wrappy/wrappy.js +33 -0
  889. data/node_modules/y18n/CHANGELOG.md +100 -0
  890. data/node_modules/y18n/LICENSE +13 -0
  891. data/node_modules/y18n/README.md +127 -0
  892. data/node_modules/y18n/build/index.cjs +203 -0
  893. data/node_modules/y18n/build/lib/cjs.js +6 -0
  894. data/node_modules/y18n/build/lib/index.js +174 -0
  895. data/node_modules/y18n/build/lib/platform-shims/node.js +19 -0
  896. data/node_modules/y18n/index.mjs +8 -0
  897. data/node_modules/y18n/package.json +70 -0
  898. data/node_modules/yallist/LICENSE +15 -0
  899. data/node_modules/yallist/README.md +204 -0
  900. data/node_modules/yallist/iterator.js +8 -0
  901. data/node_modules/yallist/package.json +29 -0
  902. data/node_modules/yallist/yallist.js +426 -0
  903. data/node_modules/yargs-parser/CHANGELOG.md +263 -0
  904. data/node_modules/yargs-parser/LICENSE.txt +14 -0
  905. data/node_modules/yargs-parser/README.md +518 -0
  906. data/node_modules/yargs-parser/browser.js +29 -0
  907. data/node_modules/yargs-parser/build/index.cjs +1042 -0
  908. data/node_modules/yargs-parser/build/lib/index.js +59 -0
  909. data/node_modules/yargs-parser/build/lib/string-utils.js +65 -0
  910. data/node_modules/yargs-parser/build/lib/tokenize-arg-string.js +40 -0
  911. data/node_modules/yargs-parser/build/lib/yargs-parser-types.js +12 -0
  912. data/node_modules/yargs-parser/build/lib/yargs-parser.js +1037 -0
  913. data/node_modules/yargs-parser/package.json +87 -0
  914. data/node_modules/yargs/CHANGELOG.md +151 -0
  915. data/node_modules/yargs/LICENSE +21 -0
  916. data/node_modules/yargs/README.md +204 -0
  917. data/node_modules/yargs/browser.mjs +7 -0
  918. data/node_modules/yargs/build/index.cjs +1 -0
  919. data/node_modules/yargs/build/lib/argsert.js +62 -0
  920. data/node_modules/yargs/build/lib/command.js +436 -0
  921. data/node_modules/yargs/build/lib/completion-templates.js +48 -0
  922. data/node_modules/yargs/build/lib/completion.js +166 -0
  923. data/node_modules/yargs/build/lib/middleware.js +85 -0
  924. data/node_modules/yargs/build/lib/parse-command.js +32 -0
  925. data/node_modules/yargs/build/lib/typings/common-types.js +9 -0
  926. data/node_modules/yargs/build/lib/typings/yargs-parser-types.js +1 -0
  927. data/node_modules/yargs/build/lib/usage.js +567 -0
  928. data/node_modules/yargs/build/lib/utils/apply-extends.js +59 -0
  929. data/node_modules/yargs/build/lib/utils/is-promise.js +5 -0
  930. data/node_modules/yargs/build/lib/utils/levenshtein.js +26 -0
  931. data/node_modules/yargs/build/lib/utils/maybe-async-result.js +17 -0
  932. data/node_modules/yargs/build/lib/utils/obj-filter.js +10 -0
  933. data/node_modules/yargs/build/lib/utils/process-argv.js +17 -0
  934. data/node_modules/yargs/build/lib/utils/set-blocking.js +12 -0
  935. data/node_modules/yargs/build/lib/utils/which-module.js +10 -0
  936. data/node_modules/yargs/build/lib/validation.js +279 -0
  937. data/node_modules/yargs/build/lib/yargs-factory.js +1452 -0
  938. data/node_modules/yargs/build/lib/yerror.js +7 -0
  939. data/node_modules/yargs/helpers/helpers.mjs +10 -0
  940. data/node_modules/yargs/helpers/index.js +14 -0
  941. data/node_modules/yargs/helpers/package.json +3 -0
  942. data/node_modules/yargs/index.cjs +43 -0
  943. data/node_modules/yargs/index.mjs +8 -0
  944. data/node_modules/yargs/lib/platform-shims/browser.mjs +94 -0
  945. data/node_modules/yargs/lib/platform-shims/esm.mjs +67 -0
  946. data/node_modules/yargs/locales/be.json +46 -0
  947. data/node_modules/yargs/locales/de.json +46 -0
  948. data/node_modules/yargs/locales/en.json +51 -0
  949. data/node_modules/yargs/locales/es.json +46 -0
  950. data/node_modules/yargs/locales/fi.json +49 -0
  951. data/node_modules/yargs/locales/fr.json +53 -0
  952. data/node_modules/yargs/locales/hi.json +49 -0
  953. data/node_modules/yargs/locales/hu.json +46 -0
  954. data/node_modules/yargs/locales/id.json +50 -0
  955. data/node_modules/yargs/locales/it.json +46 -0
  956. data/node_modules/yargs/locales/ja.json +51 -0
  957. data/node_modules/yargs/locales/ko.json +49 -0
  958. data/node_modules/yargs/locales/nb.json +44 -0
  959. data/node_modules/yargs/locales/nl.json +49 -0
  960. data/node_modules/yargs/locales/nn.json +44 -0
  961. data/node_modules/yargs/locales/pirate.json +13 -0
  962. data/node_modules/yargs/locales/pl.json +49 -0
  963. data/node_modules/yargs/locales/pt.json +45 -0
  964. data/node_modules/yargs/locales/pt_BR.json +48 -0
  965. data/node_modules/yargs/locales/ru.json +46 -0
  966. data/node_modules/yargs/locales/th.json +46 -0
  967. data/node_modules/yargs/locales/tr.json +48 -0
  968. data/node_modules/yargs/locales/uk_UA.json +51 -0
  969. data/node_modules/yargs/locales/zh_CN.json +48 -0
  970. data/node_modules/yargs/locales/zh_TW.json +47 -0
  971. data/node_modules/yargs/package.json +116 -0
  972. data/node_modules/yargs/yargs +9 -0
  973. data/package.json +1 -1
  974. data/spec/depends/api_spec.rb +184 -0
  975. data/spec/depends/spec_helper.rb +27 -0
  976. data/spec/fixtures/depends/.gitignore +2 -0
  977. data/spec/fixtures/depends/app/controllers/api/api_keys_controller.rb +2 -0
  978. data/spec/fixtures/depends/app/controllers/organizations_controller.rb +2 -0
  979. data/spec/fixtures/depends/app/models/api_key.rb +2 -0
  980. data/spec/fixtures/depends/app/models/configuration.rb +2 -0
  981. data/spec/fixtures/depends/app/models/show.rb +2 -0
  982. data/spec/fixtures/depends/app/models/user.rb +2 -0
  983. data/spec/fixtures/depends/revoke_api_key.appmap.json +901 -0
  984. data/spec/fixtures/depends/spec/actual_rspec_test.rb +7 -0
  985. data/spec/fixtures/depends/spec/api_spec.rb +2 -0
  986. data/spec/fixtures/depends/spec/user_spec.rb +2 -0
  987. data/spec/fixtures/depends/test/actual_minitest_test.rb +5 -0
  988. data/spec/fixtures/depends/user_page_scenario.appmap.json +1776 -0
  989. data/spec/fixtures/rails5_users_app/create_app +3 -3
  990. data/spec/fixtures/rails6_users_app/create_app +3 -3
  991. data/spec/fixtures/rails6_users_app/lib/tasks/appmap.rake +11 -1
  992. data/spec/service/config_analyzer_spec.rb +3 -3
  993. data/spec/service/integration_test_path_finder_spec.rb +24 -0
  994. data/test/agent_setup_status_test.rb +7 -4
  995. data/test/agent_setup_validate_test.rb +19 -2
  996. data/test/test_helper.rb +3 -0
  997. data/yarn.lock +23 -9
  998. metadata +984 -7
@@ -0,0 +1,4193 @@
1
+ import require$$0 from 'crypto';
2
+ import sqliteParser from 'sqlite-parser';
3
+
4
+ var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
5
+
6
+ function createCommonjsModule(fn) {
7
+ var module = { exports: {} };
8
+ return fn(module, module.exports), module.exports;
9
+ }
10
+
11
+ function commonjsRequire (path) {
12
+ throw new Error('Could not dynamically require "' + path + '". Please configure the dynamicRequireTargets or/and ignoreDynamicRequires option of @rollup/plugin-commonjs appropriately for this require call to work.');
13
+ }
14
+
15
+ var core = createCommonjsModule(function (module, exports) {
16
+ (function (root, factory) {
17
+ {
18
+ // CommonJS
19
+ module.exports = factory();
20
+ }
21
+ }(commonjsGlobal, function () {
22
+
23
+ /*globals window, global, require*/
24
+
25
+ /**
26
+ * CryptoJS core components.
27
+ */
28
+ var CryptoJS = CryptoJS || (function (Math, undefined$1) {
29
+
30
+ var crypto;
31
+
32
+ // Native crypto from window (Browser)
33
+ if (typeof window !== 'undefined' && window.crypto) {
34
+ crypto = window.crypto;
35
+ }
36
+
37
+ // Native (experimental IE 11) crypto from window (Browser)
38
+ if (!crypto && typeof window !== 'undefined' && window.msCrypto) {
39
+ crypto = window.msCrypto;
40
+ }
41
+
42
+ // Native crypto from global (NodeJS)
43
+ if (!crypto && typeof commonjsGlobal !== 'undefined' && commonjsGlobal.crypto) {
44
+ crypto = commonjsGlobal.crypto;
45
+ }
46
+
47
+ // Native crypto import via require (NodeJS)
48
+ if (!crypto && typeof commonjsRequire === 'function') {
49
+ try {
50
+ crypto = require$$0;
51
+ } catch (err) {}
52
+ }
53
+
54
+ /*
55
+ * Cryptographically secure pseudorandom number generator
56
+ *
57
+ * As Math.random() is cryptographically not safe to use
58
+ */
59
+ var cryptoSecureRandomInt = function () {
60
+ if (crypto) {
61
+ // Use getRandomValues method (Browser)
62
+ if (typeof crypto.getRandomValues === 'function') {
63
+ try {
64
+ return crypto.getRandomValues(new Uint32Array(1))[0];
65
+ } catch (err) {}
66
+ }
67
+
68
+ // Use randomBytes method (NodeJS)
69
+ if (typeof crypto.randomBytes === 'function') {
70
+ try {
71
+ return crypto.randomBytes(4).readInt32LE();
72
+ } catch (err) {}
73
+ }
74
+ }
75
+
76
+ throw new Error('Native crypto module could not be used to get secure random number.');
77
+ };
78
+
79
+ /*
80
+ * Local polyfill of Object.create
81
+
82
+ */
83
+ var create = Object.create || (function () {
84
+ function F() {}
85
+
86
+ return function (obj) {
87
+ var subtype;
88
+
89
+ F.prototype = obj;
90
+
91
+ subtype = new F();
92
+
93
+ F.prototype = null;
94
+
95
+ return subtype;
96
+ };
97
+ }());
98
+
99
+ /**
100
+ * CryptoJS namespace.
101
+ */
102
+ var C = {};
103
+
104
+ /**
105
+ * Library namespace.
106
+ */
107
+ var C_lib = C.lib = {};
108
+
109
+ /**
110
+ * Base object for prototypal inheritance.
111
+ */
112
+ var Base = C_lib.Base = (function () {
113
+
114
+
115
+ return {
116
+ /**
117
+ * Creates a new object that inherits from this object.
118
+ *
119
+ * @param {Object} overrides Properties to copy into the new object.
120
+ *
121
+ * @return {Object} The new object.
122
+ *
123
+ * @static
124
+ *
125
+ * @example
126
+ *
127
+ * var MyType = CryptoJS.lib.Base.extend({
128
+ * field: 'value',
129
+ *
130
+ * method: function () {
131
+ * }
132
+ * });
133
+ */
134
+ extend: function (overrides) {
135
+ // Spawn
136
+ var subtype = create(this);
137
+
138
+ // Augment
139
+ if (overrides) {
140
+ subtype.mixIn(overrides);
141
+ }
142
+
143
+ // Create default initializer
144
+ if (!subtype.hasOwnProperty('init') || this.init === subtype.init) {
145
+ subtype.init = function () {
146
+ subtype.$super.init.apply(this, arguments);
147
+ };
148
+ }
149
+
150
+ // Initializer's prototype is the subtype object
151
+ subtype.init.prototype = subtype;
152
+
153
+ // Reference supertype
154
+ subtype.$super = this;
155
+
156
+ return subtype;
157
+ },
158
+
159
+ /**
160
+ * Extends this object and runs the init method.
161
+ * Arguments to create() will be passed to init().
162
+ *
163
+ * @return {Object} The new object.
164
+ *
165
+ * @static
166
+ *
167
+ * @example
168
+ *
169
+ * var instance = MyType.create();
170
+ */
171
+ create: function () {
172
+ var instance = this.extend();
173
+ instance.init.apply(instance, arguments);
174
+
175
+ return instance;
176
+ },
177
+
178
+ /**
179
+ * Initializes a newly created object.
180
+ * Override this method to add some logic when your objects are created.
181
+ *
182
+ * @example
183
+ *
184
+ * var MyType = CryptoJS.lib.Base.extend({
185
+ * init: function () {
186
+ * // ...
187
+ * }
188
+ * });
189
+ */
190
+ init: function () {
191
+ },
192
+
193
+ /**
194
+ * Copies properties into this object.
195
+ *
196
+ * @param {Object} properties The properties to mix in.
197
+ *
198
+ * @example
199
+ *
200
+ * MyType.mixIn({
201
+ * field: 'value'
202
+ * });
203
+ */
204
+ mixIn: function (properties) {
205
+ for (var propertyName in properties) {
206
+ if (properties.hasOwnProperty(propertyName)) {
207
+ this[propertyName] = properties[propertyName];
208
+ }
209
+ }
210
+
211
+ // IE won't copy toString using the loop above
212
+ if (properties.hasOwnProperty('toString')) {
213
+ this.toString = properties.toString;
214
+ }
215
+ },
216
+
217
+ /**
218
+ * Creates a copy of this object.
219
+ *
220
+ * @return {Object} The clone.
221
+ *
222
+ * @example
223
+ *
224
+ * var clone = instance.clone();
225
+ */
226
+ clone: function () {
227
+ return this.init.prototype.extend(this);
228
+ }
229
+ };
230
+ }());
231
+
232
+ /**
233
+ * An array of 32-bit words.
234
+ *
235
+ * @property {Array} words The array of 32-bit words.
236
+ * @property {number} sigBytes The number of significant bytes in this word array.
237
+ */
238
+ var WordArray = C_lib.WordArray = Base.extend({
239
+ /**
240
+ * Initializes a newly created word array.
241
+ *
242
+ * @param {Array} words (Optional) An array of 32-bit words.
243
+ * @param {number} sigBytes (Optional) The number of significant bytes in the words.
244
+ *
245
+ * @example
246
+ *
247
+ * var wordArray = CryptoJS.lib.WordArray.create();
248
+ * var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607]);
249
+ * var wordArray = CryptoJS.lib.WordArray.create([0x00010203, 0x04050607], 6);
250
+ */
251
+ init: function (words, sigBytes) {
252
+ words = this.words = words || [];
253
+
254
+ if (sigBytes != undefined$1) {
255
+ this.sigBytes = sigBytes;
256
+ } else {
257
+ this.sigBytes = words.length * 4;
258
+ }
259
+ },
260
+
261
+ /**
262
+ * Converts this word array to a string.
263
+ *
264
+ * @param {Encoder} encoder (Optional) The encoding strategy to use. Default: CryptoJS.enc.Hex
265
+ *
266
+ * @return {string} The stringified word array.
267
+ *
268
+ * @example
269
+ *
270
+ * var string = wordArray + '';
271
+ * var string = wordArray.toString();
272
+ * var string = wordArray.toString(CryptoJS.enc.Utf8);
273
+ */
274
+ toString: function (encoder) {
275
+ return (encoder || Hex).stringify(this);
276
+ },
277
+
278
+ /**
279
+ * Concatenates a word array to this word array.
280
+ *
281
+ * @param {WordArray} wordArray The word array to append.
282
+ *
283
+ * @return {WordArray} This word array.
284
+ *
285
+ * @example
286
+ *
287
+ * wordArray1.concat(wordArray2);
288
+ */
289
+ concat: function (wordArray) {
290
+ // Shortcuts
291
+ var thisWords = this.words;
292
+ var thatWords = wordArray.words;
293
+ var thisSigBytes = this.sigBytes;
294
+ var thatSigBytes = wordArray.sigBytes;
295
+
296
+ // Clamp excess bits
297
+ this.clamp();
298
+
299
+ // Concat
300
+ if (thisSigBytes % 4) {
301
+ // Copy one byte at a time
302
+ for (var i = 0; i < thatSigBytes; i++) {
303
+ var thatByte = (thatWords[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
304
+ thisWords[(thisSigBytes + i) >>> 2] |= thatByte << (24 - ((thisSigBytes + i) % 4) * 8);
305
+ }
306
+ } else {
307
+ // Copy one word at a time
308
+ for (var i = 0; i < thatSigBytes; i += 4) {
309
+ thisWords[(thisSigBytes + i) >>> 2] = thatWords[i >>> 2];
310
+ }
311
+ }
312
+ this.sigBytes += thatSigBytes;
313
+
314
+ // Chainable
315
+ return this;
316
+ },
317
+
318
+ /**
319
+ * Removes insignificant bits.
320
+ *
321
+ * @example
322
+ *
323
+ * wordArray.clamp();
324
+ */
325
+ clamp: function () {
326
+ // Shortcuts
327
+ var words = this.words;
328
+ var sigBytes = this.sigBytes;
329
+
330
+ // Clamp
331
+ words[sigBytes >>> 2] &= 0xffffffff << (32 - (sigBytes % 4) * 8);
332
+ words.length = Math.ceil(sigBytes / 4);
333
+ },
334
+
335
+ /**
336
+ * Creates a copy of this word array.
337
+ *
338
+ * @return {WordArray} The clone.
339
+ *
340
+ * @example
341
+ *
342
+ * var clone = wordArray.clone();
343
+ */
344
+ clone: function () {
345
+ var clone = Base.clone.call(this);
346
+ clone.words = this.words.slice(0);
347
+
348
+ return clone;
349
+ },
350
+
351
+ /**
352
+ * Creates a word array filled with random bytes.
353
+ *
354
+ * @param {number} nBytes The number of random bytes to generate.
355
+ *
356
+ * @return {WordArray} The random word array.
357
+ *
358
+ * @static
359
+ *
360
+ * @example
361
+ *
362
+ * var wordArray = CryptoJS.lib.WordArray.random(16);
363
+ */
364
+ random: function (nBytes) {
365
+ var words = [];
366
+
367
+ for (var i = 0; i < nBytes; i += 4) {
368
+ words.push(cryptoSecureRandomInt());
369
+ }
370
+
371
+ return new WordArray.init(words, nBytes);
372
+ }
373
+ });
374
+
375
+ /**
376
+ * Encoder namespace.
377
+ */
378
+ var C_enc = C.enc = {};
379
+
380
+ /**
381
+ * Hex encoding strategy.
382
+ */
383
+ var Hex = C_enc.Hex = {
384
+ /**
385
+ * Converts a word array to a hex string.
386
+ *
387
+ * @param {WordArray} wordArray The word array.
388
+ *
389
+ * @return {string} The hex string.
390
+ *
391
+ * @static
392
+ *
393
+ * @example
394
+ *
395
+ * var hexString = CryptoJS.enc.Hex.stringify(wordArray);
396
+ */
397
+ stringify: function (wordArray) {
398
+ // Shortcuts
399
+ var words = wordArray.words;
400
+ var sigBytes = wordArray.sigBytes;
401
+
402
+ // Convert
403
+ var hexChars = [];
404
+ for (var i = 0; i < sigBytes; i++) {
405
+ var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
406
+ hexChars.push((bite >>> 4).toString(16));
407
+ hexChars.push((bite & 0x0f).toString(16));
408
+ }
409
+
410
+ return hexChars.join('');
411
+ },
412
+
413
+ /**
414
+ * Converts a hex string to a word array.
415
+ *
416
+ * @param {string} hexStr The hex string.
417
+ *
418
+ * @return {WordArray} The word array.
419
+ *
420
+ * @static
421
+ *
422
+ * @example
423
+ *
424
+ * var wordArray = CryptoJS.enc.Hex.parse(hexString);
425
+ */
426
+ parse: function (hexStr) {
427
+ // Shortcut
428
+ var hexStrLength = hexStr.length;
429
+
430
+ // Convert
431
+ var words = [];
432
+ for (var i = 0; i < hexStrLength; i += 2) {
433
+ words[i >>> 3] |= parseInt(hexStr.substr(i, 2), 16) << (24 - (i % 8) * 4);
434
+ }
435
+
436
+ return new WordArray.init(words, hexStrLength / 2);
437
+ }
438
+ };
439
+
440
+ /**
441
+ * Latin1 encoding strategy.
442
+ */
443
+ var Latin1 = C_enc.Latin1 = {
444
+ /**
445
+ * Converts a word array to a Latin1 string.
446
+ *
447
+ * @param {WordArray} wordArray The word array.
448
+ *
449
+ * @return {string} The Latin1 string.
450
+ *
451
+ * @static
452
+ *
453
+ * @example
454
+ *
455
+ * var latin1String = CryptoJS.enc.Latin1.stringify(wordArray);
456
+ */
457
+ stringify: function (wordArray) {
458
+ // Shortcuts
459
+ var words = wordArray.words;
460
+ var sigBytes = wordArray.sigBytes;
461
+
462
+ // Convert
463
+ var latin1Chars = [];
464
+ for (var i = 0; i < sigBytes; i++) {
465
+ var bite = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
466
+ latin1Chars.push(String.fromCharCode(bite));
467
+ }
468
+
469
+ return latin1Chars.join('');
470
+ },
471
+
472
+ /**
473
+ * Converts a Latin1 string to a word array.
474
+ *
475
+ * @param {string} latin1Str The Latin1 string.
476
+ *
477
+ * @return {WordArray} The word array.
478
+ *
479
+ * @static
480
+ *
481
+ * @example
482
+ *
483
+ * var wordArray = CryptoJS.enc.Latin1.parse(latin1String);
484
+ */
485
+ parse: function (latin1Str) {
486
+ // Shortcut
487
+ var latin1StrLength = latin1Str.length;
488
+
489
+ // Convert
490
+ var words = [];
491
+ for (var i = 0; i < latin1StrLength; i++) {
492
+ words[i >>> 2] |= (latin1Str.charCodeAt(i) & 0xff) << (24 - (i % 4) * 8);
493
+ }
494
+
495
+ return new WordArray.init(words, latin1StrLength);
496
+ }
497
+ };
498
+
499
+ /**
500
+ * UTF-8 encoding strategy.
501
+ */
502
+ var Utf8 = C_enc.Utf8 = {
503
+ /**
504
+ * Converts a word array to a UTF-8 string.
505
+ *
506
+ * @param {WordArray} wordArray The word array.
507
+ *
508
+ * @return {string} The UTF-8 string.
509
+ *
510
+ * @static
511
+ *
512
+ * @example
513
+ *
514
+ * var utf8String = CryptoJS.enc.Utf8.stringify(wordArray);
515
+ */
516
+ stringify: function (wordArray) {
517
+ try {
518
+ return decodeURIComponent(escape(Latin1.stringify(wordArray)));
519
+ } catch (e) {
520
+ throw new Error('Malformed UTF-8 data');
521
+ }
522
+ },
523
+
524
+ /**
525
+ * Converts a UTF-8 string to a word array.
526
+ *
527
+ * @param {string} utf8Str The UTF-8 string.
528
+ *
529
+ * @return {WordArray} The word array.
530
+ *
531
+ * @static
532
+ *
533
+ * @example
534
+ *
535
+ * var wordArray = CryptoJS.enc.Utf8.parse(utf8String);
536
+ */
537
+ parse: function (utf8Str) {
538
+ return Latin1.parse(unescape(encodeURIComponent(utf8Str)));
539
+ }
540
+ };
541
+
542
+ /**
543
+ * Abstract buffered block algorithm template.
544
+ *
545
+ * The property blockSize must be implemented in a concrete subtype.
546
+ *
547
+ * @property {number} _minBufferSize The number of blocks that should be kept unprocessed in the buffer. Default: 0
548
+ */
549
+ var BufferedBlockAlgorithm = C_lib.BufferedBlockAlgorithm = Base.extend({
550
+ /**
551
+ * Resets this block algorithm's data buffer to its initial state.
552
+ *
553
+ * @example
554
+ *
555
+ * bufferedBlockAlgorithm.reset();
556
+ */
557
+ reset: function () {
558
+ // Initial values
559
+ this._data = new WordArray.init();
560
+ this._nDataBytes = 0;
561
+ },
562
+
563
+ /**
564
+ * Adds new data to this block algorithm's buffer.
565
+ *
566
+ * @param {WordArray|string} data The data to append. Strings are converted to a WordArray using UTF-8.
567
+ *
568
+ * @example
569
+ *
570
+ * bufferedBlockAlgorithm._append('data');
571
+ * bufferedBlockAlgorithm._append(wordArray);
572
+ */
573
+ _append: function (data) {
574
+ // Convert string to WordArray, else assume WordArray already
575
+ if (typeof data == 'string') {
576
+ data = Utf8.parse(data);
577
+ }
578
+
579
+ // Append
580
+ this._data.concat(data);
581
+ this._nDataBytes += data.sigBytes;
582
+ },
583
+
584
+ /**
585
+ * Processes available data blocks.
586
+ *
587
+ * This method invokes _doProcessBlock(offset), which must be implemented by a concrete subtype.
588
+ *
589
+ * @param {boolean} doFlush Whether all blocks and partial blocks should be processed.
590
+ *
591
+ * @return {WordArray} The processed data.
592
+ *
593
+ * @example
594
+ *
595
+ * var processedData = bufferedBlockAlgorithm._process();
596
+ * var processedData = bufferedBlockAlgorithm._process(!!'flush');
597
+ */
598
+ _process: function (doFlush) {
599
+ var processedWords;
600
+
601
+ // Shortcuts
602
+ var data = this._data;
603
+ var dataWords = data.words;
604
+ var dataSigBytes = data.sigBytes;
605
+ var blockSize = this.blockSize;
606
+ var blockSizeBytes = blockSize * 4;
607
+
608
+ // Count blocks ready
609
+ var nBlocksReady = dataSigBytes / blockSizeBytes;
610
+ if (doFlush) {
611
+ // Round up to include partial blocks
612
+ nBlocksReady = Math.ceil(nBlocksReady);
613
+ } else {
614
+ // Round down to include only full blocks,
615
+ // less the number of blocks that must remain in the buffer
616
+ nBlocksReady = Math.max((nBlocksReady | 0) - this._minBufferSize, 0);
617
+ }
618
+
619
+ // Count words ready
620
+ var nWordsReady = nBlocksReady * blockSize;
621
+
622
+ // Count bytes ready
623
+ var nBytesReady = Math.min(nWordsReady * 4, dataSigBytes);
624
+
625
+ // Process blocks
626
+ if (nWordsReady) {
627
+ for (var offset = 0; offset < nWordsReady; offset += blockSize) {
628
+ // Perform concrete-algorithm logic
629
+ this._doProcessBlock(dataWords, offset);
630
+ }
631
+
632
+ // Remove processed words
633
+ processedWords = dataWords.splice(0, nWordsReady);
634
+ data.sigBytes -= nBytesReady;
635
+ }
636
+
637
+ // Return processed words
638
+ return new WordArray.init(processedWords, nBytesReady);
639
+ },
640
+
641
+ /**
642
+ * Creates a copy of this object.
643
+ *
644
+ * @return {Object} The clone.
645
+ *
646
+ * @example
647
+ *
648
+ * var clone = bufferedBlockAlgorithm.clone();
649
+ */
650
+ clone: function () {
651
+ var clone = Base.clone.call(this);
652
+ clone._data = this._data.clone();
653
+
654
+ return clone;
655
+ },
656
+
657
+ _minBufferSize: 0
658
+ });
659
+
660
+ /**
661
+ * Abstract hasher template.
662
+ *
663
+ * @property {number} blockSize The number of 32-bit words this hasher operates on. Default: 16 (512 bits)
664
+ */
665
+ C_lib.Hasher = BufferedBlockAlgorithm.extend({
666
+ /**
667
+ * Configuration options.
668
+ */
669
+ cfg: Base.extend(),
670
+
671
+ /**
672
+ * Initializes a newly created hasher.
673
+ *
674
+ * @param {Object} cfg (Optional) The configuration options to use for this hash computation.
675
+ *
676
+ * @example
677
+ *
678
+ * var hasher = CryptoJS.algo.SHA256.create();
679
+ */
680
+ init: function (cfg) {
681
+ // Apply config defaults
682
+ this.cfg = this.cfg.extend(cfg);
683
+
684
+ // Set initial values
685
+ this.reset();
686
+ },
687
+
688
+ /**
689
+ * Resets this hasher to its initial state.
690
+ *
691
+ * @example
692
+ *
693
+ * hasher.reset();
694
+ */
695
+ reset: function () {
696
+ // Reset data buffer
697
+ BufferedBlockAlgorithm.reset.call(this);
698
+
699
+ // Perform concrete-hasher logic
700
+ this._doReset();
701
+ },
702
+
703
+ /**
704
+ * Updates this hasher with a message.
705
+ *
706
+ * @param {WordArray|string} messageUpdate The message to append.
707
+ *
708
+ * @return {Hasher} This hasher.
709
+ *
710
+ * @example
711
+ *
712
+ * hasher.update('message');
713
+ * hasher.update(wordArray);
714
+ */
715
+ update: function (messageUpdate) {
716
+ // Append
717
+ this._append(messageUpdate);
718
+
719
+ // Update the hash
720
+ this._process();
721
+
722
+ // Chainable
723
+ return this;
724
+ },
725
+
726
+ /**
727
+ * Finalizes the hash computation.
728
+ * Note that the finalize operation is effectively a destructive, read-once operation.
729
+ *
730
+ * @param {WordArray|string} messageUpdate (Optional) A final message update.
731
+ *
732
+ * @return {WordArray} The hash.
733
+ *
734
+ * @example
735
+ *
736
+ * var hash = hasher.finalize();
737
+ * var hash = hasher.finalize('message');
738
+ * var hash = hasher.finalize(wordArray);
739
+ */
740
+ finalize: function (messageUpdate) {
741
+ // Final message update
742
+ if (messageUpdate) {
743
+ this._append(messageUpdate);
744
+ }
745
+
746
+ // Perform concrete-hasher logic
747
+ var hash = this._doFinalize();
748
+
749
+ return hash;
750
+ },
751
+
752
+ blockSize: 512/32,
753
+
754
+ /**
755
+ * Creates a shortcut function to a hasher's object interface.
756
+ *
757
+ * @param {Hasher} hasher The hasher to create a helper for.
758
+ *
759
+ * @return {Function} The shortcut function.
760
+ *
761
+ * @static
762
+ *
763
+ * @example
764
+ *
765
+ * var SHA256 = CryptoJS.lib.Hasher._createHelper(CryptoJS.algo.SHA256);
766
+ */
767
+ _createHelper: function (hasher) {
768
+ return function (message, cfg) {
769
+ return new hasher.init(cfg).finalize(message);
770
+ };
771
+ },
772
+
773
+ /**
774
+ * Creates a shortcut function to the HMAC's object interface.
775
+ *
776
+ * @param {Hasher} hasher The hasher to use in this HMAC helper.
777
+ *
778
+ * @return {Function} The shortcut function.
779
+ *
780
+ * @static
781
+ *
782
+ * @example
783
+ *
784
+ * var HmacSHA256 = CryptoJS.lib.Hasher._createHmacHelper(CryptoJS.algo.SHA256);
785
+ */
786
+ _createHmacHelper: function (hasher) {
787
+ return function (message, key) {
788
+ return new C_algo.HMAC.init(hasher, key).finalize(message);
789
+ };
790
+ }
791
+ });
792
+
793
+ /**
794
+ * Algorithm namespace.
795
+ */
796
+ var C_algo = C.algo = {};
797
+
798
+ return C;
799
+ }(Math));
800
+
801
+
802
+ return CryptoJS;
803
+
804
+ }));
805
+ });
806
+
807
+ var sha256 = createCommonjsModule(function (module, exports) {
808
+ (function (root, factory) {
809
+ {
810
+ // CommonJS
811
+ module.exports = factory(core);
812
+ }
813
+ }(commonjsGlobal, function (CryptoJS) {
814
+
815
+ (function (Math) {
816
+ // Shortcuts
817
+ var C = CryptoJS;
818
+ var C_lib = C.lib;
819
+ var WordArray = C_lib.WordArray;
820
+ var Hasher = C_lib.Hasher;
821
+ var C_algo = C.algo;
822
+
823
+ // Initialization and round constants tables
824
+ var H = [];
825
+ var K = [];
826
+
827
+ // Compute constants
828
+ (function () {
829
+ function isPrime(n) {
830
+ var sqrtN = Math.sqrt(n);
831
+ for (var factor = 2; factor <= sqrtN; factor++) {
832
+ if (!(n % factor)) {
833
+ return false;
834
+ }
835
+ }
836
+
837
+ return true;
838
+ }
839
+
840
+ function getFractionalBits(n) {
841
+ return ((n - (n | 0)) * 0x100000000) | 0;
842
+ }
843
+
844
+ var n = 2;
845
+ var nPrime = 0;
846
+ while (nPrime < 64) {
847
+ if (isPrime(n)) {
848
+ if (nPrime < 8) {
849
+ H[nPrime] = getFractionalBits(Math.pow(n, 1 / 2));
850
+ }
851
+ K[nPrime] = getFractionalBits(Math.pow(n, 1 / 3));
852
+
853
+ nPrime++;
854
+ }
855
+
856
+ n++;
857
+ }
858
+ }());
859
+
860
+ // Reusable object
861
+ var W = [];
862
+
863
+ /**
864
+ * SHA-256 hash algorithm.
865
+ */
866
+ var SHA256 = C_algo.SHA256 = Hasher.extend({
867
+ _doReset: function () {
868
+ this._hash = new WordArray.init(H.slice(0));
869
+ },
870
+
871
+ _doProcessBlock: function (M, offset) {
872
+ // Shortcut
873
+ var H = this._hash.words;
874
+
875
+ // Working variables
876
+ var a = H[0];
877
+ var b = H[1];
878
+ var c = H[2];
879
+ var d = H[3];
880
+ var e = H[4];
881
+ var f = H[5];
882
+ var g = H[6];
883
+ var h = H[7];
884
+
885
+ // Computation
886
+ for (var i = 0; i < 64; i++) {
887
+ if (i < 16) {
888
+ W[i] = M[offset + i] | 0;
889
+ } else {
890
+ var gamma0x = W[i - 15];
891
+ var gamma0 = ((gamma0x << 25) | (gamma0x >>> 7)) ^
892
+ ((gamma0x << 14) | (gamma0x >>> 18)) ^
893
+ (gamma0x >>> 3);
894
+
895
+ var gamma1x = W[i - 2];
896
+ var gamma1 = ((gamma1x << 15) | (gamma1x >>> 17)) ^
897
+ ((gamma1x << 13) | (gamma1x >>> 19)) ^
898
+ (gamma1x >>> 10);
899
+
900
+ W[i] = gamma0 + W[i - 7] + gamma1 + W[i - 16];
901
+ }
902
+
903
+ var ch = (e & f) ^ (~e & g);
904
+ var maj = (a & b) ^ (a & c) ^ (b & c);
905
+
906
+ var sigma0 = ((a << 30) | (a >>> 2)) ^ ((a << 19) | (a >>> 13)) ^ ((a << 10) | (a >>> 22));
907
+ var sigma1 = ((e << 26) | (e >>> 6)) ^ ((e << 21) | (e >>> 11)) ^ ((e << 7) | (e >>> 25));
908
+
909
+ var t1 = h + sigma1 + ch + K[i] + W[i];
910
+ var t2 = sigma0 + maj;
911
+
912
+ h = g;
913
+ g = f;
914
+ f = e;
915
+ e = (d + t1) | 0;
916
+ d = c;
917
+ c = b;
918
+ b = a;
919
+ a = (t1 + t2) | 0;
920
+ }
921
+
922
+ // Intermediate hash value
923
+ H[0] = (H[0] + a) | 0;
924
+ H[1] = (H[1] + b) | 0;
925
+ H[2] = (H[2] + c) | 0;
926
+ H[3] = (H[3] + d) | 0;
927
+ H[4] = (H[4] + e) | 0;
928
+ H[5] = (H[5] + f) | 0;
929
+ H[6] = (H[6] + g) | 0;
930
+ H[7] = (H[7] + h) | 0;
931
+ },
932
+
933
+ _doFinalize: function () {
934
+ // Shortcuts
935
+ var data = this._data;
936
+ var dataWords = data.words;
937
+
938
+ var nBitsTotal = this._nDataBytes * 8;
939
+ var nBitsLeft = data.sigBytes * 8;
940
+
941
+ // Add padding
942
+ dataWords[nBitsLeft >>> 5] |= 0x80 << (24 - nBitsLeft % 32);
943
+ dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 14] = Math.floor(nBitsTotal / 0x100000000);
944
+ dataWords[(((nBitsLeft + 64) >>> 9) << 4) + 15] = nBitsTotal;
945
+ data.sigBytes = dataWords.length * 4;
946
+
947
+ // Hash final blocks
948
+ this._process();
949
+
950
+ // Return final computed hash
951
+ return this._hash;
952
+ },
953
+
954
+ clone: function () {
955
+ var clone = Hasher.clone.call(this);
956
+ clone._hash = this._hash.clone();
957
+
958
+ return clone;
959
+ }
960
+ });
961
+
962
+ /**
963
+ * Shortcut function to the hasher's object interface.
964
+ *
965
+ * @param {WordArray|string} message The message to hash.
966
+ *
967
+ * @return {WordArray} The hash.
968
+ *
969
+ * @static
970
+ *
971
+ * @example
972
+ *
973
+ * var hash = CryptoJS.SHA256('message');
974
+ * var hash = CryptoJS.SHA256(wordArray);
975
+ */
976
+ C.SHA256 = Hasher._createHelper(SHA256);
977
+
978
+ /**
979
+ * Shortcut function to the HMAC's object interface.
980
+ *
981
+ * @param {WordArray|string} message The message to hash.
982
+ * @param {WordArray|string} key The secret key.
983
+ *
984
+ * @return {WordArray} The HMAC.
985
+ *
986
+ * @static
987
+ *
988
+ * @example
989
+ *
990
+ * var hmac = CryptoJS.HmacSHA256(message, key);
991
+ */
992
+ C.HmacSHA256 = Hasher._createHmacHelper(SHA256);
993
+ }(Math));
994
+
995
+
996
+ return CryptoJS.SHA256;
997
+
998
+ }));
999
+ });
1000
+
1001
+ const hasProp = (obj, prop) =>
1002
+ Object.prototype.hasOwnProperty.call(obj, prop);
1003
+
1004
+ function isFalsey(valueObj) {
1005
+ if (!valueObj) {
1006
+ return true;
1007
+ }
1008
+ if (valueObj.class === 'FalseClass') {
1009
+ return true;
1010
+ }
1011
+ if (valueObj.class === 'Array' && valueObj.value === '[]') {
1012
+ return true;
1013
+ }
1014
+ if (valueObj.value === '') {
1015
+ return true;
1016
+ }
1017
+
1018
+ return false;
1019
+ }
1020
+
1021
+ function isCommand(event) {
1022
+ if (event.http_server_request) {
1023
+ return true;
1024
+ }
1025
+ if (event.codeObject.labels.has('command')) {
1026
+ return true;
1027
+ }
1028
+ return false;
1029
+ }
1030
+
1031
+ function capitalizeString(str) {
1032
+ if (typeof str !== 'string') {
1033
+ return '';
1034
+ }
1035
+
1036
+ return str.slice(0, 1).toUpperCase() + str.slice(1).toLowerCase();
1037
+ }
1038
+
1039
+ function getHttpLabel(event) {
1040
+ if (hasProp(event, 'http_server_request') === false) {
1041
+ return null;
1042
+ }
1043
+
1044
+ const requestMethod = event.http_server_request.request_method;
1045
+ const pathInfo = event.http_server_request.path_info;
1046
+ let label;
1047
+
1048
+ try {
1049
+ // the url is fake, we only care about the path info anyway
1050
+ const url = new URL(pathInfo, 'http://hostname');
1051
+ label = `${requestMethod} ${url.pathname}`;
1052
+ } catch (ex) {
1053
+ label = 'HTTP Request';
1054
+ }
1055
+
1056
+ return label;
1057
+ }
1058
+
1059
+ const sqlLabels = new Set([
1060
+ 'insert',
1061
+ 'update',
1062
+ 'select',
1063
+ 'delete',
1064
+ 'alter',
1065
+ 'create',
1066
+ 'drop',
1067
+ 'rename',
1068
+ 'truncate',
1069
+ 'replace',
1070
+ 'savepoint',
1071
+ 'release',
1072
+ 'rollback',
1073
+ 'lock',
1074
+ 'unlock',
1075
+ 'set',
1076
+ 'start',
1077
+ 'call',
1078
+ 'delete',
1079
+ 'do',
1080
+ 'perform',
1081
+ 'handler',
1082
+ 'load',
1083
+ 'purge',
1084
+ 'reset',
1085
+ 'prepare',
1086
+ 'execute',
1087
+ 'deallocate',
1088
+ 'xa',
1089
+ ]);
1090
+
1091
+ function getSqlLabelFromString(sqlString) {
1092
+ const sqlChars = [...sqlString.trimLeft()];
1093
+ if (sqlChars.length > 0 && sqlChars[0] === '(') {
1094
+ // if the query is wrapped in parenthesis, drop the opening parenthesis
1095
+ // it doesn't matter if we leave a hanging closing parenthesis.
1096
+ // e.g. (SELECT 1);
1097
+
1098
+ sqlChars.shift();
1099
+ }
1100
+
1101
+ // drop sub-queries and parenthesized expressions
1102
+ let depth = 0;
1103
+ const topLevelSql = sqlChars
1104
+ .reduce((arr, c) => {
1105
+ if (c === '(') {
1106
+ depth += 1;
1107
+ }
1108
+
1109
+ if (depth === 0) {
1110
+ arr.push(c);
1111
+ }
1112
+
1113
+ if (c === ')') {
1114
+ depth -= 1;
1115
+ }
1116
+
1117
+ return arr;
1118
+ }, [])
1119
+ .join('');
1120
+
1121
+ let queryType = null;
1122
+ if (topLevelSql.search(/\s/) === -1) {
1123
+ // There's only a single token
1124
+ // e.g. BEGIN, COMMIT, CHECKPOINT
1125
+ queryType = topLevelSql;
1126
+ } else {
1127
+ // convert non-word sequences to spaces and split by space
1128
+ // find the first known token
1129
+ queryType = topLevelSql
1130
+ .replace(/[^\w]+/g, ' ')
1131
+ .toLowerCase()
1132
+ .split(' ')
1133
+ .find((t) => sqlLabels.has(t));
1134
+ }
1135
+
1136
+ return ['SQL', capitalizeString(queryType) || null].join(' ');
1137
+ }
1138
+ function getSqlLabel(event) {
1139
+ if (hasProp(event, 'sql_query') === false) {
1140
+ return null;
1141
+ }
1142
+
1143
+ return getSqlLabelFromString(
1144
+ event.sql_query.normalized_sql || event.sql_query.sql || ''
1145
+ );
1146
+ }
1147
+
1148
+ function getLabel(event) {
1149
+ let label = getHttpLabel(event);
1150
+ if (!label) {
1151
+ label = getSqlLabel(event);
1152
+ }
1153
+ return label;
1154
+ }
1155
+
1156
+ function hashify(obj) {
1157
+ const clone = { ...obj };
1158
+ Object.keys(obj).forEach((key) => {
1159
+ const val = obj[key];
1160
+ if (Array.isArray(val)) {
1161
+ clone[key] = new Set(val);
1162
+ } else if (val instanceof Set) {
1163
+ clone[key] = val;
1164
+ } else if (val && typeof val === 'object') {
1165
+ clone[key] = hashify(val);
1166
+ } else {
1167
+ clone[key] = val;
1168
+ }
1169
+ });
1170
+ return clone;
1171
+ }
1172
+
1173
+ const REPOSITORY_RESOLVERS = {
1174
+ github: (d) => {
1175
+ const match = d.url.match(/github.com[:|/]?(.*).git/);
1176
+ if (!match || match.length <= 1) {
1177
+ return null;
1178
+ }
1179
+
1180
+ const hash = typeof d.lineNumber === 'number' ? `#L${d.lineNumber}` : '';
1181
+ return `https://github.com/${match[1]}/blob/${d.commit}/${d.path}${hash}`;
1182
+ },
1183
+ };
1184
+
1185
+ function getRepositoryUrl(
1186
+ url,
1187
+ path,
1188
+ commit = 'master',
1189
+ lineNumber = null
1190
+ ) {
1191
+ if (url && path) {
1192
+ const d = { url, path, lineNumber, commit };
1193
+ const resolvers = Object.values(REPOSITORY_RESOLVERS);
1194
+ for (let i = 0; i < resolvers.length; i += 1) {
1195
+ const repositoryUrl = resolvers[i](d);
1196
+ if (repositoryUrl) {
1197
+ return repositoryUrl;
1198
+ }
1199
+ }
1200
+ }
1201
+
1202
+ return null;
1203
+ }
1204
+
1205
+ const UPPER = 0x1;
1206
+ const LOWER = 0x10;
1207
+ const getCase = (char) => (/[A-Z]/.exec(char) === null ? LOWER : UPPER);
1208
+ const getCasePattern = (str) => {
1209
+ if (str.length <= 2) {
1210
+ return null;
1211
+ }
1212
+
1213
+ return {
1214
+ firstCase: getCase(str[0]),
1215
+ secondCase: getCase(str[1]),
1216
+ };
1217
+ };
1218
+
1219
+ const splitCamelCase = (str) => {
1220
+ const strLen = str.length;
1221
+ if (strLen < 1) {
1222
+ return [];
1223
+ }
1224
+
1225
+ const casePattern = getCasePattern(str);
1226
+ if (!casePattern) {
1227
+ return [str];
1228
+ }
1229
+
1230
+ const { firstCase, secondCase } = casePattern;
1231
+ const ret = [];
1232
+ let matched = false;
1233
+ for (let i = 2; i < strLen; i += 1) {
1234
+ const charCase = getCase(str[i]);
1235
+ if (charCase === UPPER) {
1236
+ if (firstCase === LOWER || secondCase === LOWER) {
1237
+ const token = str.slice(0, i);
1238
+ ret.push(token);
1239
+ ret.push(...splitCamelCase(str.slice(i)));
1240
+ matched = true;
1241
+ break;
1242
+ }
1243
+ } else if (
1244
+ charCase === LOWER &&
1245
+ firstCase === UPPER &&
1246
+ secondCase === UPPER
1247
+ ) {
1248
+ const token = str.slice(0, i - 1);
1249
+ ret.push(token);
1250
+ ret.push(...splitCamelCase(str.slice(i - 1)));
1251
+ matched = true;
1252
+ break;
1253
+ }
1254
+ }
1255
+
1256
+ if (!matched) {
1257
+ ret.push(str);
1258
+ }
1259
+
1260
+ return ret;
1261
+ };
1262
+
1263
+ // Builds the fully qualified function name of a function (static or instance) within a
1264
+ // fully qualified class name.
1265
+ function fullyQualifiedFunctionName(event) {
1266
+ const label = getLabel(event);
1267
+ if (label) {
1268
+ return label;
1269
+ }
1270
+
1271
+ return event.toString();
1272
+ }
1273
+
1274
+ // tokenizeIdentifier returns tokens of an identifier split by non-alphanumeric and camel casing
1275
+ // example:
1276
+ // someMethodName -> [ 'some', 'method', 'name' ]
1277
+ // some_method_name -> [ 'some', 'method', 'name' ]
1278
+ // org.company.MyPackage.MyClass -> [ 'org', 'company', 'My', 'Package', 'My', 'Class']
1279
+ function tokenizeIdentifier(id) {
1280
+ const ret = [];
1281
+
1282
+ // Split first by non-alphanumeric tokens
1283
+ const tokens = (id || '').split(/[$.:#\-_]/);
1284
+
1285
+ // Split remaining tokens by camel case
1286
+ tokens.forEach((token) => {
1287
+ ret.push(...splitCamelCase(token));
1288
+ });
1289
+
1290
+ return ret;
1291
+ }
1292
+
1293
+ function addHiddenProperty(obj, property, opts) {
1294
+ if (!Object.hasOwnProperty.call(obj, '$hidden')) {
1295
+ Object.defineProperty(obj, '$hidden', {
1296
+ enumerable: false,
1297
+ writable: false,
1298
+ value: {},
1299
+ });
1300
+ }
1301
+
1302
+ Object.defineProperty(obj.$hidden, property, {
1303
+ enumerable: false,
1304
+ writable: true,
1305
+ ...opts,
1306
+ });
1307
+ }
1308
+
1309
+ function buildLabels(classMap, events) {
1310
+ const result = {};
1311
+
1312
+ function addLabel(label, obj, type, target) {
1313
+ /* eslint-disable no-param-reassign */
1314
+ if (!obj[label]) {
1315
+ obj[label] = {};
1316
+ }
1317
+
1318
+ if (!obj[label][type]) {
1319
+ obj[label][type] = [];
1320
+ }
1321
+
1322
+ obj[label][type].push(target);
1323
+ /* eslint-enable no-param-reassign */
1324
+ }
1325
+
1326
+ classMap.codeObjects
1327
+ .filter((obj) => obj.labels.size)
1328
+ .forEach((codeObject) => {
1329
+ Array.from(codeObject.labels).forEach((label) => {
1330
+ addLabel(label, result, codeObject.type, codeObject);
1331
+ });
1332
+ });
1333
+
1334
+ events
1335
+ .filter((event) => event.isCall() && event.labels.size)
1336
+ .forEach((event) => {
1337
+ Array.from(event.labels).forEach((label) => {
1338
+ addLabel(label, result, 'event', event);
1339
+ });
1340
+ });
1341
+
1342
+ return result;
1343
+ }
1344
+
1345
+ // sizeof returns a naive byte count for an object when serialized.
1346
+ // I was using an external library for this (object-sizeof), but getting results off by a factor of
1347
+ // ~2. This is awfully wasteful, slow and inaccurate but it works for now. -DB
1348
+ const sizeof = (obj) => JSON.stringify(obj).length;
1349
+
1350
+ const DYNAMIC_FIELDS = new Set([
1351
+ 'id',
1352
+ 'value',
1353
+ 'thread_id',
1354
+ 'elapsed',
1355
+ 'object_id',
1356
+ 'lineno',
1357
+ 'path',
1358
+ ]);
1359
+
1360
+ function getStaticPropValues(obj) {
1361
+ return Object.getOwnPropertyNames(obj)
1362
+ .filter((k) => typeof obj[k] !== 'object' && !DYNAMIC_FIELDS.has(k))
1363
+ .sort()
1364
+ .map((k) => obj[k]);
1365
+ }
1366
+
1367
+ /* eslint-disable no-inner-declarations */
1368
+ function parseNormalizeSQL(sql) {
1369
+ const parseSQL = sql.replace(/\s+returning\s+\*/i, '');
1370
+ let ast;
1371
+ try {
1372
+ ast = sqliteParser(parseSQL);
1373
+ } catch (e) {
1374
+ console.warn(`Unable to parse ${parseSQL} : ${e.message}`);
1375
+ return null;
1376
+ }
1377
+
1378
+ try {
1379
+ const actions = [];
1380
+ const columns = [];
1381
+ const tables = [];
1382
+
1383
+ function parse(statement) {
1384
+ const tokens = ['type', 'variant']
1385
+ .map((propertyName) => statement[propertyName])
1386
+ .filter((value) => value);
1387
+
1388
+ const key = tokens.join('.');
1389
+ // eslint-disable-next-line no-use-before-define
1390
+ let parser = parsers[key];
1391
+ if (!parser) {
1392
+ // eslint-disable-next-line no-use-before-define
1393
+ parser = parseStatement;
1394
+ }
1395
+
1396
+ const parserList = Array.isArray(parser) ? parser : [parser];
1397
+ parserList.forEach((prs) => prs(statement));
1398
+ }
1399
+
1400
+ function parseStatement(statement) {
1401
+ const reservedWords = ['type', 'variant', 'name', 'value'];
1402
+ Object.keys(statement)
1403
+ .filter((property) => !reservedWords.includes(property))
1404
+ .map((propertyName) => statement[propertyName])
1405
+ .forEach((property) => {
1406
+ if (Array.isArray(property)) {
1407
+ property.forEach(parse);
1408
+ } else if (typeof property === 'object') {
1409
+ parse(property);
1410
+ } else if (
1411
+ typeof property === 'string' ||
1412
+ typeof property === 'boolean'
1413
+ ) {
1414
+ // pass
1415
+ } else {
1416
+ console.warn(
1417
+ `Unrecognized subexpression: ${typeof property} ${property}`
1418
+ );
1419
+ }
1420
+ });
1421
+ }
1422
+
1423
+ function parseList(listElements, statement) {
1424
+ listElements.forEach((listElement) => {
1425
+ const subExpression = statement[listElement];
1426
+ if (Array.isArray(subExpression)) {
1427
+ subExpression.forEach(parse);
1428
+ } else if (typeof subExpression === 'object') {
1429
+ parse(subExpression);
1430
+ } else {
1431
+ console.warn(`Unrecognized subexpression: ${subExpression}`);
1432
+ }
1433
+ });
1434
+ }
1435
+ const nop = () => {};
1436
+ function parseIdentifierExpression(statement) {
1437
+ if (statement.format === 'table') {
1438
+ tables.push(statement.name);
1439
+ }
1440
+ parseList(['columns'], statement);
1441
+ }
1442
+ function recordAction(action) {
1443
+ return () => {
1444
+ actions.push(action);
1445
+ };
1446
+ }
1447
+
1448
+ const parsers = {
1449
+ 'literal.text': nop,
1450
+ 'literal.decimal': nop,
1451
+ 'identifier.star': (statement) => columns.push(statement.name),
1452
+ 'identifier.column': (statement) => columns.push(statement.name),
1453
+ 'identifier.table': (statement) => tables.push(statement.name),
1454
+ 'identifier.expression': parseIdentifierExpression,
1455
+ 'statement.select': [recordAction('select'), parseStatement],
1456
+ 'statement.insert': [recordAction('insert'), parseStatement],
1457
+ 'statement.update': [recordAction('update'), parseStatement],
1458
+ 'statement.delete': [recordAction('delete'), parseStatement],
1459
+ 'statement.pragma': nop,
1460
+ };
1461
+
1462
+ parse(ast);
1463
+
1464
+ function unique(list) {
1465
+ return [...new Set(list)];
1466
+ }
1467
+ const uniqueActions = unique(actions).sort();
1468
+
1469
+ return {
1470
+ actions: uniqueActions,
1471
+ tables: unique(tables).sort(),
1472
+ columns: unique(columns).sort(),
1473
+ };
1474
+ } catch (e) {
1475
+ console.warn(`Unable to interpret AST tree for ${parseSQL} : ${e.message}`);
1476
+ return null;
1477
+ }
1478
+ }
1479
+ /* eslint-enable no-inner-declarations */
1480
+
1481
+ function dumbNormalizeSQL(sql) {
1482
+ const sqlLower = sql.toLowerCase().trim();
1483
+ if (sqlLower.indexOf('pragma') === 0) {
1484
+ return {
1485
+ tables: [],
1486
+ columns: [],
1487
+ };
1488
+ }
1489
+
1490
+ const stopWords = ['where', 'limit', 'order by', 'group by', 'values', 'set'];
1491
+ const stopWordLocations = stopWords
1492
+ .map((word) => sqlLower.indexOf(` ${word}`))
1493
+ .filter((index) => index !== -1)
1494
+ .sort();
1495
+ if (stopWordLocations.length > 0) {
1496
+ const subSQL = sql.slice(0, stopWordLocations[0] - 1);
1497
+ return subSQL.replace(
1498
+ /\s([\w_]+)\(\s+'?[w\d]+'?\)\s+\)(?:\s|^)/g,
1499
+ '$1(...)'
1500
+ );
1501
+ }
1502
+
1503
+ console.warn(`Unparseable: ${sql}`);
1504
+ return 'Unparseable';
1505
+ }
1506
+
1507
+ /**
1508
+ * It's essential to normalize SQL to remove trivial differences like WHERE clauses on
1509
+ * generated id values, timestamps, etc.
1510
+ *
1511
+ * @param {string} sql
1512
+ */
1513
+ function normalizeSQL(sql) {
1514
+ return parseNormalizeSQL(sql) || dumbNormalizeSQL(sql);
1515
+ }
1516
+
1517
+ // #region ========= BEGIN UNUSED CODE =========
1518
+ // These are called from Event.compare, but that method may be removed.
1519
+ // Don't merge me!
1520
+
1521
+ function appMapObjectCompare(a, b) {
1522
+ if (a === b) {
1523
+ return true;
1524
+ }
1525
+
1526
+ if (!a || !b) {
1527
+ return false;
1528
+ }
1529
+
1530
+ const props = [
1531
+ ...new Set([
1532
+ ...Object.getOwnPropertyNames(a),
1533
+ ...Object.getOwnPropertyNames(b),
1534
+ ]),
1535
+ ].filter((k) => !DYNAMIC_FIELDS.has(k));
1536
+
1537
+ // return the props that differ
1538
+ return props.filter((k) => a[k] !== b[k]);
1539
+ }
1540
+
1541
+ function sqlCompare(a, b) {
1542
+ let { sqlQuery: sqlQueryA } = a;
1543
+ let { sqlQuery: sqlQueryB } = b;
1544
+
1545
+ if (sqlQueryA === sqlQueryB) {
1546
+ return true;
1547
+ }
1548
+
1549
+ if (!sqlQueryA || !sqlQueryB) {
1550
+ return false;
1551
+ }
1552
+
1553
+ sqlQueryA = normalizeSQL(sqlQueryA);
1554
+ sqlQueryB = normalizeSQL(sqlQueryB);
1555
+
1556
+ if (sqlQueryA.action !== sqlQueryB.action) {
1557
+ return false;
1558
+ }
1559
+
1560
+ const allColumns = [...sqlQueryA.columns, ...sqlQueryB.columns];
1561
+ const allTables = [...sqlQueryA.tables, ...sqlQueryB.tables];
1562
+
1563
+ return (
1564
+ allColumns.find(
1565
+ (c) => !sqlQueryA.columns.includes(c) || !sqlQueryB.columns.includes(c)
1566
+ ) === undefined &&
1567
+ allTables.find(
1568
+ (c) => !sqlQueryA.tables.includes(c) || !sqlQueryB.tables.includes(c)
1569
+ ) === undefined
1570
+ );
1571
+ }
1572
+
1573
+ function arrayCompare(a, b) {
1574
+ if (a === b) {
1575
+ return true;
1576
+ }
1577
+
1578
+ if (!a || !b) {
1579
+ return false;
1580
+ }
1581
+
1582
+ const lengthA = a ? a.length || 0 : 0;
1583
+ const lengthB = b ? b.length || 0 : 0;
1584
+
1585
+ if (lengthA !== lengthB) {
1586
+ return false;
1587
+ }
1588
+
1589
+ for (let i = 0; i < lengthA; i += 1) {
1590
+ if (!appMapObjectCompare(a[i], b[i])) {
1591
+ return false;
1592
+ }
1593
+ }
1594
+
1595
+ return true;
1596
+ }
1597
+
1598
+ function httpCompare(a, b) {
1599
+ const {
1600
+ message: messageA,
1601
+ httpServerRequest: httpServerRequestA,
1602
+ httpServerResponse: httpServerResponseA,
1603
+ } = a;
1604
+
1605
+ const {
1606
+ message: messageB,
1607
+ httpServerRequest: httpServerRequestB,
1608
+ httpServerResponse: httpServerResponseB,
1609
+ } = b;
1610
+
1611
+ return (
1612
+ arrayCompare(messageA, messageB) &&
1613
+ appMapObjectCompare(httpServerRequestA, httpServerRequestB) &&
1614
+ appMapObjectCompare(httpServerResponseA, httpServerResponseB)
1615
+ );
1616
+ }
1617
+
1618
+ function setCompare(a, b) {
1619
+ if (a === b) {
1620
+ return true;
1621
+ }
1622
+
1623
+ if (!a || !b) {
1624
+ return false;
1625
+ }
1626
+
1627
+ const allItems = [...new Set([...a, ...b])];
1628
+ return allItems.find((i) => !a.has(i) || !b.has(i)) === undefined;
1629
+ }
1630
+ // #endregion ========= END UNUSED CODE =========
1631
+
1632
+ function hashHttp(e) {
1633
+ const { httpServerRequest } = e;
1634
+ if (!httpServerRequest) {
1635
+ return null;
1636
+ }
1637
+
1638
+ const { message, httpServerResponse } = e;
1639
+ const content = [];
1640
+ message.forEach((m) =>
1641
+ getStaticPropValues(m).forEach((v) => content.push(v))
1642
+ );
1643
+ getStaticPropValues(httpServerResponse).forEach((v) => content.push(v));
1644
+ getStaticPropValues(httpServerRequest).forEach((v) => content.push(v));
1645
+
1646
+ return sha256(content.join('')).toString();
1647
+ }
1648
+
1649
+ function hashSql(e) {
1650
+ const { sqlQuery } = e;
1651
+ if (!sqlQuery) {
1652
+ return null;
1653
+ }
1654
+
1655
+ const normalizedSql = normalizeSQL(sqlQuery);
1656
+ const content = [normalizedSql.action];
1657
+
1658
+ if (normalizedSql.columns) {
1659
+ normalizedSql.columns.forEach((c) => content.push(c));
1660
+ }
1661
+
1662
+ if (normalizedSql.tables) {
1663
+ normalizedSql.tables.forEach((t) => content.push(t));
1664
+ }
1665
+
1666
+ return sha256(content.join('')).toString();
1667
+ }
1668
+
1669
+ // Returns a unique 'hash' (or really, a key) tied to the event's core identity: SQL, HTTP, or a
1670
+ // specific method on a specific class. This is _really_ naive. The idea is that this better finds
1671
+ // a singular change versus an existing object that has been removed and a new object added in its
1672
+ // place.
1673
+ function identityHashEvent(e) {
1674
+ if (e.httpServerRequest) {
1675
+ return 'http';
1676
+ }
1677
+
1678
+ const { sqlQuery } = e;
1679
+ if (sqlQuery) {
1680
+ const queryOps = normalizeSQL(sqlQuery);
1681
+ const content = ['sql', queryOps.action, ...queryOps.tables]
1682
+ .filter(Boolean)
1683
+ .join('');
1684
+ return sha256(content).toString();
1685
+ }
1686
+
1687
+ return e.toString();
1688
+ }
1689
+
1690
+ function hashEvent(e) {
1691
+ let hash = hashHttp(e);
1692
+ if (hash) {
1693
+ return hash;
1694
+ }
1695
+
1696
+ hash = hashSql(e);
1697
+ if (hash) {
1698
+ return hash;
1699
+ }
1700
+
1701
+ const content = [];
1702
+ getStaticPropValues(e).forEach((v) => content.push(v));
1703
+ e.parameters.forEach((p) =>
1704
+ getStaticPropValues(p).forEach((v) => content.push(v))
1705
+ );
1706
+ [...e.labels].forEach((l) => content.push(l));
1707
+
1708
+ return sha256(content.join('')).toString();
1709
+ }
1710
+
1711
+ function resolveDifferences(arr1, arr2) {
1712
+ let arr1Index = 0;
1713
+ let arr2Index = 0;
1714
+
1715
+ for (;;) {
1716
+ const a = arr1[arr1Index];
1717
+ const b = arr2[arr2Index];
1718
+ if (!a && !b) {
1719
+ return;
1720
+ }
1721
+
1722
+ if (typeof a === 'undefined') {
1723
+ arr1.push(null);
1724
+ arr1Index += 1;
1725
+ arr2Index += 1;
1726
+ continue; // eslint-disable-line no-continue
1727
+ }
1728
+
1729
+ if (typeof b === 'undefined') {
1730
+ arr2.push(null);
1731
+ arr1Index += 1;
1732
+ arr2Index += 1;
1733
+ continue; // eslint-disable-line no-continue
1734
+ }
1735
+
1736
+ const hashA = a.identityHash;
1737
+ const hashB = b.identityHash;
1738
+ if (hashA !== hashB) {
1739
+ let instancesA = 0;
1740
+ for (let i = arr1Index + 1; i < arr1.length; i += 1) {
1741
+ instancesA += arr1[i].identityHash === hashA ? 1 : 0;
1742
+ }
1743
+
1744
+ let instancesB = 0;
1745
+ for (let i = arr2Index + 1; i < arr2.length; i += 1) {
1746
+ instancesB += arr2[i].identityHash === hashA ? 1 : 0;
1747
+ }
1748
+
1749
+ if (instancesA >= instancesB) {
1750
+ arr2.splice(arr2Index, 0, null);
1751
+ } else if (instancesA < instancesB) {
1752
+ arr1.splice(arr1Index, 0, null);
1753
+ } // eslint-disable-line no-continue
1754
+ }
1755
+
1756
+ arr1Index += 1;
1757
+ arr2Index += 1;
1758
+ }
1759
+ }
1760
+
1761
+ function getRootEvents(eventArray) {
1762
+ let events = eventArray.filter((e) => e.isCall() && e.httpServerRequest);
1763
+ if (events.length === 0) {
1764
+ events = eventArray.filter((e) => e.isCall() && !e.parent);
1765
+ }
1766
+ return events;
1767
+ }
1768
+
1769
+ const CodeObjectType = {
1770
+ DATABASE: 'database',
1771
+ QUERY: 'query',
1772
+ HTTP: 'http',
1773
+ EXTERNAL_SERVICE: 'external-service',
1774
+ ROUTE: 'route',
1775
+ PACKAGE: 'package',
1776
+ CLASS: 'class',
1777
+ FUNCTION: 'function',
1778
+ };
1779
+
1780
+ class CodeObject {
1781
+ constructor(data, parent) {
1782
+ this.data = { ...data };
1783
+
1784
+ if (!(this.data.labels instanceof Set)) {
1785
+ this.data.labels = new Set(this.data.labels);
1786
+ }
1787
+
1788
+ this.children = [];
1789
+ if (parent) {
1790
+ parent.children.push(this);
1791
+ }
1792
+
1793
+ addHiddenProperty(this, 'parent', { value: parent });
1794
+ addHiddenProperty(this, 'events', { writable: false, value: [] });
1795
+ }
1796
+
1797
+ get id() {
1798
+ const tokens = this.buildId();
1799
+
1800
+ if (this.parent && this.type === CodeObjectType.FUNCTION) {
1801
+ const separator = this.static ? '.' : '#';
1802
+ tokens[tokens.length - 2] = separator;
1803
+ }
1804
+
1805
+ return tokens.join('');
1806
+ }
1807
+
1808
+ get name() {
1809
+ return this.data.name;
1810
+ }
1811
+
1812
+ get type() {
1813
+ return this.data.type;
1814
+ }
1815
+
1816
+ get static() {
1817
+ return this.data.static;
1818
+ }
1819
+
1820
+ get location() {
1821
+ return this.data.location;
1822
+ }
1823
+
1824
+ get labels() {
1825
+ return this.data.labels;
1826
+ }
1827
+
1828
+ get events() {
1829
+ return this.$hidden.events;
1830
+ }
1831
+
1832
+ get parent() {
1833
+ return this.$hidden.parent;
1834
+ }
1835
+
1836
+ set parent(val) {
1837
+ this.$hidden.parent = val;
1838
+ }
1839
+
1840
+ // Gets the source locations for this code object. For a package, no source locations are returned
1841
+ // (there would be too many to be useful). For a class, the paths to all files which add methods to the class are
1842
+ // returned. For a function, the path and line number is returned.
1843
+ get locations() {
1844
+ switch (this.type) {
1845
+ case CodeObjectType.CLASS:
1846
+ return Array.from(this.classLocations()).sort();
1847
+ case CodeObjectType.FUNCTION:
1848
+ return [this.location];
1849
+ default:
1850
+ return [];
1851
+ }
1852
+ }
1853
+
1854
+ get packageOf() {
1855
+ return [this, ...this.ancestors()]
1856
+ .filter((obj) => obj.type === CodeObjectType.PACKAGE)
1857
+ .map((obj) => obj.name)
1858
+ .reverse()
1859
+ .join('/');
1860
+ }
1861
+
1862
+ get classOf() {
1863
+ return [this, ...this.ancestors()]
1864
+ .filter((obj) => obj.type === CodeObjectType.CLASS)
1865
+ .map((obj) => obj.name)
1866
+ .reverse()
1867
+ .join('::');
1868
+ }
1869
+
1870
+ get classObject() {
1871
+ return [this, ...this.ancestors()].find(
1872
+ (obj) => obj.type === CodeObjectType.CLASS
1873
+ );
1874
+ }
1875
+
1876
+ get packageObject() {
1877
+ return [this, ...this.ancestors()].find(
1878
+ (obj) => obj.type === CodeObjectType.PACKAGE
1879
+ );
1880
+ }
1881
+
1882
+ get functions() {
1883
+ if (this.type === CodeObjectType.CLASS) {
1884
+ // getting the functions of a class should not return functions of nested classes
1885
+ return this.children.filter(
1886
+ (obj) => obj.type === CodeObjectType.FUNCTION
1887
+ );
1888
+ }
1889
+
1890
+ return this.descendants().filter(
1891
+ (obj) => obj.type === CodeObjectType.FUNCTION
1892
+ );
1893
+ }
1894
+
1895
+ get classes() {
1896
+ return [this, ...this.descendants()].filter(
1897
+ (obj) => obj.type === CodeObjectType.CLASS && obj.functions.length
1898
+ );
1899
+ }
1900
+
1901
+ get allEvents() {
1902
+ return [this, ...this.descendants()].map((obj) => obj.events).flat();
1903
+ }
1904
+
1905
+ descendants() {
1906
+ const queue = [...this.children];
1907
+ const children = [];
1908
+
1909
+ while (queue.length) {
1910
+ const child = queue.pop();
1911
+ children.push(child);
1912
+ queue.push(...child.children);
1913
+ }
1914
+
1915
+ return children;
1916
+ }
1917
+
1918
+ ancestors() {
1919
+ let currentObject = this.parent;
1920
+ const parents = [];
1921
+
1922
+ while (currentObject) {
1923
+ parents.push(currentObject);
1924
+ currentObject = currentObject.parent;
1925
+ }
1926
+
1927
+ return parents;
1928
+ }
1929
+
1930
+ // Leafs retrieves the leaf objects for the current type that contain children of another type. It
1931
+ // is useful for retrieving children without worrying about types or deeply nested objects.
1932
+ //
1933
+ // For example, the leafs of the package "com" may be:
1934
+ // - com.myorg.myapp
1935
+ // - com.myorg.myapp.api
1936
+ //
1937
+ // Whereas its children would only contain "myorg", and its descendants would include functions
1938
+ // and classes from any other nested package.
1939
+ leafs() {
1940
+ const { type } = this;
1941
+ const queue = [this];
1942
+ const leafArray = [];
1943
+
1944
+ while (queue.length) {
1945
+ const obj = queue.pop();
1946
+ const childrenOfType = obj.children.filter(
1947
+ (child) => child.type === type
1948
+ );
1949
+
1950
+ // If this object has children of another type, consider it a leaf.
1951
+ // For example, a package containing a class.
1952
+ if (childrenOfType.length) {
1953
+ queue.push(...childrenOfType);
1954
+ }
1955
+
1956
+ // If, however, this object has a variety of child types, it's both a leaf and a parent
1957
+ if (
1958
+ (!obj.children.length && obj.type === type) ||
1959
+ childrenOfType.length !== obj.children.length
1960
+ ) {
1961
+ leafArray.push(obj);
1962
+ }
1963
+ }
1964
+
1965
+ return leafArray;
1966
+ }
1967
+
1968
+ // Returns leafs of all children. Similar to the `classes` accessor, but returns children of any
1969
+ // type.
1970
+ childLeafs() {
1971
+ return this.children.map((child) => child.leafs()).flat();
1972
+ }
1973
+
1974
+ visit(fn, stack = []) {
1975
+ stack.push(this);
1976
+ fn(this, stack);
1977
+ this.children.forEach((child) => child.visit(fn, stack));
1978
+ stack.pop();
1979
+ }
1980
+
1981
+ buildId(tokens = []) {
1982
+ if (this.parent) {
1983
+ this.parent.buildId(tokens);
1984
+
1985
+ let separator;
1986
+ switch (this.parent.type) {
1987
+ case CodeObjectType.PACKAGE:
1988
+ separator = '/';
1989
+ break;
1990
+ case CodeObjectType.CLASS:
1991
+ separator = '::';
1992
+ break;
1993
+ default:
1994
+ separator = '->';
1995
+ }
1996
+ tokens.push(separator);
1997
+ }
1998
+ tokens.push(this.name);
1999
+ return tokens;
2000
+ }
2001
+
2002
+ classLocations(paths = new Set()) {
2003
+ this.children.forEach((child) => child.classLocations(paths));
2004
+
2005
+ if (this.type === CodeObjectType.FUNCTION) {
2006
+ const tokens = this.data.location.split(':', 2);
2007
+ paths.add(tokens[0]);
2008
+ }
2009
+ return paths;
2010
+ }
2011
+
2012
+ toJSON() {
2013
+ const obj = {
2014
+ name: this.data.name,
2015
+ type: this.data.type,
2016
+ };
2017
+
2018
+ if (this.data.type === CodeObjectType.FUNCTION) {
2019
+ obj.static = this.data.static;
2020
+ obj.location = this.data.location;
2021
+ }
2022
+ if (this.data.type === CodeObjectType.QUERY) {
2023
+ obj.database_type = this.data.database_type;
2024
+ }
2025
+
2026
+ if (this.children.length > 0) {
2027
+ obj.children = this.children;
2028
+ }
2029
+
2030
+ return obj;
2031
+ }
2032
+
2033
+ static constructDataChainFromEvent(event) {
2034
+ let elements;
2035
+ if (event.httpServerRequest) {
2036
+ elements = [
2037
+ {
2038
+ type: CodeObjectType.HTTP,
2039
+ name: 'HTTP server requests',
2040
+ },
2041
+ {
2042
+ type: CodeObjectType.ROUTE,
2043
+ name: event.route,
2044
+ },
2045
+ ];
2046
+ } else if (event.httpClientRequest) {
2047
+ let serviceName;
2048
+
2049
+ try {
2050
+ const url = new URL(event.httpClientRequest.url);
2051
+ serviceName = url.host;
2052
+ } catch {
2053
+ serviceName = 'External service';
2054
+ }
2055
+
2056
+ elements = [
2057
+ {
2058
+ type: CodeObjectType.EXTERNAL_SERVICE,
2059
+ name: serviceName,
2060
+ },
2061
+ ];
2062
+ } else if (event.sqlQuery) {
2063
+ elements = [
2064
+ {
2065
+ type: CodeObjectType.DATABASE,
2066
+ name: 'Database',
2067
+ },
2068
+ {
2069
+ type: CodeObjectType.QUERY,
2070
+ name: event.sqlQuery,
2071
+ database_type: event.sql.database_type,
2072
+ },
2073
+ ];
2074
+ } else {
2075
+ elements = [
2076
+ {
2077
+ type: CodeObjectType.CLASS,
2078
+ name: event.definedClass,
2079
+ },
2080
+ {
2081
+ type: CodeObjectType.FUNCTION,
2082
+ name: event.methodId,
2083
+ static: event.isStatic,
2084
+ location: '',
2085
+ },
2086
+ ];
2087
+ }
2088
+
2089
+ // Flag this object as having been created dynamically
2090
+ const queue = [...elements];
2091
+ while (queue.length) {
2092
+ const obj = queue.pop();
2093
+ obj.dynamic = true;
2094
+ if (obj.children) {
2095
+ obj.children.forEach((child) => queue.push(child));
2096
+ }
2097
+ }
2098
+
2099
+ return elements;
2100
+ }
2101
+
2102
+ get inboundConnections() {
2103
+ return this.allEvents
2104
+ .filter((e) => e.parent)
2105
+ .map((e) => e.parent.codeObject);
2106
+ }
2107
+
2108
+ get outboundConnections() {
2109
+ return this.allEvents
2110
+ .map((e) => e.children)
2111
+ .flat()
2112
+ .map((e) => e.codeObject);
2113
+ }
2114
+
2115
+ get sqlQueries() {
2116
+ return this.allEvents
2117
+ .map((e) => e.children)
2118
+ .flat()
2119
+ .filter((e) => e.sql)
2120
+ .map((e) => e.codeObject);
2121
+ }
2122
+
2123
+ get prettyName() {
2124
+ switch (this.type) {
2125
+ case CodeObjectType.FUNCTION:
2126
+ return `${this.classOf}${this.static ? '.' : '#'}${this.name}`;
2127
+ case CodeObjectType.CLASS:
2128
+ return this.classOf;
2129
+ case CodeObjectType.PACKAGE:
2130
+ return this.packageOf;
2131
+ case CodeObjectType.QUERY:
2132
+ return getSqlLabelFromString(this.name);
2133
+ default:
2134
+ return this.name;
2135
+ }
2136
+ }
2137
+
2138
+ get fqid() {
2139
+ return `${this.type}:${this.id}`;
2140
+ }
2141
+ }
2142
+
2143
+ function indexCodeObject(co, codeObjects, codeObjectsById) {
2144
+ codeObjects.push(co);
2145
+ codeObjectsById[co.id] = co;
2146
+ }
2147
+
2148
+ class ClassMap {
2149
+ constructor(classMap) {
2150
+ this.codeObjectsByLocation = {};
2151
+ this.codeObjects = [];
2152
+ this.codeObjectsById = {};
2153
+
2154
+ const buildCodeObject = (data, parent = null) => {
2155
+ const co = new CodeObject(data, parent);
2156
+ indexCodeObject(co, this.codeObjects, this.codeObjectsById);
2157
+
2158
+ (data.children || []).forEach((child) => {
2159
+ buildCodeObject(child, co);
2160
+ });
2161
+
2162
+ if (co.type !== 'package') {
2163
+ co.locations.forEach((location) => {
2164
+ let codeObjects = this.codeObjectsByLocation[location];
2165
+ if (!codeObjects) {
2166
+ codeObjects = [];
2167
+ this.codeObjectsByLocation[location] = codeObjects;
2168
+ }
2169
+ codeObjects.push(co);
2170
+ });
2171
+ }
2172
+
2173
+ return co;
2174
+ };
2175
+
2176
+ this.roots = classMap.map((root) => buildCodeObject(root));
2177
+ }
2178
+
2179
+ visit(fn) {
2180
+ this.roots.forEach((co) => co.visit(fn));
2181
+ }
2182
+
2183
+ search(query) {
2184
+ const queryLower = query.toLowerCase();
2185
+ return this.codeObjects.filter(
2186
+ (co) => co.id.toLowerCase().indexOf(queryLower) !== -1
2187
+ );
2188
+ }
2189
+
2190
+ codeObjectFromId(id) {
2191
+ return this.codeObjectsById[id];
2192
+ }
2193
+
2194
+ codeObjectsAtLocation(location) {
2195
+ return this.codeObjectsByLocation[location] || [];
2196
+ }
2197
+
2198
+ codeObjectFromEvent(event) {
2199
+ let codeObject;
2200
+ // These types of events should not be reporting path and lineno, but sometimes
2201
+ // they do.
2202
+ if (!(event.httpServerRequest || event.httpClientRequest || event.sql)) {
2203
+ const { path, lineno } = event;
2204
+ const location = [path, lineno].filter((e) => e).join(':');
2205
+ if (location !== '') {
2206
+ const codeObjects = this.codeObjectsAtLocation(location);
2207
+ codeObject = codeObjects.find((o) => o.name === event.methodId);
2208
+ if (codeObject) {
2209
+ return codeObject;
2210
+ }
2211
+ }
2212
+ }
2213
+
2214
+ return null;
2215
+ }
2216
+
2217
+ // Returns the first root code object of a given type or null if it doesn't exist
2218
+ root(type) {
2219
+ return this.roots.find((obj) => obj.type === type);
2220
+ }
2221
+
2222
+ // Returns the root HTTP code object if it exists
2223
+ get httpObject() {
2224
+ return this.root(CodeObjectType.HTTP);
2225
+ }
2226
+
2227
+ // Returns the root SQL code object if it exists
2228
+ get sqlObject() {
2229
+ return this.root(CodeObjectType.DATABASE);
2230
+ }
2231
+
2232
+ // Binds an event array to code objects and vice versa. This allows use of
2233
+ // direct accessors: `Event.codeObject` and `CodeObject.events`. Additionally,
2234
+ // it guarantees non-null accessors, meaning it will construct a code object
2235
+ // for an event if it previously did not exist.
2236
+ bindEvents(events) {
2237
+ if (!events || !Array.isArray(events) || !events.length) {
2238
+ return;
2239
+ }
2240
+
2241
+ const validCodeObjects = new Set();
2242
+ events
2243
+ .filter((e) => e.isCall())
2244
+ .forEach((e) => {
2245
+ let codeObject = this.codeObjectFromEvent(e);
2246
+ if (!codeObject) {
2247
+ const findOrCreateCodeObject = (data, codeObjectArray, parent) => {
2248
+ // TODO: This ignores static/non-static function collisions and function overloads, though this method
2249
+ // is never currently called in a context where those edge cases exist.
2250
+ let newCodeObject = codeObjectArray.find(
2251
+ (obj) => obj.type === data.type && obj.name === data.name
2252
+ );
2253
+
2254
+ if (!newCodeObject) {
2255
+ newCodeObject = new CodeObject(data, parent);
2256
+ if (!parent) {
2257
+ this.roots.push(newCodeObject);
2258
+ }
2259
+ indexCodeObject(
2260
+ newCodeObject,
2261
+ this.codeObjects,
2262
+ this.codeObjectsById
2263
+ );
2264
+ }
2265
+
2266
+ return newCodeObject;
2267
+ };
2268
+
2269
+ const dataElements = CodeObject.constructDataChainFromEvent(e);
2270
+ let parent = null;
2271
+ dataElements.forEach((dataElement) => {
2272
+ parent = findOrCreateCodeObject(
2273
+ dataElement,
2274
+ parent ? parent.children : this.roots,
2275
+ parent
2276
+ );
2277
+ });
2278
+ codeObject = parent;
2279
+ }
2280
+
2281
+ e.codeObject = codeObject;
2282
+ codeObject.events.push(e);
2283
+
2284
+ const ancestors = codeObject.ancestors();
2285
+ validCodeObjects.add(codeObject);
2286
+ ancestors.forEach((obj) => validCodeObjects.add(obj));
2287
+ });
2288
+
2289
+ this.codeObjects = this.codeObjects.filter((obj) =>
2290
+ validCodeObjects.has(obj)
2291
+ );
2292
+
2293
+ this.roots = this.roots.filter((obj) => validCodeObjects.has(obj));
2294
+
2295
+ Object.keys(this.codeObjectsByLocation).forEach((obj) => {
2296
+ if (!validCodeObjects.has(obj)) {
2297
+ delete this.codeObjectsByLocation[obj];
2298
+ }
2299
+ });
2300
+
2301
+ Object.entries(this.codeObjectsById).forEach(([id, obj]) => {
2302
+ if (!validCodeObjects.has(obj)) {
2303
+ delete this.codeObjectsById[id];
2304
+ }
2305
+ });
2306
+ }
2307
+
2308
+ toJSON() {
2309
+ // Don't write out code objects that were created during runtime
2310
+ return this.roots.filter((obj) => !obj.dynamic);
2311
+ }
2312
+ }
2313
+
2314
+ // Deprecated. Prefer `Event` instead.
2315
+ class CallNode {
2316
+ constructor(input = {}, output = {}, caller = null, labels = []) {
2317
+ this.input = input;
2318
+ this.output = output;
2319
+ this.children = [];
2320
+ this.labels = labels;
2321
+
2322
+ // Cyclic references shall not be enumerable
2323
+ addHiddenProperty(this, 'caller', { value: caller });
2324
+ }
2325
+
2326
+ get caller() {
2327
+ return this.$hidden.caller;
2328
+ }
2329
+
2330
+ set caller(value) {
2331
+ this.$hidden.$hiddencaller = value;
2332
+ }
2333
+
2334
+ clone() {
2335
+ const input = { ...this.input };
2336
+ const output = { ...this.output };
2337
+ const labels = [...this.labels];
2338
+ const newNode = new CallNode(input, output, null, labels);
2339
+
2340
+ if (this.displayName) {
2341
+ newNode.displayName = this.displayName;
2342
+ }
2343
+
2344
+ this.children.forEach((child) => {
2345
+ const newChild = child.clone();
2346
+ newNode.addChild(newChild);
2347
+ newChild.caller = newNode;
2348
+ });
2349
+
2350
+ return newNode;
2351
+ }
2352
+
2353
+ addChild(node) {
2354
+ this.children.push(node);
2355
+ }
2356
+
2357
+ // Replace a given child with a different set of children.
2358
+ replaceChild(child, children) {
2359
+ const idx = this.children.indexOf(child);
2360
+ if (idx === -1) {
2361
+ throw new Error(`${child} not found in call tree`);
2362
+ }
2363
+
2364
+ this.children.splice(idx, 1, ...children);
2365
+ /* eslint-disable no-param-reassign */
2366
+ children.forEach((c) => {
2367
+ c.caller = this;
2368
+ });
2369
+ child.caller = null;
2370
+ /* eslint-enable no-param-reassign */
2371
+ }
2372
+
2373
+ removeChild(child) {
2374
+ const childIndex = this.children.indexOf(child);
2375
+ if (childIndex < 0) {
2376
+ throw new Error(`${child} found orphaned by ${this} !`);
2377
+ }
2378
+ this.children.splice(childIndex, 1);
2379
+ }
2380
+
2381
+ postOrderForEach(fn, stack = []) {
2382
+ stack.push(this);
2383
+ const children = [...this.children];
2384
+ children.forEach((child) => child.postOrderForEach(fn, stack));
2385
+ fn(this, stack);
2386
+ stack.pop(this);
2387
+ }
2388
+
2389
+ preOrderForEach(fn, stack = []) {
2390
+ stack.push(this);
2391
+ fn(this, stack);
2392
+ const children = [...this.children];
2393
+ children.forEach((child) => child.preOrderForEach(fn, stack));
2394
+ stack.pop(this);
2395
+ }
2396
+
2397
+ forEach(fn) {
2398
+ this.postOrderForEach(fn);
2399
+ }
2400
+
2401
+ // filter returns a tree in which all nodes match a condition. If a node fails the
2402
+ // condition, its children are adopted by it's parent.
2403
+ filter(conditionFn) {
2404
+ const root = this.clone();
2405
+ root.forEach((node, stack) => {
2406
+ if (node.isRoot()) {
2407
+ return;
2408
+ }
2409
+
2410
+ if (!conditionFn(node, stack)) {
2411
+ const parent = node.caller;
2412
+ parent.replaceChild(node, node.children);
2413
+ }
2414
+ });
2415
+
2416
+ return root;
2417
+ }
2418
+
2419
+ // include returns a tree in which all leaf nodes match a condition.
2420
+ // If a node passes the condition, the node and all of its parents are retained
2421
+ // in the tree. If it fails, the node and its children are removed from the tree.
2422
+ // Note that if a node passes the condition, the condition will not be evaluated
2423
+ // for that node's parent nodes, since they are already marked as retained.
2424
+ include(conditionFn) {
2425
+ /* eslint-disable no-param-reassign */
2426
+ const root = this.clone();
2427
+ root.postOrderForEach((node, stack) => {
2428
+ if (node.isRoot()) {
2429
+ return;
2430
+ }
2431
+
2432
+ if (node.marked_include && node.caller) {
2433
+ node.caller.marked_include = true;
2434
+ return;
2435
+ }
2436
+
2437
+ node.marked_include = conditionFn(node, stack);
2438
+ if (node.marked_include) {
2439
+ if (node.caller) {
2440
+ node.caller.marked_include = true;
2441
+ }
2442
+ return;
2443
+ }
2444
+
2445
+ if (node.caller) {
2446
+ node.caller.removeChild(node);
2447
+ }
2448
+ });
2449
+
2450
+ root.postOrderForEach((node) => {
2451
+ delete node.marked_include;
2452
+ });
2453
+
2454
+ return root;
2455
+ /* eslint-enable no-param-reassign */
2456
+ }
2457
+
2458
+ // exclude returns a tree in which all nodes that match a condition are removed, along
2459
+ // with their child nodes.
2460
+ exclude(conditionFn) {
2461
+ const root = this.clone();
2462
+ root.forEach((node, stack) => {
2463
+ if (node.isRoot()) {
2464
+ return;
2465
+ }
2466
+
2467
+ if (conditionFn(node, stack)) {
2468
+ const parent = node.caller;
2469
+ parent.removeChild(node);
2470
+ }
2471
+ });
2472
+
2473
+ return root;
2474
+ }
2475
+
2476
+ // toArray returns this tree as a one dimensional array
2477
+ toArray() {
2478
+ const childEvents = this.children.map((child) => child.toArray()).flat();
2479
+
2480
+ if (this.isRoot()) {
2481
+ return childEvents;
2482
+ }
2483
+
2484
+ return [this, ...childEvents];
2485
+ }
2486
+
2487
+ // find calls find recursively on all children
2488
+ // iterates in pre-order
2489
+ find(fn) {
2490
+ if (fn(this)) {
2491
+ return this;
2492
+ }
2493
+
2494
+ for (let i = 0; i < this.children.length; i += 1) {
2495
+ const match = this.children[i].find(fn);
2496
+ if (match) {
2497
+ return match;
2498
+ }
2499
+ }
2500
+
2501
+ return null;
2502
+ }
2503
+
2504
+ // depth returns the depth of this node
2505
+ depth() {
2506
+ return this.ancestors().length;
2507
+ }
2508
+
2509
+ // ancestors returns an array of this nodes ancestors
2510
+ ancestors() {
2511
+ const nodes = [];
2512
+
2513
+ let parent = this.caller;
2514
+ while (parent) {
2515
+ nodes.push(parent);
2516
+ parent = parent.caller;
2517
+ }
2518
+
2519
+ return nodes;
2520
+ }
2521
+
2522
+ // returns whether or not a node has a particular node in its ancestry
2523
+ hasAncestor(ancestor) {
2524
+ let node = this;
2525
+ while (node) {
2526
+ if (node === ancestor) {
2527
+ return true;
2528
+ }
2529
+ node = node.caller;
2530
+ }
2531
+ return false;
2532
+ }
2533
+
2534
+ descendants() {
2535
+ return [this, ...this.children.map((x) => x.descendants()).flat()];
2536
+ }
2537
+
2538
+ next() {
2539
+ if (this.children.length > 0) {
2540
+ return this.children[0];
2541
+ }
2542
+
2543
+ let child = this;
2544
+ let parent = this.caller;
2545
+ const fnChildIndex = (n) => n === child;
2546
+ while (parent) {
2547
+ const myIndex = parent.children.findIndex(fnChildIndex);
2548
+ if (myIndex < 0) {
2549
+ throw new Error(`${this} found orphaned by ${parent}!`);
2550
+ }
2551
+
2552
+ if (myIndex < parent.children.length - 1) {
2553
+ return parent.children[myIndex + 1];
2554
+ }
2555
+
2556
+ child = parent;
2557
+ parent = parent.caller;
2558
+ }
2559
+
2560
+ return null;
2561
+ }
2562
+
2563
+ previous() {
2564
+ const parent = this.caller;
2565
+ if (!parent) {
2566
+ return null;
2567
+ }
2568
+
2569
+ if (parent.children.length === 1) {
2570
+ return parent;
2571
+ }
2572
+
2573
+ const myIndex = parent.children.findIndex((n) => n === this);
2574
+ if (myIndex < 0) {
2575
+ throw new Error(`${this.input.id} found orphaned by ${parent.input.id}!`);
2576
+ }
2577
+
2578
+ if (myIndex > 0) {
2579
+ // this branch will yield our previous node
2580
+ let candidate = parent.children[myIndex - 1];
2581
+
2582
+ // iterate until we find a leaf node
2583
+ while (candidate.children.length > 0) {
2584
+ candidate = candidate.children[candidate.children.length - 1];
2585
+ }
2586
+
2587
+ return candidate;
2588
+ }
2589
+
2590
+ return parent;
2591
+ }
2592
+
2593
+ // return the node to the left, at given max depth
2594
+ left(depth) {
2595
+ const target = depth || this.depth();
2596
+
2597
+ // find the target or the nearest descendant
2598
+ let current = this;
2599
+ for (;;) {
2600
+ const parent = current.caller;
2601
+ if (!parent) return this;
2602
+
2603
+ const siblings = parent.children;
2604
+ const i = siblings.indexOf(current);
2605
+ if (i !== 0) {
2606
+ current = parent.children[i - 1];
2607
+ break;
2608
+ } else {
2609
+ current = parent;
2610
+ }
2611
+ }
2612
+
2613
+ // find rightmost child closest to the right depth
2614
+ while (current.depth() !== target) {
2615
+ const { children } = current;
2616
+ if (children.length === 0) break;
2617
+ current = children[children.length - 1];
2618
+ }
2619
+
2620
+ return current;
2621
+ }
2622
+
2623
+ // return the node to the right, at given max depth
2624
+ right(depth) {
2625
+ const target = depth || this.depth();
2626
+
2627
+ // find the target or the nearest descendant
2628
+ let current = this;
2629
+ for (;;) {
2630
+ const parent = current.caller;
2631
+ if (!parent) return this;
2632
+
2633
+ const siblings = parent.children;
2634
+ const i = siblings.indexOf(current);
2635
+ if (i !== siblings.length - 1) {
2636
+ current = parent.children[i + 1];
2637
+ break;
2638
+ } else {
2639
+ current = parent;
2640
+ }
2641
+ }
2642
+
2643
+ // find leftmost child closest to the right depth
2644
+ while (current.depth() !== target) {
2645
+ const { children } = current;
2646
+ if (children.length === 0) break;
2647
+ [current] = children;
2648
+ }
2649
+
2650
+ return current;
2651
+ }
2652
+
2653
+ isRoot() {
2654
+ return this.caller === null;
2655
+ }
2656
+
2657
+ count() {
2658
+ let numNodes = 0;
2659
+ this.forEach(() => {
2660
+ numNodes += 1;
2661
+ });
2662
+ return numNodes;
2663
+ }
2664
+
2665
+ get id() {
2666
+ if (this.input && this.input.id) {
2667
+ return this.input.id;
2668
+ }
2669
+ return null;
2670
+ }
2671
+ }
2672
+
2673
+ function getListenerArray(eventSource, eventType) {
2674
+ /* eslint-disable no-param-reassign */
2675
+ let listeners = eventSource.listeners[eventType];
2676
+ if (!listeners) {
2677
+ listeners = [];
2678
+ eventSource.listeners[eventType] = listeners;
2679
+ }
2680
+ return listeners;
2681
+ /* eslint-enable no-param-reassign */
2682
+ }
2683
+
2684
+ class EventSource {
2685
+ constructor() {
2686
+ this.listeners = {};
2687
+ this.anyListeners = [];
2688
+ }
2689
+
2690
+ once(eventType, fn) {
2691
+ const handlers = getListenerArray(this, eventType);
2692
+ handlers.push({ fn, once: true });
2693
+ return this;
2694
+ }
2695
+
2696
+ on(eventType, fn) {
2697
+ const handlers = getListenerArray(this, eventType);
2698
+ handlers.push({ fn });
2699
+ return this;
2700
+ }
2701
+
2702
+ off(eventType, fn) {
2703
+ const handlers = this.listeners[eventType];
2704
+
2705
+ if (handlers) {
2706
+ const updatedHandlers = handlers.filter((h) => h.fn && h.fn !== fn);
2707
+ if (updatedHandlers.length === 0) {
2708
+ delete this.listeners[eventType];
2709
+ } else if (updatedHandlers.length !== handlers.length) {
2710
+ this.listeners[eventType] = updatedHandlers;
2711
+ }
2712
+ }
2713
+
2714
+ return this;
2715
+ }
2716
+
2717
+ emit(eventType, data = undefined) {
2718
+ const handlers = this.listeners[eventType];
2719
+
2720
+ if (handlers) {
2721
+ let includesOnce = false;
2722
+ handlers.forEach((handler) => {
2723
+ if (handler.once) {
2724
+ includesOnce = true;
2725
+ }
2726
+
2727
+ try {
2728
+ handler.fn(data);
2729
+ } catch (e) {
2730
+ console.error(`error occurred while executing event ${eventType}`);
2731
+ console.error(e);
2732
+ }
2733
+ });
2734
+
2735
+ if (includesOnce) {
2736
+ // Only reassign this value if we've encountered a handler that's run once
2737
+ this.listeners[eventType] = this.listeners[eventType].filter(
2738
+ (h) => !h.once
2739
+ );
2740
+ }
2741
+ }
2742
+
2743
+ this.anyListeners.forEach((eventSource) =>
2744
+ eventSource.emit(eventType, data)
2745
+ );
2746
+
2747
+ return this;
2748
+ }
2749
+
2750
+ // Pipe events from EventSource A to EventSource B. If `eventTypes` are
2751
+ // provided, bind only those types. Otherwise, pipe any event.
2752
+ pipe(eventSource, ...eventTypes) {
2753
+ if (eventTypes.length) {
2754
+ eventTypes.forEach((type) =>
2755
+ eventSource.on(type, (data) => this.emit(data))
2756
+ );
2757
+ return this;
2758
+ }
2759
+
2760
+ eventSource.any(this);
2761
+ return this;
2762
+ }
2763
+
2764
+ // Bind `eventSource` to recieve any event sent from `this`.
2765
+ any(eventSource) {
2766
+ this.anyListeners.push(eventSource);
2767
+ return this;
2768
+ }
2769
+ }
2770
+
2771
+ class CallTree extends EventSource {
2772
+ constructor(events, functionLabels = () => []) {
2773
+ super();
2774
+
2775
+ this.dataStore = {
2776
+ rootEvent: this.rootNode,
2777
+ selectedEvent: this.rootNode,
2778
+ };
2779
+
2780
+ this.rootEvent = new CallNode();
2781
+ const stack = [this.rootEvent];
2782
+ events.forEach((e) => {
2783
+ if (e.event !== 'call') {
2784
+ if (stack.length > 1) {
2785
+ stack.pop();
2786
+ }
2787
+ return;
2788
+ }
2789
+
2790
+ const parent = stack[stack.length - 1];
2791
+ const callNode = new CallNode(
2792
+ e,
2793
+ e.returnEvent,
2794
+ parent,
2795
+ functionLabels(e)
2796
+ );
2797
+ parent.addChild(callNode);
2798
+ stack.push(callNode);
2799
+ });
2800
+
2801
+ return this;
2802
+ }
2803
+
2804
+ get rootEvent() {
2805
+ return this.dataStore.rootEvent;
2806
+ }
2807
+
2808
+ set rootEvent(event) {
2809
+ this.dataStore.rootEvent = event;
2810
+ this.emit('rootEvent', event);
2811
+ }
2812
+
2813
+ get selectedEvent() {
2814
+ return this.dataStore.selectedEvent;
2815
+ }
2816
+
2817
+ set selectedEvent(event) {
2818
+ this.dataStore.selectedEvent = event;
2819
+ this.emit('selectedEvent', event);
2820
+ }
2821
+ }
2822
+
2823
+ // merge contiguous changes into a single element (as an array)
2824
+ function groupChanges(eventArray) {
2825
+ const events = new Set(eventArray);
2826
+ const seen = new Set();
2827
+ const result = [];
2828
+
2829
+ eventArray.forEach((e) => {
2830
+ if (seen.has(e)) {
2831
+ return;
2832
+ }
2833
+
2834
+ seen.add(e);
2835
+
2836
+ const group = [e];
2837
+ let currentEvent = e;
2838
+ for (;;) {
2839
+ const { nextSibling } = currentEvent;
2840
+ if (nextSibling && events.has(nextSibling)) {
2841
+ group.push(nextSibling);
2842
+ seen.add(nextSibling);
2843
+ currentEvent = nextSibling;
2844
+ } else {
2845
+ break;
2846
+ }
2847
+ }
2848
+
2849
+ result.push(group);
2850
+ });
2851
+
2852
+ return result;
2853
+ }
2854
+
2855
+ class AppMap {
2856
+ constructor(data) {
2857
+ this.data = {
2858
+ events: [],
2859
+ classMap: [],
2860
+ ...data,
2861
+ };
2862
+
2863
+ this.classMap = new ClassMap(this.data.classMap);
2864
+ this.callTree = new CallTree(this.events);
2865
+ this.classMap.bindEvents(this.events);
2866
+ this.labels = buildLabels(this.classMap, this.events);
2867
+
2868
+ // Establish event linked list references
2869
+ let previousEvent;
2870
+ this.events.forEach((e) => {
2871
+ if (previousEvent) {
2872
+ e.previous = previousEvent;
2873
+ previousEvent.next = e;
2874
+ }
2875
+
2876
+ previousEvent = e;
2877
+ });
2878
+
2879
+ // Keep these fields seperate for serialization
2880
+ delete this.data.classMap;
2881
+ }
2882
+
2883
+ get version() {
2884
+ return this.data.version;
2885
+ }
2886
+
2887
+ get metadata() {
2888
+ return this.data.metadata || {};
2889
+ }
2890
+
2891
+ get name() {
2892
+ return this.metadata.name;
2893
+ }
2894
+
2895
+ get rootEvent() {
2896
+ return this.callTree.rootEvent;
2897
+ }
2898
+
2899
+ get events() {
2900
+ return this.data.events;
2901
+ }
2902
+
2903
+ shallowCopy() {
2904
+ const copy = new AppMap({});
2905
+ copy.data.events = this.data.events;
2906
+ copy.data.metadata = this.data.metadata;
2907
+ copy.classMap = this.classMap;
2908
+ copy.callTree = this.callTree;
2909
+ return copy;
2910
+ }
2911
+
2912
+ // Retrieve an array of root entry point events (currently, just HTTP server requests). If none
2913
+ // are found, return all the root nodes which have no caller.
2914
+ rootEvents() {
2915
+ return getRootEvents(this.events);
2916
+ }
2917
+
2918
+ // Iterate many AppMaps at once as an event tree. This method will follow the deepest branch
2919
+ // available, and yield the nodes at that position. Given that the tree structure may differ
2920
+ // across AppMaps, it's possible that some nodes will be null.
2921
+ static *multiTreeIterator(baseAppMap, workingAppMap) {
2922
+ let baseEvent;
2923
+ let workingEvent;
2924
+ const baseQueue = baseAppMap.rootEvents();
2925
+ const workingQueue = workingAppMap.rootEvents();
2926
+
2927
+ resolveDifferences(baseQueue, workingQueue);
2928
+
2929
+ for (;;) {
2930
+ baseEvent = baseQueue.shift();
2931
+ workingEvent = workingQueue.shift();
2932
+
2933
+ // If both are null, every path has been exhausted. We're done.
2934
+ if (!baseEvent && !workingEvent) {
2935
+ return;
2936
+ }
2937
+
2938
+ // Don't bother continuing to iterate through a branch that doesn't exist in the other tree.
2939
+ if (baseEvent && workingEvent) {
2940
+ const baseChildren = baseEvent ? [...baseEvent.children] : [];
2941
+ const workingChildren = workingEvent ? [...workingEvent.children] : [];
2942
+
2943
+ resolveDifferences(baseChildren, workingChildren);
2944
+ baseChildren.forEach((e) => baseQueue.push(e));
2945
+ workingChildren.forEach((e) => workingQueue.push(e));
2946
+ }
2947
+
2948
+ yield [baseEvent, workingEvent];
2949
+ }
2950
+ }
2951
+
2952
+ static getDiff(baseAppMap, workingAppMap) {
2953
+ const changeSummary = {
2954
+ changed: [],
2955
+ added: [],
2956
+ removed: [],
2957
+ };
2958
+
2959
+ const iter = AppMap.multiTreeIterator(baseAppMap, workingAppMap);
2960
+ let result = iter.next();
2961
+ while (!result.done) {
2962
+ const [nodeBase, nodeWorking] = result.value;
2963
+
2964
+ if (!nodeBase) {
2965
+ changeSummary.added.push(nodeWorking);
2966
+ } else if (!nodeWorking) {
2967
+ changeSummary.removed.push(nodeBase);
2968
+ } else if (nodeBase.hash !== nodeWorking.hash) {
2969
+ changeSummary.changed.push([nodeBase, nodeWorking]);
2970
+ }
2971
+
2972
+ result = iter.next();
2973
+ }
2974
+
2975
+ changeSummary.added = groupChanges(changeSummary.added);
2976
+ changeSummary.removed = groupChanges(changeSummary.removed);
2977
+
2978
+ return changeSummary;
2979
+ }
2980
+
2981
+ toJSON() {
2982
+ return {
2983
+ ...this.data,
2984
+ classMap: this.classMap,
2985
+ };
2986
+ }
2987
+ }
2988
+
2989
+ // This class supercedes `CallTree` and `CallNode`. Events are stored in a flat
2990
+ // array and can also be traversed like a tree via `parent` and `children`.
2991
+ class Event {
2992
+ constructor(obj) {
2993
+ let data = obj;
2994
+
2995
+ if (obj instanceof Event) {
2996
+ data = { ...obj };
2997
+
2998
+ if (obj.$hidden.parameters) {
2999
+ data.parameters = obj.$hidden.parameters.map((p) => ({ ...p }));
3000
+ }
3001
+
3002
+ if (Array.isArray(obj.$hidden.message)) {
3003
+ data.message = obj.$hidden.message.map((m) => ({ ...m }));
3004
+ }
3005
+
3006
+ if (obj.$hidden.labels) {
3007
+ data.labels = [...obj.$hidden.labels];
3008
+ }
3009
+ }
3010
+
3011
+ // Cyclic references shall not be enumerable
3012
+ if (data.event === 'call') {
3013
+ addHiddenProperty(this, 'parent');
3014
+ addHiddenProperty(this, 'children', { writable: false, value: [] });
3015
+ addHiddenProperty(this, 'dataReferences', { writable: false, value: [] });
3016
+ addHiddenProperty(this, 'codeObject');
3017
+ addHiddenProperty(this, 'parameters');
3018
+ addHiddenProperty(this, 'message');
3019
+ }
3020
+
3021
+ addHiddenProperty(this, 'linkedEvent');
3022
+ addHiddenProperty(this, 'labels');
3023
+ addHiddenProperty(this, 'next');
3024
+ addHiddenProperty(this, 'previous');
3025
+ addHiddenProperty(this, 'hash');
3026
+ addHiddenProperty(this, 'identityHash');
3027
+ addHiddenProperty(this, 'depth');
3028
+
3029
+ // Data must be written last, after our properties are configured.
3030
+ Object.assign(this, data);
3031
+ }
3032
+
3033
+ get depth() {
3034
+ if (this.$hidden.depth === undefined) {
3035
+ let result = 0;
3036
+ let { parent } = this;
3037
+ while (parent) {
3038
+ result += 1;
3039
+ parent = parent.parent;
3040
+ }
3041
+ this.$hidden.depth = result;
3042
+ }
3043
+ return this.$hidden.depth;
3044
+ }
3045
+
3046
+ get methodId() {
3047
+ return this.method_id;
3048
+ }
3049
+
3050
+ get isFunction() {
3051
+ return this.definedClass && this.methodId;
3052
+ }
3053
+
3054
+ get isStatic() {
3055
+ return this.static;
3056
+ }
3057
+
3058
+ get sql() {
3059
+ return this.callEvent.sql_query;
3060
+ }
3061
+
3062
+ get returnValue() {
3063
+ return this.returnEvent.return_value;
3064
+ }
3065
+
3066
+ get linkedEvent() {
3067
+ return this.$hidden.linkedEvent;
3068
+ }
3069
+
3070
+ get next() {
3071
+ return this.$hidden.next;
3072
+ }
3073
+
3074
+ get previous() {
3075
+ return this.$hidden.previous;
3076
+ }
3077
+
3078
+ get parent() {
3079
+ return this.$hidden.parent;
3080
+ }
3081
+
3082
+ get children() {
3083
+ return this.$hidden.children || [];
3084
+ }
3085
+
3086
+ get codeObject() {
3087
+ return this.callEvent.$hidden.codeObject;
3088
+ }
3089
+
3090
+ get parameters() {
3091
+ return this.callEvent.$hidden.parameters;
3092
+ }
3093
+
3094
+ get labels() {
3095
+ const eventLabels = this.callEvent.$hidden.labels || [];
3096
+ return new Set([...eventLabels, ...this.callEvent.codeObject.labels]);
3097
+ }
3098
+
3099
+ get message() {
3100
+ return this.callEvent.$hidden.message;
3101
+ }
3102
+
3103
+ get httpServerRequest() {
3104
+ return this.callEvent.http_server_request;
3105
+ }
3106
+
3107
+ get httpServerResponse() {
3108
+ return this.returnEvent.http_server_response;
3109
+ }
3110
+
3111
+ get httpClientRequest() {
3112
+ return this.callEvent.http_client_request;
3113
+ }
3114
+
3115
+ get httpClientResponse() {
3116
+ return this.returnEvent.http_client_response;
3117
+ }
3118
+
3119
+ get definedClass() {
3120
+ return this.defined_class ? this.defined_class.replace(/\./g, '/') : null;
3121
+ }
3122
+
3123
+ get requestPath() {
3124
+ if (this.httpServerRequest) {
3125
+ return (
3126
+ this.httpServerRequest.normalized_path_info ||
3127
+ this.httpServerRequest.path_info
3128
+ );
3129
+ }
3130
+ if (this.httpClientRequest) {
3131
+ return this.httpClientRequest.url;
3132
+ }
3133
+ return null;
3134
+ }
3135
+
3136
+ get requestMethod() {
3137
+ if (this.httpServerRequest) {
3138
+ return this.httpServerRequest.request_method;
3139
+ }
3140
+ if (this.httpClientRequest) {
3141
+ return this.httpClientRequest.request_method;
3142
+ }
3143
+ return null;
3144
+ }
3145
+
3146
+ get route() {
3147
+ const { requestMethod, requestPath } = this;
3148
+ if (!requestMethod || !requestPath) {
3149
+ return null;
3150
+ }
3151
+
3152
+ return `${requestMethod} ${requestPath}`;
3153
+ }
3154
+
3155
+ get sqlQuery() {
3156
+ const { sql } = this;
3157
+ if (!sql) {
3158
+ return null;
3159
+ }
3160
+ return sql.normalized_sql || sql.sql;
3161
+ }
3162
+
3163
+ get fqid() {
3164
+ return `event:${this.id}`;
3165
+ }
3166
+
3167
+ get previousSibling() {
3168
+ const { parent } = this;
3169
+ if (!parent) {
3170
+ return null;
3171
+ }
3172
+
3173
+ const myIndex = parent.children.findIndex((e) => e === this);
3174
+ console.assert(
3175
+ myIndex !== -1,
3176
+ 'attempted to locate index of an orphaned event'
3177
+ );
3178
+
3179
+ if (myIndex === 0) {
3180
+ return null;
3181
+ }
3182
+
3183
+ return parent.children[myIndex - 1];
3184
+ }
3185
+
3186
+ get nextSibling() {
3187
+ const { parent } = this;
3188
+
3189
+ if (!parent) {
3190
+ let event = this.next;
3191
+
3192
+ // Get the next root level event
3193
+ while (event) {
3194
+ if (event.isCall() && !event.parent) {
3195
+ return event;
3196
+ }
3197
+
3198
+ event = event.next;
3199
+ }
3200
+
3201
+ return null;
3202
+ }
3203
+
3204
+ const myIndex = this.parent.children.findIndex((e) => e === this);
3205
+ console.assert(
3206
+ myIndex !== -1,
3207
+ 'attempted to locate index of an orphaned event'
3208
+ );
3209
+
3210
+ if (myIndex === parent.children.length - 1) {
3211
+ return null;
3212
+ }
3213
+
3214
+ return parent.children[myIndex + 1];
3215
+ }
3216
+
3217
+ set codeObject(value) {
3218
+ if (hasProp(this.$hidden, 'codeObject')) {
3219
+ this.$hidden.codeObject = value;
3220
+ }
3221
+ }
3222
+
3223
+ set parameters(value) {
3224
+ if (hasProp(this.$hidden, 'parameters')) {
3225
+ this.$hidden.parameters = value;
3226
+ }
3227
+ }
3228
+
3229
+ set labels(value) {
3230
+ if (hasProp(this.$hidden, 'labels')) {
3231
+ this.$hidden.labels = value;
3232
+ }
3233
+ }
3234
+
3235
+ set message(value) {
3236
+ if (hasProp(this.$hidden, 'message')) {
3237
+ this.$hidden.message = value;
3238
+ }
3239
+ }
3240
+
3241
+ set linkedEvent(value) {
3242
+ this.$hidden.linkedEvent = value;
3243
+ }
3244
+
3245
+ set next(value) {
3246
+ this.$hidden.next = value;
3247
+ }
3248
+
3249
+ set previous(value) {
3250
+ this.$hidden.previous = value;
3251
+ }
3252
+
3253
+ set parent(value) {
3254
+ this.$hidden.parent = value;
3255
+ }
3256
+
3257
+ link(event) {
3258
+ /* eslint-disable no-param-reassign */
3259
+ if (event.linkedEvent || this.linkedEvent) {
3260
+ return;
3261
+ }
3262
+
3263
+ event.linkedEvent = this;
3264
+ this.linkedEvent = event;
3265
+ /* eslint-enable no-param-reassign */
3266
+ }
3267
+
3268
+ isCall() {
3269
+ return this.event === 'call';
3270
+ }
3271
+
3272
+ isReturn() {
3273
+ return this.event === 'return';
3274
+ }
3275
+
3276
+ get callEvent() {
3277
+ return this.isCall() ? this : this.$hidden.linkedEvent;
3278
+ }
3279
+
3280
+ get returnEvent() {
3281
+ return this.isReturn() ? this : this.$hidden.linkedEvent;
3282
+ }
3283
+
3284
+ get hash() {
3285
+ if (!this.$hidden.hash) {
3286
+ this.$hidden.hash = hashEvent(this);
3287
+ }
3288
+ return this.$hidden.hash;
3289
+ }
3290
+
3291
+ get identityHash() {
3292
+ if (!this.$hidden.identityHash) {
3293
+ this.$hidden.identityHash = identityHashEvent(this);
3294
+ }
3295
+ return this.$hidden.identityHash;
3296
+ }
3297
+
3298
+ callStack() {
3299
+ const stack = this.ancestors().reverse();
3300
+ stack.push(this.callEvent);
3301
+ return stack;
3302
+ }
3303
+
3304
+ ancestors() {
3305
+ const ancestorArray = [];
3306
+ let event = this.callEvent.parent;
3307
+
3308
+ while (event) {
3309
+ ancestorArray.push(event);
3310
+ event = event.parent;
3311
+ }
3312
+
3313
+ return ancestorArray;
3314
+ }
3315
+
3316
+ descendants() {
3317
+ const descendantArray = [];
3318
+ const queue = [...this.children];
3319
+
3320
+ while (queue.length) {
3321
+ const event = queue.pop();
3322
+ event.children.forEach((child) => queue.push(child));
3323
+ descendantArray.push(event);
3324
+ }
3325
+
3326
+ return descendantArray;
3327
+ }
3328
+
3329
+ traverse(fn) {
3330
+ let event = this;
3331
+ const boundaryEvent = this.nextSibling;
3332
+ let { onEnter } = fn;
3333
+ let { onExit } = fn;
3334
+
3335
+ if (typeof fn === 'function') {
3336
+ onEnter = fn;
3337
+ onExit = fn;
3338
+ }
3339
+
3340
+ while (event) {
3341
+ if (event.isCall() && onEnter) {
3342
+ onEnter(event);
3343
+ } else if (event.isReturn() && onExit) {
3344
+ onExit(event);
3345
+ }
3346
+
3347
+ event = event.next;
3348
+ if (!event || event === boundaryEvent) {
3349
+ break;
3350
+ }
3351
+ }
3352
+ }
3353
+
3354
+ dataObjects() {
3355
+ return [this.parameters, this.message, this.returnValue]
3356
+ .flat()
3357
+ .filter(Boolean);
3358
+ }
3359
+
3360
+ toString() {
3361
+ const { sqlQuery } = this;
3362
+ if (sqlQuery) {
3363
+ return sqlQuery;
3364
+ }
3365
+
3366
+ const { route } = this;
3367
+ if (route) {
3368
+ return route;
3369
+ }
3370
+
3371
+ const { definedClass, isStatic, methodId } = this;
3372
+ return `${definedClass}${isStatic ? '.' : '#'}${methodId}`;
3373
+ }
3374
+ }
3375
+
3376
+ class EventStack {
3377
+ constructor(id) {
3378
+ this.events = [];
3379
+ this.stack = [];
3380
+ this.id = id;
3381
+ this.eventMap = {};
3382
+ }
3383
+
3384
+ add(event) {
3385
+ // Don't begin a stack with a return, we likely started recording in the
3386
+ // middle of thread execution.
3387
+ if (event.isReturn() && this.events.length === 0) {
3388
+ return;
3389
+ }
3390
+
3391
+ if (event.isCall()) {
3392
+ this.stack.push(event);
3393
+ this.eventMap[event.id] = event;
3394
+ } else {
3395
+ if (typeof event.parent_id === 'undefined') {
3396
+ const lastEvent = this.stack[this.stack.length - 1];
3397
+ if (
3398
+ lastEvent &&
3399
+ lastEvent.defined_class === event.defined_class &&
3400
+ lastEvent.method_id === event.method_id &&
3401
+ lastEvent.path === event.path &&
3402
+ lastEvent.static === event.static
3403
+ ) {
3404
+ event.parent_id = lastEvent.id; // eslint-disable-line no-param-reassign
3405
+ } else {
3406
+ // An event has returned but the last call in the stack was not its
3407
+ // caller. There's not really anything we can do to rectify this, so
3408
+ // the event will be discarded.
3409
+ return;
3410
+ }
3411
+ }
3412
+
3413
+ const call = this.eventMap[event.parent_id];
3414
+ if (call) {
3415
+ call.link(event);
3416
+ this.stack.pop();
3417
+
3418
+ const parent = this.stack[this.stack.length - 1];
3419
+ if (parent) {
3420
+ parent.children.push(call);
3421
+ call.parent = parent;
3422
+ }
3423
+ } else {
3424
+ throw new Error(
3425
+ `return #${event.id} is missing call #${event.parent_id}`
3426
+ );
3427
+ }
3428
+ }
3429
+
3430
+ this.events.push(event);
3431
+ }
3432
+
3433
+ unwound() {
3434
+ return this.events.length > 0 && this.stack.length === 0;
3435
+ }
3436
+ }
3437
+
3438
+ function getStackId(collection) {
3439
+ return (
3440
+ Object.keys(collection.activeStacks).length +
3441
+ collection.finalizedStacks.length
3442
+ );
3443
+ }
3444
+
3445
+ // EventSorter is responsible for untangling an event array. It sorts events by
3446
+ // thread execution order and drops leading return statements.
3447
+ class EventSorter {
3448
+ constructor() {
3449
+ this.activeStacks = {};
3450
+ this.finalizedStacks = [];
3451
+ }
3452
+
3453
+ // Add an event to be sorted. An event must be added through this method to
3454
+ // be collected.
3455
+ add(event) {
3456
+ let stack = this.activeStacks[event.thread_id];
3457
+ if (!stack) {
3458
+ const id = getStackId(this);
3459
+ stack = new EventStack(id);
3460
+ this.activeStacks[event.thread_id] = stack;
3461
+ }
3462
+
3463
+ stack.add(event);
3464
+
3465
+ if (stack.unwound()) {
3466
+ this.finalizedStacks.splice(stack.id, 0, stack.events);
3467
+ delete this.activeStacks[event.thread_id];
3468
+ }
3469
+ }
3470
+
3471
+ // Calculate the serialized size of all events. This is more of an
3472
+ // approximation than an exact number.
3473
+ size() {
3474
+ let size = sizeof(Object.values(this.activeStacks));
3475
+ size += sizeof(this.finalizedStacks);
3476
+ return size;
3477
+ }
3478
+
3479
+ // Returns an array of "chunks". A chunk is an array consisting of many
3480
+ // stacks. A stack is an array consisting of many events.
3481
+ collect() {
3482
+ // Join active and finalized stacks. We want to make sure we iterate over
3483
+ // every event.
3484
+ const stacks = [...this.finalizedStacks];
3485
+ Object.values(this.activeStacks).forEach((s) =>
3486
+ stacks.splice(s.id, 0, s.events)
3487
+ );
3488
+
3489
+ return stacks.reduce((chunks, stack) => {
3490
+ if (stack.length === 0) {
3491
+ return chunks;
3492
+ }
3493
+
3494
+ // We're the first chunk in, meaning we don't need to worry about any
3495
+ // chunks behind us. Just push it.
3496
+ if (chunks.length === 0) {
3497
+ chunks.push([stack]);
3498
+ return chunks;
3499
+ }
3500
+
3501
+ // If the root event is an HTTP request, this a complete chunk. Push it.
3502
+ if (stack[0].http_server_request) {
3503
+ chunks.push([stack]);
3504
+ return chunks;
3505
+ }
3506
+
3507
+ if (stack[0].http_client_request) {
3508
+ chunks.push([stack]);
3509
+ return chunks;
3510
+ }
3511
+
3512
+ // Check to see if the previous chunk began with an HTTP request. If it
3513
+ // does, push a new chunk. Otherwise, append to the last chunk.
3514
+ const prevChunk = chunks[chunks.length - 1];
3515
+ const prevStack = prevChunk[prevChunk.length - 1];
3516
+ if (
3517
+ prevStack[0].http_server_request ||
3518
+ prevStack[0].http_client_request
3519
+ ) {
3520
+ chunks.push([stack]);
3521
+ } else {
3522
+ prevChunk.push(stack);
3523
+ }
3524
+
3525
+ return chunks;
3526
+ }, []);
3527
+ }
3528
+ }
3529
+
3530
+ function eventName(classMap, e) {
3531
+ const { callEvent } = e;
3532
+ const obj = classMap.codeObjectFromEvent(callEvent);
3533
+ if (obj) {
3534
+ return obj.id;
3535
+ }
3536
+
3537
+ return `${callEvent.defined_class}${callEvent.static ? '.' : '#'}${
3538
+ callEvent.method_id
3539
+ }`;
3540
+ }
3541
+
3542
+ // Performs an array of transform functions on an object. The transform function
3543
+ // is expected to return the transformed object.
3544
+ const transform = (transforms, obj, ...args) =>
3545
+ transforms.reduce((x, fn) => fn(x, ...args), obj);
3546
+
3547
+ // AppMapBuilder is responsible for transforming appmap data before returning
3548
+ // an AppMap model.
3549
+ class AppMapBuilder extends EventSource {
3550
+ constructor(data) {
3551
+ super();
3552
+
3553
+ this.sorter = new EventSorter();
3554
+ this.transforms = {
3555
+ event: [],
3556
+ stack: [],
3557
+ chunk: [],
3558
+ };
3559
+
3560
+ if (data) {
3561
+ this.source(data);
3562
+ }
3563
+ }
3564
+
3565
+ // Provide a source of data - i.e. an appmap JSON object
3566
+ source(data) {
3567
+ const dataType = typeof data;
3568
+ if (dataType === 'object') {
3569
+ this.data = { ...data };
3570
+ } else if (dataType === 'string') {
3571
+ this.data = JSON.parse(data);
3572
+ } else {
3573
+ throw new Error(
3574
+ `got invalid type ${dataType}, expected object or string`
3575
+ );
3576
+ }
3577
+
3578
+ (this.data.events || [])
3579
+ .map((e) => new Event(e))
3580
+ .forEach((e) => this.sorter.add(e));
3581
+
3582
+ delete this.data.events;
3583
+
3584
+ return this;
3585
+ }
3586
+
3587
+ // register an optional event transform
3588
+ event(fn) {
3589
+ console.assert(typeof fn === 'function');
3590
+ this.transforms.event.push(fn);
3591
+ return this;
3592
+ }
3593
+
3594
+ // register a optional stack transform
3595
+ stack(fn) {
3596
+ console.assert(typeof fn === 'function');
3597
+ this.transforms.stack.push(fn);
3598
+ return this;
3599
+ }
3600
+
3601
+ // register a optional chunk transform
3602
+ chunk(fn) {
3603
+ console.assert(typeof fn === 'function');
3604
+ this.transforms.chunk.push(fn);
3605
+ return this;
3606
+ }
3607
+
3608
+ // normalize the appmap data before returning an Appmap model
3609
+ normalize() {
3610
+ // Re-index events
3611
+ let eventId = 1;
3612
+ this.event((event) => {
3613
+ /* eslint-disable no-param-reassign */
3614
+ event.id = eventId;
3615
+ eventId += 1;
3616
+
3617
+ if (event.isCall() && event.returnEvent) {
3618
+ event.returnEvent.parent_id = event.id;
3619
+ }
3620
+
3621
+ // Normalize status/status_code properties
3622
+ const { httpServerResponse, httpClientResponse } = event;
3623
+ if (event.isReturn()) {
3624
+ if (httpServerResponse && httpServerResponse.status_code) {
3625
+ httpServerResponse.status = httpServerResponse.status_code;
3626
+ delete httpServerResponse.status_code;
3627
+ }
3628
+ if (httpClientResponse && httpClientResponse.status_code) {
3629
+ httpClientResponse.status = httpClientResponse.status_code;
3630
+ delete httpClientResponse.status_code;
3631
+ }
3632
+ }
3633
+
3634
+ return event;
3635
+ /* eslint-enable no-param-reassign */
3636
+ });
3637
+
3638
+ // Balance the stack by adding dummy returns to calls which never return
3639
+ return this.stack((events) => {
3640
+ events
3641
+ .filter((e) => e.isCall() && !e.returnEvent)
3642
+ .reverse()
3643
+ .map((e) => {
3644
+ const returnEvent = new Event({
3645
+ event: 'return',
3646
+ thread_id: e.thread_id,
3647
+ parent_id: e.id,
3648
+ });
3649
+ returnEvent.link(e);
3650
+ return returnEvent;
3651
+ })
3652
+ .forEach((e) => events.push(e));
3653
+
3654
+ return events;
3655
+ });
3656
+ }
3657
+
3658
+ // Cut down the size of the event array before creating the Appmap model
3659
+ prune(sizeBytes) {
3660
+ console.assert(typeof sizeBytes === 'number');
3661
+
3662
+ let classMap;
3663
+ let pruneRatio = 0;
3664
+ return this.on('preprocess', (d) => {
3665
+ classMap = new ClassMap(d.data.classMap);
3666
+ pruneRatio = Math.min(sizeBytes / d.size, 1);
3667
+ }).chunk((stacks) => {
3668
+ // We're storing size/count state in the global class map. This isn't
3669
+ // great but it works for now. Reset the counts for each chunk.
3670
+ classMap.visit((obj) => {
3671
+ /* eslint-disable no-param-reassign */
3672
+ obj.size = 0;
3673
+ obj.count = 0;
3674
+ /* eslint-enable no-param-reassign */
3675
+ });
3676
+
3677
+ // Iterate each event, regardless of the stack
3678
+ stacks.flat(2).forEach((e) => {
3679
+ if (
3680
+ e.event !== 'call' ||
3681
+ e.sql_query ||
3682
+ e.http_server_request ||
3683
+ e.http_client_request
3684
+ ) {
3685
+ return;
3686
+ }
3687
+
3688
+ const obj = classMap.codeObjectFromEvent(e);
3689
+ if (obj) {
3690
+ const objSize = sizeof(e);
3691
+ obj.size = obj.size + objSize || objSize;
3692
+ obj.count = obj.count + 1 || 1;
3693
+ }
3694
+ });
3695
+
3696
+ // Build an array of code objects sorted by size. The largest object
3697
+ // will always be index 0.
3698
+ let totalBytes = 0;
3699
+ const eventAggregates = classMap.codeObjects
3700
+ .filter((obj) => obj.size)
3701
+ .sort((a, b) => a.size - b.size)
3702
+ .map((obj) => {
3703
+ totalBytes += obj.size;
3704
+ return {
3705
+ id: obj.id,
3706
+ count: obj.count,
3707
+ size: obj.size,
3708
+ totalBytes,
3709
+ };
3710
+ })
3711
+ .reverse();
3712
+
3713
+ // Build a list of unique exclusions, starting with the largest event
3714
+ // type. Iterate until the estimated event array size is under our
3715
+ // threshold.
3716
+ const exclusions = new Set();
3717
+ for (let i = 0; i < eventAggregates.length; i += 1) {
3718
+ const eventInfo = eventAggregates[i];
3719
+ if (eventInfo.totalBytes <= totalBytes * pruneRatio) {
3720
+ break;
3721
+ }
3722
+ exclusions.add(eventInfo.id);
3723
+ }
3724
+
3725
+ return stacks.map((events) =>
3726
+ events.filter((e) => {
3727
+ const { callEvent } = e;
3728
+
3729
+ // If there's no call event, there's no need to retain this event
3730
+ if (!callEvent) {
3731
+ return false;
3732
+ }
3733
+
3734
+ if (
3735
+ callEvent.http_server_request ||
3736
+ callEvent.http_client_request ||
3737
+ callEvent.sql_query
3738
+ ) {
3739
+ return true;
3740
+ }
3741
+
3742
+ const name = eventName(classMap, e);
3743
+ return !exclusions.has(name);
3744
+ })
3745
+ );
3746
+ });
3747
+ }
3748
+
3749
+ removeNoise() {
3750
+ if (!this.data.events) {
3751
+ return this;
3752
+ }
3753
+
3754
+ const hasHttp = Boolean(
3755
+ this.data.events.find((e) => e.httpServerRequest || e.httpClientRequest)
3756
+ );
3757
+ if (!hasHttp) {
3758
+ // the entire file is noise - do nothing
3759
+ return this;
3760
+ }
3761
+
3762
+ return this.chunk((stacks) =>
3763
+ stacks.filter((stack) => {
3764
+ if (!stack.length) {
3765
+ return false;
3766
+ }
3767
+
3768
+ return (
3769
+ Boolean(stack[0].httpServerRequest) ||
3770
+ Boolean(stack[0].httpClientRequest)
3771
+ );
3772
+ })
3773
+ );
3774
+ }
3775
+
3776
+ collectEvents() {
3777
+ return this.sorter
3778
+ .collect()
3779
+ .map((chunk) => {
3780
+ const transformedChunk = transform(this.transforms.chunk, chunk);
3781
+ return transformedChunk.map((stack) => {
3782
+ const transformedStack = transform(this.transforms.stack, stack);
3783
+ return transformedStack.map((event) =>
3784
+ transform(this.transforms.event, event)
3785
+ );
3786
+ });
3787
+ })
3788
+ .flat(2);
3789
+ }
3790
+
3791
+ // Returns an Appmap model after running transforms such as normalize, prune,
3792
+ // etc.
3793
+ build() {
3794
+ const size = this.sorter.size();
3795
+ this.emit('preprocess', { size, data: this.data });
3796
+ return new AppMap({ ...this.data, events: this.collectEvents() });
3797
+ }
3798
+ }
3799
+
3800
+ function buildAppMap(data = null) {
3801
+ return new AppMapBuilder(data);
3802
+ }
3803
+
3804
+ class EventNavigator {
3805
+ constructor(event) {
3806
+ this.event = event;
3807
+ }
3808
+
3809
+ get callEvent() {
3810
+ return this.event.callEvent;
3811
+ }
3812
+
3813
+ get labels() {
3814
+ const { codeObject } = this.event;
3815
+ if (codeObject && codeObject.labels) {
3816
+ return codeObject.labels;
3817
+ }
3818
+ return null;
3819
+ }
3820
+
3821
+ *self() {
3822
+ yield this;
3823
+ }
3824
+
3825
+ *ancestors() {
3826
+ let event = this.callEvent.parent;
3827
+
3828
+ while (event) {
3829
+ yield new EventNavigator(event);
3830
+ event = event.parent;
3831
+ }
3832
+ }
3833
+
3834
+ /**
3835
+ * Generates all events which precede this event in the scenario.
3836
+ */
3837
+ *preceding() {
3838
+ const ancestors = this.ancestors();
3839
+ let ancestor = ancestors.next();
3840
+ while (!ancestor.done) {
3841
+ yield new EventNavigator(ancestor.value);
3842
+ let precedingSibling = this.precedingSiblings.next();
3843
+ while (!precedingSibling.done) {
3844
+ yield new EventNavigator(precedingSibling.value);
3845
+ const descendants = precedingSibling.value.descendants();
3846
+ let descendant = descendants.next();
3847
+ while (!descendant.done) {
3848
+ yield new EventNavigator(descendant.value);
3849
+ descendant = descendants.next();
3850
+ }
3851
+ precedingSibling = this.precedingSiblings.next();
3852
+ }
3853
+ ancestor = ancestors.next();
3854
+ }
3855
+ }
3856
+
3857
+ *precedingSiblings() {
3858
+ const { parent } = this.callEvent;
3859
+ if (!parent) {
3860
+ return;
3861
+ }
3862
+
3863
+ const index = parent.children.indexOf(this.callEvent);
3864
+ for (let i = index - 1; i >= 0; i -= 1) {
3865
+ yield new EventNavigator(parent.children[i]);
3866
+ }
3867
+ }
3868
+
3869
+ *followingSiblings() {
3870
+ const { parent } = this.callEvent;
3871
+ if (!parent) {
3872
+ return;
3873
+ }
3874
+
3875
+ const index = parent.children.indexOf(this.callEvent);
3876
+ for (let i = index + 1; i < parent.children.length; i += 1) {
3877
+ yield new EventNavigator(parent.children[i]);
3878
+ }
3879
+ }
3880
+
3881
+ *descendants(filterFn = () => true) {
3882
+ if (!this.event.children || this.event.children.length === 0) {
3883
+ return;
3884
+ }
3885
+
3886
+ // We want to traverse in order. So we use this type of traversal,
3887
+ // rather than pushing all the events onto a queue. We avoid using
3888
+ // Array.shift which can be expensive.
3889
+ const queue = [this.event.children];
3890
+ let queueIndex = 0;
3891
+ let childIndex = 0;
3892
+
3893
+ while (queueIndex < queue.length) {
3894
+ const event = queue[queueIndex][childIndex];
3895
+ if (filterFn(event)) {
3896
+ yield new EventNavigator(event);
3897
+ }
3898
+ if (childIndex === queue[queueIndex].length - 1) {
3899
+ queueIndex += 1;
3900
+ childIndex = 0;
3901
+ } else {
3902
+ childIndex += 1;
3903
+ }
3904
+ if (event.children.length > 0) {
3905
+ queue.push(event.children);
3906
+ }
3907
+ }
3908
+ }
3909
+
3910
+ hasLabel(label) {
3911
+ return this.hasLabels([label]);
3912
+ }
3913
+
3914
+ hasLabels(...searchLabels) {
3915
+ if (!this.labels) {
3916
+ return false;
3917
+ }
3918
+
3919
+ if (!searchLabels || !searchLabels.length) {
3920
+ return this.labels.size > 0;
3921
+ }
3922
+
3923
+ return (
3924
+ searchLabels.filter((l) => this.labels.has(l)).length ===
3925
+ searchLabels.length
3926
+ );
3927
+ }
3928
+ }
3929
+
3930
+ function mapFunctionLocations(memo, obj) {
3931
+ /* eslint-disable no-param-reassign */
3932
+ if (obj.type === 'function') {
3933
+ memo[obj.location] = obj;
3934
+ }
3935
+
3936
+ if (obj.children) {
3937
+ obj.children.reduce(mapFunctionLocations, memo);
3938
+ }
3939
+
3940
+ return memo;
3941
+ /* eslint-enable no-param-reassign */
3942
+ }
3943
+
3944
+ class EventInfo {
3945
+ constructor(classMap) {
3946
+ this.functionObjects = classMap.reduce(mapFunctionLocations, {});
3947
+ }
3948
+
3949
+ getName(event) {
3950
+ const label = getLabel(event);
3951
+ if (label) {
3952
+ return label;
3953
+ }
3954
+
3955
+ const codeObj = this.getCodeObject(event);
3956
+ if (codeObj) {
3957
+ return codeObj.display_name;
3958
+ }
3959
+
3960
+ // Fallback algorithm
3961
+ const separator = event.static ? '.' : '#';
3962
+ return [event.defined_class, separator, event.method_id].join('');
3963
+ }
3964
+
3965
+ getLabels(event) {
3966
+ const labels = [];
3967
+
3968
+ if (event.labels) {
3969
+ labels.push(...event.labels);
3970
+ }
3971
+
3972
+ const codeObj = this.getCodeObject(event);
3973
+ if (codeObj && codeObj.labels.length) {
3974
+ labels.push(...codeObj.labels);
3975
+ }
3976
+
3977
+ return labels;
3978
+ }
3979
+
3980
+ getCodeObject(event) {
3981
+ return this.functionObjects[`${event.path}:${event.lineno}`];
3982
+ }
3983
+ }
3984
+
3985
+ const PUBLIC = 'public';
3986
+ const MVC_MODEL = 'model';
3987
+ const MVC_VIEW = 'view';
3988
+ const MVC_CONTROLLER = 'controller';
3989
+ const PROVIDER_AUTHENTICATION = 'provider.authentication';
3990
+ const PROVIDER_AUTHORIZATION = 'provider.authorization';
3991
+
3992
+ /**
3993
+ * Indicates that a scan has detected an illegal condition on an event.
3994
+ */
3995
+ class ScanError extends Error {
3996
+ constructor(message, event) {
3997
+ super(message);
3998
+ this.event = event;
3999
+ }
4000
+ }
4001
+
4002
+ /* eslint-disable no-restricted-syntax */
4003
+
4004
+ class Public {
4005
+ constructor(event) {
4006
+ this.event = event;
4007
+ }
4008
+
4009
+ toString() {
4010
+ return `${this.event.toString()} is public`;
4011
+ }
4012
+ }
4013
+
4014
+ class Authenticator {
4015
+ constructor(event) {
4016
+ this.event = event;
4017
+ }
4018
+
4019
+ toString() {
4020
+ return `Authentication is provided by ${this.event.toString()}`;
4021
+ }
4022
+ }
4023
+
4024
+ function isPublic(event) {
4025
+ return event.codeObject && event.codeObject.labels.has(PUBLIC);
4026
+ }
4027
+
4028
+ function providesAuthentication(event) {
4029
+ return (
4030
+ event.codeObject &&
4031
+ event.codeObject.labels.has(PROVIDER_AUTHENTICATION) &&
4032
+ !isFalsey(event.returnValue)
4033
+ );
4034
+ }
4035
+
4036
+ class Target$1 {
4037
+ constructor(event) {
4038
+ this.event = event;
4039
+ }
4040
+
4041
+ toString() {
4042
+ return this.event.toString();
4043
+ }
4044
+
4045
+ /**
4046
+ * Finds the labeled authenticator within the scope.
4047
+ */
4048
+ // eslint-disable-next-line require-yield
4049
+ *evaluate() {
4050
+ const pub = this.event.descendants(isPublic).next();
4051
+ if (pub.value) {
4052
+ yield new Public(pub);
4053
+ return;
4054
+ }
4055
+
4056
+ const authenticator = this.event.descendants(providesAuthentication).next();
4057
+ if (authenticator.value) {
4058
+ yield new Authenticator(authenticator.value.event);
4059
+ return;
4060
+ }
4061
+ yield new ScanError(
4062
+ `No authentication provider found in ${this.event.event.route}`,
4063
+ this.event.event
4064
+ );
4065
+ }
4066
+ }
4067
+
4068
+ class Scope$1 {
4069
+ constructor(event) {
4070
+ this.event = event;
4071
+ }
4072
+
4073
+ toString() {
4074
+ return this.event.toString();
4075
+ }
4076
+
4077
+ *targets() {
4078
+ yield new Target$1(this.event);
4079
+ }
4080
+ }
4081
+
4082
+ function isAcceptedRoute(event) {
4083
+ if (!event.isCall()) {
4084
+ return false;
4085
+ }
4086
+
4087
+ if (!event.httpServerRequest) {
4088
+ return false;
4089
+ }
4090
+
4091
+ if (event.httpServerResponse && event.httpServerResponse.status >= 300) {
4092
+ return false;
4093
+ }
4094
+
4095
+ return true;
4096
+ }
4097
+
4098
+ /**
4099
+ * Ensures non-public routes have authentication.
4100
+ */
4101
+ class AuthenticationMissing {
4102
+ // eslint-disable-next-line class-methods-use-this
4103
+ toString() {
4104
+ return 'Authentication is required';
4105
+ }
4106
+
4107
+ // eslint-disable-next-line class-methods-use-this
4108
+ *scopes(events) {
4109
+ for (let index = 0; index < events.length; index += 1) {
4110
+ const evt = events[index];
4111
+ if (isAcceptedRoute(evt)) {
4112
+ yield new Scope$1(new EventNavigator(evt));
4113
+ }
4114
+ }
4115
+ }
4116
+ }
4117
+
4118
+ /* eslint-disable import/prefer-default-export */
4119
+
4120
+ class Target {
4121
+ // eslint-disable-next-line class-methods-use-this
4122
+ toString() {
4123
+ return 'Target';
4124
+ }
4125
+
4126
+ *evaluate() {
4127
+ for (const event of this.event.descendants((evt) => evt.sql_query)) {
4128
+ yield new ScanError(
4129
+ `Query ${event.toString()} performed from view`,
4130
+ event
4131
+ );
4132
+ }
4133
+ }
4134
+ }
4135
+
4136
+ class Scope {
4137
+ constructor(event) {
4138
+ this.event = event;
4139
+ }
4140
+
4141
+ toString() {
4142
+ return this.event.toString();
4143
+ }
4144
+
4145
+ /**
4146
+ * Finds the labeled mvc.view.
4147
+ */
4148
+ *targets() {
4149
+ for (const event of this.event.descendants((evt) =>
4150
+ evt.hasLabel(MVC_VIEW)
4151
+ )) {
4152
+ yield new Target(event);
4153
+ }
4154
+ }
4155
+ }
4156
+
4157
+ /**
4158
+ * Forbids SQL queries from the view layer.
4159
+ */
4160
+ class QueryFromView {
4161
+ // eslint-disable-next-line class-methods-use-this
4162
+ *scopes(event) {
4163
+ for (const scope of new EventNavigator(event).descendants(
4164
+ (evt) => evt.httpServerRequest
4165
+ )) {
4166
+ yield new Scope(scope);
4167
+ }
4168
+ }
4169
+ }
4170
+
4171
+ /* eslint-disable no-restricted-syntax */
4172
+ function scan(scanner) {
4173
+ return (events) => {
4174
+ const targets = [];
4175
+ const matches = [];
4176
+ const errors = [];
4177
+ for (const scope of scanner.scopes(events)) {
4178
+ for (const target of scope.targets()) {
4179
+ targets.push(target);
4180
+ for (const result of target.evaluate()) {
4181
+ if (result instanceof ScanError) {
4182
+ errors.push(result);
4183
+ } else {
4184
+ matches.push(result);
4185
+ }
4186
+ }
4187
+ }
4188
+ }
4189
+ return { targets, matches, errors };
4190
+ };
4191
+ }
4192
+
4193
+ export { AppMap, AuthenticationMissing, Authenticator, CallTree, ClassMap, CodeObject, CodeObjectType, Event, EventInfo, EventNavigator, EventSource, MVC_CONTROLLER, MVC_MODEL, MVC_VIEW, PROVIDER_AUTHENTICATION, PROVIDER_AUTHORIZATION, PUBLIC, Public, QueryFromView, ScanError, addHiddenProperty, appMapObjectCompare, arrayCompare, buildAppMap, buildLabels, capitalizeString, fullyQualifiedFunctionName, getHttpLabel, getLabel, getRepositoryUrl, getRootEvents, getSqlLabel, getSqlLabelFromString, hasProp, hashEvent, hashHttp, hashSql, hashify, httpCompare, identityHashEvent, isCommand, isFalsey, normalizeSQL, resolveDifferences, scan, setCompare, sizeof, sqlCompare, tokenizeIdentifier };