tempest-react-sdk 0.41.0 → 0.42.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 (119) hide show
  1. package/README.md +3 -3
  2. package/bin/tempest.mjs +3 -3
  3. package/dist/auth/create-tempest-auth.cjs +1 -1
  4. package/dist/auth/create-tempest-auth.cjs.map +1 -1
  5. package/dist/auth/create-tempest-auth.js +34 -30
  6. package/dist/auth/create-tempest-auth.js.map +1 -1
  7. package/dist/br.cjs +1 -1
  8. package/dist/br.cjs.map +1 -1
  9. package/dist/br.d.ts +0 -13
  10. package/dist/br.js +14 -15
  11. package/dist/br.js.map +1 -1
  12. package/dist/charts/palette.cjs +1 -1
  13. package/dist/charts/palette.cjs.map +1 -1
  14. package/dist/charts/palette.js +4 -4
  15. package/dist/charts/palette.js.map +1 -1
  16. package/dist/charts.cjs +1 -1
  17. package/dist/charts.d.ts +0 -3
  18. package/dist/charts.js +8 -8
  19. package/dist/http/api-client.cjs +1 -1
  20. package/dist/http/api-client.cjs.map +1 -1
  21. package/dist/http/api-client.js +58 -30
  22. package/dist/http/api-client.js.map +1 -1
  23. package/dist/http/resumable-upload.cjs +1 -1
  24. package/dist/http/resumable-upload.js +6 -6
  25. package/dist/icons/generated/aliases.cjs +1 -1
  26. package/dist/icons/generated/aliases.cjs.map +1 -1
  27. package/dist/icons/generated/aliases.js +9 -0
  28. package/dist/icons/generated/aliases.js.map +1 -1
  29. package/dist/icons/generated/icon-names.cjs +1 -1
  30. package/dist/icons/generated/icon-names.cjs.map +1 -1
  31. package/dist/icons/generated/icon-names.js +1 -1
  32. package/dist/icons/generated/icon-names.js.map +1 -1
  33. package/dist/icons/generated/shard-a.cjs +1 -1
  34. package/dist/icons/generated/shard-a.cjs.map +1 -1
  35. package/dist/icons/generated/shard-a.js +61 -61
  36. package/dist/icons/generated/shard-a.js.map +1 -1
  37. package/dist/icons/generated/shard-b.cjs +1 -1
  38. package/dist/icons/generated/shard-b.cjs.map +1 -1
  39. package/dist/icons/generated/shard-b.js +15 -13
  40. package/dist/icons/generated/shard-b.js.map +1 -1
  41. package/dist/icons/generated/shard-e.cjs +1 -1
  42. package/dist/icons/generated/shard-e.cjs.map +1 -1
  43. package/dist/icons/generated/shard-e.js +20 -19
  44. package/dist/icons/generated/shard-e.js.map +1 -1
  45. package/dist/icons/generated/shard-f.cjs +1 -1
  46. package/dist/icons/generated/shard-f.cjs.map +1 -1
  47. package/dist/icons/generated/shard-f.js +140 -134
  48. package/dist/icons/generated/shard-f.js.map +1 -1
  49. package/dist/icons/generated/shard-h.cjs +1 -1
  50. package/dist/icons/generated/shard-h.cjs.map +1 -1
  51. package/dist/icons/generated/shard-h.js +13 -14
  52. package/dist/icons/generated/shard-h.js.map +1 -1
  53. package/dist/icons/generated/shard-l.cjs +1 -1
  54. package/dist/icons/generated/shard-l.cjs.map +1 -1
  55. package/dist/icons/generated/shard-l.js +73 -69
  56. package/dist/icons/generated/shard-l.js.map +1 -1
  57. package/dist/icons/generated/shard-m.cjs +1 -1
  58. package/dist/icons/generated/shard-m.cjs.map +1 -1
  59. package/dist/icons/generated/shard-m.js +101 -98
  60. package/dist/icons/generated/shard-m.js.map +1 -1
  61. package/dist/icons/generated/shard-p.cjs +1 -1
  62. package/dist/icons/generated/shard-p.cjs.map +1 -1
  63. package/dist/icons/generated/shard-p.js +19 -20
  64. package/dist/icons/generated/shard-p.js.map +1 -1
  65. package/dist/icons/generated/shard-r.cjs +1 -1
  66. package/dist/icons/generated/shard-r.cjs.map +1 -1
  67. package/dist/icons/generated/shard-r.js +19 -17
  68. package/dist/icons/generated/shard-r.js.map +1 -1
  69. package/dist/icons/generated/shard-s.cjs +1 -1
  70. package/dist/icons/generated/shard-s.cjs.map +1 -1
  71. package/dist/icons/generated/shard-s.js +160 -159
  72. package/dist/icons/generated/shard-s.js.map +1 -1
  73. package/dist/icons/generated/shard-u.cjs +1 -1
  74. package/dist/icons/generated/shard-u.cjs.map +1 -1
  75. package/dist/icons/generated/shard-u.js +11 -10
  76. package/dist/icons/generated/shard-u.js.map +1 -1
  77. package/dist/icons/material-symbols.cjs +2 -0
  78. package/dist/icons/material-symbols.cjs.map +1 -0
  79. package/dist/icons/material-symbols.js +32 -0
  80. package/dist/icons/material-symbols.js.map +1 -0
  81. package/dist/icons/shard-cache.cjs.map +1 -1
  82. package/dist/icons/shard-cache.js.map +1 -1
  83. package/dist/icons.cjs +1 -1
  84. package/dist/icons.d.ts +74 -5
  85. package/dist/icons.js +2 -1
  86. package/dist/imaging/encode.cjs +1 -1
  87. package/dist/imaging/encode.cjs.map +1 -1
  88. package/dist/imaging/encode.js +1 -4
  89. package/dist/imaging/encode.js.map +1 -1
  90. package/dist/imaging.cjs +1 -1
  91. package/dist/imaging.d.ts +0 -7
  92. package/dist/imaging.js +6 -6
  93. package/dist/tabular/compact.cjs +1 -1
  94. package/dist/tabular/compact.cjs.map +1 -1
  95. package/dist/tabular/compact.js +8 -8
  96. package/dist/tabular/compact.js.map +1 -1
  97. package/dist/tabular/manifest.cjs +1 -1
  98. package/dist/tabular/manifest.cjs.map +1 -1
  99. package/dist/tabular/manifest.js +13 -14
  100. package/dist/tabular/manifest.js.map +1 -1
  101. package/dist/tabular.cjs +1 -1
  102. package/dist/tabular.d.ts +0 -9
  103. package/dist/tabular.js +5 -5
  104. package/dist/tempest-react-sdk.cjs +1 -1
  105. package/dist/tempest-react-sdk.d.ts +72 -305
  106. package/dist/tempest-react-sdk.js +183 -188
  107. package/dist/vision/index.cjs +1 -1
  108. package/dist/vision/index.cjs.map +1 -1
  109. package/dist/vision/index.js +1 -1
  110. package/dist/vision/index.js.map +1 -1
  111. package/dist/vision/preprocess/pipeline.cjs +1 -1
  112. package/dist/vision/preprocess/pipeline.cjs.map +1 -1
  113. package/dist/vision/preprocess/pipeline.js +43 -28
  114. package/dist/vision/preprocess/pipeline.js.map +1 -1
  115. package/dist/vision.d.ts +6 -3
  116. package/dist/vite.cjs +1 -1
  117. package/dist/vite.d.ts +0 -25
  118. package/dist/vite.js +6 -6
  119. package/package.json +5 -5
package/README.md CHANGED
@@ -155,7 +155,7 @@ Via `package.json`:
155
155
  }
