@cavuno/board 4.65.0 → 4.67.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 (43) hide show
  1. package/CHANGELOG.md +48 -0
  2. package/dist/{_spec-CIufstif.d.mts → _spec-BehBmeHK.d.mts} +131 -1
  3. package/dist/{_spec-CIufstif.d.ts → _spec-BehBmeHK.d.ts} +131 -1
  4. package/dist/{blog-DuNJLfIh.d.ts → blog-BLpOmpyQ.d.ts} +1 -1
  5. package/dist/{blog-teDJ9KaO.d.mts → blog-BmfbjijG.d.mts} +1 -1
  6. package/dist/{board-DZNCHGgl.d.mts → board-CXd9Me7_.d.mts} +2 -2
  7. package/dist/{board-iCHYuNhr.d.ts → board-dV_3NXAI.d.ts} +2 -2
  8. package/dist/{breadcrumbs-Bt3oNIAx.d.mts → breadcrumbs-Cu_SPdRA.d.mts} +2 -2
  9. package/dist/{breadcrumbs-DYGo0yB9.d.ts → breadcrumbs-PEsRCVwI.d.ts} +2 -2
  10. package/dist/browser/cavuno-board.global.min.js +1 -1
  11. package/dist/{chunk-H3YIWHXR.mjs → chunk-ZA5TZ6UH.mjs} +5 -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 +90 -15
  17. package/dist/index.d.ts +90 -15
  18. package/dist/index.js +84 -10
  19. package/dist/index.mjs +80 -11
  20. package/dist/{jobs-CbXbDBij.d.mts → jobs-CbTUedOr.d.mts} +1 -1
  21. package/dist/{jobs-DM_QMccX.d.ts → jobs-D2mKA65F.d.ts} +1 -1
  22. package/dist/{search-B7x4qt9A.d.ts → search-CHejx_k7.d.ts} +1 -1
  23. package/dist/{search-PrqcJMft.d.mts → search-CxUViZsz.d.mts} +1 -1
  24. package/dist/{seo-ohehUCzN.d.mts → seo-CWa4rTf7.d.mts} +1 -1
  25. package/dist/{seo-C1Br7ygq.d.ts → seo-DYyQ8NTh.d.ts} +1 -1
  26. package/dist/seo-files.d.mts +2 -2
  27. package/dist/seo-files.d.ts +2 -2
  28. package/dist/seo.d.mts +6 -6
  29. package/dist/seo.d.ts +6 -6
  30. package/dist/server.d.mts +6 -6
  31. package/dist/server.d.ts +6 -6
  32. package/dist/server.mjs +1 -1
  33. package/dist/sitemap.d.mts +6 -6
  34. package/dist/sitemap.d.ts +6 -6
  35. package/dist/sitemap.mjs +1 -1
  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 -0
  40. package/skills/cavuno-board-collections/SKILL.md +31 -2
  41. package/skills/cavuno-board-filters/SKILL.md +12 -4
  42. package/skills/cavuno-board-post-a-job/SKILL.md +54 -5
  43. package/skills/manifest.json +2 -2
