Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Add APIs page for JS #12605

Draft
wants to merge 7 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 75 additions & 0 deletions docs/platforms/javascript/common/apis.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
---
title: APIs
description: "Learn more about APIs of the SDK."
customCanonicalTag: "/platforms/javascript/apis/"
sidebar_order: 3
---

This page shows all available to-level APIs of the SDK. You can use them like this:

```javascript
import * as Sentry from "@sentry/browser";

Sentry.setTag("tag", "value");
```

## Available Options

<TableOfContents ignoreIds={["available-options"]} />

## Enriching Events

<SdkApi
name="addBreadcrumb"
signature="function addBreadcrumb(breadcrumb: Breadcrumb, hint?: Hint): void"
parameters={[
{
name: "breadcrumb",
required: true,
type: [
{
name: "message",
type: "string",
description:
"If a message is provided, it is rendered as text with all whitespace preserved.",
},
{
name: "type",
type: '"default" | "debug" | "error" | "info" | "navigation" | "http" | "query" | "ui" | "user"',
defaultValue: '"default"',
description:
"The type influences how a breadcrumb is rendered in Sentry. When in doubt, leave it at `default`.",
},
{
name: "level",
type: '"fatal" | "error" | "warning" | "log" | "info" | "debug"',
defaultValue: '"info"',
description:
"The level is used in the UI to emphasize or deemphasize the breadcrumb.",
},
{
name: "category",
type: "string",
description:
"Typically it is a module name or a descriptive string. For instance, `ui.click` could be used to indicate that a click happened",
},
{
name: "data",
type: "Record<string, unknown>",
description:
"Additional data that should be sent with the breadcrumb.",
},
],
},
{
name: "hint",
type: "Record<string, unknown>",
description:
"A hint object containing additional information about the breadcrumb.",
},
]}
>
You can manually add breadcrumbs whenever something interesting happens. For
example, you might manually record a breadcrumb if the user authenticates or
another state change occurs.
</SdkApi>
99 changes: 99 additions & 0 deletions src/components/sdkApi.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import {Fragment} from 'react';
import {jsx, jsxs} from 'react/jsx-runtime';
import {toJsxRuntime} from 'hast-util-to-jsx-runtime';
import {Nodes} from 'hastscript/lib/create-h';
import bash from 'refractor/lang/bash.js';
import json from 'refractor/lang/json.js';
import {refractor} from 'refractor/lib/core.js';

import {PlatformCategory} from 'sentry-docs/types';

import {Expandable} from './expandable';
import {SdkDefinition, SdkDefinitionTable} from './sdkDefinition';

interface ParameterDef {
name: string;
type: string | ParameterDef[];
defaultValue?: string;
description?: string;
required?: boolean;
}

type Props = {
name: string;
parameters: ParameterDef[];
signature: string;
categorySupported?: PlatformCategory[];
children?: React.ReactNode;
language?: string;
};

refractor.register(bash);
refractor.register(json);

const codeToJsx = (code: string, lang = 'json') => {
return toJsxRuntime(refractor.highlight(code, lang) as Nodes, {Fragment, jsx, jsxs});
};

export function SdkApi({
name,
children,
signature,
parameters = [],
// TODO: How to handle this default better?
language = 'typescript',
categorySupported = [],
}: Props) {
return (
<SdkDefinition name={name} categorySupported={categorySupported}>
<pre className="mt-2 mb-2">{codeToJsx(signature, language)}</pre>

{parameters.length ? (
<Expandable title="Parameters">
<SdkDefinitionTable className="bg-white">
{parameters.map(param => (
<ApiParameterDef key={param.name} {...param} />
))}
</SdkDefinitionTable>
</Expandable>
) : null}

{children}
</SdkDefinition>
);
}

function ApiParameterDef({name, type, description, required}: ParameterDef) {
return (
<tr>
<th>
{name}
{required ? <span className="text-red">*</span> : null}
</th>
<td>
{typeof type === 'string' ? (
<code>{type}</code>
) : (
<RenderNestedObject objProps={type} />
)}

{description ? <p className="m-0">{description}</p> : null}
</td>
</tr>
);
}

function RenderNestedObject({objProps}: {objProps: ParameterDef[]}) {
return (
<Fragment>
<div>
<code>Object:</code>
</div>
<SdkDefinitionTable className="mt-1">
{objProps.map(prop => (
<ApiParameterDef key={prop.name} {...prop} />
))}
</SdkDefinitionTable>
</Fragment>
);
}
53 changes: 53 additions & 0 deletions src/components/sdkDefinition/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import {PlatformCategory} from 'sentry-docs/types';

import styles from './style.module.scss';

import {PlatformCategorySection} from '../platformCategorySection';

type Props = {
name: string;
categorySupported?: PlatformCategory[];
children?: React.ReactNode;
};

