@cavuno/board 4.70.0 → 4.71.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 (44) hide show
  1. package/CHANGELOG.md +10 -0
  2. package/dist/{_spec-Dk7QyuoJ.d.mts → _spec-OPrym0QJ.d.mts} +26 -1
  3. package/dist/{_spec-Dk7QyuoJ.d.ts → _spec-OPrym0QJ.d.ts} +26 -1
  4. package/dist/{blog-DfUNkngR.d.ts → blog-BlRb84MY.d.ts} +1 -1
  5. package/dist/{blog-Oo6YHXSE.d.mts → blog-CHQYIhHH.d.mts} +1 -1
  6. package/dist/{board-DzBYIwKz.d.mts → board-Btc1dzQB.d.mts} +2 -2
  7. package/dist/{board-CfmGT0yV.d.ts → board-D74R4Iml.d.ts} +2 -2
  8. package/dist/{breadcrumbs-CS0nlknq.d.ts → breadcrumbs-Bv76gXvF.d.ts} +2 -2
  9. package/dist/{breadcrumbs-DeIA0RQp.d.mts → breadcrumbs-CSm6P79s.d.mts} +2 -2
  10. package/dist/browser/cavuno-board.global.min.js +1 -1
  11. package/dist/{chunk-UIKN2ERI.mjs → chunk-AQD4OMX4.mjs} +2 -0
  12. package/dist/filters.d.mts +2 -2
  13. package/dist/filters.d.ts +2 -2
  14. package/dist/format.d.mts +4 -4
  15. package/dist/format.d.ts +4 -4
  16. package/dist/index.d.mts +31 -13
  17. package/dist/index.d.ts +31 -13
  18. package/dist/index.js +17 -7
  19. package/dist/index.mjs +16 -8
  20. package/dist/{jobs-BlAsTCQl.d.ts → jobs-BMG0vrVI.d.ts} +1 -1
  21. package/dist/{jobs-BMRvZlNx.d.mts → jobs-xjE0IrNu.d.mts} +1 -1
  22. package/dist/{search-BB1TaaLa.d.mts → search-BJkiU3Ic.d.mts} +1 -1
  23. package/dist/{search-CoBeDgYT.d.ts → search-suUh-E7O.d.ts} +1 -1
  24. package/dist/{seo-BmqJ_ChV.d.ts → seo-CW1JjEXH.d.ts} +1 -1
  25. package/dist/{seo-M_8j5vdP.d.mts → seo-DGdqWPLo.d.mts} +1 -1
  26. package/dist/seo-files.d.mts +2 -2
  27. package/dist/seo-files.d.ts +2 -2
  28. package/dist/seo-files.js +6 -0
  29. package/dist/seo-files.mjs +6 -0
  30. package/dist/seo.d.mts +6 -6
  31. package/dist/seo.d.ts +6 -6
  32. package/dist/server.d.mts +6 -6
  33. package/dist/server.d.ts +6 -6
  34. package/dist/server.mjs +1 -1
  35. package/dist/sitemap.d.mts +6 -6
  36. package/dist/sitemap.d.ts +6 -6
  37. package/dist/sitemap.mjs +1 -1
  38. package/dist/suggest.d.mts +2 -2
  39. package/dist/suggest.d.ts +2 -2
  40. package/package.json +1 -1
  41. package/skills/cavuno-board-auth/SKILL.md +3 -0
  42. package/skills/cavuno-board-job-alerts/SKILL.md +8 -3
  43. package/skills/cavuno-board-newsletter/SKILL.md +2 -0
  44. package/skills/manifest.json +1 -1
package/dist/seo.d.ts CHANGED
@@ -1,9 +1,9 @@
1
- import { P as PublicBlogPostSummary, B as BlogAuthorEmbed } from './blog-DfUNkngR.js';
2
- import { e as JsonLdObject } from './breadcrumbs-CS0nlknq.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-CS0nlknq.js';
4
- import './_spec-Dk7QyuoJ.js';
5
- import './board-CfmGT0yV.js';
6
- import './jobs-BlAsTCQl.js';
1
+ import { P as PublicBlogPostSummary, B as BlogAuthorEmbed } from './blog-BlRb84MY.js';
2
+ import { e as JsonLdObject } from './breadcrumbs-Bv76gXvF.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-Bv76gXvF.js';
4
+ import './_spec-OPrym0QJ.js';
5
+ import './board-D74R4Iml.js';
6
+ import './jobs-BMG0vrVI.js';
7
7
 
