@cavuno/board 4.4.1 → 4.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/dist/{_spec-COlkrizX.d.mts → _spec-BJah6GIZ.d.mts} +55 -0
  3. package/dist/{_spec-COlkrizX.d.ts → _spec-BJah6GIZ.d.ts} +55 -0
  4. package/dist/{blog-DO8Yn21_.d.mts → blog-4Owyo4U_.d.mts} +1 -1
  5. package/dist/{blog-CgA_ljHa.d.ts → blog-DJi_1n7W.d.ts} +1 -1
  6. package/dist/{board-JgFR-2UW.d.mts → board-CpR7o9bL.d.mts} +2 -2
  7. package/dist/{board-D51C3gB5.d.ts → board-KDx9U0nw.d.ts} +2 -2
  8. package/dist/{breadcrumbs-_QzN4nEk.d.ts → breadcrumbs-CJ-NpA-V.d.ts} +2 -2
  9. package/dist/{breadcrumbs-zAN2biAq.d.mts → breadcrumbs-DOJH_7nO.d.mts} +2 -2
  10. package/dist/browser/cavuno-board.global.min.js +1 -1
  11. package/dist/{chunk-2ETP5UH4.mjs → chunk-GC5QWN7Y.mjs} +16 -0
  12. package/dist/{chunk-YEAQ3JEI.mjs → chunk-VWGF4I5C.mjs} +143 -4
  13. package/dist/filters.d.mts +2 -2
  14. package/dist/filters.d.ts +2 -2
  15. package/dist/format.d.mts +4 -4
  16. package/dist/format.d.ts +4 -4
  17. package/dist/format.js +15 -2
  18. package/dist/format.mjs +2 -126
  19. package/dist/index.d.mts +75 -12
  20. package/dist/index.d.ts +75 -12
  21. package/dist/index.js +187 -1
  22. package/dist/index.mjs +172 -2
  23. package/dist/{jobs-DOF3QXdq.d.ts → jobs-Ay-V6Q6y.d.ts} +1 -1
  24. package/dist/{jobs-C1Mxty1n.d.mts → jobs-C27qlt6o.d.mts} +1 -1
  25. package/dist/{search-Cx_dsVUb.d.mts → search-CC-rlMgk.d.mts} +1 -1
  26. package/dist/{search-_QDaN6Um.d.ts → search-fG_K9J8x.d.ts} +1 -1
  27. package/dist/seo.d.mts +6 -6
  28. package/dist/seo.d.ts +6 -6
  29. package/dist/seo.js +16 -1
  30. package/dist/seo.mjs +1 -1
  31. package/dist/server.d.mts +5 -5
  32. package/dist/server.d.ts +5 -5
  33. package/dist/server.mjs +1 -1
  34. package/dist/sitemap.d.mts +5 -5
  35. package/dist/sitemap.d.ts +5 -5
  36. package/dist/suggest.d.mts +2 -2
  37. package/dist/suggest.d.ts +2 -2
  38. package/package.json +1 -1
  39. package/skills/cavuno-board-account/SKILL.md +11 -1
  40. package/skills/cavuno-board-companies/SKILL.md +21 -0
  41. package/skills/cavuno-board-seo/SALARY.md +2 -1
  42. package/skills/manifest.json +1 -1
package/dist/seo.js CHANGED
@@ -798,6 +798,21 @@ function normalizeLocale(language) {
798
798
  }
799
799
  }
800
800
 
801
+ // src/format/salary-range.ts
802
+ function formatNumberRange(formatter, min, max) {
803
+ if (typeof formatter.formatRange === "function") {
804
+ try {
805
+ return formatter.formatRange(min, max);
806
+ } catch {
807
+ }
808
+ }
809
+ try {
810
+ return `${formatter.format(min)}\u2013${formatter.format(max)}`;
811
+ } catch {
812
+ return null;
813
+ }
814
+ }
815
+
801
816
  // src/seo/salary.ts
802
817
  var currencyFormatterCache = /* @__PURE__ */ new Map();