156
156
  ```
157
157
 
158
- Requires React `>=18` and Node `>=20.19` to build.
158
+ Requires React `>=18` and Node `>=22.12` to build.
159
159
 
160
160
  ### Peer & bundled dependencies
161
161
 
@@ -244,7 +244,7 @@ Every module is re-exported from the package root — `import { Button, useDebou
244
244
  | `push` | `WebPushClient`, `WebPushUnsupportedError`, `WebPushPermissionDeniedError`, `usePushSubscription`, `urlBase64ToUint8Array`, `isPushSupported` |
245
245
  | `sw` _(also subpath `tempest-react-sdk/sw`)_ | `registerServiceWorker` (opt-in `autoUpdate` poll + reload, no `vite-plugin-pwa`), `skipWaiting`, `unregisterAllServiceWorkers`, `installPushHandler`, `installNotificationClickHandler`, `installSkipWaitingListener`, `installPrecache` (app-shell offline + Navigation Preload), `installRuntimeCache` (per-route caching, incl. `rangeRequests`), `createPartialResponse` (206 range slicing), `installBackgroundSync` (offline mutation queue + `periodicsync`), `registerPeriodicSync` (main-thread periodic sync), `inspectCaches`/`clearCaches` (cache observability) — the React-free `tempest-react-sdk/sw` subpath is ideal for bundling into your own `sw.ts` |
246
246
  | `charts` _(subpath `tempest-react-sdk/charts`, opt. peer `recharts`)_ | `AreaChart`, `BarChart`, `LineChart`, `PieChart`, `RadarChart`, `DEFAULT_CHART_COLORS` — themed recharts wrappers (recharts externalized; install it only if you use charts) |
247
- | `icons` _(subpath `tempest-react-sdk/icons`)_ | `Icon`, `IconProvider`, `createIconRegistry`, `useIcon`, `preloadIcons`, `iconStatus`, `peekIcon`, `loadIcon`, `resolveIconAlias`, `isIconName`, `iconNames`, `iconAliases`, type `IconName` — render any of lucide's **1997 icons by kebab-case slug**. A literal slug becomes a static import via the `tempestIcons()` Vite plugin (zero extra requests); a runtime slug loads **one chunk per initial letter** (25 max) instead of the ~2000 chunk boundaries `lucide-react`'s own `DynamicIcon` forces. Unknown slug renders `fallback` and never throws; lucide's 248 deprecated aliases keep resolving |
247
+ | `icons` _(subpath `tempest-react-sdk/icons`)_ | `Icon`, `IconProvider`, `createIconRegistry`, `useIcon`, `preloadIcons`, `iconStatus`, `peekIcon`, `loadIcon`, `resolveIconAlias`, `isIconName`, `iconNames`, `iconAliases`, type `IconName` — render any of lucide's **2024 icons by kebab-case slug**. A literal slug becomes a static import via the `tempestIcons()` Vite plugin (zero extra requests); a runtime slug loads **one chunk per initial letter** (25 max) instead of the ~2000 chunk boundaries `lucide-react`'s own `DynamicIcon` forces. Unknown slug renders `fallback` and never throws; lucide's 257 deprecated aliases keep resolving |
248
248
  | `audio` | `createAudioPlayer`, `playAudio`, `stopAudio`, `useAudio` |
249
249
  | `capture` | `BarcodeScanner`, `useBarcodeScanner`, `useTorch`, `isBarcodeDetectionSupported`, `getSupportedBarcodeFormats`, `createBarcodeDetector`, `normalizeBarcode`, `useVideoRecorder`, `createVideoRecorder`, `pickVideoMimeType`, `isVideoRecordingSupported`, `useScreenCapture`, `isScreenCaptureSupported`, `useSpeechRecognition`, `isSpeechRecognitionSupported`, `createMediaRecorder` — barcode/QR reading over the native `BarcodeDetector` (Chromium-only, so inject a polyfill through `detector` or render the `unsupported` fallback), video + screen recording on the same engine as the audio recorder, and Web Speech dictation (**Chromium streams the audio to a Google server**) |
250
250
  | `offline` _(peer: `dexie`)_ | `createOfflineStore`, `createOfflineSync` (outbox + delta-pull + watermark engine, now with `subscribe`/`getState`/`dispose` + cross-tab `crossTab`), `useOfflineSync`/`useSyncStatus` (reactive hooks), `lastWriteWins`/`higherVersionWins` (conflict resolvers), types: `OfflineStore`, `OfflineStoreConfig`, `ListOptions`, `OfflineSync`, `OfflineSyncConfig`, `OutboxEntry`, `PullPage`, `SyncPhase`, `SyncState`, `SyncRunSummary`, `SyncTrigger`, `SyncStatus`, `SyncTone`, `WatermarkStore` |
@@ -275,7 +275,7 @@ Every module is re-exported from the package root — `import { Button, useDebou
275
275
  | `ws` | `createWebSocket`, `useWebSocket` |
276
276
  | `geo` _(opt. peer `leaflet`)_ | `haversineKm`, `pathLengthKm`, `bearingDeg`, `estimateTravel`, `createOSRMBackend`, `boundingBox`, `projectMercator`, `fitProjection`, `createPositionTracker`, `usePositionTracker`, `TrajectoryMap` — tile-free SVG map + trajectory tracking (no external/paid API; Leaflet is an opt-in, lazy-loaded tile layer for self-hosted tiles), types: `Coordinate`, `TrackPoint`, `TravelEstimate`, `TravelMode`, `GeoBounds`, `RoutingBackend` |
277
277
  | `br` _(subpath `tempest-react-sdk/br`)_ | `BrazilMap`, `BrazilStateMap`, `BrazilStateCitySelect`, `listStates`, `getState`, `citiesByUf`, `statesByRegion`, `ufChoices`, `cityChoices`, `isValidUf`, `normalizeUf`, `isValidCity`, `loadBrUfGeoJson`, `loadStateMunicipalities`, types `UF`, `BrRegion`, `BrazilState` — clickable 27-UF SVG map + per-state municipality submaps (bundled simplified IBGE GeoJSON, lazy per UF) + states/cities dataset, no external API; mirrors the FastAPI SDK `utils/locations` |
278
- | `icons` _(subpath `tempest-react-sdk/icons`)_ | `Icon`, `IconProvider`, `createIconRegistry`, `useIcon`, `preloadIcons`, `iconStatus`, `peekIcon`, `loadIcon`, `resolveIconAlias`, `isIconName`, `iconNames`, `iconAliases`, type `IconName` — render any of lucide's **1997 icons by kebab-case slug**. A literal slug becomes a static import via the `tempestIcons()` Vite plugin (zero extra requests); a runtime slug loads **one chunk per initial letter** (25 max) instead of the ~2000 chunk boundaries `lucide-react`'s own `DynamicIcon` forces. Unknown slug renders `fallback` and never throws; lucide's 248 deprecated aliases keep resolving |
278
+ | `icons` _(subpath `tempest-react-sdk/icons`)_ | `Icon`, `IconProvider`, `createIconRegistry`, `useIcon`, `preloadIcons`, `iconStatus`, `peekIcon`, `loadIcon`, `resolveIconAlias`, `isIconName`, `iconNames`, `iconAliases`, type `IconName` — render any of lucide's **2024 icons by kebab-case slug**. A literal slug becomes a static import via the `tempestIcons()` Vite plugin (zero extra requests); a runtime slug loads **one chunk per initial letter** (25 max) instead of the ~2000 chunk boundaries `lucide-react`'s own `DynamicIcon` forces. Unknown slug renders `fallback` and never throws; lucide's 257 deprecated aliases keep resolving |
279
279
  | `push` | `WebPushClient`, `WebPushUnsupportedError`, `WebPushPermissionDeniedError`, `usePushSubscription`, `urlBase64ToUint8Array`, `isPushSupported` |
280
280
  | `sw` _(also subpath `tempest-react-sdk/sw`)_ | `registerServiceWorker` (opt-in `autoUpdate` poll + reload, no `vite-plugin-pwa`), `skipWaiting`, `unregisterAllServiceWorkers`, `installPushHandler`, `installNotificationClickHandler`, `installSkipWaitingListener`, `installPrecache` (app-shell offline + Navigation Preload), `installRuntimeCache` (per-route caching, incl. `rangeRequests`), `createPartialResponse` (206 range slicing), `installBackgroundSync` (offline mutation queue + `periodicsync`), `registerPeriodicSync` (main-thread periodic sync), `inspectCaches`/`clearCaches` (cache observability) — the React-free `tempest-react-sdk/sw` subpath is ideal for bundling into your own `sw.ts` |
281
281
  | `editor` _(subpath `tempest-react-sdk/editor`, opt. peers `@tiptap/react`+`@tiptap/starter-kit`)_ | `RichTextEditor` — themed tiptap v3 rich-text editor with toolbar (tiptap externalized; install it only if you use the editor) |
package/bin/tempest.mjs CHANGED
@@ -464,18 +464,18 @@ function doctor(args = []) {
464
464
  // ── Environment ─────────────────────────────────────────────────────────
465
465
  checks.push(["section", "Environment"]);
466
466
  const [maj, min] = process.versions.node.split(".").map(Number);
467
- const nodeOk = maj > 20 || (maj === 20 && min >= 19);
467
+ const nodeOk = maj > 22 || (maj === 22 && min >= 12);
468
468
  checks.push([
469
469
  nodeOk ? "ok" : "fail",
470
470
  `Node ${process.versions.node}`,
471
- nodeOk ? "" : "requires >= 20.19",
471
+ nodeOk ? "" : "requires >= 22.12 (Node 20 reached end of life on 2026-04-30)",
472
472
  ]);
473
473
  // Even majors are Node LTS lines; odd majors (21, 23…) aren't — avoid in prod.
474
474
  if (nodeOk && maj % 2 === 1) {
475
475
  checks.push([
476
476
  "warn",
477
477
  `Node ${maj} is not an LTS line`,
478
- "odd majors aren't LTS — prefer an even major (20, 22…) for production",
478
+ "odd majors aren't LTS — prefer an even major (22, 24…) for production",
479
479
  ]);
480
480
  }
481
481
  checks.push(["info", `tempest CLI v${selfVersion()}`]);
@@ -1,2 +1,2 @@
1
- const e=require("../http/api-client.cjs"),t=require("./create-auth-store.cjs"),n=require("./refresh-queue.cjs");function r(e){let t=e??{};return{token:t.access_token,refreshToken:t.refresh_token}}function i(i){let{baseURL:a,loginPath:o=`/api/auth/login`,refreshPath:s=`/api/auth/refresh`,mePath:c,storeName:l=`tempest-auth`,storage:u=`local`,withCredentials:d=!1,fetcher:f,parseTokens:p=r,parseUser:m,refreshBody:h=e=>e?{refresh_token:e}:void 0}=i,g=t.createAuthStore({name:l,storage:u}),_=`${l}-refresh`;function v(){return typeof window>`u`?null:u===`session`?window.sessionStorage:window.localStorage}function y(){return v()?.getItem(_)??null}function b(e){let t=v();t&&(e?t.setItem(_,e):t.removeItem(_))}let x=()=>g.getState(),S=()=>x().token,C=e.createApiClient({baseURL:a,withCredentials:d,fetcher:f});async function w(){if(!c)return x().user;let t=S(),n=await e.createApiClient({baseURL:a,withCredentials:d,fetcher:f,getToken:()=>t}).get(c);return x().setUser(n),n}async function T(e){let t=await C.post(o,{body:e}),{token:n,refreshToken:r}=p(t);x().setToken(n),b(r??null);let i=m?.(t);return i==null?w():(x().setUser(i),i)}function E(){x().logout(),b(null)}let D=n.createRefreshQueue(async()=>{let e=await C.post(s,{body:h(y())}),{token:t,refreshToken:n}=p(e);x().setToken(t),n&&b(n)});return{useAuthStore:g,api:e.createApiClient({baseURL:a,withCredentials:d,fetcher:f,getToken:S,refresh:D,onUnauthorized:()=>E()}),login:T,logout:E,refresh:D,getToken:S}}exports.createTempestAuth=i;
1
+ const e=require("../http/api-client.cjs"),t=require("./create-auth-store.cjs"),n=require("./refresh-queue.cjs");function r(e){let t=e??{};return{token:t.access_token,refreshToken:t.refresh_token}}function i(i){let{baseURL:a,loginPath:o=`/api/auth/login`,refreshPath:s=`/api/auth/refresh`,mePath:c,storeName:l=`tempest-auth`,storage:u=`local`,withCredentials:d=!1,fetcher:f,parseTokens:p=r,parseUser:m,refreshBody:h=e=>e?{refresh_token:e}:void 0,retry:g,redirectTo:_}=i,v=t.createAuthStore({name:l,storage:u}),y=`${l}-refresh`;function b(){return typeof window>`u`?null:u===`session`?window.sessionStorage:window.localStorage}function x(){return b()?.getItem(y)??null}function S(e){let t=b();t&&(e?t.setItem(y,e):t.removeItem(y))}let C=()=>v.getState(),w=()=>C().token,T=e.createApiClient({baseURL:a,withCredentials:d,fetcher:f});async function E(){if(!c)return C().user;let t=w(),n=await e.createApiClient({baseURL:a,withCredentials:d,fetcher:f,getToken:()=>t}).get(c);return C().setUser(n),n}async function D(e){let t=await T.post(o,{body:e}),{token:n,refreshToken:r}=p(t);C().setToken(n),S(r??null);let i=m?.(t);return i==null?E():(C().setUser(i),i)}function O(){C().logout(),S(null)}function k(){O(),_&&typeof window<`u`&&window.location.assign(_)}let A=n.createRefreshQueue(async()=>{let e=await T.post(s,{body:h(x())}),{token:t,refreshToken:n}=p(e);C().setToken(t),n&&S(n)});return{useAuthStore:v,api:e.createApiClient({baseURL:a,withCredentials:d,fetcher:f,getToken:w,refresh:A,retry:g,onUnauthorized:()=>k()}),login:D,logout:O,refresh:A,getToken:w}}exports.createTempestAuth=i;
2
2
  //# sourceMappingURL=create-tempest-auth.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"create-tempest-auth.cjs","names":[],"sources":["../../src/auth/create-tempest-auth.ts"],"sourcesContent":["import { createApiClient } from \"../http\";\nimport type { ApiClient } from \"../http\";\nimport { createAuthStore } from \"./create-auth-store\";\nimport type { AuthState } from \"./create-auth-store\";\nimport { createRefreshQueue } from \"./refresh-queue\";\n\n/** The token envelope returned by a Tempest FastAPI SDK login/refresh route. */\nexport interface TempestTokenResponse {\n /** The bearer access token. */\n access_token: string;\n /** Token type — always `\"bearer\"` for the SDK. */\n token_type?: string;\n /** Optional refresh token (when the API returns it in the body, not a cookie). */\n refresh_token?: string;\n}\n\nexport interface CreateTempestAuthOptions<TUser> {\n /** Base URL of the API. Required. */\n baseURL: string;\n /** Login route (`POST`). Default: `\"/api/auth/login\"`. */\n loginPath?: string;\n /** Refresh route (`POST`). Default: `\"/api/auth/refresh\"`. */\n refreshPath?: string;\n /** Optional current-user route (`GET`) called after login/refresh. */\n mePath?: string;\n /** Persist key for the store. Default: `\"tempest-auth\"`. */\n storeName?: string;\n /** Storage backend. Default: `\"local\"`. */\n storage?: \"local\" | \"session\";\n /** Send cookies (needed when the refresh token lives in an httpOnly cookie). */\n withCredentials?: boolean;\n /** Custom fetch implementation (testing / SSR). Defaults to `globalThis.fetch`. */\n fetcher?: typeof fetch;\n /**\n * Extract tokens from a login/refresh response. Default reads\n * `access_token` + `refresh_token`.\n */\n parseTokens?: (data: unknown) => { token: string; refreshToken?: string };\n /** Pull the user out of the login response, when the API embeds it. */\n parseUser?: (data: unknown) => TUser | null;\n /**\n * Build the refresh request body. Default sends `{ refresh_token }` when a\n * refresh token is stored, else `undefined` (cookie-based refresh).\n */\n refreshBody?: (refreshToken: string | null) => unknown;\n}\n\nexport interface TempestAuth<TUser, TCredentials> {\n /** The persisted Zustand auth store hook (compatible with `<AuthGuard>`). */\n useAuthStore: ReturnType<typeof createAuthStore<TUser>>;\n /** A `createApiClient` wired with bearer auth + 401 → refresh → retry. */\n api: ApiClient;\n /** Authenticate, store the session, and resolve the user (or null). */\n login: (credentials: TCredentials) => Promise<TUser | null>;\n /** Clear the session (and the stored refresh token). */\n logout: () => void;\n /** Refresh the access token (deduplicated across concurrent callers). */\n refresh: () => Promise<void>;\n /** The current access token, or null. */\n getToken: () => string | null;\n}\n\nfunction defaultParseTokens(data: unknown): { token: string; refreshToken?: string } {\n const d = (data ?? {}) as TempestTokenResponse;\n return { token: d.access_token, refreshToken: d.refresh_token };\n}\n\n/**\n * Turn-key auth preset wiring `createAuthStore` + `createRefreshQueue` +\n * `createApiClient` to the Tempest FastAPI SDK auth contract: login returns\n * `{ access_token, token_type }`, requests carry `Authorization: Bearer`, and a\n * `401` triggers a single deduplicated refresh + retry. Logout (or a failed\n * refresh) clears the session.\n *\n * @example\n * const auth = createTempestAuth<User, { email: string; password: string }>({\n * baseURL: import.meta.env.VITE_API_URL,\n * mePath: \"/api/auth/me\",\n * });\n *\n * await auth.login({ email, password }); // stores session, returns the user\n * const orders = await auth.api.get(\"/api/orders\"); // sends the bearer token\n * auth.logout();\n *\n * @param options - The auth configuration.\n * @returns The store hook, a wired API client, and login/logout/refresh helpers.\n */\nexport function createTempestAuth<TUser, TCredentials = { email: string; password: string }>(\n options: CreateTempestAuthOptions<TUser>,\n): TempestAuth<TUser, TCredentials> {\n const {\n baseURL,\n loginPath = \"/api/auth/login\",\n refreshPath = \"/api/auth/refresh\",\n mePath,\n storeName = \"tempest-auth\",\n storage = \"local\",\n withCredentials = false,\n fetcher,\n parseTokens = defaultParseTokens,\n parseUser,\n refreshBody = (rt) => (rt ? { refresh_token: rt } : undefined),\n } = options;\n\n const useAuthStore = createAuthStore<TUser>({ name: storeName, storage });\n const refreshKey = `${storeName}-refresh`;\n\n function storageImpl(): Storage | null {\n if (typeof window === \"undefined\") return null;\n return storage === \"session\" ? window.sessionStorage : window.localStorage;\n }\n function readRefreshToken(): string | null {\n return storageImpl()?.getItem(refreshKey) ?? null;\n }\n function writeRefreshToken(token: string | null): void {\n const s = storageImpl();\n if (!s) return;\n if (token) s.setItem(refreshKey, token);\n else s.removeItem(refreshKey);\n }\n\n const state = (): AuthState<TUser> => useAuthStore.getState();\n const getToken = (): string | null => state().token;\n\n // Bare client (no auth/refresh) used for the login + refresh calls themselves.\n const bareApi = createApiClient({ baseURL, withCredentials, fetcher });\n\n async function fetchUser(): Promise<TUser | null> {\n if (!mePath) return state().user;\n const token = getToken();\n const user = await createApiClient({\n baseURL,\n withCredentials,\n fetcher,\n getToken: () => token,\n }).get<TUser>(mePath);\n state().setUser(user);\n return user;\n }\n\n async function login(credentials: TCredentials): Promise<TUser | null> {\n const data = await bareApi.post<unknown>(loginPath, { body: credentials });\n const { token, refreshToken } = parseTokens(data);\n state().setToken(token);\n writeRefreshToken(refreshToken ?? null);\n const embedded = parseUser?.(data);\n if (embedded != null) {\n state().setUser(embedded);\n return embedded;\n }\n return fetchUser();\n }\n\n function logout(): void {\n state().logout();\n writeRefreshToken(null);\n }\n\n const refresh = createRefreshQueue(async () => {\n const data = await bareApi.post<unknown>(refreshPath, {\n body: refreshBody(readRefreshToken()),\n });\n const { token, refreshToken } = parseTokens(data);\n state().setToken(token);\n if (refreshToken) writeRefreshToken(refreshToken);\n });\n\n const api = createApiClient({\n baseURL,\n withCredentials,\n fetcher,\n getToken,\n refresh,\n onUnauthorized: () => logout(),\n });\n\n return { useAuthStore, api, login, logout, refresh, getToken };\n}\n"],"mappings":"gHA8DA,SAAS,EAAmB,EAAyD,CACjF,IAAM,EAAK,GAAQ,CAAC,EACpB,MAAO,CAAE,MAAO,EAAE,aAAc,aAAc,EAAE,aAAc,CAClE,CAsBA,SAAgB,EACZ,EACgC,CAChC,GAAM,CACF,UACA,YAAY,kBACZ,cAAc,oBACd,SACA,YAAY,eACZ,UAAU,QACV,kBAAkB,GAClB,UACA,cAAc,EACd,YACA,cAAe,GAAQ,EAAK,CAAE,cAAe,CAAG,EAAI,IAAA,IACpD,EAEE,EAAe,EAAA,gBAAuB,CAAE,KAAM,EAAW,SAAQ,CAAC,EAClE,EAAa,GAAG,EAAU,UAEhC,SAAS,GAA8B,CAEnC,OADI,OAAO,OAAW,IAAoB,KACnC,IAAY,UAAY,OAAO,eAAiB,OAAO,YAClE,CACA,SAAS,GAAkC,CACvC,OAAO,EAAY,CAAC,EAAE,QAAQ,CAAU,GAAK,IACjD,CACA,SAAS,EAAkB,EAA4B,CACnD,IAAM,EAAI,EAAY,EACjB,IACD,EAAO,EAAE,QAAQ,EAAY,CAAK,EACjC,EAAE,WAAW,CAAU,EAChC,CAEA,IAAM,MAAgC,EAAa,SAAS,EACtD,MAAgC,EAAM,CAAC,CAAC,MAGxC,EAAU,EAAA,gBAAgB,CAAE,UAAS,kBAAiB,SAAQ,CAAC,EAErE,eAAe,GAAmC,CAC9C,GAAI,CAAC,EAAQ,OAAO,EAAM,CAAC,CAAC,KAC5B,IAAM,EAAQ,EAAS,EACjB,EAAO,MAAM,EAAA,gBAAgB,CAC/B,UACA,kBACA,UACA,aAAgB,CACpB,CAAC,CAAC,CAAC,IAAW,CAAM,EAEpB,OADA,EAAM,CAAC,CAAC,QAAQ,CAAI,EACb,CACX,CAEA,eAAe,EAAM,EAAkD,CACnE,IAAM,EAAO,MAAM,EAAQ,KAAc,EAAW,CAAE,KAAM,CAAY,CAAC,EACnE,CAAE,QAAO,gBAAiB,EAAY,CAAI,EAChD,EAAM,CAAC,CAAC,SAAS,CAAK,EACtB,EAAkB,GAAgB,IAAI,EACtC,IAAM,EAAW,IAAY,CAAI,EAKjC,OAJI,GAAY,KAIT,EAAU,GAHb,EAAM,CAAC,CAAC,QAAQ,CAAQ,EACjB,EAGf,CAEA,SAAS,GAAe,CACpB,EAAM,CAAC,CAAC,OAAO,EACf,EAAkB,IAAI,CAC1B,CAEA,IAAM,EAAU,EAAA,mBAAmB,SAAY,CAC3C,IAAM,EAAO,MAAM,EAAQ,KAAc,EAAa,CAClD,KAAM,EAAY,EAAiB,CAAC,CACxC,CAAC,EACK,CAAE,QAAO,gBAAiB,EAAY,CAAI,EAChD,EAAM,CAAC,CAAC,SAAS,CAAK,EAClB,GAAc,EAAkB,CAAY,CACpD,CAAC,EAWD,MAAO,CAAE,eAAc,IATX,EAAA,gBAAgB,CACxB,UACA,kBACA,UACA,WACA,UACA,mBAAsB,EAAO,CACjC,CAEuB,EAAK,QAAO,SAAQ,UAAS,UAAS,CACjE"}
