@cavuno/board 1.22.0 → 1.24.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/index.js CHANGED
@@ -149,7 +149,7 @@ async function clearSession(storage) {
149
149
  }
150
150
 
151
151
  // src/version.ts
152
- var SDK_VERSION = "1.22.0";
152
+ var SDK_VERSION = "1.24.0";
153
153
 
154
154
  // src/client.ts
155
155
  function isRawBody(body) {
@@ -1804,6 +1804,329 @@ function meNamespace(client) {
1804
1804
  { ...options, method: "DELETE", query }
1805
1805
  );
1806
1806
  }
1807
+ },
1808
+ /**
1809
+ * The authenticated board user's messaging inbox (doc 34 / ADR-0053).
1810
+ * The v1 surface is polled REST — there is no realtime primitive; poll
1811
+ * `list` / `listMessages` / `unreadCount` on an interval (3–5s is the
1812
+ * reference cadence) for near-live updates.
1813
+ */
1814
+ conversations: {
1815
+ /**
1816
+ * List my conversations (each page sorted most-recent-activity-first;
1817
+ * cross-page cursor order is approximate — see the API docs). `archived:
1818
+ * true` returns the archived view. Poll for inbox liveness.
1819
+ *
1820
+ * @example
1821
+ * const { data } = await board.me.conversations.list({ limit: 20 });
1822
+ */
1823
+ list(query, options) {
1824
+ return client.fetch("/me/conversations", {
1825
+ ...options,
1826
+ query
1827
+ });
1828
+ },
1829
+ /**
1830
+ * The count of distinct conversations with an unread message — the
1831
+ * inbox badge. Poll for liveness.
1832
+ *
1833
+ * @example
1834
+ * const { count } = await board.me.conversations.unreadCount();
1835
+ */
1836
+ unreadCount(options) {
1837
+ return client.fetch(
1838
+ "/me/conversations/unread-count",
1839
+ options
1840
+ );
1841
+ },
1842
+ /**
1843
+ * A conversation's header — live-resolved counterparty identity, the
1844
+ * viewer's role, and the viewer's last-read pointer. The messages are a
1845
+ * separate paginated call (`listMessages`).
1846
+ *
1847
+ * @example
1848
+ * const convo = await board.me.conversations.retrieve(id);
1849
+ */
1850
+ retrieve(id, options) {
1851
+ return client.fetch(
1852
+ `/me/conversations/${encodeURIComponent(id)}`,
1853
+ options
1854
+ );
1855
+ },
1856
+ /**
1857
+ * A conversation's messages, oldest-first (append order). Unsent
1858
+ * messages are tombstones (empty `body`, `deletedAt` set). Poll for the
1859
+ * live thread.
1860
+ *
1861
+ * @example
1862
+ * const { data } = await board.me.conversations.listMessages(id, { limit: 50 });
1863
+ */
1864
+ listMessages(id, query, options) {
1865
+ return client.fetch(
1866
+ `/me/conversations/${encodeURIComponent(id)}/messages`,
1867
+ { ...options, query }
1868
+ );
1869
+ },
1870
+ /**
1871
+ * Cold-initiate a conversation with a candidate (employer-only).
1872
+ * Converges on the existing thread. Returns the created message.
1873
+ *
1874
+ * @example
1875
+ * const msg = await board.me.conversations.start({ candidateBoardUserId, body: 'Hi!' });
1876
+ */
1877
+ start(body, options) {
1878
+ return client.fetch("/me/conversations", {
1879
+ ...options,
1880
+ method: "POST",
1881
+ body
1882
+ });
1883
+ },
1884
+ /**
1885
+ * Message an applicant from the ATS (application context, outside the
1886
+ * talent paywall). Returns the created message.
1887
+ *
1888
+ * @example
1889
+ * const msg = await board.me.conversations.startAboutApplication({ applicationId, body: '…' });
1890
+ */
1891
+ startAboutApplication(body, options) {
1892
+ return client.fetch("/me/conversations/about-application", {
1893
+ ...options,
1894
+ method: "POST",
1895
+ body
1896
+ });
1897
+ },
1898
+ /**
1899
+ * Reply in an existing conversation. Returns the created message.
1900
+ *
1901
+ * @example
1902
+ * const msg = await board.me.conversations.reply(id, { body: 'Sounds good' });
1903
+ */
1904
+ reply(id, body, options) {
1905
+ return client.fetch(
1906
+ `/me/conversations/${encodeURIComponent(id)}/reply`,
1907
+ { ...options, method: "POST", body }
1908
+ );
1909
+ },
1910
+ /**
1911
+ * Mark a conversation read for the viewer. Idempotent.
1912
+ *
1913
+ * @example
1914
+ * await board.me.conversations.markRead(id);
1915
+ */
1916
+ markRead(id, options) {
1917
+ return client.fetch(
1918
+ `/me/conversations/${encodeURIComponent(id)}/read`,
1919
+ { ...options, method: "POST" }
1920
+ );
1921
+ },
1922
+ /**
1923
+ * Archive a conversation for the viewer (per-side). Idempotent.
1924
+ *
1925
+ * @example
1926
+ * await board.me.conversations.archive(id);
1927
+ */
1928
+ archive(id, options) {
1929
+ return client.fetch(
1930
+ `/me/conversations/${encodeURIComponent(id)}/archive`,
1931
+ { ...options, method: "POST" }
1932
+ );
1933
+ },
1934
+ /**
1935
+ * Move an archived conversation back to the main inbox. Idempotent.
1936
+ *
1937
+ * @example
1938
+ * await board.me.conversations.unarchive(id);
1939
+ */
1940
+ unarchive(id, options) {
1941
+ return client.fetch(
1942
+ `/me/conversations/${encodeURIComponent(id)}/unarchive`,
1943
+ { ...options, method: "POST" }
1944
+ );
1945
+ },
1946
+ /**
1947
+ * The existing employer↔candidate conversation id (or null). Tier-3
1948
+ * talent-contact helper — route to an existing thread instead of opening
1949
+ * a composer.
1950
+ *
1951
+ * @example
1952
+ * const { conversationId } = await board.me.conversations.findExisting({ candidateBoardUserId });
1953
+ */
1954
+ findExisting(query, options) {
1955
+ return client.fetch(
1956
+ "/me/conversations/find-existing",
1957
+ { ...options, query }
1958
+ );
1959
+ }
1960
+ },
1961
+ /**
1962
+ * Blocking (doc 34 §E): list / add / remove blocks + a Tier-3 status check.
1963
+ */
1964
+ blocks: {
1965
+ /**
1966
+ * The users I've blocked.
1967
+ *
1968
+ * @example
1969
+ * const { data } = await board.me.blocks.list();
1970
+ */
1971
+ list(options) {
1972
+ return client.fetch("/me/blocks", options);
1973
+ },
1974
+ /**
1975
+ * Block a user (silent). Idempotent.
1976
+ *
1977
+ * @example
1978
+ * await board.me.blocks.create({ boardUserId });
1979
+ */
1980
+ create(body, options) {
1981
+ return client.fetch("/me/blocks", {
1982
+ ...options,
1983
+ method: "POST",
1984
+ body
1985
+ });
1986
+ },
1987
+ /**
1988
+ * Unblock a user. Idempotent.
1989
+ *
1990
+ * @example
1991
+ * await board.me.blocks.remove(boardUserId);
1992
+ */
1993
+ remove(boardUserId, options) {
1994
+ return client.fetch(
1995
+ `/me/blocks/${encodeURIComponent(boardUserId)}`,
1996
+ { ...options, method: "DELETE" }
1997
+ );
1998
+ },
1999
+ /**
2000
+ * Whether I've blocked a user (Tier-3 helper).
2001
+ *
2002
+ * @example
2003
+ * const { blocked } = await board.me.blocks.status(boardUserId);
2004
+ */
2005
+ status(boardUserId, options) {
2006
+ return client.fetch(
2007
+ `/me/blocks/${encodeURIComponent(boardUserId)}`,
2008
+ options
2009
+ );
2010
+ }
2011
+ },
2012
+ /**
2013
+ * Message-scoped actions (doc 34 §E): edit / unsend your own messages
2014
+ * (15-minute window), and report a message addressed to you.
2015
+ */
2016
+ messages: {
2017
+ /**
2018
+ * Edit one of your own messages (within the 15-minute window). Returns
2019
+ * the updated message.
2020
+ *
2021
+ * @example
2022
+ * const msg = await board.me.messages.edit(id, { body: 'fixed typo' });
2023
+ */
2024
+ edit(id, body, options) {
2025
+ return client.fetch(`/me/messages/${encodeURIComponent(id)}`, {
2026
+ ...options,
2027
+ method: "PATCH",
2028
+ body
2029
+ });
2030
+ },
2031
+ /**
2032
+ * Unsend (soft-delete) one of your own messages (within the 15-minute
2033
+ * window). Idempotent. Returns the tombstoned message (empty `body`).
2034
+ *
2035
+ * @example
2036
+ * await board.me.messages.unsend(id);
2037
+ */
2038
+ unsend(id, options) {
2039
+ return client.fetch(`/me/messages/${encodeURIComponent(id)}`, {
2040
+ ...options,
2041
+ method: "DELETE"
2042
+ });
2043
+ },
2044
+ /**
2045
+ * Report a message addressed to you for moderation. Auto-blocks the
2046
+ * author.
2047
+ *
2048
+ * @example
2049
+ * const { blocked } = await board.me.messages.report(id, { reason: 'spam' });
2050
+ */
2051
+ report(id, body, options) {
2052
+ return client.fetch(
2053
+ `/me/messages/${encodeURIComponent(id)}/report`,
2054
+ { ...options, method: "POST", body }
2055
+ );
2056
+ }
2057
+ },
2058
+ /**
2059
+ * The candidate job-access paywall — the authenticated money flow (doc 36 /
2060
+ * ADR-0056). Enumerate offers publicly with `board.paywall.offers()`, then
2061
+ * `checkout` here; poll `retrieveCheckout` until complete and confirm with
2062
+ * `grant`. The SDK stays Stripe-agnostic — `checkout` returns a mount kit
2063
+ * and the frontend brings `@stripe/stripe-js`.
2064
+ */
2065
+ access: {
2066
+ /**
2067
+ * Start an embedded checkout for one offer and return a connected-account
2068
+ * mount kit `{ sessionId, clientSecret, stripeAccountId, publishableKey,
2069
+ * offerType }`. `returnPath` is a safe relative path. Requires a candidate
2070
+ * profile.
2071
+ *
2072
+ * @example
2073
+ * const kit = await board.me.access.checkout({
2074
+ * offerKey: 'monthly',
2075
+ * returnPath: '/account/access',
2076
+ * colorMode: 'light',
2077
+ * });
2078
+ * const stripe = await loadStripe(kit.publishableKey, {
2079
+ * stripeAccount: kit.stripeAccountId,
2080
+ * });
2081
+ */
2082
+ checkout(body, options) {
2083
+ return client.fetch("/me/access/checkout", {
2084
+ ...options,
2085
+ method: "POST",
2086
+ body
2087
+ });
2088
+ },
2089
+ /**
2090
+ * Poll a checkout session's state: `open` (re-mountable via
2091
+ * `clientSecret`), `complete`, or `expired`. On `complete`, re-read
2092
+ * `grant()` to confirm entitlement.
2093
+ *
2094
+ * @example
2095
+ * const s = await board.me.access.retrieveCheckout(kit.sessionId);
2096
+ */
2097
+ retrieveCheckout(sessionId, options) {
2098
+ return client.fetch(
2099
+ `/me/access/checkout/${encodeURIComponent(sessionId)}`,
2100
+ options
2101
+ );
2102
+ },
2103
+ /**
2104
+ * The viewer's candidate-access entitlement — always resolves (no-access
2105
+ * is `{ hasAccess: false, … }`, not an error). Gate the ungated jobs
2106
+ * listing on `hasAccess`.
2107
+ *
2108
+ * @example
2109
+ * const { hasAccess } = await board.me.access.grant();
2110
+ */
2111
+ grant(options) {
2112
+ return client.fetch("/me/access/grant", options);
2113
+ },
2114
+ /**
2115
+ * Open a Stripe billing-portal session to manage a recurring subscription
2116
+ * (only when the grant's `offerType` is `recurring`). Optional
2117
+ * `returnPath` threads through to Stripe's return URL.
2118
+ *
2119
+ * @example
2120
+ * const { url } = await board.me.access.portal({ returnPath: '/account' });
2121
+ * location.href = url;
2122
+ */
2123
+ portal(body, options) {
2124
+ return client.fetch("/me/access/portal", {
2125
+ ...options,
2126
+ method: "POST",
2127
+ body
2128
+ });
2129
+ }
1807
2130
  }
