hazo_notify 5.2.1 → 6.0.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 (86) hide show
  1. package/README.md +38 -6
  2. package/config/hazo_notify_config.ini +5 -0
  3. package/dist/lib/adapters/email/config.d.ts.map +1 -1
  4. package/dist/lib/adapters/email/config.js +7 -6
  5. package/dist/lib/adapters/email/config.js.map +1 -1
  6. package/dist/lib/adapters/email/providers/zeptomail_provider.d.ts.map +1 -1
  7. package/dist/lib/adapters/email/providers/zeptomail_provider.js +11 -19
  8. package/dist/lib/adapters/email/providers/zeptomail_provider.js.map +1 -1
  9. package/dist/lib/adapters/email/utils/logger.d.ts +4 -11
  10. package/dist/lib/adapters/email/utils/logger.d.ts.map +1 -1
  11. package/dist/lib/adapters/email/utils/logger.js +11 -53
  12. package/dist/lib/adapters/email/utils/logger.js.map +1 -1
  13. package/dist/lib/adapters/telegram/config.d.ts.map +1 -1
  14. package/dist/lib/adapters/telegram/config.js +5 -4
  15. package/dist/lib/adapters/telegram/config.js.map +1 -1
  16. package/dist/lib/adapters/telegram/transport.d.ts.map +1 -1
  17. package/dist/lib/adapters/telegram/transport.js +2 -1
  18. package/dist/lib/adapters/telegram/transport.js.map +1 -1
  19. package/dist/lib/config/hazo_notify_config.d.ts +45 -0
  20. package/dist/lib/config/hazo_notify_config.d.ts.map +1 -0
  21. package/dist/lib/config/hazo_notify_config.js +82 -0
  22. package/dist/lib/config/hazo_notify_config.js.map +1 -0
  23. package/dist/lib/dispatcher/batch-key.js +2 -2
  24. package/dist/lib/dispatcher/batch-key.js.map +1 -1
  25. package/dist/lib/dispatcher/index.d.ts.map +1 -1
  26. package/dist/lib/dispatcher/index.js +6 -3
  27. package/dist/lib/dispatcher/index.js.map +1 -1
  28. package/dist/lib/errors.d.ts +30 -0
  29. package/dist/lib/errors.d.ts.map +1 -0
  30. package/dist/lib/errors.js +57 -0
  31. package/dist/lib/errors.js.map +1 -0
  32. package/dist/lib/inbox/connection.d.ts.map +1 -1
  33. package/dist/lib/inbox/connection.js +4 -3
  34. package/dist/lib/inbox/connection.js.map +1 -1
  35. package/dist/lib/inbox/storage.d.ts.map +1 -1
  36. package/dist/lib/inbox/storage.js +4 -3
  37. package/dist/lib/inbox/storage.js.map +1 -1
  38. package/dist/lib/inbox/types.d.ts +3 -1
  39. package/dist/lib/inbox/types.d.ts.map +1 -1
  40. package/dist/lib/inbox/worker/flush.d.ts.map +1 -1
  41. package/dist/lib/inbox/worker/flush.js +56 -50
  42. package/dist/lib/inbox/worker/flush.js.map +1 -1
  43. package/dist/lib/inbox/worker/render.d.ts.map +1 -1
  44. package/dist/lib/inbox/worker/render.js +2 -1
  45. package/dist/lib/inbox/worker/render.js.map +1 -1
  46. package/dist/lib/jobs/digest.d.ts +77 -0
  47. package/dist/lib/jobs/digest.d.ts.map +1 -0
  48. package/dist/lib/jobs/digest.js +127 -0
  49. package/dist/lib/jobs/digest.js.map +1 -0
  50. package/dist/lib/jobs/handler.d.ts.map +1 -1
  51. package/dist/lib/jobs/handler.js +23 -18
  52. package/dist/lib/jobs/handler.js.map +1 -1
  53. package/dist/lib/jobs/index.d.ts +2 -0
  54. package/dist/lib/jobs/index.d.ts.map +1 -1
  55. package/dist/lib/jobs/index.js +1 -0
  56. package/dist/lib/jobs/index.js.map +1 -1
  57. package/dist/lib/lifecycle/default_templates.d.ts.map +1 -1
  58. package/dist/lib/lifecycle/default_templates.js +36 -0
  59. package/dist/lib/lifecycle/default_templates.js.map +1 -1
  60. package/dist/lib/lifecycle/dispatch.d.ts.map +1 -1
  61. package/dist/lib/lifecycle/dispatch.js +2 -1
  62. package/dist/lib/lifecycle/dispatch.js.map +1 -1
  63. package/dist/lib/lifecycle/handler.d.ts.map +1 -1
  64. package/dist/lib/lifecycle/handler.js +103 -97
  65. package/dist/lib/lifecycle/handler.js.map +1 -1
  66. package/dist/lib/lifecycle/scheduler.d.ts.map +1 -1
  67. package/dist/lib/lifecycle/scheduler.js +2 -1
  68. package/dist/lib/lifecycle/scheduler.js.map +1 -1
  69. package/dist/lib/logger.d.ts +2 -0
  70. package/dist/lib/logger.d.ts.map +1 -0
  71. package/dist/lib/logger.js +3 -0
  72. package/dist/lib/logger.js.map +1 -0
  73. package/dist/lib/preferences/storage.d.ts.map +1 -1
  74. package/dist/lib/preferences/storage.js +7 -2
  75. package/dist/lib/preferences/storage.js.map +1 -1
  76. package/dist/lib/preferences/types.d.ts +1 -1
  77. package/dist/lib/preferences/types.d.ts.map +1 -1
  78. package/dist/lib/utils.d.ts +1 -2
  79. package/dist/lib/utils.d.ts.map +1 -1
  80. package/dist/lib/utils.js +1 -5
  81. package/dist/lib/utils.js.map +1 -1
  82. package/migrations/011_digest_status.pg.sql +21 -0
  83. package/migrations/011_digest_status.sqlite.sql +43 -0
  84. package/migrations/012_preferences_digest.pg.sql +12 -0
  85. package/migrations/012_preferences_digest.sqlite.sql +51 -0
  86. package/package.json +20 -9
