@cavuno/board 4.42.0 → 4.45.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 +56 -0
- package/dist/{_spec-B2aizgxr.d.mts → _spec-CdNZDaaR.d.mts} +39 -0
- package/dist/{_spec-B2aizgxr.d.ts → _spec-CdNZDaaR.d.ts} +39 -0
- package/dist/bin.mjs +570 -10
- package/dist/{blog-BkACbXY0.d.ts → blog-ZvLJ6w1Q.d.ts} +1 -1
- package/dist/{blog-CYHSnNTZ.d.mts → blog-uV51b4Cg.d.mts} +1 -1
- package/dist/{board-DWeT9Jbl.d.ts → board-3JU14eF3.d.ts} +2 -2
- package/dist/{board-DK4HmSty.d.mts → board-CJw-MJpf.d.mts} +2 -2
- package/dist/{breadcrumbs-nTfIWzRh.d.mts → breadcrumbs-BY1UMCbL.d.mts} +2 -2
- package/dist/{breadcrumbs-CtKa2zPe.d.ts → breadcrumbs-CXvdv6Ry.d.ts} +2 -2
- package/dist/browser/cavuno-board.global.min.js +1 -1
- package/dist/{chunk-WSO6JN5C.mjs → chunk-DZD3DAEY.mjs} +2 -0
- package/dist/doctor.d.mts +1 -0
- package/dist/doctor.d.ts +1 -0
- package/dist/doctor.js +570 -10
- package/dist/doctor.mjs +570 -10
- 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 +107 -14
- package/dist/index.d.ts +107 -14
- package/dist/index.js +129 -8
- package/dist/index.mjs +128 -9
- package/dist/{jobs-SAkNWgAB.d.ts → jobs-C7UvN_dW.d.ts} +1 -1
- package/dist/{jobs-C_eO-WfM.d.mts → jobs-D9ERWWda.d.mts} +1 -1
- package/dist/{search-Cb3Aoa4c.d.mts → search-BMSNK85o.d.mts} +1 -1
- package/dist/{search-CVcMFOuJ.d.ts → search-D0TFnn1x.d.ts} +1 -1
- package/dist/{seo-DPVud7SH.d.mts → seo-C3WmgifR.d.mts} +1 -1
- package/dist/{seo-DgFBQTIK.d.ts → seo-CYmVKHsu.d.ts} +1 -1
- package/dist/seo-files.d.mts +25 -3
- package/dist/seo-files.d.ts +25 -3
- package/dist/seo-files.js +44 -10
- package/dist/seo-files.mjs +44 -10
- 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-filters/SKILL.md +13 -0
- package/skills/cavuno-board-i18n/SKILL.md +10 -0
- package/skills/cavuno-board-post-a-job/SKILL.md +2 -1
- package/skills/manifest.json +1 -1
package/dist/index.js
CHANGED
|
@@ -209,6 +209,8 @@ var BOARD_API_ERROR_CODES = [
|
|
|
209
209
|
"talent_list_not_found",
|
|
210
210
|
"sourced_candidate_not_found",
|
|
211
211
|
"sourced_convert_unavailable",
|
|
212
|
+
// Saved people on a talent list: a list holds at most 500 people.
|
|
213
|
+
"talent_list_full",
|
|
212
214
|
// Candidate job-access paywall
|
|
213
215
|
"candidate_paywall_access_required",
|
|
214
216
|
"paywall_already_active",
|
|
@@ -403,7 +405,7 @@ async function clearSession(storage) {
|
|
|
403
405
|
}
|
|
404
406
|
|
|
405
407
|
// src/version.ts
|
|
406
|
-
var SDK_VERSION = "4.
|
|
408
|
+
var SDK_VERSION = "4.45.0";
|
|
407
409
|
|
|
408
410
|
// src/client.ts
|
|
409
411
|
function isRawBody(body) {
|
|
@@ -1346,7 +1348,11 @@ function jobPostingNamespace(client) {
|
|
|
1346
1348
|
{ ...options, method: "POST", body: input }
|
|
1347
1349
|
);
|
|
1348
1350
|
},
|
|
1349
|
-
/**
|
|
1351
|
+
/**
|
|
1352
|
+
* List the credit options for a verified email. To spend one, pass the
|
|
1353
|
+
* option as `selectedBilling` and the same `verificationToken` as
|
|
1354
|
+
* `billingVerificationToken` to `create`.
|
|
1355
|
+
*/
|
|
1350
1356
|
getBillingOptions(input, options) {
|
|
1351
1357
|
return client.fetch(
|
|
1352
1358
|
"/job-postings/billing-options",
|
|
@@ -2486,9 +2492,12 @@ function meNamespace(client) {
|
|
|
2486
2492
|
}
|
|
2487
2493
|
},
|
|
2488
2494
|
/**
|
|
2489
|
-
* Company-owned saved
|
|
2490
|
-
*
|
|
2491
|
-
*
|
|
2495
|
+
* Company-owned saved searches over the talent directory. Each holds
|
|
2496
|
+
* named filters and, optionally, saved people (`members`). Approved
|
|
2497
|
+
* members share the same lists. Optional `job` links a list to one
|
|
2498
|
+
* company job; pass `job: null` on update to unlink. Linking a list
|
|
2499
|
+
* shortlists everyone saved to it onto that job; unlinking changes no
|
|
2500
|
+
* pipeline.
|
|
2492
2501
|
*/
|
|
2493
2502
|
talentLists: {
|
|
2494
2503
|
/**
|
|
@@ -2530,7 +2539,10 @@ function meNamespace(client) {
|
|
|
2530
2539
|
{ ...options, method: "PATCH", body }
|
|
2531
2540
|
);
|
|
2532
2541
|
},
|
|
2533
|
-
/**
|
|
2542
|
+
/**
|
|
2543
|
+
* Delete a talent list and the people saved to it. Job pipelines and
|
|
2544
|
+
* sourced membership are unaffected.
|
|
2545
|
+
*/
|
|
2534
2546
|
remove(slug, listId, options) {
|
|
2535
2547
|
return client.fetch(
|
|
2536
2548
|
`/me/companies/${encodeURIComponent(
|
|
@@ -2538,6 +2550,90 @@ function meNamespace(client) {
|
|
|
2538
2550
|
)}/talent-lists/${encodeURIComponent(listId)}`,
|
|
2539
2551
|
{ ...options, method: "DELETE" }
|
|
2540
2552
|
);
|
|
2553
|
+
},
|
|
2554
|
+
/**
|
|
2555
|
+
* The talent lists of a company one candidate is saved to — for
|
|
2556
|
+
* showing which lists a Save control has ticked.
|
|
2557
|
+
*
|
|
2558
|
+
* @example
|
|
2559
|
+
* const { data } = await board.me.companies.talentLists.memberships(
|
|
2560
|
+
* 'acme',
|
|
2561
|
+
* { candidate: candidateId },
|
|
2562
|
+
* );
|
|
2563
|
+
* const saved = new Set(data.map((m) => m.listId));
|
|
2564
|
+
*/
|
|
2565
|
+
memberships(slug, query, options) {
|
|
2566
|
+
return client.fetch(
|
|
2567
|
+
`/me/companies/${encodeURIComponent(slug)}/talent-list-memberships`,
|
|
2568
|
+
{ ...options, query }
|
|
2569
|
+
);
|
|
2570
|
+
},
|
|
2571
|
+
/**
|
|
2572
|
+
* People saved to a talent list (at most 500 per list).
|
|
2573
|
+
*/
|
|
2574
|
+
members: {
|
|
2575
|
+
/**
|
|
2576
|
+
* List the people saved to a list as directory cards, most
|
|
2577
|
+
* recently saved first unless `sort` or a keyword (`q`) is set;
|
|
2578
|
+
* with a keyword, best match first. Cards are redacted as in the
|
|
2579
|
+
* public directory when the board sells profile unlocks, except
|
|
2580
|
+
* for candidates the company has unlocked. Runs the public
|
|
2581
|
+
* talent directory search, with the same filters, restricted to
|
|
2582
|
+
* the saved people, so a "Saved" view can combine with the
|
|
2583
|
+
* list's filters. Blocked, hidden and deactivated
|
|
2584
|
+
* candidates are omitted. `total` counts every visible saved
|
|
2585
|
+
* person; `count` counts the ones the filters keep.
|
|
2586
|
+
*
|
|
2587
|
+
* @example
|
|
2588
|
+
* const { data, total } =
|
|
2589
|
+
* await board.me.companies.talentLists.members.list(
|
|
2590
|
+
* 'acme',
|
|
2591
|
+
* listId,
|
|
2592
|
+
* { skill: 'react' },
|
|
2593
|
+
* );
|
|
2594
|
+
*/
|
|
2595
|
+
list(slug, listId, query, options) {
|
|
2596
|
+
return client.fetch(
|
|
2597
|
+
`/me/companies/${encodeURIComponent(
|
|
2598
|
+
slug
|
|
2599
|
+
)}/talent-lists/${encodeURIComponent(listId)}/members`,
|
|
2600
|
+
{ ...options, query }
|
|
2601
|
+
);
|
|
2602
|
+
},
|
|
2603
|
+
/**
|
|
2604
|
+
* Save a candidate to a list. Idempotent: saving someone already
|
|
2605
|
+
* on it returns `created: false`. When the list is linked to a
|
|
2606
|
+
* job, the candidate is also shortlisted onto that job unless they
|
|
2607
|
+
* already have a pipeline row there. A full list raises
|
|
2608
|
+
* `talent_list_full` (409).
|
|
2609
|
+
*
|
|
2610
|
+
* @example
|
|
2611
|
+
* await board.me.companies.talentLists.members.add('acme', listId, {
|
|
2612
|
+
* candidateBoardUserId: candidateId,
|
|
2613
|
+
* });
|
|
2614
|
+
*/
|
|
2615
|
+
add(slug, listId, body, options) {
|
|
2616
|
+
return client.fetch(
|
|
2617
|
+
`/me/companies/${encodeURIComponent(
|
|
2618
|
+
slug
|
|
2619
|
+
)}/talent-lists/${encodeURIComponent(listId)}/members`,
|
|
2620
|
+
{ ...options, method: "POST", body }
|
|
2621
|
+
);
|
|
2622
|
+
},
|
|
2623
|
+
/**
|
|
2624
|
+
* Remove a candidate from a list. Idempotent. Never changes a job
|
|
2625
|
+
* pipeline, including the linked job's.
|
|
2626
|
+
*/
|
|
2627
|
+
remove(slug, listId, candidateBoardUserId, options) {
|
|
2628
|
+
return client.fetch(
|
|
2629
|
+
`/me/companies/${encodeURIComponent(
|
|
2630
|
+
slug
|
|
2631
|
+
)}/talent-lists/${encodeURIComponent(
|
|
2632
|
+
listId
|
|
2633
|
+
)}/members/${encodeURIComponent(candidateBoardUserId)}`,
|
|
2634
|
+
{ ...options, method: "DELETE" }
|
|
2635
|
+
);
|
|
2636
|
+
}
|
|
2541
2637
|
}
|
|
2542
2638
|
},
|
|
2543
2639
|
/**
|
|
@@ -3753,9 +3849,10 @@ function sitemapNamespace(client) {
|
|
|
3753
3849
|
function talentNamespace(client) {
|
|
3754
3850
|
return {
|
|
3755
3851
|
/**
|
|
3756
|
-
* List the board's
|
|
3852
|
+
* List the board's talent directory — candidate cards ranked by
|
|
3757
3853
|
* job-search status then most-recently-updated, the same ordering the
|
|
3758
|
-
* hosted `/talent` page renders.
|
|
3854
|
+
* hosted `/talent` page renders. Anonymous callers see `public` profiles;
|
|
3855
|
+
* a signed-in board user also sees `logged_in_only` ones.
|
|
3759
3856
|
*
|
|
3760
3857
|
* Throws `talent_directory_restricted` (403) when the board restricts the
|
|
3761
3858
|
* directory to employers (render an employer upsell), or
|
|
@@ -3788,6 +3885,30 @@ function talentNamespace(client) {
|
|
|
3788
3885
|
`/talent/${encodeURIComponent(handle)}`,
|
|
3789
3886
|
options
|
|
3790
3887
|
);
|
|
3888
|
+
},
|
|
3889
|
+
places: {
|
|
3890
|
+
/**
|
|
3891
|
+
* List the places the board's directory candidates live in, busiest
|
|
3892
|
+
* first, each with how many candidates the caller can see there (a
|
|
3893
|
+
* country counts every candidate in its cities). Anonymous callers get
|
|
3894
|
+
* counts of `public` profiles; a signed-in board user also counts
|
|
3895
|
+
* `logged_in_only` ones. Pass a place's `slug` as `talent.list`'s
|
|
3896
|
+
* `place` filter. With `q`, returns location search matches instead,
|
|
3897
|
+
* ranked as `taxonomy.places.list` ranks them.
|
|
3898
|
+
*
|
|
3899
|
+
* Same access errors as `talent.list`. Returns an empty list until the
|
|
3900
|
+
* board's place counts are built.
|
|
3901
|
+
*
|
|
3902
|
+
* @example
|
|
3903
|
+
* const { data: places } = await board.talent.places.list({ limit: 50 });
|
|
3904
|
+
* const { data: matches } = await board.talent.places.list({ q: 'lon' });
|
|
3905
|
+
*/
|
|
3906
|
+
list(query, options) {
|
|
3907
|
+
return client.fetch("/talent/places", {
|
|
3908
|
+
...options,
|
|
3909
|
+
query
|
|
3910
|
+
});
|
|
3911
|
+
}
|
|
3791
3912
|
}
|
|
3792
3913
|
};
|
|
3793
3914
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -25,7 +25,7 @@ import {
|
|
|
25
25
|
isSsoRequired,
|
|
26
26
|
isUnauthorized,
|
|
27
27
|
isValidationError
|
|
28
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-DZD3DAEY.mjs";
|
|
29
29
|
|
|
30
30
|
// src/query.ts
|
|
31
31
|
function toSearchParams(query) {
|
|
@@ -46,7 +46,7 @@ function toSearchParams(query) {
|
|
|
46
46
|
}
|
|
47
47
|
|
|
48
48
|
// src/version.ts
|
|
49
|
-
var SDK_VERSION = "4.
|
|
49
|
+
var SDK_VERSION = "4.45.0";
|
|
50
50
|
|
|
51
51
|
// src/client.ts
|
|
52
52
|
function isRawBody(body) {
|
|
@@ -989,7 +989,11 @@ function jobPostingNamespace(client) {
|
|
|
989
989
|
{ ...options, method: "POST", body: input }
|
|
990
990
|
);
|
|
991
991
|
},
|
|
992
|
-
/**
|
|
992
|
+
/**
|
|
993
|
+
* List the credit options for a verified email. To spend one, pass the
|
|
994
|
+
* option as `selectedBilling` and the same `verificationToken` as
|
|
995
|
+
* `billingVerificationToken` to `create`.
|
|
996
|
+
*/
|
|
993
997
|
getBillingOptions(input, options) {
|
|
994
998
|
return client.fetch(
|
|
995
999
|
"/job-postings/billing-options",
|
|
@@ -2129,9 +2133,12 @@ function meNamespace(client) {
|
|
|
2129
2133
|
}
|
|
2130
2134
|
},
|
|
2131
2135
|
/**
|
|
2132
|
-
* Company-owned saved
|
|
2133
|
-
*
|
|
2134
|
-
*
|
|
2136
|
+
* Company-owned saved searches over the talent directory. Each holds
|
|
2137
|
+
* named filters and, optionally, saved people (`members`). Approved
|
|
2138
|
+
* members share the same lists. Optional `job` links a list to one
|
|
2139
|
+
* company job; pass `job: null` on update to unlink. Linking a list
|
|
2140
|
+
* shortlists everyone saved to it onto that job; unlinking changes no
|
|
2141
|
+
* pipeline.
|
|
2135
2142
|
*/
|
|
2136
2143
|
talentLists: {
|
|
2137
2144
|
/**
|
|
@@ -2173,7 +2180,10 @@ function meNamespace(client) {
|
|
|
2173
2180
|
{ ...options, method: "PATCH", body }
|
|
2174
2181
|
);
|
|
2175
2182
|
},
|
|
2176
|
-
/**
|
|
2183
|
+
/**
|
|
2184
|
+
* Delete a talent list and the people saved to it. Job pipelines and
|
|
2185
|
+
* sourced membership are unaffected.
|
|
2186
|
+
*/
|
|
2177
2187
|
remove(slug, listId, options) {
|
|
2178
2188
|
return client.fetch(
|
|
2179
2189
|
`/me/companies/${encodeURIComponent(
|
|
@@ -2181,6 +2191,90 @@ function meNamespace(client) {
|
|
|
2181
2191
|
)}/talent-lists/${encodeURIComponent(listId)}`,
|
|
2182
2192
|
{ ...options, method: "DELETE" }
|
|
2183
2193
|
);
|
|
2194
|
+
},
|
|
2195
|
+
/**
|
|
2196
|
+
* The talent lists of a company one candidate is saved to — for
|
|
2197
|
+
* showing which lists a Save control has ticked.
|
|
2198
|
+
*
|
|
2199
|
+
* @example
|
|
2200
|
+
* const { data } = await board.me.companies.talentLists.memberships(
|
|
2201
|
+
* 'acme',
|
|
2202
|
+
* { candidate: candidateId },
|
|
2203
|
+
* );
|
|
2204
|
+
* const saved = new Set(data.map((m) => m.listId));
|
|
2205
|
+
*/
|
|
2206
|
+
memberships(slug, query, options) {
|
|
2207
|
+
return client.fetch(
|
|
2208
|
+
`/me/companies/${encodeURIComponent(slug)}/talent-list-memberships`,
|
|
2209
|
+
{ ...options, query }
|
|
2210
|
+
);
|
|
2211
|
+
},
|
|
2212
|
+
/**
|
|
2213
|
+
* People saved to a talent list (at most 500 per list).
|
|
2214
|
+
*/
|
|
2215
|
+
members: {
|
|
2216
|
+
/**
|
|
2217
|
+
* List the people saved to a list as directory cards, most
|
|
2218
|
+
* recently saved first unless `sort` or a keyword (`q`) is set;
|
|
2219
|
+
* with a keyword, best match first. Cards are redacted as in the
|
|
2220
|
+
* public directory when the board sells profile unlocks, except
|
|
2221
|
+
* for candidates the company has unlocked. Runs the public
|
|
2222
|
+
* talent directory search, with the same filters, restricted to
|
|
2223
|
+
* the saved people, so a "Saved" view can combine with the
|
|
2224
|
+
* list's filters. Blocked, hidden and deactivated
|
|
2225
|
+
* candidates are omitted. `total` counts every visible saved
|
|
2226
|
+
* person; `count` counts the ones the filters keep.
|
|
2227
|
+
*
|
|
2228
|
+
* @example
|
|
2229
|
+
* const { data, total } =
|
|
2230
|
+
* await board.me.companies.talentLists.members.list(
|
|
2231
|
+
* 'acme',
|
|
2232
|
+
* listId,
|
|
2233
|
+
* { skill: 'react' },
|
|
2234
|
+
* );
|
|
2235
|
+
*/
|
|
2236
|
+
list(slug, listId, query, options) {
|
|
2237
|
+
return client.fetch(
|
|
2238
|
+
`/me/companies/${encodeURIComponent(
|
|
2239
|
+
slug
|
|
2240
|
+
)}/talent-lists/${encodeURIComponent(listId)}/members`,
|
|
2241
|
+
{ ...options, query }
|
|
2242
|
+
);
|
|
2243
|
+
},
|
|
2244
|
+
/**
|
|
2245
|
+
* Save a candidate to a list. Idempotent: saving someone already
|
|
2246
|
+
* on it returns `created: false`. When the list is linked to a
|
|
2247
|
+
* job, the candidate is also shortlisted onto that job unless they
|
|
2248
|
+
* already have a pipeline row there. A full list raises
|
|
2249
|
+
* `talent_list_full` (409).
|
|
2250
|
+
*
|
|
2251
|
+
* @example
|
|
2252
|
+
* await board.me.companies.talentLists.members.add('acme', listId, {
|
|
2253
|
+
* candidateBoardUserId: candidateId,
|
|
2254
|
+
* });
|
|
2255
|
+
*/
|
|
2256
|
+
add(slug, listId, body, options) {
|
|
2257
|
+
return client.fetch(
|
|
2258
|
+
`/me/companies/${encodeURIComponent(
|
|
2259
|
+
slug
|
|
2260
|
+
)}/talent-lists/${encodeURIComponent(listId)}/members`,
|
|
2261
|
+
{ ...options, method: "POST", body }
|
|
2262
|
+
);
|
|
2263
|
+
},
|
|
2264
|
+
/**
|
|
2265
|
+
* Remove a candidate from a list. Idempotent. Never changes a job
|
|
2266
|
+
* pipeline, including the linked job's.
|
|
2267
|
+
*/
|
|
2268
|
+
remove(slug, listId, candidateBoardUserId, options) {
|
|
2269
|
+
return client.fetch(
|
|
2270
|
+
`/me/companies/${encodeURIComponent(
|
|
2271
|
+
slug
|
|
2272
|
+
)}/talent-lists/${encodeURIComponent(
|
|
2273
|
+
listId
|
|
2274
|
+
)}/members/${encodeURIComponent(candidateBoardUserId)}`,
|
|
2275
|
+
{ ...options, method: "DELETE" }
|
|
2276
|
+
);
|
|
2277
|
+
}
|
|
2184
2278
|
}
|
|
2185
2279
|
},
|
|
2186
2280
|
/**
|
|
@@ -3396,9 +3490,10 @@ function sitemapNamespace(client) {
|
|
|
3396
3490
|
function talentNamespace(client) {
|
|
3397
3491
|
return {
|
|
3398
3492
|
/**
|
|
3399
|
-
* List the board's
|
|
3493
|
+
* List the board's talent directory — candidate cards ranked by
|
|
3400
3494
|
* job-search status then most-recently-updated, the same ordering the
|
|
3401
|
-
* hosted `/talent` page renders.
|
|
3495
|
+
* hosted `/talent` page renders. Anonymous callers see `public` profiles;
|
|
3496
|
+
* a signed-in board user also sees `logged_in_only` ones.
|
|
3402
3497
|
*
|
|
3403
3498
|
* Throws `talent_directory_restricted` (403) when the board restricts the
|
|
3404
3499
|
* directory to employers (render an employer upsell), or
|
|
@@ -3431,6 +3526,30 @@ function talentNamespace(client) {
|
|
|
3431
3526
|
`/talent/${encodeURIComponent(handle)}`,
|
|
3432
3527
|
options
|
|
3433
3528
|
);
|
|
3529
|
+
},
|
|
3530
|
+
places: {
|
|
3531
|
+
/**
|
|
3532
|
+
* List the places the board's directory candidates live in, busiest
|
|
3533
|
+
* first, each with how many candidates the caller can see there (a
|
|
3534
|
+
* country counts every candidate in its cities). Anonymous callers get
|
|
3535
|
+
* counts of `public` profiles; a signed-in board user also counts
|
|
3536
|
+
* `logged_in_only` ones. Pass a place's `slug` as `talent.list`'s
|
|
3537
|
+
* `place` filter. With `q`, returns location search matches instead,
|
|
3538
|
+
* ranked as `taxonomy.places.list` ranks them.
|
|
3539
|
+
*
|
|
3540
|
+
* Same access errors as `talent.list`. Returns an empty list until the
|
|
3541
|
+
* board's place counts are built.
|
|
3542
|
+
*
|
|
3543
|
+
* @example
|
|
3544
|
+
* const { data: places } = await board.talent.places.list({ limit: 50 });
|
|
3545
|
+
* const { data: matches } = await board.talent.places.list({ q: 'lon' });
|
|
3546
|
+
*/
|
|
3547
|
+
list(query, options) {
|
|
3548
|
+
return client.fetch("/talent/places", {
|
|
3549
|
+
...options,
|
|
3550
|
+
query
|
|
3551
|
+
});
|
|
3552
|
+
}
|
|
3434
3553
|
}
|
|
3435
3554
|
};
|
|
3436
3555
|
}
|
package/dist/seo-files.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { B as BoardSeo } from './seo-
|
|
2
|
-
import './_spec-
|
|
1
|
+
import { B as BoardSeo } from './seo-C3WmgifR.mjs';
|
|
2
|
+
import './_spec-CdNZDaaR.mjs';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* `@cavuno/board/seo-files` — platform-owned crawler/identity file bodies
|
|
@@ -18,13 +18,35 @@ declare const INDEXNOW_CACHE_CONTROL = "public, max-age=86400, must-revalidate";
|
|
|
18
18
|
type SeoFileResponseInit = {
|
|
19
19
|
method?: string;
|
|
20
20
|
};
|
|
21
|
+
/**
|
|
22
|
+
* The board's own listing roots, for boards that rename or localize their
|
|
23
|
+
* URL words (for example `/vacatures` in place of `/jobs`). Each root scopes
|
|
24
|
+
* one group of pagination `Disallow` rules. A missing, root (`/`) or unsafe
|
|
25
|
+
* value keeps the default English root for that group.
|
|
26
|
+
*/
|
|
27
|
+
type RobotsListingPaths = {
|
|
28
|
+
jobs?: string | null;
|
|
29
|
+
companies?: string | null;
|
|
30
|
+
talent?: string | null;
|
|
31
|
+
};
|
|
21
32
|
/** Lines of the hosted robots body (no sitemap line). Exported so tests and hosted can share the literal. */
|
|
22
33
|
declare function robotsBody(input: {
|
|
23
34
|
canonicalBase: string;
|
|
24
35
|
sandbox?: boolean;
|
|
36
|
+
listingPaths?: RobotsListingPaths | null;
|
|
37
|
+
/**
|
|
38
|
+
* Listing roots of the board's secondary languages, served under a
|
|
39
|
+
* language prefix with that language's own URL words (for example
|
|
40
|
+
* `/de/stellen`). Each safe root adds one group of pagination rules after
|
|
41
|
+
* the base ones, in order. A missing, root or unsafe value adds nothing,
|
|
42
|
+
* and a root already listed is not repeated.
|
|
43
|
+
*/
|
|
44
|
+
localeListingPaths?: readonly RobotsListingPaths[] | null;
|
|
25
45
|
}): string;
|
|
26
46
|
declare function robotsResponse(seo: Pick<BoardSeo, 'canonicalBase'> & {
|
|
27
47
|
sandbox?: boolean;
|
|
48
|
+
listingPaths?: RobotsListingPaths | null;
|
|
49
|
+
localeListingPaths?: readonly RobotsListingPaths[] | null;
|
|
28
50
|
}, init?: SeoFileResponseInit): Response;
|
|
29
51
|
declare function adsTxtResponse(seo: Pick<BoardSeo, 'adsTxt'>, init?: SeoFileResponseInit): Response;
|
|
30
52
|
declare function indexNowResponse(seo: Pick<BoardSeo, 'indexNowKey'>, init?: SeoFileResponseInit): Response;
|
|
@@ -33,4 +55,4 @@ declare function googleSiteVerificationMeta(token: string | null | undefined): {
|
|
|
33
55
|
content: string;
|
|
34
56
|
} | null;
|
|
35
57
|
|
|
36
|
-
export { ADS_TXT_CACHE_CONTROL, INDEXNOW_CACHE_CONTROL, ROBOTS_CACHE_CONTROL, SEO_FILE_CONTENT_TYPE, type SeoFileResponseInit, adsTxtResponse, googleSiteVerificationMeta, indexNowResponse, robotsBody, robotsResponse };
|
|
58
|
+
export { ADS_TXT_CACHE_CONTROL, INDEXNOW_CACHE_CONTROL, ROBOTS_CACHE_CONTROL, type RobotsListingPaths, SEO_FILE_CONTENT_TYPE, type SeoFileResponseInit, adsTxtResponse, googleSiteVerificationMeta, indexNowResponse, robotsBody, robotsResponse };
|
package/dist/seo-files.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { B as BoardSeo } from './seo-
|
|
2
|
-
import './_spec-
|
|
1
|
+
import { B as BoardSeo } from './seo-CYmVKHsu.js';
|
|
2
|
+
import './_spec-CdNZDaaR.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* `@cavuno/board/seo-files` — platform-owned crawler/identity file bodies
|
|
@@ -18,13 +18,35 @@ declare const INDEXNOW_CACHE_CONTROL = "public, max-age=86400, must-revalidate";
|
|
|
18
18
|
type SeoFileResponseInit = {
|
|
19
19
|
method?: string;
|
|
20
20
|
};
|
|
21
|
+
/**
|
|
22
|
+
* The board's own listing roots, for boards that rename or localize their
|
|
23
|
+
* URL words (for example `/vacatures` in place of `/jobs`). Each root scopes
|
|
24
|
+
* one group of pagination `Disallow` rules. A missing, root (`/`) or unsafe
|
|
25
|
+
* value keeps the default English root for that group.
|
|
26
|
+
*/
|
|
27
|
+
type RobotsListingPaths = {
|
|
28
|
+
jobs?: string | null;
|
|
29
|
+
companies?: string | null;
|
|
30
|
+
talent?: string | null;
|
|
31
|
+
};
|
|
21
32
|
/** Lines of the hosted robots body (no sitemap line). Exported so tests and hosted can share the literal. */
|
|
22
33
|
declare function robotsBody(input: {
|
|
23
34
|
canonicalBase: string;
|
|
24
35
|
sandbox?: boolean;
|
|
36
|
+
listingPaths?: RobotsListingPaths | null;
|
|
37
|
+
/**
|
|
38
|
+
* Listing roots of the board's secondary languages, served under a
|
|
39
|
+
* language prefix with that language's own URL words (for example
|
|
40
|
+
* `/de/stellen`). Each safe root adds one group of pagination rules after
|
|
41
|
+
* the base ones, in order. A missing, root or unsafe value adds nothing,
|
|
42
|
+
* and a root already listed is not repeated.
|
|
43
|
+
*/
|
|
44
|
+
localeListingPaths?: readonly RobotsListingPaths[] | null;
|
|
25
45
|
}): string;
|
|
26
46
|
declare function robotsResponse(seo: Pick<BoardSeo, 'canonicalBase'> & {
|
|
27
47
|
sandbox?: boolean;
|
|
48
|
+
listingPaths?: RobotsListingPaths | null;
|
|
49
|
+
localeListingPaths?: readonly RobotsListingPaths[] | null;
|
|
28
50
|
}, init?: SeoFileResponseInit): Response;
|
|
29
51
|
declare function adsTxtResponse(seo: Pick<BoardSeo, 'adsTxt'>, init?: SeoFileResponseInit): Response;
|
|
30
52
|
declare function indexNowResponse(seo: Pick<BoardSeo, 'indexNowKey'>, init?: SeoFileResponseInit): Response;
|
|
@@ -33,4 +55,4 @@ declare function googleSiteVerificationMeta(token: string | null | undefined): {
|
|
|
33
55
|
content: string;
|
|
34
56
|
} | null;
|
|
35
57
|
|
|
36
|
-
export { ADS_TXT_CACHE_CONTROL, INDEXNOW_CACHE_CONTROL, ROBOTS_CACHE_CONTROL, SEO_FILE_CONTENT_TYPE, type SeoFileResponseInit, adsTxtResponse, googleSiteVerificationMeta, indexNowResponse, robotsBody, robotsResponse };
|
|
58
|
+
export { ADS_TXT_CACHE_CONTROL, INDEXNOW_CACHE_CONTROL, ROBOTS_CACHE_CONTROL, type RobotsListingPaths, SEO_FILE_CONTENT_TYPE, type SeoFileResponseInit, adsTxtResponse, googleSiteVerificationMeta, indexNowResponse, robotsBody, robotsResponse };
|
package/dist/seo-files.js
CHANGED
|
@@ -35,25 +35,54 @@ var SEO_FILE_CONTENT_TYPE = "text/plain; charset=utf-8";
|
|
|
35
35
|
var ROBOTS_CACHE_CONTROL = "public, max-age=600, s-maxage=14400, stale-while-revalidate=86400";
|
|
36
36
|
var ADS_TXT_CACHE_CONTROL = "public, max-age=3600, must-revalidate";
|
|
37
37
|
var INDEXNOW_CACHE_CONTROL = "public, max-age=86400, must-revalidate";
|
|
38
|
+
var DEFAULT_LISTING_PATHS = {
|
|
39
|
+
jobs: "/jobs",
|
|
40
|
+
companies: "/companies",
|
|
41
|
+
talent: "/talent"
|
|
42
|
+
};
|
|
43
|
+
var SAFE_LISTING_ROOT = /^(?:\/[^\s/*$?#]+)+$/;
|
|
44
|
+
function safeListingRoot(value) {
|
|
45
|
+
if (typeof value !== "string") return null;
|
|
46
|
+
const root = value.replace(/\/+$/, "");
|
|
47
|
+
return SAFE_LISTING_ROOT.test(root) ? root : null;
|
|
48
|
+
}
|
|
49
|
+
function listingRoot(value, fallback) {
|
|
50
|
+
return safeListingRoot(value) ?? fallback;
|
|
51
|
+
}
|
|
52
|
+
var LISTING_GROUPS = ["jobs", "companies", "talent"];
|
|
53
|
+
function paginationRules(root) {
|
|
54
|
+
return [
|
|
55
|
+
`Disallow: ${root}?page=`,
|
|
56
|
+
`Disallow: ${root}*&page=`,
|
|
57
|
+
`Disallow: ${root}/*?page=`
|
|
58
|
+
];
|
|
59
|
+
}
|
|
38
60
|
function robotsBody(input) {
|
|
39
61
|
if (input.sandbox) {
|
|
40
62
|
return ["User-Agent: *", "Disallow: /", ""].join("\n");
|
|
41
63
|
}
|
|
42
64
|
const canonicalBase = input.canonicalBase.replace(/\/+$/, "");
|
|
65
|
+
const paths = input.listingPaths ?? {};
|
|
66
|
+
const baseRoots = LISTING_GROUPS.map(
|
|
67
|
+
(group) => listingRoot(paths[group], DEFAULT_LISTING_PATHS[group])
|
|
68
|
+
);
|
|
69
|
+
const seen = new Set(baseRoots);
|
|
70
|
+
const localeRoots = [];
|
|
71
|
+
for (const locale of input.localeListingPaths ?? []) {
|
|
72
|
+
for (const group of LISTING_GROUPS) {
|
|
73
|
+
const root = safeListingRoot(locale[group]);
|
|
74
|
+
if (root === null || seen.has(root)) continue;
|
|
75
|
+
seen.add(root);
|
|
76
|
+
localeRoots.push(root);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
43
79
|
return [
|
|
44
80
|
"User-Agent: *",
|
|
45
81
|
"Allow: /",
|
|
46
82
|
"Disallow: /go/",
|
|
47
83
|
"Disallow: /t/",
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
"Disallow: /jobs/*?page=",
|
|
51
|
-
"Disallow: /companies?page=",
|
|
52
|
-
"Disallow: /companies*&page=",
|
|
53
|
-
"Disallow: /companies/*?page=",
|
|
54
|
-
"Disallow: /talent?page=",
|
|
55
|
-
"Disallow: /talent*&page=",
|
|
56
|
-
"Disallow: /talent/*?page=",
|
|
84
|
+
...baseRoots.flatMap(paginationRules),
|
|
85
|
+
...localeRoots.flatMap(paginationRules),
|
|
57
86
|
"",
|
|
58
87
|
`Sitemap: ${canonicalBase}/sitemap.xml`,
|
|
59
88
|
""
|
|
@@ -61,7 +90,12 @@ function robotsBody(input) {
|
|
|
61
90
|
}
|
|
62
91
|
function robotsResponse(seo, init) {
|
|
63
92
|
return textFileResponse(
|
|
64
|
-
robotsBody({
|
|
93
|
+
robotsBody({
|
|
94
|
+
canonicalBase: seo.canonicalBase,
|
|
95
|
+
sandbox: seo.sandbox,
|
|
96
|
+
listingPaths: seo.listingPaths,
|
|
97
|
+
localeListingPaths: seo.localeListingPaths
|
|
98
|
+
}),
|
|
65
99
|
ROBOTS_CACHE_CONTROL,
|
|
66
100
|
init
|
|
67
101
|
);
|