@cavuno/board 4.69.0 → 4.70.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.
- package/CHANGELOG.md +44 -0
- package/dist/{_spec-CFOj7Qdf.d.mts → _spec-Dk7QyuoJ.d.mts} +58 -2
- package/dist/{_spec-CFOj7Qdf.d.ts → _spec-Dk7QyuoJ.d.ts} +58 -2
- package/dist/{blog-BaVJi3q1.d.ts → blog-DfUNkngR.d.ts} +1 -1
- package/dist/{blog-DCRBPnpZ.d.mts → blog-Oo6YHXSE.d.mts} +1 -1
- package/dist/{board-zLt7j6hj.d.ts → board-CfmGT0yV.d.ts} +2 -2
- package/dist/{board-DMS3I3sJ.d.mts → board-DzBYIwKz.d.mts} +2 -2
- package/dist/{breadcrumbs-yGijUUtR.d.ts → breadcrumbs-CS0nlknq.d.ts} +2 -2
- package/dist/{breadcrumbs-Dwf0yq7B.d.mts → breadcrumbs-DeIA0RQp.d.mts} +2 -2
- package/dist/browser/cavuno-board.global.min.js +1 -1
- package/dist/{chunk-7SAHE7UW.mjs → chunk-UIKN2ERI.mjs} +2 -0
- package/dist/filters.d.mts +2 -2
- package/dist/filters.d.ts +2 -2
- package/dist/format.d.mts +4 -4
- package/dist/format.d.ts +4 -4
- package/dist/index.d.mts +74 -22
- package/dist/index.d.ts +74 -22
- package/dist/index.js +50 -2
- package/dist/index.mjs +49 -3
- package/dist/{jobs-Cew_q69W.d.mts → jobs-BMRvZlNx.d.mts} +1 -1
- package/dist/{jobs-Dz_w1jZq.d.ts → jobs-BlAsTCQl.d.ts} +1 -1
- package/dist/{search-DwvgvtEg.d.mts → search-BB1TaaLa.d.mts} +1 -1
- package/dist/{search-BqAYR47P.d.ts → search-CoBeDgYT.d.ts} +1 -1
- package/dist/{seo-CGy4fY5a.d.ts → seo-BmqJ_ChV.d.ts} +1 -1
- package/dist/{seo-FKj1pSHZ.d.mts → seo-M_8j5vdP.d.mts} +1 -1
- package/dist/seo-files.d.mts +2 -2
- package/dist/seo-files.d.ts +2 -2
- package/dist/seo.d.mts +6 -6
- package/dist/seo.d.ts +6 -6
- package/dist/server.d.mts +6 -6
- package/dist/server.d.ts +6 -6
- package/dist/server.mjs +1 -1
- package/dist/sitemap.d.mts +6 -6
- package/dist/sitemap.d.ts +6 -6
- package/dist/sitemap.mjs +1 -1
- package/dist/suggest.d.mts +2 -2
- package/dist/suggest.d.ts +2 -2
- package/package.json +1 -1
- package/skills/cavuno-board-account/SKILL.md +16 -0
- package/skills/cavuno-board-job-alerts/SKILL.md +7 -0
- package/skills/cavuno-board-newsletter/SKILL.md +79 -0
- package/skills/manifest.json +8 -1
package/dist/seo-files.d.mts
CHANGED
package/dist/seo-files.d.ts
CHANGED
package/dist/seo.d.mts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { P as PublicBlogPostSummary, B as BlogAuthorEmbed } from './blog-
|
|
2
|
-
import { e as JsonLdObject } from './breadcrumbs-
|
|
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-
|
|
4
|
-
import './_spec-
|
|
5
|
-
import './board-
|
|
6
|
-
import './jobs-
|
|
1
|
+
import { P as PublicBlogPostSummary, B as BlogAuthorEmbed } from './blog-Oo6YHXSE.mjs';
|
|
2
|
+
import { e as JsonLdObject } from './breadcrumbs-DeIA0RQp.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-DeIA0RQp.mjs';
|
|
4
|
+
import './_spec-Dk7QyuoJ.mjs';
|
|
5
|
+
import './board-DzBYIwKz.mjs';
|
|
6
|
+
import './jobs-BMRvZlNx.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-
|
|
2
|
-
import { e as JsonLdObject } from './breadcrumbs-
|
|
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-
|
|
4
|
-
import './_spec-
|
|
5
|
-
import './board-
|
|
6
|
-
import './jobs-
|
|
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';
|
|
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-
|
|
3
|
-
import './search-
|
|
4
|
-
import './jobs-
|
|
5
|
-
import './board-
|
|
6
|
-
import './seo-
|
|
7
|
-
import './blog-
|
|
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';
|
|
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-
|
|
3
|
-
import './search-
|
|
4
|
-
import './jobs-
|
|
5
|
-
import './board-
|
|
6
|
-
import './seo-
|
|
7
|
-
import './blog-
|
|
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';
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Session cookie codec — pure (no framework imports, no node imports) so it
|
package/dist/server.mjs
CHANGED
package/dist/sitemap.d.mts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { BoardSdk } from './index.mjs';
|
|
2
|
-
import './_spec-
|
|
3
|
-
import './search-
|
|
4
|
-
import './jobs-
|
|
5
|
-
import './board-
|
|
6
|
-
import './seo-
|
|
7
|
-
import './blog-
|
|
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';
|
|
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-
|
|
3
|
-
import './search-
|
|
4
|
-
import './jobs-
|
|
5
|
-
import './board-
|
|
6
|
-
import './seo-
|
|
7
|
-
import './blog-
|
|
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';
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Sitemap primitives — the pure XML + bucket-filename logic behind a board
|
package/dist/sitemap.mjs
CHANGED
package/dist/suggest.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { h as SuggestionItem, b as SearchSuggestQuery, F as FetchOptions, g as SuggestResult } from './search-
|
|
2
|
-
import './_spec-
|
|
1
|
+
import { h as SuggestionItem, b as SearchSuggestQuery, F as FetchOptions, g as SuggestResult } from './search-BB1TaaLa.mjs';
|
|
2
|
+
import './_spec-Dk7QyuoJ.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-
|
|
2
|
-
import './_spec-
|
|
1
|
+
import { h as SuggestionItem, b as SearchSuggestQuery, F as FetchOptions, g as SuggestResult } from './search-CoBeDgYT.js';
|
|
2
|
+
import './_spec-Dk7QyuoJ.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* `@cavuno/board/suggest` — framework-agnostic headless search-suggest
|
package/package.json
CHANGED
|
@@ -217,6 +217,22 @@ await board.me.profile.updateCustomFields({
|
|
|
217
217
|
});
|
|
218
218
|
```
|
|
219
219
|
|
|
220
|
+
Company members upload to the company's upload fields the same way, with the company slug first. `customFieldMedia` on `board.me.companies.retrieveCustomFields` lists the saved files.
|
|
221
|
+
|
|
222
|
+
```ts snippet
|
|
223
|
+
const company = await board.me.companies.retrieveCustomFields('acme');
|
|
224
|
+
const photos = Array.isArray(company.values.office_photos)
|
|
225
|
+
? company.values.office_photos
|
|
226
|
+
: [];
|
|
227
|
+
const photo = await board.me.companies.uploadCustomFieldFile(
|
|
228
|
+
'acme',
|
|
229
|
+
'office_photos',
|
|
230
|
+
file);
|
|
231
|
+
await board.me.companies.updateCustomFields('acme', {
|
|
232
|
+
values: { office_photos: [...photos, photo.id] },
|
|
233
|
+
});
|
|
234
|
+
```
|
|
235
|
+
|
|
220
236
|
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.
|
|
221
237
|
|
|
222
238
|
```ts snippet
|
|
@@ -32,14 +32,21 @@ const result = await board.jobAlerts.confirm({ token });
|
|
|
32
32
|
switch (result.status) {
|
|
33
33
|
case 'confirmed':
|
|
34
34
|
case 'already_confirmed':
|
|
35
|
+
case 'waitlisted':
|
|
35
36
|
case 'not_found':
|
|
36
37
|
break;
|
|
38
|
+
case 'unsubscribed':
|
|
39
|
+
// Show the manage page's resume option; the subscribe form sends this
|
|
40
|
+
// address no confirmation email.
|
|
41
|
+
break;
|
|
37
42
|
case 'expired':
|
|
38
43
|
await board.jobAlerts.resendConfirmation({ email });
|
|
39
44
|
break;
|
|
40
45
|
}
|
|
41
46
|
```
|
|
42
47
|
|
|
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.
|
|
49
|
+
|
|
43
50
|
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
51
|
|
|
45
52
|
`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.
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cavuno-board-newsletter
|
|
3
|
+
description: Newsletter sign-up forms with @cavuno/board. Use for an email sign-up for the board's news (footer, blog, landing page), its consent checkbox, the confirmation email, and sendingPaused.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Newsletter sign-up
|
|
7
|
+
|
|
8
|
+
`board.subscribe` signs an address up for the board's own email (news, offers, updates). It is separate from job alerts (`board.jobAlerts.subscribe`): use it for a form whose promise is "get our news", not "get matching jobs".
|
|
9
|
+
|
|
10
|
+
Every sign-up is double opt-in. The person gets a confirmation email, and nothing is sent to them until they click it. The response is the same whether the address is new, waiting to confirm, or already subscribed, so it never tells a visitor who is on the list.
|
|
11
|
+
|
|
12
|
+
## The form
|
|
13
|
+
|
|
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
|
+
- 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
|
+
- A hidden `website` field people leave empty. Bots fill it in; the API then answers as usual and does nothing.
|
|
17
|
+
|
|
18
|
+
Read the board's name from `board.context()` rather than typing it.
|
|
19
|
+
|
|
20
|
+
```ts snippet
|
|
21
|
+
const { name } = await board.context();
|
|
22
|
+
const consentText = `Send me news and offers from ${name}.`;
|
|
23
|
+
|
|
24
|
+
const result = await board.subscribe({
|
|
25
|
+
email,
|
|
26
|
+
consent: true,
|
|
27
|
+
consentText,
|
|
28
|
+
source: 'blog-footer',
|
|
29
|
+
website: honeypotValue,
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
if (result.sendingPaused) {
|
|
33
|
+
// Recorded, but the board's email is paused for now.
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
`pageUrl` is optional; it defaults to the request's `Referer`. Pass it when the call is made from your server, where the `Referer` is not the visitor's page.
|
|
38
|
+
|
|
39
|
+
## After submitting
|
|
40
|
+
|
|
41
|
+
Always show the same message: "Check your inbox to confirm your subscription." Never show "you're already subscribed"; the API deliberately doesn't say.
|
|
42
|
+
|
|
43
|
+
When `sendingPaused` is `true`, add a short note that emails from the board may be delayed. The sign-up is still recorded.
|
|
44
|
+
|
|
45
|
+
## Confirmation
|
|
46
|
+
|
|
47
|
+
The confirmation email links to the board's job alert confirmation page, the same page job alerts use. That page completes the sign-up with `board.jobAlerts.confirm({ token })`; no separate route is needed. `confirmed` and `already_confirmed` mean the person is subscribed, and `not_found` or `expired` mean the link no longer works.
|
|
48
|
+
|
|
49
|
+
The page serves both kinds of link, so word it by `subscription`. A newsletter link answers `subscription: 'marketing'` and never turns job alerts on, so don't tell that person their job alerts are confirmed:
|
|
50
|
+
|
|
51
|
+
```ts
|
|
52
|
+
const result = await board.jobAlerts.confirm({ token });
|
|
53
|
+
const subscribed =
|
|
54
|
+
result.status === 'confirmed' || result.status === 'already_confirmed';
|
|
55
|
+
const message = !subscribed
|
|
56
|
+
? 'This link no longer works.'
|
|
57
|
+
: result.subscription === 'marketing'
|
|
58
|
+
? "You're subscribed to our emails."
|
|
59
|
+
: 'Your job alert is confirmed.';
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Errors
|
|
63
|
+
|
|
64
|
+
- `validation_bad_request` (400): a field is missing or malformed, `consent` isn't `true`, or `consentText` doesn't name the board.
|
|
65
|
+
- `rate_limited` (429): 3 sign-ups a minute per address across all boards, or 10 requests a minute per IP. A self-hosted site calls from its own server, so all its visitors share that IP limit with every other sign-in and sign-up call from that server; on a builder site Cavuno hosts it counts each visitor separately, plus 6 sign-ups a minute per visitor. `details.retryAfterSeconds` says when to try again.
|
|
66
|
+
- `rate_limit_unavailable` (503): retry shortly.
|
|
67
|
+
|
|
68
|
+
```ts snippet
|
|
69
|
+
import { BoardApiError } from '@cavuno/board';
|
|
70
|
+
|
|
71
|
+
try {
|
|
72
|
+
await board.subscribe({ email, consent: true, consentText, source: 'footer' });
|
|
73
|
+
} catch (error) {
|
|
74
|
+
if (error instanceof BoardApiError && error.status === 429) {
|
|
75
|
+
// Ask them to try again in a minute.
|
|
76
|
+
}
|
|
77
|
+
throw error;
|
|
78
|
+
}
|
|
79
|
+
```
|
package/skills/manifest.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "4.
|
|
2
|
+
"version": "4.70.0",
|
|
3
3
|
"skills": [
|
|
4
4
|
{
|
|
5
5
|
"name": "cavuno-board-account",
|
|
@@ -106,6 +106,13 @@
|
|
|
106
106
|
"framework": null,
|
|
107
107
|
"category": "core"
|
|
108
108
|
},
|
|
109
|
+
{
|
|
110
|
+
"name": "cavuno-board-newsletter",
|
|
111
|
+
"description": "Newsletter sign-up forms with @cavuno/board. Use for an email sign-up for the board's news (footer, blog, landing page), its consent checkbox, the confirmation email, and sendingPaused.",
|
|
112
|
+
"path": "skills/cavuno-board-newsletter/SKILL.md",
|
|
113
|
+
"framework": null,
|
|
114
|
+
"category": "core"
|
|
115
|
+
},
|
|
109
116
|
{
|
|
110
117
|
"name": "cavuno-board-paywall",
|
|
111
118
|
"description": "Grant-is-truth candidate paywall with @cavuno/board. Use for offers, gated job counts, embedded checkout handoff, access confirmation, or subscription portal links.",
|