1
+ {"version":3,"file":"create-tempest-auth.cjs","names":[],"sources":["../../src/auth/create-tempest-auth.ts"],"sourcesContent":["import { createApiClient } from \"../http\";\nimport type { ApiClient, RetryOptions } from \"../http\";\nimport { createAuthStore } from \"./create-auth-store\";\nimport type { AuthState } from \"./create-auth-store\";\nimport { createRefreshQueue } from \"./refresh-queue\";\n\n/** The token envelope returned by a Tempest FastAPI SDK login/refresh route. */\nexport interface TempestTokenResponse {\n /** The bearer access token. */\n access_token: string;\n /** Token type — always `\"bearer\"` for the SDK. */\n token_type?: string;\n /** Optional refresh token (when the API returns it in the body, not a cookie). */\n refresh_token?: string;\n}\n\nexport interface CreateTempestAuthOptions<TUser> {\n /** Base URL of the API. Required. */\n baseURL: string;\n /** Login route (`POST`). Default: `\"/api/auth/login\"`. */\n loginPath?: string;\n /** Refresh route (`POST`). Default: `\"/api/auth/refresh\"`. */\n refreshPath?: string;\n /** Optional current-user route (`GET`) called after login/refresh. */\n mePath?: string;\n /** Persist key for the store. Default: `\"tempest-auth\"`. */\n storeName?: string;\n /** Storage backend. Default: `\"local\"`. */\n storage?: \"local\" | \"session\";\n /** Send cookies (needed when the refresh token lives in an httpOnly cookie). */\n withCredentials?: boolean;\n /** Custom fetch implementation (testing / SSR). Defaults to `globalThis.fetch`. */\n fetcher?: typeof fetch;\n /**\n * Extract tokens from a login/refresh response. Default reads\n * `access_token` + `refresh_token`.\n */\n parseTokens?: (data: unknown) => { token: string; refreshToken?: string };\n /** Pull the user out of the login response, when the API embeds it. */\n parseUser?: (data: unknown) => TUser | null;\n /**\n * Build the refresh request body. Default sends `{ refresh_token }` when a\n * refresh token is stored, else `undefined` (cookie-based refresh).\n */\n refreshBody?: (refreshToken: string | null) => unknown;\n /**\n * Retry policy for `api`, forwarded to {@link createApiClient}. Off by\n * default; `true` enables the conservative built-in policy, which never\n * replays a write.\n */\n retry?: boolean | RetryOptions;\n /**\n * Where to send the browser when the session ends — a hard navigation via\n * `window.location.assign`, after the store is cleared.\n *\n * **Prefer leaving this unset.** `logout()` already clears the store, so a\n * `<RouteGuard when={isAuthenticated} redirectTo=\"/login\">` wrapped around\n * the protected area navigates on its own, which keeps the SPA alive and the\n * router history intact. Reach for this only when the expiry can happen\n * outside any guarded subtree and a full reload is acceptable.\n */\n redirectTo?: string;\n}\n\nexport interface TempestAuth<TUser, TCredentials> {\n /** The persisted Zustand auth store hook (compatible with `<AuthGuard>`). */\n useAuthStore: ReturnType<typeof createAuthStore<TUser>>;\n /** A `createApiClient` wired with bearer auth + 401 → refresh → retry. */\n api: ApiClient;\n /** Authenticate, store the session, and resolve the user (or null). */\n login: (credentials: TCredentials) => Promise<TUser | null>;\n /** Clear the session (and the stored refresh token). */\n logout: () => void;\n /** Refresh the access token (deduplicated across concurrent callers). */\n refresh: () => Promise<void>;\n /** The current access token, or null. */\n getToken: () => string | null;\n}\n\nfunction defaultParseTokens(data: unknown): { token: string; refreshToken?: string } {\n const d = (data ?? {}) as TempestTokenResponse;\n return { token: d.access_token, refreshToken: d.refresh_token };\n}\n\n/**\n * Turn-key auth preset wiring `createAuthStore` + `createRefreshQueue` +\n * `createApiClient` to the Tempest FastAPI SDK auth contract: login returns\n * `{ access_token, token_type }`, requests carry `Authorization: Bearer`, and a\n * `401` triggers a single deduplicated refresh + replay.\n *\n * The session is cleared whenever that path ends unauthorized anyway — the\n * refresh threw, or the replay came back `401` — so a refresh token that the\n * backend has revoked cannot leave the app holding a dead session. With\n * `redirectTo` set, the browser also leaves the page; without it, clearing the\n * store is enough for a `<RouteGuard>` to navigate on its own.\n *\n * @example\n * const auth = createTempestAuth<User, { email: string; password: string }>({\n * baseURL: import.meta.env.VITE_API_URL,\n * mePath: \"/api/auth/me\",\n * });\n *\n * await auth.login({ email, password }); // stores session, returns the user\n * const orders = await auth.api.get(\"/api/orders\"); // sends the bearer token\n * auth.logout();\n *\n * @param options - The auth configuration.\n * @returns The store hook, a wired API client, and login/logout/refresh helpers.\n */\nexport function createTempestAuth<TUser, TCredentials = { email: string; password: string }>(\n options: CreateTempestAuthOptions<TUser>,\n): TempestAuth<TUser, TCredentials> {\n const {\n baseURL,\n loginPath = \"/api/auth/login\",\n refreshPath = \"/api/auth/refresh\",\n mePath,\n storeName = \"tempest-auth\",\n storage = \"local\",\n withCredentials = false,\n fetcher,\n parseTokens = defaultParseTokens,\n parseUser,\n refreshBody = (rt) => (rt ? { refresh_token: rt } : undefined),\n retry,\n redirectTo,\n } = options;\n\n const useAuthStore = createAuthStore<TUser>({ name: storeName, storage });\n const refreshKey = `${storeName}-refresh`;\n\n function storageImpl(): Storage | null {\n if (typeof window === \"undefined\") return null;\n return storage === \"session\" ? window.sessionStorage : window.localStorage;\n }\n function readRefreshToken(): string | null {\n return storageImpl()?.getItem(refreshKey) ?? null;\n }\n function writeRefreshToken(token: string | null): void {\n const s = storageImpl();\n if (!s) return;\n if (token) s.setItem(refreshKey, token);\n else s.removeItem(refreshKey);\n }\n\n const state = (): AuthState<TUser> => useAuthStore.getState();\n const getToken = (): string | null => state().token;\n\n // Bare client (no auth/refresh) used for the login + refresh calls themselves.\n const bareApi = createApiClient({ baseURL, withCredentials, fetcher });\n\n async function fetchUser(): Promise<TUser | null> {\n if (!mePath) return state().user;\n const token = getToken();\n const user = await createApiClient({\n baseURL,\n withCredentials,\n fetcher,\n getToken: () => token,\n }).get<TUser>(mePath);\n state().setUser(user);\n return user;\n }\n\n async function login(credentials: TCredentials): Promise<TUser | null> {\n const data = await bareApi.post<unknown>(loginPath, { body: credentials });\n const { token, refreshToken } = parseTokens(data);\n state().setToken(token);\n writeRefreshToken(refreshToken ?? null);\n const embedded = parseUser?.(data);\n if (embedded != null) {\n state().setUser(embedded);\n return embedded;\n }\n return fetchUser();\n }\n\n function logout(): void {\n state().logout();\n writeRefreshToken(null);\n }\n\n /**\n * Clear the session and, when `redirectTo` is set, leave the page.\n *\n * Separate from `logout` so an explicit sign-out stays a pure state change:\n * a caller that already navigates itself would otherwise get a second,\n * competing navigation.\n */\n function endSession(): void {\n logout();\n if (redirectTo && typeof window !== \"undefined\") {\n window.location.assign(redirectTo);\n }\n }\n\n const refresh = createRefreshQueue(async () => {\n const data = await bareApi.post<unknown>(refreshPath, {\n body: refreshBody(readRefreshToken()),\n });\n const { token, refreshToken } = parseTokens(data);\n state().setToken(token);\n if (refreshToken) writeRefreshToken(refreshToken);\n });\n\n const api = createApiClient({\n baseURL,\n withCredentials,\n fetcher,\n getToken,\n refresh,\n retry,\n onUnauthorized: () => endSession(),\n });\n\n return { useAuthStore, api, login, logout, refresh, getToken };\n}\n"],"mappings":"gHA+EA,SAAS,EAAmB,EAAyD,CACjF,IAAM,EAAK,GAAQ,CAAC,EACpB,MAAO,CAAE,MAAO,EAAE,aAAc,aAAc,EAAE,aAAc,CAClE,CA2BA,SAAgB,EACZ,EACgC,CAChC,GAAM,CACF,UACA,YAAY,kBACZ,cAAc,oBACd,SACA,YAAY,eACZ,UAAU,QACV,kBAAkB,GAClB,UACA,cAAc,EACd,YACA,cAAe,GAAQ,EAAK,CAAE,cAAe,CAAG,EAAI,IAAA,GACpD,QACA,cACA,EAEE,EAAe,EAAA,gBAAuB,CAAE,KAAM,EAAW,SAAQ,CAAC,EAClE,EAAa,GAAG,EAAU,UAEhC,SAAS,GAA8B,CAEnC,OADI,OAAO,OAAW,IAAoB,KACnC,IAAY,UAAY,OAAO,eAAiB,OAAO,YAClE,CACA,SAAS,GAAkC,CACvC,OAAO,EAAY,CAAC,EAAE,QAAQ,CAAU,GAAK,IACjD,CACA,SAAS,EAAkB,EAA4B,CACnD,IAAM,EAAI,EAAY,EACjB,IACD,EAAO,EAAE,QAAQ,EAAY,CAAK,EACjC,EAAE,WAAW,CAAU,EAChC,CAEA,IAAM,MAAgC,EAAa,SAAS,EACtD,MAAgC,EAAM,CAAC,CAAC,MAGxC,EAAU,EAAA,gBAAgB,CAAE,UAAS,kBAAiB,SAAQ,CAAC,EAErE,eAAe,GAAmC,CAC9C,GAAI,CAAC,EAAQ,OAAO,EAAM,CAAC,CAAC,KAC5B,IAAM,EAAQ,EAAS,EACjB,EAAO,MAAM,EAAA,gBAAgB,CAC/B,UACA,kBACA,UACA,aAAgB,CACpB,CAAC,CAAC,CAAC,IAAW,CAAM,EAEpB,OADA,EAAM,CAAC,CAAC,QAAQ,CAAI,EACb,CACX,CAEA,eAAe,EAAM,EAAkD,CACnE,IAAM,EAAO,MAAM,EAAQ,KAAc,EAAW,CAAE,KAAM,CAAY,CAAC,EACnE,CAAE,QAAO,gBAAiB,EAAY,CAAI,EAChD,EAAM,CAAC,CAAC,SAAS,CAAK,EACtB,EAAkB,GAAgB,IAAI,EACtC,IAAM,EAAW,IAAY,CAAI,EAKjC,OAJI,GAAY,KAIT,EAAU,GAHb,EAAM,CAAC,CAAC,QAAQ,CAAQ,EACjB,EAGf,CAEA,SAAS,GAAe,CACpB,EAAM,CAAC,CAAC,OAAO,EACf,EAAkB,IAAI,CAC1B,CASA,SAAS,GAAmB,CACxB,EAAO,EACH,GAAc,OAAO,OAAW,KAChC,OAAO,SAAS,OAAO,CAAU,CAEzC,CAEA,IAAM,EAAU,EAAA,mBAAmB,SAAY,CAC3C,IAAM,EAAO,MAAM,EAAQ,KAAc,EAAa,CAClD,KAAM,EAAY,EAAiB,CAAC,CACxC,CAAC,EACK,CAAE,QAAO,gBAAiB,EAAY,CAAI,EAChD,EAAM,CAAC,CAAC,SAAS,CAAK,EAClB,GAAc,EAAkB,CAAY,CACpD,CAAC,EAYD,MAAO,CAAE,eAAc,IAVX,EAAA,gBAAgB,CACxB,UACA,kBACA,UACA,WACA,UACA,QACA,mBAAsB,EAAW,CACrC,CAEuB,EAAK,QAAO,SAAQ,UAAS,UAAS,CACjE"}
@@ -10,62 +10,66 @@ function r(e) {
10
10
  };
11
11
  }
