@mongrov/analytics 0.6.0 → 0.7.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 (213) hide show
  1. package/README.md +23 -10
  2. package/UPGRADING.md +370 -0
  3. package/dist/core/device-events.d.ts +14 -0
  4. package/dist/core/device-events.d.ts.map +1 -0
  5. package/dist/core/device-events.js +13 -0
  6. package/dist/core/device-events.js.map +1 -0
  7. package/dist/core/errors.d.ts +1 -1
  8. package/dist/core/errors.d.ts.map +1 -1
  9. package/dist/core/errors.js.map +1 -1
  10. package/dist/core/extensions.d.ts +21 -4
  11. package/dist/core/extensions.d.ts.map +1 -1
  12. package/dist/core/extensions.js +21 -4
  13. package/dist/core/extensions.js.map +1 -1
  14. package/dist/core/factory.d.ts.map +1 -1
  15. package/dist/core/factory.js +125 -23
  16. package/dist/core/factory.js.map +1 -1
  17. package/dist/core/hooks.js +1 -1
  18. package/dist/core/hooks.js.map +1 -1
  19. package/dist/core/index.d.ts +11 -1
  20. package/dist/core/index.d.ts.map +1 -1
  21. package/dist/core/index.js +14 -0
  22. package/dist/core/index.js.map +1 -1
  23. package/dist/core/insight.d.ts +44 -0
  24. package/dist/core/insight.d.ts.map +1 -0
  25. package/dist/core/insight.js +62 -0
  26. package/dist/core/insight.js.map +1 -0
  27. package/dist/core/metric_metadata.d.ts +55 -0
  28. package/dist/core/metric_metadata.d.ts.map +1 -1
  29. package/dist/core/metric_metadata.js +35 -7
  30. package/dist/core/metric_metadata.js.map +1 -1
  31. package/dist/core/migrations.d.ts.map +1 -1
  32. package/dist/core/migrations.js +64 -2
  33. package/dist/core/migrations.js.map +1 -1
  34. package/dist/core/retention.d.ts +44 -13
  35. package/dist/core/retention.d.ts.map +1 -1
  36. package/dist/core/retention.js +49 -22
  37. package/dist/core/retention.js.map +1 -1
  38. package/dist/core/schemas.d.ts +73 -2
  39. package/dist/core/schemas.d.ts.map +1 -1
  40. package/dist/core/schemas.js +154 -3
  41. package/dist/core/schemas.js.map +1 -1
  42. package/dist/core/table_metadata.d.ts.map +1 -1
  43. package/dist/core/table_metadata.js +3 -0
  44. package/dist/core/table_metadata.js.map +1 -1
  45. package/dist/core/types.d.ts +45 -10
  46. package/dist/core/types.d.ts.map +1 -1
  47. package/dist/core/warehouse.d.ts +28 -0
  48. package/dist/core/warehouse.d.ts.map +1 -1
  49. package/dist/core/warehouse.js +44 -0
  50. package/dist/core/warehouse.js.map +1 -1
  51. package/dist/core/watermark-cache.d.ts +75 -0
  52. package/dist/core/watermark-cache.d.ts.map +1 -0
  53. package/dist/core/watermark-cache.js +0 -0
  54. package/dist/core/watermark-cache.js.map +1 -0
  55. package/dist/rules/__fakes__/fakeEngine.d.ts +2 -0
  56. package/dist/rules/__fakes__/fakeEngine.d.ts.map +1 -1
  57. package/dist/rules/__fakes__/fakeEngine.js +4 -0
  58. package/dist/rules/__fakes__/fakeEngine.js.map +1 -1
  59. package/dist/rules/baseline-reader.d.ts +55 -0
  60. package/dist/rules/baseline-reader.d.ts.map +1 -0
  61. package/dist/rules/baseline-reader.js +111 -0
  62. package/dist/rules/baseline-reader.js.map +1 -0
  63. package/dist/rules/compiler.d.ts +36 -1
  64. package/dist/rules/compiler.d.ts.map +1 -1
  65. package/dist/rules/compiler.js +185 -39
  66. package/dist/rules/compiler.js.map +1 -1
  67. package/dist/rules/defaults/luminx.d.ts.map +1 -1
  68. package/dist/rules/defaults/luminx.js +8 -0
  69. package/dist/rules/defaults/luminx.js.map +1 -1
  70. package/dist/rules/defaults/viva.d.ts.map +1 -1
  71. package/dist/rules/defaults/viva.js +7 -0
  72. package/dist/rules/defaults/viva.js.map +1 -1
  73. package/dist/rules/defaults/yogaring.d.ts.map +1 -1
  74. package/dist/rules/defaults/yogaring.js +7 -0
  75. package/dist/rules/defaults/yogaring.js.map +1 -1
  76. package/dist/rules/defaults/ziva.d.ts.map +1 -1
  77. package/dist/rules/defaults/ziva.js +100 -24
  78. package/dist/rules/defaults/ziva.js.map +1 -1
  79. package/dist/rules/evaluator.d.ts +14 -3
  80. package/dist/rules/evaluator.d.ts.map +1 -1
  81. package/dist/rules/evaluator.js +157 -5
  82. package/dist/rules/evaluator.js.map +1 -1
  83. package/dist/rules/factory.d.ts.map +1 -1
  84. package/dist/rules/factory.js +5 -1
  85. package/dist/rules/factory.js.map +1 -1
  86. package/dist/rules/index.d.ts +2 -1
  87. package/dist/rules/index.d.ts.map +1 -1
  88. package/dist/rules/index.js +2 -1
  89. package/dist/rules/index.js.map +1 -1
  90. package/dist/rules/schema.d.ts +75 -4
  91. package/dist/rules/schema.d.ts.map +1 -1
  92. package/dist/rules/schema.js +44 -0
  93. package/dist/rules/schema.js.map +1 -1
  94. package/dist/rules/types.d.ts +16 -1
  95. package/dist/rules/types.d.ts.map +1 -1
  96. package/dist/rules/validator.d.ts.map +1 -1
  97. package/dist/rules/validator.js +56 -0
  98. package/dist/rules/validator.js.map +1 -1
  99. package/dist/sync/baseline-compute.d.ts +63 -0
  100. package/dist/sync/baseline-compute.d.ts.map +1 -0
  101. package/dist/sync/baseline-compute.js +211 -0
  102. package/dist/sync/baseline-compute.js.map +1 -0
  103. package/dist/sync/events.d.ts +19 -5
  104. package/dist/sync/events.d.ts.map +1 -1
  105. package/dist/sync/events.js +17 -0
  106. package/dist/sync/events.js.map +1 -1
  107. package/dist/sync/factory.d.ts +25 -4
  108. package/dist/sync/factory.d.ts.map +1 -1
  109. package/dist/sync/factory.js +108 -15
  110. package/dist/sync/factory.js.map +1 -1
  111. package/dist/sync/fetcher.d.ts +15 -2
  112. package/dist/sync/fetcher.d.ts.map +1 -1
  113. package/dist/sync/fetcher.js +43 -7
  114. package/dist/sync/fetcher.js.map +1 -1
  115. package/dist/sync/flusher.d.ts +52 -2
  116. package/dist/sync/flusher.d.ts.map +1 -1
  117. package/dist/sync/flusher.js +78 -9
  118. package/dist/sync/flusher.js.map +1 -1
  119. package/dist/sync/index.d.ts +3 -1
  120. package/dist/sync/index.d.ts.map +1 -1
  121. package/dist/sync/index.js +1 -0
  122. package/dist/sync/index.js.map +1 -1
  123. package/dist/sync/mapper/activity.d.ts.map +1 -1
  124. package/dist/sync/mapper/activity.js +2 -1
  125. package/dist/sync/mapper/activity.js.map +1 -1
  126. package/dist/sync/mapper/ring-config.js +1 -1
  127. package/dist/sync/mapper/ring-config.js.map +1 -1
  128. package/dist/sync/mapper/schema.d.ts +411 -0
  129. package/dist/sync/mapper/schema.d.ts.map +1 -0
  130. package/dist/sync/mapper/schema.js +128 -0
  131. package/dist/sync/mapper/schema.js.map +1 -0
  132. package/dist/sync/mapper/sleep.d.ts +58 -13
  133. package/dist/sync/mapper/sleep.d.ts.map +1 -1
  134. package/dist/sync/mapper/sleep.js +141 -44
  135. package/dist/sync/mapper/sleep.js.map +1 -1
  136. package/dist/sync/mapper/types.d.ts +66 -10
  137. package/dist/sync/mapper/types.d.ts.map +1 -1
  138. package/dist/sync/scheduler.d.ts +7 -0
  139. package/dist/sync/scheduler.d.ts.map +1 -1
  140. package/dist/sync/scheduler.js +14 -0
  141. package/dist/sync/scheduler.js.map +1 -1
  142. package/dist/tools/__fakes__/engine.d.ts +2 -0
  143. package/dist/tools/__fakes__/engine.d.ts.map +1 -1
  144. package/dist/tools/__fakes__/engine.js +10 -0
  145. package/dist/tools/__fakes__/engine.js.map +1 -1
  146. package/dist/tools/authorize.d.ts +19 -12
  147. package/dist/tools/authorize.d.ts.map +1 -1
  148. package/dist/tools/authorize.js +31 -40
  149. package/dist/tools/authorize.js.map +1 -1
  150. package/dist/tools/factory.d.ts +2 -0
  151. package/dist/tools/factory.d.ts.map +1 -1
  152. package/dist/tools/factory.js +12 -1
  153. package/dist/tools/factory.js.map +1 -1
  154. package/dist/tools/formatters/copy-guidelines.d.ts +57 -0
  155. package/dist/tools/formatters/copy-guidelines.d.ts.map +1 -0
  156. package/dist/tools/formatters/copy-guidelines.js +110 -0
  157. package/dist/tools/formatters/copy-guidelines.js.map +1 -0
  158. package/dist/tools/formatters/index.d.ts +14 -0
  159. package/dist/tools/formatters/index.d.ts.map +1 -0
  160. package/dist/tools/formatters/index.js +14 -0
  161. package/dist/tools/formatters/index.js.map +1 -0
  162. package/dist/tools/formatters/spo2.d.ts +21 -0
  163. package/dist/tools/formatters/spo2.d.ts.map +1 -0
  164. package/dist/tools/formatters/spo2.js +79 -0
  165. package/dist/tools/formatters/spo2.js.map +1 -0
  166. package/dist/tools/{formatters.d.ts → formatters/text.d.ts} +1 -1
  167. package/dist/tools/formatters/text.d.ts.map +1 -0
  168. package/dist/tools/{formatters.js → formatters/text.js} +1 -1
  169. package/dist/tools/formatters/text.js.map +1 -0
  170. package/dist/tools/impls/activity.d.ts +2 -2
  171. package/dist/tools/impls/activity.js +7 -3
  172. package/dist/tools/impls/activity.js.map +1 -1
  173. package/dist/tools/impls/anomaly.d.ts +2 -2
  174. package/dist/tools/impls/anomaly.js +8 -4
  175. package/dist/tools/impls/anomaly.js.map +1 -1
  176. package/dist/tools/impls/compare.d.ts +2 -2
  177. package/dist/tools/impls/compare.js +8 -4
  178. package/dist/tools/impls/compare.js.map +1 -1
  179. package/dist/tools/impls/hrv.d.ts +2 -2
  180. package/dist/tools/impls/hrv.js +6 -2
  181. package/dist/tools/impls/hrv.js.map +1 -1
  182. package/dist/tools/impls/insights.d.ts +4 -4
  183. package/dist/tools/impls/insights.d.ts.map +1 -1
  184. package/dist/tools/impls/insights.js +10 -3
  185. package/dist/tools/impls/insights.js.map +1 -1
  186. package/dist/tools/impls/sleep.d.ts +2 -2
  187. package/dist/tools/impls/sleep.js +6 -2
  188. package/dist/tools/impls/sleep.js.map +1 -1
  189. package/dist/tools/impls/spo2.d.ts +52 -0
  190. package/dist/tools/impls/spo2.d.ts.map +1 -0
  191. package/dist/tools/impls/spo2.js +65 -0
  192. package/dist/tools/impls/spo2.js.map +1 -0
  193. package/dist/tools/index.d.ts +1 -0
  194. package/dist/tools/index.d.ts.map +1 -1
  195. package/dist/tools/index.js +4 -0
  196. package/dist/tools/index.js.map +1 -1
  197. package/dist/tools/mcp/guard.d.ts +28 -11
  198. package/dist/tools/mcp/guard.d.ts.map +1 -1
  199. package/dist/tools/mcp/guard.js +45 -15
  200. package/dist/tools/mcp/guard.js.map +1 -1
  201. package/dist/tools/mcp/index.d.ts +1 -1
  202. package/dist/tools/mcp/index.d.ts.map +1 -1
  203. package/dist/tools/mcp/index.js +1 -1
  204. package/dist/tools/mcp/index.js.map +1 -1
  205. package/dist/tools/mcp/server.d.ts.map +1 -1
  206. package/dist/tools/mcp/server.js +4 -0
  207. package/dist/tools/mcp/server.js.map +1 -1
  208. package/dist/tools/mcp/transports/http.d.ts.map +1 -1
  209. package/dist/tools/mcp/transports/http.js +4 -0
  210. package/dist/tools/mcp/transports/http.js.map +1 -1
  211. package/package.json +8 -5
  212. package/dist/tools/formatters.d.ts.map +0 -1
  213. package/dist/tools/formatters.js.map +0 -1