8
8
  /**
9
9
  * Blog structured data on the `@cavuno/board` wire types, transcribed from
package/dist/server.d.mts CHANGED
@@ -1,10 +1,10 @@
1
1
  import { BoardSdk } from './index.mjs';
2
- import './_spec-Dk7QyuoJ.mjs';
3
- import './search-BB1TaaLa.mjs';
4
- import './jobs-BMRvZlNx.mjs';
5
- import './board-DzBYIwKz.mjs';
6
- import './seo-M_8j5vdP.mjs';
7
- import './blog-Oo6YHXSE.mjs';
2
+ import './_spec-OPrym0QJ.mjs';
3
+ import './search-BJkiU3Ic.mjs';
4
+ import './jobs-xjE0IrNu.mjs';
5
+ import './board-Btc1dzQB.mjs';
6
+ import './seo-DGdqWPLo.mjs';
7
+ import './blog-CHQYIhHH.mjs';
8
8
 
9
9
  /**
10
10
  * Session cookie codec — pure (no framework imports, no node imports) so it
package/dist/server.d.ts CHANGED
@@ -1,10 +1,10 @@
1
1
  import { BoardSdk } from './index.js';
2
- import './_spec-Dk7QyuoJ.js';
3
- import './search-CoBeDgYT.js';
4
- import './jobs-BlAsTCQl.js';
5
- import './board-CfmGT0yV.js';
6
- import './seo-BmqJ_ChV.js';
7
- import './blog-DfUNkngR.js';
2
+ import './_spec-OPrym0QJ.js';
3
+ import './search-suUh-E7O.js';
4
+ import './jobs-BMG0vrVI.js';
5
+ import './board-D74R4Iml.js';
6
+ import './seo-CW1JjEXH.js';
7
+ import './blog-BlRb84MY.js';
8
8
 
9
9
  /**
10
10
  * Session cookie codec — pure (no framework imports, no node imports) so it
package/dist/server.mjs CHANGED
@@ -4,7 +4,7 @@ import {
4
4
  } from "./chunk-Z4ALWIGS.mjs";
5
5
  import {
6
6
  isUnauthorized
7
- } from "./chunk-UIKN2ERI.mjs";
7
+ } from "./chunk-AQD4OMX4.mjs";
8
8
 
9
9
  // src/server/cookie.ts
10
10
  var COOKIE_ATTRIBUTES = "Path=/; HttpOnly; Secure; SameSite=Lax";
@@ -1,10 +1,10 @@
1
1
  import { BoardSdk } from './index.mjs';
2
- import './_spec-Dk7QyuoJ.mjs';
3
- import './search-BB1TaaLa.mjs';
4
- import './jobs-BMRvZlNx.mjs';
5
- import './board-DzBYIwKz.mjs';
6
- import './seo-M_8j5vdP.mjs';
7
- import './blog-Oo6YHXSE.mjs';
2
+ import './_spec-OPrym0QJ.mjs';
3
+ import './search-BJkiU3Ic.mjs';
4
+ import './jobs-xjE0IrNu.mjs';
5
+ import './board-Btc1dzQB.mjs';
6
+ import './seo-DGdqWPLo.mjs';
7
+ import './blog-CHQYIhHH.mjs';
8
8
 
9
9
  /**
10
10
  * Sitemap primitives — the pure XML + bucket-filename logic behind a board
package/dist/sitemap.d.ts CHANGED
@@ -1,10 +1,10 @@
1
1
  import { BoardSdk } from './index.js';
2
- import './_spec-Dk7QyuoJ.js';
3
- import './search-CoBeDgYT.js';
4
- import './jobs-BlAsTCQl.js';
5
- import './board-CfmGT0yV.js';
6
- import './seo-BmqJ_ChV.js';
7
- import './blog-DfUNkngR.js';
2
+ import './_spec-OPrym0QJ.js';
3
+ import './search-suUh-E7O.js';
4
+ import './jobs-BMG0vrVI.js';
5
+ import './board-D74R4Iml.js';
6
+ import './seo-CW1JjEXH.js';
7
+ import './blog-BlRb84MY.js';
8
8
 
9
9
  /**
10
10
  * Sitemap primitives — the pure XML + bucket-filename logic behind a board
package/dist/sitemap.mjs CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-DLSO6XXY.mjs";
4
4
  import {
5
5
  isNotFound
6
- } from "./chunk-UIKN2ERI.mjs";
6
+ } from "./chunk-AQD4OMX4.mjs";
7
7
  import {
8
8
  BOARD_PATHS,
9
9
  blogAuthorPath,
@@ -1,5 +1,5 @@
1
- import { h as SuggestionItem, b as SearchSuggestQuery, F as FetchOptions, g as SuggestResult } from './search-BB1TaaLa.mjs';
2
- import './_spec-Dk7QyuoJ.mjs';
1
+ import { h as SuggestionItem, b as SearchSuggestQuery, F as FetchOptions, g as SuggestResult } from './search-BJkiU3Ic.mjs';
2
+ import './_spec-OPrym0QJ.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-CoBeDgYT.js';
2
- import './_spec-Dk7QyuoJ.js';
1
+ import { h as SuggestionItem, b as SearchSuggestQuery, F as FetchOptions, g as SuggestResult } from './search-suUh-E7O.js';
2
+ import './_spec-OPrym0QJ.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.70.0",
3
+ "version": "4.71.0",
4
4
  "description": "Build custom job boards and careers pages with Cavuno’s TypeScript SDK.",
5
5
  "keywords": [
6
6
  "api-client",
@@ -28,6 +28,7 @@ await board.auth.register({
28
28
  email: 'ada@example.com',
29
29
  password: 'a-strong-password',
30
30
  displayName: 'Ada',
31
+ timeZone: browserTimeZone, // read in the browser, sent with the form
31
32
  });
32
33
 
33
34
  const session = await board.auth.login({
@@ -40,6 +41,8 @@ const session = await board.auth.login({
40
41
 
41
42
  For alternate entry points, use `requestMagicLink` / `consumeMagicLink` or the OAuth authorization and exchange methods exposed under `board.auth`.
42
43
 
44
+ Pass `timeZone` to `register` and `consumeMagicLink`: the person's IANA time zone from `Intl.DateTimeFormat().resolvedOptions().timeZone`, read in their browser (such as `Europe/Berlin`). On your server it returns the server's zone, so never fill it in there. The board keeps the first value it gets for a person and ignores an invalid one, so it never fails the sign-up.
45
+
43
46
  **Complete when:** the chosen entry flow returns a session and `board.me.retrieve()` resolves as that board user.
44
47
 
45
48
  ## 3. Handle expiry explicitly
@@ -16,6 +16,8 @@ Both lanes are available only when `board.context()` reports `features.jobAlerts
16
16
 
17
17
  `subscribe` requires consent and deliberately returns the same submitted response for new and existing addresses. `confirm` always resolves; its status owns the landing-page branch.
18
18
 
19
+ Send the person's time zone as `timeZone`: read `Intl.DateTimeFormat().resolvedOptions().timeZone` in their browser (such as `Europe/Berlin`) and pass it with the form. On your server it returns the server's zone, so never fill it in there. The board keeps the first value it gets for a person and ignores an invalid one.
20
+
19
21
  ```ts snippet
20
22
  const submitted = await board.jobAlerts.subscribe({
21
23
  email: 'ada@example.com',
@@ -26,6 +28,7 @@ const submitted = await board.jobAlerts.subscribe({
26
28
  remoteOptions: ['remote'],
27
29
  placeSlugs: ['berlin'],
28
30
  },
31
+ timeZone: browserTimeZone, // read in the browser, sent with the form
29
32
  });
30
33
 
31
34
  const result = await board.jobAlerts.confirm({ token });
@@ -36,8 +39,8 @@ switch (result.status) {
36
39
  case 'not_found':
37
40
  break;
38
41
  case 'unsubscribed':
39
- // Show the manage page's resume option; the subscribe form sends this
40
- // address no confirmation email.
42
+ // Offer the subscribe form again (it emails a fresh confirmation link)
43
+ // or the manage page's resume option.
41
44
  break;
42
45
  case 'expired':
43
46
  await board.jobAlerts.resendConfirmation({ email });
@@ -45,7 +48,7 @@ switch (result.status) {
45
48
  }
46
49
  ```
47
50
 
48
- `waitlisted` means the alert is confirmed but the board can't send to more people yet; it starts once a spot opens. `unsubscribed` means the link was sent before the alerts were turned off, so it doesn't turn them back on. Subscribing again with the form sends no confirmation email to that address; the person resumes alerts from the manage link in an alert email (`board.jobAlerts.resubscribe`) or by signing in and creating an alert.
51
+ `waitlisted` means the alert is confirmed but the board can't send to more people yet; it starts once a spot opens. `unsubscribed` means the link was sent before the alerts were turned off, so it doesn't turn them back on. Subscribing again with the form sends that address a fresh confirmation email, at most once every 12 hours and never while it is suppressed or when the board's team unsubscribed the address; clicking it resumes the alerts. The manage link in an alert email (`board.jobAlerts.resubscribe`) and signing in to create an alert resume them too.
49
52
 
50
53
  Only `jobFunctions`, `placeSlugs`, and `remoteOptions` filter digest delivery. Seniority and salary fields are stored but do not scope delivery. The supported cadence is `weekly`.
51
54
 
@@ -102,6 +105,8 @@ await board.jobAlerts.deletePreference({
102
105
 
103
106
  `unsubscribe` and `resubscribe` accept an optional `preferenceId`. Each managed preference also includes its own `manageToken`.
104
107
 
108
+ `resubscribe` returns `status`: `resubscribed` means the subscription is resumed. `confirmation_sent` means the address never confirmed, so a confirmation email went out instead; keep showing the alerts as off and tell the person to check their inbox. A 429 means rate limiting or a confirmation email requested in the last two minutes; nothing new was sent. A 409 (`job_alert_email_suppressed`) means the address never confirmed and can't receive email, so nothing was sent; keep the alerts off and don't retry. A 502 (`job_alert_confirmation_send_failed`) means the email could not be sent.
109
+
105
110
  `updatePreference` is a full replacement. Round-trip every retained value and always send `frequency`.
106
111
 
107
112
  ```ts snippet
@@ -14,6 +14,7 @@ Every sign-up is double opt-in. The person gets a confirmation email, and nothin
14
14
  - An **unticked** checkbox the person must tick. Its wording must name the board, for example "Send me news and offers from Acme Jobs." Send that exact wording as `consentText`; it is kept as the record of what they agreed to, and a `consentText` without the board's name is refused with a 400.
15
15
  - A `source` label for the form, such as `blog-footer` or `homepage-hero` (lowercase letters, digits and hyphens). It shows as the person's Source in the board's dashboard, so give each form its own.
16
16
  - A hidden `website` field people leave empty. Bots fill it in; the API then answers as usual and does nothing.
17
+ - The person's time zone as `timeZone`: read `Intl.DateTimeFormat().resolvedOptions().timeZone` in their browser (such as `Europe/Berlin`) and send it with the form. On your server it returns the server's zone, so never fill it in there. The board keeps the first value it gets for a person and ignores an invalid one.
17
18
 
18
19
  Read the board's name from `board.context()` rather than typing it.
19
20
 
@@ -27,6 +28,7 @@ const result = await board.subscribe({
27
28
  consentText,
28
29
  source: 'blog-footer',
29
30
  website: honeypotValue,
31
+ timeZone: browserTimeZone, // read in the browser, sent with the form
30
32
  });
31
33
 
32
34
  if (result.sendingPaused) {
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "4.70.0",
2
+ "version": "4.71.0",
3
3
  "skills": [
4
4
  {
5
5
  "name": "cavuno-board-account",