12
12
  function i(i) {
13
- let { baseURL: a, loginPath: o = "/api/auth/login", refreshPath: s = "/api/auth/refresh", mePath: c, storeName: l = "tempest-auth", storage: u = "local", withCredentials: d = !1, fetcher: f, parseTokens: p = r, parseUser: m, refreshBody: h = (e) => e ? { refresh_token: e } : void 0 } = i, g = t({
13
+ let { baseURL: a, loginPath: o = "/api/auth/login", refreshPath: s = "/api/auth/refresh", mePath: c, storeName: l = "tempest-auth", storage: u = "local", withCredentials: d = !1, fetcher: f, parseTokens: p = r, parseUser: m, refreshBody: h = (e) => e ? { refresh_token: e } : void 0, retry: g, redirectTo: _ } = i, v = t({
14
14
  name: l,
15
15
  storage: u
16
- }), _ = `${l}-refresh`;
17
- function v() {
16
+ }), y = `${l}-refresh`;
17
+ function b() {
18
18
  return typeof window > "u" ? null : u === "session" ? window.sessionStorage : window.localStorage;
19
19
  }
20
- function y() {
21
- return v()?.getItem(_) ?? null;
20
+ function x() {
21
+ return b()?.getItem(y) ?? null;
22
22
  }
23
- function b(e) {
24
- let t = v();
25
- t && (e ? t.setItem(_, e) : t.removeItem(_));
23
+ function S(e) {
24
+ let t = b();
25
+ t && (e ? t.setItem(y, e) : t.removeItem(y));
26
26
  }
27
- let x = () => g.getState(), S = () => x().token, C = e({
27
+ let C = () => v.getState(), w = () => C().token, T = e({
28
28
  baseURL: a,
29
29
  withCredentials: d,
30
30
  fetcher: f
31
31
  });
32
- async function w() {
33
- if (!c) return x().user;
34
- let t = S(), n = await e({
32
+ async function E() {
33
+ if (!c) return C().user;
34
+ let t = w(), n = await e({
35
35
  baseURL: a,
36
36
  withCredentials: d,
37
37
  fetcher: f,
38
38
  getToken: () => t
39
39
  }).get(c);
40
- return x().setUser(n), n;
40
+ return C().setUser(n), n;
41
41
  }
42
- async function T(e) {
43
- let t = await C.post(o, { body: e }), { token: n, refreshToken: r } = p(t);
44
- x().setToken(n), b(r ?? null);
42
+ async function D(e) {
43
+ let t = await T.post(o, { body: e }), { token: n, refreshToken: r } = p(t);
44
+ C().setToken(n), S(r ?? null);
45
45
  let i = m?.(t);
46
- return i == null ? w() : (x().setUser(i), i);
46
+ return i == null ? E() : (C().setUser(i), i);
47
47
  }
48
- function E() {
49
- x().logout(), b(null);
48
+ function O() {
49
+ C().logout(), S(null);
50
50
  }
51
- let D = n(async () => {
52
- let e = await C.post(s, { body: h(y()) }), { token: t, refreshToken: n } = p(e);
53
- x().setToken(t), n && b(n);
51
+ function k() {
52
+ O(), _ && typeof window < "u" && window.location.assign(_);
53
+ }
54
+ let A = n(async () => {
55
+ let e = await T.post(s, { body: h(x()) }), { token: t, refreshToken: n } = p(e);
56
+ C().setToken(t), n && S(n);
54
57
  });
55
58
  return {
56
- useAuthStore: g,
59
+ useAuthStore: v,
57
60
  api: e({
58
61
  baseURL: a,
59
62
  withCredentials: d,
60
63
  fetcher: f,
61
- getToken: S,
62
- refresh: D,
63
- onUnauthorized: () => E()
64
+ getToken: w,
65
+ refresh: A,
66
+ retry: g,
67
+ onUnauthorized: () => k()
64
68
  }),
65
- login: T,
66
- logout: E,
67
- refresh: D,
68
- getToken: S
69
+ login: D,
70
+ logout: O,
71
+ refresh: A,
72
+ getToken: w
69
73
  };
70
74
  }
71
75
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"create-tempest-auth.js","names":[],"sources":["../../src/auth/create-tempest-auth.ts"],"sourcesContent":["import { createApiClient } from \"../http\";\nimport type { ApiClient } from \"../http\";\nimport { createAuthStore } from \"./create-auth-store\";\nimport type { AuthState } from \"./create-auth-store\";\nimport { createRefreshQueue } from \"./refresh-queue\";\n\n/** The token envelope returned by a Tempest FastAPI SDK login/refresh route. */\nexport interface TempestTokenResponse {\n /** The bearer access token. */\n access_token: string;\n /** Token type — always `\"bearer\"` for the SDK. */\n token_type?: string;\n /** Optional refresh token (when the API returns it in the body, not a cookie). */\n refresh_token?: string;\n}\n\nexport interface CreateTempestAuthOptions<TUser> {\n /** Base URL of the API. Required. */\n baseURL: string;\n /** Login route (`POST`). Default: `\"/api/auth/login\"`. */\n loginPath?: string;\n /** Refresh route (`POST`). Default: `\"/api/auth/refresh\"`. */\n refreshPath?: string;\n /** Optional current-user route (`GET`) called after login/refresh. */\n mePath?: string;\n /** Persist key for the store. Default: `\"tempest-auth\"`. */\n storeName?: string;\n /** Storage backend. Default: `\"local\"`. */\n storage?: \"local\" | \"session\";\n /** Send cookies (needed when the refresh token lives in an httpOnly cookie). */\n withCredentials?: boolean;\n /** Custom fetch implementation (testing / SSR). Defaults to `globalThis.fetch`. */\n fetcher?: typeof fetch;\n /**\n * Extract tokens from a login/refresh response. Default reads\n * `access_token` + `refresh_token`.\n */\n parseTokens?: (data: unknown) => { token: string; refreshToken?: string };\n /** Pull the user out of the login response, when the API embeds it. */\n parseUser?: (data: unknown) => TUser | null;\n /**\n * Build the refresh request body. Default sends `{ refresh_token }` when a\n * refresh token is stored, else `undefined` (cookie-based refresh).\n */\n refreshBody?: (refreshToken: string | null) => unknown;\n}\n\nexport interface TempestAuth<TUser, TCredentials> {\n /** The persisted Zustand auth store hook (compatible with `<AuthGuard>`). */\n useAuthStore: ReturnType<typeof createAuthStore<TUser>>;\n /** A `createApiClient` wired with bearer auth + 401 → refresh → retry. */\n api: ApiClient;\n /** Authenticate, store the session, and resolve the user (or null). */\n login: (credentials: TCredentials) => Promise<TUser | null>;\n /** Clear the session (and the stored refresh token). */\n logout: () => void;\n /** Refresh the access token (deduplicated across concurrent callers). */\n refresh: () => Promise<void>;\n /** The current access token, or null. */\n getToken: () => string | null;\n}\n\nfunction defaultParseTokens(data: unknown): { token: string; refreshToken?: string } {\n const d = (data ?? {}) as TempestTokenResponse;\n return { token: d.access_token, refreshToken: d.refresh_token };\n}\n\n/**\n * Turn-key auth preset wiring `createAuthStore` + `createRefreshQueue` +\n * `createApiClient` to the Tempest FastAPI SDK auth contract: login returns\n * `{ access_token, token_type }`, requests carry `Authorization: Bearer`, and a\n * `401` triggers a single deduplicated refresh + retry. Logout (or a failed\n * refresh) clears the session.\n *\n * @example\n * const auth = createTempestAuth<User, { email: string; password: string }>({\n * baseURL: import.meta.env.VITE_API_URL,\n * mePath: \"/api/auth/me\",\n * });\n *\n * await auth.login({ email, password }); // stores session, returns the user\n * const orders = await auth.api.get(\"/api/orders\"); // sends the bearer token\n * auth.logout();\n *\n * @param options - The auth configuration.\n * @returns The store hook, a wired API client, and login/logout/refresh helpers.\n */\nexport function createTempestAuth<TUser, TCredentials = { email: string; password: string }>(\n options: CreateTempestAuthOptions<TUser>,\n): TempestAuth<TUser, TCredentials> {\n const {\n baseURL,\n loginPath = \"/api/auth/login\",\n refreshPath = \"/api/auth/refresh\",\n mePath,\n storeName = \"tempest-auth\",\n storage = \"local\",\n withCredentials = false,\n fetcher,\n parseTokens = defaultParseTokens,\n parseUser,\n refreshBody = (rt) => (rt ? { refresh_token: rt } : undefined),\n } = options;\n\n const useAuthStore = createAuthStore<TUser>({ name: storeName, storage });\n const refreshKey = `${storeName}-refresh`;\n\n function storageImpl(): Storage | null {\n if (typeof window === \"undefined\") return null;\n return storage === \"session\" ? window.sessionStorage : window.localStorage;\n }\n function readRefreshToken(): string | null {\n return storageImpl()?.getItem(refreshKey) ?? null;\n }\n function writeRefreshToken(token: string | null): void {\n const s = storageImpl();\n if (!s) return;\n if (token) s.setItem(refreshKey, token);\n else s.removeItem(refreshKey);\n }\n\n const state = (): AuthState<TUser> => useAuthStore.getState();\n const getToken = (): string | null => state().token;\n\n // Bare client (no auth/refresh) used for the login + refresh calls themselves.\n const bareApi = createApiClient({ baseURL, withCredentials, fetcher });\n\n async function fetchUser(): Promise<TUser | null> {\n if (!mePath) return state().user;\n const token = getToken();\n const user = await createApiClient({\n baseURL,\n withCredentials,\n fetcher,\n getToken: () => token,\n }).get<TUser>(mePath);\n state().setUser(user);\n return user;\n }\n\n async function login(credentials: TCredentials): Promise<TUser | null> {\n const data = await bareApi.post<unknown>(loginPath, { body: credentials });\n const { token, refreshToken } = parseTokens(data);\n state().setToken(token);\n writeRefreshToken(refreshToken ?? null);\n const embedded = parseUser?.(data);\n if (embedded != null) {\n state().setUser(embedded);\n return embedded;\n }\n return fetchUser();\n }\n\n function logout(): void {\n state().logout();\n writeRefreshToken(null);\n }\n\n const refresh = createRefreshQueue(async () => {\n const data = await bareApi.post<unknown>(refreshPath, {\n body: refreshBody(readRefreshToken()),\n });\n const { token, refreshToken } = parseTokens(data);\n state().setToken(token);\n if (refreshToken) writeRefreshToken(refreshToken);\n });\n\n const api = createApiClient({\n baseURL,\n withCredentials,\n fetcher,\n getToken,\n refresh,\n onUnauthorized: () => logout(),\n });\n\n return { useAuthStore, api, login, logout, refresh, getToken };\n}\n"],"mappings":";;;;AA8DA,SAAS,EAAmB,GAAyD;CACjF,IAAM,IAAK,KAAQ,CAAC;CACpB,OAAO;EAAE,OAAO,EAAE;EAAc,cAAc,EAAE;CAAc;AAClE;AAsBA,SAAgB,EACZ,GACgC;CAChC,IAAM,EACF,YACA,eAAY,mBACZ,iBAAc,qBACd,WACA,eAAY,gBACZ,aAAU,SACV,qBAAkB,IAClB,YACA,iBAAc,GACd,cACA,kBAAe,MAAQ,IAAK,EAAE,eAAe,EAAG,IAAI,KAAA,MACpD,GAEE,IAAe,EAAuB;EAAE,MAAM;EAAW;CAAQ,CAAC,GAClE,IAAa,GAAG,EAAU;CAEhC,SAAS,IAA8B;EAEnC,OADI,OAAO,SAAW,MAAoB,OACnC,MAAY,YAAY,OAAO,iBAAiB,OAAO;CAClE;CACA,SAAS,IAAkC;EACvC,OAAO,EAAY,CAAC,EAAE,QAAQ,CAAU,KAAK;CACjD;CACA,SAAS,EAAkB,GAA4B;EACnD,IAAM,IAAI,EAAY;EACjB,MACD,IAAO,EAAE,QAAQ,GAAY,CAAK,IACjC,EAAE,WAAW,CAAU;CAChC;CAEA,IAAM,UAAgC,EAAa,SAAS,GACtD,UAAgC,EAAM,CAAC,CAAC,OAGxC,IAAU,EAAgB;EAAE;EAAS;EAAiB;CAAQ,CAAC;CAErE,eAAe,IAAmC;EAC9C,IAAI,CAAC,GAAQ,OAAO,EAAM,CAAC,CAAC;EAC5B,IAAM,IAAQ,EAAS,GACjB,IAAO,MAAM,EAAgB;GAC/B;GACA;GACA;GACA,gBAAgB;EACpB,CAAC,CAAC,CAAC,IAAW,CAAM;EAEpB,OADA,EAAM,CAAC,CAAC,QAAQ,CAAI,GACb;CACX;CAEA,eAAe,EAAM,GAAkD;EACnE,IAAM,IAAO,MAAM,EAAQ,KAAc,GAAW,EAAE,MAAM,EAAY,CAAC,GACnE,EAAE,UAAO,oBAAiB,EAAY,CAAI;EAEhD,AADA,EAAM,CAAC,CAAC,SAAS,CAAK,GACtB,EAAkB,KAAgB,IAAI;EACtC,IAAM,IAAW,IAAY,CAAI;EAKjC,OAJI,KAAY,OAIT,EAAU,KAHb,EAAM,CAAC,CAAC,QAAQ,CAAQ,GACjB;CAGf;CAEA,SAAS,IAAe;EAEpB,AADA,EAAM,CAAC,CAAC,OAAO,GACf,EAAkB,IAAI;CAC1B;CAEA,IAAM,IAAU,EAAmB,YAAY;EAC3C,IAAM,IAAO,MAAM,EAAQ,KAAc,GAAa,EAClD,MAAM,EAAY,EAAiB,CAAC,EACxC,CAAC,GACK,EAAE,UAAO,oBAAiB,EAAY,CAAI;EAEhD,AADA,EAAM,CAAC,CAAC,SAAS,CAAK,GAClB,KAAc,EAAkB,CAAY;CACpD,CAAC;CAWD,OAAO;EAAE;EAAc,KATX,EAAgB;GACxB;GACA;GACA;GACA;GACA;GACA,sBAAsB,EAAO;EACjC,CAEuB;EAAK;EAAO;EAAQ;EAAS;CAAS;AACjE"}
1
+ {"version":3,"file":"create-tempest-auth.js","names":[],"sources":["../../src/auth/create-tempest-auth.ts"],"sourcesContent":["import { createApiClient } from \"../http\";\nimport type { ApiClient, RetryOptions } from \"../http\";\nimport { createAuthStore } from \"./create-auth-store\";\nimport type { AuthState } from \"./create-auth-store\";\nimport { createRefreshQueue } from \"./refresh-queue\";\n\n/** The token envelope returned by a Tempest FastAPI SDK login/refresh route. */\nexport interface TempestTokenResponse {\n /** The bearer access token. */\n access_token: string;\n /** Token type — always `\"bearer\"` for the SDK. */\n token_type?: string;\n /** Optional refresh token (when the API returns it in the body, not a cookie). */\n refresh_token?: string;\n}\n\nexport interface CreateTempestAuthOptions<TUser> {\n /** Base URL of the API. Required. */\n baseURL: string;\n /** Login route (`POST`). Default: `\"/api/auth/login\"`. */\n loginPath?: string;\n /** Refresh route (`POST`). Default: `\"/api/auth/refresh\"`. */\n refreshPath?: string;\n /** Optional current-user route (`GET`) called after login/refresh. */\n mePath?: string;\n /** Persist key for the store. Default: `\"tempest-auth\"`. */\n storeName?: string;\n /** Storage backend. Default: `\"local\"`. */\n storage?: \"local\" | \"session\";\n /** Send cookies (needed when the refresh token lives in an httpOnly cookie). */\n withCredentials?: boolean;\n /** Custom fetch implementation (testing / SSR). Defaults to `globalThis.fetch`. */\n fetcher?: typeof fetch;\n /**\n * Extract tokens from a login/refresh response. Default reads\n * `access_token` + `refresh_token`.\n */\n parseTokens?: (data: unknown) => { token: string; refreshToken?: string };\n /** Pull the user out of the login response, when the API embeds it. */\n parseUser?: (data: unknown) => TUser | null;\n /**\n * Build the refresh request body. Default sends `{ refresh_token }` when a\n * refresh token is stored, else `undefined` (cookie-based refresh).\n */\n refreshBody?: (refreshToken: string | null) => unknown;\n /**\n * Retry policy for `api`, forwarded to {@link createApiClient}. Off by\n * default; `true` enables the conservative built-in policy, which never\n * replays a write.\n */\n retry?: boolean | RetryOptions;\n /**\n * Where to send the browser when the session ends — a hard navigation via\n * `window.location.assign`, after the store is cleared.\n *\n * **Prefer leaving this unset.** `logout()` already clears the store, so a\n * `<RouteGuard when={isAuthenticated} redirectTo=\"/login\">` wrapped around\n * the protected area navigates on its own, which keeps the SPA alive and the\n * router history intact. Reach for this only when the expiry can happen\n * outside any guarded subtree and a full reload is acceptable.\n */\n redirectTo?: string;\n}\n\nexport interface TempestAuth<TUser, TCredentials> {\n /** The persisted Zustand auth store hook (compatible with `<AuthGuard>`). */\n useAuthStore: ReturnType<typeof createAuthStore<TUser>>;\n /** A `createApiClient` wired with bearer auth + 401 → refresh → retry. */\n api: ApiClient;\n /** Authenticate, store the session, and resolve the user (or null). */\n login: (credentials: TCredentials) => Promise<TUser | null>;\n /** Clear the session (and the stored refresh token). */\n logout: () => void;\n /** Refresh the access token (deduplicated across concurrent callers). */\n refresh: () => Promise<void>;\n /** The current access token, or null. */\n getToken: () => string | null;\n}\n\nfunction defaultParseTokens(data: unknown): { token: string; refreshToken?: string } {\n const d = (data ?? {}) as TempestTokenResponse;\n return { token: d.access_token, refreshToken: d.refresh_token };\n}\n\n/**\n * Turn-key auth preset wiring `createAuthStore` + `createRefreshQueue` +\n * `createApiClient` to the Tempest FastAPI SDK auth contract: login returns\n * `{ access_token, token_type }`, requests carry `Authorization: Bearer`, and a\n * `401` triggers a single deduplicated refresh + replay.\n *\n * The session is cleared whenever that path ends unauthorized anyway — the\n * refresh threw, or the replay came back `401` — so a refresh token that the\n * backend has revoked cannot leave the app holding a dead session. With\n * `redirectTo` set, the browser also leaves the page; without it, clearing the\n * store is enough for a `<RouteGuard>` to navigate on its own.\n *\n * @example\n * const auth = createTempestAuth<User, { email: string; password: string }>({\n * baseURL: import.meta.env.VITE_API_URL,\n * mePath: \"/api/auth/me\",\n * });\n *\n * await auth.login({ email, password }); // stores session, returns the user\n * const orders = await auth.api.get(\"/api/orders\"); // sends the bearer token\n * auth.logout();\n *\n * @param options - The auth configuration.\n * @returns The store hook, a wired API client, and login/logout/refresh helpers.\n */\nexport function createTempestAuth<TUser, TCredentials = { email: string; password: string }>(\n options: CreateTempestAuthOptions<TUser>,\n): TempestAuth<TUser, TCredentials> {\n const {\n baseURL,\n loginPath = \"/api/auth/login\",\n refreshPath = \"/api/auth/refresh\",\n mePath,\n storeName = \"tempest-auth\",\n storage = \"local\",\n withCredentials = false,\n fetcher,\n parseTokens = defaultParseTokens,\n parseUser,\n refreshBody = (rt) => (rt ? { refresh_token: rt } : undefined),\n retry,\n redirectTo,\n } = options;\n\n const useAuthStore = createAuthStore<TUser>({ name: storeName, storage });\n const refreshKey = `${storeName}-refresh`;\n\n function storageImpl(): Storage | null {\n if (typeof window === \"undefined\") return null;\n return storage === \"session\" ? window.sessionStorage : window.localStorage;\n }\n function readRefreshToken(): string | null {\n return storageImpl()?.getItem(refreshKey) ?? null;\n }\n function writeRefreshToken(token: string | null): void {\n const s = storageImpl();\n if (!s) return;\n if (token) s.setItem(refreshKey, token);\n else s.removeItem(refreshKey);\n }\n\n const state = (): AuthState<TUser> => useAuthStore.getState();\n const getToken = (): string | null => state().token;\n\n // Bare client (no auth/refresh) used for the login + refresh calls themselves.\n const bareApi = createApiClient({ baseURL, withCredentials, fetcher });\n\n async function fetchUser(): Promise<TUser | null> {\n if (!mePath) return state().user;\n const token = getToken();\n const user = await createApiClient({\n baseURL,\n withCredentials,\n fetcher,\n getToken: () => token,\n }).get<TUser>(mePath);\n state().setUser(user);\n return user;\n }\n\n async function login(credentials: TCredentials): Promise<TUser | null> {\n const data = await bareApi.post<unknown>(loginPath, { body: credentials });\n const { token, refreshToken } = parseTokens(data);\n state().setToken(token);\n writeRefreshToken(refreshToken ?? null);\n const embedded = parseUser?.(data);\n if (embedded != null) {\n state().setUser(embedded);\n return embedded;\n }\n return fetchUser();\n }\n\n function logout(): void {\n state().logout();\n writeRefreshToken(null);\n }\n\n /**\n * Clear the session and, when `redirectTo` is set, leave the page.\n *\n * Separate from `logout` so an explicit sign-out stays a pure state change:\n * a caller that already navigates itself would otherwise get a second,\n * competing navigation.\n */\n function endSession(): void {\n logout();\n if (redirectTo && typeof window !== \"undefined\") {\n window.location.assign(redirectTo);\n }\n }\n\n const refresh = createRefreshQueue(async () => {\n const data = await bareApi.post<unknown>(refreshPath, {\n body: refreshBody(readRefreshToken()),\n });\n const { token, refreshToken } = parseTokens(data);\n state().setToken(token);\n if (refreshToken) writeRefreshToken(refreshToken);\n });\n\n const api = createApiClient({\n baseURL,\n withCredentials,\n fetcher,\n getToken,\n refresh,\n retry,\n onUnauthorized: () => endSession(),\n });\n\n return { useAuthStore, api, login, logout, refresh, getToken };\n}\n"],"mappings":";;;;AA+EA,SAAS,EAAmB,GAAyD;CACjF,IAAM,IAAK,KAAQ,CAAC;CACpB,OAAO;EAAE,OAAO,EAAE;EAAc,cAAc,EAAE;CAAc;AAClE;AA2BA,SAAgB,EACZ,GACgC;CAChC,IAAM,EACF,YACA,eAAY,mBACZ,iBAAc,qBACd,WACA,eAAY,gBACZ,aAAU,SACV,qBAAkB,IAClB,YACA,iBAAc,GACd,cACA,kBAAe,MAAQ,IAAK,EAAE,eAAe,EAAG,IAAI,KAAA,GACpD,UACA,kBACA,GAEE,IAAe,EAAuB;EAAE,MAAM;EAAW;CAAQ,CAAC,GAClE,IAAa,GAAG,EAAU;CAEhC,SAAS,IAA8B;EAEnC,OADI,OAAO,SAAW,MAAoB,OACnC,MAAY,YAAY,OAAO,iBAAiB,OAAO;CAClE;CACA,SAAS,IAAkC;EACvC,OAAO,EAAY,CAAC,EAAE,QAAQ,CAAU,KAAK;CACjD;CACA,SAAS,EAAkB,GAA4B;EACnD,IAAM,IAAI,EAAY;EACjB,MACD,IAAO,EAAE,QAAQ,GAAY,CAAK,IACjC,EAAE,WAAW,CAAU;CAChC;CAEA,IAAM,UAAgC,EAAa,SAAS,GACtD,UAAgC,EAAM,CAAC,CAAC,OAGxC,IAAU,EAAgB;EAAE;EAAS;EAAiB;CAAQ,CAAC;CAErE,eAAe,IAAmC;EAC9C,IAAI,CAAC,GAAQ,OAAO,EAAM,CAAC,CAAC;EAC5B,IAAM,IAAQ,EAAS,GACjB,IAAO,MAAM,EAAgB;GAC/B;GACA;GACA;GACA,gBAAgB;EACpB,CAAC,CAAC,CAAC,IAAW,CAAM;EAEpB,OADA,EAAM,CAAC,CAAC,QAAQ,CAAI,GACb;CACX;CAEA,eAAe,EAAM,GAAkD;EACnE,IAAM,IAAO,MAAM,EAAQ,KAAc,GAAW,EAAE,MAAM,EAAY,CAAC,GACnE,EAAE,UAAO,oBAAiB,EAAY,CAAI;EAEhD,AADA,EAAM,CAAC,CAAC,SAAS,CAAK,GACtB,EAAkB,KAAgB,IAAI;EACtC,IAAM,IAAW,IAAY,CAAI;EAKjC,OAJI,KAAY,OAIT,EAAU,KAHb,EAAM,CAAC,CAAC,QAAQ,CAAQ,GACjB;CAGf;CAEA,SAAS,IAAe;EAEpB,AADA,EAAM,CAAC,CAAC,OAAO,GACf,EAAkB,IAAI;CAC1B;CASA,SAAS,IAAmB;EAExB,AADA,EAAO,GACH,KAAc,OAAO,SAAW,OAChC,OAAO,SAAS,OAAO,CAAU;CAEzC;CAEA,IAAM,IAAU,EAAmB,YAAY;EAC3C,IAAM,IAAO,MAAM,EAAQ,KAAc,GAAa,EAClD,MAAM,EAAY,EAAiB,CAAC,EACxC,CAAC,GACK,EAAE,UAAO,oBAAiB,EAAY,CAAI;EAEhD,AADA,EAAM,CAAC,CAAC,SAAS,CAAK,GAClB,KAAc,EAAkB,CAAY;CACpD,CAAC;CAYD,OAAO;EAAE;EAAc,KAVX,EAAgB;GACxB;GACA;GACA;GACA;GACA;GACA;GACA,sBAAsB,EAAW;EACrC,CAEuB;EAAK;EAAO;EAAQ;EAAS;CAAS;AACjE"}
package/dist/br.cjs CHANGED
@@ -1,2 +1,2 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./br/locations.cjs"),t=require("./br/state-geo.cjs"),n=require("./br/geocode.cjs"),r=require("./br/MapMarkers.cjs"),i=require("./br/regions.cjs"),a=require("./br/BrazilMap.cjs"),o=require("./br/BrazilStateMap.cjs"),s=require("./br/BrazilStateCitySelect.cjs"),c=require("./br/MunicipalitySearch.cjs"),l=require("./br/scales.cjs"),u=require("./br/MapLegend.cjs"),d=require("./br/pix.cjs"),f=require("./br/PixQRCode.cjs"),p=require("./br/boleto.cjs"),m=require("./br/nfe.cjs"),h=require("./br/holidays.cjs");async function g(){return(await Promise.resolve().then(()=>require("./br/br-geo.cjs"))).BR_UF_GEOJSON}exports.BoletoError=p.BoletoError,exports.BrazilMap=a.BrazilMap,exports.BrazilStateCitySelect=s.BrazilStateCitySelect,exports.BrazilStateMap=o.BrazilStateMap,exports.ChaveNFeError=m.ChaveNFeError,exports.DIVERGING_RDBU=l.DIVERGING_RDBU,exports.MapLegend=u.MapLegend,exports.MapMarkers=r.MapMarkers,exports.MunicipalitySearch=c.MunicipalitySearch,exports.PixError=d.PixError,exports.PixQRCode=f.PixQRCode,exports.REGION_COLORS=i.REGION_COLORS,exports.SEQUENTIAL_BLUES=l.SEQUENTIAL_BLUES,exports.SEQUENTIAL_GREENS=l.SEQUENTIAL_GREENS,exports.SEQUENTIAL_VIRIDIS=l.SEQUENTIAL_VIRIDIS,exports.addBusinessDays=h.addBusinessDays,exports.boletoDueDate=p.boletoDueDate,exports.boletoKind=p.boletoKind,exports.chaveNFeCheckDigit=m.chaveNFeCheckDigit,exports.citiesByUf=e.citiesByUf,exports.cityChoices=e.cityChoices,exports.codigoBarrasToLinhaDigitavel=p.codigoBarrasToLinhaDigitavel,exports.easterSunday=h.easterSunday,exports.fatorVencimento=p.fatorVencimento,exports.formatChaveNFe=m.formatChaveNFe,exports.formatLinhaDigitavel=p.formatLinhaDigitavel,exports.geocodeMunicipality=n.geocodeMunicipality,exports.getState=e.getState,exports.holidaysFor=h.holidaysFor,exports.interpolatePalette=l.interpolatePalette,exports.isBusinessDay=h.isBusinessDay,exports.isHoliday=h.isHoliday,exports.isValidCity=e.isValidCity,exports.isValidUf=e.isValidUf,exports.linhaDigitavelToCodigoBarras=p.linhaDigitavelToCodigoBarras,exports.listStates=e.listStates,exports.loadBrUfGeoJson=g,exports.loadStateMunicipalities=t.loadStateMunicipalities,exports.mod10Dac=p.mod10Dac,exports.mod11DacArrecadacao=p.mod11DacArrecadacao,exports.mod11DacCobranca=p.mod11DacCobranca,exports.municipalityCentroid=n.municipalityCentroid,exports.nearestMunicipality=n.nearestMunicipality,exports.nextBusinessDay=h.nextBusinessDay,exports.normalizePixKey=d.normalizePixKey,exports.normalizeUf=e.normalizeUf,exports.parseChaveNFe=m.parseChaveNFe,exports.parseCodigoBarras=p.parseCodigoBarras,exports.parseLinhaDigitavel=p.parseLinhaDigitavel,exports.parsePixPayload=d.parsePixPayload,exports.pixCrc16=d.pixCrc16,exports.pixKeyType=d.pixKeyType,exports.pixPayload=d.pixPayload,exports.quantizeScale=l.quantizeScale,exports.regionLegendItems=i.regionLegendItems,exports.reverseGeocode=n.reverseGeocode,exports.searchMunicipalities=n.searchMunicipalities,exports.sequentialScale=l.sequentialScale,exports.stateCentroid=n.stateCentroid,exports.statesByRegion=e.statesByRegion,exports.thresholdScale=l.thresholdScale,exports.ufChoices=e.ufChoices,exports.validateBoleto=p.validateBoleto,exports.validateChaveNFe=m.validateChaveNFe;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./br/locations.cjs"),t=require("./br/state-geo.cjs"),n=require("./br/geocode.cjs"),r=require("./br/regions.cjs"),i=require("./br/BrazilMap.cjs"),a=require("./br/BrazilStateMap.cjs"),o=require("./br/BrazilStateCitySelect.cjs"),s=require("./br/MunicipalitySearch.cjs"),c=require("./br/scales.cjs"),l=require("./br/MapLegend.cjs"),u=require("./br/pix.cjs"),d=require("./br/PixQRCode.cjs"),f=require("./br/boleto.cjs"),p=require("./br/nfe.cjs"),m=require("./br/holidays.cjs");async function h(){return(await Promise.resolve().then(()=>require("./br/br-geo.cjs"))).BR_UF_GEOJSON}exports.BoletoError=f.BoletoError,exports.BrazilMap=i.BrazilMap,exports.BrazilStateCitySelect=o.BrazilStateCitySelect,exports.BrazilStateMap=a.BrazilStateMap,exports.ChaveNFeError=p.ChaveNFeError,exports.DIVERGING_RDBU=c.DIVERGING_RDBU,exports.MapLegend=l.MapLegend,exports.MunicipalitySearch=s.MunicipalitySearch,exports.PixError=u.PixError,exports.PixQRCode=d.PixQRCode,exports.REGION_COLORS=r.REGION_COLORS,exports.SEQUENTIAL_BLUES=c.SEQUENTIAL_BLUES,exports.SEQUENTIAL_GREENS=c.SEQUENTIAL_GREENS,exports.SEQUENTIAL_VIRIDIS=c.SEQUENTIAL_VIRIDIS,exports.addBusinessDays=m.addBusinessDays,exports.boletoDueDate=f.boletoDueDate,exports.boletoKind=f.boletoKind,exports.chaveNFeCheckDigit=p.chaveNFeCheckDigit,exports.citiesByUf=e.citiesByUf,exports.cityChoices=e.cityChoices,exports.codigoBarrasToLinhaDigitavel=f.codigoBarrasToLinhaDigitavel,exports.easterSunday=m.easterSunday,exports.fatorVencimento=f.fatorVencimento,exports.formatChaveNFe=p.formatChaveNFe,exports.formatLinhaDigitavel=f.formatLinhaDigitavel,exports.geocodeMunicipality=n.geocodeMunicipality,exports.getState=e.getState,exports.holidaysFor=m.holidaysFor,exports.isBusinessDay=m.isBusinessDay,exports.isHoliday=m.isHoliday,exports.isValidCity=e.isValidCity,exports.isValidUf=e.isValidUf,exports.linhaDigitavelToCodigoBarras=f.linhaDigitavelToCodigoBarras,exports.listStates=e.listStates,exports.loadBrUfGeoJson=h,exports.loadStateMunicipalities=t.loadStateMunicipalities,exports.mod10Dac=f.mod10Dac,exports.mod11DacArrecadacao=f.mod11DacArrecadacao,exports.mod11DacCobranca=f.mod11DacCobranca,exports.municipalityCentroid=n.municipalityCentroid,exports.nearestMunicipality=n.nearestMunicipality,exports.nextBusinessDay=m.nextBusinessDay,exports.normalizePixKey=u.normalizePixKey,exports.normalizeUf=e.normalizeUf,exports.parseChaveNFe=p.parseChaveNFe,exports.parseCodigoBarras=f.parseCodigoBarras,exports.parseLinhaDigitavel=f.parseLinhaDigitavel,exports.parsePixPayload=u.parsePixPayload,exports.pixCrc16=u.pixCrc16,exports.pixKeyType=u.pixKeyType,exports.pixPayload=u.pixPayload,exports.quantizeScale=c.quantizeScale,exports.regionLegendItems=r.regionLegendItems,exports.reverseGeocode=n.reverseGeocode,exports.searchMunicipalities=n.searchMunicipalities,exports.sequentialScale=c.sequentialScale,exports.stateCentroid=n.stateCentroid,exports.statesByRegion=e.statesByRegion,exports.thresholdScale=c.thresholdScale,exports.ufChoices=e.ufChoices,exports.validateBoleto=f.validateBoleto,exports.validateChaveNFe=p.validateChaveNFe;
2
2
  //# sourceMappingURL=br.cjs.map
package/dist/br.cjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"br.cjs","names":[],"sources":["../src/br/index.ts"],"sourcesContent":["// Brazilian locations data (states + cities) — mirrors the `utils/locations`\n// module of tempest-fastapi-sdk.\nexport {\n listStates,\n getState,\n citiesByUf,\n statesByRegion,\n isValidUf,\n normalizeUf,\n isValidCity,\n ufChoices,\n cityChoices,\n} from \"./locations\";\nexport type { UF, BrRegion, BrazilState, Choice } from \"./locations\";\n\n// UF GeoJSON types (the geometry itself is lazy-loaded by BrazilMap).\nimport type { BrUfFeatureCollection } from \"./br-geo\";\nexport type { BrUfFeature, BrUfFeatureCollection, BrUfGeometry, Ring } from \"./br-geo\";\n\n/**\n * Lazily load the bundled simplified UF GeoJSON (~36 KB gzip). Kept out of the\n * synchronous barrel so a data-only import never pulls the geometry.\n */\nexport async function loadBrUfGeoJson(): Promise<BrUfFeatureCollection> {\n const mod = await import(\"./br-geo\");\n return mod.BR_UF_GEOJSON;\n}\n\n// Per-state municipality geometry (lazy, one chunk per UF).\nexport { loadStateMunicipalities } from \"./state-geo\";\nexport type { MunicipalityFeature, StateMunicipalities } from \"./state-geo\";\n\n// Offline geocoding (lazy centroid index).\nexport {\n nearestMunicipality,\n reverseGeocode,\n geocodeMunicipality,\n searchMunicipalities,\n municipalityCentroid,\n stateCentroid,\n} from \"./geocode\";\nexport type { MunicipalityCentroid, NearestMunicipality, ReverseGeocodeResult } from \"./geocode\";\n\n// Components\nexport { BrazilMap } from \"./BrazilMap\";\nexport type { BrazilMapProps, BrazilMapTooltipData } from \"./BrazilMap\";\nexport { BrazilStateMap } from \"./BrazilStateMap\";\nexport type {\n BrazilStateMapProps,\n BrazilStateMapTooltipData,\n Municipality,\n} from \"./BrazilStateMap\";\nexport { BrazilStateCitySelect } from \"./BrazilStateCitySelect\";\nexport type { BrazilStateCitySelectProps, BrazilStateCitySelection } from \"./BrazilStateCitySelect\";\nexport { MunicipalitySearch } from \"./MunicipalitySearch\";\nexport type { MunicipalitySearchProps } from \"./MunicipalitySearch\";\nexport type { GeoMarker } from \"@/geo/types\";\nexport { MapMarkers } from \"./MapMarkers\";\nexport type { MapMarkersProps } from \"./MapMarkers\";\nexport { MapLegend } from \"./MapLegend\";\nexport type { MapLegendProps, LegendItem } from \"./MapLegend\";\n\n// Pix — BR Code (EMV MPM) payload + the QR that carries it.\nexport {\n normalizePixKey,\n parsePixPayload,\n PixError,\n pixCrc16,\n pixKeyType,\n pixPayload,\n} from \"./pix\";\nexport type {\n NormalizedPixKey,\n ParsePixOptions,\n PixData,\n PixDynamicInput,\n PixField,\n PixInput,\n PixKeyType,\n PixStaticInput,\n} from \"./pix\";\nexport { PixQRCode } from \"./PixQRCode\";\nexport type { PixQRCodeLabels, PixQRCodeProps } from \"./PixQRCode\";\n\n// Boleto — 47/48-digit typed line, 44-digit barcode, FEBRABAN check digits.\nexport {\n boletoDueDate,\n BoletoError,\n boletoKind,\n codigoBarrasToLinhaDigitavel,\n fatorVencimento,\n formatLinhaDigitavel,\n linhaDigitavelToCodigoBarras,\n mod10Dac,\n mod11DacArrecadacao,\n mod11DacCobranca,\n parseCodigoBarras,\n parseLinhaDigitavel,\n validateBoleto,\n} from \"./boleto\";\nexport type {\n Boleto,\n BoletoArrecadacao,\n BoletoBanco,\n BoletoEpoch,\n BoletoKind,\n BoletoOptions,\n} from \"./boleto\";\n\n// NF-e / NFC-e / CT-e access key.\nexport {\n chaveNFeCheckDigit,\n ChaveNFeError,\n formatChaveNFe,\n parseChaveNFe,\n validateChaveNFe,\n} from \"./nfe\";\nexport type { ChaveNFe } from \"./nfe\";\n\n// National holidays + business-day arithmetic.\nexport {\n addBusinessDays,\n easterSunday,\n holidaysFor,\n isBusinessDay,\n isHoliday,\n nextBusinessDay,\n} from \"./holidays\";\nexport type { BusinessDayOptions, DateInput, Holiday, HolidayKind } from \"./holidays\";\n\n// Color scales + palettes for choropleths.\nexport {\n interpolatePalette,\n sequentialScale,\n quantizeScale,\n thresholdScale,\n SEQUENTIAL_BLUES,\n SEQUENTIAL_GREENS,\n SEQUENTIAL_VIRIDIS,\n DIVERGING_RDBU,\n} from \"./scales\";\nexport type { ColorScale } from \"./scales\";\nexport { REGION_COLORS, regionLegendItems } from \"./regions\";\n"],"mappings":"6kBAuBA,eAAsB,GAAkD,CAEpE,OAAO,MAAA,QAAA,QAAA,CAAA,CAAA,SAAA,QADW,iBAAA,CAAA,EAAA,CACP,aACf"}
1
+ {"version":3,"file":"br.cjs","names":[],"sources":["../src/br/index.ts"],"sourcesContent":["// Brazilian locations data (states + cities) — mirrors the `utils/locations`\n// module of tempest-fastapi-sdk.\nexport {\n listStates,\n getState,\n citiesByUf,\n statesByRegion,\n isValidUf,\n normalizeUf,\n isValidCity,\n ufChoices,\n cityChoices,\n} from \"./locations\";\nexport type { UF, BrRegion, BrazilState, Choice } from \"./locations\";\n\n// UF GeoJSON types (the geometry itself is lazy-loaded by BrazilMap).\nimport type { BrUfFeatureCollection } from \"./br-geo\";\nexport type { BrUfFeature, BrUfFeatureCollection, BrUfGeometry, Ring } from \"./br-geo\";\n\n/**\n * Lazily load the bundled simplified UF GeoJSON (~36 KB gzip). Kept out of the\n * synchronous barrel so a data-only import never pulls the geometry.\n */\nexport async function loadBrUfGeoJson(): Promise<BrUfFeatureCollection> {\n const mod = await import(\"./br-geo\");\n return mod.BR_UF_GEOJSON;\n}\n\n// Per-state municipality geometry (lazy, one chunk per UF).\nexport { loadStateMunicipalities } from \"./state-geo\";\nexport type { MunicipalityFeature, StateMunicipalities } from \"./state-geo\";\n\n// Offline geocoding (lazy centroid index).\nexport {\n nearestMunicipality,\n reverseGeocode,\n geocodeMunicipality,\n searchMunicipalities,\n municipalityCentroid,\n stateCentroid,\n} from \"./geocode\";\nexport type { MunicipalityCentroid, NearestMunicipality, ReverseGeocodeResult } from \"./geocode\";\n\n// Components\nexport { BrazilMap } from \"./BrazilMap\";\nexport type { BrazilMapProps, BrazilMapTooltipData } from \"./BrazilMap\";\nexport { BrazilStateMap } from \"./BrazilStateMap\";\nexport type {\n BrazilStateMapProps,\n BrazilStateMapTooltipData,\n Municipality,\n} from \"./BrazilStateMap\";\nexport { BrazilStateCitySelect } from \"./BrazilStateCitySelect\";\nexport type { BrazilStateCitySelectProps, BrazilStateCitySelection } from \"./BrazilStateCitySelect\";\nexport { MunicipalitySearch } from \"./MunicipalitySearch\";\nexport type { MunicipalitySearchProps } from \"./MunicipalitySearch\";\nexport type { GeoMarker } from \"@/geo/types\";\nexport type { MapMarkersProps } from \"./MapMarkers\";\nexport { MapLegend } from \"./MapLegend\";\nexport type { MapLegendProps, LegendItem } from \"./MapLegend\";\n\n// Pix — BR Code (EMV MPM) payload + the QR that carries it.\nexport {\n normalizePixKey,\n parsePixPayload,\n PixError,\n pixCrc16,\n pixKeyType,\n pixPayload,\n} from \"./pix\";\nexport type {\n NormalizedPixKey,\n ParsePixOptions,\n PixData,\n PixDynamicInput,\n PixField,\n PixInput,\n PixKeyType,\n PixStaticInput,\n} from \"./pix\";\nexport { PixQRCode } from \"./PixQRCode\";\nexport type { PixQRCodeLabels, PixQRCodeProps } from \"./PixQRCode\";\n\n// Boleto — 47/48-digit typed line, 44-digit barcode, FEBRABAN check digits.\nexport {\n boletoDueDate,\n BoletoError,\n boletoKind,\n codigoBarrasToLinhaDigitavel,\n fatorVencimento,\n formatLinhaDigitavel,\n linhaDigitavelToCodigoBarras,\n mod10Dac,\n mod11DacArrecadacao,\n mod11DacCobranca,\n parseCodigoBarras,\n parseLinhaDigitavel,\n validateBoleto,\n} from \"./boleto\";\nexport type {\n Boleto,\n BoletoArrecadacao,\n BoletoBanco,\n BoletoEpoch,\n BoletoKind,\n BoletoOptions,\n} from \"./boleto\";\n\n// NF-e / NFC-e / CT-e access key.\nexport {\n chaveNFeCheckDigit,\n ChaveNFeError,\n formatChaveNFe,\n parseChaveNFe,\n validateChaveNFe,\n} from \"./nfe\";\nexport type { ChaveNFe } from \"./nfe\";\n\n// National holidays + business-day arithmetic.\nexport {\n addBusinessDays,\n easterSunday,\n holidaysFor,\n isBusinessDay,\n isHoliday,\n nextBusinessDay,\n} from \"./holidays\";\nexport type { BusinessDayOptions, DateInput, Holiday, HolidayKind } from \"./holidays\";\n\n// Color scales + palettes for choropleths.\nexport {\n sequentialScale,\n quantizeScale,\n thresholdScale,\n SEQUENTIAL_BLUES,\n SEQUENTIAL_GREENS,\n SEQUENTIAL_VIRIDIS,\n DIVERGING_RDBU,\n} from \"./scales\";\nexport type { ColorScale } from \"./scales\";\nexport { REGION_COLORS, regionLegendItems } from \"./regions\";\n"],"mappings":"4iBAuBA,eAAsB,GAAkD,CAEpE,OAAO,MAAA,QAAA,QAAA,CAAA,CAAA,SAAA,QADW,iBAAA,CAAA,EAAA,CACP,aACf"}
package/dist/br.d.ts CHANGED
@@ -674,12 +674,6 @@ export declare type HolidayKind = "national" | "banking";
674
674
  */
675
675
  export declare function holidaysFor(year: number): Holiday[];
676
676
 
677
- /**
678
- * Interpolate a palette at `t ∈ [0, 1]`, blending between the two nearest
679
- * stops. `t <= 0` → first color, `t >= 1` → last.
680
- */
681
- export declare function interpolatePalette(palette: readonly string[], t: number): string;
682
-
683
677
  /**
684
678
  * Whether a date is a working day: not a weekend, not a holiday.
685
679
  *
@@ -793,13 +787,6 @@ export declare interface MapLegendProps extends Omit<HTMLAttributes<HTMLDivEleme
793
787
  format?: (value: number) => string;
794
788
  }
795
789
 
796
- /**
797
- * SVG overlay of point markers, projected with the host map's projection so
798
- * they align with its shapes. Each marker carries a native `<title>` (its
799
- * `label`) and is clickable when `onMarkerClick` is set.
800
- */
801
- export declare function MapMarkers({ projection, markers, onMarkerClick }: MapMarkersProps): JSX.Element;
802
-
803
790
  export declare interface MapMarkersProps {
804
791
  /** Projection used by the host map (markers must share it to line up). */
805
792
  projection: FittedProjection;
package/dist/br.js CHANGED
@@ -1,24 +1,23 @@
1
1
  import { citiesByUf as e, cityChoices as t, getState as n, isValidCity as r, isValidUf as i, listStates as a, normalizeUf as o, statesByRegion as s, ufChoices as c } from "./br/locations.js";
2
2
  import { loadStateMunicipalities as l } from "./br/state-geo.js";
3
3
  import { geocodeMunicipality as u, municipalityCentroid as d, nearestMunicipality as f, reverseGeocode as p, searchMunicipalities as m, stateCentroid as h } from "./br/geocode.js";
4
- import { MapMarkers as g } from "./br/MapMarkers.js";
5
- import { REGION_COLORS as _, regionLegendItems as v } from "./br/regions.js";
6
- import { BrazilMap as y } from "./br/BrazilMap.js";
7
- import { BrazilStateMap as b } from "./br/BrazilStateMap.js";
8
- import { BrazilStateCitySelect as x } from "./br/BrazilStateCitySelect.js";
9
- import { MunicipalitySearch as S } from "./br/MunicipalitySearch.js";
10
- import { DIVERGING_RDBU as C, SEQUENTIAL_BLUES as w, SEQUENTIAL_GREENS as T, SEQUENTIAL_VIRIDIS as E, interpolatePalette as D, quantizeScale as O, sequentialScale as k, thresholdScale as A } from "./br/scales.js";
11
- import { MapLegend as j } from "./br/MapLegend.js";
12
- import { PixError as M, normalizePixKey as N, parsePixPayload as P, pixCrc16 as F, pixKeyType as I, pixPayload as L } from "./br/pix.js";
13
- import { PixQRCode as R } from "./br/PixQRCode.js";
14
- import { BoletoError as z, boletoDueDate as B, boletoKind as V, codigoBarrasToLinhaDigitavel as H, fatorVencimento as U, formatLinhaDigitavel as W, linhaDigitavelToCodigoBarras as G, mod10Dac as K, mod11DacArrecadacao as q, mod11DacCobranca as J, parseCodigoBarras as Y, parseLinhaDigitavel as X, validateBoleto as Z } from "./br/boleto.js";
15
- import { ChaveNFeError as Q, chaveNFeCheckDigit as $, formatChaveNFe as ee, parseChaveNFe as te, validateChaveNFe as ne } from "./br/nfe.js";
16
- import { addBusinessDays as re, easterSunday as ie, holidaysFor as ae, isBusinessDay as oe, isHoliday as se, nextBusinessDay as ce } from "./br/holidays.js";
4
+ import { REGION_COLORS as g, regionLegendItems as _ } from "./br/regions.js";
5
+ import { BrazilMap as v } from "./br/BrazilMap.js";
6
+ import { BrazilStateMap as y } from "./br/BrazilStateMap.js";
7
+ import { BrazilStateCitySelect as b } from "./br/BrazilStateCitySelect.js";
8
+ import { MunicipalitySearch as x } from "./br/MunicipalitySearch.js";
9
+ import { DIVERGING_RDBU as S, SEQUENTIAL_BLUES as C, SEQUENTIAL_GREENS as w, SEQUENTIAL_VIRIDIS as T, quantizeScale as E, sequentialScale as D, thresholdScale as O } from "./br/scales.js";
10
+ import { MapLegend as k } from "./br/MapLegend.js";
11
+ import { PixError as A, normalizePixKey as j, parsePixPayload as M, pixCrc16 as N, pixKeyType as P, pixPayload as F } from "./br/pix.js";
12
+ import { PixQRCode as I } from "./br/PixQRCode.js";
13
+ import { BoletoError as L, boletoDueDate as R, boletoKind as z, codigoBarrasToLinhaDigitavel as B, fatorVencimento as V, formatLinhaDigitavel as H, linhaDigitavelToCodigoBarras as U, mod10Dac as W, mod11DacArrecadacao as G, mod11DacCobranca as K, parseCodigoBarras as q, parseLinhaDigitavel as J, validateBoleto as Y } from "./br/boleto.js";
14
+ import { ChaveNFeError as X, chaveNFeCheckDigit as Z, formatChaveNFe as Q, parseChaveNFe as $, validateChaveNFe as ee } from "./br/nfe.js";
15
+ import { addBusinessDays as te, easterSunday as ne, holidaysFor as re, isBusinessDay as ie, isHoliday as ae, nextBusinessDay as oe } from "./br/holidays.js";
17
16
  //#region src/br/index.ts
18
- async function le() {
17
+ async function se() {
19
18
  return (await import("./br/br-geo.js")).BR_UF_GEOJSON;
20
19
  }
21
20
  //#endregion
22
- export { z as BoletoError, y as BrazilMap, x as BrazilStateCitySelect, b as BrazilStateMap, Q as ChaveNFeError, C as DIVERGING_RDBU, j as MapLegend, g as MapMarkers, S as MunicipalitySearch, M as PixError, R as PixQRCode, _ as REGION_COLORS, w as SEQUENTIAL_BLUES, T as SEQUENTIAL_GREENS, E as SEQUENTIAL_VIRIDIS, re as addBusinessDays, B as boletoDueDate, V as boletoKind, $ as chaveNFeCheckDigit, e as citiesByUf, t as cityChoices, H as codigoBarrasToLinhaDigitavel, ie as easterSunday, U as fatorVencimento, ee as formatChaveNFe, W as formatLinhaDigitavel, u as geocodeMunicipality, n as getState, ae as holidaysFor, D as interpolatePalette, oe as isBusinessDay, se as isHoliday, r as isValidCity, i as isValidUf, G as linhaDigitavelToCodigoBarras, a as listStates, le as loadBrUfGeoJson, l as loadStateMunicipalities, K as mod10Dac, q as mod11DacArrecadacao, J as mod11DacCobranca, d as municipalityCentroid, f as nearestMunicipality, ce as nextBusinessDay, N as normalizePixKey, o as normalizeUf, te as parseChaveNFe, Y as parseCodigoBarras, X as parseLinhaDigitavel, P as parsePixPayload, F as pixCrc16, I as pixKeyType, L as pixPayload, O as quantizeScale, v as regionLegendItems, p as reverseGeocode, m as searchMunicipalities, k as sequentialScale, h as stateCentroid, s as statesByRegion, A as thresholdScale, c as ufChoices, Z as validateBoleto, ne as validateChaveNFe };
21
+ export { L as BoletoError, v as BrazilMap, b as BrazilStateCitySelect, y as BrazilStateMap, X as ChaveNFeError, S as DIVERGING_RDBU, k as MapLegend, x as MunicipalitySearch, A as PixError, I as PixQRCode, g as REGION_COLORS, C as SEQUENTIAL_BLUES, w as SEQUENTIAL_GREENS, T as SEQUENTIAL_VIRIDIS, te as addBusinessDays, R as boletoDueDate, z as boletoKind, Z as chaveNFeCheckDigit, e as citiesByUf, t as cityChoices, B as codigoBarrasToLinhaDigitavel, ne as easterSunday, V as fatorVencimento, Q as formatChaveNFe, H as formatLinhaDigitavel, u as geocodeMunicipality, n as getState, re as holidaysFor, ie as isBusinessDay, ae as isHoliday, r as isValidCity, i as isValidUf, U as linhaDigitavelToCodigoBarras, a as listStates, se as loadBrUfGeoJson, l as loadStateMunicipalities, W as mod10Dac, G as mod11DacArrecadacao, K as mod11DacCobranca, d as municipalityCentroid, f as nearestMunicipality, oe as nextBusinessDay, j as normalizePixKey, o as normalizeUf, $ as parseChaveNFe, q as parseCodigoBarras, J as parseLinhaDigitavel, M as parsePixPayload, N as pixCrc16, P as pixKeyType, F as pixPayload, E as quantizeScale, _ as regionLegendItems, p as reverseGeocode, m as searchMunicipalities, D as sequentialScale, h as stateCentroid, s as statesByRegion, O as thresholdScale, c as ufChoices, Y as validateBoleto, ee as validateChaveNFe };
23
22
 
24
23
  //# sourceMappingURL=br.js.map
package/dist/br.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"br.js","names":[],"sources":["../src/br/index.ts"],"sourcesContent":["// Brazilian locations data (states + cities) — mirrors the `utils/locations`\n// module of tempest-fastapi-sdk.\nexport {\n listStates,\n getState,\n citiesByUf,\n statesByRegion,\n isValidUf,\n normalizeUf,\n isValidCity,\n ufChoices,\n cityChoices,\n} from \"./locations\";\nexport type { UF, BrRegion, BrazilState, Choice } from \"./locations\";\n\n// UF GeoJSON types (the geometry itself is lazy-loaded by BrazilMap).\nimport type { BrUfFeatureCollection } from \"./br-geo\";\nexport type { BrUfFeature, BrUfFeatureCollection, BrUfGeometry, Ring } from \"./br-geo\";\n\n/**\n * Lazily load the bundled simplified UF GeoJSON (~36 KB gzip). Kept out of the\n * synchronous barrel so a data-only import never pulls the geometry.\n */\nexport async function loadBrUfGeoJson(): Promise<BrUfFeatureCollection> {\n const mod = await import(\"./br-geo\");\n return mod.BR_UF_GEOJSON;\n}\n\n// Per-state municipality geometry (lazy, one chunk per UF).\nexport { loadStateMunicipalities } from \"./state-geo\";\nexport type { MunicipalityFeature, StateMunicipalities } from \"./state-geo\";\n\n// Offline geocoding (lazy centroid index).\nexport {\n nearestMunicipality,\n reverseGeocode,\n geocodeMunicipality,\n searchMunicipalities,\n municipalityCentroid,\n stateCentroid,\n} from \"./geocode\";\nexport type { MunicipalityCentroid, NearestMunicipality, ReverseGeocodeResult } from \"./geocode\";\n\n// Components\nexport { BrazilMap } from \"./BrazilMap\";\nexport type { BrazilMapProps, BrazilMapTooltipData } from \"./BrazilMap\";\nexport { BrazilStateMap } from \"./BrazilStateMap\";\nexport type {\n BrazilStateMapProps,\n BrazilStateMapTooltipData,\n Municipality,\n} from \"./BrazilStateMap\";\nexport { BrazilStateCitySelect } from \"./BrazilStateCitySelect\";\nexport type { BrazilStateCitySelectProps, BrazilStateCitySelection } from \"./BrazilStateCitySelect\";\nexport { MunicipalitySearch } from \"./MunicipalitySearch\";\nexport type { MunicipalitySearchProps } from \"./MunicipalitySearch\";\nexport type { GeoMarker } from \"@/geo/types\";\nexport { MapMarkers } from \"./MapMarkers\";\nexport type { MapMarkersProps } from \"./MapMarkers\";\nexport { MapLegend } from \"./MapLegend\";\nexport type { MapLegendProps, LegendItem } from \"./MapLegend\";\n\n// Pix — BR Code (EMV MPM) payload + the QR that carries it.\nexport {\n normalizePixKey,\n parsePixPayload,\n PixError,\n pixCrc16,\n pixKeyType,\n pixPayload,\n} from \"./pix\";\nexport type {\n NormalizedPixKey,\n ParsePixOptions,\n PixData,\n PixDynamicInput,\n PixField,\n PixInput,\n PixKeyType,\n PixStaticInput,\n} from \"./pix\";\nexport { PixQRCode } from \"./PixQRCode\";\nexport type { PixQRCodeLabels, PixQRCodeProps } from \"./PixQRCode\";\n\n// Boleto — 47/48-digit typed line, 44-digit barcode, FEBRABAN check digits.\nexport {\n boletoDueDate,\n BoletoError,\n boletoKind,\n codigoBarrasToLinhaDigitavel,\n fatorVencimento,\n formatLinhaDigitavel,\n linhaDigitavelToCodigoBarras,\n mod10Dac,\n mod11DacArrecadacao,\n mod11DacCobranca,\n parseCodigoBarras,\n parseLinhaDigitavel,\n validateBoleto,\n} from \"./boleto\";\nexport type {\n Boleto,\n BoletoArrecadacao,\n BoletoBanco,\n BoletoEpoch,\n BoletoKind,\n BoletoOptions,\n} from \"./boleto\";\n\n// NF-e / NFC-e / CT-e access key.\nexport {\n chaveNFeCheckDigit,\n ChaveNFeError,\n formatChaveNFe,\n parseChaveNFe,\n validateChaveNFe,\n} from \"./nfe\";\nexport type { ChaveNFe } from \"./nfe\";\n\n// National holidays + business-day arithmetic.\nexport {\n addBusinessDays,\n easterSunday,\n holidaysFor,\n isBusinessDay,\n isHoliday,\n nextBusinessDay,\n} from \"./holidays\";\nexport type { BusinessDayOptions, DateInput, Holiday, HolidayKind } from \"./holidays\";\n\n// Color scales + palettes for choropleths.\nexport {\n interpolatePalette,\n sequentialScale,\n quantizeScale,\n thresholdScale,\n SEQUENTIAL_BLUES,\n SEQUENTIAL_GREENS,\n SEQUENTIAL_VIRIDIS,\n DIVERGING_RDBU,\n} from \"./scales\";\nexport type { ColorScale } from \"./scales\";\nexport { REGION_COLORS, regionLegendItems } from \"./regions\";\n"],"mappings":";;;;;;;;;;;;;;;;;AAuBA,eAAsB,KAAkD;CAEpE,QAAO,MADW,OAAO,kBAAA,CACd;AACf"}
1
+ {"version":3,"file":"br.js","names":[],"sources":["../src/br/index.ts"],"sourcesContent":["// Brazilian locations data (states + cities) — mirrors the `utils/locations`\n// module of tempest-fastapi-sdk.\nexport {\n listStates,\n getState,\n citiesByUf,\n statesByRegion,\n isValidUf,\n normalizeUf,\n isValidCity,\n ufChoices,\n cityChoices,\n} from \"./locations\";\nexport type { UF, BrRegion, BrazilState, Choice } from \"./locations\";\n\n// UF GeoJSON types (the geometry itself is lazy-loaded by BrazilMap).\nimport type { BrUfFeatureCollection } from \"./br-geo\";\nexport type { BrUfFeature, BrUfFeatureCollection, BrUfGeometry, Ring } from \"./br-geo\";\n\n/**\n * Lazily load the bundled simplified UF GeoJSON (~36 KB gzip). Kept out of the\n * synchronous barrel so a data-only import never pulls the geometry.\n */\nexport async function loadBrUfGeoJson(): Promise<BrUfFeatureCollection> {\n const mod = await import(\"./br-geo\");\n return mod.BR_UF_GEOJSON;\n}\n\n// Per-state municipality geometry (lazy, one chunk per UF).\nexport { loadStateMunicipalities } from \"./state-geo\";\nexport type { MunicipalityFeature, StateMunicipalities } from \"./state-geo\";\n\n// Offline geocoding (lazy centroid index).\nexport {\n nearestMunicipality,\n reverseGeocode,\n geocodeMunicipality,\n searchMunicipalities,\n municipalityCentroid,\n stateCentroid,\n} from \"./geocode\";\nexport type { MunicipalityCentroid, NearestMunicipality, ReverseGeocodeResult } from \"./geocode\";\n\n// Components\nexport { BrazilMap } from \"./BrazilMap\";\nexport type { BrazilMapProps, BrazilMapTooltipData } from \"./BrazilMap\";\nexport { BrazilStateMap } from \"./BrazilStateMap\";\nexport type {\n BrazilStateMapProps,\n BrazilStateMapTooltipData,\n Municipality,\n} from \"./BrazilStateMap\";\nexport { BrazilStateCitySelect } from \"./BrazilStateCitySelect\";\nexport type { BrazilStateCitySelectProps, BrazilStateCitySelection } from \"./BrazilStateCitySelect\";\nexport { MunicipalitySearch } from \"./MunicipalitySearch\";\nexport type { MunicipalitySearchProps } from \"./MunicipalitySearch\";\nexport type { GeoMarker } from \"@/geo/types\";\nexport type { MapMarkersProps } from \"./MapMarkers\";\nexport { MapLegend } from \"./MapLegend\";\nexport type { MapLegendProps, LegendItem } from \"./MapLegend\";\n\n// Pix — BR Code (EMV MPM) payload + the QR that carries it.\nexport {\n normalizePixKey,\n parsePixPayload,\n PixError,\n pixCrc16,\n pixKeyType,\n pixPayload,\n} from \"./pix\";\nexport type {\n NormalizedPixKey,\n ParsePixOptions,\n PixData,\n PixDynamicInput,\n PixField,\n PixInput,\n PixKeyType,\n PixStaticInput,\n} from \"./pix\";\nexport { PixQRCode } from \"./PixQRCode\";\nexport type { PixQRCodeLabels, PixQRCodeProps } from \"./PixQRCode\";\n\n// Boleto — 47/48-digit typed line, 44-digit barcode, FEBRABAN check digits.\nexport {\n boletoDueDate,\n BoletoError,\n boletoKind,\n codigoBarrasToLinhaDigitavel,\n fatorVencimento,\n formatLinhaDigitavel,\n linhaDigitavelToCodigoBarras,\n mod10Dac,\n mod11DacArrecadacao,\n mod11DacCobranca,\n parseCodigoBarras,\n parseLinhaDigitavel,\n validateBoleto,\n} from \"./boleto\";\nexport type {\n Boleto,\n BoletoArrecadacao,\n BoletoBanco,\n BoletoEpoch,\n BoletoKind,\n BoletoOptions,\n} from \"./boleto\";\n\n// NF-e / NFC-e / CT-e access key.\nexport {\n chaveNFeCheckDigit,\n ChaveNFeError,\n formatChaveNFe,\n parseChaveNFe,\n validateChaveNFe,\n} from \"./nfe\";\nexport type { ChaveNFe } from \"./nfe\";\n\n// National holidays + business-day arithmetic.\nexport {\n addBusinessDays,\n easterSunday,\n holidaysFor,\n isBusinessDay,\n isHoliday,\n nextBusinessDay,\n} from \"./holidays\";\nexport type { BusinessDayOptions, DateInput, Holiday, HolidayKind } from \"./holidays\";\n\n// Color scales + palettes for choropleths.\nexport {\n sequentialScale,\n quantizeScale,\n thresholdScale,\n SEQUENTIAL_BLUES,\n SEQUENTIAL_GREENS,\n SEQUENTIAL_VIRIDIS,\n DIVERGING_RDBU,\n} from \"./scales\";\nexport type { ColorScale } from \"./scales\";\nexport { REGION_COLORS, regionLegendItems } from \"./regions\";\n"],"mappings":";;;;;;;;;;;;;;;;AAuBA,eAAsB,KAAkD;CAEpE,QAAO,MADW,OAAO,kBAAA,CACd;AACf"}
@@ -1,2 +1,2 @@
1
- var e=[`#2563eb`,`#16a34a`,`#f59e0b`,`#7c3aed`,`#ec4899`,`#06b6d4`],t=8;function n(t){if(typeof window>`u`||typeof document>`u`)return e;let n=t??document.documentElement;if(!n)return e;let r=window.getComputedStyle(n),i=[],a=Number.parseInt(r.getPropertyValue(`--tempest-chart-count`).trim(),10),o=Number.isFinite(a)&&a>0?Math.min(a,8):8;for(let e=1;e<=o;e+=1){let t=r.getPropertyValue(`--tempest-chart-${e}`).trim();if(!t)break;i.push(t)}return i.length>0?i:e}function r(e,t,n=e===`grid`?`#e4e7ec`:`#667085`){if(typeof window>`u`||typeof document>`u`)return n;let r=t??document.documentElement;return r&&window.getComputedStyle(r).getPropertyValue(`--tempest-chart-${e}`).trim()||n}exports.CHART_COLOR_TOKEN_COUNT=t,exports.DEFAULT_CHART_COLORS=e,exports.resolveChartChrome=r,exports.resolveChartColors=n;
1
+ var e=[`#2563eb`,`#16a34a`,`#f59e0b`,`#7c3aed`,`#ec4899`,`#06b6d4`];function t(t){if(typeof window>`u`||typeof document>`u`)return e;let n=t??document.documentElement;if(!n)return e;let r=window.getComputedStyle(n),i=[],a=Number.parseInt(r.getPropertyValue(`--tempest-chart-count`).trim(),10),o=Number.isFinite(a)&&a>0?Math.min(a,8):8;for(let e=1;e<=o;e+=1){let t=r.getPropertyValue(`--tempest-chart-${e}`).trim();if(!t)break;i.push(t)}return i.length>0?i:e}function n(e,t,n=e===`grid`?`#e4e7ec`:`#667085`){if(typeof window>`u`||typeof document>`u`)return n;let r=t??document.documentElement;return r&&window.getComputedStyle(r).getPropertyValue(`--tempest-chart-${e}`).trim()||n}exports.DEFAULT_CHART_COLORS=e,exports.resolveChartChrome=n,exports.resolveChartColors=t;
2
2
  //# sourceMappingURL=palette.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"palette.cjs","names":[],"sources":["../../src/charts/palette.ts"],"sourcesContent":["/**\n * Series colors for Tempest charts, resolved from the theme tokens.\n *\n * Recharts sets colors as SVG presentation attributes (`fill=\"…\"`), where\n * `var(--token)` is **not** substituted — browsers only resolve custom properties\n * in CSS declarations. So the tokens are read from the computed style and handed\n * over as literal colors, which is what keeps a re-theme (and dark mode)\n * reflected in the charts.\n */\n\n/**\n * Fallback palette: six visually distinct hex colors (blue, green, amber,\n * violet, pink, cyan) in cycle order.\n *\n * Used when the `--tempest-chart-*` tokens cannot be read — no stylesheet\n * imported, a non-browser environment (tests, build scripts), or a host page that\n * dropped the tokens. Exported so callers can start from it and pass a tweaked\n * array to any chart's `colors` prop.\n */\nexport const DEFAULT_CHART_COLORS: string[] = [\n \"#2563eb\", // blue\n \"#16a34a\", // green\n \"#f59e0b\", // amber\n \"#7c3aed\", // violet\n \"#ec4899\", // pink\n \"#06b6d4\", // cyan\n];\n\n/** How many `--tempest-chart-N` tokens the SDK ships. */\nexport const CHART_COLOR_TOKEN_COUNT = 8;\n\n/**\n * Read `--tempest-chart-1` … `--tempest-chart-8` into a color array.\n *\n * Respects `--tempest-chart-count` when the theme declares one (`createTheme`\n * writes it), so a six-color brand palette is read as six and not padded with the\n * SDK's leftover `-7`/`-8` defaults. Otherwise it walks the tokens and stops at\n * the first unset one. Returns {@link DEFAULT_CHART_COLORS} when nothing is\n * resolvable.\n *\n * @param element - Element to resolve the tokens against. Default `<html>`; pass\n * a subtree root when a section carries a scoped theme.\n * @returns Literal color strings in cycle order.\n */\nexport function resolveChartColors(element?: Element | null): string[] {\n if (typeof window === \"undefined\" || typeof document === \"undefined\") {\n return DEFAULT_CHART_COLORS;\n }\n\n const target = element ?? document.documentElement;\n if (!target) return DEFAULT_CHART_COLORS;\n\n const styles = window.getComputedStyle(target);\n const resolved: string[] = [];\n const declared = Number.parseInt(styles.getPropertyValue(\"--tempest-chart-count\").trim(), 10);\n const limit =\n Number.isFinite(declared) && declared > 0\n ? Math.min(declared, CHART_COLOR_TOKEN_COUNT)\n : CHART_COLOR_TOKEN_COUNT;\n\n for (let index = 1; index <= limit; index += 1) {\n const value = styles.getPropertyValue(`--tempest-chart-${index}`).trim();\n if (!value) break;\n resolved.push(value);\n }\n\n return resolved.length > 0 ? resolved : DEFAULT_CHART_COLORS;\n}\n\n/**\n * Read one piece of chart chrome (`--tempest-chart-grid` / `--tempest-chart-axis`).\n *\n * @param part - Which chrome token to read.\n * @param element - Element to resolve against. Default `<html>`.\n * @param fallback - Value returned when the token is unset.\n * @returns The resolved color, or `fallback`.\n */\nexport function resolveChartChrome(\n part: \"grid\" | \"axis\",\n element?: Element | null,\n fallback = part === \"grid\" ? \"#e4e7ec\" : \"#667085\",\n): string {\n if (typeof window === \"undefined\" || typeof document === \"undefined\") return fallback;\n const target = element ?? document.documentElement;\n if (!target) return fallback;\n const value = window\n .getComputedStyle(target)\n .getPropertyValue(`--tempest-chart-${part}`)\n .trim();\n return value || fallback;\n}\n"],"mappings":"AAmBA,IAAa,EAAiC,CAC1C,UACA,UACA,UACA,UACA,UACA,SACJ,EAGa,EAA0B,EAevC,SAAgB,EAAmB,EAAoC,CACnE,GAAI,OAAO,OAAW,KAAe,OAAO,SAAa,IACrD,OAAO,EAGX,IAAM,EAAS,GAAW,SAAS,gBACnC,GAAI,CAAC,EAAQ,OAAO,EAEpB,IAAM,EAAS,OAAO,iBAAiB,CAAM,EACvC,EAAqB,CAAC,EACtB,EAAW,OAAO,SAAS,EAAO,iBAAiB,uBAAuB,CAAC,CAAC,KAAK,EAAG,EAAE,EACtF,EACF,OAAO,SAAS,CAAQ,GAAK,EAAW,EAClC,KAAK,IAAI,EAAA,CAAiC,EAAA,EAGpD,IAAK,IAAI,EAAQ,EAAG,GAAS,EAAO,GAAS,EAAG,CAC5C,IAAM,EAAQ,EAAO,iBAAiB,mBAAmB,GAAO,CAAC,CAAC,KAAK,EACvE,GAAI,CAAC,EAAO,MACZ,EAAS,KAAK,CAAK,CACvB,CAEA,OAAO,EAAS,OAAS,EAAI,EAAW,CAC5C,CAUA,SAAgB,EACZ,EACA,EACA,EAAW,IAAS,OAAS,UAAY,UACnC,CACN,GAAI,OAAO,OAAW,KAAe,OAAO,SAAa,IAAa,OAAO,EAC7E,IAAM,EAAS,GAAW,SAAS,gBAMnC,OALK,GACS,OACT,iBAAiB,CAAM,CAAC,CACxB,iBAAiB,mBAAmB,GAAM,CAAC,CAC3C,KACE,GALa,CAMxB"}
1
+ {"version":3,"file":"palette.cjs","names":[],"sources":["../../src/charts/palette.ts"],"sourcesContent":["/**\n * Series colors for Tempest charts, resolved from the theme tokens.\n *\n * Recharts sets colors as SVG presentation attributes (`fill=\"…\"`), where\n * `var(--token)` is **not** substituted — browsers only resolve custom properties\n * in CSS declarations. So the tokens are read from the computed style and handed\n * over as literal colors, which is what keeps a re-theme (and dark mode)\n * reflected in the charts.\n */\n\n/**\n * Fallback palette: six visually distinct hex colors (blue, green, amber,\n * violet, pink, cyan) in cycle order.\n *\n * Used when the `--tempest-chart-*` tokens cannot be read — no stylesheet\n * imported, a non-browser environment (tests, build scripts), or a host page that\n * dropped the tokens. Exported so callers can start from it and pass a tweaked\n * array to any chart's `colors` prop.\n */\nexport const DEFAULT_CHART_COLORS: string[] = [\n \"#2563eb\", // blue\n \"#16a34a\", // green\n \"#f59e0b\", // amber\n \"#7c3aed\", // violet\n \"#ec4899\", // pink\n \"#06b6d4\", // cyan\n];\n\n/** How many `--tempest-chart-N` tokens the SDK ships. */\nexport const CHART_COLOR_TOKEN_COUNT = 8;\n\n/**\n * Read `--tempest-chart-1` … `--tempest-chart-8` into a color array.\n *\n * Respects `--tempest-chart-count` when the theme declares one (`createTheme`\n * writes it), so a six-color brand palette is read as six and not padded with the\n * SDK's leftover `-7`/`-8` defaults. Otherwise it walks the tokens and stops at\n * the first unset one. Returns {@link DEFAULT_CHART_COLORS} when nothing is\n * resolvable.\n *\n * @param element - Element to resolve the tokens against. Default `<html>`; pass\n * a subtree root when a section carries a scoped theme.\n * @returns Literal color strings in cycle order.\n */\nexport function resolveChartColors(element?: Element | null): string[] {\n if (typeof window === \"undefined\" || typeof document === \"undefined\") {\n return DEFAULT_CHART_COLORS;\n }\n\n const target = element ?? document.documentElement;\n if (!target) return DEFAULT_CHART_COLORS;\n\n const styles = window.getComputedStyle(target);\n const resolved: string[] = [];\n const declared = Number.parseInt(styles.getPropertyValue(\"--tempest-chart-count\").trim(), 10);\n const limit =\n Number.isFinite(declared) && declared > 0\n ? Math.min(declared, CHART_COLOR_TOKEN_COUNT)\n : CHART_COLOR_TOKEN_COUNT;\n\n for (let index = 1; index <= limit; index += 1) {\n const value = styles.getPropertyValue(`--tempest-chart-${index}`).trim();\n if (!value) break;\n resolved.push(value);\n }\n\n return resolved.length > 0 ? resolved : DEFAULT_CHART_COLORS;\n}\n\n/**\n * Read one piece of chart chrome (`--tempest-chart-grid` / `--tempest-chart-axis`).\n *\n * @param part - Which chrome token to read.\n * @param element - Element to resolve against. Default `<html>`.\n * @param fallback - Value returned when the token is unset.\n * @returns The resolved color, or `fallback`.\n */\nexport function resolveChartChrome(\n part: \"grid\" | \"axis\",\n element?: Element | null,\n fallback = part === \"grid\" ? \"#e4e7ec\" : \"#667085\",\n): string {\n if (typeof window === \"undefined\" || typeof document === \"undefined\") return fallback;\n const target = element ?? document.documentElement;\n if (!target) return fallback;\n const value = window\n .getComputedStyle(target)\n .getPropertyValue(`--tempest-chart-${part}`)\n .trim();\n return value || fallback;\n}\n"],"mappings":"AAmBA,IAAa,EAAiC,CAC1C,UACA,UACA,UACA,UACA,UACA,SACJ,EAkBA,SAAgB,EAAmB,EAAoC,CACnE,GAAI,OAAO,OAAW,KAAe,OAAO,SAAa,IACrD,OAAO,EAGX,IAAM,EAAS,GAAW,SAAS,gBACnC,GAAI,CAAC,EAAQ,OAAO,EAEpB,IAAM,EAAS,OAAO,iBAAiB,CAAM,EACvC,EAAqB,CAAC,EACtB,EAAW,OAAO,SAAS,EAAO,iBAAiB,uBAAuB,CAAC,CAAC,KAAK,EAAG,EAAE,EACtF,EACF,OAAO,SAAS,CAAQ,GAAK,EAAW,EAClC,KAAK,IAAI,EAAA,CAAiC,EAAA,EAGpD,IAAK,IAAI,EAAQ,EAAG,GAAS,EAAO,GAAS,EAAG,CAC5C,IAAM,EAAQ,EAAO,iBAAiB,mBAAmB,GAAO,CAAC,CAAC,KAAK,EACvE,GAAI,CAAC,EAAO,MACZ,EAAS,KAAK,CAAK,CACvB,CAEA,OAAO,EAAS,OAAS,EAAI,EAAW,CAC5C,CAUA,SAAgB,EACZ,EACA,EACA,EAAW,IAAS,OAAS,UAAY,UACnC,CACN,GAAI,OAAO,OAAW,KAAe,OAAO,SAAa,IAAa,OAAO,EAC7E,IAAM,EAAS,GAAW,SAAS,gBAMnC,OALK,GACS,OACT,iBAAiB,CAAM,CAAC,CACxB,iBAAiB,mBAAmB,GAAM,CAAC,CAC3C,KACE,GALa,CAMxB"}
@@ -6,8 +6,8 @@ var e = [
6
6
  "#7c3aed",
7
7
  "#ec4899",
8
8
  "#06b6d4"
9
- ], t = 8;
10
- function n(t) {
9
+ ];
10
+ function t(t) {
11
11
  if (typeof window > "u" || typeof document > "u") return e;
12
12
  let n = t ?? document.documentElement;
13
13
  if (!n) return e;
@@ -19,12 +19,12 @@ function n(t) {
19
19
  }
20
20
  return i.length > 0 ? i : e;
21
21
  }
22
- function r(e, t, n = e === "grid" ? "#e4e7ec" : "#667085") {
22
+ function n(e, t, n = e === "grid" ? "#e4e7ec" : "#667085") {
23
23
  if (typeof window > "u" || typeof document > "u") return n;
24
24
  let r = t ?? document.documentElement;
25
25
  return r && window.getComputedStyle(r).getPropertyValue(`--tempest-chart-${e}`).trim() || n;
26
26
  }
27
27
  //#endregion
28
- export { t as CHART_COLOR_TOKEN_COUNT, e as DEFAULT_CHART_COLORS, r as resolveChartChrome, n as resolveChartColors };
28
+ export { e as DEFAULT_CHART_COLORS, n as resolveChartChrome, t as resolveChartColors };
29
29
 
30
30
  //# sourceMappingURL=palette.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"palette.js","names":[],"sources":["../../src/charts/palette.ts"],"sourcesContent":["/**\n * Series colors for Tempest charts, resolved from the theme tokens.\n *\n * Recharts sets colors as SVG presentation attributes (`fill=\"…\"`), where\n * `var(--token)` is **not** substituted — browsers only resolve custom properties\n * in CSS declarations. So the tokens are read from the computed style and handed\n * over as literal colors, which is what keeps a re-theme (and dark mode)\n * reflected in the charts.\n */\n\n/**\n * Fallback palette: six visually distinct hex colors (blue, green, amber,\n * violet, pink, cyan) in cycle order.\n *\n * Used when the `--tempest-chart-*` tokens cannot be read — no stylesheet\n * imported, a non-browser environment (tests, build scripts), or a host page that\n * dropped the tokens. Exported so callers can start from it and pass a tweaked\n * array to any chart's `colors` prop.\n */\nexport const DEFAULT_CHART_COLORS: string[] = [\n \"#2563eb\", // blue\n \"#16a34a\", // green\n \"#f59e0b\", // amber\n \"#7c3aed\", // violet\n \"#ec4899\", // pink\n \"#06b6d4\", // cyan\n];\n\n/** How many `--tempest-chart-N` tokens the SDK ships. */\nexport const CHART_COLOR_TOKEN_COUNT = 8;\n\n/**\n * Read `--tempest-chart-1` … `--tempest-chart-8` into a color array.\n *\n * Respects `--tempest-chart-count` when the theme declares one (`createTheme`\n * writes it), so a six-color brand palette is read as six and not padded with the\n * SDK's leftover `-7`/`-8` defaults. Otherwise it walks the tokens and stops at\n * the first unset one. Returns {@link DEFAULT_CHART_COLORS} when nothing is\n * resolvable.\n *\n * @param element - Element to resolve the tokens against. Default `<html>`; pass\n * a subtree root when a section carries a scoped theme.\n * @returns Literal color strings in cycle order.\n */\nexport function resolveChartColors(element?: Element | null): string[] {\n if (typeof window === \"undefined\" || typeof document === \"undefined\") {\n return DEFAULT_CHART_COLORS;\n }\n\n const target = element ?? document.documentElement;\n if (!target) return DEFAULT_CHART_COLORS;\n\n const styles = window.getComputedStyle(target);\n const resolved: string[] = [];\n const declared = Number.parseInt(styles.getPropertyValue(\"--tempest-chart-count\").trim(), 10);\n const limit =\n Number.isFinite(declared) && declared > 0\n ? Math.min(declared, CHART_COLOR_TOKEN_COUNT)\n : CHART_COLOR_TOKEN_COUNT;\n\n for (let index = 1; index <= limit; index += 1) {\n const value = styles.getPropertyValue(`--tempest-chart-${index}`).trim();\n if (!value) break;\n resolved.push(value);\n }\n\n return resolved.length > 0 ? resolved : DEFAULT_CHART_COLORS;\n}\n\n/**\n * Read one piece of chart chrome (`--tempest-chart-grid` / `--tempest-chart-axis`).\n *\n * @param part - Which chrome token to read.\n * @param element - Element to resolve against. Default `<html>`.\n * @param fallback - Value returned when the token is unset.\n * @returns The resolved color, or `fallback`.\n */\nexport function resolveChartChrome(\n part: \"grid\" | \"axis\",\n element?: Element | null,\n fallback = part === \"grid\" ? \"#e4e7ec\" : \"#667085\",\n): string {\n if (typeof window === \"undefined\" || typeof document === \"undefined\") return fallback;\n const target = element ?? document.documentElement;\n if (!target) return fallback;\n const value = window\n .getComputedStyle(target)\n .getPropertyValue(`--tempest-chart-${part}`)\n .trim();\n return value || fallback;\n}\n"],"mappings":";AAmBA,IAAa,IAAiC;CAC1C;CACA;CACA;CACA;CACA;CACA;AACJ,GAGa,IAA0B;AAevC,SAAgB,EAAmB,GAAoC;CACnE,IAAI,OAAO,SAAW,OAAe,OAAO,WAAa,KACrD,OAAO;CAGX,IAAM,IAAS,KAAW,SAAS;CACnC,IAAI,CAAC,GAAQ,OAAO;CAEpB,IAAM,IAAS,OAAO,iBAAiB,CAAM,GACvC,IAAqB,CAAC,GACtB,IAAW,OAAO,SAAS,EAAO,iBAAiB,uBAAuB,CAAC,CAAC,KAAK,GAAG,EAAE,GACtF,IACF,OAAO,SAAS,CAAQ,KAAK,IAAW,IAClC,KAAK,IAAI,GAAA,CAAiC,IAAA;CAGpD,KAAK,IAAI,IAAQ,GAAG,KAAS,GAAO,KAAS,GAAG;EAC5C,IAAM,IAAQ,EAAO,iBAAiB,mBAAmB,GAAO,CAAC,CAAC,KAAK;EACvE,IAAI,CAAC,GAAO;EACZ,EAAS,KAAK,CAAK;CACvB;CAEA,OAAO,EAAS,SAAS,IAAI,IAAW;AAC5C;AAUA,SAAgB,EACZ,GACA,GACA,IAAW,MAAS,SAAS,YAAY,WACnC;CACN,IAAI,OAAO,SAAW,OAAe,OAAO,WAAa,KAAa,OAAO;CAC7E,IAAM,IAAS,KAAW,SAAS;CAMnC,OALK,KACS,OACT,iBAAiB,CAAM,CAAC,CACxB,iBAAiB,mBAAmB,GAAM,CAAC,CAC3C,KACE,KALa;AAMxB"}
1
+ {"version":3,"file":"palette.js","names":[],"sources":["../../src/charts/palette.ts"],"sourcesContent":["/**\n * Series colors for Tempest charts, resolved from the theme tokens.\n *\n * Recharts sets colors as SVG presentation attributes (`fill=\"…\"`), where\n * `var(--token)` is **not** substituted — browsers only resolve custom properties\n * in CSS declarations. So the tokens are read from the computed style and handed\n * over as literal colors, which is what keeps a re-theme (and dark mode)\n * reflected in the charts.\n */\n\n/**\n * Fallback palette: six visually distinct hex colors (blue, green, amber,\n * violet, pink, cyan) in cycle order.\n *\n * Used when the `--tempest-chart-*` tokens cannot be read — no stylesheet\n * imported, a non-browser environment (tests, build scripts), or a host page that\n * dropped the tokens. Exported so callers can start from it and pass a tweaked\n * array to any chart's `colors` prop.\n */\nexport const DEFAULT_CHART_COLORS: string[] = [\n \"#2563eb\", // blue\n \"#16a34a\", // green\n \"#f59e0b\", // amber\n \"#7c3aed\", // violet\n \"#ec4899\", // pink\n \"#06b6d4\", // cyan\n];\n\n/** How many `--tempest-chart-N` tokens the SDK ships. */\nexport const CHART_COLOR_TOKEN_COUNT = 8;\n\n/**\n * Read `--tempest-chart-1` … `--tempest-chart-8` into a color array.\n *\n * Respects `--tempest-chart-count` when the theme declares one (`createTheme`\n * writes it), so a six-color brand palette is read as six and not padded with the\n * SDK's leftover `-7`/`-8` defaults. Otherwise it walks the tokens and stops at\n * the first unset one. Returns {@link DEFAULT_CHART_COLORS} when nothing is\n * resolvable.\n *\n * @param element - Element to resolve the tokens against. Default `<html>`; pass\n * a subtree root when a section carries a scoped theme.\n * @returns Literal color strings in cycle order.\n */\nexport function resolveChartColors(element?: Element | null): string[] {\n if (typeof window === \"undefined\" || typeof document === \"undefined\") {\n return DEFAULT_CHART_COLORS;\n }\n\n const target = element ?? document.documentElement;\n if (!target) return DEFAULT_CHART_COLORS;\n\n const styles = window.getComputedStyle(target);\n const resolved: string[] = [];\n const declared = Number.parseInt(styles.getPropertyValue(\"--tempest-chart-count\").trim(), 10);\n const limit =\n Number.isFinite(declared) && declared > 0\n ? Math.min(declared, CHART_COLOR_TOKEN_COUNT)\n : CHART_COLOR_TOKEN_COUNT;\n\n for (let index = 1; index <= limit; index += 1) {\n const value = styles.getPropertyValue(`--tempest-chart-${index}`).trim();\n if (!value) break;\n resolved.push(value);\n }\n\n return resolved.length > 0 ? resolved : DEFAULT_CHART_COLORS;\n}\n\n/**\n * Read one piece of chart chrome (`--tempest-chart-grid` / `--tempest-chart-axis`).\n *\n * @param part - Which chrome token to read.\n * @param element - Element to resolve against. Default `<html>`.\n * @param fallback - Value returned when the token is unset.\n * @returns The resolved color, or `fallback`.\n */\nexport function resolveChartChrome(\n part: \"grid\" | \"axis\",\n element?: Element | null,\n fallback = part === \"grid\" ? \"#e4e7ec\" : \"#667085\",\n): string {\n if (typeof window === \"undefined\" || typeof document === \"undefined\") return fallback;\n const target = element ?? document.documentElement;\n if (!target) return fallback;\n const value = window\n .getComputedStyle(target)\n .getPropertyValue(`--tempest-chart-${part}`)\n .trim();\n return value || fallback;\n}\n"],"mappings":";AAmBA,IAAa,IAAiC;CAC1C;CACA;CACA;CACA;CACA;CACA;AACJ;AAkBA,SAAgB,EAAmB,GAAoC;CACnE,IAAI,OAAO,SAAW,OAAe,OAAO,WAAa,KACrD,OAAO;CAGX,IAAM,IAAS,KAAW,SAAS;CACnC,IAAI,CAAC,GAAQ,OAAO;CAEpB,IAAM,IAAS,OAAO,iBAAiB,CAAM,GACvC,IAAqB,CAAC,GACtB,IAAW,OAAO,SAAS,EAAO,iBAAiB,uBAAuB,CAAC,CAAC,KAAK,GAAG,EAAE,GACtF,IACF,OAAO,SAAS,CAAQ,KAAK,IAAW,IAClC,KAAK,IAAI,GAAA,CAAiC,IAAA;CAGpD,KAAK,IAAI,IAAQ,GAAG,KAAS,GAAO,KAAS,GAAG;EAC5C,IAAM,IAAQ,EAAO,iBAAiB,mBAAmB,GAAO,CAAC,CAAC,KAAK;EACvE,IAAI,CAAC,GAAO;EACZ,EAAS,KAAK,CAAK;CACvB;CAEA,OAAO,EAAS,SAAS,IAAI,IAAW;AAC5C;AAUA,SAAgB,EACZ,GACA,GACA,IAAW,MAAS,SAAS,YAAY,WACnC;CACN,IAAI,OAAO,SAAW,OAAe,OAAO,WAAa,KAAa,OAAO;CAC7E,IAAM,IAAS,KAAW,SAAS;CAMnC,OALK,KACS,OACT,iBAAiB,CAAM,CAAC,CACxB,iBAAiB,mBAAmB,GAAM,CAAC,CAC3C,KACE,KALa;AAMxB"}
package/dist/charts.cjs CHANGED
@@ -1 +1 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./charts/scales.cjs"),t=require("./charts/palette.cjs"),n=require("./charts/use-chart-colors.cjs"),r=require("./charts/AreaChart.cjs"),i=require("./charts/BarChart.cjs"),a=require("./charts/LineChart.cjs"),o=require("./charts/PieChart.cjs"),s=require("./charts/RadarChart.cjs");exports.AreaChart=r.AreaChart,exports.BarChart=i.BarChart,exports.CHART_COLOR_TOKEN_COUNT=t.CHART_COLOR_TOKEN_COUNT,exports.DEFAULT_CHART_COLORS=t.DEFAULT_CHART_COLORS,exports.DIVERGING_STEP_COUNT=e.DIVERGING_STEP_COUNT,exports.LineChart=a.LineChart,exports.ORDINAL_START_STEP=e.ORDINAL_START_STEP,exports.PieChart=o.PieChart,exports.RadarChart=s.RadarChart,exports.SEQUENTIAL_STEP_COUNT=e.SEQUENTIAL_STEP_COUNT,exports.divergingScale=e.divergingScale,exports.resolveChartChrome=t.resolveChartChrome,exports.resolveChartColors=t.resolveChartColors,exports.scaleSteps=e.scaleSteps,exports.sequentialScale=e.sequentialScale,exports.useChartColors=n.useChartColors;
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./charts/scales.cjs"),t=require("./charts/palette.cjs"),n=require("./charts/use-chart-colors.cjs"),r=require("./charts/AreaChart.cjs"),i=require("./charts/BarChart.cjs"),a=require("./charts/LineChart.cjs"),o=require("./charts/PieChart.cjs"),s=require("./charts/RadarChart.cjs");exports.AreaChart=r.AreaChart,exports.BarChart=i.BarChart,exports.DEFAULT_CHART_COLORS=t.DEFAULT_CHART_COLORS,exports.DIVERGING_STEP_COUNT=e.DIVERGING_STEP_COUNT,exports.LineChart=a.LineChart,exports.ORDINAL_START_STEP=e.ORDINAL_START_STEP,exports.PieChart=o.PieChart,exports.RadarChart=s.RadarChart,exports.SEQUENTIAL_STEP_COUNT=e.SEQUENTIAL_STEP_COUNT,exports.divergingScale=e.divergingScale,exports.resolveChartChrome=t.resolveChartChrome,exports.resolveChartColors=t.resolveChartColors,exports.scaleSteps=e.scaleSteps,exports.sequentialScale=e.sequentialScale,exports.useChartColors=n.useChartColors;
package/dist/charts.d.ts CHANGED
@@ -57,9 +57,6 @@ export declare interface CartesianChartProps {
57
57
  className?: string;
58
58
  }
59
59
 
60
- /** How many `--tempest-chart-N` tokens the SDK ships. */
61
- export declare const CHART_COLOR_TOKEN_COUNT = 8;
62
-
63
60
  /** A `var(--tempest-chart-…)` reference, so the value follows the active theme. */
64
61
  export declare type ChartColorToken = string;
65
62
 
package/dist/charts.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import { DIVERGING_STEP_COUNT as e, ORDINAL_START_STEP as t, SEQUENTIAL_STEP_COUNT as n, divergingScale as r, scaleSteps as i, sequentialScale as a } from "./charts/scales.js";
2
- import { CHART_COLOR_TOKEN_COUNT as o, DEFAULT_CHART_COLORS as s, resolveChartChrome as c, resolveChartColors as l } from "./charts/palette.js";
3
- import { useChartColors as u } from "./charts/use-chart-colors.js";
4
- import { AreaChart as d } from "./charts/AreaChart.js";
5
- import { BarChart as f } from "./charts/BarChart.js";
6
- import { LineChart as p } from "./charts/LineChart.js";
7
- import { PieChart as m } from "./charts/PieChart.js";
8
- import { RadarChart as h } from "./charts/RadarChart.js";
9
- export { d as AreaChart, f as BarChart, o as CHART_COLOR_TOKEN_COUNT, s as DEFAULT_CHART_COLORS, e as DIVERGING_STEP_COUNT, p as LineChart, t as ORDINAL_START_STEP, m as PieChart, h as RadarChart, n as SEQUENTIAL_STEP_COUNT, r as divergingScale, c as resolveChartChrome, l as resolveChartColors, i as scaleSteps, a as sequentialScale, u as useChartColors };
2
+ import { DEFAULT_CHART_COLORS as o, resolveChartChrome as s, resolveChartColors as c } from "./charts/palette.js";
3
+ import { useChartColors as l } from "./charts/use-chart-colors.js";
4
+ import { AreaChart as u } from "./charts/AreaChart.js";
5
+ import { BarChart as d } from "./charts/BarChart.js";
6
+ import { LineChart as f } from "./charts/LineChart.js";
7
+ import { PieChart as p } from "./charts/PieChart.js";
8
+ import { RadarChart as m } from "./charts/RadarChart.js";
9
+ export { u as AreaChart, d as BarChart, o as DEFAULT_CHART_COLORS, e as DIVERGING_STEP_COUNT, f as LineChart, t as ORDINAL_START_STEP, p as PieChart, m as RadarChart, n as SEQUENTIAL_STEP_COUNT, r as divergingScale, s as resolveChartChrome, c as resolveChartColors, i as scaleSteps, a as sequentialScale, l as useChartColors };
@@ -1,2 +1,2 @@
1
- const e=require("../utils/ids.cjs"),t=require("./errors.cjs");function n(e,t,n){let r=new URL(t,e.endsWith(`/`)?e:`${e}/`);if(n)for(let[e,t]of Object.entries(n))t!=null&&r.searchParams.set(e,String(t));return r.toString()}function r(e){return typeof FormData<`u`&&e instanceof FormData}async function i(e,n){let r;try{r=await e.clone().json()}catch{try{r=await e.text()}catch{r=null}}return new t.TempestApiError(t.buildApiError(e.status,r,e.headers,n))}function a(t){let a=t.fetcher??globalThis.fetch.bind(globalThis);function o(){let e=t.getToken?.();return e?{Authorization:`Bearer ${e}`}:{}}async function s(e,i,s){let{body:c,params:l,headers:u,...d}=i,f=r(c),p={...f?{}:{"Content-Type":`application/json`},...s?{"X-Request-ID":s}:{},...t.headers,...o(),...u},m={...d,headers:p,credentials:t.withCredentials?`include`:d.credentials,body:c==null?void 0:f?c:JSON.stringify(c)};return a(n(t.baseURL,e,l),m)}async function c(n,r={}){let a=t.requestId?t.requestId():e.randomId(),o=await s(n,r,a);if(o.status===401){if(t.refresh)try{await t.refresh(),o=await s(n,r,a)}catch{throw await t.onUnauthorized?.(o),await i(o,a)}else await t.onUnauthorized?.(o)}if(!o.ok)throw await i(o,a);if(o.status!==204)return(o.headers.get(`content-type`)??``).includes(`application/json`)?await o.json():await o.text()}async function l(e,t,n=`POST`){return c(e,{method:n,body:t})}return{request:c,get:(e,t)=>c(e,{...t,method:`GET`}),post:(e,t)=>c(e,{...t,method:`POST`}),put:(e,t)=>c(e,{...t,method:`PUT`}),patch:(e,t)=>c(e,{...t,method:`PATCH`}),delete:(e,t)=>c(e,{...t,method:`DELETE`}),upload:l}}exports.createApiClient=a;
1
+ const e=require("../utils/ids.cjs"),t=require("./errors.cjs"),n=require("./retry.cjs");var r=new Set([`GET`,`HEAD`,`OPTIONS`]),i=new Set([0,408,425,429]);function a(e,n){return!r.has(n)||!(e instanceof t.TempestApiError)?!1:i.has(e.status)||e.status>=500}function o(e){return e?e===!0?{}:e:null}function s(e,t,n){let r=new URL(t,e.endsWith(`/`)?e:`${e}/`);if(n)for(let[e,t]of Object.entries(n))t!=null&&r.searchParams.set(e,String(t));return r.toString()}function c(e){return typeof FormData<`u`&&e instanceof FormData}async function l(e,n){let r;try{r=await e.clone().json()}catch{try{r=await e.text()}catch{r=null}}return new t.TempestApiError(t.buildApiError(e.status,r,e.headers,n))}function u(t){let r=t.fetcher??globalThis.fetch.bind(globalThis);function i(){let e=t.getToken?.();return e?{Authorization:`Bearer ${e}`}:{}}async function u(e,n,a){let{body:o,params:l,headers:u,...d}=n,f=c(o),p={...f?{}:{"Content-Type":`application/json`},...a?{"X-Request-ID":a}:{},...t.headers,...i(),...u},m={...d,headers:p,credentials:t.withCredentials?`include`:d.credentials,body:o==null?void 0:f?o:JSON.stringify(o)};return r(s(t.baseURL,e,l),m)}async function d(n,r){let i=t.requestId?t.requestId():e.randomId(),a=await u(n,r,i);if(a.status===401){if(t.refresh){try{await t.refresh(),a=await u(n,r,i)}catch{throw await t.onUnauthorized?.(a),await l(a,i)}a.status===401&&await t.onUnauthorized?.(a)}else await t.onUnauthorized?.(a)}if(!a.ok)throw await l(a,i);if(a.status!==204)return(a.headers.get(`content-type`)??``).includes(`application/json`)?await a.json():await a.text()}async function f(e,r={}){let i=o(t.retry);if(!i)return d(e,r);let s=(r.method??`GET`).toUpperCase();return n.retry(()=>d(e,r),{...i,shouldRetry:i.shouldRetry??(e=>a(e,s))})}async function p(e,t,n=`POST`){return f(e,{method:n,body:t})}return{request:f,get:(e,t)=>f(e,{...t,method:`GET`}),post:(e,t)=>f(e,{...t,method:`POST`}),put:(e,t)=>f(e,{...t,method:`PUT`}),patch:(e,t)=>f(e,{...t,method:`PATCH`}),delete:(e,t)=>f(e,{...t,method:`DELETE`}),upload:p}}exports.createApiClient=u;
2
2
  //# sourceMappingURL=api-client.cjs.map