@@ -2,43 +2,98 @@
2
2
  * Sleep reconstruction mapper (T-06).
3
3
  *
4
4
  * Firmware `sleep_processed` emits per-block rows tagged with a `start`
5
- * (session start), `end`, `block_type` (primary / light / deep / rem / ...),
6
- * `confidence` (0..1), and per-block `timestamp` (block instant). Multiple
7
- * blocks share the same `start` when they belong to the same sleep session.
5
+ * (session start), `end` (session end), `block_type` (primary / light / deep /
6
+ * rem / awake), `confidence` (0..1), and per-block `timestamp` (block instant).
7
+ * Multiple blocks share the same `start` when they belong to the same session.
8
8
  *
9
9
  * Reconstruction rules (spec.md §Firmware mapper + tasks.md T-06):
10
10
  * - Group rows by `start`.
11
11
  * - A session is included if AT LEAST ONE block in the group has
12
12
  * `block_type === 'primary'` AND `confidence >= 0.7`. This filters
13
13
  * day-time naps and low-confidence noise.
14
- * - Session boundaries: `start_ts` = earliest block ts in the group;
15
- * `end_ts` = latest block ts + 1 minute (block ts marks start of the
16
- * 1-min block).
17
- * - `session_id` = stable hash of `user_id + start_ts.toISOString()`.
18
- * - `night_of` = 6pm-6pm rule applied to `start_ts` (see `time.ts`).
19
- * - Stages: one row per firmware block that passed the primary+confidence
20
- * filter, carrying `session_id`, `block_type`, and `confidence`.
21
- * - Raw: every input row is preserved verbatim in `sleep_raw` (payload
22
- * column) regardless of the primary/confidence filter, so downstream
23
- * reprocessing can revisit sessions with new heuristics.
14
+ * - Session boundaries come from the firmware's own envelope fields:
15
+ * `ts_start = parse(start)`, `ts_end = parse(end)`. `total_minutes` is
16
+ * their difference. Deriving the envelope from block instants would
17
+ * under-report any session whose first/last minutes went unclassified.
18
+ * - `session_id` = `nanoid(24) + '_' + fnv1a32hex(device_id | user_id |
19
+ * ts_session_start)` (principle 25, locked) collision-safe even with
20
+ * corrupted timestamps.
21
+ * - `night_of` = 6pm-6pm rule applied to `ts_start` (see `time.ts`).
22
+ * - Stages: one row per classified block, carrying `session_id` and the
23
+ * DDL's integer `stage` code. `primary` is the session envelope marker,
24
+ * not a stage, so it produces no `sleep_stage` row — the DDL's stage
25
+ * enum (1=awake, 2=light, 3=deep, 5=rem) has no code for it. Unknown
26
+ * block types are likewise skipped; nothing is lost, because...
27
+ * - Raw: every input row is preserved in `sleep_raw` regardless of the
28
+ * primary/confidence filter, flattened onto the DDL's columns, so
29
+ * downstream reprocessing can revisit sessions with new heuristics.
30
+ *
31
+ * Principle 20 boundary: firmware `block_type` strings are translated to our
32
+ * integer codes here and never reach the warehouse.
24
33
  */
