hazo_auth 6.0.0 → 7.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (256) hide show
  1. package/README.md +233 -8
  2. package/SETUP_CHECKLIST.md +240 -0
  3. package/cli-src/cli/validate.ts +4 -0
  4. package/cli-src/lib/auth/nextauth_config.ts +101 -1
  5. package/cli-src/lib/cookies_config.server.ts +1 -0
  6. package/cli-src/lib/email_verification_config.server.ts +0 -34
  7. package/cli-src/lib/forgot_password_config.server.ts +0 -34
  8. package/cli-src/lib/login_config.server.ts +14 -31
  9. package/cli-src/lib/my_settings_config.server.ts +0 -3
  10. package/cli-src/lib/oauth_config.server.ts +58 -0
  11. package/cli-src/lib/otp_config.server.ts +91 -0
  12. package/cli-src/lib/register_config.server.ts +11 -31
  13. package/cli-src/lib/reset_password_config.server.ts +0 -31
  14. package/cli-src/lib/services/email_service.ts +3 -1
  15. package/cli-src/lib/services/email_template_manifest.ts +17 -0
  16. package/cli-src/lib/services/email_templates/otp_signin_code.html +13 -0
  17. package/cli-src/lib/services/email_templates/otp_signin_code.txt +5 -0
  18. package/cli-src/lib/services/index.ts +8 -2
  19. package/cli-src/lib/services/oauth_service.ts +197 -0
  20. package/cli-src/lib/services/otp_service.ts +295 -0
  21. package/cli-src/lib/services/session_token_service.ts +4 -1
  22. package/config/hazo_auth_config.example.ini +76 -41
  23. package/dist/cli/validate.d.ts.map +1 -1
  24. package/dist/cli/validate.js +4 -0
  25. package/dist/client.d.ts +2 -0
  26. package/dist/client.d.ts.map +1 -1
  27. package/dist/client.js +1 -0
  28. package/dist/components/layouts/create_firm/index.d.ts +4 -8
  29. package/dist/components/layouts/create_firm/index.d.ts.map +1 -1
  30. package/dist/components/layouts/create_firm/index.js +3 -3
  31. package/dist/components/layouts/email_verification/index.d.ts +4 -5
  32. package/dist/components/layouts/email_verification/index.d.ts.map +1 -1
  33. package/dist/components/layouts/email_verification/index.js +4 -4
  34. package/dist/components/layouts/forgot_password/index.d.ts +4 -5
  35. package/dist/components/layouts/forgot_password/index.d.ts.map +1 -1
  36. package/dist/components/layouts/forgot_password/index.js +2 -2
  37. package/dist/components/layouts/login/index.d.ts +19 -9
  38. package/dist/components/layouts/login/index.d.ts.map +1 -1
  39. package/dist/components/layouts/login/index.js +12 -6
  40. package/dist/components/layouts/otp/index.d.ts +17 -0
  41. package/dist/components/layouts/otp/index.d.ts.map +1 -0
  42. package/dist/components/layouts/otp/index.js +16 -0
  43. package/dist/components/layouts/register/index.d.ts +11 -7
  44. package/dist/components/layouts/register/index.d.ts.map +1 -1
  45. package/dist/components/layouts/register/index.js +8 -4
  46. package/dist/components/layouts/reset_password/index.d.ts +4 -5
  47. package/dist/components/layouts/reset_password/index.d.ts.map +1 -1
  48. package/dist/components/layouts/reset_password/index.js +5 -5
  49. package/dist/components/layouts/shared/components/already_logged_in_guard.d.ts +3 -5
  50. package/dist/components/layouts/shared/components/already_logged_in_guard.d.ts.map +1 -1
  51. package/dist/components/layouts/shared/components/already_logged_in_guard.js +2 -2
  52. package/dist/components/layouts/shared/components/facebook_sign_in_button.d.ts +25 -0
  53. package/dist/components/layouts/shared/components/facebook_sign_in_button.d.ts.map +1 -0
  54. package/dist/components/layouts/shared/components/facebook_sign_in_button.js +49 -0
  55. package/dist/components/layouts/shared/components/sidebar_layout_wrapper.d.ts.map +1 -1
  56. package/dist/components/layouts/shared/components/sidebar_layout_wrapper.js +8 -3
  57. package/dist/components/layouts/shared/components/two_column_auth_layout.d.ts +3 -6
  58. package/dist/components/layouts/shared/components/two_column_auth_layout.d.ts.map +1 -1
  59. package/dist/components/layouts/shared/components/two_column_auth_layout.js +8 -5
  60. package/dist/components/otp/OTPRequestForm.d.ts +11 -0
  61. package/dist/components/otp/OTPRequestForm.d.ts.map +1 -0
  62. package/dist/components/otp/OTPRequestForm.js +42 -0
  63. package/dist/components/otp/OTPVerifyForm.d.ts +16 -0
  64. package/dist/components/otp/OTPVerifyForm.d.ts.map +1 -0
  65. package/dist/components/otp/OTPVerifyForm.js +75 -0
  66. package/dist/components/otp/index.d.ts +5 -0
  67. package/dist/components/otp/index.d.ts.map +1 -0
  68. package/dist/components/otp/index.js +2 -0
  69. package/dist/components/ui/input-otp.d.ts +35 -0
  70. package/dist/components/ui/input-otp.d.ts.map +1 -0
  71. package/dist/components/ui/input-otp.js +44 -0
  72. package/dist/consent/consent_state.d.ts +18 -0
  73. package/dist/consent/consent_state.d.ts.map +1 -0
  74. package/dist/consent/consent_state.js +29 -0
  75. package/dist/consent/cookie_consent_banner.d.ts +11 -0
  76. package/dist/consent/cookie_consent_banner.d.ts.map +1 -0
  77. package/dist/consent/cookie_consent_banner.js +40 -0
  78. package/dist/consent/gtm_mapping.d.ts +13 -0
  79. package/dist/consent/gtm_mapping.d.ts.map +1 -0
  80. package/dist/consent/gtm_mapping.js +30 -0
  81. package/dist/consent/index.d.ts +7 -0
  82. package/dist/consent/index.d.ts.map +1 -0
  83. package/dist/consent/index.js +7 -0
  84. package/dist/consent/manage_modal.d.ts +2 -0
  85. package/dist/consent/manage_modal.d.ts.map +1 -0
  86. package/dist/consent/manage_modal.js +33 -0
  87. package/dist/consent/read_consent.d.ts +15 -0
  88. package/dist/consent/read_consent.d.ts.map +1 -0
  89. package/dist/consent/read_consent.js +23 -0
  90. package/dist/consent/use_consent.d.ts +7 -0
  91. package/dist/consent/use_consent.d.ts.map +1 -0
  92. package/dist/consent/use_consent.js +55 -0
  93. package/dist/lib/auth/nextauth_config.d.ts +10 -0
  94. package/dist/lib/auth/nextauth_config.d.ts.map +1 -1
  95. package/dist/lib/auth/nextauth_config.js +80 -2
  96. package/dist/lib/cookies_config.server.d.ts +1 -0
  97. package/dist/lib/cookies_config.server.d.ts.map +1 -1
  98. package/dist/lib/cookies_config.server.js +1 -0
  99. package/dist/lib/email_verification_config.server.d.ts +0 -3
  100. package/dist/lib/email_verification_config.server.d.ts.map +1 -1
  101. package/dist/lib/email_verification_config.server.js +0 -15
  102. package/dist/lib/forgot_password_config.server.d.ts +0 -3
  103. package/dist/lib/forgot_password_config.server.d.ts.map +1 -1
  104. package/dist/lib/forgot_password_config.server.js +0 -15
  105. package/dist/lib/login_config.server.d.ts +6 -3
  106. package/dist/lib/login_config.server.d.ts.map +1 -1
  107. package/dist/lib/login_config.server.js +7 -13
  108. package/dist/lib/my_settings_config.server.d.ts +0 -1
  109. package/dist/lib/my_settings_config.server.d.ts.map +1 -1
  110. package/dist/lib/my_settings_config.server.js +0 -2
  111. package/dist/lib/oauth_config.server.d.ts +17 -0
  112. package/dist/lib/oauth_config.server.d.ts.map +1 -1
  113. package/dist/lib/oauth_config.server.js +25 -0
  114. package/dist/lib/otp_config.server.d.ts +49 -0
  115. package/dist/lib/otp_config.server.d.ts.map +1 -0
  116. package/dist/lib/otp_config.server.js +48 -0
  117. package/dist/lib/register_config.server.d.ts +2 -3
  118. package/dist/lib/register_config.server.d.ts.map +1 -1
  119. package/dist/lib/register_config.server.js +4 -13
  120. package/dist/lib/reset_password_config.server.d.ts +0 -3
  121. package/dist/lib/reset_password_config.server.d.ts.map +1 -1
  122. package/dist/lib/reset_password_config.server.js +0 -13
  123. package/dist/lib/services/email_service.d.ts +1 -1
  124. package/dist/lib/services/email_service.d.ts.map +1 -1
  125. package/dist/lib/services/email_service.js +2 -0
  126. package/dist/lib/services/email_template_manifest.d.ts.map +1 -1
  127. package/dist/lib/services/email_template_manifest.js +17 -0
  128. package/dist/lib/services/email_templates/otp_signin_code.html +13 -0
  129. package/dist/lib/services/email_templates/otp_signin_code.txt +5 -0
  130. package/dist/lib/services/index.d.ts +2 -0
  131. package/dist/lib/services/index.d.ts.map +1 -1
  132. package/dist/lib/services/index.js +1 -0
  133. package/dist/lib/services/oauth_service.d.ts +24 -0
  134. package/dist/lib/services/oauth_service.d.ts.map +1 -1
  135. package/dist/lib/services/oauth_service.js +155 -0
  136. package/dist/lib/services/otp_service.d.ts +46 -0
  137. package/dist/lib/services/otp_service.d.ts.map +1 -0
  138. package/dist/lib/services/otp_service.js +238 -0
  139. package/dist/lib/services/session_token_service.d.ts +3 -1
  140. package/dist/lib/services/session_token_service.d.ts.map +1 -1
  141. package/dist/lib/services/session_token_service.js +4 -2
  142. package/dist/page_components/create_firm.d.ts +13 -1
  143. package/dist/page_components/create_firm.d.ts.map +1 -1
  144. package/dist/page_components/create_firm.js +10 -6
  145. package/dist/page_components/forgot_password.d.ts +1 -4
  146. package/dist/page_components/forgot_password.d.ts.map +1 -1
  147. package/dist/page_components/forgot_password.js +2 -6
  148. package/dist/page_components/login.d.ts +1 -4
  149. package/dist/page_components/login.d.ts.map +1 -1
  150. package/dist/page_components/login.js +2 -6
  151. package/dist/page_components/otp.d.ts +4 -0
  152. package/dist/page_components/otp.d.ts.map +1 -0
  153. package/dist/page_components/otp.js +5 -0
  154. package/dist/page_components/register.d.ts +1 -4
  155. package/dist/page_components/register.d.ts.map +1 -1
  156. package/dist/page_components/register.js +2 -6
  157. package/dist/page_components/reset_password.d.ts +1 -4
  158. package/dist/page_components/reset_password.d.ts.map +1 -1
  159. package/dist/page_components/reset_password.js +2 -6
  160. package/dist/page_components/verify_email.d.ts +1 -4
  161. package/dist/page_components/verify_email.d.ts.map +1 -1
  162. package/dist/page_components/verify_email.js +2 -6
  163. package/dist/server/routes/index.d.ts +3 -0
  164. package/dist/server/routes/index.d.ts.map +1 -1
  165. package/dist/server/routes/index.js +4 -0
  166. package/dist/server/routes/me.d.ts.map +1 -1
  167. package/dist/server/routes/me.js +43 -1
  168. package/dist/server/routes/oauth_facebook_callback.d.ts +8 -0
  169. package/dist/server/routes/oauth_facebook_callback.d.ts.map +1 -0
  170. package/dist/server/routes/oauth_facebook_callback.js +157 -0
  171. package/dist/server/routes/oauth_google_callback.js +1 -1
  172. package/dist/server/routes/otp/request.d.ts +3 -0
  173. package/dist/server/routes/otp/request.d.ts.map +1 -0
  174. package/dist/server/routes/otp/request.js +33 -0
  175. package/dist/server/routes/otp/verify.d.ts +3 -0
  176. package/dist/server/routes/otp/verify.d.ts.map +1 -0
  177. package/dist/server/routes/otp/verify.js +58 -0
  178. package/dist/server-lib.d.ts +3 -0
  179. package/dist/server-lib.d.ts.map +1 -1
  180. package/dist/server-lib.js +2 -0
  181. package/dist/server_pages/forgot_password.d.ts +13 -17
  182. package/dist/server_pages/forgot_password.d.ts.map +1 -1
  183. package/dist/server_pages/forgot_password.js +12 -8
  184. package/dist/server_pages/forgot_password_client_wrapper.d.ts +7 -6
  185. package/dist/server_pages/forgot_password_client_wrapper.d.ts.map +1 -1
  186. package/dist/server_pages/forgot_password_client_wrapper.js +2 -2
  187. package/dist/server_pages/login.d.ts +22 -21
  188. package/dist/server_pages/login.d.ts.map +1 -1
  189. package/dist/server_pages/login.js +15 -19
  190. package/dist/server_pages/login_client_wrapper.d.ts +10 -6
  191. package/dist/server_pages/login_client_wrapper.d.ts.map +1 -1
  192. package/dist/server_pages/login_client_wrapper.js +2 -2
  193. package/dist/server_pages/my_settings.d.ts +2 -0
  194. package/dist/server_pages/my_settings.d.ts.map +1 -1
  195. package/dist/server_pages/my_settings.js +8 -2
  196. package/dist/server_pages/otp.d.ts +56 -0
  197. package/dist/server_pages/otp.d.ts.map +1 -0
  198. package/dist/server_pages/otp.js +45 -0
  199. package/dist/server_pages/register.d.ts +19 -16
  200. package/dist/server_pages/register.d.ts.map +1 -1
  201. package/dist/server_pages/register.js +15 -12
  202. package/dist/server_pages/register_client_wrapper.d.ts +10 -6
  203. package/dist/server_pages/register_client_wrapper.d.ts.map +1 -1
  204. package/dist/server_pages/register_client_wrapper.js +2 -2
  205. package/dist/server_pages/reset_password.d.ts +11 -16
  206. package/dist/server_pages/reset_password.d.ts.map +1 -1
  207. package/dist/server_pages/reset_password.js +11 -9
  208. package/dist/server_pages/reset_password_client_wrapper.d.ts +7 -6
  209. package/dist/server_pages/reset_password_client_wrapper.d.ts.map +1 -1
  210. package/dist/server_pages/reset_password_client_wrapper.js +2 -2
  211. package/dist/server_pages/verify_email.d.ts +11 -17
  212. package/dist/server_pages/verify_email.d.ts.map +1 -1
  213. package/dist/server_pages/verify_email.js +11 -8
  214. package/dist/server_pages/verify_email_client_wrapper.d.ts +7 -6
  215. package/dist/server_pages/verify_email_client_wrapper.d.ts.map +1 -1
  216. package/dist/server_pages/verify_email_client_wrapper.js +2 -2
  217. package/dist/strings/default_strings.d.ts +47 -0
  218. package/dist/strings/default_strings.d.ts.map +1 -0
  219. package/dist/strings/default_strings.js +18 -0
  220. package/dist/strings/index.d.ts +4 -0
  221. package/dist/strings/index.d.ts.map +1 -0
  222. package/dist/strings/index.js +3 -0
  223. package/dist/strings/strings_context.d.ts +12 -0
  224. package/dist/strings/strings_context.d.ts.map +1 -0
  225. package/dist/strings/strings_context.js +23 -0
  226. package/dist/strings/strings_provider.d.ts +26 -0
  227. package/dist/strings/strings_provider.d.ts.map +1 -0
  228. package/dist/strings/strings_provider.js +45 -0
  229. package/dist/theme/create_theme.d.ts +7 -0
  230. package/dist/theme/create_theme.d.ts.map +1 -0
  231. package/dist/theme/create_theme.js +97 -0
  232. package/dist/theme/hex_to_hsl.d.ts +16 -0
  233. package/dist/theme/hex_to_hsl.d.ts.map +1 -0
  234. package/dist/theme/hex_to_hsl.js +110 -0
  235. package/dist/theme/index.d.ts +4 -0
  236. package/dist/theme/index.d.ts.map +1 -0
  237. package/dist/theme/index.js +3 -0
  238. package/dist/theme/luminance.d.ts +11 -0
  239. package/dist/theme/luminance.d.ts.map +1 -0
  240. package/dist/theme/luminance.js +45 -0
  241. package/dist/theme/theme_provider.d.ts +14 -0
  242. package/dist/theme/theme_provider.d.ts.map +1 -0
  243. package/dist/theme/theme_provider.js +23 -0
  244. package/dist/theme/theme_types.d.ts +36 -0
  245. package/dist/theme/theme_types.d.ts.map +1 -0
  246. package/dist/theme/theme_types.js +1 -0
  247. package/dist/themes/index.d.ts +3 -0
  248. package/dist/themes/index.d.ts.map +1 -0
  249. package/dist/themes/index.js +2 -0
  250. package/dist/themes/preset_indigo_sunset.d.ts +3 -0
  251. package/dist/themes/preset_indigo_sunset.d.ts.map +1 -0
  252. package/dist/themes/preset_indigo_sunset.js +20 -0
  253. package/dist/themes/preset_neutral.d.ts +3 -0
  254. package/dist/themes/preset_neutral.d.ts.map +1 -0
  255. package/dist/themes/preset_neutral.js +14 -0
  256. package/package.json +36 -2
