@cavuno/board 1.38.0 → 1.40.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/README.md +7 -0
- package/dist/{jobs-DMH3Ytoq.d.mts → _spec-DRbgPIlN.d.mts} +404 -96
- package/dist/{jobs-DMH3Ytoq.d.ts → _spec-DRbgPIlN.d.ts} +404 -96
- package/dist/bin.mjs +242 -18
- package/dist/{board-CBry4f7H.d.mts → board-BxPUtrOl.d.ts} +1 -1
- package/dist/{board-tV-zcaHs.d.ts → board-DCiNpgFf.d.mts} +1 -1
- package/dist/doctor.js +238 -14
- package/dist/doctor.mjs +238 -14
- package/dist/filters.d.mts +18 -4
- package/dist/filters.d.ts +18 -4
- package/dist/filters.js +17 -0
- package/dist/filters.mjs +17 -0
- package/dist/format.d.mts +3 -2
- package/dist/format.d.ts +3 -2
- package/dist/index.d.mts +62 -73
- package/dist/index.d.ts +62 -73
- package/dist/index.js +71 -1
- package/dist/index.mjs +71 -1
- package/dist/jobs-DAGAVHQL.d.ts +105 -0
- package/dist/jobs-DhePKSRe.d.mts +105 -0
- package/dist/{salaries-CaGlcCC6.d.ts → salaries-D6SUVMmt.d.mts} +2 -1
- package/dist/{salaries-01g4wK8y.d.mts → salaries-cqb78kg0.d.ts} +2 -1
- package/dist/search-BalPAS0P.d.ts +81 -0
- package/dist/search-DYUQzCq_.d.mts +81 -0
- package/dist/seo.d.mts +4 -3
- package/dist/seo.d.ts +4 -3
- package/dist/server.d.mts +56 -4
- package/dist/server.d.ts +56 -4
- package/dist/server.js +41 -0
- package/dist/server.mjs +41 -0
- package/dist/sitemap.d.mts +5 -3
- package/dist/sitemap.d.ts +5 -3
- package/dist/suggest.d.mts +70 -0
- package/dist/suggest.d.ts +70 -0
- package/dist/suggest.js +165 -0
- package/dist/suggest.mjs +144 -0
- package/dist/theme.d.mts +49 -1
- package/dist/theme.d.ts +49 -1
- package/dist/theme.js +60 -26
- package/dist/theme.mjs +60 -26
- package/package.json +11 -1
- package/skills/cavuno-board-filters/SKILL.md +11 -4
- package/skills/cavuno-board-jobs/SKILL.md +18 -2
- package/skills/cavuno-board-suggest/SKILL.md +119 -0
- package/skills/manifest.json +9 -2
package/dist/index.mjs
CHANGED
|
@@ -265,7 +265,7 @@ async function clearSession(storage) {
|
|
|
265
265
|
}
|
|
266
266
|
|
|
267
267
|
// src/version.ts
|
|
268
|
-
var SDK_VERSION = "1.
|
|
268
|
+
var SDK_VERSION = "1.40.0";
|
|
269
269
|
|
|
270
270
|
// src/client.ts
|
|
271
271
|
function isRawBody(body) {
|
|
@@ -1351,6 +1351,20 @@ function meNamespace(client) {
|
|
|
1351
1351
|
{ ...options, method: "DELETE" }
|
|
1352
1352
|
);
|
|
1353
1353
|
},
|
|
1354
|
+
/**
|
|
1355
|
+
* Retrieve my full editable company profile (summary, socials, logo,
|
|
1356
|
+
* description) — the read half of `update`, for pre-populating an edit
|
|
1357
|
+
* form. Requires an approved membership.
|
|
1358
|
+
*
|
|
1359
|
+
* @example
|
|
1360
|
+
* const company = await board.me.companies.retrieve('acme');
|
|
1361
|
+
*/
|
|
1362
|
+
retrieve(slug, options) {
|
|
1363
|
+
return client.fetch(
|
|
1364
|
+
`/me/companies/${encodeURIComponent(slug)}`,
|
|
1365
|
+
options
|
|
1366
|
+
);
|
|
1367
|
+
},
|
|
1354
1368
|
/**
|
|
1355
1369
|
* Edit my company profile (merge-patch — omitted fields stay
|
|
1356
1370
|
* unchanged). Requires an approved membership. Returns the company.
|
|
@@ -1364,6 +1378,22 @@ function meNamespace(client) {
|
|
|
1364
1378
|
{ ...options, method: "PATCH", body }
|
|
1365
1379
|
);
|
|
1366
1380
|
},
|
|
1381
|
+
/**
|
|
1382
|
+
* Upload + attach my company logo (JPEG/PNG/WebP/GIF, ≤2 MB) via a single
|
|
1383
|
+
* multipart POST. Requires an approved membership. Returns the updated
|
|
1384
|
+
* company with its new `logoUrl`.
|
|
1385
|
+
*
|
|
1386
|
+
* @example
|
|
1387
|
+
* const company = await board.me.companies.uploadLogo('acme', file);
|
|
1388
|
+
*/
|
|
1389
|
+
uploadLogo(slug, file, options) {
|
|
1390
|
+
const form = new FormData();
|
|
1391
|
+
form.append("file", file);
|
|
1392
|
+
return client.fetch(
|
|
1393
|
+
`/me/companies/${encodeURIComponent(slug)}/logo`,
|
|
1394
|
+
{ ...options, method: "POST", body: form }
|
|
1395
|
+
);
|
|
1396
|
+
},
|
|
1367
1397
|
/** The work-email verification state machine for a pending claim. */
|
|
1368
1398
|
workEmail: {
|
|
1369
1399
|
/**
|
|
@@ -1689,6 +1719,25 @@ function meNamespace(client) {
|
|
|
1689
1719
|
}
|
|
1690
1720
|
}
|
|
1691
1721
|
},
|
|
1722
|
+
/**
|
|
1723
|
+
* The viewer's talent entitlement on this board (CAV-243) — "does this
|
|
1724
|
+
* employer have talent access?" for gating a Message-vs-upsell CTA.
|
|
1725
|
+
* Candidates and unaffiliated viewers get `hasTalentAccess: false`.
|
|
1726
|
+
*
|
|
1727
|
+
* @example
|
|
1728
|
+
* const { hasTalentAccess } = await board.me.talentAccess.retrieve();
|
|
1729
|
+
*/
|
|
1730
|
+
talentAccess: {
|
|
1731
|
+
/**
|
|
1732
|
+
* Retrieve the viewer's talent entitlement. Never cache — per-user.
|
|
1733
|
+
*
|
|
1734
|
+
* @example
|
|
1735
|
+
* const access = await board.me.talentAccess.retrieve();
|
|
1736
|
+
*/
|
|
1737
|
+
retrieve(options) {
|
|
1738
|
+
return client.fetch("/me/talent-access", options);
|
|
1739
|
+
}
|
|
1740
|
+
},
|
|
1692
1741
|
/**
|
|
1693
1742
|
* The authenticated board user's job-alert preferences (ADR-0053) —
|
|
1694
1743
|
* a collection (up to 10). Creating one is active immediately (no
|
|
@@ -2431,6 +2480,26 @@ function salariesNamespace(client) {
|
|
|
2431
2480
|
};
|
|
2432
2481
|
}
|
|
2433
2482
|
|
|
2483
|
+
// src/namespaces/search.ts
|
|
2484
|
+
function searchNamespace(client) {
|
|
2485
|
+
return {
|
|
2486
|
+
/**
|
|
2487
|
+
* GET /search/suggest — federated keyword suggestions (companies +
|
|
2488
|
+
* taxonomy terms), one interleaved server-ranked list. Order is the
|
|
2489
|
+
* contract: do not re-sort.
|
|
2490
|
+
*
|
|
2491
|
+
* @example
|
|
2492
|
+
* const { items } = await board.search.suggest({ q: 'acme', limit: 10 });
|
|
2493
|
+
*/
|
|
2494
|
+
suggest(query, options) {
|
|
2495
|
+
return client.fetch("/search/suggest", {
|
|
2496
|
+
...options,
|
|
2497
|
+
query
|
|
2498
|
+
});
|
|
2499
|
+
}
|
|
2500
|
+
};
|
|
2501
|
+
}
|
|
2502
|
+
|
|
2434
2503
|
// src/namespaces/talent.ts
|
|
2435
2504
|
function talentNamespace(client) {
|
|
2436
2505
|
return {
|
|
@@ -2652,6 +2721,7 @@ function createBoardClient(options) {
|
|
|
2652
2721
|
me: meNamespace(client),
|
|
2653
2722
|
password: passwordNamespace(client),
|
|
2654
2723
|
taxonomy: taxonomyNamespace(client),
|
|
2724
|
+
search: searchNamespace(client),
|
|
2655
2725
|
redirects: redirectsNamespace(client),
|
|
2656
2726
|
jobAlerts: jobAlertsNamespace(client),
|
|
2657
2727
|
jobPosting: jobPostingNamespace(client),
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { S as Schemas } from './_spec-DRbgPIlN.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Stripe-shaped success envelopes (`01-conventions.md` §5.1). The
|
|
5
|
+
* server MAY add top-level fields; consumers MUST ignore unknown
|
|
6
|
+
* fields.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Optional offset-pagination metadata generated from the Board API contract.
|
|
10
|
+
* `nextCursor` is preserved alongside for forward cursor iteration.
|
|
11
|
+
*/
|
|
12
|
+
type OffsetPagination = Schemas['OffsetPagination'];
|
|
13
|
+
/** @deprecated Use `OffsetPagination`. */
|
|
14
|
+
type StorefrontPagination = OffsetPagination;
|
|
15
|
+
/** @deprecated Use `OffsetPagination`. */
|
|
16
|
+
type JobCatalogPagination = OffsetPagination;
|
|
17
|
+
type ListEnvelope<T> = OffsetPagination & {
|
|
18
|
+
object: 'list';
|
|
19
|
+
url: string;
|
|
20
|
+
hasMore: boolean;
|
|
21
|
+
/** `null` when `hasMore` is false — always present, never undefined. */
|
|
22
|
+
nextCursor: string | null;
|
|
23
|
+
data: T[];
|
|
24
|
+
};
|
|
25
|
+
type SearchEnvelope<T> = OffsetPagination & {
|
|
26
|
+
object: 'search_result';
|
|
27
|
+
url: string;
|
|
28
|
+
hasMore: boolean;
|
|
29
|
+
nextCursor: string | null;
|
|
30
|
+
data: T[];
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
type PublicJob = Schemas['PublicJob'];
|
|
34
|
+
type PublicJobCard = Schemas['PublicJobCard'];
|
|
35
|
+
/**
|
|
36
|
+
* A job's opaque, display-only custom-field values (CAV-294), keyed by each
|
|
37
|
+
* field's `key`. Resolve labels via the board's `CustomFieldDefinition`s
|
|
38
|
+
* (`board.context().customFields`).
|
|
39
|
+
*/
|
|
40
|
+
type CustomFieldValues = PublicJob['customFieldValues'];
|
|
41
|
+
type CustomFieldValue = CustomFieldValues[string];
|
|
42
|
+
type JobCompany = Schemas['JobCompany'];
|
|
43
|
+
type OfficeLocation = Schemas['JobOfficeLocation'];
|
|
44
|
+
type RemoteOption = NonNullable<PublicJob['remoteOption']>;
|
|
45
|
+
type EmploymentType = NonNullable<PublicJob['employmentType']>;
|
|
46
|
+
type Seniority = NonNullable<PublicJob['seniority']>;
|
|
47
|
+
/** Candidate-facing result ordering (ADR-0048); `relevance` is the default. */
|
|
48
|
+
type JobSort = NonNullable<Schemas['PublicSearchJobsBody']['sort']>;
|
|
49
|
+
type EducationRequirement = PublicJob['educationRequirements'][number];
|
|
50
|
+
type RemotePermit = PublicJob['remotePermits'][number];
|
|
51
|
+
type RemoteTimezone = PublicJob['remoteTimezones'][number];
|
|
52
|
+
/**
|
|
53
|
+
* Derived suggestion on a browse list (ADR-0037 §8): jobs surface `category`
|
|
54
|
+
* and `skill` terms; the companies list surfaces `market` terms.
|
|
55
|
+
*/
|
|
56
|
+
interface RelatedSearch {
|
|
57
|
+
type: 'category' | 'skill' | 'market';
|
|
58
|
+
slug: string;
|
|
59
|
+
term: string;
|
|
60
|
+
count: number;
|
|
61
|
+
}
|
|
62
|
+
/** The browse list envelope — `PublicJobCard`s + job catalog pagination + `relatedSearches`. */
|
|
63
|
+
type JobCardListEnvelope = ListEnvelope<PublicJobCard> & {
|
|
64
|
+
relatedSearches?: RelatedSearch[];
|
|
65
|
+
};
|
|
66
|
+
/** The search envelope — `PublicJobCard`s + job catalog pagination. */
|
|
67
|
+
type JobCardSearchEnvelope = SearchEnvelope<PublicJobCard>;
|
|
68
|
+
type JobsListQuery = {
|
|
69
|
+
cursor?: string;
|
|
70
|
+
/** 1–100. */
|
|
71
|
+
limit?: number;
|
|
72
|
+
/** Job catalog page offset; takes precedence over `cursor`. `offset + limit` ≤ 10,000. */
|
|
73
|
+
offset?: number;
|
|
74
|
+
/** Repeated param (up to 10) — OR-matched. Repeat `companyId` per value. */
|
|
75
|
+
companyId?: string[];
|
|
76
|
+
/**
|
|
77
|
+
* Company slugs (the public URL identity). Repeat for multiple values
|
|
78
|
+
* (up to 10). Resolved server-side; unknown slugs are dropped. Combined
|
|
79
|
+
* with `companyId` as a union. If the provided company filter resolves
|
|
80
|
+
* to no known companies, the result is empty.
|
|
81
|
+
*/
|
|
82
|
+
companySlug?: string[];
|
|
83
|
+
remoteOption?: RemoteOption[];
|
|
84
|
+
employmentType?: EmploymentType[];
|
|
85
|
+
seniority?: Seniority[];
|
|
86
|
+
/** Result ordering (ADR-0048). Absent ⇒ `relevance` (the featured-ranked browse). */
|
|
87
|
+
sort?: JobSort;
|
|
88
|
+
/** Place slug for a geo radius search; unresolvable slugs are ignored. */
|
|
89
|
+
location?: string;
|
|
90
|
+
/** Radius in km around `location` (10–250; default 50). */
|
|
91
|
+
radius?: number;
|
|
92
|
+
/** Category slug seed (the `/jobs/[keyword]` page) — server resolves it to the English source name; unresolvable → 404. */
|
|
93
|
+
category?: string;
|
|
94
|
+
/** Skill slug seed (the `/jobs/skills/[skill]` page) — server-resolved; unresolvable → 404. */
|
|
95
|
+
skill?: string;
|
|
96
|
+
/** Sparse fieldset (Medusa-style `+field`). Only `'+description'` is supported — adds `description` to each card. */
|
|
97
|
+
fields?: string;
|
|
98
|
+
};
|
|
99
|
+
type JobsSimilarQuery = {
|
|
100
|
+
/** How many similar jobs to return (1–20; default 5). */
|
|
101
|
+
limit?: number;
|
|
102
|
+
};
|
|
103
|
+
type JobsSearchBody = Schemas['PublicSearchJobsBody'];
|
|
104
|
+
|
|
105
|
+
export type { CustomFieldValues as C, EmploymentType as E, JobSort as J, ListEnvelope as L, OfficeLocation as O, PublicJob as P, RemoteOption as R, Seniority as S, PublicJobCard as a, JobsListQuery as b, JobCardListEnvelope as c, JobsSearchBody as d, JobCardSearchEnvelope as e, JobsSimilarQuery as f, SearchEnvelope as g, CustomFieldValue as h, EducationRequirement as i, JobCatalogPagination as j, JobCompany as k, OffsetPagination as l, RelatedSearch as m, RemotePermit as n, RemoteTimezone as o, StorefrontPagination as p };
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { S as Schemas } from './_spec-DRbgPIlN.mjs';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Stripe-shaped success envelopes (`01-conventions.md` §5.1). The
|
|
5
|
+
* server MAY add top-level fields; consumers MUST ignore unknown
|
|
6
|
+
* fields.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Optional offset-pagination metadata generated from the Board API contract.
|
|
10
|
+
* `nextCursor` is preserved alongside for forward cursor iteration.
|
|
11
|
+
*/
|
|
12
|
+
type OffsetPagination = Schemas['OffsetPagination'];
|
|
13
|
+
/** @deprecated Use `OffsetPagination`. */
|
|
14
|
+
type StorefrontPagination = OffsetPagination;
|
|
15
|
+
/** @deprecated Use `OffsetPagination`. */
|
|
16
|
+
type JobCatalogPagination = OffsetPagination;
|
|
17
|
+
type ListEnvelope<T> = OffsetPagination & {
|
|
18
|
+
object: 'list';
|
|
19
|
+
url: string;
|
|
20
|
+
hasMore: boolean;
|
|
21
|
+
/** `null` when `hasMore` is false — always present, never undefined. */
|
|
22
|
+
nextCursor: string | null;
|
|
23
|
+
data: T[];
|
|
24
|
+
};
|
|
25
|
+
type SearchEnvelope<T> = OffsetPagination & {
|
|
26
|
+
object: 'search_result';
|
|
27
|
+
url: string;
|
|
28
|
+
hasMore: boolean;
|
|
29
|
+
nextCursor: string | null;
|
|
30
|
+
data: T[];
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
type PublicJob = Schemas['PublicJob'];
|
|
34
|
+
type PublicJobCard = Schemas['PublicJobCard'];
|
|
35
|
+
/**
|
|
36
|
+
* A job's opaque, display-only custom-field values (CAV-294), keyed by each
|
|
37
|
+
* field's `key`. Resolve labels via the board's `CustomFieldDefinition`s
|
|
38
|
+
* (`board.context().customFields`).
|
|
39
|
+
*/
|
|
40
|
+
type CustomFieldValues = PublicJob['customFieldValues'];
|
|
41
|
+
type CustomFieldValue = CustomFieldValues[string];
|
|
42
|
+
type JobCompany = Schemas['JobCompany'];
|
|
43
|
+
type OfficeLocation = Schemas['JobOfficeLocation'];
|
|
44
|
+
type RemoteOption = NonNullable<PublicJob['remoteOption']>;
|
|
45
|
+
type EmploymentType = NonNullable<PublicJob['employmentType']>;
|
|
46
|
+
type Seniority = NonNullable<PublicJob['seniority']>;
|
|
47
|
+
/** Candidate-facing result ordering (ADR-0048); `relevance` is the default. */
|
|
48
|
+
type JobSort = NonNullable<Schemas['PublicSearchJobsBody']['sort']>;
|
|
49
|
+
type EducationRequirement = PublicJob['educationRequirements'][number];
|
|
50
|
+
type RemotePermit = PublicJob['remotePermits'][number];
|
|
51
|
+
type RemoteTimezone = PublicJob['remoteTimezones'][number];
|
|
52
|
+
/**
|
|
53
|
+
* Derived suggestion on a browse list (ADR-0037 §8): jobs surface `category`
|
|
54
|
+
* and `skill` terms; the companies list surfaces `market` terms.
|
|
55
|
+
*/
|
|
56
|
+
interface RelatedSearch {
|
|
57
|
+
type: 'category' | 'skill' | 'market';
|
|
58
|
+
slug: string;
|
|
59
|
+
term: string;
|
|
60
|
+
count: number;
|
|
61
|
+
}
|
|
62
|
+
/** The browse list envelope — `PublicJobCard`s + job catalog pagination + `relatedSearches`. */
|
|
63
|
+
type JobCardListEnvelope = ListEnvelope<PublicJobCard> & {
|
|
64
|
+
relatedSearches?: RelatedSearch[];
|
|
65
|
+
};
|
|
66
|
+
/** The search envelope — `PublicJobCard`s + job catalog pagination. */
|
|
67
|
+
type JobCardSearchEnvelope = SearchEnvelope<PublicJobCard>;
|
|
68
|
+
type JobsListQuery = {
|
|
69
|
+
cursor?: string;
|
|
70
|
+
/** 1–100. */
|
|
71
|
+
limit?: number;
|
|
72
|
+
/** Job catalog page offset; takes precedence over `cursor`. `offset + limit` ≤ 10,000. */
|
|
73
|
+
offset?: number;
|
|
74
|
+
/** Repeated param (up to 10) — OR-matched. Repeat `companyId` per value. */
|
|
75
|
+
companyId?: string[];
|
|
76
|
+
/**
|
|
77
|
+
* Company slugs (the public URL identity). Repeat for multiple values
|
|
78
|
+
* (up to 10). Resolved server-side; unknown slugs are dropped. Combined
|
|
79
|
+
* with `companyId` as a union. If the provided company filter resolves
|
|
80
|
+
* to no known companies, the result is empty.
|
|
81
|
+
*/
|
|
82
|
+
companySlug?: string[];
|
|
83
|
+
remoteOption?: RemoteOption[];
|
|
84
|
+
employmentType?: EmploymentType[];
|
|
85
|
+
seniority?: Seniority[];
|
|
86
|
+
/** Result ordering (ADR-0048). Absent ⇒ `relevance` (the featured-ranked browse). */
|
|
87
|
+
sort?: JobSort;
|
|
88
|
+
/** Place slug for a geo radius search; unresolvable slugs are ignored. */
|
|
89
|
+
location?: string;
|
|
90
|
+
/** Radius in km around `location` (10–250; default 50). */
|
|
91
|
+
radius?: number;
|
|
92
|
+
/** Category slug seed (the `/jobs/[keyword]` page) — server resolves it to the English source name; unresolvable → 404. */
|
|
93
|
+
category?: string;
|
|
94
|
+
/** Skill slug seed (the `/jobs/skills/[skill]` page) — server-resolved; unresolvable → 404. */
|
|
95
|
+
skill?: string;
|
|
96
|
+
/** Sparse fieldset (Medusa-style `+field`). Only `'+description'` is supported — adds `description` to each card. */
|
|
97
|
+
fields?: string;
|
|
98
|
+
};
|
|
99
|
+
type JobsSimilarQuery = {
|
|
100
|
+
/** How many similar jobs to return (1–20; default 5). */
|
|
101
|
+
limit?: number;
|
|
102
|
+
};
|
|
103
|
+
type JobsSearchBody = Schemas['PublicSearchJobsBody'];
|
|
104
|
+
|
|
105
|
+
export type { CustomFieldValues as C, EmploymentType as E, JobSort as J, ListEnvelope as L, OfficeLocation as O, PublicJob as P, RemoteOption as R, Seniority as S, PublicJobCard as a, JobsListQuery as b, JobCardListEnvelope as c, JobsSearchBody as d, JobCardSearchEnvelope as e, JobsSimilarQuery as f, SearchEnvelope as g, CustomFieldValue as h, EducationRequirement as i, JobCatalogPagination as j, JobCompany as k, OffsetPagination as l, RelatedSearch as m, RemotePermit as n, RemoteTimezone as o, StorefrontPagination as p };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { S as Schemas } from './_spec-DRbgPIlN.mjs';
|
|
2
|
+
import { L as ListEnvelope, m as RelatedSearch } from './jobs-DhePKSRe.mjs';
|
|
2
3
|
|
|
3
4
|
/** Author shape embedded on posts (no `object` discriminator). */
|
|
4
5
|
type BlogAuthorEmbed = Schemas['PublicBlogAuthorEmbed'];
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { S as Schemas } from './_spec-DRbgPIlN.js';
|
|
2
|
+
import { L as ListEnvelope, m as RelatedSearch } from './jobs-DAGAVHQL.js';
|
|
2
3
|
|
|
3
4
|
/** Author shape embedded on posts (no `object` discriminator). */
|
|
4
5
|
type BlogAuthorEmbed = Schemas['PublicBlogAuthorEmbed'];
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { S as Schemas } from './_spec-DRbgPIlN.js';
|
|
2
|
+
|
|
3
|
+
type Awaitable<T> = T | Promise<T>;
|
|
4
|
+
/**
|
|
5
|
+
* Async token storage. The SDK reads the access token from storage on
|
|
6
|
+
* every request (fresh-token rule); auth methods write/clear the pair.
|
|
7
|
+
*/
|
|
8
|
+
interface CustomStorage {
|
|
9
|
+
getItem(key: string): Awaitable<string | null>;
|
|
10
|
+
setItem(key: string, value: string): Awaitable<void>;
|
|
11
|
+
removeItem(key: string): Awaitable<void>;
|
|
12
|
+
}
|
|
13
|
+
type StorageMode = 'memory' | 'nostore' | 'local' | 'session' | CustomStorage;
|
|
14
|
+
declare const ACCESS_TOKEN_KEY = "cavuno_board_access_token";
|
|
15
|
+
declare const REFRESH_TOKEN_KEY = "cavuno_board_refresh_token";
|
|
16
|
+
/** Board-password access grant — sent as `X-Board-Access` to pass the wall. */
|
|
17
|
+
declare const BOARD_ACCESS_GRANT_KEY = "cavuno_board_access_grant";
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* The request handed to `onRequest` and `fetch`. `onRequest` may
|
|
21
|
+
* mutate or replace it wholesale (locale headers, URL rewrites);
|
|
22
|
+
* whatever it returns is what gets fetched.
|
|
23
|
+
*/
|
|
24
|
+
interface BoardRequest {
|
|
25
|
+
/** Fully built URL, query string included. */
|
|
26
|
+
url: string;
|
|
27
|
+
/** Final RequestInit: method, Headers instance, serialized body, plus passthrough keys (`signal`, `cache`, `next`, `cf`, …). */
|
|
28
|
+
init: RequestInit;
|
|
29
|
+
}
|
|
30
|
+
interface Logger {
|
|
31
|
+
debug(message: string): void;
|
|
32
|
+
error(message: string): void;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Per-call options on every SDK method. Everything besides `body` and
|
|
36
|
+
* `query` is passed through to `fetch` untouched, so framework caching
|
|
37
|
+
* (`next: { tags }`, `cf: {...}`, `cache:`) rides for free.
|
|
38
|
+
*/
|
|
39
|
+
type FetchOptions = Omit<RequestInit, 'body'> & {
|
|
40
|
+
body?: unknown;
|
|
41
|
+
query?: Record<string, unknown>;
|
|
42
|
+
};
|
|
43
|
+
interface BoardClientOptions {
|
|
44
|
+
baseUrl: string;
|
|
45
|
+
/** Board identifier: `pk_…` key | `boards_…` ID | slug (ADR-0032). */
|
|
46
|
+
board: string;
|
|
47
|
+
storage: CustomStorage;
|
|
48
|
+
globalHeaders?: Record<string, string>;
|
|
49
|
+
onRequest?: (req: BoardRequest) => Awaitable<BoardRequest>;
|
|
50
|
+
onResponse?: (res: Response, req: BoardRequest) => Awaitable<void>;
|
|
51
|
+
logger?: Logger;
|
|
52
|
+
}
|
|
53
|
+
declare class BoardClient {
|
|
54
|
+
readonly storage: CustomStorage;
|
|
55
|
+
private readonly basePath;
|
|
56
|
+
private readonly options;
|
|
57
|
+
constructor(options: BoardClientOptions);
|
|
58
|
+
/**
|
|
59
|
+
* The full request pipeline. Public and first-class: custom endpoints
|
|
60
|
+
* work without an SDK release, and still get the board-identifier
|
|
61
|
+
* base path, default headers, bearer token, and both hooks.
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* const stats = await board.client.fetch<MyShape>('/custom/stats');
|
|
65
|
+
*/
|
|
66
|
+
fetch<T>(path: string, init?: FetchOptions): Promise<T>;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
type SuggestResult = Schemas['SuggestResult'];
|
|
70
|
+
type SuggestionItem = Schemas['SuggestionItem'];
|
|
71
|
+
type CompanySuggestion = Schemas['CompanySuggestion'];
|
|
72
|
+
type TermSuggestion = Schemas['TermSuggestion'];
|
|
73
|
+
/** Query for `board.search.suggest()`. */
|
|
74
|
+
type SearchSuggestQuery = {
|
|
75
|
+
/** Keyword; under 2 chars the server returns an empty `items` array. */
|
|
76
|
+
q?: string;
|
|
77
|
+
/** Max interleaved suggestions (1–25; default 25). */
|
|
78
|
+
limit?: number;
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
export { type Awaitable as A, type BoardRequest as B, type CompanySuggestion as C, type FetchOptions as F, type Logger as L, REFRESH_TOKEN_KEY as R, type SuggestionItem as S, type TermSuggestion as T, type SearchSuggestQuery as a, type SuggestResult as b, type StorageMode as c, BoardClient as d, ACCESS_TOKEN_KEY as e, BOARD_ACCESS_GRANT_KEY as f, type CustomStorage as g };
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { S as Schemas } from './_spec-DRbgPIlN.mjs';
|
|
2
|
+
|
|
3
|
+
type Awaitable<T> = T | Promise<T>;
|
|
4
|
+
/**
|
|
5
|
+
* Async token storage. The SDK reads the access token from storage on
|
|
6
|
+
* every request (fresh-token rule); auth methods write/clear the pair.
|
|
7
|
+
*/
|
|
8
|
+
interface CustomStorage {
|
|
9
|
+
getItem(key: string): Awaitable<string | null>;
|
|
10
|
+
setItem(key: string, value: string): Awaitable<void>;
|
|
11
|
+
removeItem(key: string): Awaitable<void>;
|
|
12
|
+
}
|
|
13
|
+
type StorageMode = 'memory' | 'nostore' | 'local' | 'session' | CustomStorage;
|
|
14
|
+
declare const ACCESS_TOKEN_KEY = "cavuno_board_access_token";
|
|
15
|
+
declare const REFRESH_TOKEN_KEY = "cavuno_board_refresh_token";
|
|
16
|
+
/** Board-password access grant — sent as `X-Board-Access` to pass the wall. */
|
|
17
|
+
declare const BOARD_ACCESS_GRANT_KEY = "cavuno_board_access_grant";
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* The request handed to `onRequest` and `fetch`. `onRequest` may
|
|
21
|
+
* mutate or replace it wholesale (locale headers, URL rewrites);
|
|
22
|
+
* whatever it returns is what gets fetched.
|
|
23
|
+
*/
|
|
24
|
+
interface BoardRequest {
|
|
25
|
+
/** Fully built URL, query string included. */
|
|
26
|
+
url: string;
|
|
27
|
+
/** Final RequestInit: method, Headers instance, serialized body, plus passthrough keys (`signal`, `cache`, `next`, `cf`, …). */
|
|
28
|
+
init: RequestInit;
|
|
29
|
+
}
|
|
30
|
+
interface Logger {
|
|
31
|
+
debug(message: string): void;
|
|
32
|
+
error(message: string): void;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Per-call options on every SDK method. Everything besides `body` and
|
|
36
|
+
* `query` is passed through to `fetch` untouched, so framework caching
|
|
37
|
+
* (`next: { tags }`, `cf: {...}`, `cache:`) rides for free.
|
|
38
|
+
*/
|
|
39
|
+
type FetchOptions = Omit<RequestInit, 'body'> & {
|
|
40
|
+
body?: unknown;
|
|
41
|
+
query?: Record<string, unknown>;
|
|
42
|
+
};
|
|
43
|
+
interface BoardClientOptions {
|
|
44
|
+
baseUrl: string;
|
|
45
|
+
/** Board identifier: `pk_…` key | `boards_…` ID | slug (ADR-0032). */
|
|
46
|
+
board: string;
|
|
47
|
+
storage: CustomStorage;
|
|
48
|
+
globalHeaders?: Record<string, string>;
|
|
49
|
+
onRequest?: (req: BoardRequest) => Awaitable<BoardRequest>;
|
|
50
|
+
onResponse?: (res: Response, req: BoardRequest) => Awaitable<void>;
|
|
51
|
+
logger?: Logger;
|
|
52
|
+
}
|
|
53
|
+
declare class BoardClient {
|
|
54
|
+
readonly storage: CustomStorage;
|
|
55
|
+
private readonly basePath;
|
|
56
|
+
private readonly options;
|
|
57
|
+
constructor(options: BoardClientOptions);
|
|
58
|
+
/**
|
|
59
|
+
* The full request pipeline. Public and first-class: custom endpoints
|
|
60
|
+
* work without an SDK release, and still get the board-identifier
|
|
61
|
+
* base path, default headers, bearer token, and both hooks.
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* const stats = await board.client.fetch<MyShape>('/custom/stats');
|
|
65
|
+
*/
|
|
66
|
+
fetch<T>(path: string, init?: FetchOptions): Promise<T>;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
type SuggestResult = Schemas['SuggestResult'];
|
|
70
|
+
type SuggestionItem = Schemas['SuggestionItem'];
|
|
71
|
+
type CompanySuggestion = Schemas['CompanySuggestion'];
|
|
72
|
+
type TermSuggestion = Schemas['TermSuggestion'];
|
|
73
|
+
/** Query for `board.search.suggest()`. */
|
|
74
|
+
type SearchSuggestQuery = {
|
|
75
|
+
/** Keyword; under 2 chars the server returns an empty `items` array. */
|
|
76
|
+
q?: string;
|
|
77
|
+
/** Max interleaved suggestions (1–25; default 25). */
|
|
78
|
+
limit?: number;
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
export { type Awaitable as A, type BoardRequest as B, type CompanySuggestion as C, type FetchOptions as F, type Logger as L, REFRESH_TOKEN_KEY as R, type SuggestionItem as S, type TermSuggestion as T, type SearchSuggestQuery as a, type SuggestResult as b, type StorageMode as c, BoardClient as d, ACCESS_TOKEN_KEY as e, BOARD_ACCESS_GRANT_KEY as f, type CustomStorage as g };
|
package/dist/seo.d.mts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { P as PublicBlogPostSummary, B as BlogAuthorEmbed, C as CompanyCategorySalary, a as CompanySalary, L as LocationSalaryDetail, S as SkillSalaryDetail, T as TitleSalaryDetail } from './salaries-
|
|
2
|
-
import { P as PublicBoard } from './board-
|
|
3
|
-
import { P as PublicJob } from './jobs-
|
|
1
|
+
import { P as PublicBlogPostSummary, B as BlogAuthorEmbed, C as CompanyCategorySalary, a as CompanySalary, L as LocationSalaryDetail, S as SkillSalaryDetail, T as TitleSalaryDetail } from './salaries-D6SUVMmt.mjs';
|
|
2
|
+
import { P as PublicBoard } from './board-DCiNpgFf.mjs';
|
|
3
|
+
import { P as PublicJob } from './jobs-DhePKSRe.mjs';
|
|
4
4
|
import { B as BoardLabelOverrides } from './ui-copy-CKfFTtLk.mjs';
|
|
5
|
+
import './_spec-DRbgPIlN.mjs';
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* Google for Jobs `JobPosting` structured data on the `@cavuno/board` wire
|
package/dist/seo.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { P as PublicBlogPostSummary, B as BlogAuthorEmbed, C as CompanyCategorySalary, a as CompanySalary, L as LocationSalaryDetail, S as SkillSalaryDetail, T as TitleSalaryDetail } from './salaries-
|
|
2
|
-
import { P as PublicBoard } from './board-
|
|
3
|
-
import { P as PublicJob } from './jobs-
|
|
1
|
+
import { P as PublicBlogPostSummary, B as BlogAuthorEmbed, C as CompanyCategorySalary, a as CompanySalary, L as LocationSalaryDetail, S as SkillSalaryDetail, T as TitleSalaryDetail } from './salaries-cqb78kg0.js';
|
|
2
|
+
import { P as PublicBoard } from './board-BxPUtrOl.js';
|
|
3
|
+
import { P as PublicJob } from './jobs-DAGAVHQL.js';
|
|
4
4
|
import { B as BoardLabelOverrides } from './ui-copy-CKfFTtLk.js';
|
|
5
|
+
import './_spec-DRbgPIlN.js';
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* Google for Jobs `JobPosting` structured data on the `@cavuno/board` wire
|
package/dist/server.d.mts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { BoardSdk } from './index.mjs';
|
|
2
|
-
import './
|
|
3
|
-
import './
|
|
4
|
-
import './
|
|
2
|
+
import './_spec-DRbgPIlN.mjs';
|
|
3
|
+
import './search-DYUQzCq_.mjs';
|
|
4
|
+
import './board-DCiNpgFf.mjs';
|
|
5
|
+
import './jobs-DhePKSRe.mjs';
|
|
6
|
+
import './salaries-D6SUVMmt.mjs';
|
|
5
7
|
|
|
6
8
|
/**
|
|
7
9
|
* Session cookie codec — pure (no framework imports, no node imports) so it
|
|
@@ -75,6 +77,56 @@ declare function safeRedirectPath(path: string | undefined | null, defaultPath?:
|
|
|
75
77
|
*/
|
|
76
78
|
declare function currentPathFromReferer(referer: string | null): string;
|
|
77
79
|
|
|
80
|
+
/**
|
|
81
|
+
* MIG-10 (added scope) — keep `<slug>.cavuno.app` live after a custom-domain
|
|
82
|
+
* cutover by 308-redirecting to the board's canonical custom domain.
|
|
83
|
+
*
|
|
84
|
+
* ## Where this lives (DEVIATION LOUDLY)
|
|
85
|
+
* **Serving-side, not the dispatch edge.** Production hostname→worker
|
|
86
|
+
* routing is the WFP dispatch Worker's KV map (`hostname → workerName`
|
|
87
|
+
* only — see `docs/recipes/ops/wfp-dispatch-custom-domain.md` and
|
|
88
|
+
* `createWfpReleaseDeploy` / `deterministicWorkerName`). That edge has
|
|
89
|
+
* **no board domain data** (no Convex, no primaryDomain). Inventing a
|
|
90
|
+
* second edge datastore for canonical hosts is forbidden by the ticket.
|
|
91
|
+
*
|
|
92
|
+
* Data source: the board's public context already carries
|
|
93
|
+
* `primaryDomain: string | null` (`GET /v1/boards/:id` via
|
|
94
|
+
* `serializeBoardContext`). The starter loads context for every request
|
|
95
|
+
* (theme, features, analytics) — reuse that field. When `primaryDomain`
|
|
96
|
+
* is set, a request whose Host is a `*.cavuno.app` serving host 308s to
|
|
97
|
+
* `https://<primaryDomain><path+query>` in **one hop**. Domainless boards
|
|
98
|
+
* (`primaryDomain === null`) keep **serving** from cavuno.app (no redirect).
|
|
99
|
+
*
|
|
100
|
+
* Wire this helper into the starter's root middleware / entry (the
|
|
101
|
+
* migration starter's host check) with `Response.redirect(url, 308)`.
|
|
102
|
+
* Pure so unit tests pin behaviour without a Worker runtime.
|
|
103
|
+
*
|
|
104
|
+
* Pattern: Vercel `*.vercel.app` / GitHub `github.io` permanent fallback
|
|
105
|
+
* origin — SEO-neutral 308 to the canonical production host.
|
|
106
|
+
*/
|
|
107
|
+
/**
|
|
108
|
+
* True when the request host is a cavuno.app board-serving host
|
|
109
|
+
* (slug or board-hash subdomain), not the apex and not a preview host
|
|
110
|
+
* we deliberately leave alone.
|
|
111
|
+
*/
|
|
112
|
+
declare function isCavunoAppServingHost(hostname: string): boolean;
|
|
113
|
+
/**
|
|
114
|
+
* When a custom-domain board is hit on its cavuno.app fallback origin,
|
|
115
|
+
* return the one-hop 308 Location to the canonical custom domain.
|
|
116
|
+
* Domainless boards (no primaryDomain) return null — serve in place.
|
|
117
|
+
*/
|
|
118
|
+
declare function getCavunoAppCanonicalRedirectUrl(params: {
|
|
119
|
+
currentHost: string | null;
|
|
120
|
+
/**
|
|
121
|
+
* From `board.context().primaryDomain` — the board's active primary
|
|
122
|
+
* custom domain hostname, or null when domainless.
|
|
123
|
+
*/
|
|
124
|
+
primaryDomain: string | null | undefined;
|
|
125
|
+
/** Full request URL or path+query; path+query is preserved on the hop. */
|
|
126
|
+
requestUrl?: string | null;
|
|
127
|
+
defaultPath?: string;
|
|
128
|
+
}): string | null;
|
|
129
|
+
|
|
78
130
|
/**
|
|
79
131
|
* Single-flight session refresh — dedupes concurrent refreshes for the same
|
|
80
132
|
* session WITHIN one process/isolate (the rotation race, ADR-0057 wart #4,
|
|
@@ -109,4 +161,4 @@ declare function currentPathFromReferer(referer: string | null): string;
|
|
|
109
161
|
*/
|
|
110
162
|
declare function createSessionRefresher(board: Pick<BoardSdk, 'auth' | 'client'>): (session: BoardSession) => Promise<BoardSession | null>;
|
|
111
163
|
|
|
112
|
-
export { BOARD_ACCESS_COOKIE_NAME, type BoardSession, SESSION_COOKIE_NAME, clearGrantCookie, clearSessionCookie, createSessionRefresher, currentPathFromReferer, grantCookieName, isExpiringSoon, parseGrantCookie, parseSessionCookie, safeRedirectPath, serializeGrantCookie, serializeSessionCookie, sessionCookieName };
|
|
164
|
+
export { BOARD_ACCESS_COOKIE_NAME, type BoardSession, SESSION_COOKIE_NAME, clearGrantCookie, clearSessionCookie, createSessionRefresher, currentPathFromReferer, getCavunoAppCanonicalRedirectUrl, grantCookieName, isCavunoAppServingHost, isExpiringSoon, parseGrantCookie, parseSessionCookie, safeRedirectPath, serializeGrantCookie, serializeSessionCookie, sessionCookieName };
|