@classic-homes/auth 1.2.0 → 1.8.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.
@@ -0,0 +1,3 @@
1
+ export { authActions, authStore, currentUser, isAuthenticated } from './chunk-EBTCVIUQ.js';
2
+ import './chunk-HVOZBQIF.js';
3
+ import './chunk-X7KH4DDN.js';
@@ -1,5 +1,5 @@
1
- import { authApi } from './chunk-GKS5EDOT.js';
2
- import { isInitialized, getConfig, hasRole, hasAnyRole, hasAllRoles, decodeJWT, getStorage, getDefaultStorage } from './chunk-VFEGS6FR.js';
1
+ import { authApi } from './chunk-HVOZBQIF.js';
2
+ import { isInitialized, getConfig, hasRole, hasAnyRole, hasAllRoles, decodeJWT, getStorage, getDefaultStorage } from './chunk-X7KH4DDN.js';
3
3
 
4
4
  // src/svelte/stores/auth.svelte.ts
5
5
  var STORAGE_VERSION = 2;
@@ -1,4 +1,4 @@
1
- import { getConfig, getStorage, getFetch, isValidRedirectUrl } from './chunk-VFEGS6FR.js';
1
+ import { getConfig, getStorage, getFetch, isValidRedirectUrl } from './chunk-X7KH4DDN.js';
2
2
 
3
3
  // src/core/client.ts
4
4
  var isRefreshing = false;