@@ -8,7 +8,9 @@
8
8
  * @packageDocumentation
9
9
  */
10
10
  import { createHash } from 'node:crypto';
11
+ import { withContext, getContext } from 'hazo_core';
11
12
  import { evaluateConditions } from './resolver.js';
13
+ import { NotifySequenceNotFoundError, NotifyStepNotFoundError } from '../errors.js';
12
14
  import { dispatchStep } from './dispatch.js';
13
15
  import { loadStatusRow, updateStatusRow } from './status.js';
14
16
  /**
@@ -31,115 +33,119 @@ import { loadStatusRow, updateStatusRow } from './status.js';
31
33
  export function createLifecycleStepHandler(opts, get_user_email) {
32
34
  const max_attempts = opts.max_attempts ?? 3;
33
35
  return async function lifecycle_step_handler(job, log) {
34
- // hazo_jobs (SQLite backend) may deliver payload as a JSON string.
35
- const payload = typeof job.payload === 'string'
36
- ? JSON.parse(job.payload)
37
- : job.payload;
38
- const { status_row_id, user_id, sequence_id, step_id } = payload;
39
- log?.info?.(`[lifecycle] step start row=${status_row_id} user=${user_id} seq=${sequence_id} step=${step_id}`);
40
- // 1. Load the status row.
41
- const row = await loadStatusRow(opts.hazo_connect, status_row_id);
42
- // 2. Guard: already processed or gone.
43
- if (!row || row.status !== 'scheduled') {
44
- log?.info?.(`[lifecycle] step skip (already handled) row=${status_row_id} status=${row?.status ?? 'not_found'}`);
45
- return;
46
- }
47
- // 3. Increment attempt counter.
48
- const attempt_count = row.attempt_count + 1;
49
- try {
50
- // 4. Opt-out check.
51
- if (opts.is_opted_out) {
52
- const opted_out = await opts.is_opted_out(user_id);
53
- if (opted_out) {
36
+ const correlationId = getContext()?.correlationId
37
+ ?? `notify_lifecycle_${job.id}`;
38
+ return withContext({ correlationId }, async () => {
39
+ // hazo_jobs (SQLite backend) may deliver payload as a JSON string.
40
+ const payload = typeof job.payload === 'string'
41
+ ? JSON.parse(job.payload)
42
+ : job.payload;
43
+ const { status_row_id, user_id, sequence_id, step_id } = payload;
44
+ log?.info?.(`[lifecycle] step start row=${status_row_id} user=${user_id} seq=${sequence_id} step=${step_id}`);
45
+ // 1. Load the status row.
46
+ const row = await loadStatusRow(opts.hazo_connect, status_row_id);
47
+ // 2. Guard: already processed or gone.
48
+ if (!row || row.status !== 'scheduled') {
49
+ log?.info?.(`[lifecycle] step skip (already handled) row=${status_row_id} status=${row?.status ?? 'not_found'}`);
50
+ return;
51
+ }
52
+ // 3. Increment attempt counter.
53
+ const attempt_count = row.attempt_count + 1;
54
+ try {
55
+ // 4. Opt-out check.
56
+ if (opts.is_opted_out) {
57
+ const opted_out = await opts.is_opted_out(user_id);
58
+ if (opted_out) {
59
+ await updateStatusRow(opts.hazo_connect, status_row_id, {
60
+ status: 'skipped',
61
+ skip_reason: 'opted_out',
62
+ attempt_count,
63
+ });
64
+ log?.info?.(`[lifecycle] step skipped (opted_out) row=${status_row_id}`);
65
+ return;
66
+ }
67
+ }
68
+ // 5. Locate the step definition.
69
+ const sequence = opts.sequences[sequence_id];
70
+ if (!sequence) {
71
+ throw new NotifySequenceNotFoundError(sequence_id);
72
+ }
73
+ const step = sequence.find((s) => s.id === step_id);
74
+ if (!step) {
75
+ throw new NotifyStepNotFoundError(sequence_id, step_id);
76
+ }
77
+ // 6. Evaluate conditions.
78
+ const condition_result = await evaluateConditions(step.conditions, opts.resolvers, user_id);
79
+ if (!condition_result.pass) {
80
+ const skip_reason = `condition_failed:${condition_result.reason ?? 'unknown'}`;
54
81
  await updateStatusRow(opts.hazo_connect, status_row_id, {
55
82
  status: 'skipped',
56
- skip_reason: 'opted_out',
83
+ skip_reason,
57
84
  attempt_count,
58
85
  });
59
- log?.info?.(`[lifecycle] step skipped (opted_out) row=${status_row_id}`);
86
+ log?.info?.(`[lifecycle] step skipped row=${status_row_id} reason=${skip_reason}`);
60
87
  return;
61
88
  }
62
- }
63
- // 5. Locate the step definition.
64
- const sequence = opts.sequences[sequence_id];
65
- if (!sequence) {
66
- throw new Error(`sequence_not_found:${sequence_id}`);
67
- }
68
- const step = sequence.find((s) => s.id === step_id);
69
- if (!step) {
70
- throw new Error(`step_not_found:${sequence_id}/${step_id}`);
71
- }
72
- // 6. Evaluate conditions.
73
- const condition_result = await evaluateConditions(step.conditions, opts.resolvers, user_id);
74
- if (!condition_result.pass) {
75
- const skip_reason = `condition_failed:${condition_result.reason ?? 'unknown'}`;
76
- await updateStatusRow(opts.hazo_connect, status_row_id, {
77
- status: 'skipped',
78
- skip_reason,
79
- attempt_count,
89
+ // 7. Resolve recipient email address.
90
+ const to = await get_user_email(user_id);
91
+ // 8. Resolve extra template variables (e.g. opt-out link, A/B subjects).
92
+ const raw_vars = opts.get_variables
93
+ ? await opts.get_variables(user_id, step_id)
94
+ : {};
95
+ // 8a. A/B subject selection: if both subject_a and subject_b are provided,
96
+ // pick one deterministically by hashing user_id + template_name.
97
+ // Remove both from template variables so they don't appear in the body.
98
+ let subject_override;
99
+ let ab_variant;
100
+ const { subject_a, subject_b, ...extra_vars } = raw_vars;
101
+ if (subject_a && subject_b) {
102
+ const hash_byte = createHash('sha256')
103
+ .update(user_id + step.template)
104
+ .digest()[0];
105
+ ab_variant = (hash_byte & 1) === 0 ? 'a' : 'b';
106
+ subject_override = ab_variant === 'a' ? subject_a : subject_b;
107
+ }
108
+ // 9. Dispatch the email.
109
+ await dispatchStep({
110
+ hazo_connect: opts.hazo_connect,
111
+ user_id,
112
+ template_name: step.template,
113
+ variables: extra_vars,
114
+ to,
115
+ locale: opts.default_locale ?? null,
116
+ subject_override,
80
117
  });
81
- log?.info?.(`[lifecycle] step skipped row=${status_row_id} reason=${skip_reason}`);
82
- return;
83
- }
84
- // 7. Resolve recipient email address.
85
- const to = await get_user_email(user_id);
86
- // 8. Resolve extra template variables (e.g. opt-out link, A/B subjects).
87
- const raw_vars = opts.get_variables
88
- ? await opts.get_variables(user_id, step_id)
89
- : {};
90
- // 8a. A/B subject selection: if both subject_a and subject_b are provided,
91
- // pick one deterministically by hashing user_id + template_name.
92
- // Remove both from template variables so they don't appear in the body.
93
- let subject_override;
94
- let ab_variant;
95
- const { subject_a, subject_b, ...extra_vars } = raw_vars;
96
- if (subject_a && subject_b) {
97
- const hash_byte = createHash('sha256')
98
- .update(user_id + step.template)
99
- .digest()[0];
100
- ab_variant = (hash_byte & 1) === 0 ? 'a' : 'b';
101
- subject_override = ab_variant === 'a' ? subject_a : subject_b;
102
- }
103
- // 9. Dispatch the email.
104
- await dispatchStep({
105
- hazo_connect: opts.hazo_connect,
106
- user_id,
107
- template_name: step.template,
108
- variables: extra_vars,
109
- to,
110
- locale: opts.default_locale ?? null,
111
- subject_override,
112
- });
113
- // 10. Mark as sent (include dispatch_meta for A/B tracking).
114
- await updateStatusRow(opts.hazo_connect, status_row_id, {
115
- status: 'sent',
116
- sent_at: new Date().toISOString(),
117
- attempt_count,
118
- ...(ab_variant
119
- ? { dispatch_meta: { ab_variant, subject: subject_override } }
120
- : {}),
121
- });
122
- log?.info?.(`[lifecycle] step sent row=${status_row_id} template=${step.template}`);
123
- }
124
- catch (err) {
125
- const msg = err instanceof Error ? err.message : String(err);
126
- log?.error?.(`[lifecycle] step error row=${status_row_id} err=${msg}`);
127
- if (attempt_count >= max_attempts) {
118
+ // 10. Mark as sent (include dispatch_meta for A/B tracking).
128
119
  await updateStatusRow(opts.hazo_connect, status_row_id, {
129
- status: 'failed',
130
- failure_message: msg,
120
+ status: 'sent',
121
+ sent_at: new Date().toISOString(),
131
122
  attempt_count,
123
+ ...(ab_variant
124
+ ? { dispatch_meta: { ab_variant, subject: subject_override } }
125
+ : {}),
132
126
  });
133
- log?.error?.(`[lifecycle] step failed permanently row=${status_row_id}`);
127
+ log?.info?.(`[lifecycle] step sent row=${status_row_id} template=${step.template}`);
134
128
  }
135
- else {
136
- // Leave status as 'scheduled' so hazo_jobs retries the job.
137
- await updateStatusRow(opts.hazo_connect, status_row_id, {
138
- attempt_count,
139
- failure_message: msg,
140
- });
129
+ catch (err) {
130
+ const msg = err instanceof Error ? err.message : String(err);
131
+ log?.error?.(`[lifecycle] step error row=${status_row_id} err=${msg}`);
132
+ if (attempt_count >= max_attempts) {
133
+ await updateStatusRow(opts.hazo_connect, status_row_id, {
134
+ status: 'failed',
135
+ failure_message: msg,
136
+ attempt_count,
137
+ });
138
+ log?.error?.(`[lifecycle] step failed permanently row=${status_row_id}`);
139
+ }
140
+ else {
141
+ // Leave status as 'scheduled' so hazo_jobs retries the job.
142
+ await updateStatusRow(opts.hazo_connect, status_row_id, {
143
+ attempt_count,
144
+ failure_message: msg,
145
+ });
146
+ }
141
147
  }
142
- }
148
+ });
143
149
  };
144
150
  }
145
151
  //# sourceMappingURL=handler.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"handler.js","sourceRoot":"","sources":["../../../src/lib/lifecycle/handler.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"handler.js","sourceRoot":"","sources":["../../../src/lib/lifecycle/handler.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../../../src/lib/lifecycle/scheduler.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,OAAO,KAAK,EACV,kBAAkB,EAClB,yBAAyB,EAE1B,MAAM,YAAY,CAAC;AAEpB;;;GAGG;AACH,eAAO,MAAM,uBAAuB,+BAA+B,CAAC;AAcpE;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,yBAAyB,EAC/B,cAAc,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,GACnD,kBAAkB,CAmGpB"}
1
+ {"version":3,"file":"scheduler.d.ts","sourceRoot":"","sources":["../../../src/lib/lifecycle/scheduler.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAMH,OAAO,KAAK,EACV,kBAAkB,EAClB,yBAAyB,EAE1B,MAAM,YAAY,CAAC;AAEpB;;;GAGG;AACH,eAAO,MAAM,uBAAuB,+BAA+B,CAAC;AAcpE;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,CACtC,IAAI,EAAE,yBAAyB,EAC/B,cAAc,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,GACnD,kBAAkB,CAiGpB"}
@@ -10,6 +10,7 @@
10
10
  import { insertStatusRow, queryStatusRows } from './status.js';
11
11
  import { recordEvent as _recordEvent } from './events.js';
12
12
  import { createLifecycleStepHandler } from './handler.js';
13
+ import { NotifySequenceNotFoundError } from '../errors.js';
13
14
  /**
14
15
  * Job type string registered with hazo_jobs for deferred lifecycle steps.
15
16
  * Re-exported from `hazo_notify/lifecycle` for consumer use.
@@ -41,7 +42,7 @@ export function createLifecycleScheduler(opts, get_user_email) {
41
42
  async function start({ user_id, sequence_id, }) {
42
43
  const steps = opts.sequences[sequence_id];
43
44
  if (!steps) {
44
- throw new Error(`[lifecycle] sequence not found: '${sequence_id}'`);
45
+ throw new NotifySequenceNotFoundError(sequence_id);
45
46
  }
46
47
  const now = new Date();
47
48
  for (const step of steps) {
@@ -1 +1 @@
1
- {"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../../../src/lib/lifecycle/scheduler.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../../../src/lib/lifecycle/scheduler.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC/D,OAAO,EAAE,WAAW,IAAI,YAAY,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,EAAE,0BAA0B,EAAE,MAAM,cAAc,CAAC;AAC1D,OAAO,EAAE,2BAA2B,EAAE,MAAM,cAAc,CAAC;AAO3D;;;GAGG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,4BAA4B,CAAC;AAEpE;;;;;;GAMG;AACH,SAAS,mBAAmB,CAAC,GAAY;IACvC,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;IACzF,OAAO,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;AAC7D,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,wBAAwB,CACtC,IAA+B,EAC/B,cAAoD;IAEpD,MAAM,WAAW,GAAG,0BAA0B,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;IAErE,KAAK,UAAU,KAAK,CAAC,EACnB,OAAO,EACP,WAAW,GAIZ;QACC,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QAC1C,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,IAAI,2BAA2B,CAAC,WAAW,CAAC,CAAC;QACrD,CAAC;QAED,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;QAEvB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,gEAAgE;YAChE,IAAI,YAA4C,CAAC;YACjD,IAAI,CAAC;gBACH,YAAY,GAAG,MAAM,eAAe,CAAC,IAAI,CAAC,YAAY,EAAE;oBACtD,MAAM,EAAE,IAAI,CAAC,MAAM;oBACnB,OAAO;oBACP,WAAW;oBACX,OAAO,EAAE,IAAI,CAAC,EAAE;oBAChB,MAAM,EAAE,WAAW;oBACnB,OAAO,EAAE,IAAI;oBACb,WAAW,EAAE,IAAI;oBACjB,MAAM,EAAE,IAAI;oBACZ,eAAe,EAAE,IAAI;iBACtB,CAAC,CAAC;YACL,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,IAAI,mBAAmB,CAAC,GAAG,CAAC,EAAE,CAAC;oBAC7B,oDAAoD;oBACpD,SAAS;gBACX,CAAC;gBACD,MAAM,GAAG,CAAC;YACZ,CAAC;YAED,sDAAsD;YACtD,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;gBACjC,MAAM,MAAM,GAAG,IAAI,IAAI,CACrB,GAAG,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,cAAc,GAAG,IAAI,CACnD,CAAC,WAAW,EAAE,CAAC;gBAEhB,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;oBACvC,IAAI,EAAE,uBAAuB;oBAC7B,OAAO,EAAE;wBACP,aAAa,EAAE,YAAY,CAAC,EAAE;wBAC9B,MAAM,EAAE,IAAI,CAAC,MAAM;wBACnB,OAAO;wBACP,WAAW;wBACX,OAAO,EAAE,IAAI,CAAC,EAAE;qBACjB;oBACD,KAAK,EAAE,MAAM;iBACd,CAAC,CAAC;gBAEH,kEAAkE;gBAClE,IAAI,CAAC;oBACH,MAAM,IAAI,CAAC,YAAY,CAAC,UAAU,CAChC,8BAA8B,EAC9B,YAAY,CAAC,EAAE,EACf,EAAE,MAAM,EAAE,KAAK,EAAiC,CACjD,CAAC;gBACJ,CAAC;gBAAC,MAAM,CAAC;oBACP,8DAA8D;gBAChE,CAAC;YACH,CAAC;YACD,yEAAyE;QAC3E,CAAC;IACH,CAAC;IAED,KAAK,UAAU,iBAAiB,CAAC,MAIhC;QACC,OAAO,YAAY,CAAC,IAAI,EAAE,cAAc,EAAE,MAAM,CAAC,CAAC;IACpD,CAAC;IAED,KAAK,UAAU,SAAS,CAAC,EACvB,OAAO,EACP,WAAW,GAIZ;QACC,OAAO,eAAe,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC;IAC/E,CAAC;IAED,OAAO;QACL,KAAK;QACL,WAAW,EAAE,iBAAiB;QAC9B,SAAS;QACT,YAAY,EAAE,WAAW;KAC1B,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare const log: import("hazo_core").HazoCoreLogger;
2
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/lib/logger.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,GAAG,oCAA8B,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { createLogger } from 'hazo_core';
2
+ export const log = createLogger('hazo_notify');
3
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/lib/logger.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAEzC,MAAM,CAAC,MAAM,GAAG,GAAG,YAAY,CAAC,aAAa,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../../src/lib/preferences/storage.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EACV,aAAa,EACb,kBAAkB,EAClB,oBAAoB,EACpB,0BAA0B,EAC1B,cAAc,EACf,MAAM,YAAY,CAAC;AAqBpB;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,IAAI,EAAE;IAC3C,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAS3B;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,aAAa,CAAC,CAmCtF;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE,oBAAoB,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAU9F;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,oBAAoB,GAAG,OAAO,CAAC,OAAO,CAAC,CAKpF;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,0BAA0B,GAC/B,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC,CAuCnD"}
1
+ {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../../../src/lib/preferences/storage.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EACV,aAAa,EACb,kBAAkB,EAClB,oBAAoB,EACpB,0BAA0B,EAC1B,cAAc,EACf,MAAM,YAAY,CAAC;AAqBpB;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,IAAI,EAAE;IAC3C,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAS3B;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,aAAa,CAAC,CAuCtF;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE,oBAAoB,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAU9F;AAED;;GAEG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,oBAAoB,GAAG,OAAO,CAAC,OAAO,CAAC,CAKpF;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,0BAA0B,GAC/B,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC,CAuCnD"}
@@ -4,8 +4,9 @@
4
4
  * Uses rawQuery via getInboxConnection() — compatible with both SQLite and Postgres.
5
5
  * @packageDocumentation
6
6
  */
