@cavuno/board 4.45.0 → 4.48.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 (60) hide show
  1. package/CHANGELOG.md +64 -0
  2. package/dist/{_spec-CdNZDaaR.d.mts → _spec-Fw9b79TI.d.mts} +54 -4
  3. package/dist/{_spec-CdNZDaaR.d.ts → _spec-Fw9b79TI.d.ts} +54 -4
  4. package/dist/bin.mjs +1 -0
  5. package/dist/{blog-ZvLJ6w1Q.d.ts → blog-DldIXX6n.d.ts} +1 -1
  6. package/dist/{blog-uV51b4Cg.d.mts → blog-Dlyky5Eo.d.mts} +1 -1
  7. package/dist/{board-3JU14eF3.d.ts → board-B1Ueww2w.d.ts} +2 -2
  8. package/dist/{board-CJw-MJpf.d.mts → board-DkwbMZdt.d.mts} +2 -2
  9. package/dist/{breadcrumbs-CXvdv6Ry.d.ts → breadcrumbs-Bj8SieZi.d.mts} +5 -3
  10. package/dist/{breadcrumbs-BY1UMCbL.d.mts → breadcrumbs-CzFiddAt.d.ts} +5 -3
  11. package/dist/browser/cavuno-board.global.min.js +1 -1
  12. package/dist/{chunk-5KCWHENV.mjs → chunk-2KD2CWFL.mjs} +1 -1
  13. package/dist/{chunk-XXQCESMU.mjs → chunk-JFDWTTOQ.mjs} +5 -0
  14. package/dist/{chunk-KDFKVWTZ.mjs → chunk-JTFUOGWE.mjs} +3 -3
  15. package/dist/doctor.js +1 -0
  16. package/dist/doctor.mjs +1 -0
  17. package/dist/filters.d.mts +2 -2
  18. package/dist/filters.d.ts +2 -2
  19. package/dist/format.d.mts +4 -4
  20. package/dist/format.d.ts +4 -4
  21. package/dist/format.js +3 -2
  22. package/dist/format.mjs +2 -2
  23. package/dist/go.js +1 -0
  24. package/dist/go.mjs +1 -1
  25. package/dist/index.d.mts +73 -13
  26. package/dist/index.d.ts +73 -13
  27. package/dist/index.js +57 -23
  28. package/dist/index.mjs +57 -23
  29. package/dist/{jobs-D9ERWWda.d.mts → jobs-oSTStcbC.d.mts} +1 -1
  30. package/dist/{jobs-C7UvN_dW.d.ts → jobs-rnatMRvm.d.ts} +1 -1
  31. package/dist/paths.d.mts +7 -1
  32. package/dist/paths.d.ts +7 -1
  33. package/dist/paths.js +5 -0
  34. package/dist/paths.mjs +3 -1
  35. package/dist/route-contract.js +1 -0
  36. package/dist/route-contract.mjs +2 -2
  37. package/dist/{search-D0TFnn1x.d.ts → search-CKvtGE6t.d.ts} +1 -1
  38. package/dist/{search-BMSNK85o.d.mts → search-uiAE7AFt.d.mts} +1 -1
  39. package/dist/{seo-CYmVKHsu.d.ts → seo-C2WvBFEi.d.ts} +1 -1
  40. package/dist/{seo-C3WmgifR.d.mts → seo-Cz0544dX.d.mts} +1 -1
  41. package/dist/seo-files.d.mts +2 -2
  42. package/dist/seo-files.d.ts +2 -2
  43. package/dist/seo.d.mts +6 -6
  44. package/dist/seo.d.ts +6 -6
  45. package/dist/seo.js +3 -2
  46. package/dist/seo.mjs +2 -2
  47. package/dist/server.d.mts +6 -6
  48. package/dist/server.d.ts +6 -6
  49. package/dist/sitemap.d.mts +6 -6
  50. package/dist/sitemap.d.ts +6 -6
  51. package/dist/sitemap.js +1 -0
  52. package/dist/sitemap.mjs +1 -1
  53. package/dist/suggest.d.mts +2 -2
  54. package/dist/suggest.d.ts +2 -2
  55. package/dist/well-known.js +1 -0
  56. package/dist/well-known.mjs +2 -2
  57. package/package.json +1 -1
  58. package/skills/cavuno-board-job-alerts/SKILL.md +29 -1
  59. package/skills/cavuno-board-talent-access/SKILL.md +2 -0
  60. package/skills/manifest.json +1 -1
package/dist/index.mjs CHANGED
@@ -46,7 +46,7 @@ function toSearchParams(query) {
46
46
  }
47
47
 
48
48
  // src/version.ts
49
- var SDK_VERSION = "4.45.0";
49
+ var SDK_VERSION = "4.48.0";
50
50
 