package/dist/index.js CHANGED
@@ -131,6 +131,8 @@ var BOARD_API_ERROR_CODES = [
131
131
  "blog_post_not_found",
132
132
  "blog_author_not_found",
133
133
  "blog_tag_not_found",
134
+ // Public collections
135
+ "collections_not_found",
134
136
  // Job aggregator feeds
135
137
  "feeds_not_found",
136
138
  "feed_not_ready",
@@ -151,6 +153,8 @@ var BOARD_API_ERROR_CODES = [
151
153
  "candidate_job_not_found",
152
154
  "candidate_notification_preference_paused",
153
155
  "candidate_profile_required",
156
+ "candidate_custom_field_not_found",
157
+ "candidate_custom_field_not_editable",
154
158
  "resume_invalid_file",
155
159
  "resume_upload_forbidden",
156
160
  // Applications
@@ -237,6 +241,7 @@ var BOARD_API_ERROR_CODES = [
237
241
  "job_posting_logo_lookup_unavailable",
238
242
  "job_posting_logo_not_found",
239
243
  "job_posting_rejected",
244
+ "job_posting_checkout_not_found",
240
245
  // Digital products and purchases
241
246
  "products_not_found",
242
247
  "product_checkout_not_found",
@@ -441,7 +446,7 @@ async function clearSession(storage) {
441
446
  }
442
447
 
443
448
  // src/version.ts
444
- var SDK_VERSION = "4.65.0";
449
+ var SDK_VERSION = "4.67.0";
445
450
 
446
451
  // src/client.ts
447
452
  function isRawBody(body) {
@@ -1165,6 +1170,30 @@ function blogNamespace(client) {
1165
1170
  };
1166
1171
  }
1167
1172
 
1173
+ // src/namespaces/collections.ts
1174
+ function collectionsNamespace(client) {
1175
+ return {
1176
+ /**
1177
+ * List the active entries of a collection the operator made public,
1178
+ * sorted by name, with only its public fields. A collection that is not
1179
+ * public reads as not found (`collections_not_found`). Follow
1180
+ * `nextCursor` for more.
1181
+ *
1182
+ * @example
1183
+ * const { data, nextCursor } = await board.collections.entries(
1184
+ * 'trade_communities',
1185
+ * { limit: 50 },
1186
+ * );
1187
+ */
1188
+ entries(key, query, options) {
1189
+ return client.fetch(
1190
+ `/collections/${encodeURIComponent(key)}/entries`,
1191
+ { ...options, query }
1192
+ );
1193
+ }
1194
+ };
1195
+ }
1196
+
1168
1197
  // src/namespaces/companies.ts
1169
1198
  function companiesNamespace(client) {
1170
1199
  const markets = Object.assign(
@@ -1426,6 +1455,23 @@ function jobPostingNamespace(client) {
1426
1455
  body: input
1427
1456
  });
1428
1457
  },
1458
+ /**
1459
+ * After a paid posting's checkout (`sessionId` from an `embedded_checkout`
1460
+ * result, or `session_id` on the return URL): `awaiting_payment` until the
1461
+ * payment is confirmed (poll briefly), `processing` while a bank payment
1462
+ * clears, then `paid` or `payment_failed`, or `canceled` if the checkout
1463
+ * expired. `jobStatus` and `jobUrl` say whether the job is live.
1464
+ *
1465
+ * @example
1466
+ * const s = await board.jobPosting.getCheckout(sessionId);
1467
+ * if (s.jobUrl) location.assign(s.jobUrl);
1468
+ */
1469
+ getCheckout(sessionId, options) {
1470
+ return client.fetch(
1471
+ `/job-postings/checkout/${encodeURIComponent(sessionId)}`,
1472
+ options
1473
+ );
1474
+ },
1429
1475
  /**
1430
1476
  * Upload a company logo (JPEG/PNG/WebP/GIF, ≤2 MB). Returns the stored
1431
1477
  * `publicUrl` — pass it back as the top-level `logoUrl` on `create(...)`.
@@ -1811,19 +1857,26 @@ function meNamespace(client) {
1811
1857
  query
1812
1858
  });
1813
1859
  },
1814
- /** Retrieve my profile custom-field definitions and current values. */
1860
+ /**
1861
+ * Retrieve my profile custom-field definitions, current values, and the
1862
+ * saved files of upload fields (`customFieldMedia`).
1863
+ */
1815
1864
  retrieveCustomFields(options) {
1816
- return client.fetch("/me/profile/custom-fields", {
1817
- ...options
1818
- });
1865
+ return client.fetch(
1866
+ "/me/profile/custom-fields",
1867
+ { ...options }
1868
+ );
1819
1869
  },
1820
1870
  /** Additively update my editable candidate profile custom fields. */
1821
1871
  updateCustomFields(body, options) {
1822
- return client.fetch("/me/profile/custom-fields", {
1823
- ...options,
1824
- method: "PATCH",
1825
- body
1826
- });
1872
+ return client.fetch(
1873
+ "/me/profile/custom-fields",
1874
+ {
1875
+ ...options,
1876
+ method: "PATCH",
1877
+ body
1878
+ }
1879
+ );
1827
1880
  },
1828
1881
  /** Retrieve editable catalog references on my candidate profile. */
1829
1882
  retrieveObjectReferences(options) {
@@ -2021,6 +2074,26 @@ function meNamespace(client) {
2021
2074
  method: "POST",
2022
2075
  body: form
2023
2076
  });
2077
+ },
2078
+ /**
2079
+ * Upload one file to an owner-editable `image_gallery` or `file` field
2080
+ * of my profile (up to 10 MB; galleries take JPEG, PNG, WebP or GIF).
2081
+ * The file is a draft until its `id` is saved to the field with
2082
+ * `updateCustomFields`, as the ordered list of file IDs.
2083
+ *
2084
+ * @example
2085
+ * const image = await board.me.profile.uploadCustomFieldFile('portfolio', file);
2086
+ * await board.me.profile.updateCustomFields({
2087
+ * values: { portfolio: [...savedIds, image.id] },
2088
+ * });
2089
+ */
2090
+ uploadCustomFieldFile(fieldKey, file, options) {
2091
+ const form = new FormData();
2092
+ form.append("file", file);
2093
+ return client.fetch(
2094
+ `/me/profile/custom-fields/${encodeURIComponent(fieldKey)}/files`,
2095
+ { ...options, method: "POST", body: form }
2096
+ );
2024
2097
  }
2025
2098
  },
2026
2099
  /**
@@ -4725,6 +4798,7 @@ function createBoardClient(options) {
4725
4798
  embed: embedNamespace(client),
4726
4799
  companies: companiesNamespace(client),
4727
4800
  blog: blogNamespace(client),
4801
+ collections: collectionsNamespace(client),
4728
4802
  auth: authNamespace(client, options.board),
4729
4803
  me: meNamespace(client),
4730
4804
  invites: invitesNamespace(client),
package/dist/index.mjs CHANGED
@@ -28,7 +28,7 @@ import {
28
28
  isSsoRequired,
29
29
  isUnauthorized,
30
30
  isValidationError
31
- } from "./chunk-H3YIWHXR.mjs";
31
+ } from "./chunk-ZA5TZ6UH.mjs";
32
32
 
33
33
  // src/query.ts
34
34
  function toSearchParams(query) {
@@ -49,7 +49,7 @@ function toSearchParams(query) {
49
49
  }
50
50
 
51
51
  // src/version.ts
52
- var SDK_VERSION = "4.65.0";
52
+ var SDK_VERSION = "4.67.0";
53
53
 
54
54
  // src/client.ts
55
55
  function isRawBody(body) {
@@ -770,6 +770,30 @@ function blogNamespace(client) {
770
770
  };
771
771
  }
772
772
 
773
+ // src/namespaces/collections.ts
774
+ function collectionsNamespace(client) {
775
+ return {
776
+ /**
777
+ * List the active entries of a collection the operator made public,
778
+ * sorted by name, with only its public fields. A collection that is not
779
+ * public reads as not found (`collections_not_found`). Follow
780
+ * `nextCursor` for more.
781
+ *
782
+ * @example
783
+ * const { data, nextCursor } = await board.collections.entries(
784
+ * 'trade_communities',
785
+ * { limit: 50 },
786
+ * );
787
+ */
788
+ entries(key, query, options) {
789
+ return client.fetch(
790
+ `/collections/${encodeURIComponent(key)}/entries`,
791
+ { ...options, query }
792
+ );
793
+ }
794
+ };
795
+ }
796
+
773
797
  // src/namespaces/companies.ts