@@ -0,0 +1,45 @@
1
+ import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
2
+ import { DEFAULT_STRINGS } from "./default_strings.js";
3
+ import { setStrings } from "./strings_context.js";
4
+ function deep_merge(base, overrides) {
5
+ const result = Object.assign({}, base);
6
+ const ov = overrides;
7
+ for (const key in ov) {
8
+ const override_val = ov[key];
9
+ const base_val = base[key];
10
+ if (override_val !== undefined &&
11
+ override_val !== null &&
12
+ typeof override_val === "object" &&
13
+ !Array.isArray(override_val) &&
14
+ typeof base_val === "object" &&
15
+ base_val !== null) {
16
+ result[key] = deep_merge(base_val, override_val);
17
+ }
18
+ else if (override_val !== undefined) {
19
+ result[key] = override_val;
20
+ }
21
+ }
22
+ return result;
23
+ }
24
+ /**
25
+ * Server Component that registers custom string overrides for all descendant
26
+ * hazo_auth page components rendered in the same React request.
27
+ *
28
+ * Usage:
29
+ * ```tsx
30
+ * <HazoAuthStringsProvider
31
+ * strings={{ login: { title: "Welcome back", ctaText: "Log in" } }}
32
+ * >
33
+ * <LoginPage />
34
+ * </HazoAuthStringsProvider>
35
+ * ```
36
+ *
37
+ * Any field not supplied falls back to DEFAULT_STRINGS.
38
+ */
39
+ export function HazoAuthStringsProvider({ strings, children, }) {
40
+ const resolved = strings
41
+ ? deep_merge(DEFAULT_STRINGS, strings)
42
+ : DEFAULT_STRINGS;
43
+ setStrings(resolved);
44
+ return _jsx(_Fragment, { children: children });
45
+ }
@@ -0,0 +1,7 @@
1
+ import type { HazoAuthTheme } from "./theme_types";
2
+ /**
3
+ * Creates a fully-resolved HazoAuthTheme from a partial input, applying defaults
4
+ * from preset_neutral. Computes all shadcn CSS variable overrides.
5
+ */
6
+ export declare function createTheme(input: Partial<HazoAuthTheme>): HazoAuthTheme;
7
+ //# sourceMappingURL=create_theme.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"create_theme.d.ts","sourceRoot":"","sources":["../../src/theme/create_theme.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAKnD;;;GAGG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG,aAAa,CA6ExE"}
@@ -0,0 +1,97 @@
1
+ import { hex_to_hsl, adjust_lightness } from "./hex_to_hsl.js";
2
+ import { pick_foreground } from "./luminance.js";
3
+ import { preset_neutral } from "../themes/preset_neutral.js";
4
+ /**
5
+ * Creates a fully-resolved HazoAuthTheme from a partial input, applying defaults
6
+ * from preset_neutral. Computes all shadcn CSS variable overrides.
7
+ */
8
+ export function createTheme(input) {
9
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
10
+ // Step 1: Deep merge input over preset_neutral defaults
11
+ const merged = Object.assign(Object.assign(Object.assign({}, preset_neutral), input), { colors: Object.assign(Object.assign({}, preset_neutral.colors), ((_a = input.colors) !== null && _a !== void 0 ? _a : {})), fonts: (_b = input.fonts) !== null && _b !== void 0 ? _b : preset_neutral.fonts, radius: Object.assign(Object.assign({}, ((_c = preset_neutral.radius) !== null && _c !== void 0 ? _c : {})), ((_d = input.radius) !== null && _d !== void 0 ? _d : {})), layout: (_e = input.layout) !== null && _e !== void 0 ? _e : preset_neutral.layout, brandPanel: (_f = input.brandPanel) !== null && _f !== void 0 ? _f : preset_neutral.brandPanel });
12
+ // Step 2: Compute CSS variable overrides
13
+ const colors = merged.colors;
14
+ const radius = (_g = merged.radius) !== null && _g !== void 0 ? _g : { md: "0.5rem" };
15
+ const md = (_h = radius.md) !== null && _h !== void 0 ? _h : "0.5rem";
16
+ // Derive radius values
17
+ const derivedRadius = _derive_radius(md);
18
+ // Build computed overrides
19
+ const computed = {
20
+ "--primary": hex_to_hsl(colors.primary),
21
+ "--primary-foreground": hex_to_hsl(pick_foreground(colors.primary)),
22
+ "--ring": hex_to_hsl(colors.accent),
23
+ "--background": hex_to_hsl(colors.surface),
24
+ "--foreground": hex_to_hsl(colors.textPrimary),
25
+ "--card": hex_to_hsl(colors.surfaceElevated),
26
+ "--card-foreground": hex_to_hsl(pick_foreground(colors.surfaceElevated)),
27
+ "--popover": hex_to_hsl(colors.surfaceElevated),
28
+ "--popover-foreground": hex_to_hsl(pick_foreground(colors.surfaceElevated)),
29
+ "--border": hex_to_hsl(colors.border),
30
+ "--input": hex_to_hsl(colors.border),
31
+ "--muted-foreground": hex_to_hsl(colors.textMuted),
32
+ "--secondary-foreground": hex_to_hsl(colors.textSecondary),
33
+ "--destructive": "0 84% 60%",
34
+ "--destructive-foreground": "0 0% 100%",
35
+ // Derived background tones
36
+ "--secondary": hex_to_hsl(adjust_lightness(colors.surface, -0.03)),
37
+ "--muted": hex_to_hsl(adjust_lightness(colors.surface, -0.06)),
38
+ "--accent": hex_to_hsl(adjust_lightness(colors.surface, -0.04)),
39
+ "--accent-foreground": hex_to_hsl(pick_foreground(adjust_lightness(colors.surface, -0.04))),
40
+ // Radius
41
+ "--radius-sm": derivedRadius.sm,
42
+ "--radius": derivedRadius.md,
43
+ "--radius-lg": derivedRadius.lg,
44
+ "--radius-xl": derivedRadius.xl,
45
+ };
46
+ // Font vars (only if provided)
47
+ if ((_j = merged.fonts) === null || _j === void 0 ? void 0 : _j.display) {
48
+ computed["--font-display"] = merged.fonts.display;
49
+ }
50
+ if ((_k = merged.fonts) === null || _k === void 0 ? void 0 : _k.body) {
51
+ computed["--font-body"] = merged.fonts.body;
52
+ }
53
+ if ((_l = merged.fonts) === null || _l === void 0 ? void 0 : _l.mono) {
54
+ computed["--font-mono"] = merged.fonts.mono;
55
+ }
56
+ // Step 3: Merge user overrides on top (escape hatch — user wins)
57
+ const finalOverrides = Object.assign(Object.assign({}, computed), ((_m = input.overrides) !== null && _m !== void 0 ? _m : {}));
58
+ // Step 4: Return resolved theme
59
+ return Object.assign(Object.assign({}, merged), { overrides: finalOverrides });
60
+ }
61
+ // ---------------------------------------------------------------------------
62
+ // Internal helpers
63
+ // ---------------------------------------------------------------------------
64
+ /**
65
+ * Derives sm, lg, xl radius values from the md value.
66
+ * Handles rem and px units.
67
+ */
68
+ function _derive_radius(md) {
69
+ const remMatch = md.match(/^([\d.]+)rem$/);
70
+ const pxMatch = md.match(/^([\d.]+)px$/);
71
+ if (remMatch) {
72
+ const base = parseFloat(remMatch[1]);
73
+ const unit = "rem";
74
+ return {
75
+ sm: `${_round(base * 0.5)}${unit}`,
76
+ md: md,
77
+ lg: `${_round(base * 1.5)}${unit}`,
78
+ xl: `${_round(base * 2)}${unit}`,
79
+ };
80
+ }
81
+ if (pxMatch) {
82
+ const base = parseFloat(pxMatch[1]);
83
+ const unit = "px";
84
+ return {
85
+ sm: `${_round(base * 0.5)}${unit}`,
86
+ md: md,
87
+ lg: `${_round(base * 1.5)}${unit}`,
88
+ xl: `${_round(base * 2)}${unit}`,
89
+ };
90
+ }
91
+ // Fallback: can't parse, use md for everything
92
+ return { sm: md, md, lg: md, xl: md };
93
+ }
94
+ function _round(n) {
95
+ // Round to 4 decimal places max, but trim trailing zeros
96
+ return parseFloat(n.toFixed(4));
97
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Converts a hex color string to HSL format "H S% L%".
3
+ * Returns shadcn-compatible space-separated string: "<h> <s>% <l>%"
4
+ * Handles: 3-digit hex, uppercase, with or without leading #
5
+ */
6
+ export declare function hex_to_hsl(hex: string): string;
7
+ /**
8
+ * Shifts the L (lightness) channel of a hex color by `delta` (0–1 range of percentage points).
9
+ * e.g. adjust_lightness("#FFFFFF", -0.03) drops L by 3 percentage points.
10
+ * Clamps result to [0, 100]%. Returns a hex string.
11
+ *
12
+ * Note: uses HSL lightness (0–100 scale), NOT WCAG relative luminance (0–1 scale).
13
+ * See luminance.ts for WCAG relative_luminance.
14
+ */
15
+ export declare function adjust_lightness(hex: string, delta: number): string;
16
+ //# sourceMappingURL=hex_to_hsl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hex_to_hsl.d.ts","sourceRoot":"","sources":["../../src/theme/hex_to_hsl.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAG9C;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAMnE"}
@@ -0,0 +1,110 @@
1
+ /**
2
+ * Converts a hex color string to HSL format "H S% L%".
3
+ * Returns shadcn-compatible space-separated string: "<h> <s>% <l>%"
4
+ * Handles: 3-digit hex, uppercase, with or without leading #
5
+ */
6
+ export function hex_to_hsl(hex) {
7
+ const { h, s, l } = _hex_to_hsl_values(hex);
8
+ return `${Math.round(h)} ${Math.round(s)}% ${Math.round(l)}%`;
9
+ }
10
+ /**
11
+ * Shifts the L (lightness) channel of a hex color by `delta` (0–1 range of percentage points).
12
+ * e.g. adjust_lightness("#FFFFFF", -0.03) drops L by 3 percentage points.
13
+ * Clamps result to [0, 100]%. Returns a hex string.
14
+ *
15
+ * Note: uses HSL lightness (0–100 scale), NOT WCAG relative luminance (0–1 scale).
16
+ * See luminance.ts for WCAG relative_luminance.
17
+ */
18
+ export function adjust_lightness(hex, delta) {
19
+ const { h, s, l } = _hex_to_hsl_values(hex);
20
+ // delta is in the same scale as l (0–100)
21
+ const deltaPercent = delta * 100;
22
+ const newL = Math.max(0, Math.min(100, l + deltaPercent));
23
+ return _hsl_to_hex(h, s, newL);
24
+ }
25
+ function _normalize_hex(hex) {
26
+ // Strip leading # if present
27
+ let h = hex.startsWith("#") ? hex.slice(1) : hex;
28
+ // Expand 3-digit shorthand
29
+ if (h.length === 3) {
30
+ h = h[0] + h[0] + h[1] + h[1] + h[2] + h[2];
31
+ }
32
+ return h.toLowerCase();
33
+ }
34
+ function _hex_to_hsl_values(hex) {
35
+ const h = _normalize_hex(hex);
36
+ const r = parseInt(h.slice(0, 2), 16) / 255;
37
+ const g = parseInt(h.slice(2, 4), 16) / 255;
38
+ const b = parseInt(h.slice(4, 6), 16) / 255;
39
+ const max = Math.max(r, g, b);
40
+ const min = Math.min(r, g, b);
41
+ const delta = max - min;
42
+ // Lightness
43
+ const l = (max + min) / 2;
44
+ // Saturation
45
+ let s = 0;
46
+ if (delta !== 0) {
47
+ s = delta / (1 - Math.abs(2 * l - 1));
48
+ }
49
+ // Hue
50
+ let hue = 0;
51
+ if (delta !== 0) {
52
+ if (max === r) {
53
+ hue = ((g - b) / delta) % 6;
54
+ }
55
+ else if (max === g) {
56
+ hue = (b - r) / delta + 2;
57
+ }
58
+ else {
59
+ hue = (r - g) / delta + 4;
60
+ }
61
+ hue = hue * 60;
62
+ if (hue < 0)
63
+ hue += 360;
64
+ }
65
+ return { h: hue, s: s * 100, l: l * 100 };
66
+ }
67
+ function _hsl_to_hex(h, s, l) {
68
+ // Normalize s, l to 0–1
69
+ const sN = s / 100;
70
+ const lN = l / 100;
71
+ const c = (1 - Math.abs(2 * lN - 1)) * sN;
72
+ const x = c * (1 - Math.abs(((h / 60) % 2) - 1));
73
+ const m = lN - c / 2;
74
+ let r = 0, g = 0, b = 0;
75
+ if (h >= 0 && h < 60) {
76
+ r = c;
77
+ g = x;
78
+ b = 0;
79
+ }
80
+ else if (h >= 60 && h < 120) {
81
+ r = x;
82
+ g = c;
83
+ b = 0;
84
+ }
85
+ else if (h >= 120 && h < 180) {
86
+ r = 0;
87
+ g = c;
88
+ b = x;
89
+ }
90
+ else if (h >= 180 && h < 240) {
91
+ r = 0;
92
+ g = x;
93
+ b = c;
94
+ }
95
+ else if (h >= 240 && h < 300) {
96
+ r = x;
97
+ g = 0;
98
+ b = c;
99
+ }
100
+ else {
101
+ r = c;
102
+ g = 0;
103
+ b = x;
104
+ }
105
+ const toHex = (n) => {
106
+ const val = Math.round((n + m) * 255);
107
+ return Math.max(0, Math.min(255, val)).toString(16).padStart(2, "0");
108
+ };
109
+ return `#${toHex(r)}${toHex(g)}${toHex(b)}`;
110
+ }
@@ -0,0 +1,4 @@
1
+ export * from "./theme_types.js";
2
+ export * from "./create_theme.js";
3
+ export * from "./theme_provider.js";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/theme/index.ts"],"names":[],"mappings":"AAAA,cAAc,eAAe,CAAC;AAC9B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,kBAAkB,CAAC"}
@@ -0,0 +1,3 @@
1
+ export * from "./theme_types.js";
2
+ export * from "./create_theme.js";
3
+ export * from "./theme_provider.js";
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Calculates the relative luminance of a hex color per WCAG 2.1.
3
+ * Returns a value between 0 (black) and 1 (white).
4
+ */
5
+ export declare function relative_luminance(hex: string): number;
6
+ /**
7
+ * Returns the foreground color (light or dark) with best contrast against bg_hex.
8
+ * Uses WCAG contrast ratio formula.
9
+ */
10
+ export declare function pick_foreground(bg_hex: string, light_hex?: string, dark_hex?: string): string;
11
+ //# sourceMappingURL=luminance.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"luminance.d.ts","sourceRoot":"","sources":["../../src/theme/luminance.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAStD;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,EACd,SAAS,GAAE,MAAkB,EAC7B,QAAQ,GAAE,MAAkB,GAC3B,MAAM,CAeR"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Calculates the relative luminance of a hex color per WCAG 2.1.
3
+ * Returns a value between 0 (black) and 1 (white).
4
+ */
5
+ export function relative_luminance(hex) {
6
+ const { r, g, b } = _hex_to_rgb(hex);
7
+ const linearize = (c) => {
8
+ const normalized = c / 255;
9
+ return normalized <= 0.04045
10
+ ? normalized / 12.92
11
+ : Math.pow((normalized + 0.055) / 1.055, 2.4);
12
+ };
13
+ return 0.2126 * linearize(r) + 0.7152 * linearize(g) + 0.0722 * linearize(b);
14
+ }
15
+ /**
16
+ * Returns the foreground color (light or dark) with best contrast against bg_hex.
17
+ * Uses WCAG contrast ratio formula.
18
+ */
19
+ export function pick_foreground(bg_hex, light_hex = "#FFFFFF", dark_hex = "#0F172A") {
20
+ const bgL = relative_luminance(bg_hex);
21
+ const lightL = relative_luminance(light_hex);
22
+ const darkL = relative_luminance(dark_hex);
23
+ const contrast_ratio = (l1, l2) => {
24
+ const lighter = Math.max(l1, l2);
25
+ const darker = Math.min(l1, l2);
26
+ return (lighter + 0.05) / (darker + 0.05);
27
+ };
28
+ const lightContrast = contrast_ratio(bgL, lightL);
29
+ const darkContrast = contrast_ratio(bgL, darkL);
30
+ return lightContrast >= darkContrast ? light_hex : dark_hex;
31
+ }
32
+ // ---------------------------------------------------------------------------
33
+ // Internal helpers
34
+ // ---------------------------------------------------------------------------
35
+ function _hex_to_rgb(hex) {
36
+ let h = hex.startsWith("#") ? hex.slice(1) : hex;
37
+ if (h.length === 3) {
38
+ h = h[0] + h[0] + h[1] + h[1] + h[2] + h[2];
39
+ }
40
+ return {
41
+ r: parseInt(h.slice(0, 2), 16),
42
+ g: parseInt(h.slice(2, 4), 16),
43
+ b: parseInt(h.slice(4, 6), 16),
44
+ };
45
+ }
@@ -0,0 +1,14 @@
1
+ import type { HazoAuthTheme } from "./theme_types";
2
+ /**
3
+ * Server Component that injects theme CSS variables into the page at SSR time.
4
+ * Wraps children in a div with a style tag containing :root overrides.
5
+ * CSS variable values are derived from the theme object — all values are hex
6
+ * colors converted to HSL strings (e.g. "244 55% 41%") or rem/px radius
7
+ * values, so they cannot contain HTML or script injection.
8
+ * No "use client" — runs on the server.
9
+ */
10
+ export declare function HazoAuthThemeProvider({ theme, children, }: {
11
+ theme: HazoAuthTheme;
12
+ children: React.ReactNode;
13
+ }): import("react/jsx-runtime").JSX.Element;
14
+ //# sourceMappingURL=theme_provider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme_provider.d.ts","sourceRoot":"","sources":["../../src/theme/theme_provider.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEnD;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,EACpC,KAAK,EACL,QAAQ,GACT,EAAE;IACD,KAAK,EAAE,aAAa,CAAC;IACrB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,2CAgBA"}
@@ -0,0 +1,23 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ // file_description: Server Component that applies a HazoAuthTheme via CSS variables injected at SSR time
3
+ // NO "use client" — this is intentionally a Server Component
4
+ import { createTheme } from "./create_theme.js";
5
+ /**
6
+ * Server Component that injects theme CSS variables into the page at SSR time.
7
+ * Wraps children in a div with a style tag containing :root overrides.
8
+ * CSS variable values are derived from the theme object — all values are hex
9
+ * colors converted to HSL strings (e.g. "244 55% 41%") or rem/px radius
10
+ * values, so they cannot contain HTML or script injection.
11
+ * No "use client" — runs on the server.
12
+ */
13
+ export function HazoAuthThemeProvider({ theme, children, }) {
14
+ var _a;
15
+ const resolved = createTheme(theme);
16
+ const cssVars = Object.entries((_a = resolved.overrides) !== null && _a !== void 0 ? _a : {})
17
+ .map(([key, val]) => `${key}: ${val};`)
18
+ .join(" ");
19
+ // CSS variable values come from createTheme which produces only HSL strings,
20
+ // rem/px values, and font family tokens — never raw user HTML.
21
+ const css = `:root { ${cssVars} }`;
22
+ return (_jsxs("div", { "data-hazo-auth-theme": "true", children: [_jsx("style", { dangerouslySetInnerHTML: { __html: css } }), children] }));
23
+ }
@@ -0,0 +1,36 @@
1
+ export interface HazoAuthTheme {
2
+ colors: {
3
+ primary: string;
4
+ accent: string;
5
+ surface: string;
6
+ surfaceElevated: string;
7
+ border: string;
8
+ textPrimary: string;
9
+ textSecondary: string;
10
+ textMuted: string;
11
+ };
12
+ fonts?: {
13
+ display?: string;
14
+ body?: string;
15
+ mono?: string;
16
+ };
17
+ radius?: {
18
+ sm?: string;
19
+ md?: string;
20
+ lg?: string;
21
+ xl?: string;
22
+ };
23
+ layout: "split" | "centered";
24
+ brandPanel?: {
25
+ logoSrc: string;
26
+ tagline?: string;
27
+ backgroundGradient?: string;
28
+ accentImage?: string;
29
+ };
30
+ overrides?: Record<string, string>;
31
+ }
32
+ export type ResolvedTheme = Required<HazoAuthTheme> & {
33
+ colors: Required<HazoAuthTheme["colors"]>;
34
+ radius: Required<NonNullable<HazoAuthTheme["radius"]>>;
35
+ };
36
+ //# sourceMappingURL=theme_types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"theme_types.d.ts","sourceRoot":"","sources":["../../src/theme/theme_types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE;QACN,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,EAAE,MAAM,CAAC;QACf,OAAO,EAAE,MAAM,CAAC;QAChB,eAAe,EAAE,MAAM,CAAC;QACxB,MAAM,EAAE,MAAM,CAAC;QACf,WAAW,EAAE,MAAM,CAAC;QACpB,aAAa,EAAE,MAAM,CAAC;QACtB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;IACF,KAAK,CAAC,EAAE;QACN,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;IACF,MAAM,CAAC,EAAE;QACP,EAAE,CAAC,EAAE,MAAM,CAAC;QACZ,EAAE,CAAC,EAAE,MAAM,CAAC;QACZ,EAAE,CAAC,EAAE,MAAM,CAAC;QACZ,EAAE,CAAC,EAAE,MAAM,CAAC;KACb,CAAC;IACF,MAAM,EAAE,OAAO,GAAG,UAAU,CAAC;IAC7B,UAAU,CAAC,EAAE;QACX,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,kBAAkB,CAAC,EAAE,MAAM,CAAC;QAC5B,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpC;AAGD,MAAM,MAAM,aAAa,GAAG,QAAQ,CAAC,aAAa,CAAC,GAAG;IACpD,MAAM,EAAE,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC1C,MAAM,EAAE,QAAQ,CAAC,WAAW,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;CACxD,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,3 @@
1
+ export { preset_neutral } from "./preset_neutral.js";
2
+ export { preset_indigo_sunset } from "./preset_indigo_sunset.js";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/themes/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { preset_neutral } from "./preset_neutral.js";
2
+ export { preset_indigo_sunset } from "./preset_indigo_sunset.js";
@@ -0,0 +1,3 @@
1
+ import type { HazoAuthTheme } from "../theme/theme_types";
2
+ export declare const preset_indigo_sunset: HazoAuthTheme;
3
+ //# sourceMappingURL=preset_indigo_sunset.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preset_indigo_sunset.d.ts","sourceRoot":"","sources":["../../src/themes/preset_indigo_sunset.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D,eAAO,MAAM,oBAAoB,EAAE,aAmBlC,CAAC"}
@@ -0,0 +1,20 @@
1
+ export const preset_indigo_sunset = {
2
+ colors: {
3
+ primary: "#3730A3",
4
+ accent: "#F59E0B",
5
+ surface: "#FFFFFF",
6
+ surfaceElevated: "#FAFAFA",
7
+ border: "#E5E7EB",
8
+ textPrimary: "#111827",
9
+ textSecondary: "#374151",
10
+ textMuted: "#6B7280",
11
+ },
12
+ fonts: { display: "var(--font-display)", body: "var(--font-body)" },
13
+ radius: { md: "0.5rem" },
14
+ layout: "split",
15
+ brandPanel: {
16
+ logoSrc: "/hazo_auth/images/preset_indigo_sunset_logo_placeholder.svg",
17
+ tagline: "Welcome.",
18
+ backgroundGradient: "linear-gradient(135deg, #3730A3 0%, #F59E0B 100%)",
19
+ },
20
+ };
@@ -0,0 +1,3 @@
1
+ import type { HazoAuthTheme } from "../theme/theme_types";
2
+ export declare const preset_neutral: HazoAuthTheme;
3
+ //# sourceMappingURL=preset_neutral.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"preset_neutral.d.ts","sourceRoot":"","sources":["../../src/themes/preset_neutral.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D,eAAO,MAAM,cAAc,EAAE,aAa5B,CAAC"}
@@ -0,0 +1,14 @@
1
+ export const preset_neutral = {
2
+ colors: {
3
+ primary: "#475569",
4
+ accent: "#475569",
5
+ surface: "#FFFFFF",
6
+ surfaceElevated: "#F8FAFC",
7
+ border: "#E2E8F0",
8
+ textPrimary: "#0F172A",
9
+ textSecondary: "#475569",
10
+ textMuted: "#64748B",
11
+ },
12
+ radius: { md: "0.5rem" },
13
+ layout: "centered",
14
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hazo_auth",
3
- "version": "6.0.0",
3
+ "version": "7.0.1",
4
4
  "description": "Zero-config authentication UI components for Next.js with RBAC, OAuth, scope-based multi-tenancy, and invitations",
5
5
  "keywords": [
6
6
  "authentication",
@@ -45,6 +45,22 @@
45
45
  "types": "./dist/server-lib.d.ts",
46
46
  "import": "./dist/server-lib.js"
47
47
  },
48
+ "./consent": {
49
+ "types": "./dist/consent/index.d.ts",
50
+ "import": "./dist/consent/index.js"
51
+ },
52
+ "./strings": {
53
+ "types": "./dist/strings/index.d.ts",
54
+ "import": "./dist/strings/index.js"
55
+ },
56
+ "./theme": {
57
+ "types": "./dist/theme/index.d.ts",
58
+ "import": "./dist/theme/index.js"
59
+ },
60
+ "./themes": {
61
+ "types": "./dist/themes/index.d.ts",
62
+ "import": "./dist/themes/index.js"
63
+ },
48
64
  "./components/layouts/login": {
49
65
  "types": "./dist/components/layouts/login/index.d.ts",
50
66
  "import": "./dist/components/layouts/login/index.js"
@@ -81,6 +97,10 @@
81
97
  "types": "./dist/components/layouts/create_firm/index.d.ts",
82
98
  "import": "./dist/components/layouts/create_firm/index.js"
83
99
  },
100
+ "./components/layouts/otp": {
101
+ "types": "./dist/components/layouts/otp/index.d.ts",
102
+ "import": "./dist/components/layouts/otp/index.js"
103
+ },
84
104
  "./components/layouts/shared": {
85
105
  "types": "./dist/components/layouts/shared/index.d.ts",
86
106
  "import": "./dist/components/layouts/shared/index.js"
@@ -113,6 +133,10 @@
113
133
  "types": "./dist/server_pages/login.d.ts",
114
134
  "import": "./dist/server_pages/login.js"
115
135
  },
136
+ "./pages/otp": {
137
+ "types": "./dist/server_pages/otp.d.ts",
138
+ "import": "./dist/server_pages/otp.js"
139
+ },
116
140
  "./pages/register": {
117
141
  "types": "./dist/server_pages/register.d.ts",
118
142
  "import": "./dist/server_pages/register.js"
@@ -141,6 +165,10 @@
141
165
  "types": "./dist/page_components/login.d.ts",
142
166
  "import": "./dist/page_components/login.js"
143
167
  },
168
+ "./page_components/otp": {
169
+ "types": "./dist/page_components/otp.d.ts",
170
+ "import": "./dist/page_components/otp.js"
171
+ },
144
172
  "./page_components/register": {
145
173
  "types": "./dist/page_components/register.d.ts",
146
174
  "import": "./dist/page_components/register.js"
@@ -205,7 +233,8 @@
205
233
  "migrate": "tsx scripts/apply_migration.ts",
206
234
  "init-users": "tsx scripts/init_users.ts init_users",
207
235
  "test": "cross-env NODE_ENV=test POSTGREST_URL=http://209.38.26.241:4402 POSTGREST_API_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiYXBpX3VzZXIifQ.zBoUGymrxTUk1DNYIGUCtQU4HFaWEHlbE9_8Y3hUaTw jest --runInBand",
208
- "test:watch": "cross-env NODE_ENV=test POSTGREST_URL=http://209.38.26.241:4402 POSTGREST_API_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiYXBpX3VzZXIifQ.zBoUGymrxTUk1DNYIGUCtQU4HFaWEHlbE9_8Y3hUaTw jest --watch"
236
+ "test:watch": "cross-env NODE_ENV=test POSTGREST_URL=http://209.38.26.241:4402 POSTGREST_API_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiYXBpX3VzZXIifQ.zBoUGymrxTUk1DNYIGUCtQU4HFaWEHlbE9_8Y3hUaTw jest --watch",
237
+ "autotest:browser": "tsx scripts/autotest_browser.ts"
209
238
  },
210
239
  "dependencies": {
211
240
  "axios": "^1.13.2",
@@ -254,6 +283,7 @@
254
283
  "hazo_logs": "^1.0.13",
255
284
  "hazo_notify": "^3.0.0",
256
285
  "hazo_ui": "^2.7.0",
286
+ "input-otp": "^1.4.0",
257
287
  "lucide-react": "^0.553.0",
258
288
  "next": ">=14.0.0",
259
289
  "next-auth": "^4.24.0",
@@ -278,6 +308,9 @@
278
308
  "hazo_ui": {
279
309
  "optional": true
280
310
  },
311
+ "input-otp": {
312
+ "optional": true
313
+ },
281
314
  "next-themes": {
282
315
  "optional": true
283
316
  },
@@ -380,6 +413,7 @@
380
413
  "hazo_ui": "^2.7.0",
381
414
  "jest": "^30.2.0",
382
415
  "jest-environment-jsdom": "^30.0.0",
416
+ "input-otp": "^1.4.0",
383
417
  "lucide-react": "^0.553.0",
384
418
  "next": "^16.0.7",
385
419
  "next-auth": "^4.24.13",