7
- import { randomUUID } from 'node:crypto';
7
+ import { generateRequestId } from 'hazo_core';
8
8
  import { getInboxConnection } from '../inbox/connection.js';
9
+ import { HazoValidationError } from 'hazo_core';
9
10
  const TABLE = 'hazo_notify_preferences';
10
11
  function conn() {
11
12
  return getInboxConnection();
@@ -38,6 +39,10 @@ export async function list_preferences(opts) {
38
39
  * Upsert a preference row. A second call with the same key updates `mode`.
39
40
  */
40
41
  export async function set_preference(input) {
42
+ const VALID_MODES = ['on', 'off', 'digest'];
43
+ if (!VALID_MODES.includes(input.mode)) {
44
+ throw new HazoValidationError({ code: 'HAZO_NOTIFY_INVALID_PREF_MODE', pkg: 'hazo_notify', message: `Invalid preference mode '${input.mode}'. Must be one of: ${VALID_MODES.join(', ')}` });
45
+ }
41
46
  const all = await list_preferences({ user_id: input.user_id });
42
47
  const match = all.find(r => r.scope_id === (input.scope_id ?? null) &&
43
48
  r.event_type === (input.event_type ?? null) &&
@@ -47,7 +52,7 @@ export async function set_preference(input) {
47
52
  await conn().rawQuery(`UPDATE ${TABLE} SET mode = ?, updated_at = ? WHERE id = ?`, { params: [input.mode, now, match.id] });
48
53
  return { ...match, mode: input.mode, updated_at: now };
49
54
  }
50
- const id = randomUUID();
55
+ const id = generateRequestId().slice(4);
51
56
  const now = new Date().toISOString();
52
57
  await conn().rawQuery(`INSERT INTO ${TABLE} (id, user_id, scope_id, event_type, channel_id, mode, created_at, updated_at)
53
58
  VALUES (?, ?, ?, ?, ?, ?, ?, ?)`, { params: [id, input.user_id, input.scope_id ?? null, input.event_type ?? null, input.channel_id, input.mode, now, now] });
@@ -1 +1 @@
1
- {"version":3,"file":"storage.js","sourceRoot":"","sources":["../../../src/lib/preferences/storage.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"storage.js","sourceRoot":"","sources":["../../../src/lib/preferences/storage.ts"],"names":[],"mappings":"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"}
@@ -16,7 +16,7 @@
16
16
  * @packageDocumentation
17
17
  */
18
18
  /** Delivery mode for a channel. 'digest' is added in 5.3.0. */
19
- export type PreferenceMode = 'on' | 'off';
19
+ export type PreferenceMode = 'on' | 'off' | 'digest';
20
20
  /** A single preference row as returned by the storage layer. */
21
21
  export interface PreferenceRow {
22
22
  id: string;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/lib/preferences/types.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;;;;GAgBG;AAEH,+DAA+D;AAC/D,MAAM,MAAM,cAAc,GAAG,IAAI,GAAG,KAAK,CAAC;AAE1C,gEAAgE;AAChE,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,uCAAuC;IACvC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,wCAAwC;IACxC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,cAAc,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,gCAAgC;AAChC,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,gDAAgD;IAChD,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,6BAA6B;IAC7B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,cAAc,CAAC;CACtB;AAED,kCAAkC;AAClC,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,uEAAuE;AACvE,MAAM,WAAW,0BAA0B;IACzC,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,8DAA8D;IAC9D,YAAY,CAAC,EAAE,cAAc,CAAC;CAC/B"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/lib/preferences/types.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;;;;GAgBG;AAEH,+DAA+D;AAC/D,MAAM,MAAM,cAAc,GAAG,IAAI,GAAG,KAAK,GAAG,QAAQ,CAAC;AAErD,gEAAgE;AAChE,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,uCAAuC;IACvC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,wCAAwC;IACxC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,cAAc,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,gCAAgC;AAChC,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;IAChB,gDAAgD;IAChD,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,6BAA6B;IAC7B,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,cAAc,CAAC;CACtB;AAED,kCAAkC;AAClC,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,uEAAuE;AACvE,MAAM,WAAW,0BAA0B;IACzC,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,8DAA8D;IAC9D,YAAY,CAAC,EAAE,cAAc,CAAC;CAC/B"}
@@ -1,3 +1,2 @@
1
- import { type ClassValue } from 'clsx';
2
- export declare function cn(...inputs: ClassValue[]): string;
1
+ export { cn } from 'hazo_ui';
3
2
  //# sourceMappingURL=utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/lib/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,UAAU,EAAE,MAAM,MAAM,CAAC;AAG7C,wBAAgB,EAAE,CAAC,GAAG,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,CAElD"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/lib/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC"}
package/dist/lib/utils.js CHANGED
@@ -1,6 +1,2 @@
1
- import { clsx } from 'clsx';
2
- import { twMerge } from 'tailwind-merge';
3
- export function cn(...inputs) {
4
- return twMerge(clsx(inputs));
5
- }
1
+ export { cn } from 'hazo_ui';
6
2
  //# sourceMappingURL=utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/lib/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAmB,MAAM,MAAM,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AAEzC,MAAM,UAAU,EAAE,CAAC,GAAG,MAAoB;IACxC,OAAO,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;AAC/B,CAAC"}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/lib/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,EAAE,EAAE,MAAM,SAAS,CAAC"}
@@ -0,0 +1,21 @@
1
+ -- migrations/011_digest_status.pg.sql
2
+ -- Adds 'digesting' to the delivery status CHECK constraint and a partial index
3
+ -- for the digest flush job query.
4
+ -- CAUTION: Dropping + recreating a CHECK constraint requires a brief table
5
+ -- lock in Postgres. Run during low-traffic window.
6
+
7
+ BEGIN;
8
+
9
+ ALTER TABLE hazo_notify_channel_deliveries
10
+ DROP CONSTRAINT IF EXISTS hazo_notify_channel_deliveries_status_check;
11
+
12
+ ALTER TABLE hazo_notify_channel_deliveries
13
+ ADD CONSTRAINT hazo_notify_channel_deliveries_status_check
14
+ CHECK (status IN ('pending', 'sent', 'failed', 'digesting'));
15
+
16
+ -- Index for digest flush job: find all digesting rows per channel quickly.
17
+ CREATE INDEX IF NOT EXISTS idx_delivery_digesting
18
+ ON hazo_notify_channel_deliveries (channel_id, created_at)
19
+ WHERE status = 'digesting';
20
+
21
+ COMMIT;
@@ -0,0 +1,43 @@
1
+ -- migrations/011_digest_status.sqlite.sql
2
+ -- SQLite: recreate table with updated CHECK constraint.
3
+ -- Safe to run multiple times (DROP IF EXISTS + CREATE IF NOT EXISTS).
4
+
5
+ BEGIN;
6
+
7
+ CREATE TABLE IF NOT EXISTS hazo_notify_channel_deliveries_new (
8
+ id TEXT PRIMARY KEY,
9
+ inbox_id TEXT NOT NULL REFERENCES hazo_notify_inbox(id) ON DELETE CASCADE,
10
+ channel_id TEXT NOT NULL,
11
+ payload TEXT NOT NULL,
12
+ status TEXT NOT NULL DEFAULT 'pending',
13
+ flush_after TEXT NOT NULL,
14
+ attempt_count INTEGER NOT NULL DEFAULT 0,
15
+ message_id TEXT,
16
+ last_error TEXT,
17
+ finalized_at TEXT,
18
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
19
+ updated_at TEXT NOT NULL DEFAULT (datetime('now')),
20
+ CHECK (status IN ('pending', 'sent', 'failed', 'digesting'))
21
+ );
22
+
23
+ INSERT INTO hazo_notify_channel_deliveries_new
24
+ SELECT * FROM hazo_notify_channel_deliveries;
25
+
26
+ DROP TABLE hazo_notify_channel_deliveries;
27
+
28
+ ALTER TABLE hazo_notify_channel_deliveries_new
29
+ RENAME TO hazo_notify_channel_deliveries;
30
+
31
+ -- Recreate indexes (were dropped with the original table)
32
+ CREATE UNIQUE INDEX IF NOT EXISTS uniq_delivery_inbox_channel
33
+ ON hazo_notify_channel_deliveries (inbox_id, channel_id);
34
+
35
+ CREATE INDEX IF NOT EXISTS idx_delivery_due
36
+ ON hazo_notify_channel_deliveries (channel_id, flush_after)
37
+ WHERE status = 'pending';
38
+
39
+ CREATE INDEX IF NOT EXISTS idx_delivery_digesting
40
+ ON hazo_notify_channel_deliveries (channel_id, created_at)
41
+ WHERE status = 'digesting';
42
+
43
+ COMMIT;
@@ -0,0 +1,12 @@
1
+ -- migrations/012_preferences_digest.pg.sql
2
+ -- Extends hazo_notify_preferences.mode CHECK constraint to allow 'digest'.
3
+ BEGIN;
4
+
5
+ ALTER TABLE hazo_notify_preferences
6
+ DROP CONSTRAINT IF EXISTS hazo_notify_preferences_mode_check;
7
+
8
+ ALTER TABLE hazo_notify_preferences
9
+ ADD CONSTRAINT hazo_notify_preferences_mode_check
10
+ CHECK (mode IN ('on', 'off', 'digest'));
11
+
12
+ COMMIT;
@@ -0,0 +1,51 @@
1
+ -- migrations/012_preferences_digest.sqlite.sql
2
+ -- Extends hazo_notify_preferences.mode CHECK constraint to allow 'digest'.
3
+ -- SQLite does not support ALTER TABLE ... ADD CONSTRAINT, so we recreate the table.
4
+
5
+ PRAGMA foreign_keys = OFF;
6
+
7
+ -- Create new table with updated CHECK constraint
8
+ CREATE TABLE hazo_notify_preferences_new (
9
+ id TEXT PRIMARY KEY,
10
+ user_id TEXT NOT NULL,
11
+ scope_id TEXT, -- NULL = global
12
+ event_type TEXT, -- NULL = all events
13
+ channel_id TEXT NOT NULL,
14
+ mode TEXT NOT NULL DEFAULT 'on',
15
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
16
+ updated_at TEXT NOT NULL DEFAULT (datetime('now')),
17
+ CHECK (mode IN ('on', 'off', 'digest'))
18
+ );
19
+
20
+ -- Copy all data from old table
21
+ INSERT INTO hazo_notify_preferences_new
22
+ SELECT id, user_id, scope_id, event_type, channel_id, mode, created_at, updated_at
23
+ FROM hazo_notify_preferences;
24
+
25
+ -- Drop old table
26
+ DROP TABLE hazo_notify_preferences;
27
+
28
+ -- Rename new table to original name
29
+ ALTER TABLE hazo_notify_preferences_new RENAME TO hazo_notify_preferences;
30
+
31
+ -- Recreate indexes from migration 010
32
+ CREATE UNIQUE INDEX IF NOT EXISTS hazo_notify_pref_nn
33
+ ON hazo_notify_preferences (user_id, scope_id, event_type, channel_id)
34
+ WHERE scope_id IS NOT NULL AND event_type IS NOT NULL;
35
+
36
+ CREATE UNIQUE INDEX IF NOT EXISTS hazo_notify_pref_sn
37
+ ON hazo_notify_preferences (user_id, event_type, channel_id)
38
+ WHERE scope_id IS NULL AND event_type IS NOT NULL;
39
+
40
+ CREATE UNIQUE INDEX IF NOT EXISTS hazo_notify_pref_en
41
+ ON hazo_notify_preferences (user_id, scope_id, channel_id)
42
+ WHERE scope_id IS NOT NULL AND event_type IS NULL;
43
+
44
+ CREATE UNIQUE INDEX IF NOT EXISTS hazo_notify_pref_ss
45
+ ON hazo_notify_preferences (user_id, channel_id)
46
+ WHERE scope_id IS NULL AND event_type IS NULL;
47
+
48
+ CREATE INDEX IF NOT EXISTS hazo_notify_pref_user_idx
49
+ ON hazo_notify_preferences (user_id);
50
+
51
+ PRAGMA foreign_keys = ON;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hazo_notify",
3
- "version": "5.2.1",
3
+ "version": "6.0.0",
4
4
  "type": "module",
5
5
  "description": "Email notification system with scope-aware template management",
6
6
  "main": "./dist/lib/index.js",
@@ -124,21 +124,32 @@
124
124
  "dependencies": {
125
125
  "clsx": "^2.1.1",
126
126
  "handlebars": "^4.7.8",
127
- "hazo_config": "^2.1.0",
128
127
  "isomorphic-dompurify": "^2.9.0",
129
128
  "lru-cache": "^11.3.6",
130
129
  "tailwind-merge": "^3.5.0"
131
130
  },
132
131
  "peerDependencies": {
133
- "hazo_connect": "^2.7.1",
134
- "hazo_jobs": "^0.7.0",
135
- "hazo_logs": "^1.0.13",
136
- "hazo_ui": "^2.17.0"
132
+ "hazo_api": "^2.0.0",
133
+ "hazo_config": "^2.1.5",
134
+ "hazo_connect": "^3.0.0",
135
+ "hazo_core": "^1.0.0",
136
+ "hazo_jobs": "^0.12.0",
137
+ "hazo_logs": "^2.0.0",
138
+ "hazo_ui": "^3.1.0"
137
139
  },
138
140
  "peerDependenciesMeta": {
141
+ "hazo_api": {
142
+ "optional": true
143
+ },
144
+ "hazo_config": {
145
+ "optional": true
146
+ },
139
147
  "hazo_connect": {
140
148
  "optional": true
141
149
  },
150
+ "hazo_core": {
151
+ "optional": true
152
+ },
142
153
  "hazo_logs": {
143
154
  "optional": true
144
155
  },
@@ -201,9 +212,9 @@
201
212
  "class-variance-authority": "^0.7.0",
202
213
  "clsx": "^2.1.1",
203
214
  "cmdk": "^1.1.1",
204
- "hazo_auth": "^5.2.0",
205
- "hazo_connect": "^2.7.1",
206
- "hazo_ui": "^2.17.0",
215
+ "hazo_auth": "^9.0.0",
216
+ "hazo_connect": "^3.0.0",
217
+ "hazo_ui": "^3.1.0",
207
218
  "jest": "^30.2.0",
208
219
  "jest-environment-jsdom": "^30.4.1",
209
220
  "lexical": "^0.39.0",