@cavuno/board 4.68.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 +73 -0
- package/dist/{_spec-t2B6ioRS.d.mts → _spec-Dk7QyuoJ.d.mts} +69 -2
- package/dist/{_spec-t2B6ioRS.d.ts → _spec-Dk7QyuoJ.d.ts} +69 -2
- package/dist/{blog-W1cBNXyS.d.ts → blog-DfUNkngR.d.ts} +1 -1
- package/dist/{blog-B8UJJza1.d.mts → blog-Oo6YHXSE.d.mts} +1 -1
- package/dist/{board-On_r_ixp.d.ts → board-CfmGT0yV.d.ts} +2 -2
- package/dist/{board-8RMVpFBw.d.mts → board-DzBYIwKz.d.mts} +2 -2
- package/dist/{breadcrumbs-eV2OQqf6.d.ts → breadcrumbs-CS0nlknq.d.ts} +2 -2
- package/dist/{breadcrumbs-BgBj_AiZ.d.mts → breadcrumbs-DeIA0RQp.d.mts} +2 -2
- package/dist/browser/cavuno-board.global.min.js +1 -1
- package/dist/{chunk-ZA5TZ6UH.mjs → chunk-UIKN2ERI.mjs} +3 -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 +89 -38
- package/dist/index.d.ts +89 -38
- package/dist/index.js +60 -3
- package/dist/index.mjs +58 -4
- package/dist/{jobs-CrGBikhJ.d.mts → jobs-BMRvZlNx.d.mts} +1 -1
- package/dist/{jobs-D_LjWgIk.d.ts → jobs-BlAsTCQl.d.ts} +1 -1
- package/dist/{search-Yw5qsooq.d.mts → search-BB1TaaLa.d.mts} +1 -1
- package/dist/{search-ClbqUjkA.d.ts → search-CoBeDgYT.d.ts} +1 -1
- package/dist/{seo-CY5Vl13y.d.ts → seo-BmqJ_ChV.d.ts} +1 -1
- package/dist/{seo-Bjevxvzd.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/index.js
CHANGED
|
@@ -81,6 +81,7 @@ var BOARD_API_ERROR_CODES = [
|
|
|
81
81
|
// Board-user auth
|
|
82
82
|
"board_auth_account_not_found",
|
|
83
83
|
"board_auth_email_taken",
|
|
84
|
+
"board_auth_email_undeliverable",
|
|
84
85
|
"board_auth_invalid_credentials",
|
|
85
86
|
"board_auth_invalid_token",
|
|
86
87
|
"board_auth_registration_disabled",
|
|
@@ -199,6 +200,8 @@ var BOARD_API_ERROR_CODES = [
|
|
|
199
200
|
"employer_not_member",
|
|
200
201
|
"employer_payment_required",
|
|
201
202
|
"employer_pipeline_stage_not_found",
|
|
203
|
+
"company_custom_field_not_found",
|
|
204
|
+
"company_custom_field_not_editable",
|
|
202
205
|
"employer_member_not_found",
|
|
203
206
|
"employer_invite_not_found",
|
|
204
207
|
"not_company_admin",
|
|
@@ -446,7 +449,7 @@ async function clearSession(storage) {
|
|
|
446
449
|
}
|
|
447
450
|
|
|
448
451
|
// src/version.ts
|
|
449
|
-
var SDK_VERSION = "4.
|
|
452
|
+
var SDK_VERSION = "4.70.0";
|
|
450
453
|
|
|
451
454
|
// src/client.ts
|
|
452
455
|
function isRawBody(body) {
|
|
@@ -2262,7 +2265,10 @@ function meNamespace(client) {
|
|
|
2262
2265
|
{ ...options, method: "PATCH", body }
|
|
2263
2266
|
);
|
|
2264
2267
|
},
|
|
2265
|
-
/**
|
|
2268
|
+
/**
|
|
2269
|
+
* Retrieve profile custom fields for a company I belong to, with the
|
|
2270
|
+
* saved files of upload fields (`customFieldMedia`).
|
|
2271
|
+
*/
|
|
2266
2272
|
retrieveCustomFields(slug, options) {
|
|
2267
2273
|
return client.fetch(
|
|
2268
2274
|
`/me/companies/${encodeURIComponent(slug)}/custom-fields`,
|
|
@@ -2276,6 +2282,26 @@ function meNamespace(client) {
|
|
|
2276
2282
|
{ ...options, method: "PATCH", body }
|
|
2277
2283
|
);
|
|
2278
2284
|
},
|
|
2285
|
+
/**
|
|
2286
|
+
* Upload one file to an owner-editable `image_gallery` or `file` field
|
|
2287
|
+
* of a company I belong to (up to 10 MB; galleries take JPEG, PNG, WebP
|
|
2288
|
+
* or GIF). The file is a draft until its `id` is saved to the field with
|
|
2289
|
+
* `updateCustomFields`, as the ordered list of file IDs.
|
|
2290
|
+
*
|
|
2291
|
+
* @example
|
|
2292
|
+
* const image = await board.me.companies.uploadCustomFieldFile('acme', 'office_photos', file);
|
|
2293
|
+
* await board.me.companies.updateCustomFields('acme', {
|
|
2294
|
+
* values: { office_photos: [...savedIds, image.id] },
|
|
2295
|
+
* });
|
|
2296
|
+
*/
|
|
2297
|
+
uploadCustomFieldFile(slug, fieldKey, file, options) {
|
|
2298
|
+
const form = new FormData();
|
|
2299
|
+
form.append("file", file);
|
|
2300
|
+
return client.fetch(
|
|
2301
|
+
`/me/companies/${encodeURIComponent(slug)}/custom-fields/${encodeURIComponent(fieldKey)}/files`,
|
|
2302
|
+
{ ...options, method: "POST", body: form }
|
|
2303
|
+
);
|
|
2304
|
+
},
|
|
2279
2305
|
/**
|
|
2280
2306
|
* Delete a company I admin (soft-delete cascade + Forager
|
|
2281
2307
|
* exclusion). Resolves void on success (204).
|
|
@@ -2358,11 +2384,17 @@ function meNamespace(client) {
|
|
|
2358
2384
|
* membership on this board; 409 `membership_seat_taken` when the company
|
|
2359
2385
|
* already holds one (or has an invoice pending).
|
|
2360
2386
|
*
|
|
2387
|
+
* By default every completed checkout redirects to `returnPath`. Pass
|
|
2388
|
+
* `redirectOnCompletion: 'if_required'` to keep a card buyer on the page:
|
|
2389
|
+
* Stripe.js calls `onComplete` instead, and only a payment method that
|
|
2390
|
+
* needs a redirect returns to `returnPath`.
|
|
2391
|
+
*
|
|
2361
2392
|
* @example
|
|
2362
2393
|
* const kit = await board.me.companies.startMembershipCheckout('acme', {
|
|
2363
2394
|
* planId,
|
|
2364
2395
|
* returnPath: '/memberships',
|
|
2365
2396
|
* colorMode: 'light',
|
|
2397
|
+
* redirectOnCompletion: 'if_required',
|
|
2366
2398
|
* });
|
|
2367
2399
|
*/
|
|
2368
2400
|
startMembershipCheckout(slug, body, options) {
|
|
@@ -2647,7 +2679,9 @@ function meNamespace(client) {
|
|
|
2647
2679
|
* My reusable billing options for a company — active subscription slots +
|
|
2648
2680
|
* remaining pre-purchased (bundle) order slots, the options a held draft
|
|
2649
2681
|
* can be published with at no new charge (the checkout `billing.type:
|
|
2650
|
-
* 'order' | 'subscription'`).
|
|
2682
|
+
* 'order' | 'subscription'`). `capabilities` says whether the company
|
|
2683
|
+
* can post at all (`canPost`), so a form can show a members-only gate
|
|
2684
|
+
* before the job is written.
|
|
2651
2685
|
*/
|
|
2652
2686
|
billingOptions: {
|
|
2653
2687
|
/**
|
|
@@ -4794,6 +4828,29 @@ function createBoardClient(options) {
|
|
|
4794
4828
|
seo(options2) {
|
|
4795
4829
|
return client.fetch("/seo", options2);
|
|
4796
4830
|
},
|
|
4831
|
+
/**
|
|
4832
|
+
* Sign an address up for the board's email from a newsletter form. Sends
|
|
4833
|
+
* a confirmation email; nothing is granted until the person clicks it.
|
|
4834
|
+
* Always resolves `{ status: 'submitted', sendingPaused }`. Limited to 3
|
|
4835
|
+
* a minute per address and 10 requests a minute per IP; on a builder
|
|
4836
|
+
* site Cavuno hosts the IP limit counts each visitor, plus 6 sign-ups a
|
|
4837
|
+
* minute per visitor (429 `rate_limited`).
|
|
4838
|
+
*
|
|
4839
|
+
* @example
|
|
4840
|
+
* await board.subscribe({
|
|
4841
|
+
* email,
|
|
4842
|
+
* consent: true,
|
|
4843
|
+
* consentText: 'Send me news and offers from Acme Jobs.',
|
|
4844
|
+
* source: 'blog-footer',
|
|
4845
|
+
* });
|
|
4846
|
+
*/
|
|
4847
|
+
subscribe(input, options2) {
|
|
4848
|
+
return client.fetch("/subscribe", {
|
|
4849
|
+
...options2,
|
|
4850
|
+
method: "POST",
|
|
4851
|
+
body: input
|
|
4852
|
+
});
|
|
4853
|
+
},
|
|
4797
4854
|
jobs: jobsNamespace(client),
|
|
4798
4855
|
embed: embedNamespace(client),
|
|
4799
4856
|
companies: companiesNamespace(client),
|
package/dist/index.mjs
CHANGED
|
@@ -28,7 +28,7 @@ import {
|
|
|
28
28
|
isSsoRequired,
|
|
29
29
|
isUnauthorized,
|
|
30
30
|
isValidationError
|
|
31
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-UIKN2ERI.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.
|
|
52
|
+
var SDK_VERSION = "4.70.0";
|
|
53
53
|
|
|
54
54
|
// src/client.ts
|
|
55
55
|
function isRawBody(body) {
|
|
@@ -1862,7 +1862,10 @@ function meNamespace(client) {
|
|
|
1862
1862
|
{ ...options, method: "PATCH", body }
|
|
1863
1863
|
);
|
|
1864
1864
|
},
|
|
1865
|
-
/**
|
|
1865
|
+
/**
|
|
1866
|
+
* Retrieve profile custom fields for a company I belong to, with the
|
|
1867
|
+
* saved files of upload fields (`customFieldMedia`).
|
|
1868
|
+
*/
|
|
1866
1869
|
retrieveCustomFields(slug, options) {
|
|
1867
1870
|
return client.fetch(
|
|
1868
1871
|
`/me/companies/${encodeURIComponent(slug)}/custom-fields`,
|
|
@@ -1876,6 +1879,26 @@ function meNamespace(client) {
|
|
|
1876
1879
|
{ ...options, method: "PATCH", body }
|
|
1877
1880
|
);
|
|
1878
1881
|
},
|
|
1882
|
+
/**
|
|
1883
|
+
* Upload one file to an owner-editable `image_gallery` or `file` field
|
|
1884
|
+
* of a company I belong to (up to 10 MB; galleries take JPEG, PNG, WebP
|
|
1885
|
+
* or GIF). The file is a draft until its `id` is saved to the field with
|
|
1886
|
+
* `updateCustomFields`, as the ordered list of file IDs.
|
|
1887
|
+
*
|
|
1888
|
+
* @example
|
|
1889
|
+
* const image = await board.me.companies.uploadCustomFieldFile('acme', 'office_photos', file);
|
|
1890
|
+
* await board.me.companies.updateCustomFields('acme', {
|
|
1891
|
+
* values: { office_photos: [...savedIds, image.id] },
|
|
1892
|
+
* });
|
|
1893
|
+
*/
|
|
1894
|
+
uploadCustomFieldFile(slug, fieldKey, file, options) {
|
|
1895
|
+
const form = new FormData();
|
|
1896
|
+
form.append("file", file);
|
|
1897
|
+
return client.fetch(
|
|
1898
|
+
`/me/companies/${encodeURIComponent(slug)}/custom-fields/${encodeURIComponent(fieldKey)}/files`,
|
|
1899
|
+
{ ...options, method: "POST", body: form }
|
|
1900
|
+
);
|
|
1901
|
+
},
|
|
1879
1902
|
/**
|
|
1880
1903
|
* Delete a company I admin (soft-delete cascade + Forager
|
|
1881
1904
|
* exclusion). Resolves void on success (204).
|
|
@@ -1958,11 +1981,17 @@ function meNamespace(client) {
|
|
|
1958
1981
|
* membership on this board; 409 `membership_seat_taken` when the company
|
|
1959
1982
|
* already holds one (or has an invoice pending).
|
|
1960
1983
|
*
|
|
1984
|
+
* By default every completed checkout redirects to `returnPath`. Pass
|
|
1985
|
+
* `redirectOnCompletion: 'if_required'` to keep a card buyer on the page:
|
|
1986
|
+
* Stripe.js calls `onComplete` instead, and only a payment method that
|
|
1987
|
+
* needs a redirect returns to `returnPath`.
|
|
1988
|
+
*
|
|
1961
1989
|
* @example
|
|
1962
1990
|
* const kit = await board.me.companies.startMembershipCheckout('acme', {
|
|
1963
1991
|
* planId,
|
|
1964
1992
|
* returnPath: '/memberships',
|
|
1965
1993
|
* colorMode: 'light',
|
|
1994
|
+
* redirectOnCompletion: 'if_required',
|
|
1966
1995
|
* });
|
|
1967
1996
|
*/
|
|
1968
1997
|
startMembershipCheckout(slug, body, options) {
|
|
@@ -2247,7 +2276,9 @@ function meNamespace(client) {
|
|
|
2247
2276
|
* My reusable billing options for a company — active subscription slots +
|
|
2248
2277
|
* remaining pre-purchased (bundle) order slots, the options a held draft
|
|
2249
2278
|
* can be published with at no new charge (the checkout `billing.type:
|
|
2250
|
-
* 'order' | 'subscription'`).
|
|
2279
|
+
* 'order' | 'subscription'`). `capabilities` says whether the company
|
|
2280
|
+
* can post at all (`canPost`), so a form can show a members-only gate
|
|
2281
|
+
* before the job is written.
|
|
2251
2282
|
*/
|
|
2252
2283
|
billingOptions: {
|
|
2253
2284
|
/**
|
|
@@ -4364,6 +4395,29 @@ function createBoardClient(options) {
|
|
|
4364
4395
|
seo(options2) {
|
|
4365
4396
|
return client.fetch("/seo", options2);
|
|
4366
4397
|
},
|
|
4398
|
+
/**
|
|
4399
|
+
* Sign an address up for the board's email from a newsletter form. Sends
|
|
4400
|
+
* a confirmation email; nothing is granted until the person clicks it.
|
|
4401
|
+
* Always resolves `{ status: 'submitted', sendingPaused }`. Limited to 3
|
|
4402
|
+
* a minute per address and 10 requests a minute per IP; on a builder
|
|
4403
|
+
* site Cavuno hosts the IP limit counts each visitor, plus 6 sign-ups a
|
|
4404
|
+
* minute per visitor (429 `rate_limited`).
|
|
4405
|
+
*
|
|
4406
|
+
* @example
|
|
4407
|
+
* await board.subscribe({
|
|
4408
|
+
* email,
|
|
4409
|
+
* consent: true,
|
|
4410
|
+
* consentText: 'Send me news and offers from Acme Jobs.',
|
|
4411
|
+
* source: 'blog-footer',
|
|
4412
|
+
* });
|
|
4413
|
+
*/
|
|
4414
|
+
subscribe(input, options2) {
|
|
4415
|
+
return client.fetch("/subscribe", {
|
|
4416
|
+
...options2,
|
|
4417
|
+
method: "POST",
|
|
4418
|
+
body: input
|
|
4419
|
+
});
|
|
4420
|
+
},
|
|
4367
4421
|
jobs: jobsNamespace(client),
|
|
4368
4422
|
embed: embedNamespace(client),
|
|
4369
4423
|
companies: companiesNamespace(client),
|
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.",
|