@burdenoff/website-sdk 2026.1021.1 → 2026.1021.3
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 +58 -0
- package/dist/components/partners.js.map +1 -1
- package/dist/components/partners.mjs.map +1 -1
- package/dist/content/index.d.mts +1 -1
- package/dist/content/index.d.ts +1 -1
- package/dist/content/index.js +421 -198
- package/dist/content/index.js.map +1 -1
- package/dist/content/index.mjs +414 -199
- package/dist/content/index.mjs.map +1 -1
- package/dist/{index-ySbOLSD5.d.ts → index-CB0Uw1xD.d.ts} +108 -1
- package/dist/{index-gm3pBCJT.d.mts → index-Ctws7kGs.d.mts} +108 -1
- package/dist/index.d.mts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +227 -4
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +220 -5
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
|
@@ -88,6 +88,12 @@ interface ContentPageListData {
|
|
|
88
88
|
interface UseContentPageOptions {
|
|
89
89
|
/** Whether to use template variable replacement (resolvedContentPage) */
|
|
90
90
|
resolve?: boolean;
|
|
91
|
+
/**
|
|
92
|
+
* Set to `false` to skip the request entirely — e.g. when the page was
|
|
93
|
+
* already fetched at build time. The hook then settles immediately with
|
|
94
|
+
* `data: null`, `loading: false`. Defaults to `true`.
|
|
95
|
+
*/
|
|
96
|
+
enabled?: boolean;
|
|
91
97
|
}
|
|
92
98
|
/**
|
|
93
99
|
* Hook to fetch a single public content page by slug.
|
|
@@ -165,6 +171,107 @@ interface MarkdownProps {
|
|
|
165
171
|
*/
|
|
166
172
|
declare function Markdown({ children, className, inline, components, rehypePlugins, }: MarkdownProps): ReactNode;
|
|
167
173
|
|
|
174
|
+
/** The legal documents every product website is expected to publish. */
|
|
175
|
+
type LegalDocumentKey = "privacy" | "terms" | "cookies" | "refunds" | "aup" | "dpa" | "ai-terms" | "subprocessors";
|
|
176
|
+
interface LegalDocument {
|
|
177
|
+
key: LegalDocumentKey;
|
|
178
|
+
/** CMS slug (`ProductContentPage.slug`), shared by every product. */
|
|
179
|
+
slug: string;
|
|
180
|
+
/** Title used when the CMS row has none, or cannot be loaded. */
|
|
181
|
+
title: string;
|
|
182
|
+
/** Meta description used when the CMS row has no `seoDescription`. */
|
|
183
|
+
description: string;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Canonical CMS slugs for the legal set. Website routes may differ per site
|
|
187
|
+
* (`/privacy` or `/legal/privacy`); the slug never does.
|
|
188
|
+
*/
|
|
189
|
+
declare const LEGAL_DOCUMENTS: Readonly<Record<LegalDocumentKey, LegalDocument>>;
|
|
190
|
+
/** Every legal document key, in display order. */
|
|
191
|
+
declare const LEGAL_DOCUMENT_KEYS: readonly LegalDocumentKey[];
|
|
192
|
+
/** Look up a legal document by its key or its CMS slug. */
|
|
193
|
+
declare function findLegalDocument(keyOrSlug: string): LegalDocument | null;
|
|
194
|
+
/** A legal page as fetched from the CMS (and as stored in build-time JSON). */
|
|
195
|
+
interface LegalContentEntry {
|
|
196
|
+
title: string;
|
|
197
|
+
slug: string;
|
|
198
|
+
content: string;
|
|
199
|
+
contentFormat: string;
|
|
200
|
+
seoTitle?: string | null;
|
|
201
|
+
seoDescription?: string | null;
|
|
202
|
+
seoKeywords?: string | null;
|
|
203
|
+
lastUpdated?: string | null;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Fetch one legal page for a product. `productId` may be the product UUID or
|
|
207
|
+
* its slug. Resolves to `null` when neither the product nor the global
|
|
208
|
+
* template has the page; rejects on GraphQL or transport errors, so a build
|
|
209
|
+
* script can keep its previous cache instead of publishing an empty page.
|
|
210
|
+
*/
|
|
211
|
+
declare function fetchLegalContentPage(client: WebSDKClient, slug: string, productId: string): Promise<LegalContentEntry | null>;
|
|
212
|
+
interface FetchLegalContentOptions {
|
|
213
|
+
/** Product UUID or slug. */
|
|
214
|
+
productId: string;
|
|
215
|
+
/** Documents to fetch. Defaults to the full legal set. */
|
|
216
|
+
documents?: readonly LegalDocumentKey[];
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Fetch a product's legal pages, keyed by CMS slug. Pages the CMS does not
|
|
220
|
+
* have are `null`. Rejects if any request fails, so callers never mistake an
|
|
221
|
+
* outage for a missing page.
|
|
222
|
+
*
|
|
223
|
+
* @example
|
|
224
|
+
* ```ts
|
|
225
|
+
* // scripts/fetch-legal-content.ts (build time)
|
|
226
|
+
* const client = new WebSDKClient({
|
|
227
|
+
* gatewayUrl: 'https://graphql.burdenoff.com/global/graphql',
|
|
228
|
+
* productId: 'vibecontrols',
|
|
229
|
+
* })
|
|
230
|
+
* const pages = await fetchLegalContent(client, { productId: 'vibecontrols' })
|
|
231
|
+
* writeFileSync('src/data/legal-content.json', JSON.stringify(pages, null, 2))
|
|
232
|
+
* ```
|
|
233
|
+
*/
|
|
234
|
+
declare function fetchLegalContent(client: WebSDKClient, options: FetchLegalContentOptions): Promise<Record<string, LegalContentEntry | null>>;
|
|
235
|
+
/**
|
|
236
|
+
* Split a leading `# Heading` off markdown content. The CMS documents start
|
|
237
|
+
* with their own H1; the page renders the title itself, so keeping both would
|
|
238
|
+
* put two H1s on the page.
|
|
239
|
+
*/
|
|
240
|
+
declare function splitLeadingHeading(content: string, format: string): {
|
|
241
|
+
heading: string | null;
|
|
242
|
+
body: string;
|
|
243
|
+
};
|
|
244
|
+
/**
|
|
245
|
+
* Format an ISO date as "October 21, 2026". UTC, so prerendered HTML and the
|
|
246
|
+
* hydrated page agree whatever the visitor's time zone. Returns `null` for a
|
|
247
|
+
* missing or unparsable date.
|
|
248
|
+
*/
|
|
249
|
+
declare function formatLegalDate(iso: string | null | undefined): string | null;
|
|
250
|
+
interface LegalPageProps {
|
|
251
|
+
/** Which legal document to show. Use `slug` instead for a non-standard page. */
|
|
252
|
+
document?: LegalDocumentKey;
|
|
253
|
+
/** CMS slug, for a page outside {@link LEGAL_DOCUMENTS}. Ignored when `document` is set. */
|
|
254
|
+
slug?: string;
|
|
255
|
+
/**
|
|
256
|
+
* Content fetched at build time (see {@link fetchLegalContent}). When this
|
|
257
|
+
* prop is present the page makes no request; pass `null` for a page the
|
|
258
|
+
* build found missing.
|
|
259
|
+
*/
|
|
260
|
+
initialContent?: LegalContentEntry | null;
|
|
261
|
+
/** Overrides the registry title used when the CMS row has none. */
|
|
262
|
+
fallbackTitle?: string;
|
|
263
|
+
/** Overrides the registry description used when the CMS row has none. */
|
|
264
|
+
fallbackDescription?: string;
|
|
265
|
+
/** Product/brand name appended to the browser title. */
|
|
266
|
+
productName?: string;
|
|
267
|
+
/** Canonical URL of this page. */
|
|
268
|
+
canonicalUrl?: string;
|
|
269
|
+
/** Address shown when the document cannot be loaded. */
|
|
270
|
+
contactEmail?: string;
|
|
271
|
+
className?: string;
|
|
272
|
+
}
|
|
273
|
+
declare function LegalPage(props: LegalPageProps): react.JSX.Element;
|
|
274
|
+
|
|
168
275
|
interface PublicInterviewRoundConfig {
|
|
169
276
|
roundNumber: number;
|
|
170
277
|
name: string;
|
|
@@ -427,4 +534,4 @@ interface ContractsPageProps {
|
|
|
427
534
|
}
|
|
428
535
|
declare function ContractsPage(props: ContractsPageProps): react.JSX.Element;
|
|
429
536
|
|
|
430
|
-
export {
|
|
537
|
+
export { type PressKitAssetCategory as A, BlogListPage as B, type CareersPostingOption as C, PressKitPage as D, type PressKitPageProps as E, type FetchLegalContentOptions as F, type PublicInterviewRoundConfig as G, type PublicJobPosting as H, type UsePublicJobPostingsOptions as I, fetchLegalContent as J, fetchLegalContentPage as K, LEGAL_DOCUMENTS as L, Markdown as M, fetchPublicJobPosting as N, fetchPublicJobPostings as O, type PressKitAsset as P, fetchPublicJobPostingsForSubmission as Q, findLegalDocument as R, formatLegalDate as S, splitLeadingHeading as T, type UsePublicJobPostingOptions as U, useContentPage as V, useContentPages as W, usePublicJobPosting as X, usePublicJobPostings as Y, usePublicJobPostingsForSubmission as Z, type UseContentPageOptions as _, type BlogListPageProps as a, BlogPostPage as b, type BlogPostPageProps as c, CareersApplyForm as d, type CareersApplyFormProps as e, CaseStudiesListPage as f, type CaseStudiesListPageProps as g, CaseStudyPage as h, type CaseStudyPageProps as i, type ChangelogEntry as j, ChangelogPage as k, type ChangelogPageProps as l, type ContentPageData as m, type ContentPageListData as n, type ContentPageListItem as o, ContentRenderer as p, type ContractAsset as q, ContractsPage as r, type ContractsPageProps as s, LEGAL_DOCUMENT_KEYS as t, type LegalContentEntry as u, type LegalDocument as v, type LegalDocumentKey as w, LegalPage as x, type LegalPageProps as y, type MarkdownProps as z };
|
|
@@ -88,6 +88,12 @@ interface ContentPageListData {
|
|
|
88
88
|
interface UseContentPageOptions {
|
|
89
89
|
/** Whether to use template variable replacement (resolvedContentPage) */
|
|
90
90
|
resolve?: boolean;
|
|
91
|
+
/**
|
|
92
|
+
* Set to `false` to skip the request entirely — e.g. when the page was
|
|
93
|
+
* already fetched at build time. The hook then settles immediately with
|
|
94
|
+
* `data: null`, `loading: false`. Defaults to `true`.
|
|
95
|
+
*/
|
|
96
|
+
enabled?: boolean;
|
|
91
97
|
}
|
|
92
98
|
/**
|
|
93
99
|
* Hook to fetch a single public content page by slug.
|
|
@@ -165,6 +171,107 @@ interface MarkdownProps {
|
|
|
165
171
|
*/
|
|
166
172
|
declare function Markdown({ children, className, inline, components, rehypePlugins, }: MarkdownProps): ReactNode;
|
|
167
173
|
|
|
174
|
+
/** The legal documents every product website is expected to publish. */
|
|
175
|
+
type LegalDocumentKey = "privacy" | "terms" | "cookies" | "refunds" | "aup" | "dpa" | "ai-terms" | "subprocessors";
|
|
176
|
+
interface LegalDocument {
|
|
177
|
+
key: LegalDocumentKey;
|
|
178
|
+
/** CMS slug (`ProductContentPage.slug`), shared by every product. */
|
|
179
|
+
slug: string;
|
|
180
|
+
/** Title used when the CMS row has none, or cannot be loaded. */
|
|
181
|
+
title: string;
|
|
182
|
+
/** Meta description used when the CMS row has no `seoDescription`. */
|
|
183
|
+
description: string;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Canonical CMS slugs for the legal set. Website routes may differ per site
|
|
187
|
+
* (`/privacy` or `/legal/privacy`); the slug never does.
|
|
188
|
+
*/
|
|
189
|
+
declare const LEGAL_DOCUMENTS: Readonly<Record<LegalDocumentKey, LegalDocument>>;
|
|
190
|
+
/** Every legal document key, in display order. */
|
|
191
|
+
declare const LEGAL_DOCUMENT_KEYS: readonly LegalDocumentKey[];
|
|
192
|
+
/** Look up a legal document by its key or its CMS slug. */
|
|
193
|
+
declare function findLegalDocument(keyOrSlug: string): LegalDocument | null;
|
|
194
|
+
/** A legal page as fetched from the CMS (and as stored in build-time JSON). */
|
|
195
|
+
interface LegalContentEntry {
|
|
196
|
+
title: string;
|
|
197
|
+
slug: string;
|
|
198
|
+
content: string;
|
|
199
|
+
contentFormat: string;
|
|
200
|
+
seoTitle?: string | null;
|
|
201
|
+
seoDescription?: string | null;
|
|
202
|
+
seoKeywords?: string | null;
|
|
203
|
+
lastUpdated?: string | null;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Fetch one legal page for a product. `productId` may be the product UUID or
|
|
207
|
+
* its slug. Resolves to `null` when neither the product nor the global
|
|
208
|
+
* template has the page; rejects on GraphQL or transport errors, so a build
|
|
209
|
+
* script can keep its previous cache instead of publishing an empty page.
|
|
210
|
+
*/
|
|
211
|
+
declare function fetchLegalContentPage(client: WebSDKClient, slug: string, productId: string): Promise<LegalContentEntry | null>;
|
|
212
|
+
interface FetchLegalContentOptions {
|
|
213
|
+
/** Product UUID or slug. */
|
|
214
|
+
productId: string;
|
|
215
|
+
/** Documents to fetch. Defaults to the full legal set. */
|
|
216
|
+
documents?: readonly LegalDocumentKey[];
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Fetch a product's legal pages, keyed by CMS slug. Pages the CMS does not
|
|
220
|
+
* have are `null`. Rejects if any request fails, so callers never mistake an
|
|
221
|
+
* outage for a missing page.
|
|
222
|
+
*
|
|
223
|
+
* @example
|
|
224
|
+
* ```ts
|
|
225
|
+
* // scripts/fetch-legal-content.ts (build time)
|
|
226
|
+
* const client = new WebSDKClient({
|
|
227
|
+
* gatewayUrl: 'https://graphql.burdenoff.com/global/graphql',
|
|
228
|
+
* productId: 'vibecontrols',
|
|
229
|
+
* })
|
|
230
|
+
* const pages = await fetchLegalContent(client, { productId: 'vibecontrols' })
|
|
231
|
+
* writeFileSync('src/data/legal-content.json', JSON.stringify(pages, null, 2))
|
|
232
|
+
* ```
|
|
233
|
+
*/
|
|
234
|
+
declare function fetchLegalContent(client: WebSDKClient, options: FetchLegalContentOptions): Promise<Record<string, LegalContentEntry | null>>;
|
|
235
|
+
/**
|
|
236
|
+
* Split a leading `# Heading` off markdown content. The CMS documents start
|
|
237
|
+
* with their own H1; the page renders the title itself, so keeping both would
|
|
238
|
+
* put two H1s on the page.
|
|
239
|
+
*/
|
|
240
|
+
declare function splitLeadingHeading(content: string, format: string): {
|
|
241
|
+
heading: string | null;
|
|
242
|
+
body: string;
|
|
243
|
+
};
|
|
244
|
+
/**
|
|
245
|
+
* Format an ISO date as "October 21, 2026". UTC, so prerendered HTML and the
|
|
246
|
+
* hydrated page agree whatever the visitor's time zone. Returns `null` for a
|
|
247
|
+
* missing or unparsable date.
|
|
248
|
+
*/
|
|
249
|
+
declare function formatLegalDate(iso: string | null | undefined): string | null;
|
|
250
|
+
interface LegalPageProps {
|
|
251
|
+
/** Which legal document to show. Use `slug` instead for a non-standard page. */
|
|
252
|
+
document?: LegalDocumentKey;
|
|
253
|
+
/** CMS slug, for a page outside {@link LEGAL_DOCUMENTS}. Ignored when `document` is set. */
|
|
254
|
+
slug?: string;
|
|
255
|
+
/**
|
|
256
|
+
* Content fetched at build time (see {@link fetchLegalContent}). When this
|
|
257
|
+
* prop is present the page makes no request; pass `null` for a page the
|
|
258
|
+
* build found missing.
|
|
259
|
+
*/
|
|
260
|
+
initialContent?: LegalContentEntry | null;
|
|
261
|
+
/** Overrides the registry title used when the CMS row has none. */
|
|
262
|
+
fallbackTitle?: string;
|
|
263
|
+
/** Overrides the registry description used when the CMS row has none. */
|
|
264
|
+
fallbackDescription?: string;
|
|
265
|
+
/** Product/brand name appended to the browser title. */
|
|
266
|
+
productName?: string;
|
|
267
|
+
/** Canonical URL of this page. */
|
|
268
|
+
canonicalUrl?: string;
|
|
269
|
+
/** Address shown when the document cannot be loaded. */
|
|
270
|
+
contactEmail?: string;
|
|
271
|
+
className?: string;
|
|
272
|
+
}
|
|
273
|
+
declare function LegalPage(props: LegalPageProps): react.JSX.Element;
|
|
274
|
+
|
|
168
275
|
interface PublicInterviewRoundConfig {
|
|
169
276
|
roundNumber: number;
|
|
170
277
|
name: string;
|
|
@@ -427,4 +534,4 @@ interface ContractsPageProps {
|
|
|
427
534
|
}
|
|
428
535
|
declare function ContractsPage(props: ContractsPageProps): react.JSX.Element;
|
|
429
536
|
|
|
430
|
-
export {
|
|
537
|
+
export { type PressKitAssetCategory as A, BlogListPage as B, type CareersPostingOption as C, PressKitPage as D, type PressKitPageProps as E, type FetchLegalContentOptions as F, type PublicInterviewRoundConfig as G, type PublicJobPosting as H, type UsePublicJobPostingsOptions as I, fetchLegalContent as J, fetchLegalContentPage as K, LEGAL_DOCUMENTS as L, Markdown as M, fetchPublicJobPosting as N, fetchPublicJobPostings as O, type PressKitAsset as P, fetchPublicJobPostingsForSubmission as Q, findLegalDocument as R, formatLegalDate as S, splitLeadingHeading as T, type UsePublicJobPostingOptions as U, useContentPage as V, useContentPages as W, usePublicJobPosting as X, usePublicJobPostings as Y, usePublicJobPostingsForSubmission as Z, type UseContentPageOptions as _, type BlogListPageProps as a, BlogPostPage as b, type BlogPostPageProps as c, CareersApplyForm as d, type CareersApplyFormProps as e, CaseStudiesListPage as f, type CaseStudiesListPageProps as g, CaseStudyPage as h, type CaseStudyPageProps as i, type ChangelogEntry as j, ChangelogPage as k, type ChangelogPageProps as l, type ContentPageData as m, type ContentPageListData as n, type ContentPageListItem as o, ContentRenderer as p, type ContractAsset as q, ContractsPage as r, type ContractsPageProps as s, LEGAL_DOCUMENT_KEYS as t, type LegalContentEntry as u, type LegalDocument as v, type LegalDocumentKey as w, LegalPage as x, type LegalPageProps as y, type MarkdownProps as z };
|
package/dist/index.d.mts
CHANGED
|
@@ -2,8 +2,8 @@ export { G as GraphQLResponse, W as WebSDKClient, a as WebSDKClientConfig, b as
|
|
|
2
2
|
export { W as WebSDKProvider, a as WebSDKProviderProps, u as useWebSDK, b as useWebSDKConfig } from './provider-MFV1NVqZ.mjs';
|
|
3
3
|
export { ContactCategory, ContactPage, ContactPageProps, DEFAULT_CONTACT_CATEGORIES } from './components/contact.mjs';
|
|
4
4
|
export { PartnersPage, PartnersPageProps } from './components/partners.mjs';
|
|
5
|
-
import { C as CareersPostingOption } from './index-
|
|
6
|
-
export { B as BlogListPage, a as BlogListPageProps, b as BlogPostPage, c as BlogPostPageProps, d as CareersApplyForm, e as CareersApplyFormProps, f as CaseStudiesListPage, g as CaseStudiesListPageProps, h as CaseStudyPage, i as CaseStudyPageProps, j as ChangelogEntry, k as ChangelogPage, l as ChangelogPageProps, m as ContentPageData, n as ContentPageListData, o as ContentPageListItem, p as ContentRenderer, q as ContractAsset, r as ContractsPage, s as ContractsPageProps, M as Markdown,
|
|
5
|
+
import { C as CareersPostingOption } from './index-Ctws7kGs.mjs';
|
|
6
|
+
export { B as BlogListPage, a as BlogListPageProps, b as BlogPostPage, c as BlogPostPageProps, d as CareersApplyForm, e as CareersApplyFormProps, f as CaseStudiesListPage, g as CaseStudiesListPageProps, h as CaseStudyPage, i as CaseStudyPageProps, j as ChangelogEntry, k as ChangelogPage, l as ChangelogPageProps, m as ContentPageData, n as ContentPageListData, o as ContentPageListItem, p as ContentRenderer, q as ContractAsset, r as ContractsPage, s as ContractsPageProps, F as FetchLegalContentOptions, L as LEGAL_DOCUMENTS, t as LEGAL_DOCUMENT_KEYS, u as LegalContentEntry, v as LegalDocument, w as LegalDocumentKey, x as LegalPage, y as LegalPageProps, M as Markdown, z as MarkdownProps, P as PressKitAsset, A as PressKitAssetCategory, D as PressKitPage, E as PressKitPageProps, G as PublicInterviewRoundConfig, H as PublicJobPosting, U as UsePublicJobPostingOptions, I as UsePublicJobPostingsOptions, J as fetchLegalContent, K as fetchLegalContentPage, N as fetchPublicJobPosting, O as fetchPublicJobPostings, Q as fetchPublicJobPostingsForSubmission, R as findLegalDocument, S as formatLegalDate, T as splitLeadingHeading, V as useContentPage, W as useContentPages, X as usePublicJobPosting, Y as usePublicJobPostings, Z as usePublicJobPostingsForSubmission } from './index-Ctws7kGs.mjs';
|
|
7
7
|
import * as react from 'react';
|
|
8
8
|
import { ComponentType, ReactNode } from 'react';
|
|
9
9
|
export { NewsletterForm, NewsletterFormProps, NewsletterPage, NewsletterPageProps } from './components/newsletter.mjs';
|
|
@@ -810,7 +810,7 @@ declare function formatAnswerDate(value: string, locale: ExploreLocale): string;
|
|
|
810
810
|
|
|
811
811
|
declare const buttonVariants: (props?: ({
|
|
812
812
|
variant?: "link" | "default" | "destructive" | "outline" | "secondary" | "ghost" | null | undefined;
|
|
813
|
-
size?: "
|
|
813
|
+
size?: "default" | "sm" | "lg" | "icon" | null | undefined;
|
|
814
814
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
815
815
|
interface ButtonProps extends react.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {
|
|
816
816
|
asChild?: boolean;
|
package/dist/index.d.ts
CHANGED
|
@@ -2,8 +2,8 @@ export { G as GraphQLResponse, W as WebSDKClient, a as WebSDKClientConfig, b as
|
|
|
2
2
|
export { W as WebSDKProvider, a as WebSDKProviderProps, u as useWebSDK, b as useWebSDKConfig } from './provider-Dwgz4d0r.js';
|
|
3
3
|
export { ContactCategory, ContactPage, ContactPageProps, DEFAULT_CONTACT_CATEGORIES } from './components/contact.js';
|
|
4
4
|
export { PartnersPage, PartnersPageProps } from './components/partners.js';
|
|
5
|
-
import { C as CareersPostingOption } from './index-
|
|
6
|
-
export { B as BlogListPage, a as BlogListPageProps, b as BlogPostPage, c as BlogPostPageProps, d as CareersApplyForm, e as CareersApplyFormProps, f as CaseStudiesListPage, g as CaseStudiesListPageProps, h as CaseStudyPage, i as CaseStudyPageProps, j as ChangelogEntry, k as ChangelogPage, l as ChangelogPageProps, m as ContentPageData, n as ContentPageListData, o as ContentPageListItem, p as ContentRenderer, q as ContractAsset, r as ContractsPage, s as ContractsPageProps, M as Markdown,
|
|
5
|
+
import { C as CareersPostingOption } from './index-CB0Uw1xD.js';
|
|
6
|
+
export { B as BlogListPage, a as BlogListPageProps, b as BlogPostPage, c as BlogPostPageProps, d as CareersApplyForm, e as CareersApplyFormProps, f as CaseStudiesListPage, g as CaseStudiesListPageProps, h as CaseStudyPage, i as CaseStudyPageProps, j as ChangelogEntry, k as ChangelogPage, l as ChangelogPageProps, m as ContentPageData, n as ContentPageListData, o as ContentPageListItem, p as ContentRenderer, q as ContractAsset, r as ContractsPage, s as ContractsPageProps, F as FetchLegalContentOptions, L as LEGAL_DOCUMENTS, t as LEGAL_DOCUMENT_KEYS, u as LegalContentEntry, v as LegalDocument, w as LegalDocumentKey, x as LegalPage, y as LegalPageProps, M as Markdown, z as MarkdownProps, P as PressKitAsset, A as PressKitAssetCategory, D as PressKitPage, E as PressKitPageProps, G as PublicInterviewRoundConfig, H as PublicJobPosting, U as UsePublicJobPostingOptions, I as UsePublicJobPostingsOptions, J as fetchLegalContent, K as fetchLegalContentPage, N as fetchPublicJobPosting, O as fetchPublicJobPostings, Q as fetchPublicJobPostingsForSubmission, R as findLegalDocument, S as formatLegalDate, T as splitLeadingHeading, V as useContentPage, W as useContentPages, X as usePublicJobPosting, Y as usePublicJobPostings, Z as usePublicJobPostingsForSubmission } from './index-CB0Uw1xD.js';
|
|
7
7
|
import * as react from 'react';
|
|
8
8
|
import { ComponentType, ReactNode } from 'react';
|
|
9
9
|
export { NewsletterForm, NewsletterFormProps, NewsletterPage, NewsletterPageProps } from './components/newsletter.js';
|
|
@@ -810,7 +810,7 @@ declare function formatAnswerDate(value: string, locale: ExploreLocale): string;
|
|
|
810
810
|
|
|
811
811
|
declare const buttonVariants: (props?: ({
|
|
812
812
|
variant?: "link" | "default" | "destructive" | "outline" | "secondary" | "ghost" | null | undefined;
|
|
813
|
-
size?: "
|
|
813
|
+
size?: "default" | "sm" | "lg" | "icon" | null | undefined;
|
|
814
814
|
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
815
815
|
interface ButtonProps extends react.ButtonHTMLAttributes<HTMLButtonElement>, VariantProps<typeof buttonVariants> {
|
|
816
816
|
asChild?: boolean;
|
package/dist/index.js
CHANGED
|
@@ -1317,10 +1317,15 @@ function useContentPage(slug, options) {
|
|
|
1317
1317
|
hasProvider,
|
|
1318
1318
|
productLoading
|
|
1319
1319
|
);
|
|
1320
|
+
const enabled = options?.enabled !== false;
|
|
1320
1321
|
const [data, setData] = React.useState(null);
|
|
1321
|
-
const [loading, setLoading] = React.useState(
|
|
1322
|
+
const [loading, setLoading] = React.useState(enabled);
|
|
1322
1323
|
const [error, setError] = React.useState(null);
|
|
1323
1324
|
const fetchPage = React.useCallback(async () => {
|
|
1325
|
+
if (!enabled) {
|
|
1326
|
+
setLoading(false);
|
|
1327
|
+
return;
|
|
1328
|
+
}
|
|
1324
1329
|
if (gate === "wait") return;
|
|
1325
1330
|
if (gate === "unavailable") {
|
|
1326
1331
|
setData(null);
|
|
@@ -1354,7 +1359,15 @@ function useContentPage(slug, options) {
|
|
|
1354
1359
|
} finally {
|
|
1355
1360
|
setLoading(false);
|
|
1356
1361
|
}
|
|
1357
|
-
}, [
|
|
1362
|
+
}, [
|
|
1363
|
+
client,
|
|
1364
|
+
enabled,
|
|
1365
|
+
gate,
|
|
1366
|
+
productError,
|
|
1367
|
+
resolvedProductId,
|
|
1368
|
+
slug,
|
|
1369
|
+
options?.resolve
|
|
1370
|
+
]);
|
|
1358
1371
|
React.useEffect(() => {
|
|
1359
1372
|
fetchPage();
|
|
1360
1373
|
}, [fetchPage]);
|
|
@@ -14787,6 +14800,205 @@ function RybbitAnalytics({
|
|
|
14787
14800
|
}, [siteId, scriptUrl, enabled]);
|
|
14788
14801
|
return null;
|
|
14789
14802
|
}
|
|
14803
|
+
var LEGAL_DOCUMENTS = {
|
|
14804
|
+
privacy: {
|
|
14805
|
+
key: "privacy",
|
|
14806
|
+
slug: "privacy-policy",
|
|
14807
|
+
title: "Privacy Policy",
|
|
14808
|
+
description: "How we collect, use, share and protect your personal information."
|
|
14809
|
+
},
|
|
14810
|
+
terms: {
|
|
14811
|
+
key: "terms",
|
|
14812
|
+
slug: "terms-of-service",
|
|
14813
|
+
title: "Terms of Service",
|
|
14814
|
+
description: "The terms that govern your use of the service."
|
|
14815
|
+
},
|
|
14816
|
+
cookies: {
|
|
14817
|
+
key: "cookies",
|
|
14818
|
+
slug: "cookie-policy",
|
|
14819
|
+
title: "Cookie Policy",
|
|
14820
|
+
description: "The cookies and similar technologies we use, and why."
|
|
14821
|
+
},
|
|
14822
|
+
refunds: {
|
|
14823
|
+
key: "refunds",
|
|
14824
|
+
slug: "refund-policy",
|
|
14825
|
+
title: "Refund Policy",
|
|
14826
|
+
description: "How cancellations and refunds work for paid plans."
|
|
14827
|
+
},
|
|
14828
|
+
aup: {
|
|
14829
|
+
key: "aup",
|
|
14830
|
+
slug: "acceptable-use-policy",
|
|
14831
|
+
title: "Acceptable Use Policy",
|
|
14832
|
+
description: "What you may and may not do with the service."
|
|
14833
|
+
},
|
|
14834
|
+
dpa: {
|
|
14835
|
+
key: "dpa",
|
|
14836
|
+
slug: "data-processing-addendum",
|
|
14837
|
+
title: "Data Processing Addendum",
|
|
14838
|
+
description: "Our obligations as a processor of personal data on your behalf."
|
|
14839
|
+
},
|
|
14840
|
+
"ai-terms": {
|
|
14841
|
+
key: "ai-terms",
|
|
14842
|
+
slug: "ai-product-terms",
|
|
14843
|
+
title: "AI Product Terms",
|
|
14844
|
+
description: "The terms that apply to AI features, including how your data is and is not used."
|
|
14845
|
+
},
|
|
14846
|
+
subprocessors: {
|
|
14847
|
+
key: "subprocessors",
|
|
14848
|
+
slug: "subprocessors",
|
|
14849
|
+
title: "Subprocessors",
|
|
14850
|
+
description: "The third parties that help us host, secure and support the service."
|
|
14851
|
+
}
|
|
14852
|
+
};
|
|
14853
|
+
var LEGAL_DOCUMENT_KEYS = Object.keys(
|
|
14854
|
+
LEGAL_DOCUMENTS
|
|
14855
|
+
);
|
|
14856
|
+
function findLegalDocument(keyOrSlug) {
|
|
14857
|
+
if (Object.prototype.hasOwnProperty.call(LEGAL_DOCUMENTS, keyOrSlug)) {
|
|
14858
|
+
return LEGAL_DOCUMENTS[keyOrSlug];
|
|
14859
|
+
}
|
|
14860
|
+
return Object.values(LEGAL_DOCUMENTS).find((doc) => doc.slug === keyOrSlug) ?? null;
|
|
14861
|
+
}
|
|
14862
|
+
var LEGAL_CONTENT_QUERY = `
|
|
14863
|
+
query PublicLegalContentPage($slug: String!, $productId: String!) {
|
|
14864
|
+
publicResolvedContentPage(slug: $slug, productId: $productId) {
|
|
14865
|
+
title
|
|
14866
|
+
slug
|
|
14867
|
+
content
|
|
14868
|
+
contentFormat
|
|
14869
|
+
seoTitle
|
|
14870
|
+
seoDescription
|
|
14871
|
+
seoKeywords
|
|
14872
|
+
lastUpdated
|
|
14873
|
+
}
|
|
14874
|
+
}
|
|
14875
|
+
`;
|
|
14876
|
+
async function fetchLegalContentPage(client, slug, productId) {
|
|
14877
|
+
const result = await client.query(LEGAL_CONTENT_QUERY, { slug, productId }, { cache: false });
|
|
14878
|
+
if (result.errors?.length) {
|
|
14879
|
+
throw new Error(result.errors[0]?.message ?? "Unknown error");
|
|
14880
|
+
}
|
|
14881
|
+
return result.data?.publicResolvedContentPage ?? null;
|
|
14882
|
+
}
|
|
14883
|
+
async function fetchLegalContent(client, options) {
|
|
14884
|
+
const docs = (options.documents ?? LEGAL_DOCUMENT_KEYS).map(
|
|
14885
|
+
(key) => LEGAL_DOCUMENTS[key]
|
|
14886
|
+
);
|
|
14887
|
+
const entries = await Promise.all(
|
|
14888
|
+
docs.map(
|
|
14889
|
+
async (doc) => [
|
|
14890
|
+
doc.slug,
|
|
14891
|
+
await fetchLegalContentPage(client, doc.slug, options.productId)
|
|
14892
|
+
]
|
|
14893
|
+
)
|
|
14894
|
+
);
|
|
14895
|
+
return Object.fromEntries(entries);
|
|
14896
|
+
}
|
|
14897
|
+
function splitLeadingHeading(content, format) {
|
|
14898
|
+
if (format.toLowerCase() !== "markdown")
|
|
14899
|
+
return { heading: null, body: content };
|
|
14900
|
+
const match = /^\s*#[ \t]+([^\n]+?)[ \t#]*(?:\n|$)/.exec(content);
|
|
14901
|
+
if (!match?.[1]) return { heading: null, body: content };
|
|
14902
|
+
return {
|
|
14903
|
+
heading: match[1].trim(),
|
|
14904
|
+
body: content.slice(match[0].length).replace(/^\s+/, "")
|
|
14905
|
+
};
|
|
14906
|
+
}
|
|
14907
|
+
function formatLegalDate(iso) {
|
|
14908
|
+
if (!iso) return null;
|
|
14909
|
+
const date = new Date(iso);
|
|
14910
|
+
if (Number.isNaN(date.getTime())) return null;
|
|
14911
|
+
return date.toLocaleDateString("en-US", {
|
|
14912
|
+
year: "numeric",
|
|
14913
|
+
month: "long",
|
|
14914
|
+
day: "numeric",
|
|
14915
|
+
timeZone: "UTC"
|
|
14916
|
+
});
|
|
14917
|
+
}
|
|
14918
|
+
function LegalPage(props) {
|
|
14919
|
+
const {
|
|
14920
|
+
document: document2,
|
|
14921
|
+
slug: slugProp,
|
|
14922
|
+
initialContent,
|
|
14923
|
+
fallbackTitle,
|
|
14924
|
+
fallbackDescription,
|
|
14925
|
+
productName,
|
|
14926
|
+
canonicalUrl,
|
|
14927
|
+
contactEmail,
|
|
14928
|
+
className = ""
|
|
14929
|
+
} = props;
|
|
14930
|
+
const registered = document2 ? LEGAL_DOCUMENTS[document2] : slugProp ? findLegalDocument(slugProp) : null;
|
|
14931
|
+
const slug = registered?.slug ?? slugProp ?? "";
|
|
14932
|
+
const prefetched = initialContent !== void 0;
|
|
14933
|
+
const { data: fetched, loading } = useContentPage(slug, {
|
|
14934
|
+
resolve: true,
|
|
14935
|
+
enabled: !prefetched && slug !== ""
|
|
14936
|
+
});
|
|
14937
|
+
const page = prefetched ? initialContent ?? null : fetched;
|
|
14938
|
+
const isLoading = !prefetched && slug !== "" && loading;
|
|
14939
|
+
const defaultTitle = fallbackTitle ?? registered?.title ?? "Legal";
|
|
14940
|
+
const defaultDescription = fallbackDescription ?? registered?.description ?? "";
|
|
14941
|
+
const { heading, body } = page ? splitLeadingHeading(page.content, page.contentFormat) : { heading: null, body: "" };
|
|
14942
|
+
const title = page?.title || heading || defaultTitle;
|
|
14943
|
+
const updated = formatLegalDate(page?.lastUpdated);
|
|
14944
|
+
const unavailable = !isLoading && !page;
|
|
14945
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `w-full ${className}`, children: [
|
|
14946
|
+
/* @__PURE__ */ jsxRuntime.jsx(ProseStyles, {}),
|
|
14947
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
14948
|
+
PageHead,
|
|
14949
|
+
{
|
|
14950
|
+
title: page?.seoTitle || title,
|
|
14951
|
+
description: page?.seoDescription?.trim() || defaultDescription,
|
|
14952
|
+
keywords: page?.seoKeywords ?? void 0,
|
|
14953
|
+
productName,
|
|
14954
|
+
url: canonicalUrl,
|
|
14955
|
+
robots: unavailable ? "noindex, follow" : void 0
|
|
14956
|
+
}
|
|
14957
|
+
),
|
|
14958
|
+
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
14959
|
+
"article",
|
|
14960
|
+
{
|
|
14961
|
+
className: "max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 py-16 sm:py-24",
|
|
14962
|
+
"aria-busy": isLoading,
|
|
14963
|
+
children: [
|
|
14964
|
+
/* @__PURE__ */ jsxRuntime.jsx("h1", { className: "text-3xl sm:text-4xl font-bold tracking-tight text-foreground mb-3", children: title }),
|
|
14965
|
+
updated && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "text-sm text-muted-foreground mb-10", children: [
|
|
14966
|
+
"Last updated:",
|
|
14967
|
+
" ",
|
|
14968
|
+
/* @__PURE__ */ jsxRuntime.jsx("time", { dateTime: page?.lastUpdated ?? void 0, children: updated })
|
|
14969
|
+
] }),
|
|
14970
|
+
isLoading ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "space-y-3", "data-testid": "legal-page-loading", children: [
|
|
14971
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-4 w-3/4 rounded bg-muted animate-pulse" }),
|
|
14972
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-4 w-full rounded bg-muted animate-pulse" }),
|
|
14973
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-4 w-5/6 rounded bg-muted animate-pulse" })
|
|
14974
|
+
] }) : page ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: "boff-prose max-w-none", children: /* @__PURE__ */ jsxRuntime.jsx(ContentRenderer, { content: body, format: page.contentFormat }) }) : /* @__PURE__ */ jsxRuntime.jsxs(
|
|
14975
|
+
"div",
|
|
14976
|
+
{
|
|
14977
|
+
role: "status",
|
|
14978
|
+
className: "rounded-xl border border-border bg-muted/30 p-6",
|
|
14979
|
+
children: [
|
|
14980
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-base text-foreground", children: "This document is not available right now." }),
|
|
14981
|
+
contactEmail && /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "mt-2 text-sm text-muted-foreground", children: [
|
|
14982
|
+
"For a copy, contact",
|
|
14983
|
+
" ",
|
|
14984
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
14985
|
+
"a",
|
|
14986
|
+
{
|
|
14987
|
+
className: "text-primary underline",
|
|
14988
|
+
href: `mailto:${contactEmail}`,
|
|
14989
|
+
children: contactEmail
|
|
14990
|
+
}
|
|
14991
|
+
),
|
|
14992
|
+
"."
|
|
14993
|
+
] })
|
|
14994
|
+
]
|
|
14995
|
+
}
|
|
14996
|
+
)
|
|
14997
|
+
]
|
|
14998
|
+
}
|
|
14999
|
+
)
|
|
15000
|
+
] });
|
|
15001
|
+
}
|
|
14790
15002
|
var PUBLIC_JOB_POSTING_FIELDS = (
|
|
14791
15003
|
/* GraphQL */
|
|
14792
15004
|
`
|
|
@@ -15347,8 +15559,8 @@ function AnimationStyles() {
|
|
|
15347
15559
|
return /* @__PURE__ */ jsxRuntime.jsx("style", { dangerouslySetInnerHTML: { __html: ANIMATION_STYLES } });
|
|
15348
15560
|
}
|
|
15349
15561
|
var CASE_STUDIES_QUERY = `
|
|
15350
|
-
query CaseStudies($productId: String!, $limit: Int, $offset: Int) {
|
|
15351
|
-
publicContentPages(productId: $productId, limit: $limit, offset: $offset) {
|
|
15562
|
+
query CaseStudies($productId: String!, $tag: String, $limit: Int, $offset: Int) {
|
|
15563
|
+
publicContentPages(productId: $productId, tag: $tag, limit: $limit, offset: $offset) {
|
|
15352
15564
|
items {
|
|
15353
15565
|
id
|
|
15354
15566
|
title
|
|
@@ -15748,6 +15960,9 @@ function CaseStudiesListPage(props) {
|
|
|
15748
15960
|
try {
|
|
15749
15961
|
const result = await client.query(CASE_STUDIES_QUERY, {
|
|
15750
15962
|
productId: resolvedProductId,
|
|
15963
|
+
// Filter server-side: an unfiltered page of `limit` rows is mostly blog/legal pages, so
|
|
15964
|
+
// real case studies past it were never listed and the page fell back to the empty state.
|
|
15965
|
+
tag: CASE_STUDY_TAG,
|
|
15751
15966
|
limit,
|
|
15752
15967
|
offset
|
|
15753
15968
|
});
|
|
@@ -19382,8 +19597,11 @@ exports.ExplorePage = ExplorePage;
|
|
|
19382
19597
|
exports.FALLBACK_EXPLORE_LIMITS = FALLBACK_EXPLORE_LIMITS;
|
|
19383
19598
|
exports.FOOTERLESS_ROUTES = FOOTERLESS_ROUTES;
|
|
19384
19599
|
exports.Input = Input;
|
|
19600
|
+
exports.LEGAL_DOCUMENTS = LEGAL_DOCUMENTS;
|
|
19601
|
+
exports.LEGAL_DOCUMENT_KEYS = LEGAL_DOCUMENT_KEYS;
|
|
19385
19602
|
exports.Label = Label;
|
|
19386
19603
|
exports.LaunchCountdown = LaunchCountdown;
|
|
19604
|
+
exports.LegalPage = LegalPage;
|
|
19387
19605
|
exports.Markdown = Markdown;
|
|
19388
19606
|
exports.NewsletterForm = NewsletterForm;
|
|
19389
19607
|
exports.NewsletterPage = NewsletterPage;
|
|
@@ -19431,12 +19649,16 @@ exports.conceptPath = conceptPath;
|
|
|
19431
19649
|
exports.detectElectronPlatform = detectElectronPlatform;
|
|
19432
19650
|
exports.emitProductSlug = emitProductSlug;
|
|
19433
19651
|
exports.exploreQuestionHref = exploreQuestionHref;
|
|
19652
|
+
exports.fetchLegalContent = fetchLegalContent;
|
|
19653
|
+
exports.fetchLegalContentPage = fetchLegalContentPage;
|
|
19434
19654
|
exports.fetchPublicJobPosting = fetchPublicJobPosting;
|
|
19435
19655
|
exports.fetchPublicJobPostings = fetchPublicJobPostings;
|
|
19436
19656
|
exports.fetchPublicJobPostingsForSubmission = fetchPublicJobPostingsForSubmission;
|
|
19437
19657
|
exports.fetchPublicProduct = fetchPublicProduct;
|
|
19658
|
+
exports.findLegalDocument = findLegalDocument;
|
|
19438
19659
|
exports.formatAnswerDate = formatAnswerDate;
|
|
19439
19660
|
exports.formatDownloads = formatDownloads;
|
|
19661
|
+
exports.formatLegalDate = formatLegalDate;
|
|
19440
19662
|
exports.formatPrice = formatPrice2;
|
|
19441
19663
|
exports.getAnswerBySlug = getAnswerBySlug;
|
|
19442
19664
|
exports.getConceptBySlug = getConceptBySlug;
|
|
@@ -19460,6 +19682,7 @@ exports.productSlugsByOrigin = productSlugsByOrigin;
|
|
|
19460
19682
|
exports.resolvePricingProductKey = resolvePricingProductKey;
|
|
19461
19683
|
exports.shouldRenderSiteFooter = shouldRenderSiteFooter;
|
|
19462
19684
|
exports.speechLocaleOf = speechLocaleOf;
|
|
19685
|
+
exports.splitLeadingHeading = splitLeadingHeading;
|
|
19463
19686
|
exports.stopSpeaking = stopSpeaking;
|
|
19464
19687
|
exports.useContentPage = useContentPage;
|
|
19465
19688
|
exports.useContentPages = useContentPages;
|