@@ -77,7 +77,7 @@ function updateStoredTokens(accessToken, refreshToken) {
77
77
  parsed.accessToken = accessToken;
78
78
  parsed.refreshToken = refreshToken;
79
79
  storage.setItem(storageKey, JSON.stringify(parsed));
80
- import('./auth.svelte-MGVCAICX.js').then(({ authStore }) => {
80
+ import('./auth.svelte-FIHKI5BD.js').then(({ authStore }) => {
81
81
  authStore.updateTokens(accessToken, refreshToken);
82
82
  }).catch(() => {
83
83
  });
@@ -92,7 +92,7 @@ function clearStoredAuth() {
92
92
  async function expireSession() {
93
93
  clearStoredAuth();
94
94
  try {
95
- const { authStore } = await import('./auth.svelte-MGVCAICX.js');
95
+ const { authStore } = await import('./auth.svelte-FIHKI5BD.js');
96
96
  authStore.handleSessionExpired();
97
97
  } catch {
98
98
  }
@@ -302,8 +302,8 @@ async function apiRequestInternal(endpoint, options, isRetry) {
302
302
  }
303
303
  }
304
304
  if (!response.ok) {
305
- const dataObj = data;
306
- const errorMessage = data.error?.message || (typeof dataObj.message === "string" ? dataObj.message : void 0) || data.meta?.message || (typeof dataObj.detail === "string" ? dataObj.detail : void 0) || `Request failed (${response.status})`;
305
+ const errorBody = data ?? {};
306
+ const errorMessage = errorBody.error?.message || (typeof errorBody.message === "string" ? errorBody.message : void 0) || errorBody.meta?.message || (typeof errorBody.detail === "string" ? errorBody.detail : void 0) || `Request failed (${response.status})`;
307
307
  const error = new Error(errorMessage);
308
308
  config.onAuthError?.(error);
309
309
  throw error;
@@ -1,5 +1,5 @@
1
- import { authApi } from './chunk-GKS5EDOT.js';
2
- import { getUserRoles, hasAnyRole } from './chunk-VFEGS6FR.js';
1
+ import { authApi } from './chunk-HVOZBQIF.js';
2
+ import { getUserRoles, hasAnyRole } from './chunk-X7KH4DDN.js';
3
3
 
4
4
  // src/core/guards.ts
5
5
  function isMfaChallengeResponse(response) {
@@ -59,7 +59,7 @@ var AuthService = class {
59
59
  }
60
60
  if (options?.autoSetAuth !== false && !isMfaChallengeResponse(response)) {
61
61
  try {
62
- const { authStore } = await import('./auth.svelte-MGVCAICX.js');
62
+ const { authStore } = await import('./auth.svelte-FIHKI5BD.js');
63
63
  authStore.setAuth(
64
64
  response.accessToken,
65
65
  response.refreshToken,
@@ -245,7 +245,7 @@ var AuthService = class {
245
245
  }
246
246
  if (options?.autoSetAuth !== false) {
247
247
  try {
248
- const { authStore } = await import('./auth.svelte-MGVCAICX.js');
248
+ const { authStore } = await import('./auth.svelte-FIHKI5BD.js');
249
249
  authStore.setAuth(
250
250
  response.accessToken,
251
251
  response.refreshToken,
@@ -1,6 +1,6 @@
1
- import { authService } from './chunk-7OXE7SAW.js';
2
- import { authStore, currentUser, isAuthenticated, authActions } from './chunk-LMFSLTIV.js';
3
- import { isInitialized, initAuth, getUserRoles } from './chunk-VFEGS6FR.js';
1
+ import { authService } from './chunk-QTX7L4QY.js';
2
+ import { authStore, currentUser, isAuthenticated, authActions } from './chunk-EBTCVIUQ.js';
3
+ import { isInitialized, initAuth, getUserRoles } from './chunk-X7KH4DDN.js';
4
4
 
5
5
  // src/svelte/guards/auth-guard.ts
6
6
  function checkAuth(options = {}) {
@@ -171,6 +171,7 @@ var ROLE_NAMES = [
171
171
  "marketing_staff",
172
172
  "purchasing_staff",
173
173
  "sales_staff",
174
+ "stormwater_staff",
174
175
  "warranty_staff",
175
176
  "employee",
176
177
  "user",
@@ -204,6 +205,7 @@ var ROLE_HIERARCHY = {
204
205
  marketing_staff: 2,
205
206
  purchasing_staff: 2,
206
207
  sales_staff: 2,
208
+ stormwater_staff: 2,
207
209
  warranty_staff: 2,
208
210
  manager: 3,
209
211
  admin: 4
@@ -20,6 +20,14 @@ interface ApiRequestOptions extends Omit<RequestInit, 'body' | 'signal'> {
20
20
  /** AbortSignal for manual cancellation */
21
21
  signal?: AbortSignal;
22
22
  }
23
+ /**
24
+ * The CHAPI envelope shape, for endpoints that wrap their payload in `data`.
25
+ *
26
+ * NOTE: this is NOT the return type of `apiRequest`/`api.*`. Those resolve to
27
+ * the parsed response body itself — pass the envelope as the type argument
28
+ * (`api.get<{ data: User }>(...)`) and unwrap with `extractData` when the
29
+ * endpoint actually wraps. Many CHAPI endpoints return their payload bare.
30
+ */
23
31
  interface ApiResponse<T = unknown> {
24
32
  data?: T;
25
33
  meta?: {
@@ -72,16 +80,16 @@ declare function extractData<T>(response: {
72
80
  /**
73
81
  * Make an API request.
74
82
  */
75
- declare function apiRequest<T = unknown>(endpoint: string, options?: ApiRequestOptions): Promise<ApiResponse<T>>;
83
+ declare function apiRequest<T = unknown>(endpoint: string, options?: ApiRequestOptions): Promise<T>;
76
84
  /**
77
85
  * Convenience methods for common HTTP methods.
78
86
  */
79
87
  declare const api: {
80
- get: <T = unknown>(endpoint: string, authenticated?: boolean, customFetch?: typeof fetch) => Promise<ApiResponse<T>>;
81
- post: <T = unknown>(endpoint: string, body: unknown, authenticated?: boolean, customFetch?: typeof fetch) => Promise<ApiResponse<T>>;
82
- put: <T = unknown>(endpoint: string, body: unknown, authenticated?: boolean, customFetch?: typeof fetch) => Promise<ApiResponse<T>>;
83
- patch: <T = unknown>(endpoint: string, body: unknown, authenticated?: boolean, customFetch?: typeof fetch) => Promise<ApiResponse<T>>;
84
- delete: <T = unknown>(endpoint: string, authenticated?: boolean, customFetch?: typeof fetch, body?: unknown) => Promise<ApiResponse<T>>;
88
+ get: <T = unknown>(endpoint: string, authenticated?: boolean, customFetch?: typeof fetch) => Promise<T>;
89
+ post: <T = unknown>(endpoint: string, body: unknown, authenticated?: boolean, customFetch?: typeof fetch) => Promise<T>;
90
+ put: <T = unknown>(endpoint: string, body: unknown, authenticated?: boolean, customFetch?: typeof fetch) => Promise<T>;
91
+ patch: <T = unknown>(endpoint: string, body: unknown, authenticated?: boolean, customFetch?: typeof fetch) => Promise<T>;
92
+ delete: <T = unknown>(endpoint: string, authenticated?: boolean, customFetch?: typeof fetch, body?: unknown) => Promise<T>;
85
93
  };
86
94
 
87
95
  /**
@@ -469,11 +477,16 @@ declare function extractClaims<T extends string>(token: string, claims: T[]): Pi
469
477
  *
470
478
  * Mirrors `ROLE_NAMES` in the API. `builder`/`customer_service`/`demo`/
471
479
  * `stormwater` are staff-tier clones of `agent`; the `<department>_staff` roles
472
- * are grant-on-top docs roles held alongside another role; `employee` is the
473
- * read-only base staff floor (default for Authentik SSO); `vendor`/`customer`/
474
- * `subcontractor` are clones of `user`, row-scoped to their own homes.
480
+ * are grant-on-top docs roles held alongside another role, one per department
481
+ * the API lists in `DEPARTMENT_SCOPES`; `employee` is the read-only base staff
482
+ * floor (default for Authentik SSO); `vendor`/`customer`/`subcontractor` are
483
+ * clones of `user`, row-scoped to their own homes.
484
+ *
485
+ * `stormwater` and `stormwater_staff` are two different roles: the first is the
486
+ * field app's clone of `agent`, the second is that department's docs role.
487
+ * Someone on the stormwater team who also reads the docs holds both.
475
488
  */
476
- declare const ROLE_NAMES: readonly ["admin", "manager", "agent", "builder", "customer_service", "demo", "stormwater", "accounting_staff", "architecture_staff", "construction_staff", "crl_staff", "design_staff", "hr_staff", "it_staff", "landdev_staff", "marketing_staff", "purchasing_staff", "sales_staff", "warranty_staff", "employee", "user", "vendor", "customer", "subcontractor", "guest"];
489
+ declare const ROLE_NAMES: readonly ["admin", "manager", "agent", "builder", "customer_service", "demo", "stormwater", "accounting_staff", "architecture_staff", "construction_staff", "crl_staff", "design_staff", "hr_staff", "it_staff", "landdev_staff", "marketing_staff", "purchasing_staff", "sales_staff", "stormwater_staff", "warranty_staff", "employee", "user", "vendor", "customer", "subcontractor", "guest"];
477
490
  /**
478
491
  * A known role name.
479
492
  *
@@ -1,3 +1,3 @@
1
- export { AuthService, RoleDeniedError, authService, formatUserRoles, getAvailableMethods, getAvatarFallback, getDisplayName, getGreeting, getMfaToken, getUserEmail, getUserInitials, isLoginSuccessResponse, isMfaChallengeResponse, isRoleDeniedError } from '../chunk-7OXE7SAW.js';
2
- export { api, apiRequest, authApi, clearStoredAuth, extractData, getAccessToken, getRefreshToken, getSessionToken, updateStoredTokens } from '../chunk-GKS5EDOT.js';
3
- export { ROLE_HIERARCHY, ROLE_NAMES, computePrimaryRole, createMemoryStorage, createSessionStorage, decodeJWT, extractClaims, getConfig, getDefaultStorage, getEffectiveLevel, getFetch, getStorage, getTokenExpiration, getTokenRemainingTime, getUserRoles, hasAllRoles, hasAnyRole, hasRole, initAuth, isInitialized, isTokenExpired, resetConfig } from '../chunk-VFEGS6FR.js';
1
+ export { AuthService, RoleDeniedError, authService, formatUserRoles, getAvailableMethods, getAvatarFallback, getDisplayName, getGreeting, getMfaToken, getUserEmail, getUserInitials, isLoginSuccessResponse, isMfaChallengeResponse, isRoleDeniedError } from '../chunk-QTX7L4QY.js';
2
+ export { api, apiRequest, authApi, clearStoredAuth, extractData, getAccessToken, getRefreshToken, getSessionToken, updateStoredTokens } from '../chunk-HVOZBQIF.js';
3
+ export { ROLE_HIERARCHY, ROLE_NAMES, computePrimaryRole, createMemoryStorage, createSessionStorage, decodeJWT, extractClaims, getConfig, getDefaultStorage, getEffectiveLevel, getFetch, getStorage, getTokenExpiration, getTokenRemainingTime, getUserRoles, hasAllRoles, hasAnyRole, hasRole, initAuth, isInitialized, isTokenExpired, resetConfig } from '../chunk-X7KH4DDN.js';
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- export { canAccess, checkAuth, createAuthClient, createAuthGuard, createAuthHook, createNavFilter, filterByAccess, filterNavSections, matchesRoute, protectedLoad, requireAuth, requirePermission, requireRole, routePatterns } from './chunk-FTHQBYF2.js';
2
- export { AuthService, RoleDeniedError, authService, formatUserRoles, getAvailableMethods, getAvatarFallback, getDisplayName, getGreeting, getMfaToken, getUserEmail, getUserInitials, isLoginSuccessResponse, isMfaChallengeResponse, isRoleDeniedError } from './chunk-7OXE7SAW.js';
3
- export { authActions, authStore, currentUser, isAuthenticated } from './chunk-LMFSLTIV.js';
4
- export { api, apiRequest, authApi, clearStoredAuth, extractData, getAccessToken, getRefreshToken, getSessionToken, updateStoredTokens } from './chunk-GKS5EDOT.js';
5
- export { ROLE_HIERARCHY, ROLE_NAMES, computePrimaryRole, createMemoryStorage, createSessionStorage, decodeJWT, extractClaims, getConfig, getDefaultStorage, getEffectiveLevel, getFetch, getStorage, getTokenExpiration, getTokenRemainingTime, getUserRoles, hasAllRoles, hasAnyRole, hasRole, initAuth, isInitialized, isTokenExpired, resetConfig } from './chunk-VFEGS6FR.js';
1
+ export { canAccess, checkAuth, createAuthClient, createAuthGuard, createAuthHook, createNavFilter, filterByAccess, filterNavSections, matchesRoute, protectedLoad, requireAuth, requirePermission, requireRole, routePatterns } from './chunk-UGD4PNYI.js';
2
+ export { AuthService, RoleDeniedError, authService, formatUserRoles, getAvailableMethods, getAvatarFallback, getDisplayName, getGreeting, getMfaToken, getUserEmail, getUserInitials, isLoginSuccessResponse, isMfaChallengeResponse, isRoleDeniedError } from './chunk-QTX7L4QY.js';
3
+ export { authActions, authStore, currentUser, isAuthenticated } from './chunk-EBTCVIUQ.js';
4
+ export { api, apiRequest, authApi, clearStoredAuth, extractData, getAccessToken, getRefreshToken, getSessionToken, updateStoredTokens } from './chunk-HVOZBQIF.js';
5
+ export { ROLE_HIERARCHY, ROLE_NAMES, computePrimaryRole, createMemoryStorage, createSessionStorage, decodeJWT, extractClaims, getConfig, getDefaultStorage, getEffectiveLevel, getFetch, getStorage, getTokenExpiration, getTokenRemainingTime, getUserRoles, hasAllRoles, hasAnyRole, hasRole, initAuth, isInitialized, isTokenExpired, resetConfig } from './chunk-X7KH4DDN.js';
@@ -1,5 +1,5 @@
1
- export { canAccess, checkAuth, createAuthClient, createAuthGuard, createAuthHook, createNavFilter, filterByAccess, filterNavSections, matchesRoute, protectedLoad, requireAuth, requirePermission, requireRole, routePatterns } from '../chunk-FTHQBYF2.js';
2
- export { RoleDeniedError, formatUserRoles, getAvatarFallback, getDisplayName, getGreeting, getUserEmail, getUserInitials, isRoleDeniedError } from '../chunk-7OXE7SAW.js';
3
- export { authActions, authStore, currentUser, isAuthenticated } from '../chunk-LMFSLTIV.js';
4
- import '../chunk-GKS5EDOT.js';
5
- export { initAuth, isInitialized } from '../chunk-VFEGS6FR.js';
1
+ export { canAccess, checkAuth, createAuthClient, createAuthGuard, createAuthHook, createNavFilter, filterByAccess, filterNavSections, matchesRoute, protectedLoad, requireAuth, requirePermission, requireRole, routePatterns } from '../chunk-UGD4PNYI.js';
2
+ export { RoleDeniedError, formatUserRoles, getAvatarFallback, getDisplayName, getGreeting, getUserEmail, getUserInitials, isRoleDeniedError } from '../chunk-QTX7L4QY.js';
3
+ export { authActions, authStore, currentUser, isAuthenticated } from '../chunk-EBTCVIUQ.js';
4
+ import '../chunk-HVOZBQIF.js';
5
+ export { initAuth, isInitialized } from '../chunk-X7KH4DDN.js';
@@ -1,4 +1,4 @@
1
- import { hasRole, hasAnyRole, hasAllRoles, initAuth, resetConfig, getUserRoles, isTokenExpired, decodeJWT } from '../chunk-VFEGS6FR.js';
1
+ import { hasRole, hasAnyRole, hasAllRoles, initAuth, resetConfig, getUserRoles, isTokenExpired, decodeJWT } from '../chunk-X7KH4DDN.js';
2
2
 
3
3
  // src/testing/fixtures/users.ts
4
4
  var mockUser = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@classic-homes/auth",
3
- "version": "1.2.0",
3
+ "version": "1.8.0",
4
4
  "description": "Authentication services and Svelte bindings for Classic Theme apps",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -1,3 +0,0 @@
1
- export { authActions, authStore, currentUser, isAuthenticated } from './chunk-LMFSLTIV.js';
2
- import './chunk-GKS5EDOT.js';
3
- import './chunk-VFEGS6FR.js';