export function SdkDefinition({name, children, categorySupported = []}: Props) {
return (
<PlatformCategorySection supported={categorySupported}>
<div>
<h3 id={name} aria-label={name} data-sdk-option>
<a href={`#${name}`}>
<svg
className="anchorlink before"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
>
<path
d="M9.199 13.599a5.99 5.99 0 0 0 3.949 2.345 5.987 5.987 0 0 0 5.105-1.702l2.995-2.994a5.992 5.992 0 0 0 1.695-4.285 5.976 5.976 0 0 0-1.831-4.211 5.99 5.99 0 0 0-6.431-1.242 6.003 6.003 0 0 0-1.905 1.24l-1.731 1.721a.999.999 0 1 0 1.41 1.418l1.709-1.699a3.985 3.985 0 0 1 2.761-1.123 3.975 3.975 0 0 1 2.799 1.122 3.997 3.997 0 0 1 .111 5.644l-3.005 3.006a3.982 3.982 0 0 1-3.395 1.126 3.987 3.987 0 0 1-2.632-1.563A1 1 0 0 0 9.201 13.6zm5.602-3.198a5.99 5.99 0 0 0-3.949-2.345 5.987 5.987 0 0 0-5.105 1.702l-2.995 2.994a5.992 5.992 0 0 0-1.695 4.285 5.976 5.976 0 0 0 1.831 4.211 5.99 5.99 0 0 0 6.431 1.242 6.003 6.003 0 0 0 1.905-1.24l1.723-1.723a.999.999 0 1 0-1.414-1.414L9.836 19.81a3.985 3.985 0 0 1-2.761 1.123 3.975 3.975 0 0 1-2.799-1.122 3.997 3.997 0 0 1-.111-5.644l3.005-3.006a3.982 3.982 0 0 1 3.395-1.126 3.987 3.987 0 0 1 2.632 1.563 1 1 0 0 0 1.602-1.198z"
fill="currentColor"
/>
</svg>
{name}
</a>
</h3>

{children}
</div>
</PlatformCategorySection>
);
}

export function SdkDefinitionTable({
children,
className,
}: {
children?: React.ReactNode;
className?: string;
}) {
return (
<table className={styles['sdk-option-table'] + (className ? ` ${className}` : '')}>
<tbody>{children}</tbody>
</table>
);
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
.sdk-option-table {
--border-radius: 6px;

font-size: 1rem;
width: auto !important;

// This is necessary to make rounded borders work :(
border-collapse: separate !important;
border-spacing: 0px;

&:first-child {
margin-top: 0;
}

&:last-child {
margin-bottom: 0;
}

& tr th, & tr td {
border-bottom-width: 0;
border-right-width: 0;
Expand Down
86 changes: 86 additions & 0 deletions src/components/sdkOption.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import {getCurrentPlatformOrGuide} from 'sentry-docs/docTree';
import {serverContext} from 'sentry-docs/serverContext';
import {PlatformCategory} from 'sentry-docs/types';

import {PlatformCategorySection} from './platformCategorySection';
import {PlatformSection} from './platformSection';
import {SdkDefinition, SdkDefinitionTable} from './sdkDefinition';

type Props = {
name: string;
type: string;
categorySupported?: PlatformCategory[];
children?: React.ReactNode;
defaultValue?: string;
envVar?: string;
};

export function SdkOption({
name,
children,
type,
defaultValue,
envVar,
categorySupported = [],
}: Props) {
const {showBrowserOnly, showServerLikeOnly} = getPlatformHints(categorySupported);

return (
<SdkDefinition name={name} categorySupported={categorySupported}>
<SdkDefinitionTable>
{type && <OptionDefRow label="Type" value={type} />}
{defaultValue && <OptionDefRow label="Default" value={defaultValue} />}

<PlatformCategorySection supported={['server', 'serverless']}>
<PlatformSection notSupported={['javascript.nextjs']}>
{envVar && <OptionDefRow label="ENV Variable" value={envVar} />}
</PlatformSection>
</PlatformCategorySection>

{showBrowserOnly && <OptionDefRow label="Only available on" value="Client" />}
{showServerLikeOnly && <OptionDefRow label="Only available on" value="Server" />}
</SdkDefinitionTable>

{children}
</SdkDefinition>
);
}

function OptionDefRow({label, value}: {label: string; value: string}) {
return (
<tr>
<th>{label}</th>
<td>
<code>{value}</code>
</td>
</tr>
);
}

function getPlatformHints(categorySupported: PlatformCategory[]) {
const {rootNode, path} = serverContext();
const currentPlatformOrGuide = getCurrentPlatformOrGuide(rootNode, path);
const currentCategories = currentPlatformOrGuide?.categories || [];

// We only handle browser, server & serverless here for now
const currentIsBrowser = currentCategories.includes('browser');
const currentIsServer = currentCategories.includes('server');
const currentIsServerless = currentCategories.includes('serverless');
const currentIsServerLike = currentIsServer || currentIsServerless;

const hasCategorySupported = categorySupported.length > 0;
const supportedBrowserOnly =
categorySupported.includes('browser') &&
!categorySupported.includes('server') &&
!categorySupported.includes('serverless');
const supportedServerLikeOnly =
!categorySupported.includes('browser') &&
(categorySupported.includes('server') || categorySupported.includes('serverless'));

const showBrowserOnly =
hasCategorySupported && supportedBrowserOnly && currentIsServerLike;
const showServerLikeOnly =
hasCategorySupported && supportedServerLikeOnly && currentIsBrowser;

return {showBrowserOnly, showServerLikeOnly};
}
Loading
Loading