774
798
  function companiesNamespace(client) {
775
799
  const markets = Object.assign(
@@ -1031,6 +1055,23 @@ function jobPostingNamespace(client) {
1031
1055
  body: input
1032
1056
  });
1033
1057
  },
1058
+ /**
1059
+ * After a paid posting's checkout (`sessionId` from an `embedded_checkout`
1060
+ * result, or `session_id` on the return URL): `awaiting_payment` until the
1061
+ * payment is confirmed (poll briefly), `processing` while a bank payment
1062
+ * clears, then `paid` or `payment_failed`, or `canceled` if the checkout
1063
+ * expired. `jobStatus` and `jobUrl` say whether the job is live.
1064
+ *
1065
+ * @example
1066
+ * const s = await board.jobPosting.getCheckout(sessionId);
1067
+ * if (s.jobUrl) location.assign(s.jobUrl);
1068
+ */
1069
+ getCheckout(sessionId, options) {
1070
+ return client.fetch(
1071
+ `/job-postings/checkout/${encodeURIComponent(sessionId)}`,
1072
+ options
1073
+ );
1074
+ },
1034
1075
  /**
1035
1076
  * Upload a company logo (JPEG/PNG/WebP/GIF, ≤2 MB). Returns the stored
1036
1077
  * `publicUrl` — pass it back as the top-level `logoUrl` on `create(...)`.
@@ -1416,19 +1457,26 @@ function meNamespace(client) {
1416
1457
  query
1417
1458
  });
1418
1459
  },
1419
- /** Retrieve my profile custom-field definitions and current values. */
1460
+ /**
1461
+ * Retrieve my profile custom-field definitions, current values, and the
1462
+ * saved files of upload fields (`customFieldMedia`).
1463
+ */
1420
1464
  retrieveCustomFields(options) {
1421
- return client.fetch("/me/profile/custom-fields", {
1422
- ...options
1423
- });
1465
+ return client.fetch(
1466
+ "/me/profile/custom-fields",
1467
+ { ...options }
1468
+ );
1424
1469
  },
