hazo_auth 6.1.1 → 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.
- package/README.md +163 -8
- package/SETUP_CHECKLIST.md +148 -0
- package/cli-src/lib/auth/nextauth_config.ts +101 -1
- package/cli-src/lib/email_verification_config.server.ts +0 -34
- package/cli-src/lib/forgot_password_config.server.ts +0 -34
- package/cli-src/lib/login_config.server.ts +0 -31
- package/cli-src/lib/my_settings_config.server.ts +0 -3
- package/cli-src/lib/oauth_config.server.ts +58 -0
- package/cli-src/lib/register_config.server.ts +11 -31
- package/cli-src/lib/reset_password_config.server.ts +0 -31
- package/cli-src/lib/services/oauth_service.ts +197 -0
- package/config/hazo_auth_config.example.ini +38 -41
- package/dist/components/layouts/create_firm/index.d.ts +4 -8
- package/dist/components/layouts/create_firm/index.d.ts.map +1 -1
- package/dist/components/layouts/create_firm/index.js +3 -3
- package/dist/components/layouts/email_verification/index.d.ts +4 -5
- package/dist/components/layouts/email_verification/index.d.ts.map +1 -1
- package/dist/components/layouts/email_verification/index.js +4 -4
- package/dist/components/layouts/forgot_password/index.d.ts +4 -5
- package/dist/components/layouts/forgot_password/index.d.ts.map +1 -1
- package/dist/components/layouts/forgot_password/index.js +2 -2
- package/dist/components/layouts/login/index.d.ts +13 -9
- package/dist/components/layouts/login/index.d.ts.map +1 -1
- package/dist/components/layouts/login/index.js +12 -6
- package/dist/components/layouts/otp/index.d.ts +8 -1
- package/dist/components/layouts/otp/index.d.ts.map +1 -1
- package/dist/components/layouts/otp/index.js +4 -2
- package/dist/components/layouts/register/index.d.ts +11 -7
- package/dist/components/layouts/register/index.d.ts.map +1 -1
- package/dist/components/layouts/register/index.js +8 -4
- package/dist/components/layouts/reset_password/index.d.ts +4 -5
- package/dist/components/layouts/reset_password/index.d.ts.map +1 -1
- package/dist/components/layouts/reset_password/index.js +5 -5
- package/dist/components/layouts/shared/components/already_logged_in_guard.d.ts +3 -5
- package/dist/components/layouts/shared/components/already_logged_in_guard.d.ts.map +1 -1
- package/dist/components/layouts/shared/components/already_logged_in_guard.js +2 -2
- package/dist/components/layouts/shared/components/facebook_sign_in_button.d.ts +25 -0
- package/dist/components/layouts/shared/components/facebook_sign_in_button.d.ts.map +1 -0
- package/dist/components/layouts/shared/components/facebook_sign_in_button.js +49 -0
- package/dist/components/layouts/shared/components/sidebar_layout_wrapper.js +1 -1
- package/dist/components/layouts/shared/components/two_column_auth_layout.d.ts +3 -6
- package/dist/components/layouts/shared/components/two_column_auth_layout.d.ts.map +1 -1
- package/dist/components/layouts/shared/components/two_column_auth_layout.js +8 -5
- package/dist/consent/consent_state.d.ts +18 -0
- package/dist/consent/consent_state.d.ts.map +1 -0
- package/dist/consent/consent_state.js +29 -0
- package/dist/consent/cookie_consent_banner.d.ts +11 -0
- package/dist/consent/cookie_consent_banner.d.ts.map +1 -0
- package/dist/consent/cookie_consent_banner.js +40 -0
- package/dist/consent/gtm_mapping.d.ts +13 -0
- package/dist/consent/gtm_mapping.d.ts.map +1 -0
- package/dist/consent/gtm_mapping.js +30 -0
- package/dist/consent/index.d.ts +7 -0
- package/dist/consent/index.d.ts.map +1 -0
- package/dist/consent/index.js +7 -0
- package/dist/consent/manage_modal.d.ts +2 -0
- package/dist/consent/manage_modal.d.ts.map +1 -0
- package/dist/consent/manage_modal.js +33 -0
- package/dist/consent/read_consent.d.ts +15 -0
- package/dist/consent/read_consent.d.ts.map +1 -0
- package/dist/consent/read_consent.js +23 -0
- package/dist/consent/use_consent.d.ts +7 -0
- package/dist/consent/use_consent.d.ts.map +1 -0
- package/dist/consent/use_consent.js +55 -0
- package/dist/lib/auth/nextauth_config.d.ts +10 -0
- package/dist/lib/auth/nextauth_config.d.ts.map +1 -1
- package/dist/lib/auth/nextauth_config.js +80 -2
- package/dist/lib/email_verification_config.server.d.ts +0 -3
- package/dist/lib/email_verification_config.server.d.ts.map +1 -1
- package/dist/lib/email_verification_config.server.js +0 -15
- package/dist/lib/forgot_password_config.server.d.ts +0 -3
- package/dist/lib/forgot_password_config.server.d.ts.map +1 -1
- package/dist/lib/forgot_password_config.server.js +0 -15
- package/dist/lib/login_config.server.d.ts +0 -3
- package/dist/lib/login_config.server.d.ts.map +1 -1
- package/dist/lib/login_config.server.js +0 -13
- package/dist/lib/my_settings_config.server.d.ts +0 -1
- package/dist/lib/my_settings_config.server.d.ts.map +1 -1
- package/dist/lib/my_settings_config.server.js +0 -2
- package/dist/lib/oauth_config.server.d.ts +17 -0
- package/dist/lib/oauth_config.server.d.ts.map +1 -1
- package/dist/lib/oauth_config.server.js +25 -0
- package/dist/lib/register_config.server.d.ts +2 -3
- package/dist/lib/register_config.server.d.ts.map +1 -1
- package/dist/lib/register_config.server.js +4 -13
- package/dist/lib/reset_password_config.server.d.ts +0 -3
- package/dist/lib/reset_password_config.server.d.ts.map +1 -1
- package/dist/lib/reset_password_config.server.js +0 -13
- package/dist/lib/services/oauth_service.d.ts +24 -0
- package/dist/lib/services/oauth_service.d.ts.map +1 -1
- package/dist/lib/services/oauth_service.js +155 -0
- package/dist/page_components/create_firm.d.ts +13 -1
- package/dist/page_components/create_firm.d.ts.map +1 -1
- package/dist/page_components/create_firm.js +10 -6
- package/dist/page_components/forgot_password.d.ts +1 -4
- package/dist/page_components/forgot_password.d.ts.map +1 -1
- package/dist/page_components/forgot_password.js +2 -6
- package/dist/page_components/login.d.ts +1 -4
- package/dist/page_components/login.d.ts.map +1 -1
- package/dist/page_components/login.js +2 -6
- package/dist/page_components/register.d.ts +1 -4
- package/dist/page_components/register.d.ts.map +1 -1
- package/dist/page_components/register.js +2 -6
- package/dist/page_components/reset_password.d.ts +1 -4
- package/dist/page_components/reset_password.d.ts.map +1 -1
- package/dist/page_components/reset_password.js +2 -6
- package/dist/page_components/verify_email.d.ts +1 -4
- package/dist/page_components/verify_email.d.ts.map +1 -1
- package/dist/page_components/verify_email.js +2 -6
- package/dist/server/routes/index.d.ts +1 -0
- package/dist/server/routes/index.d.ts.map +1 -1
- package/dist/server/routes/index.js +1 -0
- package/dist/server/routes/oauth_facebook_callback.d.ts +8 -0
- package/dist/server/routes/oauth_facebook_callback.d.ts.map +1 -0
- package/dist/server/routes/oauth_facebook_callback.js +157 -0
- package/dist/server/routes/oauth_google_callback.js +1 -1
- package/dist/server_pages/forgot_password.d.ts +13 -17
- package/dist/server_pages/forgot_password.d.ts.map +1 -1
- package/dist/server_pages/forgot_password.js +12 -8
- package/dist/server_pages/forgot_password_client_wrapper.d.ts +7 -6
- package/dist/server_pages/forgot_password_client_wrapper.d.ts.map +1 -1
- package/dist/server_pages/forgot_password_client_wrapper.js +2 -2
- package/dist/server_pages/login.d.ts +22 -21
- package/dist/server_pages/login.d.ts.map +1 -1
- package/dist/server_pages/login.js +15 -19
- package/dist/server_pages/login_client_wrapper.d.ts +10 -6
- package/dist/server_pages/login_client_wrapper.d.ts.map +1 -1
- package/dist/server_pages/login_client_wrapper.js +2 -2
- package/dist/server_pages/my_settings.d.ts +2 -0
- package/dist/server_pages/my_settings.d.ts.map +1 -1
- package/dist/server_pages/my_settings.js +8 -2
- package/dist/server_pages/otp.d.ts +16 -2
- package/dist/server_pages/otp.d.ts.map +1 -1
- package/dist/server_pages/otp.js +10 -3
- package/dist/server_pages/register.d.ts +19 -16
- package/dist/server_pages/register.d.ts.map +1 -1
- package/dist/server_pages/register.js +15 -12
- package/dist/server_pages/register_client_wrapper.d.ts +10 -6
- package/dist/server_pages/register_client_wrapper.d.ts.map +1 -1
- package/dist/server_pages/register_client_wrapper.js +2 -2
- package/dist/server_pages/reset_password.d.ts +11 -16
- package/dist/server_pages/reset_password.d.ts.map +1 -1
- package/dist/server_pages/reset_password.js +11 -9
- package/dist/server_pages/reset_password_client_wrapper.d.ts +7 -6
- package/dist/server_pages/reset_password_client_wrapper.d.ts.map +1 -1
- package/dist/server_pages/reset_password_client_wrapper.js +2 -2
- package/dist/server_pages/verify_email.d.ts +11 -17
- package/dist/server_pages/verify_email.d.ts.map +1 -1
- package/dist/server_pages/verify_email.js +11 -8
- package/dist/server_pages/verify_email_client_wrapper.d.ts +7 -6
- package/dist/server_pages/verify_email_client_wrapper.d.ts.map +1 -1
- package/dist/server_pages/verify_email_client_wrapper.js +2 -2
- package/dist/strings/default_strings.d.ts +47 -0
- package/dist/strings/default_strings.d.ts.map +1 -0
- package/dist/strings/default_strings.js +18 -0
- package/dist/strings/index.d.ts +4 -0
- package/dist/strings/index.d.ts.map +1 -0
- package/dist/strings/index.js +3 -0
- package/dist/strings/strings_context.d.ts +12 -0
- package/dist/strings/strings_context.d.ts.map +1 -0
- package/dist/strings/strings_context.js +23 -0
- package/dist/strings/strings_provider.d.ts +26 -0
- package/dist/strings/strings_provider.d.ts.map +1 -0
- package/dist/strings/strings_provider.js +45 -0
- package/dist/theme/create_theme.d.ts +7 -0
- package/dist/theme/create_theme.d.ts.map +1 -0
- package/dist/theme/create_theme.js +97 -0
- package/dist/theme/hex_to_hsl.d.ts +16 -0
- package/dist/theme/hex_to_hsl.d.ts.map +1 -0
- package/dist/theme/hex_to_hsl.js +110 -0
- package/dist/theme/index.d.ts +4 -0
- package/dist/theme/index.d.ts.map +1 -0
- package/dist/theme/index.js +3 -0
- package/dist/theme/luminance.d.ts +11 -0
- package/dist/theme/luminance.d.ts.map +1 -0
- package/dist/theme/luminance.js +45 -0
- package/dist/theme/theme_provider.d.ts +14 -0
- package/dist/theme/theme_provider.d.ts.map +1 -0
- package/dist/theme/theme_provider.js +23 -0
- package/dist/theme/theme_types.d.ts +36 -0
- package/dist/theme/theme_types.d.ts.map +1 -0
- package/dist/theme/theme_types.js +1 -0
- package/dist/themes/index.d.ts +3 -0
- package/dist/themes/index.d.ts.map +1 -0
- package/dist/themes/index.js +2 -0
- package/dist/themes/preset_indigo_sunset.d.ts +3 -0
- package/dist/themes/preset_indigo_sunset.d.ts.map +1 -0
- package/dist/themes/preset_indigo_sunset.js +20 -0
- package/dist/themes/preset_neutral.d.ts +3 -0
- package/dist/themes/preset_neutral.d.ts.map +1 -0
- package/dist/themes/preset_neutral.js +14 -0
- package/package.json +19 -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 @@
|
|
|
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,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 @@
|
|
|
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 @@
|
|
|
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 @@
|
|
|
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": "
|
|
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"
|
|
@@ -217,7 +233,8 @@
|
|
|
217
233
|
"migrate": "tsx scripts/apply_migration.ts",
|
|
218
234
|
"init-users": "tsx scripts/init_users.ts init_users",
|
|
219
235
|
"test": "cross-env NODE_ENV=test POSTGREST_URL=http://209.38.26.241:4402 POSTGREST_API_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiYXBpX3VzZXIifQ.zBoUGymrxTUk1DNYIGUCtQU4HFaWEHlbE9_8Y3hUaTw jest --runInBand",
|
|
220
|
-
"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"
|
|
221
238
|
},
|
|
222
239
|
"dependencies": {
|
|
223
240
|
"axios": "^1.13.2",
|