@cavuno/board 1.2.1 → 1.4.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/dist/bin.mjs ADDED
@@ -0,0 +1,74 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/skills.ts
4
+ import { readFileSync } from "fs";
5
+ import { dirname, resolve } from "path";
6
+ import { fileURLToPath } from "url";
7
+ function packageRoot() {
8
+ return resolve(dirname(fileURLToPath(import.meta.url)), "..");
9
+ }
10
+ function resolveFromPackageRoot(relativePath) {
11
+ return resolve(packageRoot(), relativePath);
12
+ }
13
+ function loadSkillManifest() {
14
+ const manifestPath = resolveFromPackageRoot("skills/manifest.json");
15
+ return JSON.parse(readFileSync(manifestPath, "utf8"));
16
+ }
17
+
18
+ // src/setup/run.ts
19
+ import { cpSync, existsSync, mkdirSync, readFileSync as readFileSync2 } from "fs";
20
+ import { dirname as dirname2, resolve as resolve2 } from "path";
21
+ function detectFramework(cwd) {
22
+ const pkgPath = resolve2(cwd, "package.json");
23
+ if (!existsSync(pkgPath)) return null;
24
+ const pkg = JSON.parse(readFileSync2(pkgPath, "utf8"));
25
+ const deps = { ...pkg.dependencies, ...pkg.devDependencies };
26
+ if (deps["@tanstack/react-start"]) return "tanstack-start";
27
+ return null;
28
+ }
29
+ function runSetup(cwd = process.cwd()) {
30
+ const manifest = loadSkillManifest();
31
+ const framework = detectFramework(cwd);
32
+ const chosen = manifest.skills.filter(
33
+ (skill) => skill.category === "core" || skill.framework === framework
34
+ );
35
+ const targetDir = resolve2(cwd, ".claude", "skills");
36
+ mkdirSync(targetDir, { recursive: true });
37
+ const copied = [];
38
+ for (const skill of chosen) {
39
+ const sourceDir = dirname2(resolveFromPackageRoot(skill.path));
40
+ const destDir = resolve2(targetDir, skill.name);
41
+ mkdirSync(destDir, { recursive: true });
42
+ cpSync(sourceDir, destDir, { recursive: true });
43
+ copied.push(skill.name);
44
+ }
45
+ return { version: manifest.version, framework, targetDir, copied };
46
+ }
47
+
48
+ // src/bin.ts
49
+ function main() {
50
+ if (process.argv[2] !== "setup") {
51
+ console.error("Usage: cavuno-board setup");
52
+ process.exit(1);
53
+ }
54
+ const result = runSetup();
55
+ console.log(`
56
+ @cavuno/board setup \u2014 v${result.version}`);
57
+ console.log(
58
+ `Detected framework: ${result.framework ?? "none (core skills only)"}`
59
+ );
60
+ console.log(`Copied ${result.copied.length} skills \u2192 ${result.targetDir}`);
61
+ for (const name of result.copied) console.log(` - ${name}`);
62
+ console.log("\nNext steps:");
63
+ console.log(" 1. Set your environment variables:");
64
+ console.log(" PUBLIC_CAVUNO_API_URL=https://api.cavuno.com");
65
+ console.log(
66
+ " PUBLIC_CAVUNO_BOARD=pk_... # your board publishable key"
67
+ );
68
+ console.log(' 2. Ask your coding agent: "set up my Cavuno board".');
69
+ console.log(" It reads the cavuno-board-setup skill first.");
70
+ console.log(
71
+ "\n Re-run `npx @cavuno/board setup` after upgrading to refresh skills."
72
+ );
73
+ }
74
+ main();
package/dist/index.d.mts CHANGED
@@ -252,6 +252,8 @@ interface CustomStorage {
252
252
  type StorageMode = 'memory' | 'nostore' | CustomStorage;
253
253
  declare const ACCESS_TOKEN_KEY = "cavuno_board_access_token";
254
254
  declare const REFRESH_TOKEN_KEY = "cavuno_board_refresh_token";
255
+ /** Board-password access grant — sent as `X-Board-Access` to pass the wall. */
256
+ declare const BOARD_ACCESS_GRANT_KEY = "cavuno_board_access_grant";
255
257
 
256
258
  /**
257
259
  * The request handed to `onRequest` and `fetch`. `onRequest` may
@@ -340,6 +342,8 @@ interface PublicBoard {
340
342
  language: string;
341
343
  logoUrl: string | null;
342
344
  primaryDomain: string | null;
345
+ /** Whitelabel toggle (default `true`) — render the "Powered by Cavuno" badge unless `false`. */
346
+ showCavunoBranding: boolean;
343
347
  features: PublicBoardFeatures;
344
348
  analytics: PublicBoardAnalytics;
345
349
  theme: PublicBoardTheme | null;
@@ -364,6 +368,24 @@ interface BoardSeo {
364
368
  * canonical links from it — NOT the request origin.
365
369
  */
366
370
  canonicalBase: string;
371
+ /**
372
+ * Absolute URLs for the board's configured favicons / app icons (null when
373
+ * unset). The variant key implies the role + size; build `<link rel="icon">`
374
+ * tags + the web-manifest icon list from these.
375
+ */
376
+ icons: {
377
+ ico: string | null;
378
+ svg: string | null;
379
+ appleTouch: string | null;
380
+ icon192: string | null;
381
+ icon512: string | null;
382
+ iconMaskable512: string | null;
383
+ };
384
+ /** Web-manifest metadata; assemble `site.webmanifest` from this + `icons`. */
385
+ manifest: {
386
+ name: string;
387
+ themeColor: string;
388
+ };
367
389
  }
368
390
 
369
391
  /**
@@ -402,6 +424,12 @@ declare class BoardApiError extends Error {
402
424
  declare function isBoardApiError(e: unknown): e is BoardApiError;
403
425
  declare function isNotFound(e: unknown): e is BoardApiError;
404
426
  declare function isUnauthorized(e: unknown): e is BoardApiError;
427
+ /**
428
+ * The board is password-protected and the read carried no valid `X-Board-Access`
429
+ * grant. Distinct from an expired board-USER token (also 401): this code means
430
+ * "call `password.verify()` again to mint a fresh grant", not "re-login".
431
+ */
432
+ declare function isBoardPasswordRequired(e: unknown): e is BoardApiError;
405
433
  declare function isForbidden(e: unknown): e is BoardApiError;
406
434
  declare function isValidationError(e: unknown): e is BoardApiError;
407
435
  declare function isRateLimited(e: unknown): e is BoardApiError;
@@ -413,7 +441,7 @@ declare function isConflict(e: unknown): e is BoardApiError;
413
441
  * constant because the package is platform-neutral and cannot read
414
442
  * package.json at runtime.
415
443
  */
416
- declare const SDK_VERSION = "1.2.1";
444
+ declare const SDK_VERSION = "1.4.0";
417
445
 
418
446
  interface BoardUser {
419
447
  id: string;
@@ -464,6 +492,41 @@ interface ResetPasswordBody {
464
492
  password: string;
465
493
  }
466
494
 
495
+ /**
496
+ * Query for `board.embed.jobs()` — the embeddable, UNGATED jobs widget. Mirrors
497
+ * the browse list's facets + geo, plus a free-text `q` keyword (the widget is
498
+ * searchable). Deliberately has NO `category`/`skill` programmatic seeding and
499
+ * NO `fields` sparse fieldset — the embed widget exposes none of those.
500
+ */
501
+ type EmbedJobsQuery = {
502
+ /** Free-text search query, up to 200 characters. */
503
+ q?: string;
504
+ cursor?: string;
505
+ /** Default 8; values above the embed ceiling of 50 are clamped to 50. */
506
+ limit?: number;
507
+ /** Storefront page offset; takes precedence over `cursor`. `offset + limit` ≤ 10,000. */
508
+ offset?: number;
509
+ /** Single or repeated (up to 10) — repeated params are OR-matched. */
510
+ companyId?: string | string[];
511
+ remoteOption?: RemoteOption | RemoteOption[];
512
+ employmentType?: EmploymentType | EmploymentType[];
513
+ seniority?: Seniority | Seniority[];
514
+ /** Place slug for a geo radius search; unresolvable slugs are ignored. */
515
+ location?: string;
516
+ /** Radius in km around `location` (10–250; default 50). */
517
+ radius?: number;
518
+ };
519
+
520
+ /**
521
+ * The board-access grant returned by `password.verify()`. Send `token` as the
522
+ * `X-Board-Access` header on content reads to pass a board's password wall
523
+ * (the SDK does this automatically once the grant is stored).
524
+ */
525
+ interface BoardAccessGrant {
526
+ object: 'board_access_grant';
527
+ token: string;
528
+ }
529
+
467
530
  /**
468
531
  * The result of resolving a path against the board's configured redirects
469
532
  * (`board.redirects.resolve()`). A headless frontend 308s to `target`, or 404s
@@ -477,6 +540,29 @@ interface RedirectResolution {
477
540
  target: string | null;
478
541
  }
479
542
 
543
+ /**
544
+ * A board legal/about page (ADR-0039 transitional portable-prose field). The
545
+ * API serves owner-authored prose as portable HTML; the starter authors the
546
+ * layout + JSON-LD. Impressum additionally carries structured legal-entity
547
+ * facts and is gated by the board's `impressumEnabled` flag (404 when off).
548
+ */
549
+ type LegalPageType = 'terms-of-service' | 'privacy-policy' | 'cookie-policy' | 'about' | 'impressum';
550
+ interface LegalEntity {
551
+ legalName: string | null;
552
+ address: string | null;
553
+ }
554
+ interface PublicLegalPage {
555
+ object: 'legal_page';
556
+ type: string;
557
+ /** Page heading (H1), with `{{board_name}}` resolved. */
558
+ title: string;
559
+ /** Owner-authored prose as portable HTML; `''` when the page has no body. */
560
+ content: string;
561
+ contentFormat: 'html';
562
+ /** Structured impressum facts; `null` for non-impressum pages. */
563
+ legalEntity: LegalEntity | null;
564
+ }
565
+
480
566
  /** Author shape embedded on posts (no `object` discriminator). */
481
567
  interface BlogAuthorEmbed {
482
568
  id: string;
@@ -509,9 +595,13 @@ interface PublicBlogPostSummary {
509
595
  slug: string;
510
596
  featured: boolean;
511
597
  coverUrl: string | null;
598
+ /** Alt text for `coverUrl` (the cover/feature image). */
599
+ featureImageAlt: string | null;
512
600
  customExcerpt: string | null;
513
601
  readingTimeMin: number | null;
514
602
  publishedAt: string | null;
603
+ /** A custom canonical URL override for this post, if set. */
604
+ canonicalUrl: string | null;
515
605
  createdAt: string;
516
606
  authors: BlogAuthorEmbed[];
517
607
  tags: BlogTagEmbed[];
@@ -520,11 +610,22 @@ interface PublicBlogPostSummary {
520
610
  interface PublicBlogPost extends PublicBlogPostSummary {
521
611
  html: string | null;
522
612
  ogImageUrl: string | null;
523
- featureImageAlt: string | null;
524
613
  featureImageCaption: string | null;
525
614
  seoTitle: string | null;
526
615
  seoDescription: string | null;
527
- canonicalUrl: string | null;
616
+ /**
617
+ * Slug-history resolution. When the requested slug is a renamed post's OLD
618
+ * slug, `redirected` is `true` and `newSlug` is the post's current slug —
619
+ * issue a 308 to it. Otherwise `redirected` is `false` and `newSlug` is null.
620
+ */
621
+ redirected: boolean;
622
+ newSlug: string | null;
623
+ }
624
+ /** Previous (older) + next (newer) posts for the detail prev/next nav. */
625
+ interface PublicBlogAdjacentPosts {
626
+ object: 'blog_adjacent_posts';
627
+ previous: PublicBlogPostSummary | null;
628
+ next: PublicBlogPostSummary | null;
528
629
  }
529
630
  type BlogPostsListQuery = {
530
631
  cursor?: string;
@@ -535,6 +636,10 @@ type BlogPostsListQuery = {
535
636
  /** Opt-in only: pass `'true'` to restrict to featured posts. */
536
637
  featured?: 'true';
537
638
  };
639
+ type BlogSimilarQuery = {
640
+ /** 1–20; default 6. */
641
+ limit?: number;
642
+ };
538
643
  interface BlogSearchBody {
539
644
  /** Free-text query, 1–200 characters. Required. */
540
645
  query: string;
@@ -567,6 +672,21 @@ type CompanyJobsListQuery = {
567
672
  /** 1–100. */
568
673
  limit?: number;
569
674
  };
675
+ type CompanySimilarQuery = {
676
+ /** 1–20, default 6. */
677
+ limit?: number;
678
+ };
679
+ interface CompanyMarket {
680
+ object: 'company_market';
681
+ slug: string;
682
+ name: string;
683
+ companyCount: number;
684
+ }
685
+ type CompanyMarketsListQuery = {
686
+ /** 1–200, default 100 (a top-by-company-count preview). */
687
+ limit?: number;
688
+ search?: string;
689
+ };
570
690
  interface CompaniesSearchBody {
571
691
  /** Free-text query, up to 200 characters. */
572
692
  query?: string;
@@ -596,6 +716,109 @@ interface SaveJobBody {
596
716
  jobId: string;
597
717
  }
598
718
 
719
+ type JobAlertFrequency = 'daily' | 'weekly';
720
+ type JobAlertRemoteOption = 'on_site' | 'hybrid' | 'remote';
721
+ /**
722
+ * Alert filters a consumer can capture. Only `jobFunctions` (→ job categories),
723
+ * `placeSlugs` (→ place IDs) and `remoteOptions` scope the digest server-side;
724
+ * `seniorityLevels`/`salary*` are stored but do not filter delivery.
725
+ */
726
+ type JobAlertFiltersInput = {
727
+ jobFunctions?: string[];
728
+ seniorityLevels?: string[];
729
+ remoteOptions?: JobAlertRemoteOption[];
730
+ placeSlugs?: string[];
731
+ salaryMin?: number;
732
+ salaryMax?: number;
733
+ salaryCurrency?: string;
734
+ };
735
+ /** Body for `jobAlerts.subscribe`. `consent` must be `true` (server-enforced). */
736
+ type JobAlertSubscribeInput = {
737
+ email: string;
738
+ consent: true;
739
+ frequency?: JobAlertFrequency;
740
+ filters?: JobAlertFiltersInput;
741
+ /** Scopes the alert to the originating job/search (for the digest + analytics). */
742
+ context?: {
743
+ source?: string;
744
+ jobId?: string;
745
+ jobSlug?: string;
746
+ };
747
+ };
748
+ interface JobAlertSubscription {
749
+ object: 'job_alert_subscription';
750
+ status: 'created' | 'duplicate';
751
+ requiresConfirmation: boolean;
752
+ confirmed: boolean;
753
+ }
754
+ interface JobAlertConfirmation {
755
+ object: 'job_alert_confirmation';
756
+ status: 'confirmed' | 'already_confirmed' | 'expired' | 'not_found';
757
+ }
758
+ interface JobAlertResendResult {
759
+ object: 'job_alert_confirmation_resend';
760
+ status: 'sent' | 'not_found' | 'already_confirmed' | 'throttled' | 'send_failed';
761
+ }
762
+ interface JobAlertManageResult {
763
+ object: 'job_alert_manage_result';
764
+ success: boolean;
765
+ }
766
+ /**
767
+ * The stored filter criteria surfaced on the manage page (a serializable subset
768
+ * of the internal filter object — the fields a consumer renders). `jobFunctions`,
769
+ * `placeIds` and `remoteOptions` are the dimensions the digest actually matches on.
770
+ */
771
+ interface JobAlertStoredFilters {
772
+ jobFunctions?: string[];
773
+ seniorityLevels?: string[];
774
+ remoteOptions?: string[];
775
+ placeIds?: string[];
776
+ salaryMin?: number | null;
777
+ salaryMax?: number | null;
778
+ salaryCurrency?: string | null;
779
+ frequency?: string;
780
+ }
781
+ interface JobAlertPreference {
782
+ id: string;
783
+ label: string | null;
784
+ frequency: string;
785
+ isActive: boolean;
786
+ filters: JobAlertStoredFilters;
787
+ /** Per-preference HMAC token for `updatePreference`/`deletePreference`. */
788
+ manageToken: string;
789
+ }
790
+ interface JobAlertManageState {
791
+ object: 'job_alert_manage_state';
792
+ email: string;
793
+ confirmed: boolean;
794
+ unsubscribed: boolean;
795
+ preferences: JobAlertPreference[];
796
+ }
797
+ /** Query for `jobAlerts.manage` — the HMAC manage token from the digest email. */
798
+ type JobAlertManageQuery = {
799
+ subscription: string;
800
+ token: string;
801
+ };
802
+ /** Body for `jobAlerts.unsubscribe` / `resubscribe` (HMAC manage token). */
803
+ type JobAlertManageTokenInput = {
804
+ subscriptionId: string;
805
+ token: string;
806
+ preferenceId?: string;
807
+ };
808
+ type JobAlertUpdatePreferenceInput = {
809
+ subscriptionId: string;
810
+ preferenceId: string;
811
+ token: string;
812
+ /** Required — the update is a full replace; restate it to avoid resetting cadence. */
813
+ frequency: JobAlertFrequency;
814
+ filters?: JobAlertFiltersInput;
815
+ };
816
+ type JobAlertDeletePreferenceInput = {
817
+ subscriptionId: string;
818
+ preferenceId: string;
819
+ token: string;
820
+ };
821
+
599
822
  interface TaxonomyGeo {
600
823
  lat: number | null;
601
824
  lng: number | null;
@@ -622,6 +845,17 @@ interface TaxonomyResolution {
622
845
  redirectTo: string | null;
623
846
  geo: TaxonomyGeo | null;
624
847
  }
848
+ /**
849
+ * Query for `taxonomy.places.list()`. Omit it (or `q`) for the full locations
850
+ * directory; pass `q` (≥2 chars) for location autocomplete — the top name
851
+ * matches ranked, what a location search field renders.
852
+ */
853
+ type PlacesListQuery = {
854
+ /** Location autocomplete query; ≥2 chars → top name matches, under 2 → empty. */
855
+ q?: string;
856
+ /** Max autocomplete results when `q` is given (1–50; default 10). */
857
+ limit?: number;
858
+ };
625
859
  /**
626
860
  * A place in the board's locations directory (`taxonomy.places.list()` →
627
861
  * `GET /places`), the data the `/jobs/locations/` index renders. `jobCount` is
@@ -701,16 +935,23 @@ declare function createBoardClient(options: CreateBoardClientOptions): {
701
935
  search(body: JobsSearchBody, query?: Record<string, never>, options?: FetchOptions): Promise<JobCardSearchEnvelope>;
702
936
  similar(jobSlug: string, query?: JobsSimilarQuery, options?: FetchOptions): Promise<ListEnvelope<PublicJobCard>>;
703
937
  };
938
+ embed: {
939
+ jobs(query?: EmbedJobsQuery, options?: FetchOptions): Promise<ListEnvelope<PublicJobCard>>;
940
+ };
704
941
  companies: {
705
942
  list(query?: CompaniesListQuery, options?: FetchOptions): Promise<ListEnvelope<PublicCompany>>;
706
943
  retrieve(companySlug: string, query?: Record<string, never>, options?: FetchOptions): Promise<PublicCompany>;
707
944
  search(body: CompaniesSearchBody, query?: Record<string, never>, options?: FetchOptions): Promise<SearchEnvelope<PublicCompany>>;
708
945
  listJobs(companySlug: string, query?: CompanyJobsListQuery, options?: FetchOptions): Promise<JobCardListEnvelope>;
946
+ similar(companySlug: string, query?: CompanySimilarQuery, options?: FetchOptions): Promise<ListEnvelope<PublicCompany>>;
947
+ markets(query?: CompanyMarketsListQuery, options?: FetchOptions): Promise<ListEnvelope<CompanyMarket>>;
709
948
  };
710
949
  blog: {
711
950
  posts: {
712
951
  list(query?: BlogPostsListQuery, options?: FetchOptions): Promise<ListEnvelope<PublicBlogPostSummary>>;
713
952
  retrieve(postSlug: string, query?: Record<string, never>, options?: FetchOptions): Promise<PublicBlogPost>;
953
+ adjacent(postSlug: string, options?: FetchOptions): Promise<PublicBlogAdjacentPosts>;
954
+ similar(postSlug: string, query?: BlogSimilarQuery, options?: FetchOptions): Promise<ListEnvelope<PublicBlogPostSummary>>;
714
955
  };
715
956
  tags: {
716
957
  list(query?: Record<string, never>, options?: FetchOptions): Promise<ListEnvelope<PublicBlogTag>>;
@@ -722,6 +963,9 @@ declare function createBoardClient(options: CreateBoardClientOptions): {
722
963
  };
723
964
  search(body: BlogSearchBody, query?: Record<string, never>, options?: FetchOptions): Promise<SearchEnvelope<PublicBlogPostSummary>>;
724
965
  };
966
+ legal: {
967
+ retrieve(type: LegalPageType, options?: FetchOptions): Promise<PublicLegalPage>;
968
+ };
725
969
  auth: {
726
970
  register(body: RegisterBody, options?: FetchOptions): Promise<BoardAuthSession>;
727
971
  login(body: LoginBody, options?: FetchOptions): Promise<BoardAuthSession>;
@@ -739,6 +983,9 @@ declare function createBoardClient(options: CreateBoardClientOptions): {
739
983
  unsave(jobId: string, query?: Record<string, never>, options?: FetchOptions): Promise<void>;
740
984
  };
741
985
  };
986
+ password: {
987
+ verify(password: string, options?: FetchOptions): Promise<BoardAccessGrant>;
988
+ };
742
989
  taxonomy: {
743
990
  categories: {
744
991
  resolve(slug: string, options?: FetchOptions): Promise<TaxonomyResolution>;
@@ -747,14 +994,28 @@ declare function createBoardClient(options: CreateBoardClientOptions): {
747
994
  resolve(slug: string, options?: FetchOptions): Promise<TaxonomyResolution>;
748
995
  };
749
996
  places: {
750
- list(options?: FetchOptions): Promise<ListEnvelope<PublicPlace>>;
997
+ list(query?: PlacesListQuery, options?: FetchOptions): Promise<ListEnvelope<PublicPlace>>;
751
998
  resolve(slug: string, options?: FetchOptions): Promise<TaxonomyResolution>;
752
999
  };
753
1000
  };
754
1001
  redirects: {
755
1002
  resolve(path: string, options?: FetchOptions): Promise<RedirectResolution>;
756
1003
  };
1004
+ jobAlerts: {
1005
+ subscribe(input: JobAlertSubscribeInput, options?: FetchOptions): Promise<JobAlertSubscription>;
1006
+ confirm(input: {
1007
+ token: string;
1008
+ }, options?: FetchOptions): Promise<JobAlertConfirmation>;
1009
+ resendConfirmation(input: {
1010
+ email: string;
1011
+ }, options?: FetchOptions): Promise<JobAlertResendResult>;
1012
+ manage(query: JobAlertManageQuery, options?: FetchOptions): Promise<JobAlertManageState>;
1013
+ unsubscribe(input: JobAlertManageTokenInput, options?: FetchOptions): Promise<JobAlertManageResult>;
1014
+ resubscribe(input: JobAlertManageTokenInput, options?: FetchOptions): Promise<JobAlertManageResult>;
1015
+ updatePreference(input: JobAlertUpdatePreferenceInput, options?: FetchOptions): Promise<JobAlertManageResult>;
1016
+ deletePreference(input: JobAlertDeletePreferenceInput, options?: FetchOptions): Promise<JobAlertManageResult>;
1017
+ };
757
1018
  };
758
1019
  type BoardSdk = ReturnType<typeof createBoardClient>;
759
1020
 
760
- export { ACCESS_TOKEN_KEY, type Awaitable, type BlogAuthorEmbed, type BlogPostsListQuery, type BlogSearchBody, type BlogTagEmbed, BoardApiError, type BoardAuthSession, BoardClient, type BoardRequest, type BoardSdk, type BoardSeo, type BoardUser, type CompaniesListQuery, type CompaniesSearchBody, type CompanyJobsListQuery, type CreateBoardClientOptions, type CustomStorage, type EducationRequirement, type EmploymentType, type FetchOptions, type ForgotPasswordBody, type JobCardListEnvelope, type JobCardSearchEnvelope, type JobCompany, type JobsListQuery, type JobsSearchBody, type ListEnvelope, type Logger, type LoginBody, type LogoutBody, type OfficeLocation, type PublicBlogAuthor, type PublicBlogPost, type PublicBlogPostSummary, type PublicBlogTag, type PublicBoard, type PublicBoardAnalytics, type PublicBoardFeatures, type PublicBoardTheme, type PublicCompany, type PublicJob, type PublicJobCard, type PublicPlace, REFRESH_TOKEN_KEY, type RedirectResolution, type RefreshBody, type RegisterBody, type RelatedSearch, type RemoteOption, type RemotePermit, type RemoteTimezone, type ResetPasswordBody, SDK_VERSION, type SaveJobBody, type SavedJob, type SavedJobsListQuery, type SearchEnvelope, type Seniority, type StorageMode, type StorefrontPagination, type TaxonomyGeo, type TaxonomyResolution, type VerifyEmailBody, createBoardClient, isBoardApiError, isConflict, isForbidden, isNotFound, isRateLimited, isUnauthorized, isValidationError };
1021
+ export { ACCESS_TOKEN_KEY, type Awaitable, BOARD_ACCESS_GRANT_KEY, type BlogAuthorEmbed, type BlogPostsListQuery, type BlogSearchBody, type BlogSimilarQuery, type BlogTagEmbed, type BoardAccessGrant, BoardApiError, type BoardAuthSession, BoardClient, type BoardRequest, type BoardSdk, type BoardSeo, type BoardUser, type CompaniesListQuery, type CompaniesSearchBody, type CompanyJobsListQuery, type CompanyMarket, type CompanyMarketsListQuery, type CompanySimilarQuery, type CreateBoardClientOptions, type CustomStorage, type EducationRequirement, type EmbedJobsQuery, type EmploymentType, type FetchOptions, type ForgotPasswordBody, type JobAlertConfirmation, type JobAlertDeletePreferenceInput, type JobAlertFiltersInput, type JobAlertFrequency, type JobAlertManageQuery, type JobAlertManageResult, type JobAlertManageState, type JobAlertManageTokenInput, type JobAlertPreference, type JobAlertRemoteOption, type JobAlertResendResult, type JobAlertStoredFilters, type JobAlertSubscribeInput, type JobAlertSubscription, type JobAlertUpdatePreferenceInput, type JobCardListEnvelope, type JobCardSearchEnvelope, type JobCompany, type JobsListQuery, type JobsSearchBody, type LegalEntity, type LegalPageType, type ListEnvelope, type Logger, type LoginBody, type LogoutBody, type OfficeLocation, type PlacesListQuery, type PublicBlogAdjacentPosts, type PublicBlogAuthor, type PublicBlogPost, type PublicBlogPostSummary, type PublicBlogTag, type PublicBoard, type PublicBoardAnalytics, type PublicBoardFeatures, type PublicBoardTheme, type PublicCompany, type PublicJob, type PublicJobCard, type PublicLegalPage, type PublicPlace, REFRESH_TOKEN_KEY, type RedirectResolution, type RefreshBody, type RegisterBody, type RelatedSearch, type RemoteOption, type RemotePermit, type RemoteTimezone, type ResetPasswordBody, SDK_VERSION, type SaveJobBody, type SavedJob, type SavedJobsListQuery, type SearchEnvelope, type Seniority, type StorageMode, type StorefrontPagination, type TaxonomyGeo, type TaxonomyResolution, type VerifyEmailBody, createBoardClient, isBoardApiError, isBoardPasswordRequired, isConflict, isForbidden, isNotFound, isRateLimited, isUnauthorized, isValidationError };