1425
1470
  /** Additively update my editable candidate profile custom fields. */
1426
1471
  updateCustomFields(body, options) {
1427
- return client.fetch("/me/profile/custom-fields", {
1428
- ...options,
1429
- method: "PATCH",
1430
- body
1431
- });
1472
+ return client.fetch(
1473
+ "/me/profile/custom-fields",
1474
+ {
1475
+ ...options,
1476
+ method: "PATCH",
1477
+ body
1478
+ }
1479
+ );
1432
1480
  },
1433
1481
  /** Retrieve editable catalog references on my candidate profile. */
1434
1482
  retrieveObjectReferences(options) {
@@ -1626,6 +1674,26 @@ function meNamespace(client) {
1626
1674
  method: "POST",
1627
1675
  body: form
1628
1676
  });
1677
+ },
1678
+ /**
1679
+ * Upload one file to an owner-editable `image_gallery` or `file` field
1680
+ * of my profile (up to 10 MB; galleries take JPEG, PNG, WebP or GIF).
1681
+ * The file is a draft until its `id` is saved to the field with
1682
+ * `updateCustomFields`, as the ordered list of file IDs.
1683
+ *
1684
+ * @example
1685
+ * const image = await board.me.profile.uploadCustomFieldFile('portfolio', file);
1686
+ * await board.me.profile.updateCustomFields({
1687
+ * values: { portfolio: [...savedIds, image.id] },
1688
+ * });
1689
+ */
1690
+ uploadCustomFieldFile(fieldKey, file, options) {
1691
+ const form = new FormData();
1692
+ form.append("file", file);
1693
+ return client.fetch(
1694
+ `/me/profile/custom-fields/${encodeURIComponent(fieldKey)}/files`,
1695
+ { ...options, method: "POST", body: form }
1696
+ );
1629
1697
  }
1630
1698
  },