34
+ import { nanoid } from 'nanoid';
25
35
  import { computeNightOf, parseTimestamp } from './time';
26
36
  const MINUTE_MS = 60000;
27
37
  const PRIMARY = 'primary';
28
38
  const CONFIDENCE_FLOOR = 0.7;
39
+ /**
40
+ * Block width in minutes when the firmware revision omits `unit_length`.
41
+ * Firmware doc §Sleep processing: blocks are 1-min wide by convention.
42
+ */
43
+ export const DEFAULT_BLOCK_MINUTES = 1;
44
+ /**
45
+ * Firmware `block_type` → `sleep_stage.stage` code (spec §Table schema:
46
+ * `stage SMALLINT NOT NULL -- 1=awake, 2=light, 3=deep, 5=rem`).
47
+ *
48
+ * `primary` is deliberately absent: it marks the session envelope, not a
49
+ * sleep stage. The enum is intentionally sparse (no 4) to match the DDL
50
+ * comment verbatim.
51
+ */
52
+ export const SLEEP_STAGE_CODES = Object.freeze({
53
+ awake: 1,
54
+ light: 2,
55
+ deep: 3,
56
+ rem: 5,
57
+ });
58
+ /** Reverse lookup for the stage-minute accumulator + diagnostics. */
59
+ export const SLEEP_STAGE_NAMES = Object.freeze({
60
+ 1: 'awake',
61
+ 2: 'light',
62
+ 3: 'deep',
63
+ 5: 'rem',
64
+ });
65
+ /** Per-block width, honouring a firmware-supplied `unit_length`. */
66
+ function blockMinutes(row) {
67
+ return typeof row.unit_length === 'number' && row.unit_length > 0
68
+ ? row.unit_length
69
+ : DEFAULT_BLOCK_MINUTES;
70
+ }
71
+ /**
72
+ * `sleep_raw.quality` is NOT NULL. Firmware revisions that carry a native
73
+ * `quality` pass it through verbatim; older revisions derive it from the
74
+ * block confidence (0..1 → 0..100) so the column is always populated.
75
+ */
76
+ function rawQuality(row) {
77
+ return typeof row.quality === 'number'
78
+ ? row.quality
79
+ : Math.round(row.confidence * 100);
80
+ }
29
81
  export function reconstructSleepSessions(rows, ctx) {
30
82
  const sleep_session = [];
31
83
  const sleep_stage = [];
32
84
  const sleep_raw = [];
33
- // Raw pass — all input rows preserved verbatim for reprocessing.
85
+ // Raw pass — every input row preserved for reprocessing, including rows
86
+ // from sessions the primary/confidence filter drops.
34
87
  for (const row of rows) {
35
88
  sleep_raw.push({
36
89
  ts: parseTimestamp(row.timestamp),
90
+ ts_session_start: parseTimestamp(row.start),
37
91
  brand: ctx.brand,
38
92
  family_id: ctx.familyId,
39
93
  user_id: ctx.userId,
40
94
  device_id: ctx.deviceId,
41
- payload: row,
95
+ quality: rawQuality(row),
96
+ unit_length: typeof row.unit_length === 'number' ? row.unit_length : null,
42
97
  });
43
98
  }
44
99
  // Group by `start`.
@@ -56,48 +111,90 @@ export function reconstructSleepSessions(rows, ctx) {
56
111
  const hasQualifyingPrimary = blocks.some(b => b.block_type === PRIMARY && b.confidence >= CONFIDENCE_FLOOR);
57
112
  if (!hasQualifyingPrimary)
58
113
  continue;
59
- const blockInstants = blocks.map(b => parseTimestamp(b.timestamp));
60
- const startTs = new Date(Math.min(...blockInstants.map(d => d.getTime())));
61
- // Sessions extend to the end of the last block (blocks are 1-min wide by
62
- // convention firmware doc §Sleep processing).
63
- const endTs = new Date(Math.max(...blockInstants.map(d => d.getTime())) + MINUTE_MS);
64
- const nightOf = computeNightOf(startTs, ctx.userTimezone);
65
- const sessionId = makeSessionId(ctx.userId, startTs);
66
- sleep_session.push({
67
- ts: startTs,
68
- brand: ctx.brand,
69
- family_id: ctx.familyId,
70
- user_id: ctx.userId,
71
- device_id: ctx.deviceId,
72
- session_id: sessionId,
73
- start_ts: startTs,
74
- end_ts: endTs,
75
- night_of: nightOf,
76
- });
77
- for (let i = 0; i < blocks.length; i++) {
78
- const b = blocks[i];
114
+ // Envelope from the firmware's own session fields. `end` is exclusive of
115
+ // nothing it is the session end instant, so total is a plain delta.
116
+ const tsStart = parseTimestamp(startKey);
117
+ const tsEnd = parseTimestamp(blocks[0].end);
118
+ const totalMinutes = Math.max(0, Math.round((tsEnd.getTime() - tsStart.getTime()) / MINUTE_MS));
119
+ const nightOf = computeNightOf(tsStart, ctx.userTimezone);
120
+ const sessionId = makeSessionId(ctx, tsStart);
121
+ // Stage rows + per-stage minute accumulation in one pass.
122
+ const stageMinutes = {
123
+ awake: 0,
124
+ light: 0,
125
+ deep: 0,
126
+ rem: 0,
127
+ };
128
+ let confidenceSum = 0;
129
+ for (const b of blocks) {
130
+ confidenceSum += b.confidence;
131
+ const code = SLEEP_STAGE_CODES[b.block_type];
132
+ if (code === undefined) {
133
+ // `primary` (envelope marker) and any unrecognised firmware block
134
+ // type. Not a stage — preserved in sleep_raw, skipped here.
135
+ continue;
136
+ }
137
+ stageMinutes[SLEEP_STAGE_NAMES[code]] += blockMinutes(b);
79
138
  sleep_stage.push({
80
- ts: blockInstants[i],
139
+ ts: parseTimestamp(b.timestamp),
81
140
  brand: ctx.brand,
82
141
  family_id: ctx.familyId,
83
142
  user_id: ctx.userId,
84
143
  device_id: ctx.deviceId,
85
144
  session_id: sessionId,
86
- stage: b.block_type,
145
+ stage: code,
87
146
  confidence: b.confidence,
88
147
  });
89
148
  }
90
- // Reference `startKey` to silence "unused" if TS ever tightens loop typing.
91
- void startKey;
149
+ sleep_session.push({
150
+ brand: ctx.brand,
151
+ family_id: ctx.familyId,
152
+ user_id: ctx.userId,
153
+ device_id: ctx.deviceId,
154
+ session_id: sessionId,
155
+ ts_start: tsStart,
156
+ ts_end: tsEnd,
157
+ total_minutes: totalMinutes,
158
+ deep_minutes: stageMinutes.deep,
159
+ rem_minutes: stageMinutes.rem,
160
+ light_minutes: stageMinutes.light,
161
+ awake_minutes: stageMinutes.awake,
162
+ avg_confidence: blocks.length > 0 ? confidenceSum / blocks.length : null,
163
+ night_of: nightOf,
164
+ });
92
165
  }
93
166
  return { sleep_session, sleep_stage, sleep_raw };
94
167
  }
95
168
  /**
96
- * Stable, non-cryptographic session id: `<userId>:<startIso>`. Deterministic
97
- * so re-imports don't produce duplicates; carries enough context to survive
98
- * cross-user joins without collision at the user's cardinality.
169
+ * Session id components (principle 25, locked):
170
+ * `nanoid(24) + '_' + fnv1a32hex(device_id | user_id | ts_session_start)`
171
+ *
172
+ * The random prefix makes ids collision-safe even when the firmware emits
173
+ * corrupted/duplicated timestamps; the hash suffix is deterministic over the
174
+ * identifying tuple so ids remain diagnosable (same device+user+start ⇒
175
+ * same suffix). The random source is injectable via `ctx.idGenerator` to
176
+ * keep the mapper testable — the suffix is always deterministic.
177
+ */
178
+ export function sessionIdComponents(ctx, tsSessionStart) {
179
+ const random = ctx.idGenerator ? ctx.idGenerator() : nanoid(24);
180
+ const hash = fnv1a32hex(`${ctx.deviceId}|${ctx.userId}|${tsSessionStart.toISOString()}`);
181
+ return { random, hash };
182
+ }
183
+ function makeSessionId(ctx, startTs) {
184
+ const { random, hash } = sessionIdComponents(ctx, startTs);
185
+ return `${random}_${hash}`;
186
+ }
187
+ /**
188
+ * FNV-1a 32-bit, hex-encoded (8 lowercase hex chars). Implemented inline —
189
+ * a dependency for 10 lines of arithmetic is not worth the supply-chain
190
+ * surface, and the mapper only needs a stable non-cryptographic digest.
99
191
  */
100
- function makeSessionId(userId, startTs) {
101
- return `${userId}:${startTs.toISOString()}`;
192
+ export function fnv1a32hex(input) {
193
+ let h = 0x811C9DC5;
194
+ for (let i = 0; i < input.length; i++) {
195
+ h ^= input.charCodeAt(i);
196
+ h = Math.imul(h, 0x01000193) >>> 0;
197
+ }
198
+ return h.toString(16).padStart(8, '0');
102
199
  }
103
200
  //# sourceMappingURL=sleep.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sleep.js","sourceRoot":"","sources":["../../../src/sync/mapper/sleep.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sleep.js","sourceRoot":"","sources":["../../../src/sync/mapper/sleep.ts"],"names":[],"mappings":"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"}
@@ -18,6 +18,13 @@ export interface MapperContext {
18
18
  deviceId: string;
19
19
  /** IANA timezone string, e.g. 'America/Los_Angeles'. */
20
20
  userTimezone: string;
21
+ /**
22
+ * Random-id source for session ids (principle 25). Defaults to
23
+ * `() => nanoid(24)`. Injectable so tests can keep the mapper
24
+ * deterministic — the hash suffix of a session id is always
25
+ * deterministic regardless of this generator.
26
+ */
27
+ idGenerator?: () => string;
21
28
  }
22
29
  export interface FirmwareHRVRow {
23
30
  timestamp: string;
@@ -54,6 +61,18 @@ export interface FirmwareSleepRow {
54
61
  block_type: string;
55
62
  confidence: number;
56
63
  timestamp: string;
64
+ /**
65
+ * Raw per-block quality score, when the firmware revision carries one.
66
+ * Passed through verbatim to `sleep_raw.quality`. Revisions that omit it
67
+ * fall back to `round(confidence * 100)` — see `mapper/sleep.ts`.
68
+ */
69
+ quality?: number;
70
+ /**
71
+ * Block width in minutes, when the firmware revision carries one.
72
+ * Passed through verbatim to `sleep_raw.unit_length`; drives stage-minute
73
+ * accumulation. Defaults to `DEFAULT_BLOCK_MINUTES` (1) when absent.
74
+ */
75
+ unit_length?: number;
57
76
  }
58
77
  export interface FirmwareBatteryRow {
59
78
  timestamp: string;
@@ -78,13 +97,21 @@ export interface FirmwareExport {
78
97
  battery_table: FirmwareBatteryRow[];
79
98
  ring: FirmwareRingConfig;
80
99
  }
81
- interface BaseRow {
82
- ts: Date;
100
+ /**
101
+ * Tenant columns every warehouse row carries (spec §Table schema —
102
+ * "every sensor row carries brand, family_id, user_id"). Split out from
103
+ * `BaseRow` because `sleep_session` has no `ts` column: its time axis is
104
+ * `ts_start` / `ts_end`.
105
+ */
106
+ interface TenantRow {
83
107
  brand: string;
84
108
  family_id: string;
85
109
  user_id: string;
86
110
  device_id: string;
87
111
  }
112
+ interface BaseRow extends TenantRow {
113
+ ts: Date;
114
+ }
88
115
  export interface HrvRow extends BaseRow {
89
116
  hrv_ms: number | null;
90
117
  stress: number | null;
@@ -104,24 +131,53 @@ export interface TemperatureRow extends BaseRow {
104
131
  export interface ActivityRow extends BaseRow {
105
132
  steps: number;
106
133
  }
134
+ /**
135
+ * `activity_bucket` warehouse row — 10-min calories/distance. Steps are NOT
136
+ * carried here: they live in `activity` at 1-min resolution after unnest
137
+ * (spec §Table schema). A `steps` field here would silently double-count.
138
+ */
107
139
  export interface ActivityBucketRow extends BaseRow {
108
- steps: number;
109
140
  calories: number;
110
141
  distance_km: number;
111
142
  }
112
- export interface SleepSessionRow extends BaseRow {
143
+ /**
144
+ * `sleep_session` warehouse row. Column names + nullability mirror the DDL
145
+ * in `core/schemas.ts` exactly, so `row[c]` keyed by
146
+ * `columnOrder.sleep_session` yields correct positional appender input.
147
+ *
148
+ * No `ts` — the DDL partitions on `day(ts_start)`.
149
+ */
150
+ export interface SleepSessionRow extends TenantRow {
113
151
  session_id: string;
114
- start_ts: Date;
115
- end_ts: Date;
152
+ ts_start: Date;
153
+ ts_end: Date;
154
+ total_minutes: number;
155
+ deep_minutes: number | null;
156
+ rem_minutes: number | null;
157
+ light_minutes: number | null;
158
+ awake_minutes: number | null;
159
+ avg_confidence: number | null;
116
160
  night_of: Date;
117
161
  }
162
+ /**
163
+ * `sleep_stage` warehouse row. `stage` is the DDL's integer code
164
+ * (`SLEEP_STAGE_CODES`), never the raw firmware `block_type` string —
165
+ * principle 20: firmware enums do not reach our schema.
166
+ */
118
167
  export interface SleepStageRow extends BaseRow {
119
168
  session_id: string;
120
- stage: string;
121
- confidence: number;
169
+ stage: number;
170
+ confidence: number | null;
122
171
  }
172
+ /**
173
+ * `sleep_raw` warehouse row (`collected_only`). Preserves each firmware
174
+ * block for reprocessing, flattened onto the DDL's columns rather than
175
+ * stashed as an opaque payload blob.
176
+ */
123
177
  export interface SleepRawRow extends BaseRow {
124
- payload: FirmwareSleepRow;
178
+ ts_session_start: Date;
179
+ quality: number;
180
+ unit_length: number | null;
125
181
  }
126
182
  export interface DeviceEventRow extends BaseRow {
127
183
  event_type: string;
@@ -144,7 +200,7 @@ export interface DeviceBatteryRow extends BaseRow {
144
200
  * (`data_type`, `start_time`, `end_time`, `weeks`) are produced by a
145
201
  * consumer-provided `RingConfigTranslator` (see below).
146
202
  */
147
- export interface DeviceConfigRow extends BaseRow {
203
+ export interface DeviceConfigRow extends TenantRow {
148
204
  data_type: number;
149
205
  interval_minutes: number;
150
206
  start_time: string | null;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/sync/mapper/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/sync/mapper/types.ts"],"names":[],"mappings":"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"}
@@ -43,6 +43,13 @@ export interface SyncCoordinator {
43
43
  fetchIncremental: (ctx: AttachContext) => Promise<Array<{
44
44
  ok: boolean;
45
45
  }>>;
46
+ /**
47
+ * Day-first baseline recompute (Sprint 5 T-15). Runs AFTER fetch so the
48
+ * quantiles see rows that just arrived from R2, not just locally-flushed
49
+ * ones — a baseline computed before the fetch would be short a day on
50
+ * every multi-device family. Optional; failures never fail the cycle.
51
+ */
52
+ computeBaselines?: () => Promise<void>;
46
53
  onCycleComplete?: () => Promise<void>;
47
54
  }
48
55
  /** Debug/info logger — matches `@mongrov/core` shape narrowly. */
@@ -1 +1 @@
1
- {"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../../src/sync/scheduler.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../../src/sync/scheduler.ts"],"names":[],"mappings":"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"}
@@ -98,6 +98,20 @@ _SyncScheduler_config = new WeakMap(), _SyncScheduler_state = new WeakMap(), _Sy
98
98
  await __classPrivateFieldGet(this, _SyncScheduler_config, "f").coordinator.pushAll(__classPrivateFieldGet(this, _SyncScheduler_config, "f").tables, __classPrivateFieldGet(this, _SyncScheduler_config, "f").ctx);
99
99
  await __classPrivateFieldGet(this, _SyncScheduler_config, "f").coordinator.pushClosesForDeviceConfig?.(__classPrivateFieldGet(this, _SyncScheduler_config, "f").ctx);
100
100
  await __classPrivateFieldGet(this, _SyncScheduler_config, "f").coordinator.fetchIncremental(__classPrivateFieldGet(this, _SyncScheduler_config, "f").ctx);
101
+ // Baselines are derived data — a failure here leaves the previous
102
+ // (still-valid) rows in place and must not mark the cycle failed,
103
+ // which would otherwise strand the scheduler in `error` and stop
104
+ // future flushes over a stale percentile.
105
+ if (__classPrivateFieldGet(this, _SyncScheduler_config, "f").coordinator.computeBaselines) {
106
+ try {
107
+ await __classPrivateFieldGet(this, _SyncScheduler_config, "f").coordinator.computeBaselines();
108
+ }
109
+ catch (cause) {
110
+ __classPrivateFieldGet(this, _SyncScheduler_config, "f").logger.warn('scheduler.cycle.baselines_failed', {
111
+ error: String(cause),
112
+ });
113
+ }
114
+ }
101
115
  await __classPrivateFieldGet(this, _SyncScheduler_config, "f").coordinator.onCycleComplete?.();
102
116
  __classPrivateFieldGet(this, _SyncScheduler_config, "f").logger.debug('scheduler.cycle.ok');
103
117
  __classPrivateFieldGet(this, _SyncScheduler_instances, "m", _SyncScheduler_setState).call(this, 'idle');
@@ -1 +1 @@
1
- {"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../../src/sync/scheduler.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../../src/sync/scheduler.ts"],"names":[],"mappings":"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"}
@@ -20,6 +20,8 @@ export interface FakeEngine extends AnalyticsEngine {
20
20
  }[];
21
21
  queueRows: (sqlSubstring: string, rows: unknown[]) => void;
22
22
  setError: (err: Error | null) => void;
23
+ /** Seed the roster returned by `getFamilyMembers()`. */
24
+ setFamilyMembers: (ids: string[]) => void;
23
25
  }
24
26
  export declare function createFakeEngine(): FakeEngine;
25
27
  //# sourceMappingURL=engine.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../../src/tools/__fakes__/engine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAEvD;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,UAAW,SAAQ,eAAe;IACjD,QAAQ,CAAC,KAAK,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,EAAE,CAAA;IAClE,SAAS,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAA;IAC1D,QAAQ,EAAE,CAAC,GAAG,EAAE,KAAK,GAAG,IAAI,KAAK,IAAI,CAAA;CACtC;AAED,wBAAgB,gBAAgB,IAAI,UAAU,CAmC7C"}
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../../src/tools/__fakes__/engine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAEvD;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,UAAW,SAAQ,eAAe;IACjD,QAAQ,CAAC,KAAK,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,EAAE,CAAA;IAClE,SAAS,EAAE,CAAC,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAA;IAC1D,QAAQ,EAAE,CAAC,GAAG,EAAE,KAAK,GAAG,IAAI,KAAK,IAAI,CAAA;IACrC,wDAAwD;IACxD,gBAAgB,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,IAAI,CAAA;CAC1C;AAED,wBAAgB,gBAAgB,IAAI,UAAU,CA4C7C"}
@@ -1,10 +1,19 @@
1
1
  export function createFakeEngine() {
2
2
  const queues = [];
3
+ let familyMembers = [];
3
4
  const calls = [];
4
5
  let error = null;
5
6
  const engine = {
6
7
  async attach() { },
7
8
  async detach() { },
9
+ async dismissInsight() { },
10
+ async getFamilyMembers() {
11
+ // Honour `setError` so fail-closed tests exercise a real throw from
12
+ // the membership path, not an incidental empty roster.
13
+ if (error)
14
+ throw error;
15
+ return familyMembers;
16
+ },
8
17
  async execute(sql, params) {
9
18
  calls.push({ sql, params: params ?? {} });
10
19
  if (error)
@@ -32,6 +41,7 @@ export function createFakeEngine() {
32
41
  calls,
33
42
  queueRows(substring, rows) { queues.push({ substring, rows }); },
34
43
  setError(err) { error = err; },
44
+ setFamilyMembers(ids) { familyMembers = ids; },
35
45
  };
36
46
  return engine;
37
47
  }
@@ -1 +1 @@
1
- {"version":3,"file":"engine.js","sourceRoot":"","sources":["../../../src/tools/__fakes__/engine.ts"],"names":[],"mappings":"AAsBA,MAAM,UAAU,gBAAgB;IAC9B,MAAM,MAAM,GAA6C,EAAE,CAAA;IAC3D,MAAM,KAAK,GAAuD,EAAE,CAAA;IACpE,IAAI,KAAK,GAAiB,IAAI,CAAA;IAE9B,MAAM,MAAM,GAAe;QACzB,KAAK,CAAC,MAAM,KAAI,CAAC;QACjB,KAAK,CAAC,MAAM,KAAI,CAAC;QACjB,KAAK,CAAC,OAAO,CAAI,GAAW,EAAE,MAAgC;YAC5D,KAAK,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,IAAI,EAAE,EAAE,CAAC,CAAA;YACzC,IAAI,KAAK;gBAAE,MAAM,KAAK,CAAA;YACtB,MAAM,GAAG,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAA;YAC5D,IAAI,GAAG,KAAK,CAAC,CAAC;gBAAE,OAAO,EAAS,CAAA;YAChC,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAA;YACjC,OAAO,CAAC,CAAC,IAAW,CAAA;QACtB,CAAC;QACD,MAAM;YACJ,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAA;QACnD,CAAC;QACD,cAAc;YACZ,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAA;QAC3D,CAAC;QACD,KAAK,EAAE,UAAU;QACjB,SAAS,EAAE,IAAI;QACf,OAAO,EAAE,MAAM;QACf,IAAI,EAAE,IAAI;QACV,SAAS,EAAE,GAAG,EAAE,CAAC,GAAG,EAAE,GAAE,CAAC;QACzB,KAAK,CAAC,YAAY,KAAI,CAAC;QACvB,KAAK,CAAC,aAAa,KAAK,OAAO,IAAI,CAAA,CAAC,CAAC;QACrC,KAAK,CAAC,KAAK,KAAI,CAAC;QAChB,KAAK;QACL,SAAS,CAAC,SAAS,EAAE,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA,CAAC,CAAC;QAC/D,QAAQ,CAAC,GAAG,IAAI,KAAK,GAAG,GAAG,CAAA,CAAC,CAAC;KAC9B,CAAA;IACD,OAAO,MAAM,CAAA;AACf,CAAC"}
1
+ {"version":3,"file":"engine.js","sourceRoot":"","sources":["../../../src/tools/__fakes__/engine.ts"],"names":[],"mappings":"AAwBA,MAAM,UAAU,gBAAgB;IAC9B,MAAM,MAAM,GAA6C,EAAE,CAAA;IAC3D,IAAI,aAAa,GAAa,EAAE,CAAA;IAChC,MAAM,KAAK,GAAuD,EAAE,CAAA;IACpE,IAAI,KAAK,GAAiB,IAAI,CAAA;IAE9B,MAAM,MAAM,GAAe;QACzB,KAAK,CAAC,MAAM,KAAI,CAAC;QACjB,KAAK,CAAC,MAAM,KAAI,CAAC;QACjB,KAAK,CAAC,cAAc,KAAI,CAAC;QACzB,KAAK,CAAC,gBAAgB;YACpB,oEAAoE;YACpE,uDAAuD;YACvD,IAAI,KAAK;gBAAE,MAAM,KAAK,CAAA;YACtB,OAAO,aAAa,CAAA;QACtB,CAAC;QACD,KAAK,CAAC,OAAO,CAAI,GAAW,EAAE,MAAgC;YAC5D,KAAK,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,IAAI,EAAE,EAAE,CAAC,CAAA;YACzC,IAAI,KAAK;gBAAE,MAAM,KAAK,CAAA;YACtB,MAAM,GAAG,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAA;YAC5D,IAAI,GAAG,KAAK,CAAC,CAAC;gBAAE,OAAO,EAAS,CAAA;YAChC,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAA;YACjC,OAAO,CAAC,CAAC,IAAW,CAAA;QACtB,CAAC;QACD,MAAM;YACJ,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAA;QACnD,CAAC;QACD,cAAc;YACZ,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAA;QAC3D,CAAC;QACD,KAAK,EAAE,UAAU;QACjB,SAAS,EAAE,IAAI;QACf,OAAO,EAAE,MAAM;QACf,IAAI,EAAE,IAAI;QACV,SAAS,EAAE,GAAG,EAAE,CAAC,GAAG,EAAE,GAAE,CAAC;QACzB,KAAK,CAAC,YAAY,KAAI,CAAC;QACvB,KAAK,CAAC,aAAa,KAAK,OAAO,IAAI,CAAA,CAAC,CAAC;QACrC,KAAK,CAAC,KAAK,KAAI,CAAC;QAChB,KAAK;QACL,SAAS,CAAC,SAAS,EAAE,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA,CAAC,CAAC;QAC/D,QAAQ,CAAC,GAAG,IAAI,KAAK,GAAG,GAAG,CAAA,CAAC,CAAC;QAC7B,gBAAgB,CAAC,GAAG,IAAI,aAAa,GAAG,GAAG,CAAA,CAAC,CAAC;KAC9C,CAAA;IACD,OAAO,MAAM,CAAA;AACf,CAAC"}
@@ -3,10 +3,20 @@
3
3
  *
4
4
  * `familyScopeAuthorize` — grants access iff `args.userId` is either
5
5
  * the requester themselves or another member of the requester's
6
- * family. When `config.familyMembersProvider` is supplied (the
7
- * factory path since T-11), membership resolves via that provider;
8
- * otherwise the legacy SQL path against a `family_member` table is
9
- * used (kept for standalone hook usage and backwards compat).
6
+ * family.
7
+ *
8
+ * Membership always resolves through the engine's configured
9
+ * `FamilyMembersProvider` (principle 39 "Rules engine and AI tools
10
+ * share the same source of truth"): an explicitly-passed
11
+ * `config.familyMembersProvider` wins, otherwise `analytics
12
+ * .getFamilyMembers()` delegates to the one wired at `createAnalytics`.
13
+ *
14
+ * There is deliberately no SQL fallback. The spec's illustrative
15
+ * `SELECT 1 FROM family_member ...` referenced a table that no DDL in
16
+ * this package ever creates, so that path could only ever throw and
17
+ * fail closed — silently denying every cross-member query on any
18
+ * install that didn't pass a provider. Membership lives in the RxDB
19
+ * Family doc, not in DuckDB.
10
20
  *
11
21
  * Both hooks fail closed on any error — provider throws, engine
12
22
  * throws, missing/malformed args — return `false` rather than
@@ -23,14 +33,11 @@ export interface AuthorizeConfig {
23
33
  }
24
34
  export declare function familyScopeAuthorize(analytics: AnalyticsEngine, config?: AuthorizeConfig): AuthorizeFn;
25
35
  /**
26
- * `orgScopeAuthorize` — parity with family scope but against an
27
- * `org_member` table. Orgs are not first-class in v0.1.0; the ctx
28
- * `familyId` is treated as the org id until org membership is wired
29
- * through `RequestContext`.
30
- *
31
- * When `familyMembersProvider` is supplied, the same provider is
32
- * consulted (v0.1.0 shim — a dedicated `orgMembersProvider` will
33
- * split out once orgs land).
36
+ * `orgScopeAuthorize` — parity with family scope. Orgs are not
37
+ * first-class in v0.1.0; the ctx `familyId` is treated as the org id
38
+ * until org membership is wired through `RequestContext`, and the same
39
+ * membership provider is consulted (v0.1.0 shim — a dedicated
40
+ * `orgMembersProvider` splits out once orgs land).
34
41
  */
35
42
  export declare function orgScopeAuthorize(analytics: AnalyticsEngine, config?: AuthorizeConfig): AuthorizeFn;
36
43
  //# sourceMappingURL=authorize.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"authorize.d.ts","sourceRoot":"","sources":["../../src/tools/authorize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAA;AAC3E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAE1C,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,qBAAqB,CAAC,EAAE,qBAAqB,CAAA;CAC9C;AAED,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,eAAe,EAC1B,MAAM,GAAE,eAAoB,GAC3B,WAAW,CAmCb;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,eAAe,EAC1B,MAAM,GAAE,eAAoB,GAC3B,WAAW,CAmCb"}
1
+ {"version":3,"file":"authorize.d.ts","sourceRoot":"","sources":["../../src/tools/authorize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAA;AAC3E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AAE1C,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,qBAAqB,CAAC,EAAE,qBAAqB,CAAA;CAC9C;AAED,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,eAAe,EAC1B,MAAM,GAAE,eAAoB,GAC3B,WAAW,CAuBb;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,eAAe,EAC1B,MAAM,GAAE,eAAoB,GAC3B,WAAW,CAuBb"}