@adonis-agora/telescope 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (254) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +26 -0
  3. package/dist/configure.d.ts +16 -0
  4. package/dist/configure.d.ts.map +1 -0
  5. package/dist/configure.js +75 -0
  6. package/dist/configure.js.map +1 -0
  7. package/dist/providers/telescope_ai_provider.d.ts +20 -0
  8. package/dist/providers/telescope_ai_provider.d.ts.map +1 -0
  9. package/dist/providers/telescope_ai_provider.js +45 -0
  10. package/dist/providers/telescope_ai_provider.js.map +1 -0
  11. package/dist/providers/telescope_alerts_provider.d.ts +23 -0
  12. package/dist/providers/telescope_alerts_provider.d.ts.map +1 -0
  13. package/dist/providers/telescope_alerts_provider.js +72 -0
  14. package/dist/providers/telescope_alerts_provider.js.map +1 -0
  15. package/dist/providers/telescope_provider.d.ts +43 -0
  16. package/dist/providers/telescope_provider.d.ts.map +1 -0
  17. package/dist/providers/telescope_provider.js +103 -0
  18. package/dist/providers/telescope_provider.js.map +1 -0
  19. package/dist/providers/telescope_ui_provider.d.ts +21 -0
  20. package/dist/providers/telescope_ui_provider.d.ts.map +1 -0
  21. package/dist/providers/telescope_ui_provider.js +119 -0
  22. package/dist/providers/telescope_ui_provider.js.map +1 -0
  23. package/dist/providers/telescope_watchers_provider.d.ts +31 -0
  24. package/dist/providers/telescope_watchers_provider.d.ts.map +1 -0
  25. package/dist/providers/telescope_watchers_provider.js +116 -0
  26. package/dist/providers/telescope_watchers_provider.js.map +1 -0
  27. package/dist/src/ai/define_config.d.ts +56 -0
  28. package/dist/src/ai/define_config.d.ts.map +1 -0
  29. package/dist/src/ai/define_config.js +39 -0
  30. package/dist/src/ai/define_config.js.map +1 -0
  31. package/dist/src/ai/diagnoser.d.ts +34 -0
  32. package/dist/src/ai/diagnoser.d.ts.map +1 -0
  33. package/dist/src/ai/diagnoser.js +74 -0
  34. package/dist/src/ai/diagnoser.js.map +1 -0
  35. package/dist/src/ai/diagnosis_cache.d.ts +43 -0
  36. package/dist/src/ai/diagnosis_cache.d.ts.map +1 -0
  37. package/dist/src/ai/diagnosis_cache.js +56 -0
  38. package/dist/src/ai/diagnosis_cache.js.map +1 -0
  39. package/dist/src/ai/factory.d.ts +15 -0
  40. package/dist/src/ai/factory.d.ts.map +1 -0
  41. package/dist/src/ai/factory.js +24 -0
  42. package/dist/src/ai/factory.js.map +1 -0
  43. package/dist/src/ai/index.d.ts +14 -0
  44. package/dist/src/ai/index.d.ts.map +1 -0
  45. package/dist/src/ai/index.js +15 -0
  46. package/dist/src/ai/index.js.map +1 -0
  47. package/dist/src/ai/prompt.d.ts +31 -0
  48. package/dist/src/ai/prompt.d.ts.map +1 -0
  49. package/dist/src/ai/prompt.js +66 -0
  50. package/dist/src/ai/prompt.js.map +1 -0
  51. package/dist/src/ai/telescope_ai_diagnoser.d.ts +79 -0
  52. package/dist/src/ai/telescope_ai_diagnoser.d.ts.map +1 -0
  53. package/dist/src/ai/telescope_ai_diagnoser.js +111 -0
  54. package/dist/src/ai/telescope_ai_diagnoser.js.map +1 -0
  55. package/dist/src/alerts/alert_channel.d.ts +69 -0
  56. package/dist/src/alerts/alert_channel.d.ts.map +1 -0
  57. package/dist/src/alerts/alert_channel.js +114 -0
  58. package/dist/src/alerts/alert_channel.js.map +1 -0
  59. package/dist/src/alerts/alert_rule.d.ts +86 -0
  60. package/dist/src/alerts/alert_rule.d.ts.map +1 -0
  61. package/dist/src/alerts/alert_rule.js +2 -0
  62. package/dist/src/alerts/alert_rule.js.map +1 -0
  63. package/dist/src/alerts/alerter.d.ts +72 -0
  64. package/dist/src/alerts/alerter.d.ts.map +1 -0
  65. package/dist/src/alerts/alerter.js +248 -0
  66. package/dist/src/alerts/alerter.js.map +1 -0
  67. package/dist/src/alerts/define_config.d.ts +68 -0
  68. package/dist/src/alerts/define_config.d.ts.map +1 -0
  69. package/dist/src/alerts/define_config.js +57 -0
  70. package/dist/src/alerts/define_config.js.map +1 -0
  71. package/dist/src/alerts/exception_source.d.ts +44 -0
  72. package/dist/src/alerts/exception_source.d.ts.map +1 -0
  73. package/dist/src/alerts/exception_source.js +79 -0
  74. package/dist/src/alerts/exception_source.js.map +1 -0
  75. package/dist/src/alerts/index.d.ts +16 -0
  76. package/dist/src/alerts/index.d.ts.map +1 -0
  77. package/dist/src/alerts/index.js +17 -0
  78. package/dist/src/alerts/index.js.map +1 -0
  79. package/dist/src/alerts/new_exception_tracker.d.ts +50 -0
  80. package/dist/src/alerts/new_exception_tracker.d.ts.map +1 -0
  81. package/dist/src/alerts/new_exception_tracker.js +74 -0
  82. package/dist/src/alerts/new_exception_tracker.js.map +1 -0
  83. package/dist/src/alerts/parse_duration.d.ts +10 -0
  84. package/dist/src/alerts/parse_duration.d.ts.map +1 -0
  85. package/dist/src/alerts/parse_duration.js +27 -0
  86. package/dist/src/alerts/parse_duration.js.map +1 -0
  87. package/dist/src/alerts/slack_format.d.ts +60 -0
  88. package/dist/src/alerts/slack_format.d.ts.map +1 -0
  89. package/dist/src/alerts/slack_format.js +122 -0
  90. package/dist/src/alerts/slack_format.js.map +1 -0
  91. package/dist/src/context_accessor.d.ts +30 -0
  92. package/dist/src/context_accessor.d.ts.map +1 -0
  93. package/dist/src/context_accessor.js +20 -0
  94. package/dist/src/context_accessor.js.map +1 -0
  95. package/dist/src/define_config.d.ts +109 -0
  96. package/dist/src/define_config.d.ts.map +1 -0
  97. package/dist/src/define_config.js +38 -0
  98. package/dist/src/define_config.js.map +1 -0
  99. package/dist/src/diagnostics_registry.d.ts +46 -0
  100. package/dist/src/diagnostics_registry.d.ts.map +1 -0
  101. package/dist/src/diagnostics_registry.js +34 -0
  102. package/dist/src/diagnostics_registry.js.map +1 -0
  103. package/dist/src/diagnostics_watcher.d.ts +72 -0
  104. package/dist/src/diagnostics_watcher.d.ts.map +1 -0
  105. package/dist/src/diagnostics_watcher.js +119 -0
  106. package/dist/src/diagnostics_watcher.js.map +1 -0
  107. package/dist/src/entry.d.ts +81 -0
  108. package/dist/src/entry.d.ts.map +1 -0
  109. package/dist/src/entry.js +34 -0
  110. package/dist/src/entry.js.map +1 -0
  111. package/dist/src/exception_family_hash.d.ts +29 -0
  112. package/dist/src/exception_family_hash.d.ts.map +1 -0
  113. package/dist/src/exception_family_hash.js +30 -0
  114. package/dist/src/exception_family_hash.js.map +1 -0
  115. package/dist/src/exception_watcher.d.ts +66 -0
  116. package/dist/src/exception_watcher.d.ts.map +1 -0
  117. package/dist/src/exception_watcher.js +94 -0
  118. package/dist/src/exception_watcher.js.map +1 -0
  119. package/dist/src/extension/registry.d.ts +17 -0
  120. package/dist/src/extension/registry.d.ts.map +1 -0
  121. package/dist/src/extension/registry.js +56 -0
  122. package/dist/src/extension/registry.js.map +1 -0
  123. package/dist/src/extension/types.d.ts +158 -0
  124. package/dist/src/extension/types.d.ts.map +1 -0
  125. package/dist/src/extension/types.js +5 -0
  126. package/dist/src/extension/types.js.map +1 -0
  127. package/dist/src/index.d.ts +36 -0
  128. package/dist/src/index.d.ts.map +1 -0
  129. package/dist/src/index.js +28 -0
  130. package/dist/src/index.js.map +1 -0
  131. package/dist/src/redaction/redact.d.ts +93 -0
  132. package/dist/src/redaction/redact.d.ts.map +1 -0
  133. package/dist/src/redaction/redact.js +184 -0
  134. package/dist/src/redaction/redact.js.map +1 -0
  135. package/dist/src/redaction/redacting_store.d.ts +28 -0
  136. package/dist/src/redaction/redacting_store.d.ts.map +1 -0
  137. package/dist/src/redaction/redacting_store.js +49 -0
  138. package/dist/src/redaction/redacting_store.js.map +1 -0
  139. package/dist/src/registry.d.ts +26 -0
  140. package/dist/src/registry.d.ts.map +1 -0
  141. package/dist/src/registry.js +28 -0
  142. package/dist/src/registry.js.map +1 -0
  143. package/dist/src/request_watcher.d.ts +44 -0
  144. package/dist/src/request_watcher.d.ts.map +1 -0
  145. package/dist/src/request_watcher.js +37 -0
  146. package/dist/src/request_watcher.js.map +1 -0
  147. package/dist/src/service.d.ts +36 -0
  148. package/dist/src/service.d.ts.map +1 -0
  149. package/dist/src/service.js +65 -0
  150. package/dist/src/service.js.map +1 -0
  151. package/dist/src/store.d.ts +56 -0
  152. package/dist/src/store.d.ts.map +1 -0
  153. package/dist/src/store.js +2 -0
  154. package/dist/src/store.js.map +1 -0
  155. package/dist/src/stores/factory.d.ts +61 -0
  156. package/dist/src/stores/factory.d.ts.map +1 -0
  157. package/dist/src/stores/factory.js +42 -0
  158. package/dist/src/stores/factory.js.map +1 -0
  159. package/dist/src/stores/lucid.d.ts +138 -0
  160. package/dist/src/stores/lucid.d.ts.map +1 -0
  161. package/dist/src/stores/lucid.js +257 -0
  162. package/dist/src/stores/lucid.js.map +1 -0
  163. package/dist/src/stores/memory.d.ts +31 -0
  164. package/dist/src/stores/memory.d.ts.map +1 -0
  165. package/dist/src/stores/memory.js +117 -0
  166. package/dist/src/stores/memory.js.map +1 -0
  167. package/dist/src/telescope_middleware.d.ts +19 -0
  168. package/dist/src/telescope_middleware.d.ts.map +1 -0
  169. package/dist/src/telescope_middleware.js +56 -0
  170. package/dist/src/telescope_middleware.js.map +1 -0
  171. package/dist/src/ui/api.d.ts +49 -0
  172. package/dist/src/ui/api.d.ts.map +1 -0
  173. package/dist/src/ui/api.js +155 -0
  174. package/dist/src/ui/api.js.map +1 -0
  175. package/dist/src/ui/dashboard.d.ts +8 -0
  176. package/dist/src/ui/dashboard.d.ts.map +1 -0
  177. package/dist/src/ui/dashboard.html +626 -0
  178. package/dist/src/ui/dashboard.js +29 -0
  179. package/dist/src/ui/dashboard.js.map +1 -0
  180. package/dist/src/ui/define_config.d.ts +87 -0
  181. package/dist/src/ui/define_config.d.ts.map +1 -0
  182. package/dist/src/ui/define_config.js +104 -0
  183. package/dist/src/ui/define_config.js.map +1 -0
  184. package/dist/src/ui/extension_api.d.ts +23 -0
  185. package/dist/src/ui/extension_api.d.ts.map +1 -0
  186. package/dist/src/ui/extension_api.js +50 -0
  187. package/dist/src/ui/extension_api.js.map +1 -0
  188. package/dist/src/ui/guard.d.ts +33 -0
  189. package/dist/src/ui/guard.d.ts.map +1 -0
  190. package/dist/src/ui/guard.js +47 -0
  191. package/dist/src/ui/guard.js.map +1 -0
  192. package/dist/src/ui/http.d.ts +47 -0
  193. package/dist/src/ui/http.d.ts.map +1 -0
  194. package/dist/src/ui/http.js +43 -0
  195. package/dist/src/ui/http.js.map +1 -0
  196. package/dist/src/ui/index.d.ts +12 -0
  197. package/dist/src/ui/index.d.ts.map +1 -0
  198. package/dist/src/ui/index.js +13 -0
  199. package/dist/src/ui/index.js.map +1 -0
  200. package/dist/src/watchers/cache_watcher.d.ts +60 -0
  201. package/dist/src/watchers/cache_watcher.d.ts.map +1 -0
  202. package/dist/src/watchers/cache_watcher.js +72 -0
  203. package/dist/src/watchers/cache_watcher.js.map +1 -0
  204. package/dist/src/watchers/define_config.d.ts +38 -0
  205. package/dist/src/watchers/define_config.d.ts.map +1 -0
  206. package/dist/src/watchers/define_config.js +17 -0
  207. package/dist/src/watchers/define_config.js.map +1 -0
  208. package/dist/src/watchers/emitter.d.ts +32 -0
  209. package/dist/src/watchers/emitter.d.ts.map +1 -0
  210. package/dist/src/watchers/emitter.js +2 -0
  211. package/dist/src/watchers/emitter.js.map +1 -0
  212. package/dist/src/watchers/http_client_watcher.d.ts +74 -0
  213. package/dist/src/watchers/http_client_watcher.d.ts.map +1 -0
  214. package/dist/src/watchers/http_client_watcher.js +168 -0
  215. package/dist/src/watchers/http_client_watcher.js.map +1 -0
  216. package/dist/src/watchers/index.d.ts +19 -0
  217. package/dist/src/watchers/index.d.ts.map +1 -0
  218. package/dist/src/watchers/index.js +19 -0
  219. package/dist/src/watchers/index.js.map +1 -0
  220. package/dist/src/watchers/logs_watcher.d.ts +82 -0
  221. package/dist/src/watchers/logs_watcher.d.ts.map +1 -0
  222. package/dist/src/watchers/logs_watcher.js +145 -0
  223. package/dist/src/watchers/logs_watcher.js.map +1 -0
  224. package/dist/src/watchers/lucid_query_watcher.d.ts +64 -0
  225. package/dist/src/watchers/lucid_query_watcher.d.ts.map +1 -0
  226. package/dist/src/watchers/lucid_query_watcher.js +84 -0
  227. package/dist/src/watchers/lucid_query_watcher.js.map +1 -0
  228. package/dist/src/watchers/mail_watcher.d.ts +51 -0
  229. package/dist/src/watchers/mail_watcher.d.ts.map +1 -0
  230. package/dist/src/watchers/mail_watcher.js +93 -0
  231. package/dist/src/watchers/mail_watcher.js.map +1 -0
  232. package/dist/src/watchers/normalize_http_target.d.ts +17 -0
  233. package/dist/src/watchers/normalize_http_target.d.ts.map +1 -0
  234. package/dist/src/watchers/normalize_http_target.js +41 -0
  235. package/dist/src/watchers/normalize_http_target.js.map +1 -0
  236. package/dist/src/watchers/query_family_hash.d.ts +8 -0
  237. package/dist/src/watchers/query_family_hash.d.ts.map +1 -0
  238. package/dist/src/watchers/query_family_hash.js +31 -0
  239. package/dist/src/watchers/query_family_hash.js.map +1 -0
  240. package/dist/src/watchers/record.d.ts +22 -0
  241. package/dist/src/watchers/record.d.ts.map +1 -0
  242. package/dist/src/watchers/record.js +48 -0
  243. package/dist/src/watchers/record.js.map +1 -0
  244. package/dist/stubs/config/telescope.stub +56 -0
  245. package/dist/stubs/config/telescope_ai.stub +36 -0
  246. package/dist/stubs/config/telescope_alerts.stub +47 -0
  247. package/dist/stubs/config/telescope_ui.stub +40 -0
  248. package/dist/stubs/config/telescope_watchers.stub +30 -0
  249. package/dist/stubs/database/migrations/create_telescope_entries_table.stub +39 -0
  250. package/dist/stubs/main.d.ts +6 -0
  251. package/dist/stubs/main.d.ts.map +1 -0
  252. package/dist/stubs/main.js +7 -0
  253. package/dist/stubs/main.js.map +1 -0
  254. package/package.json +140 -0
