@bakery-framework/plugin-analytics 2.0.0-alpha.1 → 2.0.0-alpha.12

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bakery-framework/plugin-analytics",
3
- "version": "2.0.0-alpha.1",
3
+ "version": "2.0.0-alpha.12",
4
4
  "description": "Bakery analytics plugin.",
5
5
  "keywords": [
6
6
  "bakery",
@@ -25,6 +25,7 @@
25
25
  "main": "./src/index.ts",
26
26
  "exports": {
27
27
  ".": "./src/index.ts",
28
+ "./setup": "./src/setup.ts",
28
29
  "./stats": "./src/endpoints/stats.ts",
29
30
  "./package.json": "./package.json"
30
31
  },
@@ -34,9 +35,9 @@
34
35
  "!src/tests"
35
36
  ],
36
37
  "dependencies": {
37
- "@bakery-framework/core": "^1.2.3"
38
+ "@bakery-framework/core": "^2.0.0-alpha.12"
38
39
  },
39
40
  "engines": {
40
- "bun": ">=1.3.14"
41
+ "bun": ">=1.4.0"
41
42
  }
42
43
  }
@@ -2,6 +2,7 @@ import { Bakery } from '@bakery-framework/core/core/bakery'
2
2
  import { Session } from '@bakery-framework/core/session'
3
3
  import type { JsonResponseData } from '@bakery-framework/core/utils/common'
4
4
  import {
5
+ type AuthorizeFn,
5
6
  requestHasCredential,
6
7
  response,
7
8
  } from '@bakery-framework/core/utils/http'
@@ -83,8 +84,12 @@ export type AnalyticsStats = ReturnType<typeof computeStats>
83
84
  * A request predicate, for apps that gate by their own roles rather than (or
84
85
  * as well as) a shared key. Returning `true` admits; throwing or returning
85
86
  * anything else denies (convention 2).
87
+ *
88
+ * Re-exported from core rather than declared here: the dashboard and
89
+ * db-explorer plugins need the same type, and three byte-identical copies of a
90
+ * security type drift the way the guards themselves already had.
86
91
  */
87
- export type AuthorizeFn = (req: Request) => boolean | Promise<boolean>
92
+ export type { AuthorizeFn } from '@bakery-framework/core/utils/http'
88
93
 
89
94
  /**
90
95
  * Analytics owns the auth for its endpoints, and the dashboard delegates to
package/src/index.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { definePlugin } from '@bakery-framework/core/plugins'
2
+ import { parsedUrl } from '@bakery-framework/core/utils/http'
2
3
  import { recordErrorPageHit, recordRouteHit } from './core'
3
4
 
4
5
  export {
@@ -52,7 +53,7 @@ export default function analyticsPlugin(options: AnalyticsPluginOptions = {}) {
52
53
  })
53
54
  },
54
55
  onRoute(req) {
55
- const url: URL = (req as any).__parsedUrl || new URL(req.url)
56
+ const url = parsedUrl(req)
56
57
  recordRouteHit(req.method, url.pathname, url.search)
57
58
  },
58
59
  onStart: async server => {
package/src/setup.ts CHANGED
@@ -187,14 +187,43 @@ export function handleAnalyticsRequest(
187
187
 
188
188
  let registered = false
189
189
 
190
- export function setupAnalytics(
191
- options: { credential?: string; authorize?: AuthorizeFn } = {},
192
- ) {
193
- // Auth is (re)applied every call — last config wins — so the dashboard
194
- // bringing analytics up with the shared key overrides a bare
195
- // `analyticsPlugin()`, whichever order they registered in.
196
- setAnalyticsCredential(options.credential)
197
- setAnalyticsAuthorize(options.authorize)
190
+ export interface AnalyticsAuthOptions {
191
+ credential?: string
192
+ authorize?: AuthorizeFn
193
+ }
194
+
195
+ /**
196
+ * The auth half of `setupAnalytics`, split out from the once-only half.
197
+ *
198
+ * Auth is (re)applied on every call — last config wins — so the dashboard
199
+ * bringing analytics up with the shared key overrides a bare
200
+ * `analyticsPlugin()`, whichever order they registered in.
201
+ *
202
+ * "Whichever order" is what the `!== undefined` buys, and it is the whole
203
+ * reason each option is applied conditionally rather than assigned straight
204
+ * through. Both plugins forward their options here and an application
205
+ * configures whichever of the two it thinks of as the console, so under a
206
+ * plain assignment the answer would depend on registration order: in
207
+ * `apps/example`, `analyticsPlugin({ credential })` runs after
208
+ * `dashboardPlugin({ authorize })` and would have wiped the predicate,
209
+ * shutting the console it was registered to open. A call that carries a value
210
+ * wins; a bare call is a no-op against auth rather than a silent disarm.
211
+ * Turning a door off means not registering the plugin, or passing the empty
212
+ * string — never omitting the option.
213
+ *
214
+ * It is separate, and exported, because `setupAnalytics` cannot be called from
215
+ * a test: it also registers two handlers, installs a shutdown hook and kicks
216
+ * off a data load, none of them restorable (convention 9).
217
+ */
218
+ export function applyAnalyticsAuth(options: AnalyticsAuthOptions): void {
219
+ if (options.credential !== undefined) {
220
+ setAnalyticsCredential(options.credential)
221
+ }
222
+ if (options.authorize !== undefined) setAnalyticsAuthorize(options.authorize)
223
+ }
224
+
225
+ export function setupAnalytics(options: AnalyticsAuthOptions = {}) {
226
+ applyAnalyticsAuth(options)
198
227
 
199
228
  // The rest runs once. Analytics is now a hard dependency of the dashboard,
200
229
  // so both may set it up in one process; the handler registrations are