@cavuno/board 4.4.1 → 4.6.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 +31 -0
  2. package/dist/{_spec-COlkrizX.d.mts → _spec-Dm-1AieO.d.mts} +61 -1
  3. package/dist/{_spec-COlkrizX.d.ts → _spec-Dm-1AieO.d.ts} +61 -1
  4. package/dist/{blog-CgA_ljHa.d.ts → blog-BvyEW4bf.d.ts} +1 -1
  5. package/dist/{blog-DO8Yn21_.d.mts → blog-C5g0Tt8w.d.mts} +1 -1
  6. package/dist/{board-D51C3gB5.d.ts → board-CW3qMKdu.d.ts} +2 -2
  7. package/dist/{board-JgFR-2UW.d.mts → board-CemD1yEl.d.mts} +2 -2
  8. package/dist/{breadcrumbs-_QzN4nEk.d.ts → breadcrumbs-BRHiWWSf.d.ts} +2 -2
  9. package/dist/{breadcrumbs-zAN2biAq.d.mts → breadcrumbs-Bgmklae3.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 +89 -12
  20. package/dist/index.d.ts +89 -12
  21. package/dist/index.js +205 -1
  22. package/dist/index.mjs +190 -2
  23. package/dist/{jobs-C1Mxty1n.d.mts → jobs-B0phTsdB.d.mts} +1 -1
  24. package/dist/{jobs-DOF3QXdq.d.ts → jobs-f-n4_rrz.d.ts} +1 -1
  25. package/dist/{search-_QDaN6Um.d.ts → search-C1LHejWz.d.ts} +1 -1
  26. package/dist/{search-Cx_dsVUb.d.mts → search-DVg1L-3s.d.mts} +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 +31 -2
  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 +2 -2
package/dist/index.js CHANGED
@@ -70,6 +70,11 @@ var BOARD_API_ERROR_CODES = [
70
70
  "board_auth_invalid_token",
71
71
  "board_auth_registration_disabled",
72
72
  "board_auth_token_expired",
73
+ "invalid_current_password",
74
+ "no_password",
75
+ "same_email",
76
+ "email_taken",
77
+ "invalid_token",
73
78
  // Board password gate
74
79
  "board_password_required",
75
80
  "board_password_invalid",
@@ -149,6 +154,17 @@ var BOARD_API_ERROR_CODES = [
149
154
  "employer_not_member",
150
155
  "employer_payment_required",
151
156
  "employer_pipeline_stage_not_found",
157
+ "employer_member_not_found",
158
+ "employer_invite_not_found",
159
+ "not_company_admin",
160
+ "not_company_member",
161
+ "company_deletion_disabled",
162
+ "last_admin",
163
+ "already_member",
164
+ "already_invited",
165
+ "invalid_email",
166
+ "invite_email_mismatch",
167
+ "candidate_role",
152
168
  // Candidate job-access paywall
153
169
  "paywall_already_active",
154
170
  "paywall_disabled",
@@ -312,7 +328,7 @@ async function clearSession(storage) {
312
328
  }
313
329
 
314
330
  // src/version.ts
315
- var SDK_VERSION = "4.4.1";
331
+ var SDK_VERSION = "4.6.0";
316
332
 
317
333
  // src/client.ts
318
334
  function isRawBody(body) {
@@ -1146,6 +1162,70 @@ function meNamespace(client) {
1146
1162
  delete(options) {
1147
1163
  return client.fetch("/me", { ...options, method: "DELETE" });
1148
1164
  },
1165
+ /**
1166
+ * Change my password. Requires the current password. Persists the
1167
+ * returned bearer pair (the server bumped `authVersion` and killed
1168
+ * every other session). Passwordless accounts get 400 `no_password`
1169
+ * — use `auth.forgotPassword` to set one.
1170
+ *
1171
+ * @example
1172
+ * await board.me.updatePassword({
1173
+ * currentPassword: 'oldpass99',
1174
+ * newPassword: 'newpass99',
1175
+ * });
1176
+ */
1177
+ async updatePassword(body, options) {
1178
+ const session = await client.fetch("/me/password", {
1179
+ ...options,
1180
+ method: "POST",
1181
+ body
1182
+ });
1183
+ await writeSession(client.storage, session);
1184
+ return session;
1185
+ },
1186
+ /**
1187
+ * Request an email change. A verification link is mailed to the new
1188
+ * address; the email swaps only after `confirmEmailChange`.
1189
+ *
1190
+ * @example
1191
+ * await board.me.requestEmailChange({ email: 'new@example.com' });
1192
+ */
1193
+ requestEmailChange(body, options) {
1194
+ return client.fetch("/me/email", {
1195
+ ...options,
1196
+ method: "POST",
1197
+ body
1198
+ });
1199
+ },
1200
+ /**
1201
+ * Confirm an email-change token (from the verification email) — no
1202
+ * session required. Resolves void (204).
1203
+ *
1204
+ * @example
1205
+ * await board.me.confirmEmailChange({ token });
1206
+ */
1207
+ confirmEmailChange(body, options) {
1208
+ return client.fetch("/me/email/confirm", {
1209
+ ...options,
1210
+ method: "POST",
1211
+ body
1212
+ });
1213
+ },
1214
+ /**
1215
+ * Accept a company member invite. Session-gated — the signed-in
1216
+ * board user's email must match the invite. Returns the company
1217
+ * slug the caller now belongs to.
1218
+ *
1219
+ * @example
1220
+ * const { companySlug } = await board.me.acceptInvite({ token });
1221
+ */
1222
+ acceptInvite(body, options) {
1223
+ return client.fetch("/me/invites/accept", {
1224
+ ...options,
1225
+ method: "POST",
1226
+ body
1227
+ });
1228
+ },
1149
1229
  /**
1150
1230
  * The authenticated candidate's own account self-service.
1151
1231
  * `profile.*` is the lean profile singleton + its
@@ -1422,6 +1502,112 @@ function meNamespace(client) {
1422
1502
  { ...options, method: "PATCH", body }
1423
1503
  );
1424
1504
  },
1505
+ /**
1506
+ * Delete a company I admin (soft-delete cascade + Forager
1507
+ * exclusion). Resolves void on success (204).
1508
+ *
1509
+ * @example
1510
+ * await board.me.companies.delete('acme');
1511
+ */
1512
+ delete(slug, options) {
1513
+ return client.fetch(`/me/companies/${encodeURIComponent(slug)}`, {
1514
+ ...options,
1515
+ method: "DELETE"
1516
+ });
1517
+ },
1518
+ /**
1519
+ * List approved members of a company I belong to.
1520
+ *
1521
+ * @example
1522
+ * const { data } = await board.me.companies.listMembers('acme');
1523
+ */
1524
+ listMembers(slug, options) {
1525
+ return client.fetch(
1526
+ `/me/companies/${encodeURIComponent(slug)}/members`,
1527
+ options
1528
+ );
1529
+ },
1530
+ /**
1531
+ * Set a member's role (`admin` | `member`). Admin-only. Demoting
1532
+ * the last admin is 409 `last_admin`. Resolves void (204).
1533
+ *
1534
+ * @example
1535
+ * await board.me.companies.updateMemberRole('acme', memberId, {
1536
+ * role: 'admin',
1537
+ * });
1538
+ */
1539
+ updateMemberRole(slug, memberId, body, options) {
1540
+ return client.fetch(
1541
+ `/me/companies/${encodeURIComponent(slug)}/members/${encodeURIComponent(memberId)}`,
1542
+ { ...options, method: "PATCH", body }
1543
+ );
1544
+ },
1545
+ /**
1546
+ * Remove a member. Admin-only. Removing the last admin is 409
1547
+ * `last_admin`. Resolves void (204).
1548
+ *
1549
+ * @example
1550
+ * await board.me.companies.removeMember('acme', memberId);
1551
+ */
1552
+ removeMember(slug, memberId, options) {
1553
+ return client.fetch(
1554
+ `/me/companies/${encodeURIComponent(slug)}/members/${encodeURIComponent(memberId)}`,
1555
+ { ...options, method: "DELETE" }
1556
+ );
1557
+ },
1558
+ /**
1559
+ * Leave a company I belong to. Leaving as the last admin is 409
1560
+ * `last_admin`. Resolves void (204).
1561
+ *
1562
+ * @example
1563
+ * await board.me.companies.leave('acme');
1564
+ */
1565
+ leave(slug, options) {
1566
+ return client.fetch(
1567
+ `/me/companies/${encodeURIComponent(slug)}/membership`,
1568
+ { ...options, method: "DELETE" }
1569
+ );
1570
+ },
1571
+ /**
1572
+ * List pending member invites for a company I belong to.
1573
+ *
1574
+ * @example
1575
+ * const { data } = await board.me.companies.listInvites('acme');
1576
+ */
1577
+ listInvites(slug, options) {
1578
+ return client.fetch(
1579
+ `/me/companies/${encodeURIComponent(slug)}/invites`,
1580
+ options
1581
+ );
1582
+ },
1583
+ /**
1584
+ * Invite an email to join a company I admin. Returns the pending
1585
+ * invite. Duplicate members/invites are 400
1586
+ * `already_member` / `already_invited`.
1587
+ *
1588
+ * @example
1589
+ * await board.me.companies.createInvite('acme', {
1590
+ * email: 'ada@acme.test',
1591
+ * });
1592
+ */
1593
+ createInvite(slug, body, options) {
1594
+ return client.fetch(
1595
+ `/me/companies/${encodeURIComponent(slug)}/invites`,
1596
+ { ...options, method: "POST", body }
1597
+ );
1598
+ },
1599
+ /**
1600
+ * Revoke a pending invite. Admin-only. Resolves void (204).
1601
+ *
1602
+ * @example
1603
+ * await board.me.companies.revokeInvite('acme', inviteId);
1604
+ */
1605
+ revokeInvite(slug, inviteId, options) {
1606
+ return client.fetch(
1607
+ `/me/companies/${encodeURIComponent(slug)}/invites/${encodeURIComponent(inviteId)}`,
1608
+ { ...options, method: "DELETE" }
1609
+ );
1610
+ },
1425
1611
  /**
1426
1612
  * Upload + attach my company logo (JPEG/PNG/WebP/GIF, ≤2 MB) via a single
1427
1613
  * multipart POST. Requires an approved membership. Returns the updated
@@ -2039,6 +2225,24 @@ function meNamespace(client) {
2039
2225
  });
2040
2226
  }
2041
2227
  },
2228
+ recommendedJobs: {
2229
+ /**
2230
+ * Personalized job recommendations for the authenticated candidate,
2231
+ * best match first (ranked server-side from their profile). Each item
2232
+ * wraps the same slim `job_card` the jobs list emits. Empty when the
2233
+ * profile has no matching signal yet — check `board.me.profile` to
2234
+ * drive an upload-resume prompt.
2235
+ *
2236
+ * @example
2237
+ * const { data } = await board.me.recommendedJobs.list({ limit: 20 });
2238
+ */
2239
+ list(query, options) {
2240
+ return client.fetch(
2241
+ "/me/recommended-jobs",
2242
+ { ...options, query }
2243
+ );
2244
+ }
2245
+ },
2042
2246
  savedJobs: {
2043
2247
  /**
2044
2248
  * List the authenticated user's saved jobs (each embeds the full
package/dist/index.mjs CHANGED
@@ -15,7 +15,7 @@ import {
15
15
  isValidationError,
16
16
  resolveStorage,
17
17
  writeSession
18
- } from "./chunk-2ETP5UH4.mjs";
18
+ } from "./chunk-GC5QWN7Y.mjs";
19
19
  import {
20
20
  paginate
21
21
  } from "./chunk-DLSO6XXY.mjs";
@@ -39,7 +39,7 @@ function toSearchParams(query) {
39
39
  }
40
40
 
41
41
  // src/version.ts
42
- var SDK_VERSION = "4.4.1";
42
+ var SDK_VERSION = "4.6.0";
43
43
 
44
44
  // src/client.ts
45
45
  function isRawBody(body) {
@@ -873,6 +873,70 @@ function meNamespace(client) {
873
873
  delete(options) {
874
874
  return client.fetch("/me", { ...options, method: "DELETE" });
875
875
  },
876
+ /**
877
+ * Change my password. Requires the current password. Persists the
878
+ * returned bearer pair (the server bumped `authVersion` and killed
879
+ * every other session). Passwordless accounts get 400 `no_password`
880
+ * — use `auth.forgotPassword` to set one.
881
+ *
882
+ * @example
883
+ * await board.me.updatePassword({
884
+ * currentPassword: 'oldpass99',
885
+ * newPassword: 'newpass99',
886
+ * });
887
+ */
888
+ async updatePassword(body, options) {
889
+ const session = await client.fetch("/me/password", {
890
+ ...options,
891
+ method: "POST",
892
+ body
893
+ });
894
+ await writeSession(client.storage, session);
895
+ return session;
896
+ },
897
+ /**
898
+ * Request an email change. A verification link is mailed to the new
899
+ * address; the email swaps only after `confirmEmailChange`.
900
+ *
901
+ * @example
902
+ * await board.me.requestEmailChange({ email: 'new@example.com' });
903
+ */
904
+ requestEmailChange(body, options) {
905
+ return client.fetch("/me/email", {
906
+ ...options,
907
+ method: "POST",
908
+ body
909
+ });
910
+ },
911
+ /**
912
+ * Confirm an email-change token (from the verification email) — no
913
+ * session required. Resolves void (204).
914
+ *
915
+ * @example
916
+ * await board.me.confirmEmailChange({ token });
917
+ */
918
+ confirmEmailChange(body, options) {
919
+ return client.fetch("/me/email/confirm", {
920
+ ...options,
921
+ method: "POST",
922
+ body
923
+ });
924
+ },
925
+ /**
926
+ * Accept a company member invite. Session-gated — the signed-in
927
+ * board user's email must match the invite. Returns the company
928
+ * slug the caller now belongs to.
929
+ *
930
+ * @example
931
+ * const { companySlug } = await board.me.acceptInvite({ token });
932
+ */
933
+ acceptInvite(body, options) {
934
+ return client.fetch("/me/invites/accept", {
935
+ ...options,
936
+ method: "POST",
937
+ body
938
+ });
939
+ },
876
940
  /**
877
941
  * The authenticated candidate's own account self-service.
878
942
  * `profile.*` is the lean profile singleton + its
@@ -1149,6 +1213,112 @@ function meNamespace(client) {
1149
1213
  { ...options, method: "PATCH", body }
1150
1214
  );
1151
1215
  },
1216
+ /**
1217
+ * Delete a company I admin (soft-delete cascade + Forager
1218
+ * exclusion). Resolves void on success (204).
1219
+ *
1220
+ * @example
1221
+ * await board.me.companies.delete('acme');
1222
+ */
1223
+ delete(slug, options) {
1224
+ return client.fetch(`/me/companies/${encodeURIComponent(slug)}`, {
1225
+ ...options,
1226
+ method: "DELETE"
1227
+ });
1228
+ },
1229
+ /**
1230
+ * List approved members of a company I belong to.
1231
+ *
1232
+ * @example
1233
+ * const { data } = await board.me.companies.listMembers('acme');
1234
+ */
1235
+ listMembers(slug, options) {
1236
+ return client.fetch(
1237
+ `/me/companies/${encodeURIComponent(slug)}/members`,
1238
+ options
1239
+ );
1240
+ },
1241
+ /**
1242
+ * Set a member's role (`admin` | `member`). Admin-only. Demoting
1243
+ * the last admin is 409 `last_admin`. Resolves void (204).
1244
+ *
1245
+ * @example
1246
+ * await board.me.companies.updateMemberRole('acme', memberId, {
1247
+ * role: 'admin',
1248
+ * });
1249
+ */
1250
+ updateMemberRole(slug, memberId, body, options) {
1251
+ return client.fetch(
1252
+ `/me/companies/${encodeURIComponent(slug)}/members/${encodeURIComponent(memberId)}`,
1253
+ { ...options, method: "PATCH", body }
1254
+ );
1255
+ },
1256
+ /**
1257
+ * Remove a member. Admin-only. Removing the last admin is 409
1258
+ * `last_admin`. Resolves void (204).
1259
+ *
1260
+ * @example
1261
+ * await board.me.companies.removeMember('acme', memberId);
1262
+ */
1263
+ removeMember(slug, memberId, options) {
1264
+ return client.fetch(
1265
+ `/me/companies/${encodeURIComponent(slug)}/members/${encodeURIComponent(memberId)}`,
1266
+ { ...options, method: "DELETE" }
1267
+ );
1268
+ },
1269
+ /**
1270
+ * Leave a company I belong to. Leaving as the last admin is 409
1271
+ * `last_admin`. Resolves void (204).
1272
+ *
1273
+ * @example
1274
+ * await board.me.companies.leave('acme');
1275
+ */
1276
+ leave(slug, options) {
1277
+ return client.fetch(
1278
+ `/me/companies/${encodeURIComponent(slug)}/membership`,
1279
+ { ...options, method: "DELETE" }
1280
+ );
1281
+ },
1282
+ /**
1283
+ * List pending member invites for a company I belong to.
1284
+ *
1285
+ * @example
1286
+ * const { data } = await board.me.companies.listInvites('acme');
1287
+ */
1288
+ listInvites(slug, options) {
1289
+ return client.fetch(
1290
+ `/me/companies/${encodeURIComponent(slug)}/invites`,
1291
+ options
1292
+ );
1293
+ },
1294
+ /**
1295
+ * Invite an email to join a company I admin. Returns the pending
1296
+ * invite. Duplicate members/invites are 400
1297
+ * `already_member` / `already_invited`.
1298
+ *
1299
+ * @example
1300
+ * await board.me.companies.createInvite('acme', {
1301
+ * email: 'ada@acme.test',
1302
+ * });
1303
+ */
1304
+ createInvite(slug, body, options) {
1305
+ return client.fetch(
1306
+ `/me/companies/${encodeURIComponent(slug)}/invites`,
1307
+ { ...options, method: "POST", body }
1308
+ );
1309
+ },
1310
+ /**
1311
+ * Revoke a pending invite. Admin-only. Resolves void (204).
1312
+ *
1313
+ * @example
1314
+ * await board.me.companies.revokeInvite('acme', inviteId);
1315
+ */
1316
+ revokeInvite(slug, inviteId, options) {
1317
+ return client.fetch(
1318
+ `/me/companies/${encodeURIComponent(slug)}/invites/${encodeURIComponent(inviteId)}`,
1319
+ { ...options, method: "DELETE" }
1320
+ );
1321
+ },
1152
1322
  /**
1153
1323
  * Upload + attach my company logo (JPEG/PNG/WebP/GIF, ≤2 MB) via a single
1154
1324
  * multipart POST. Requires an approved membership. Returns the updated
@@ -1766,6 +1936,24 @@ function meNamespace(client) {
1766
1936
  });
1767
1937
  }
1768
1938
  },
1939
+ recommendedJobs: {
1940
+ /**
1941
+ * Personalized job recommendations for the authenticated candidate,
1942
+ * best match first (ranked server-side from their profile). Each item
1943
+ * wraps the same slim `job_card` the jobs list emits. Empty when the
1944
+ * profile has no matching signal yet — check `board.me.profile` to
1945
+ * drive an upload-resume prompt.
1946
+ *
1947
+ * @example
1948
+ * const { data } = await board.me.recommendedJobs.list({ limit: 20 });
1949
+ */
1950
+ list(query, options) {
1951
+ return client.fetch(
1952
+ "/me/recommended-jobs",
1953
+ { ...options, query }
1954
+ );
1955
+ }
1956
+ },
1769
1957
  savedJobs: {
1770
1958
  /**
1771
1959
  * List the authenticated user's saved jobs (each embeds the full
@@ -1,4 +1,4 @@
1
- import { S as Schemas } from './_spec-COlkrizX.mjs';
1
+ import { S as Schemas } from './_spec-Dm-1AieO.mjs';
2
2
 
3
3
  /**
4
4
  * Optional pagination metadata returned by Board API list operations.
@@ -1,4 +1,4 @@
1
- import { S as Schemas } from './_spec-COlkrizX.js';
1
+ import { S as Schemas } from './_spec-Dm-1AieO.js';
2
2
 
3
3
  /**
4
4
  * Optional pagination metadata returned by Board API list operations.
@@ -1,4 +1,4 @@
1
- import { S as Schemas } from './_spec-COlkrizX.js';
1
+ import { S as Schemas } from './_spec-Dm-1AieO.js';
2
2
 
3
3
  type Awaitable<T> = T | Promise<T>;
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { S as Schemas } from './_spec-COlkrizX.mjs';
1
+ import { S as Schemas } from './_spec-Dm-1AieO.mjs';
2
2
 
3
3
  type Awaitable<T> = T | Promise<T>;
4
4
  /**
package/dist/seo.d.mts CHANGED
@@ -1,9 +1,9 @@
1
- import { P as PublicBlogPostSummary, B as BlogAuthorEmbed } from './blog-DO8Yn21_.mjs';
2
- import { e as JsonLdObject } from './breadcrumbs-zAN2biAq.mjs';
3
- export { A as ALL_COUNTRY_CODES, B as BreadcrumbItemInput, g as FaqItem, J as JobBreadcrumb, h as JsonLdBoard, N as NumberNotation, i as SENIORITY_ORDER, j as SalaryFaqEntry, k as SalaryJsonLdOptions, l as SalaryOccupationListOptions, b as buildJobBreadcrumbs, m as buildSalaryFaq, o as companyCategorySalaryJsonLd, p as companySalaryJsonLd, q as createBreadcrumbJsonLd, r as createJobPostingJsonLd, s as crossAxisSalaryJsonLd, t as faqJsonLd, c as formatSalaryStat, d as formatSalaryStatRange, u as itemListJsonLd, v as locationSalaryJsonLd, n as normalizeWebsiteUrl, w as skillSalaryJsonLd, x as sortBySeniority, y as titleSalaryJsonLd } from './breadcrumbs-zAN2biAq.mjs';
4
- import './_spec-COlkrizX.mjs';
5
- import './board-JgFR-2UW.mjs';
6
- import './jobs-C1Mxty1n.mjs';
1
+ import { P as PublicBlogPostSummary, B as BlogAuthorEmbed } from './blog-C5g0Tt8w.mjs';
2
+ import { e as JsonLdObject } from './breadcrumbs-Bgmklae3.mjs';
3
+ export { A as ALL_COUNTRY_CODES, B as BreadcrumbItemInput, g as FaqItem, J as JobBreadcrumb, h as JsonLdBoard, N as NumberNotation, i as SENIORITY_ORDER, j as SalaryFaqEntry, k as SalaryJsonLdOptions, l as SalaryOccupationListOptions, b as buildJobBreadcrumbs, m as buildSalaryFaq, o as companyCategorySalaryJsonLd, p as companySalaryJsonLd, q as createBreadcrumbJsonLd, r as createJobPostingJsonLd, s as crossAxisSalaryJsonLd, t as faqJsonLd, c as formatSalaryStat, d as formatSalaryStatRange, u as itemListJsonLd, v as locationSalaryJsonLd, n as normalizeWebsiteUrl, w as skillSalaryJsonLd, x as sortBySeniority, y as titleSalaryJsonLd } from './breadcrumbs-Bgmklae3.mjs';
4
+ import './_spec-Dm-1AieO.mjs';
5
+ import './board-CemD1yEl.mjs';
6
+ import './jobs-B0phTsdB.mjs';
7
7
 
8
8
  /**
9
9
  * Blog structured data on the `@cavuno/board` wire types, transcribed from
package/dist/seo.d.ts CHANGED
@@ -1,9 +1,9 @@
1
- import { P as PublicBlogPostSummary, B as BlogAuthorEmbed } from './blog-CgA_ljHa.js';
2
- import { e as JsonLdObject } from './breadcrumbs-_QzN4nEk.js';
3
- export { A as ALL_COUNTRY_CODES, B as BreadcrumbItemInput, g as FaqItem, J as JobBreadcrumb, h as JsonLdBoard, N as NumberNotation, i as SENIORITY_ORDER, j as SalaryFaqEntry, k as SalaryJsonLdOptions, l as SalaryOccupationListOptions, b as buildJobBreadcrumbs, m as buildSalaryFaq, o as companyCategorySalaryJsonLd, p as companySalaryJsonLd, q as createBreadcrumbJsonLd, r as createJobPostingJsonLd, s as crossAxisSalaryJsonLd, t as faqJsonLd, c as formatSalaryStat, d as formatSalaryStatRange, u as itemListJsonLd, v as locationSalaryJsonLd, n as normalizeWebsiteUrl, w as skillSalaryJsonLd, x as sortBySeniority, y as titleSalaryJsonLd } from './breadcrumbs-_QzN4nEk.js';
4
- import './_spec-COlkrizX.js';
5
- import './board-D51C3gB5.js';
6
- import './jobs-DOF3QXdq.js';
1
+ import { P as PublicBlogPostSummary, B as BlogAuthorEmbed } from './blog-BvyEW4bf.js';
2
+ import { e as JsonLdObject } from './breadcrumbs-BRHiWWSf.js';
3
+ export { A as ALL_COUNTRY_CODES, B as BreadcrumbItemInput, g as FaqItem, J as JobBreadcrumb, h as JsonLdBoard, N as NumberNotation, i as SENIORITY_ORDER, j as SalaryFaqEntry, k as SalaryJsonLdOptions, l as SalaryOccupationListOptions, b as buildJobBreadcrumbs, m as buildSalaryFaq, o as companyCategorySalaryJsonLd, p as companySalaryJsonLd, q as createBreadcrumbJsonLd, r as createJobPostingJsonLd, s as crossAxisSalaryJsonLd, t as faqJsonLd, c as formatSalaryStat, d as formatSalaryStatRange, u as itemListJsonLd, v as locationSalaryJsonLd, n as normalizeWebsiteUrl, w as skillSalaryJsonLd, x as sortBySeniority, y as titleSalaryJsonLd } from './breadcrumbs-BRHiWWSf.js';
4
+ import './_spec-Dm-1AieO.js';
5
+ import './board-CW3qMKdu.js';
6
+ import './jobs-f-n4_rrz.js';
7
7
 
8
8
  /**
9
9
  * Blog structured data on the `@cavuno/board` wire types, transcribed from
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-Dm-1AieO.mjs';
3
+ import './search-DVg1L-3s.mjs';
4
+ import './board-CemD1yEl.mjs';
5
+ import './jobs-B0phTsdB.mjs';
6
+ import './blog-C5g0Tt8w.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-Dm-1AieO.js';
3
+ import './search-C1LHejWz.js';
4
+ import './board-CW3qMKdu.js';
5
+ import './jobs-f-n4_rrz.js';
6
+ import './blog-BvyEW4bf.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-Dm-1AieO.mjs';
3
+ import './search-DVg1L-3s.mjs';
4
+ import './board-CemD1yEl.mjs';
5
+ import './jobs-B0phTsdB.mjs';
6
+ import './blog-C5g0Tt8w.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-Dm-1AieO.js';
3
+ import './search-C1LHejWz.js';
4
+ import './board-CW3qMKdu.js';
5
+ import './jobs-f-n4_rrz.js';
6
+ import './blog-BvyEW4bf.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-DVg1L-3s.mjs';
2
+ import './_spec-Dm-1AieO.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-C1LHejWz.js';
2
+ import './_spec-Dm-1AieO.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.6.0",
4
4
  "description": "Build custom job boards and careers pages with Cavuno’s TypeScript SDK.",
5
5
  "keywords": [
6
6
  "api-client",