1808
2131
  };
1809
2132
  }
@@ -1832,6 +2155,27 @@ function passwordNamespace(client) {
1832
2155
  };
1833
2156
  }
1834
2157
 
2158
+ // src/namespaces/paywall.ts
2159
+ function paywallNamespace(client) {
2160
+ return {
2161
+ /**
2162
+ * List the board's enabled candidate-access paywall offers (public) — the
2163
+ * pricing tiers a candidate picks before starting checkout
2164
+ * (`board.me.access.checkout`). Returns `[]` when the paywall is disabled.
2165
+ * The internal Stripe price id is never exposed.
2166
+ *
2167
+ * @example
2168
+ * const { data } = await board.paywall.offers();
2169
+ */
2170
+ offers(options) {
2171
+ return client.fetch(
2172
+ "/paywall/offers/enabled",
2173
+ options
2174
+ );
2175
+ }
2176
+ };
2177
+ }
2178
+
1835
2179
  // src/namespaces/plans.ts
1836
2180
  function plansNamespace(client) {
1837
2181
  return {
@@ -2108,6 +2452,7 @@ function createBoardClient(options) {
2108
2452
  jobPosting: jobPostingNamespace(client),
2109
2453
  salaries: salariesNamespace(client),
2110
2454
  talent: talentNamespace(client),
2111
- plans: plansNamespace(client)
2455
+ plans: plansNamespace(client),
2456
+ paywall: paywallNamespace(client)
2112
2457
  };
2113
2458
  }