1631
1699
  /**
@@ -4300,6 +4368,7 @@ function createBoardClient(options) {
4300
4368
  embed: embedNamespace(client),
4301
4369
  companies: companiesNamespace(client),
4302
4370
  blog: blogNamespace(client),
4371
+ collections: collectionsNamespace(client),
4303
4372
  auth: authNamespace(client, options.board),
4304
4373
  me: meNamespace(client),
4305
4374
  invites: invitesNamespace(client),
@@ -1,4 +1,4 @@
1
- import { S as Schemas } from './_spec-CIufstif.mjs';
1
+ import { S as Schemas } from './_spec-BehBmeHK.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-CIufstif.js';
1
+ import { S as Schemas } from './_spec-BehBmeHK.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-CIufstif.js';
1
+ import { S as Schemas } from './_spec-BehBmeHK.js';
2
2
 
3
3
  type Awaitable<T> = T | Promise<T>;
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { S as Schemas } from './_spec-CIufstif.mjs';
1
+ import { S as Schemas } from './_spec-BehBmeHK.mjs';
2
2
 
3
3
  type Awaitable<T> = T | Promise<T>;
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { S as Schemas } from './_spec-CIufstif.mjs';
1
+ import { S as Schemas } from './_spec-BehBmeHK.mjs';
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-CIufstif.js';
1
+ import { S as Schemas } from './_spec-BehBmeHK.js';
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-ohehUCzN.mjs';
2
- import './_spec-CIufstif.mjs';
1
+ import { B as BoardSeo } from './seo-CWa4rTf7.mjs';
2
+ import './_spec-BehBmeHK.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-C1Br7ygq.js';
2
- import './_spec-CIufstif.js';
1
+ import { B as BoardSeo } from './seo-DYyQ8NTh.js';
2
+ import './_spec-BehBmeHK.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-teDJ9KaO.mjs';
2
- import { e as JsonLdObject } from './breadcrumbs-Bt3oNIAx.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-Bt3oNIAx.mjs';
4
- import './_spec-CIufstif.mjs';
5
- import './board-DZNCHGgl.mjs';
6
- import './jobs-CbXbDBij.mjs';
1
+ import { P as PublicBlogPostSummary, B as BlogAuthorEmbed } from './blog-BmfbjijG.mjs';
2
+ import { e as JsonLdObject } from './breadcrumbs-Cu_SPdRA.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-Cu_SPdRA.mjs';
4
+ import './_spec-BehBmeHK.mjs';
5
+ import './board-CXd9Me7_.mjs';
6
+ import './jobs-CbTUedOr.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-DuNJLfIh.js';
2
- import { e as JsonLdObject } from './breadcrumbs-DYGo0yB9.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-DYGo0yB9.js';
4
- import './_spec-CIufstif.js';
5
- import './board-iCHYuNhr.js';
6
- import './jobs-DM_QMccX.js';
1
+ import { P as PublicBlogPostSummary, B as BlogAuthorEmbed } from './blog-BLpOmpyQ.js';
2
+ import { e as JsonLdObject } from './breadcrumbs-PEsRCVwI.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-PEsRCVwI.js';
4
+ import './_spec-BehBmeHK.js';
5
+ import './board-dV_3NXAI.js';
6
+ import './jobs-D2mKA65F.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-CIufstif.mjs';
3
- import './search-PrqcJMft.mjs';
4
- import './jobs-CbXbDBij.mjs';
5
- import './board-DZNCHGgl.mjs';
6
- import './seo-ohehUCzN.mjs';
7
- import './blog-teDJ9KaO.mjs';
2
+ import './_spec-BehBmeHK.mjs';
3
+ import './search-CxUViZsz.mjs';
4
+ import './jobs-CbTUedOr.mjs';
5
+ import './board-CXd9Me7_.mjs';
6
+ import './seo-CWa4rTf7.mjs';
7
+ import './blog-BmfbjijG.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-CIufstif.js';
3
- import './search-B7x4qt9A.js';
4
- import './jobs-DM_QMccX.js';
5
- import './board-iCHYuNhr.js';
6
- import './seo-C1Br7ygq.js';
7
- import './blog-DuNJLfIh.js';
2
+ import './_spec-BehBmeHK.js';
3
+ import './search-CHejx_k7.js';
4
+ import './jobs-D2mKA65F.js';
5
+ import './board-dV_3NXAI.js';
6
+ import './seo-DYyQ8NTh.js';
7
+ import './blog-BLpOmpyQ.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-H3YIWHXR.mjs";
7
+ } from "./chunk-ZA5TZ6UH.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-CIufstif.mjs';
3
- import './search-PrqcJMft.mjs';
4
- import './jobs-CbXbDBij.mjs';
5
- import './board-DZNCHGgl.mjs';
6
- import './seo-ohehUCzN.mjs';
7
- import './blog-teDJ9KaO.mjs';
2
+ import './_spec-BehBmeHK.mjs';
3
+ import './search-CxUViZsz.mjs';
4
+ import './jobs-CbTUedOr.mjs';
5
+ import './board-CXd9Me7_.mjs';
6
+ import './seo-CWa4rTf7.mjs';
7
+ import './blog-BmfbjijG.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-CIufstif.js';
3
- import './search-B7x4qt9A.js';
4
- import './jobs-DM_QMccX.js';
5
- import './board-iCHYuNhr.js';
6
- import './seo-C1Br7ygq.js';
7
- import './blog-DuNJLfIh.js';
2
+ import './_spec-BehBmeHK.js';
3
+ import './search-CHejx_k7.js';
4
+ import './jobs-D2mKA65F.js';
5
+ import './board-dV_3NXAI.js';
6
+ import './seo-DYyQ8NTh.js';
7
+ import './blog-BLpOmpyQ.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-H3YIWHXR.mjs";
6
+ } from "./chunk-ZA5TZ6UH.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-PrqcJMft.mjs';
2
- import './_spec-CIufstif.mjs';
1
+ import { h as SuggestionItem, b as SearchSuggestQuery, F as FetchOptions, g as SuggestResult } from './search-CxUViZsz.mjs';
2
+ import './_spec-BehBmeHK.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-B7x4qt9A.js';
2
- import './_spec-CIufstif.js';
1
+ import { h as SuggestionItem, b as SearchSuggestQuery, F as FetchOptions, g as SuggestResult } from './search-CHejx_k7.js';
2
+ import './_spec-BehBmeHK.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.65.0",
3
+ "version": "4.67.0",
4
4
  "description": "Build custom job boards and careers pages with Cavuno’s TypeScript SDK.",
5
5
  "keywords": [
6
6
  "api-client",
@@ -206,6 +206,17 @@ The SDK builds multipart `FormData` with field `file` from a `Blob` or `File`. A
206
206
  const { avatarUrl } = await board.me.profile.uploadAvatar(file);
207
207
  ```
208
208
 
209
+ Image gallery and file custom fields take one upload per call, up to 10 MB; galleries accept JPEG, PNG, WebP or GIF and hold at most 10 images. Only fields with `editableByOwner: true` accept uploads. An upload is a draft until you save its `id` to the field: the field's value is the ordered list of file IDs, so append, remove or reorder IDs and send the whole list. Drafts never saved are deleted after a day. Show previews from the returned `url` and from `customFieldMedia` on `retrieveCustomFields`; both are signed links that expire, so read them fresh rather than storing them.
210
+
211
+ ```ts snippet
212
+ const { values } = await board.me.profile.retrieveCustomFields();
213
+ const saved = Array.isArray(values.portfolio) ? values.portfolio : [];
214
+ const image = await board.me.profile.uploadCustomFieldFile('portfolio', file);
215
+ await board.me.profile.updateCustomFields({
216
+ values: { portfolio: [...saved, image.id] },
217
+ });
218
+ ```
219
+
209
220
  Resume upload starts an asynchronous parse that may populate the profile. Poll within a fixed budget, surface failure, and keep manual editing available if parsing runs long.
210
221
 
211
222
  ```ts snippet
@@ -1,13 +1,13 @@
1
1
  ---
2
2
  name: cavuno-board-collections
3
- description: Custom profile fields and collection references with @cavuno/board. Use for rendering company, talent or job custom fields, collection entries, benefits/technologies/certification sections, or collection-backed filters.
3
+ description: Custom profile fields, collection references and public collections with @cavuno/board. Use for rendering company, talent or job custom fields, collection entries, a page that lists a collection's entries (resources, partners, communities), benefits/technologies/certification sections, or collection-backed filters.
4
4
  ---
5
5
 
6
6
  # Custom fields and collections
7
7
 
8
8
  An operator defines two kinds of extra data. A **custom field** stores one typed value directly on a company, talent profile, or job. A **collection reference** points that record at reusable entries — benefits, technologies, certifications, learning resources — that the operator maintains once and every record shares.
9
9
 
10
- Hosted Cavuno boards do not render either one. The API resolves them and your frontend decides the layout, so this surface is read-heavy: definitions tell you what to draw, resolved selections tell you what to draw it with.
10
+ Your site renders both. The API resolves them and your frontend decides the layout, so this surface is read-heavy: definitions tell you what to draw, resolved selections tell you what to draw it with. A collection the operator made public can also be listed on its own page with `board.collections.entries` (see below).
11
11
 
12
12
  ## The read model
13
13
 
@@ -76,6 +76,34 @@ for (const field of job.resolvedCollectionFields) {
76
76
  }
77
77
  ```
78
78
 
79
+ ## Public collections
80
+
81
+ A collection the operator turned **Public** on (Settings, Collections) can be listed on its own page, such as a Resources or Partners page. Ask the operator for the collection's key; a collection that is not public, archived, or unknown throws `BoardApiError` with code `collections_not_found`.
82
+
83
+ ```ts snippet
84
+ const entries = [];
85
+ let cursor: string | undefined;
86
+ do {
87
+ const page = await board.collections.entries('trade_communities', {
88
+ limit: 100,
89
+ cursor,
90
+ });
91
+ entries.push(...page.data);
92
+ cursor = page.nextCursor ?? undefined;
93
+ } while (cursor);
94
+
95
+ for (const entry of entries) {
96
+ renderResource({
97
+ heading: entry.name,
98
+ logoUrl: entry.logoUrl,
99
+ website: entry.values.website,
100
+ href: entry.slug ? `/resources/${entry.slug}` : undefined,
101
+ });
102
+ }
103
+ ```
104
+
105
+ Each entry is `{ id, name, slug?, logoUrl?, fields, values, references? }`, sorted by name: the same `fields` / `values` / `references` shape as a job collection entry, without the per-job `title` and `description`. Take labels from `fields`.
106
+
79
107
  Visibility is enforced server-side. Public reads return only public scalar fields, public collection fields, and active entries; private definitions and archived entries are omitted entirely, not nulled. Do not render a placeholder for a key that is absent — the operator meant it to be invisible. An owner read returns the private owner-editable fields too, so the same component can receive either payload; branch on what is present.
80
108
 
81
109
  ## Owner writes
@@ -140,6 +168,7 @@ Finish only after every applicable check passes:
140
168
  - Rich text renders as formatted HTML, not escaped tags.
141
169
  - A private field and an archived entry are absent from the public render, with no empty placeholder left behind.
142
170
  - Job pages read `resolvedCollectionFields`, and company or talent pages read `objectReferences` — neither shape is assumed for the other.
171
+ - A page that lists a collection reads `board.collections.entries`, follows `nextCursor` to the end, and handles `collections_not_found` without a broken page.
143
172
  - Filter requests carry record IDs from a choices call, and the filter control's options come from the public definition list.
144
173
  - A multi-select picker stops at the definition's `maxSelections`, or at 100 when the definition omits it.
145
174
 
@@ -112,18 +112,26 @@ const categoryOptions = categories.data.map((term) => ({
112
112
  }));
113
113
  ```
114
114
 
115
- For homepage "browse by category" tiles, ask for the busiest terms rather
116
- than the first page of the name-sorted collection:
115
+ Categories also carry `totalJobCount`: published jobs on the category or
116
+ any subcategory, each job once. A parent category page lists its
117
+ subcategories' jobs, so show `totalJobCount` next to category links. A parent
118
+ whose jobs all sit in subcategories has `jobCount` 0 and is still listed.
119
+
120
+ For homepage "browse by category" tiles, ask for the busiest top-level
121
+ categories rather than the first page of the name-sorted collection:
117
122
 
118
123
  ```ts snippet
119
124
  const top = await board.taxonomy.categories.list({
125
+ topLevel: true,
120
126
  limit: 8,
121
- sort: 'jobCount',
127
+ sort: 'totalJobCount',
122
128
  });
123
129
  ```
124
130
 
125
131
  Category and skill lists accept `q`, `limit` (1–100), `sort` (`name` or
126
- `jobCount`), and opaque `cursor`. Pass `nextCursor` unchanged to the next
132
+ `jobCount`; categories also `totalJobCount`), and opaque `cursor`. With
133
+ `sort: 'jobCount'` and no `q` or `topLevel`, a parent with no jobs of its own
134
+ is left out; `totalJobCount` includes it. Pass `nextCursor` unchanged to the next
127
135
  request. The cursor is bound to `q`, `limit`, and `sort`.
128
136
 
129
137
  ```ts snippet