51
51
  // src/client.ts
52
52
  function isRawBody(body) {
@@ -2134,11 +2134,15 @@ function meNamespace(client) {
2134
2134
  },
2135
2135
  /**
2136
2136
  * Company-owned saved searches over the talent directory. Each holds
2137
- * named filters and, optionally, saved people (`members`). Approved
2138
- * members share the same lists. Optional `job` links a list to one
2139
- * company job; pass `job: null` on update to unlink. Linking a list
2140
- * shortlists everyone saved to it onto that job; unlinking changes no
2141
- * pipeline.
2137
+ * named filters and saved people (`members`), with no size limit.
2138
+ * Approved members share the same lists. Optional `job` links a list
2139
+ * to one company job, and a job has at most one list; pass
2140
+ * `job: null` on update to unlink. Saving to a linked list is how a
2141
+ * sourced candidate is shortlisted onto the job, and removing takes
2142
+ * them off while they are still at Shortlisted, so the list and the
2143
+ * job agree. Linking a list shortlists everyone saved to it, saves the
2144
+ * sourced people already on the job, and folds in the job's previous
2145
+ * list. Unlinking changes neither side.
2142
2146
  */
2143
2147
  talentLists: {
2144
2148
  /**
@@ -2210,13 +2214,15 @@ function meNamespace(client) {
2210
2214
  );
2211
2215
  },
2212
2216
  /**
2213
- * People saved to a talent list (at most 500 per list).
2217
+ * People saved to a talent list. A list has no size limit.
2214
2218
  */
2215
2219
  members: {
2216
2220
  /**
2217
- * List the people saved to a list as directory cards, most
2218
- * recently saved first unless `sort` or a keyword (`q`) is set;
2219
- * with a keyword, best match first. Cards are redacted as in the
2221
+ * List the people saved to a list as directory cards, in the
2222
+ * public directory's order: best match first with a keyword
2223
+ * (`q`), otherwise by `sort` or the directory's default order. A
2224
+ * save or removal shows here within seconds; `memberCount` is
2225
+ * immediate. Cards are redacted as in the
2220
2226
  * public directory when the board sells profile unlocks, except
2221
2227
  * for candidates the company has unlocked. Runs the public
2222
2228
  * talent directory search, with the same filters, restricted to
@@ -2245,8 +2251,9 @@ function meNamespace(client) {
2245
2251
  * Save a candidate to a list. Idempotent: saving someone already
2246
2252
  * on it returns `created: false`. When the list is linked to a
2247
2253
  * job, the candidate is also shortlisted onto that job unless they
2248
- * already have a pipeline row there. A full list raises
2249
- * `talent_list_full` (409).
2254
+ * already have a pipeline row there; this is the way to shortlist
2255
+ * a sourced candidate. Lists have no size limit, so
2256
+ * `talent_list_full` is never raised.
2250
2257
  *
2251
2258
  * @example
2252
2259
  * await board.me.companies.talentLists.members.add('acme', listId, {
@@ -2262,8 +2269,11 @@ function meNamespace(client) {
2262
2269
  );
2263
2270
  },
2264
2271
  /**
2265
- * Remove a candidate from a list. Idempotent. Never changes a job
2266
- * pipeline, including the linked job's.
2272
+ * Remove a candidate from a list. Idempotent. On a list linked to
2273
+ * a job, also removes their pipeline row on that job while it is a
2274
+ * sourced row still at Shortlisted; anyone further along, or who
2275
+ * applied, keeps it (end that with a rejection). An unlinked list
2276
+ * changes no pipeline.
2267
2277
  */
2268
2278
  remove(slug, listId, candidateBoardUserId, options) {
2269
2279
  return client.fetch(
@@ -2279,15 +2289,21 @@ function meNamespace(client) {
2279
2289
  },
2280
2290
  /**
2281
2291
  * Per-job sourced membership — the unstaged kanban rail.
2282
- * Saving a candidate always writes here. Convert-on-drop creates a
2283
- * pipeline application with source `sourced` (hidden from the
2284
- * candidate until they apply themselves).
2292
+ *
2293
+ * @deprecated A job's sourced people are the people saved to its
2294
+ * talent list. Use `talentLists.members` on the list whose `jobId` is
2295
+ * the job: `add` shortlists, `remove` takes them off, and `list` with
2296
+ * `stage` reads pipeline columns. `add` and `remove` here forward to
2297
+ * those calls.
2285
2298
  */
2286
2299
  sourcedCandidates: {
2287
2300
  /**
2288
2301
  * List sourced candidates still on the rail for a job. Anyone who
2289
2302
  * already has a pipeline application for that job is omitted.
2290
2303
  *
2304
+ * @deprecated Use `talentLists.members.list` on the job's talent
2305
+ * list.
2306
+ *
2291
2307
  * @example
2292
2308
  * const { data } = await board.me.companies.sourcedCandidates.list(
2293
2309
  * 'acme',
@@ -2302,7 +2318,12 @@ function meNamespace(client) {
2302
2318
  },
2303
2319
  /**
2304
2320
  * Save a candidate onto a job's sourced rail. Idempotent: a second
2305
- * add for the same pair returns `created: false`.
2321
+ * add for the same pair returns `created: false`. Saves them to the
2322
+ * job's talent list (created, named after the job, when it has
2323
+ * none) and shortlists them onto the job.
2324
+ *
2325
+ * @deprecated Use `talentLists.members.add` on the job's talent
2326
+ * list.
2306
2327
  *
2307
2328
  * @example
2308
2329
  * const saved = await board.me.companies.sourcedCandidates.add(
@@ -2317,7 +2338,14 @@ function meNamespace(client) {
2317
2338
  body
2318
2339
  });
2319
2340
  },
2320
- /** Remove a sourced membership. Does not touch pipeline applications. */
2341
+ /**
2342
+ * Remove a sourced membership: the candidate leaves the job's talent
2343
+ * list, and their pipeline row on the job goes too while it is a
2344
+ * sourced row still at Shortlisted.
2345
+ *
2346
+ * @deprecated Use `talentLists.members.remove` on the job's talent
2347
+ * list.
2348
+ */
2321
2349
  remove(slug, sourcedId, options) {
2322
2350
  return client.fetch(
2323
2351
  `/me/companies/${encodeURIComponent(
@@ -2333,6 +2361,9 @@ function meNamespace(client) {
2333
2361
  * `review`. A board without a native pipeline raises
2334
2362
  * `sourced_convert_unavailable` (409).
2335
2363
  *
2364
+ * @deprecated Saving to the job's talent list already shortlists
2365
+ * the candidate; move them on the pipeline from there.
2366
+ *
2336
2367
  * @example
2337
2368
  * const result = await board.me.companies.sourcedCandidates.convert(
2338
2369
  * 'acme',
@@ -3533,9 +3564,10 @@ function talentNamespace(client) {
3533
3564
  * first, each with how many candidates the caller can see there (a
3534
3565
  * country counts every candidate in its cities). Anonymous callers get
3535
3566
  * counts of `public` profiles; a signed-in board user also counts
3536
- * `logged_in_only` ones. Pass a place's `slug` as `talent.list`'s
3537
- * `place` filter. With `q`, returns location search matches instead,
3538
- * ranked as `taxonomy.places.list` ranks them.
3567
+ * `logged_in_only` ones. Pass a place's `slug` (or its board-language
3568
+ * `canonicalSlug`) as `talent.list`'s `place` filter, and show its
3569
+ * board-language `displayName`. With `q`, returns location search
3570
+ * matches instead, ranked as `taxonomy.places.list` ranks them.
3539
3571
  *
3540
3572
  * Same access errors as `talent.list`. Returns an empty list until the
3541
3573
  * board's place counts are built.
@@ -3603,7 +3635,9 @@ function taxonomyNamespace(client) {
3603
3635
  /**
3604
3636
  * Without `query`: list every place used by a published job, with its
3605
3637
  * live job count (the locations directory). With `query.q` (≥2 chars):
3606
- * location autocomplete — the top name matches ranked.
3638
+ * location autocomplete — the top name matches ranked. Each place
3639
+ * carries its board-language `displayName` and `canonicalSlug`; link
3640
+ * with `canonicalSlug`.
3607
3641
  */
3608
3642
  list(query, options) {
3609
3643
  return client.fetch("/places", {
@@ -1,4 +1,4 @@
1
- import { S as Schemas } from './_spec-CdNZDaaR.mjs';
1
+ import { S as Schemas } from './_spec-Fw9b79TI.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-CdNZDaaR.js';
1
+ import { S as Schemas } from './_spec-Fw9b79TI.js';
2
2
 
3
3
  /**
4
4
  * Optional pagination metadata returned by Board API list operations.
package/dist/paths.d.mts CHANGED
@@ -134,6 +134,11 @@ declare function blogAuthorPath(authorSlug: string): string;
134
134
  * Only the handle is encoded.
135
135
  */
136
136
  declare function talentProfilePath(handle: string): string;
137
+ /**
138
+ * Talent location page (`/talent/locations/<place>`): the candidates who live
139
+ * in a place. Pass the place's `canonicalSlug` from the talent place list.
140
+ */
141
+ declare function talentLocationPath(placeSlug: string): string;
137
142
  /**
138
143
  * Static top-level board paths (indexed marketing + index surfaces). Kept
139
144
  * here so the sitemap and consumers share one definition of the chrome
@@ -155,6 +160,7 @@ declare const BOARD_PATHS: {
155
160
  readonly cookiePolicy: "/cookie-policy";
156
161
  readonly impressum: "/impressum";
157
162
  readonly talent: "/talent";
163
+ readonly talentLocations: "/talent/locations";
158
164
  readonly employers: "/employers";
159
165
  /**
160
166
  * Alert-email surfaces. Promoted out of raw literals in
@@ -188,4 +194,4 @@ declare function goAlertsConfirmPath(): string;
188
194
  */
189
195
  declare function boardUrl(origin: string, path: string): string;
190
196
 
191
- export { BOARD_PATHS, type SuggestionPathInput, type SuggestionPathOptions, type SuggestionPathScope, blogAuthorPath, blogPostPath, blogTagPath, boardUrl, companyMarketPath, companyPath, companySalaryPath, encodePathSegment, goAlertsConfirmPath, goAlertsManagePath, goJobPath, jobDetailPath, jobsCategoryPath, jobsLocationCategoryPath, jobsLocationPath, jobsLocationSkillPath, jobsSkillPath, salaryLocationPath, salarySkillPath, salaryTitlePath, suggestionPath, talentProfilePath };
197
+ export { BOARD_PATHS, type SuggestionPathInput, type SuggestionPathOptions, type SuggestionPathScope, blogAuthorPath, blogPostPath, blogTagPath, boardUrl, companyMarketPath, companyPath, companySalaryPath, encodePathSegment, goAlertsConfirmPath, goAlertsManagePath, goJobPath, jobDetailPath, jobsCategoryPath, jobsLocationCategoryPath, jobsLocationPath, jobsLocationSkillPath, jobsSkillPath, salaryLocationPath, salarySkillPath, salaryTitlePath, suggestionPath, talentLocationPath, talentProfilePath };
package/dist/paths.d.ts CHANGED
@@ -134,6 +134,11 @@ declare function blogAuthorPath(authorSlug: string): string;
134
134
  * Only the handle is encoded.
135
135
  */
136
136
  declare function talentProfilePath(handle: string): string;
137
+ /**
138
+ * Talent location page (`/talent/locations/<place>`): the candidates who live
139
+ * in a place. Pass the place's `canonicalSlug` from the talent place list.
140
+ */
141
+ declare function talentLocationPath(placeSlug: string): string;
137
142
  /**
138
143
  * Static top-level board paths (indexed marketing + index surfaces). Kept
139
144
  * here so the sitemap and consumers share one definition of the chrome
@@ -155,6 +160,7 @@ declare const BOARD_PATHS: {
155
160
  readonly cookiePolicy: "/cookie-policy";
156
161
  readonly impressum: "/impressum";
157
162
  readonly talent: "/talent";
163
+ readonly talentLocations: "/talent/locations";
158
164
  readonly employers: "/employers";
159
165
  /**
160
166
  * Alert-email surfaces. Promoted out of raw literals in
@@ -188,4 +194,4 @@ declare function goAlertsConfirmPath(): string;
188
194
  */
189
195
  declare function boardUrl(origin: string, path: string): string;
190
196
 
191
- export { BOARD_PATHS, type SuggestionPathInput, type SuggestionPathOptions, type SuggestionPathScope, blogAuthorPath, blogPostPath, blogTagPath, boardUrl, companyMarketPath, companyPath, companySalaryPath, encodePathSegment, goAlertsConfirmPath, goAlertsManagePath, goJobPath, jobDetailPath, jobsCategoryPath, jobsLocationCategoryPath, jobsLocationPath, jobsLocationSkillPath, jobsSkillPath, salaryLocationPath, salarySkillPath, salaryTitlePath, suggestionPath, talentProfilePath };
197
+ export { BOARD_PATHS, type SuggestionPathInput, type SuggestionPathOptions, type SuggestionPathScope, blogAuthorPath, blogPostPath, blogTagPath, boardUrl, companyMarketPath, companyPath, companySalaryPath, encodePathSegment, goAlertsConfirmPath, goAlertsManagePath, goJobPath, jobDetailPath, jobsCategoryPath, jobsLocationCategoryPath, jobsLocationPath, jobsLocationSkillPath, jobsSkillPath, salaryLocationPath, salarySkillPath, salaryTitlePath, suggestionPath, talentLocationPath, talentProfilePath };
package/dist/paths.js CHANGED
@@ -42,6 +42,7 @@ __export(paths_exports, {
42
42
  salarySkillPath: () => salarySkillPath,
43
43
  salaryTitlePath: () => salaryTitlePath,
44
44
  suggestionPath: () => suggestionPath,
45
+ talentLocationPath: () => talentLocationPath,
45
46
  talentProfilePath: () => talentProfilePath
46
47
  });
47
48
  module.exports = __toCommonJS(paths_exports);
@@ -131,6 +132,9 @@ function blogAuthorPath(authorSlug) {
131
132
  function talentProfilePath(handle) {
132
133
  return `/p/${encodePathSegment(handle)}`;
133
134
  }
135
+ function talentLocationPath(placeSlug) {
136
+ return `/talent/locations/${encodePathSegment(placeSlug)}`;
137
+ }
134
138
  var BOARD_PATHS = {
135
139
  home: "/",
136
140
  jobs: "/jobs",
@@ -147,6 +151,7 @@ var BOARD_PATHS = {
147
151
  cookiePolicy: "/cookie-policy",
148
152
  impressum: "/impressum",
149
153
  talent: "/talent",
154
+ talentLocations: "/talent/locations",
150
155
  employers: "/employers",
151
156
  /**
152
157
  * Alert-email surfaces. Promoted out of raw literals in
package/dist/paths.mjs CHANGED
@@ -21,8 +21,9 @@ import {
21
21
  salarySkillPath,
22
22
  salaryTitlePath,
23
23
  suggestionPath,
24
+ talentLocationPath,
24
25
  talentProfilePath
25
- } from "./chunk-XXQCESMU.mjs";
26
+ } from "./chunk-JFDWTTOQ.mjs";
26
27
  export {
27
28
  BOARD_PATHS,
28
29
  blogAuthorPath,
@@ -46,5 +47,6 @@ export {
46
47
  salarySkillPath,
47
48
  salaryTitlePath,
48
49
  suggestionPath,
50
+ talentLocationPath,
49
51
  talentProfilePath
50
52
  };
@@ -119,6 +119,7 @@ var BOARD_PATHS = {
119
119
  cookiePolicy: "/cookie-policy",
120
120
  impressum: "/impressum",
121
121
  talent: "/talent",
122
+ talentLocations: "/talent/locations",
122
123
  employers: "/employers",
123
124
  /**
124
125
  * Alert-email surfaces. Promoted out of raw literals in
@@ -26,8 +26,8 @@ import {
26
26
  parseTanStackRoutes,
27
27
  sameParamSet,
28
28
  validateManifest
29
- } from "./chunk-5KCWHENV.mjs";
30
- import "./chunk-XXQCESMU.mjs";
29
+ } from "./chunk-2KD2CWFL.mjs";
30
+ import "./chunk-JFDWTTOQ.mjs";
31
31
  export {
32
32
  ALL_ROLES,
33
33
  CANONICAL_MANIFEST,
@@ -1,4 +1,4 @@
1
- import { S as Schemas } from './_spec-CdNZDaaR.js';
1
+ import { S as Schemas } from './_spec-Fw9b79TI.js';
2
2
 
3
3
  type Awaitable<T> = T | Promise<T>;
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { S as Schemas } from './_spec-CdNZDaaR.mjs';
1
+ import { S as Schemas } from './_spec-Fw9b79TI.mjs';
2
2
 
3
3
  type Awaitable<T> = T | Promise<T>;
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { S as Schemas } from './_spec-CdNZDaaR.js';
1
+ import { S as Schemas } from './_spec-Fw9b79TI.js';
2
2
 
3
3
  /**
4
4
  * The public SEO-infra payload (`board.seo()`) — platform infrastructure a
@@ -1,4 +1,4 @@
1
- import { S as Schemas } from './_spec-CdNZDaaR.mjs';
1
+ import { S as Schemas } from './_spec-Fw9b79TI.mjs';
2
2
 
3
3
  /**
4
4
  * The public SEO-infra payload (`board.seo()`) — platform infrastructure a
@@ -1,5 +1,5 @@
1
- import { B as BoardSeo } from './seo-C3WmgifR.mjs';
2
- import './_spec-CdNZDaaR.mjs';
1
+ import { B as BoardSeo } from './seo-Cz0544dX.mjs';
2
+ import './_spec-Fw9b79TI.mjs';
3
3
 
4
4
  /**
5
5
  * `@cavuno/board/seo-files` — platform-owned crawler/identity file bodies
@@ -1,5 +1,5 @@
1
- import { B as BoardSeo } from './seo-CYmVKHsu.js';
2
- import './_spec-CdNZDaaR.js';
1
+ import { B as BoardSeo } from './seo-C2WvBFEi.js';
2
+ import './_spec-Fw9b79TI.js';
3
3
 
4
4
  /**
5
5
  * `@cavuno/board/seo-files` — platform-owned crawler/identity file bodies
package/dist/seo.d.mts CHANGED
@@ -1,9 +1,9 @@
1
- import { P as PublicBlogPostSummary, B as BlogAuthorEmbed } from './blog-uV51b4Cg.mjs';
2
- import { e as JsonLdObject } from './breadcrumbs-BY1UMCbL.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-BY1UMCbL.mjs';
4
- import './_spec-CdNZDaaR.mjs';
5
- import './board-CJw-MJpf.mjs';
6
- import './jobs-D9ERWWda.mjs';
1
+ import { P as PublicBlogPostSummary, B as BlogAuthorEmbed } from './blog-Dlyky5Eo.mjs';
2
+ import { e as JsonLdObject } from './breadcrumbs-Bj8SieZi.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-Bj8SieZi.mjs';
4
+ import './_spec-Fw9b79TI.mjs';
5
+ import './board-DkwbMZdt.mjs';
6
+ import './jobs-oSTStcbC.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-ZvLJ6w1Q.js';
2
- import { e as JsonLdObject } from './breadcrumbs-CXvdv6Ry.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-CXvdv6Ry.js';
4
- import './_spec-CdNZDaaR.js';
5
- import './board-3JU14eF3.js';
6
- import './jobs-C7UvN_dW.js';
1
+ import { P as PublicBlogPostSummary, B as BlogAuthorEmbed } from './blog-DldIXX6n.js';
2
+ import { e as JsonLdObject } from './breadcrumbs-CzFiddAt.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-CzFiddAt.js';
4
+ import './_spec-Fw9b79TI.js';
5
+ import './board-B1Ueww2w.js';
6
+ import './jobs-rnatMRvm.js';
7
7
 
8
8
  /**
9
9
  * Blog structured data on the `@cavuno/board` wire types, transcribed from
package/dist/seo.js CHANGED
@@ -199,6 +199,7 @@ var BOARD_PATHS = {
199
199
  cookiePolicy: "/cookie-policy",
200
200
  impressum: "/impressum",
201
201
  talent: "/talent",
202
+ talentLocations: "/talent/locations",
202
203
  employers: "/employers",
203
204
  /**
204
205
  * Alert-email surfaces. Promoted out of raw literals in
@@ -262,11 +263,11 @@ function buildJobBreadcrumbs(job) {
262
263
  ];
263
264
  let lastPlaceSlug = null;
264
265
  for (const place of job.placeHierarchy) {
265
- lastPlaceSlug = place.slug;
266
+ lastPlaceSlug = place.canonicalSlug;
266
267
  crumbs.push({
267
268
  kind: "place",
268
269
  name: place.name,
269
- path: jobsLocationPath(place.slug)
270
+ path: jobsLocationPath(place.canonicalSlug)
270
271
  });
271
272
  }
272
273
  const primaryCategory = job.categories[0];
package/dist/seo.mjs CHANGED
@@ -17,11 +17,11 @@ import {
17
17
  skillSalaryJsonLd,
18
18
  sortBySeniority,
19
19
  titleSalaryJsonLd
20
- } from "./chunk-KDFKVWTZ.mjs";
20
+ } from "./chunk-JTFUOGWE.mjs";
21
21
  import {
22
22
  boardUrl,
23
23
  jobDetailPath
24
- } from "./chunk-XXQCESMU.mjs";
24
+ } from "./chunk-JFDWTTOQ.mjs";
25
25
 
26
26
  // src/seo/blog.ts
27
27
  function createBlogArticleJsonLd({
package/dist/server.d.mts CHANGED
@@ -1,10 +1,10 @@
1
1
  import { BoardSdk } from './index.mjs';
2
- import './_spec-CdNZDaaR.mjs';
3
- import './search-BMSNK85o.mjs';
4
- import './jobs-D9ERWWda.mjs';
5
- import './board-CJw-MJpf.mjs';
6
- import './seo-C3WmgifR.mjs';
7
- import './blog-uV51b4Cg.mjs';
2
+ import './_spec-Fw9b79TI.mjs';
3
+ import './search-uiAE7AFt.mjs';
4
+ import './jobs-oSTStcbC.mjs';
5
+ import './board-DkwbMZdt.mjs';
6
+ import './seo-Cz0544dX.mjs';
7
+ import './blog-Dlyky5Eo.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-CdNZDaaR.js';
3
- import './search-D0TFnn1x.js';
4
- import './jobs-C7UvN_dW.js';
5
- import './board-3JU14eF3.js';
6
- import './seo-CYmVKHsu.js';
7
- import './blog-ZvLJ6w1Q.js';
2
+ import './_spec-Fw9b79TI.js';
3
+ import './search-CKvtGE6t.js';
4
+ import './jobs-rnatMRvm.js';
5
+ import './board-B1Ueww2w.js';
6
+ import './seo-C2WvBFEi.js';
7
+ import './blog-DldIXX6n.js';
8
8
 
9
9
  /**
10
10
  * Session cookie codec — pure (no framework imports, no node imports) so it
@@ -1,10 +1,10 @@
1
1
  import { BoardSdk } from './index.mjs';
2
- import './_spec-CdNZDaaR.mjs';
3
- import './search-BMSNK85o.mjs';
4
- import './jobs-D9ERWWda.mjs';
5
- import './board-CJw-MJpf.mjs';
6
- import './seo-C3WmgifR.mjs';
7
- import './blog-uV51b4Cg.mjs';
2
+ import './_spec-Fw9b79TI.mjs';
3
+ import './search-uiAE7AFt.mjs';
4
+ import './jobs-oSTStcbC.mjs';
5
+ import './board-DkwbMZdt.mjs';
6
+ import './seo-Cz0544dX.mjs';
7
+ import './blog-Dlyky5Eo.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-CdNZDaaR.js';
3
- import './search-D0TFnn1x.js';
4
- import './jobs-C7UvN_dW.js';
5
- import './board-3JU14eF3.js';
6
- import './seo-CYmVKHsu.js';
7
- import './blog-ZvLJ6w1Q.js';
2
+ import './_spec-Fw9b79TI.js';
3
+ import './search-CKvtGE6t.js';
4
+ import './jobs-rnatMRvm.js';
5
+ import './board-B1Ueww2w.js';
6
+ import './seo-C2WvBFEi.js';
7
+ import './blog-DldIXX6n.js';
8
8
 
9
9
  /**
10
10
  * Sitemap primitives — the pure XML + bucket-filename logic behind a board
package/dist/sitemap.js CHANGED
@@ -240,6 +240,7 @@ var BOARD_PATHS = {
240
240
  cookiePolicy: "/cookie-policy",
241
241
  impressum: "/impressum",
242
242
  talent: "/talent",
243
+ talentLocations: "/talent/locations",
243
244
  employers: "/employers",
244
245
  /**
245
246
  * Alert-email surfaces. Promoted out of raw literals in
package/dist/sitemap.mjs CHANGED
@@ -19,7 +19,7 @@ import {
19
19
  salaryLocationPath,
20
20
  salarySkillPath,
21
21
  salaryTitlePath
22
- } from "./chunk-XXQCESMU.mjs";
22
+ } from "./chunk-JFDWTTOQ.mjs";
23
23
 
24
24
  // src/sitemap/xml.ts
25
25
  var SITEMAP_BUCKETS = [
@@ -1,5 +1,5 @@
1
- import { h as SuggestionItem, b as SearchSuggestQuery, F as FetchOptions, g as SuggestResult } from './search-BMSNK85o.mjs';
2
- import './_spec-CdNZDaaR.mjs';
1
+ import { h as SuggestionItem, b as SearchSuggestQuery, F as FetchOptions, g as SuggestResult } from './search-uiAE7AFt.mjs';
2
+ import './_spec-Fw9b79TI.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-D0TFnn1x.js';
2
- import './_spec-CdNZDaaR.js';
1
+ import { h as SuggestionItem, b as SearchSuggestQuery, F as FetchOptions, g as SuggestResult } from './search-CKvtGE6t.js';
2
+ import './_spec-Fw9b79TI.js';
3
3
 
4
4
  /**
5
5
  * `@cavuno/board/suggest` — framework-agnostic headless search-suggest
@@ -100,6 +100,7 @@ var BOARD_PATHS = {
100
100
  cookiePolicy: "/cookie-policy",
101
101
  impressum: "/impressum",
102
102
  talent: "/talent",
103
+ talentLocations: "/talent/locations",
103
104
  employers: "/employers",
104
105
  /**
105
106
  * Alert-email surfaces. Promoted out of raw literals in
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  compileManifest
3
- } from "./chunk-5KCWHENV.mjs";
4
- import "./chunk-XXQCESMU.mjs";
3
+ } from "./chunk-2KD2CWFL.mjs";
4
+ import "./chunk-JFDWTTOQ.mjs";
5
5
 
6
6
  // src/well-known/handler.ts
7
7
  var WELL_KNOWN_CACHE_CONTROL = "public, max-age=300";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cavuno/board",
3
- "version": "4.45.0",
3
+ "version": "4.48.0",
4
4
  "description": "Build custom job boards and careers pages with Cavuno’s TypeScript SDK.",
5
5
  "keywords": [
6
6
  "api-client",
@@ -42,6 +42,31 @@ switch (result.status) {
42
42
 
43
43
  Only `jobFunctions`, `placeSlugs`, and `remoteOptions` filter digest delivery. Seniority and salary fields are stored but do not scope delivery. The supported cadence is `weekly`.
44
44
 
45
+ `jobFunctions` are category and skill slugs (the `slug` of a category or skill, such as `engineering` or `media-and-communication`). A digest matches a job when any entry equals one of the job's category or skill slugs. Prefer sending slugs. If you send display names or free-text keywords instead, the server slugifies each one when the alert is saved and matches it against the board's category and skill slugs, their aliases, and their board-language slugs. A display name that does not slugify to one of those (for example, a renamed category) is stored slugified and will not match, so send slugs whenever you have them. Alerts read back from the API therefore always carry slugs, so compare and display them as slugs.
46
+
47
+ ## Alert kinds, keywords, and anchor jobs
48
+
49
+ Every alert read back from either lane carries a read-only `kind`:
50
+
51
+ - `similar_job`: jobs similar to the job the visitor subscribed from. Subscribe from a job page with `context: { source: 'job_detail', jobId }` (or `job_apply_dialog`). `anchorJob` is that job as `{ id, slug, title }`, kept after the job closes. It is `null` for other kinds, and for an older similar-job alert whose job has not been captured yet.
52
+ - `search`: a board search for the alert's keywords, in `filters.query`. An older search alert can report `kind: 'search'` with `filters.query` `null`: its keyword is the single `jobFunctions` entry. When `query` is `null`, show the job functions as the alert's search instead.
53
+ - `filters`: jobs matching the stored filters exactly.
54
+
55
+ Send the query a search page ran as `filters.query` (on `board.me.alerts`, the top-level `query`), at most 200 characters after trimming. Keep sending the location and other filters alongside it.
56
+
57
+ ```ts snippet
58
+ await board.jobAlerts.subscribe({
59
+ email: 'ada@example.com',
60
+ consent: true,
61
+ filters: { query: 'Python developer', placeSlugs: ['berlin'] },
62
+ context: { source: 'jobs_list' },
63
+ });
64
+ ```
65
+
66
+ A sent `query` is stored as given (trimmed), so `front-end` reads back as `front-end`. A job-page `context` without a `jobId` cannot anchor a similar-job alert; with a `query` it makes a `search` alert. A client that predates `query` and sends the search keyword as its single `jobFunctions` entry, with a search-page `context.source`, still works: the server keeps that keyword as the alert's `query`.
67
+
68
+ On an update, `null` clears `query`, and omitting it keeps the stored keywords as long as `jobFunctions` are unchanged. An update never changes `kind`, except that giving a `filters` alert a `query` makes it a `search` alert. A `similar_job` alert takes no `query`: sending one, on subscribe with a job-page `context` or on an update, fails with `validation_bad_request` (400). To follow keywords instead, remove the similar-job alert and create a search alert. In alert lists, show the kind and, for similar-job alerts, link the anchor job.
69
+
45
70
  ## Anonymous lane: manage-token transport
46
71
 
47
72
  The read and write transports intentionally use different keys:
@@ -92,16 +117,19 @@ const { data: alerts } = await board.me.alerts.list();
92
117
  alerts[0]?.isActive;
93
118
  alerts[0]?.lastSentAt;
94
119
  alerts[0]?.filters;
120
+ alerts[0]?.kind;
121
+ alerts[0]?.anchorJob;
95
122
 
96
123
  const alert = await board.me.alerts.create({
97
124
  frequency: 'weekly',
98
- jobFunctions: ['engineering'],
125
+ query: 'Platform engineer',
99
126
  remoteOptions: ['remote'],
100
127
  });
101
128
 
102
129
  const current = await board.me.alerts.retrieve(alert.id);
103
130
  await board.me.alerts.update(alert.id, {
104
131
  frequency: 'weekly',
132
+ query: current.filters.query,
105
133
  jobFunctions: current.filters.jobFunctions,
106
134
  seniorityLevels: current.filters.seniorityLevels,
107
135
  remoteOptions: current.filters.remoteOptions,
@@ -130,6 +130,8 @@ await board.me.conversations.start({
130
130
 
131
131
  Named `/p/{handle}` is the share bypass and always shows a full `public` profile. Opaque `/p/{id}` is the unlock-gated route. When `accessModel === 'paid_unlocks_and_messaging'`, directory cards redact for viewers who are not unlimited.
132
132
 
133
+ `lastActive` on directory cards and profiles is a coarse bucket (`today`, `this_week`, `this_month`, `last_3_months`, `over_3_months`) for a signed-in employer looking at a candidate who is actively looking or open to offers, and `null` otherwise. It stays on redacted cards. Render it as a short label such as "Active this week" and hide it when `null`.
134
+
133
135
  ```ts snippet
134
136
  const named = await board.talent.retrieve('jane-doe');
135
137
  const opaque = await board.talent.retrieve('bu_candidate');
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "4.45.0",
2
+ "version": "4.48.0",
3
3
  "skills": [
4
4
  {
5
5
  "name": "cavuno-board-account",