@@ -0,0 +1,87 @@
1
+ import type { UiHttpContext } from './http.js';
2
+ /**
3
+ * The decision hook gating the dashboard + JSON API. Return `true` to allow the
4
+ * request through, `false` to reject it (the guard answers 401/403). It receives
5
+ * the (framework-light) HTTP context, so a host can inspect headers, a session,
6
+ * an injected user — whatever its own auth exposes. Sync or async.
7
+ */
8
+ export type AuthorizeHook = (ctx: UiHttpContext) => boolean | Promise<boolean>;
9
+ /**
10
+ * Built-in credential gate used by the default {@link AuthorizeHook} when no
11
+ * custom `authorize` is supplied. When set, a request is allowed in production
12
+ * only if it presents the matching credential; otherwise the default policy is
13
+ * "allow only outside production".
14
+ */
15
+ export interface UiCredentials {
16
+ /**
17
+ * A bearer/opaque token. A request is allowed when it carries
18
+ * `Authorization: Bearer <token>` OR `?token=<token>` matching this value.
19
+ */
20
+ token?: string;
21
+ /** HTTP Basic credentials (`Authorization: Basic <base64(user:pass)>`). */
22
+ basic?: {
23
+ username: string;
24
+ password: string;
25
+ };
26
+ }
27
+ /**
28
+ * The shape of `config/telescope_ui.ts`. Everything is optional with sane
29
+ * defaults: the dashboard is mounted at `/telescope`, and access is allowed
30
+ * automatically outside production (and denied in production unless a `token` /
31
+ * `basic` credential — or a custom `authorize` hook — says otherwise).
32
+ */
33
+ export interface TelescopeUiConfig {
34
+ /**
35
+ * Master switch. When `false`, the provider registers no routes at all (the
36
+ * dashboard and JSON API simply do not exist). Default `true`.
37
+ */
38
+ enabled?: boolean;
39
+ /**
40
+ * URL prefix the dashboard + JSON API mount under. The dashboard page is served
41
+ * at the prefix root; the JSON API lives at `<path>/api/*`. Default `/telescope`.
42
+ */
43
+ path?: string;
44
+ /**
45
+ * The access-decision hook. When omitted, the default policy is used: allow when
46
+ * not in production, otherwise require a configured {@link UiCredentials}. Provide
47
+ * this to delegate to your own app auth (e.g. `ctx.auth.user?.isAdmin === true`).
48
+ */
49
+ authorize?: AuthorizeHook;
50
+ /**
51
+ * Built-in credentials for the default policy (ignored when a custom `authorize`
52
+ * is supplied). Lets you gate a production dashboard without writing a hook.
53
+ */
54
+ credentials?: UiCredentials;
55
+ }
56
+ /** The fully-resolved config the provider acts on (no optionals on the basics). */
57
+ export interface ResolvedTelescopeUiConfig {
58
+ enabled: boolean;
59
+ /** Always a leading-slash, no-trailing-slash prefix, e.g. `/telescope`. */
60
+ path: string;
61
+ authorize: AuthorizeHook;
62
+ credentials: UiCredentials;
63
+ }
64
+ /**
65
+ * Identity helper giving `config/telescope_ui.ts` full type-checking. Mirrors the
66
+ * AdonisJS `defineConfig` convention.
67
+ *
68
+ * ```ts
69
+ * import { defineConfig } from '@adonis-agora/telescope/ui'
70
+ * export default defineConfig({ path: '/__telescope', authorize: (ctx) => true })
71
+ * ```
72
+ */
73
+ export declare function defineConfig(config: TelescopeUiConfig): TelescopeUiConfig;
74
+ /** Normalize a prefix to a leading slash with no trailing slash (`/telescope`). */
75
+ export declare function normalizePath(path: string): string;
76
+ /**
77
+ * The default access policy used when no custom `authorize` is configured:
78
+ *
79
+ * - if a `token` credential is set and the request presents it → allow;
80
+ * - if `basic` credentials are set and the request presents them → allow;
81
+ * - otherwise allow only when NOT in production (so a dev dashboard "just works"
82
+ * while a production deploy is denied unless explicitly gated).
83
+ */
84
+ export declare function defaultAuthorize(credentials: UiCredentials): AuthorizeHook;
85
+ /** Apply defaults to a (possibly partial) config. */
86
+ export declare function resolveConfig(config?: TelescopeUiConfig): ResolvedTelescopeUiConfig;
87
+ //# sourceMappingURL=define_config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"define_config.d.ts","sourceRoot":"","sources":["../../../src/ui/define_config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE/C;;;;;GAKG;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,GAAG,EAAE,aAAa,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAE/E;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2EAA2E;IAC3E,KAAK,CAAC,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;CAChD;AAED;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IAChC;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,SAAS,CAAC,EAAE,aAAa,CAAC;IAC1B;;;OAGG;IACH,WAAW,CAAC,EAAE,aAAa,CAAC;CAC7B;AAED,mFAAmF;AACnF,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,OAAO,CAAC;IACjB,2EAA2E;IAC3E,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,aAAa,CAAC;IACzB,WAAW,EAAE,aAAa,CAAC;CAC5B;AAED;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,iBAAiB,GAAG,iBAAiB,CAEzE;AAED,mFAAmF;AACnF,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAMlD;AAiDD;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,aAAa,GAAG,aAAa,CAS1E;AAED,qDAAqD;AACrD,wBAAgB,aAAa,CAAC,MAAM,GAAE,iBAAsB,GAAG,yBAAyB,CAQvF"}
@@ -0,0 +1,104 @@
1
+ /**
2
+ * Identity helper giving `config/telescope_ui.ts` full type-checking. Mirrors the
3
+ * AdonisJS `defineConfig` convention.
4
+ *
5
+ * ```ts
6
+ * import { defineConfig } from '@adonis-agora/telescope/ui'
7
+ * export default defineConfig({ path: '/__telescope', authorize: (ctx) => true })
8
+ * ```
9
+ */
10
+ export function defineConfig(config) {
11
+ return config;
12
+ }
13
+ /** Normalize a prefix to a leading slash with no trailing slash (`/telescope`). */
14
+ export function normalizePath(path) {
15
+ let p = path.trim();
16
+ if (p === '' || p === '/')
17
+ return '/telescope';
18
+ if (!p.startsWith('/'))
19
+ p = `/${p}`;
20
+ while (p.length > 1 && p.endsWith('/'))
21
+ p = p.slice(0, -1);
22
+ return p;
23
+ }
24
+ /** Whether the current process is running in production. */
25
+ function isProduction() {
26
+ return process.env.NODE_ENV === 'production';
27
+ }
28
+ /**
29
+ * Constant-time-ish string compare to avoid trivially leaking length/timing of a
30
+ * configured secret. Not a substitute for a real auth system, but better than `===`
31
+ * for a dev-tool credential check.
32
+ */
33
+ function safeEqual(a, b) {
34
+ if (a.length !== b.length)
35
+ return false;
36
+ let mismatch = 0;
37
+ for (let i = 0; i < a.length; i++)
38
+ mismatch |= a.charCodeAt(i) ^ b.charCodeAt(i);
39
+ return mismatch === 0;
40
+ }
41
+ /** Pull a bearer token from `Authorization: Bearer …` or `?token=…`. */
42
+ function readToken(ctx) {
43
+ const auth = ctx.request.header('authorization');
44
+ if (auth !== undefined) {
45
+ const match = /^Bearer\s+(.+)$/i.exec(auth.trim());
46
+ if (match?.[1] !== undefined)
47
+ return match[1].trim();
48
+ }
49
+ const qsToken = ctx.request.qs().token;
50
+ return typeof qsToken === 'string' ? qsToken : undefined;
51
+ }
52
+ /** Decode and compare `Authorization: Basic …` against configured credentials. */
53
+ function matchesBasic(ctx, basic) {
54
+ const auth = ctx.request.header('authorization');
55
+ if (auth === undefined)
56
+ return false;
57
+ const match = /^Basic\s+(.+)$/i.exec(auth.trim());
58
+ if (match?.[1] === undefined)
59
+ return false;
60
+ let decoded;
61
+ try {
62
+ decoded = Buffer.from(match[1].trim(), 'base64').toString('utf8');
63
+ }
64
+ catch {
65
+ return false;
66
+ }
67
+ const sep = decoded.indexOf(':');
68
+ if (sep === -1)
69
+ return false;
70
+ const username = decoded.slice(0, sep);
71
+ const password = decoded.slice(sep + 1);
72
+ return safeEqual(username, basic.username) && safeEqual(password, basic.password);
73
+ }
74
+ /**
75
+ * The default access policy used when no custom `authorize` is configured:
76
+ *
77
+ * - if a `token` credential is set and the request presents it → allow;
78
+ * - if `basic` credentials are set and the request presents them → allow;
79
+ * - otherwise allow only when NOT in production (so a dev dashboard "just works"
80
+ * while a production deploy is denied unless explicitly gated).
81
+ */
82
+ export function defaultAuthorize(credentials) {
83
+ return (ctx) => {
84
+ if (credentials.token !== undefined) {
85
+ const presented = readToken(ctx);
86
+ if (presented !== undefined && safeEqual(presented, credentials.token))
87
+ return true;
88
+ }
89
+ if (credentials.basic !== undefined && matchesBasic(ctx, credentials.basic))
90
+ return true;
91
+ return !isProduction();
92
+ };
93
+ }
94
+ /** Apply defaults to a (possibly partial) config. */
95
+ export function resolveConfig(config = {}) {
96
+ const credentials = config.credentials ?? {};
97
+ return {
98
+ enabled: config.enabled ?? true,
99
+ path: normalizePath(config.path ?? '/telescope'),
100
+ authorize: config.authorize ?? defaultAuthorize(credentials),
101
+ credentials,
102
+ };
103
+ }
104
+ //# sourceMappingURL=define_config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"define_config.js","sourceRoot":"","sources":["../../../src/ui/define_config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import type { ExtensionRegistry } from '../extension/registry.js';
2
+ import type { ExtensionContext } from '../extension/types.js';
3
+ import type { UiHttpContext } from './http.js';
4
+ /**
5
+ * JSON handlers for the extension SDK surface: dashboard/entry-type metadata and the per-panel data
6
+ * providers. Framework-light (same {@link UiHttpContext} as {@link TelescopeApi}), so they unit-test
7
+ * against a plain request/response. Constructed with the booted {@link ExtensionRegistry} and the
8
+ * {@link ExtensionContext} provider resolves run against.
9
+ */
10
+ export declare class ExtensionApi {
11
+ private readonly registry;
12
+ private readonly ctx;
13
+ constructor(registry: ExtensionRegistry, ctx: ExtensionContext);
14
+ /** `GET /api/meta` — the dashboards + entry types contributed by every extension. */
15
+ meta(http: UiHttpContext): unknown;
16
+ /**
17
+ * `GET /api/ext/:ext/data/:provider` — resolve a named data provider. The `:ext` segment must be
18
+ * the provider's owning extension (namespace check), so one extension can't be addressed under
19
+ * another's name. The panel's request query string is passed through to `resolve`.
20
+ */
21
+ data(http: UiHttpContext, ext: string, providerName: string): Promise<unknown>;
22
+ }
23
+ //# sourceMappingURL=extension_api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extension_api.d.ts","sourceRoot":"","sources":["../../../src/ui/extension_api.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE/C;;;;;GAKG;AACH,qBAAa,YAAY;IAErB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,GAAG;gBADH,QAAQ,EAAE,iBAAiB,EAC3B,GAAG,EAAE,gBAAgB;IAGxC,qFAAqF;IACrF,IAAI,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO;IASlC;;;;OAIG;IACG,IAAI,CAAC,IAAI,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAoBrF"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * JSON handlers for the extension SDK surface: dashboard/entry-type metadata and the per-panel data
3
+ * providers. Framework-light (same {@link UiHttpContext} as {@link TelescopeApi}), so they unit-test
4
+ * against a plain request/response. Constructed with the booted {@link ExtensionRegistry} and the
5
+ * {@link ExtensionContext} provider resolves run against.
6
+ */
7
+ export class ExtensionApi {
8
+ registry;
9
+ ctx;
10
+ constructor(registry, ctx) {
11
+ this.registry = registry;
12
+ this.ctx = ctx;
13
+ }
14
+ /** `GET /api/meta` — the dashboards + entry types contributed by every extension. */
15
+ meta(http) {
16
+ return http.response.status(200).send({
17
+ data: {
18
+ entryTypes: this.registry.entryTypes(),
19
+ dashboards: this.registry.dashboards(),
20
+ },
21
+ });
22
+ }
23
+ /**
24
+ * `GET /api/ext/:ext/data/:provider` — resolve a named data provider. The `:ext` segment must be
25
+ * the provider's owning extension (namespace check), so one extension can't be addressed under
26
+ * another's name. The panel's request query string is passed through to `resolve`.
27
+ */
28
+ async data(http, ext, providerName) {
29
+ const owner = this.registry.providerOwner(providerName);
30
+ if (owner === undefined || owner !== ext) {
31
+ return http.response
32
+ .status(404)
33
+ .send({ error: `Unknown data provider "${ext}/${providerName}"` });
34
+ }
35
+ const provider = this.registry.findProvider(providerName);
36
+ if (!provider) {
37
+ return http.response.status(404).send({ error: `Unknown data provider "${providerName}"` });
38
+ }
39
+ try {
40
+ const result = await provider.resolve(http.request.qs(), this.ctx);
41
+ return http.response.status(200).send({ data: result });
42
+ }
43
+ catch (err) {
44
+ return http.response
45
+ .status(500)
46
+ .send({ error: err instanceof Error ? err.message : String(err) });
47
+ }
48
+ }
49
+ }
50
+ //# sourceMappingURL=extension_api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extension_api.js","sourceRoot":"","sources":["../../../src/ui/extension_api.ts"],"names":[],"mappings":"AAIA;;;;;GAKG;AACH,MAAM,OAAO,YAAY;IAEJ;IACA;IAFnB,YACmB,QAA2B,EAC3B,GAAqB;QADrB,aAAQ,GAAR,QAAQ,CAAmB;QAC3B,QAAG,GAAH,GAAG,CAAkB;IACrC,CAAC;IAEJ,qFAAqF;IACrF,IAAI,CAAC,IAAmB;QACtB,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;YACpC,IAAI,EAAE;gBACJ,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE;gBACtC,UAAU,EAAE,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE;aACvC;SACF,CAAC,CAAC;IACL,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,IAAI,CAAC,IAAmB,EAAE,GAAW,EAAE,YAAoB;QAC/D,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC;QACxD,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,GAAG,EAAE,CAAC;YACzC,OAAO,IAAI,CAAC,QAAQ;iBACjB,MAAM,CAAC,GAAG,CAAC;iBACX,IAAI,CAAC,EAAE,KAAK,EAAE,0BAA0B,GAAG,IAAI,YAAY,GAAG,EAAE,CAAC,CAAC;QACvE,CAAC;QACD,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC;QAC1D,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,0BAA0B,YAAY,GAAG,EAAE,CAAC,CAAC;QAC9F,CAAC;QACD,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;YACnE,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;QAC1D,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,IAAI,CAAC,QAAQ;iBACjB,MAAM,CAAC,GAAG,CAAC;iBACX,IAAI,CAAC,EAAE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACvE,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,33 @@
1
+ import type { AuthorizeHook } from './define_config.js';
2
+ import type { UiHttpContext } from './http.js';
3
+ /** The outcome of an authorization check. */
4
+ export interface GuardResult {
5
+ /** Whether the request may proceed to the handler. */
6
+ allowed: boolean;
7
+ /** When denied, the HTTP status the caller should answer with (401 or 403). */
8
+ status?: number;
9
+ /** When denied, a short message body. */
10
+ message?: string;
11
+ }
12
+ /**
13
+ * Run the configured {@link AuthorizeHook} against a request and translate the
14
+ * decision into a {@link GuardResult}. Framework-light: takes the same minimal
15
+ * HTTP context the handlers do, so it is unit-testable without a server.
16
+ *
17
+ * Denials are distinguished:
18
+ * - **401** when the request presented NO credential at all (an `Authorization`
19
+ * header is absent and no `?token`) — prompts the host/browser to authenticate;
20
+ * - **403** when a credential WAS presented but rejected (wrong token/password).
21
+ *
22
+ * Any error thrown by a custom `authorize` hook fails closed (403) rather than
23
+ * leaking the dashboard.
24
+ */
25
+ export declare function runGuard(ctx: UiHttpContext, authorize: AuthorizeHook): Promise<GuardResult>;
26
+ /**
27
+ * Guard `ctx` and, on denial, write the status + message onto the response and
28
+ * return `false`. On success returns `true` and leaves the response untouched for
29
+ * the handler. A `WWW-Authenticate` header is sent on a 401 so a browser can
30
+ * surface a Basic-auth prompt when that scheme is in play.
31
+ */
32
+ export declare function enforceGuard(ctx: UiHttpContext, authorize: AuthorizeHook): Promise<boolean>;
33
+ //# sourceMappingURL=guard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guard.d.ts","sourceRoot":"","sources":["../../../src/ui/guard.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE/C,6CAA6C;AAC7C,MAAM,WAAW,WAAW;IAC1B,sDAAsD;IACtD,OAAO,EAAE,OAAO,CAAC;IACjB,+EAA+E;IAC/E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,yCAAyC;IACzC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,QAAQ,CAAC,GAAG,EAAE,aAAa,EAAE,SAAS,EAAE,aAAa,GAAG,OAAO,CAAC,WAAW,CAAC,CAejG;AAED;;;;;GAKG;AACH,wBAAsB,YAAY,CAAC,GAAG,EAAE,aAAa,EAAE,SAAS,EAAE,aAAa,GAAG,OAAO,CAAC,OAAO,CAAC,CAUjG"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Run the configured {@link AuthorizeHook} against a request and translate the
3
+ * decision into a {@link GuardResult}. Framework-light: takes the same minimal
4
+ * HTTP context the handlers do, so it is unit-testable without a server.
5
+ *
6
+ * Denials are distinguished:
7
+ * - **401** when the request presented NO credential at all (an `Authorization`
8
+ * header is absent and no `?token`) — prompts the host/browser to authenticate;
9
+ * - **403** when a credential WAS presented but rejected (wrong token/password).
10
+ *
11
+ * Any error thrown by a custom `authorize` hook fails closed (403) rather than
12
+ * leaking the dashboard.
13
+ */
14
+ export async function runGuard(ctx, authorize) {
15
+ let allowed;
16
+ try {
17
+ allowed = await authorize(ctx);
18
+ }
19
+ catch {
20
+ return { allowed: false, status: 403, message: 'Forbidden' };
21
+ }
22
+ if (allowed)
23
+ return { allowed: true };
24
+ const presentedCredential = ctx.request.header('authorization') !== undefined || typeof ctx.request.qs().token === 'string';
25
+ return presentedCredential
26
+ ? { allowed: false, status: 403, message: 'Forbidden' }
27
+ : { allowed: false, status: 401, message: 'Unauthorized' };
28
+ }
29
+ /**
30
+ * Guard `ctx` and, on denial, write the status + message onto the response and
31
+ * return `false`. On success returns `true` and leaves the response untouched for
32
+ * the handler. A `WWW-Authenticate` header is sent on a 401 so a browser can
33
+ * surface a Basic-auth prompt when that scheme is in play.
34
+ */
35
+ export async function enforceGuard(ctx, authorize) {
36
+ const result = await runGuard(ctx, authorize);
37
+ if (result.allowed)
38
+ return true;
39
+ const status = result.status ?? 403;
40
+ ctx.response.status(status);
41
+ if (status === 401) {
42
+ ctx.response.header('WWW-Authenticate', 'Basic realm="Telescope", Bearer');
43
+ }
44
+ ctx.response.send({ error: result.message ?? 'Forbidden' });
45
+ return false;
46
+ }
47
+ //# sourceMappingURL=guard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guard.js","sourceRoot":"","sources":["../../../src/ui/guard.ts"],"names":[],"mappings":"AAaA;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,GAAkB,EAAE,SAAwB;IACzE,IAAI,OAAgB,CAAC;IACrB,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,SAAS,CAAC,GAAG,CAAC,CAAC;IACjC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC;IAC/D,CAAC;IACD,IAAI,OAAO;QAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAEtC,MAAM,mBAAmB,GACvB,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,eAAe,CAAC,KAAK,SAAS,IAAI,OAAO,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC,KAAK,KAAK,QAAQ,CAAC;IAElG,OAAO,mBAAmB;QACxB,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,WAAW,EAAE;QACvD,CAAC,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC;AAC/D,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,GAAkB,EAAE,SAAwB;IAC7E,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IAC9C,IAAI,MAAM,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAChC,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC;IACpC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC5B,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;QACnB,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,kBAAkB,EAAE,iCAAiC,CAAC,CAAC;IAC7E,CAAC;IACD,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,OAAO,IAAI,WAAW,EAAE,CAAC,CAAC;IAC5D,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * The minimal HTTP surface the JSON API handlers and the auth guard read/write,
3
+ * kept deliberately framework-light so handlers are unit-testable with a plain
4
+ * object (no running AdonisJS server). An Adonis `HttpContext` satisfies this
5
+ * structurally — `request.qs()`, `request.header()`, and a `response` that can
6
+ * set a status and a body — so the provider passes the real `ctx` straight
7
+ * through.
8
+ */
9
+ /** The slice of an inbound request the UI reads. */
10
+ export interface UiRequest {
11
+ /** The request method, upper- or lower-cased (`GET`, `get`). */
12
+ method(): string;
13
+ /** The parsed query string as a flat record (Adonis `request.qs()`). */
14
+ qs(): Record<string, unknown>;
15
+ /** A single request header by (case-insensitive) name, or `undefined`. */
16
+ header(name: string): string | undefined;
17
+ }
18
+ /** The slice of an outbound response the UI writes. */
19
+ export interface UiResponse {
20
+ /** Set the HTTP status code; returns `this` for chaining (Adonis-compatible). */
21
+ status(code: number): UiResponse;
22
+ /** Set a response header; returns `this` for chaining (Adonis-compatible). */
23
+ header(name: string, value: string): UiResponse;
24
+ /** Send a body (object → JSON, string → as-is). Terminal. */
25
+ send(body: unknown): unknown;
26
+ }
27
+ /** A framework-light HTTP context: just the request + response slices above. */
28
+ export interface UiHttpContext {
29
+ request: UiRequest;
30
+ response: UiResponse;
31
+ }
32
+ /**
33
+ * A tiny in-memory {@link UiResponse} for tests and for capturing a handler's
34
+ * output without a live server. Records the last status/headers/body written.
35
+ */
36
+ export declare class RecordingResponse implements UiResponse {
37
+ statusCode: number;
38
+ readonly headers: Record<string, string>;
39
+ body: unknown;
40
+ sent: boolean;
41
+ status(code: number): this;
42
+ header(name: string, value: string): this;
43
+ send(body: unknown): unknown;
44
+ }
45
+ /** Build a plain {@link UiRequest} from a method, query record, and headers. */
46
+ export declare function makeRequest(method: string, qs?: Record<string, unknown>, headers?: Record<string, string>): UiRequest;
47
+ //# sourceMappingURL=http.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../../src/ui/http.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,oDAAoD;AACpD,MAAM,WAAW,SAAS;IACxB,gEAAgE;IAChE,MAAM,IAAI,MAAM,CAAC;IACjB,wEAAwE;IACxE,EAAE,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,0EAA0E;IAC1E,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;CAC1C;AAED,uDAAuD;AACvD,MAAM,WAAW,UAAU;IACzB,iFAAiF;IACjF,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,UAAU,CAAC;IACjC,8EAA8E;IAC9E,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,UAAU,CAAC;IAChD,6DAA6D;IAC7D,IAAI,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC;CAC9B;AAED,gFAAgF;AAChF,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,SAAS,CAAC;IACnB,QAAQ,EAAE,UAAU,CAAC;CACtB;AAED;;;GAGG;AACH,qBAAa,iBAAkB,YAAW,UAAU;IAClD,UAAU,SAAO;IACjB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAM;IAC9C,IAAI,EAAE,OAAO,CAAa;IAC1B,IAAI,UAAS;IAEb,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAK1B,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAKzC,IAAI,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO;CAK7B;AAED,gFAAgF;AAChF,wBAAgB,WAAW,CACzB,MAAM,EAAE,MAAM,EACd,EAAE,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EAChC,OAAO,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,GACnC,SAAS,CAQX"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * The minimal HTTP surface the JSON API handlers and the auth guard read/write,
3
+ * kept deliberately framework-light so handlers are unit-testable with a plain
4
+ * object (no running AdonisJS server). An Adonis `HttpContext` satisfies this
5
+ * structurally — `request.qs()`, `request.header()`, and a `response` that can
6
+ * set a status and a body — so the provider passes the real `ctx` straight
7
+ * through.
8
+ */
9
+ /**
10
+ * A tiny in-memory {@link UiResponse} for tests and for capturing a handler's
11
+ * output without a live server. Records the last status/headers/body written.
12
+ */
13
+ export class RecordingResponse {
14
+ statusCode = 200;
15
+ headers = {};
16
+ body = undefined;
17
+ sent = false;
18
+ status(code) {
19
+ this.statusCode = code;
20
+ return this;
21
+ }
22
+ header(name, value) {
23
+ this.headers[name.toLowerCase()] = value;
24
+ return this;
25
+ }
26
+ send(body) {
27
+ this.body = body;
28
+ this.sent = true;
29
+ return body;
30
+ }
31
+ }
32
+ /** Build a plain {@link UiRequest} from a method, query record, and headers. */
33
+ export function makeRequest(method, qs = {}, headers = {}) {
34
+ const lower = {};
35
+ for (const [key, value] of Object.entries(headers))
36
+ lower[key.toLowerCase()] = value;
37
+ return {
38
+ method: () => method,
39
+ qs: () => qs,
40
+ header: (name) => lower[name.toLowerCase()],
41
+ };
42
+ }
43
+ //# sourceMappingURL=http.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.js","sourceRoot":"","sources":["../../../src/ui/http.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AA4BH;;;GAGG;AACH,MAAM,OAAO,iBAAiB;IAC5B,UAAU,GAAG,GAAG,CAAC;IACR,OAAO,GAA2B,EAAE,CAAC;IAC9C,IAAI,GAAY,SAAS,CAAC;IAC1B,IAAI,GAAG,KAAK,CAAC;IAEb,MAAM,CAAC,IAAY;QACjB,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACvB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,CAAC,IAAY,EAAE,KAAa;QAChC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,GAAG,KAAK,CAAC;QACzC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC,IAAa;QAChB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AAED,gFAAgF;AAChF,MAAM,UAAU,WAAW,CACzB,MAAc,EACd,KAA8B,EAAE,EAChC,UAAkC,EAAE;IAEpC,MAAM,KAAK,GAA2B,EAAE,CAAC;IACzC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC;QAAE,KAAK,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,GAAG,KAAK,CAAC;IACrF,OAAO;QACL,MAAM,EAAE,GAAG,EAAE,CAAC,MAAM;QACpB,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE;QACZ,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;KAC5C,CAAC;AACJ,CAAC"}
@@ -0,0 +1,12 @@
1
+ /** Keep in sync with this package's `version` in package.json. */
2
+ export declare const VERSION = "0.1.0";
3
+ export { defineConfig, resolveConfig, normalizePath, defaultAuthorize } from './define_config.js';
4
+ export type { AuthorizeHook, ResolvedTelescopeUiConfig, TelescopeUiConfig, UiCredentials, } from './define_config.js';
5
+ export { RecordingResponse, makeRequest } from './http.js';
6
+ export type { UiHttpContext, UiRequest, UiResponse } from './http.js';
7
+ export { enforceGuard, runGuard } from './guard.js';
8
+ export type { GuardResult } from './guard.js';
9
+ export { TelescopeApi, buildQuery, toSummary } from './api.js';
10
+ export type { EntrySummary } from './api.js';
11
+ export { renderDashboard } from './dashboard.js';
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ui/index.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,eAAO,MAAM,OAAO,UAAU,CAAC;AAG/B,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAClG,YAAY,EACV,aAAa,EACb,yBAAyB,EACzB,iBAAiB,EACjB,aAAa,GACd,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAC3D,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAGtE,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACpD,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAG9C,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAC/D,YAAY,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAG7C,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,13 @@
1
+ /** Keep in sync with this package's `version` in package.json. */
2
+ export const VERSION = '0.1.0';
3
+ // — config —
4
+ export { defineConfig, resolveConfig, normalizePath, defaultAuthorize } from './define_config.js';
5
+ // — HTTP shapes (framework-light) —
6
+ export { RecordingResponse, makeRequest } from './http.js';
7
+ // — auth guard —
8
+ export { enforceGuard, runGuard } from './guard.js';
9
+ // — JSON API —
10
+ export { TelescopeApi, buildQuery, toSummary } from './api.js';
11
+ // — dashboard —
12
+ export { renderDashboard } from './dashboard.js';
13
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/ui/index.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAClE,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC;AAE/B,aAAa;AACb,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAQlG,oCAAoC;AACpC,OAAO,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAG3D,iBAAiB;AACjB,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAGpD,eAAe;AACf,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAG/D,gBAAgB;AAChB,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,60 @@
1
+ import { type RecordInput } from '../entry.js';
2
+ import type { EmitterLike, Watcher } from './emitter.js';
3
+ /**
4
+ * The `@adonisjs/cache` event names this watcher subscribes to, mapped to the
5
+ * cache operation recorded for each.
6
+ *
7
+ * NOTE: `@adonisjs/cache` is not installed in this repository, so these event
8
+ * names and their payloads could NOT be verified against its types (see this
9
+ * package's README). They follow `@adonisjs/cache`'s documented `cache:*` event
10
+ * convention but should be treated as best-effort. The set is exported so a host
11
+ * can override it if a future version diverges.
12
+ */
13
+ export declare const CACHE_EVENTS: Record<string, CacheOperation>;
14
+ /** The normalized cache operation a recorded entry describes. */
15
+ export type CacheOperation = 'hit' | 'miss' | 'write' | 'delete' | 'clear';
16
+ /**
17
+ * The structural slice of a `@adonisjs/cache` event payload this watcher reads.
18
+ * Read defensively (every field optional) because the exact shape is owned by
19
+ * `@adonisjs/cache` and could not be verified here.
20
+ */
21
+ export interface CacheEventLike {
22
+ key?: string;
23
+ store?: string;
24
+ }
25
+ /** The recorded body of a `cache` entry. */
26
+ export interface CacheEntryContent {
27
+ /** The cache operation observed. */
28
+ operation: CacheOperation;
29
+ /** The cache key, or `null` when the event did not carry one. */
30
+ key: string | null;
31
+ /** The cache store name (e.g. `'redis'`), or `null`. */
32
+ store: string | null;
33
+ /** The active trace id at operation time, or `null`. */
34
+ traceId: string | null;
35
+ }
36
+ /**
37
+ * Records `@adonisjs/cache` activity as `cache` telescope entries — one per
38
+ * hit/miss/write/delete/clear event — correlated to the active request via the
39
+ * trace id.
40
+ *
41
+ * Recording is fire-and-forget and fully guarded: a telescope failure can never
42
+ * break a cache operation.
43
+ *
44
+ * @remarks
45
+ * The event-name → operation map ({@link CACHE_EVENTS}) is best-effort because
46
+ * `@adonisjs/cache` is not installed in this repo and its event contract could not
47
+ * be verified. Pass a custom map to the constructor to adapt to your version.
48
+ */
49
+ export declare class CacheWatcher implements Watcher {
50
+ readonly type: "cache";
51
+ private readonly events;
52
+ private readonly unsubscribes;
53
+ constructor(events?: Record<string, CacheOperation>);
54
+ start(emitter: EmitterLike): void;
55
+ stop(): void;
56
+ private handle;
57
+ }
58
+ /** Map a cache operation + payload to a telescope {@link RecordInput}. */
59
+ export declare function buildCacheEntry(operation: CacheOperation, event: CacheEventLike): RecordInput<CacheEntryContent>;
60
+ //# sourceMappingURL=cache_watcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache_watcher.d.ts","sourceRoot":"","sources":["../../../src/watchers/cache_watcher.ts"],"names":[],"mappings":"AACA,OAAO,EAAa,KAAK,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAGzD;;;;;;;;;GASG;AACH,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAMvD,CAAC;AAEF,iEAAiE;AACjE,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;AAE3E;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,4CAA4C;AAC5C,MAAM,WAAW,iBAAiB;IAChC,oCAAoC;IACpC,SAAS,EAAE,cAAc,CAAC;IAC1B,iEAAiE;IACjE,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,wDAAwD;IACxD,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,wDAAwD;IACxD,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED;;;;;;;;;;;;GAYG;AACH,qBAAa,YAAa,YAAW,OAAO;IAC1C,QAAQ,CAAC,IAAI,UAAmB;IAChC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiC;IACxD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAyB;gBAE1C,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAgB;IAIjE,KAAK,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI;IAOjC,IAAI,IAAI,IAAI;IAKZ,OAAO,CAAC,MAAM;CAIf;AAED,0EAA0E;AAC1E,wBAAgB,eAAe,CAC7B,SAAS,EAAE,cAAc,EACzB,KAAK,EAAE,cAAc,GACpB,WAAW,CAAC,iBAAiB,CAAC,CAYhC"}