803
818
  function notationForMagnitude(...values) {
@@ -855,7 +870,7 @@ function formatSalaryStatRange(locale, min, max, currency, notation) {
855
870
  const low = Math.min(min, max);
856
871
  const high = Math.max(min, max);
857
872
  if (low === high) return formatter.format(low);
858
- return formatter.formatRange(low, high);
873
+ return formatNumberRange(formatter, low, high);
859
874
  }
860
875
  var SENIORITY_ORDER = [
861
876
  "entry_level",
package/dist/seo.mjs CHANGED
@@ -17,7 +17,7 @@ import {
17
17
  skillSalaryJsonLd,
18
18
  sortBySeniority,
19
19
  titleSalaryJsonLd
20
- } from "./chunk-YEAQ3JEI.mjs";
20
+ } from "./chunk-VWGF4I5C.mjs";
21
21
  import {
22
22
  boardUrl,
23
23
  jobDetailPath
package/dist/server.d.mts CHANGED
@@ -1,9 +1,9 @@
1
1
  import { BoardSdk } from './index.mjs';
2
- import './_spec-COlkrizX.mjs';
3
- import './search-Cx_dsVUb.mjs';
4
- import './board-JgFR-2UW.mjs';
5
- import './jobs-C1Mxty1n.mjs';
6
- import './blog-DO8Yn21_.mjs';
2
+ import './_spec-BJah6GIZ.mjs';
3
+ import './search-CC-rlMgk.mjs';
4
+ import './board-CpR7o9bL.mjs';
5
+ import './jobs-C27qlt6o.mjs';
6
+ import './blog-4Owyo4U_.mjs';
7
7
 
8
8
  /**
9
9
  * Session cookie codec — pure (no framework imports, no node imports) so it
package/dist/server.d.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  import { BoardSdk } from './index.js';
2
- import './_spec-COlkrizX.js';
3
- import './search-_QDaN6Um.js';
4
- import './board-D51C3gB5.js';
5
- import './jobs-DOF3QXdq.js';
6
- import './blog-CgA_ljHa.js';
2
+ import './_spec-BJah6GIZ.js';
3
+ import './search-fG_K9J8x.js';
4
+ import './board-KDx9U0nw.js';
5
+ import './jobs-Ay-V6Q6y.js';
6
+ import './blog-DJi_1n7W.js';
7
7
 
8
8
  /**
9
9
  * Session cookie codec — pure (no framework imports, no node imports) so it
package/dist/server.mjs CHANGED
@@ -2,7 +2,7 @@ import {
2
2
  isNoStore,
3
3
  isUnauthorized,
4
4
  scopeToken
5
- } from "./chunk-2ETP5UH4.mjs";
5
+ } from "./chunk-GC5QWN7Y.mjs";
6
6
 
7
7
  // src/server/cookie.ts
8
8
  var COOKIE_ATTRIBUTES = "Path=/; HttpOnly; Secure; SameSite=Lax";
@@ -1,9 +1,9 @@
1
1
  import { BoardSdk } from './index.mjs';
2
- import './_spec-COlkrizX.mjs';
3
- import './search-Cx_dsVUb.mjs';
4
- import './board-JgFR-2UW.mjs';
5
- import './jobs-C1Mxty1n.mjs';
6
- import './blog-DO8Yn21_.mjs';
2
+ import './_spec-BJah6GIZ.mjs';
3
+ import './search-CC-rlMgk.mjs';
4
+ import './board-CpR7o9bL.mjs';
5
+ import './jobs-C27qlt6o.mjs';
6
+ import './blog-4Owyo4U_.mjs';
7
7
 
8
8
  /**
9
9
  * Sitemap primitives — the pure XML + bucket-filename logic behind a board
package/dist/sitemap.d.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  import { BoardSdk } from './index.js';
2
- import './_spec-COlkrizX.js';
3
- import './search-_QDaN6Um.js';
4
- import './board-D51C3gB5.js';
5
- import './jobs-DOF3QXdq.js';
6
- import './blog-CgA_ljHa.js';
2
+ import './_spec-BJah6GIZ.js';
3
+ import './search-fG_K9J8x.js';
4
+ import './board-KDx9U0nw.js';
5
+ import './jobs-Ay-V6Q6y.js';
6
+ import './blog-DJi_1n7W.js';
7
7
 
8
8
  /**
9
9
  * Sitemap primitives — the pure XML + bucket-filename logic behind a board
@@ -1,5 +1,5 @@
1
- import { h as SuggestionItem, b as SearchSuggestQuery, F as FetchOptions, g as SuggestResult } from './search-Cx_dsVUb.mjs';
2
- import './_spec-COlkrizX.mjs';
1
+ import { h as SuggestionItem, b as SearchSuggestQuery, F as FetchOptions, g as SuggestResult } from './search-CC-rlMgk.mjs';
2
+ import './_spec-BJah6GIZ.mjs';
3
3
 
4
4
  /**
5
5
  * `@cavuno/board/suggest` — framework-agnostic headless search-suggest
package/dist/suggest.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { h as SuggestionItem, b as SearchSuggestQuery, F as FetchOptions, g as SuggestResult } from './search-_QDaN6Um.js';
2
- import './_spec-COlkrizX.js';
1
+ import { h as SuggestionItem, b as SearchSuggestQuery, F as FetchOptions, g as SuggestResult } from './search-fG_K9J8x.js';
2
+ import './_spec-BJah6GIZ.js';
3
3
 
4
4
  /**
5
5
  * `@cavuno/board/suggest` — framework-agnostic headless search-suggest
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cavuno/board",
3
- "version": "4.4.1",
3
+ "version": "4.5.0",
4
4
  "description": "Build custom job boards and careers pages with Cavuno’s TypeScript SDK.",
5
5
  "keywords": [
6
6
  "api-client",
@@ -7,7 +7,7 @@ description: Candidate self-service boundary with @cavuno/board. Use for account
7
7
 
8
8
  Signed-in candidate data lives under `board.me`. Browser calls use the bearer token in `auth.storage`; server calls pass it per request in `options.headers`. See `cavuno-board-auth` for cookie-based server sessions.
9
9
 
10
- The only anonymous method here is token-based email unsubscribe. Applications, employer companies, messaging, and alerts have their own skills.
10
+ Anonymous methods here are token-based email unsubscribe and email-change confirm (`confirmEmailChange`). Applications, employer companies, messaging, and alerts have their own skills.
11
11
 
12
12
  The host application owns forms, file pickers, and cookie plumbing; this SDK surface supplies data operations.
13
13
 
@@ -15,10 +15,20 @@ The host application owns forms, file pickers, and cookie plumbing; this SDK sur
15
15
 
16
16
  Account deletion is a synchronous, irreversible cascade over the profile, collections, saved jobs, alerts, avatar, and resume. Obtain explicit confirmation before calling it.
17
17
 
18
+ Change the password with the current password. The SDK persists the returned session so the caller stays signed in. Passwordless accounts (magic-link or OAuth) get `no_password` — send them through `auth.forgotPassword` instead.
19
+
18
20
  ```ts snippet
19
21
  const me = await board.me.retrieve();
20
22
  await board.me.delete();
21
23
 
24
+ await board.me.updatePassword({
25
+ currentPassword: 'oldpass99',
26
+ newPassword: 'newpass99',
27
+ });
28
+
29
+ await board.me.requestEmailChange({ email: 'new@example.com' });
30
+ await board.me.confirmEmailChange({ token });
31
+
22
32
  const profile = await board.me.profile.retrieve();
23
33
  await board.me.profile.update({
24
34
  headline: 'Staff Engineer',
@@ -12,6 +12,27 @@ Board-wide jobs use `jobs.*`, board-wide salary hubs use `salaries.*`, and
12
12
  employer self-service uses authenticated `board.me.companies.*`. The host app
13
13
  owns admin writes, sitemaps, and OG-image routes.
14
14
 
15
+ An approved admin can delete a company they manage and can list, retitle, or
16
+ remove members. Any approved member can leave with `board.me.companies.leave`.
17
+ Demoting, removing, or leaving as the last admin is `last_admin`. Admins
18
+ invite by email; approved members can list pending invites; accept is
19
+ session-gated on `board.me.acceptInvite`.
20
+
21
+ ```ts snippet
22
+ await board.me.companies.delete('acme');
23
+ const { data: members } = await board.me.companies.listMembers('acme');
24
+ await board.me.companies.updateMemberRole('acme', members[0].id, {
25
+ role: 'admin',
26
+ });
27
+ await board.me.companies.removeMember('acme', members[0].id);
28
+ await board.me.companies.leave('acme');
29
+
30
+ const { data: invites } = await board.me.companies.listInvites('acme');
31
+ await board.me.companies.createInvite('acme', { email: 'ada@acme.test' });
32
+ await board.me.companies.revokeInvite('acme', invites[0].id);
33
+ const { companySlug } = await board.me.acceptInvite({ token });
34
+ ```
35
+
15
36
  ## List and search
16
37
 
17
38
  `companies.list` returns `CompanyListEnvelope`: `ListEnvelope<PublicCompany>`
@@ -102,7 +102,8 @@ const index = itemListJsonLd([
102
102
  - `formatSalaryStat(locale, value, currency, notation?)` /
103
103
  `formatSalaryStatRange(locale, min, max, currency, notation?)` for
104
104
  salary-page amounts (currency from the detail, not hardcoded USD;
105
- `formatRange` owns the join). `notation` matches `formatSalaryRange`
105
+ `formatRange` owns the join when present, else two `format()` calls
106
+ joined with an en-dash). `notation` matches `formatSalaryRange`
106
107
  (magnitude default when omitted; pass `'standard'` for full figures).
107
108
  Returns `null` when currency is empty or `Intl` rejects inputs.
108
109
  - `SENIORITY_ORDER` / `sortBySeniority` for seniority ladder ordering
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "4.4.1",
2
+ "version": "4.5.0",
3
3
  "skills": [
4
4
  {
5
5
  "name": "cavuno-board-account",