open-index/open-npm huggingface dataset:
npm package: @port.finance/port-sdk
Description: Port SDK for interacting with Port Finance
Author: Port Finance
Latest version: 0.2.69

# 🔧 Port Finance SDK

[![npm](https://img.shields.io/npm/v/@port.finance/port-sdk.svg)](https://www.npmjs.com/package/@port.finance/port-sdk)

An SDK to interact with Port Finance on-chain program.

## Installation

```
yarn add @port.finance/port-sdk
```
npm package: @port.finance/swap-ui
Description: [![Build Status](https://travis-ci.com/project-serum/swap-ui.svg?branch=master)](https://travis-ci.com/project-serum/swap-ui) [![npm](https://img.shields.io/npm/v/@project-serum/swap-ui.svg)](https://www.npmjs.com/package/@project-serum/swap-ui)
Author: Port Finance
Latest version: 0.0.5

# `@project-serum/swap-ui`

[![Build Status](https://travis-ci.com/project-serum/swap-ui.svg?branch=master)](https://travis-ci.com/project-serum/swap-ui)
[![npm](https://img.shields.io/npm/v/@project-serum/swap-ui.svg)](https://www.npmjs.com/package/@project-serum/swap-ui)

A reusable React component for swapping on the Serum DEX. The Solana program can be
found [here](https://github.com/project-serum/swap).

## Usage

#### Install

First install the required peer dependencies into your React project.

```
yarn add @material-ui/core @material-ui/icons @material-ui/lab @project-serum/anchor @solana/spl-token-registry @solana/web3.js material-ui-popup-state react-async-hook
```

Then install the package.

```
yarn add @project-serum/swap-ui
```

#### Add the Swap Component

To embed the `Swap` component into your application,
one can minimally provide an [Anchor](https://github.com/project-serum/anchor)
[Provider](https://project-serum.github.io/anchor/ts/classes/provider.html)
and [TokenListContainer](https://github.com/solana-labs/token-list).
For example,

 ```javascript
<Swap provider={provider} tokenList={tokenList} />
```

All of the complexity of communicating with the Serum DEX and managing
its data is handled internally by the component.

#### Referral Fees

To earn referral fees, one can also pass in a `referral` property,
which is the `PublicKey` of the Solana wallet that *owns* the associated
token accounts in which referral fees are paid (i.e., USDC and USDT).

## Developing

#### Install dependencies

```
yarn
```

#### Build

```
yarn build
```

## Run the example app

For local development and educational purposes, a minimal React app is provided
in the `example/` subdirectory.

To run, change directories via `cd example/` and start the app.

### Start the app

```
yarn start
```
npm package: @portabletext-typed/types
Description: @portabletext/types with typed generics. Mostly internal for other packages in the monorepo.
Latest version: 4.0.1

# @portabletext-typed/types

[![NPM Downloads](https://img.shields.io/npm/dw/@portabletext-typed/types?style=flat&logo=npm)](https://www.npmjs.com/package/@portabletext-typed/types)
[![GitHub commit activity (branch)](https://img.shields.io/github/commit-activity/m/saiichihashimoto/sanity-typed?style=flat&logo=github)](https://github.com/saiichihashimoto/sanity-typed/pulls?q=is%3Apr+is%3Aclosed)
[![GitHub Repo stars](https://img.shields.io/github/stars/saiichihashimoto/sanity-typed?style=flat&logo=github)](https://github.com/saiichihashimoto/sanity-typed/stargazers)
[![GitHub contributors](https://img.shields.io/github/contributors/saiichihashimoto/sanity-typed?style=flat&logo=github)](https://github.com/saiichihashimoto/sanity-typed/graphs/contributors)
[![GitHub issues by-label](https://img.shields.io/github/issues/saiichihashimoto/sanity-typed/help%20wanted?style=flat&logo=github&color=007286)](https://github.com/saiichihashimoto/sanity-typed/labels/help%20wanted)
[![Minified Size](https://img.shields.io/bundlephobia/min/@portabletext-typed/types?style=flat)](https://www.npmjs.com/package/@portabletext-typed/types?activeTab=code)
[![License](https://img.shields.io/github/license/saiichihashimoto/sanity-typed?style=flat)](LICENSE)

[![GitHub Sponsors](https://img.shields.io/github/sponsors/saiichihashimoto?style=flat&logo=githubsponsors)](https://github.com/sponsors/saiichihashimoto)

[@portabletext/types](https://github.com/portabletext/types) with typed generics. Mostly internal for other packages in the monorepo.

## Breaking Changes

### 3 to 4

#### Node Requirement to ^22.14.0

The required Node version is now ^22.14.0. Older versions are no longer supported and newer versions will be added as we validate them.

### 2 to 3

#### Typescript version from 5.7.2 <= x <= 5.7.3

The supported Typescript version is now 5.7.2 <= x <= 5.7.3. Older versions are no longer supported and newer versions will be added as we validate them.

### 1 to 2

#### Typescript version from 5.4.2 <= x <= 5.6.3

The supported Typescript version is now 5.4.2 <= x <= 5.6.3. Older versions are no longer supported and newer versions will be added as we validate them.
npm package: @portabletext/block-tools
Description: Sanity-flavored HTML to Portable Text conversion (wraps @portabletext/html)
Author: Sanity.io
Latest version: 5.1.1

# `@portabletext/block-tools`

> Sanity-flavored HTML to Portable Text conversion

This package wraps [`@portabletext/html`](../html) for use with Sanity schemas. If you're not using Sanity's schema system, use `@portabletext/html` directly - it has the same features with a simpler API.

## When to use which

| Package                     | Use when                                                        |
| --------------------------- | --------------------------------------------------------------- |
| `@portabletext/html`        | Standalone projects, custom schemas, or any non-Sanity context  |
| `@portabletext/block-tools` | Sanity projects where you already have a compiled Sanity schema |

## Usage

```ts
import {htmlToBlocks} from '@portabletext/block-tools'
import {Schema} from '@sanity/schema'

const defaultSchema = Schema.compile({
  name: 'myBlog',
  types: [
    {
      type: 'object',
      name: 'blogPost',
      fields: [
        {
          title: 'Title',
          type: 'string',
          name: 'title',
        },
        {
          title: 'Body',
          name: 'body',
          type: 'array',
          of: [{type: 'block'}],
        },
      ],
    },
  ],
})

const blockContentType = defaultSchema
  .get('blogPost')
  .fields.find((field) => field.name === 'body').type

const blocks = htmlToBlocks(
  '<html><body><h1>Hello world!</h1></body></html>',
  blockContentType,
)
```

### `htmlToBlocks(html, blockContentType, options?)`

Converts HTML to Portable Text blocks using a Sanity block content schema type.

Internally delegates to `@portabletext/html` after converting the Sanity schema. Supports the same `parseHtml`, `rules`, and `keyGenerator` options. See the [`@portabletext/html` README](../html/README.md) for full documentation on rules, whitespace handling, image matchers, and paste source support.

**NOTE:** To use in Node.js, you need to provide a `parseHtml` option - generally using `JSDOM`:

```ts
import {JSDOM} from 'jsdom'

const blocks = htmlToBlocks(html, blockContentType, {
  parseHtml: (html) => new JSDOM(html).window.document,
})
```

### `normalizeBlock(block, options?)`

Normalize a block object structure to ensure it has `_key`, `_type`, `children`, and `markDefs`.

```ts
import {normalizeBlock} from '@portabletext/block-tools'

const normalized = normalizeBlock({
  _type: 'block',
  children: [{_type: 'span', text: 'Hello', marks: ['strong']}],
})
// => { _key: '...', _type: 'block', children: [{ _key: '...', _type: 'span', text: 'Hello', marks: ['strong'] }], markDefs: [] }
```

## License

MIT
npm package: @portabletext/plugin-character-pair-decorator
Description: Automatically match a pair of characters and decorate the text in between
Author: Sanity.io
Latest version: 7.0.25

# `@portabletext/plugin-character-pair-decorator`

> ✨ Automatically match a pair of characters and decorate the text in between

Import the `CharacterPairDecoratorPlugin` React component and place it inside the `EditorProvider` to automatically register the necessary Behaviors:

```tsx
import {
  defineSchema,
  EditorProvider,
  PortableTextEditable,
} from '@portabletext/editor'
import {CharacterPairDecoratorPlugin} from '@portabletext/plugin-character-pair-decorator'

function App() {
  return (
    <EditorProvider
      initialConfig={{
        schemaDefinition: defineSchema({
          decorators: [{name: 'italic'}],
        }),
      }}
    >
      <PortableTextEditable />
      <CharacterPairDecoratorPlugin
        decorator={({context}) =>
          context.schema.decorators.find((d) => d.name === 'italic')?.name
        }
        pair={{char: '#', amount: 1}}
      />
    </EditorProvider>
  )
}
```
npm package: @portabletext/plugin-markdown-shortcuts
Description: Adds helpful Markdown shortcuts to the editor
Author: Sanity.io
Latest version: 7.0.25

# `@portabletext/plugin-markdown-shortcuts`

> ⬇️ Adds helpful Markdown shortcuts to the editor

Import the `MarkdownShortcutsPlugin` React component and place it inside the `EditorProvider` and tell it about your schema:

```tsx
import {
  defineSchema,
  EditorProvider,
  PortableTextEditable,
} from '@portabletext/editor'
import {MarkdownShortcutsPlugin} from '@portabletext/plugin-markdown-shortcuts'

const schemaDefinition = defineSchema({
  blockObjects: [{name: 'break'}],
  annotations: [{name: 'link', fields: [{name: 'href', type: 'string'}]}]
  decorators: [
    {name: 'em'},
    {name: 'code'},
    {name: 'strike-through'},
    {name: 'strong'},
  ],
  lists: [{name: 'bullet'}, {name: 'number'}],
  styles: [
    {name: 'normal'},
    {name: 'h1'},
    {name: 'h2'},
    {name: 'h3'},
    {name: 'h4'},
    {name: 'h5'},
    {name: 'h6'},
    {name: 'blockquote'},
  ],
})

function App() {
  return (
    <EditorProvider
      initialConfig={{
        schemaDefinition,
      }}
    >
      <PortableTextEditable />
      <MarkdownShortcutsPlugin
        boldDecorator={({schema}) =>
          schema.decorators.find((d) => d.name === 'strong')?.name
        }
        codeDecorator={({schema}) =>
          schema.decorators.find((d) => d.name === 'code')?.name
        }
        italicDecorator={({schema}) =>
          schema.decorators.find((d) => d.name === 'em')?.name
        }
        strikeThroughDecorator={({schema}) =>
          schema.decorators.find((d) => d.name === 'strike-through')?.name
        }
        defaultStyle={({schema}) =>
          schema.styles.find((s) => s.name === 'normal')?.name
        }
        headingStyle={({schema, level}) =>
          schema.styles.find((s) => s.name === `h${level}`)?.name
        }
        blockquoteStyle={({schema}) =>
          schema.styles.find((s) => s.name === 'blockquote')?.name
        }
        orderedList={({schema}) =>
          schema.lists.find((s) => s.name === 'number')?.name
        }
        unorderedList={({schema}) =>
          schema.lists.find((s) => s.name === 'bullet')?.name
        }
        horizontalRuleObject={({schema}) => {
          const schemaType = schema.blockObjects.find(
            (object) => object.name === 'break',
          )

          if (!schemaType) {
            return undefined
          }

          return {_type: schemaType.name}
        }}
        linkObject={({schema, href}) => {
          const schemaType = schema.annotations.find(
            (annotation) => annotation.name === 'link',
          )
          const hrefField = schemaType?.fields.find(
            (field) => field.name === 'href' && field.type === 'string',
          )

          if (!schemaType || !hrefField) {
            return undefined
          }

          return {
            _type: schemaType.name,
            [hrefField.name]: href,
          }
        }}
      />
    </EditorProvider>
  )
}
```
npm package: @portabletext/plugin-one-line
Description: 🤏 Restricts the Portable Text Editor to a single line
Author: Sanity.io
Latest version: 6.0.25

# One-Line Plugin

> 🤏 Restricts the Portable Text Editor to a single line

The plugin blocks `insert.break` events and provides smart handling of other `insert.*` events like `insert.block`.

Configure it with as high priority as possible to make sure other plugins don't overwrite `insert.*` events before this plugin gets a chance to do so.

Import the `OneLinePlugin` React component and place it inside the `EditorProvider` to automatically register the necessary Behaviors:

```tsx
import {
  defineSchema,
  EditorProvider,
  PortableTextEditable,
} from '@portabletext/editor'
import {OneLinePlugin} from '@portabletext/plugin-one-line'

function App() {
  return (
    <EditorProvider initialConfig={{schemaDefinition: defineSchema({})}}>
      <PortableTextEditable />
      <OneLinePlugin />
    </EditorProvider>
  )
}
```
npm package: @portabletext/plugin-sdk-value
Description: Synchronizes the Portable Text Editor value with the Sanity SDK, allowing for two-way editing.
Author: Sanity.io
Latest version: 6.0.25

# SDK Value Plugin

> 🔗 Connects a Portable Text Editor with a Sanity document using the SDK

The SDK Value plugin provides seamless two-way synchronization between a Portable Text Editor instance and a specific field in a Sanity document. This enables real-time collaboration and ensures that changes made through the editor are immediately reflected in the document, and vice versa.

## Features

- **Two-way synchronization**: Changes in the editor update the document, and document changes update the editor
- **Real-time updates**: Automatically handles patches from external sources (other users, mutations, etc.)
- **Optimistic updates**: Provides smooth user experience with immediate local updates

## Usage

Import the `SDKValuePlugin` React component and place it inside the `EditorProvider`. The plugin requires document handle properties and a path to specify which field to synchronize:

```tsx
import {
  defineSchema,
  EditorProvider,
  PortableTextEditable,
} from '@portabletext/editor'
import {SDKValuePlugin} from '@portabletext/plugin-sdk-value'

function MyEditor() {
  return (
    <EditorProvider initialConfig={{schemaDefinition: defineSchema({})}}>
      <PortableTextEditable />
      <SDKValuePlugin
        documentId="my-document-id"
        documentType="myDocumentType"
        path="content"
      />
    </EditorProvider>
  )
}
```

## Props

The `SDKValuePlugin` component accepts a [Document Handle](https://www.sanity.io/docs/app-sdk/document-handles) plus an additional `path` parameter:

| Prop           | Type                | Description                                                        |
| -------------- | ------------------- | ------------------------------------------------------------------ |
| `documentId`   | `string`            | The document ID                                                    |
| `documentType` | `string`            | The document type                                                  |
| `path`         | `string`            | [JSONMatch][json-match] path expression to the Portable Text field |
| `dataset`      | `string` (optional) | Dataset name (if different from configured default)                |
| `projectId`    | `string` (optional) | Project ID (if different from configured default)                  |

[json-match]: https://www.sanity.io/docs/content-lake/json-match

## Requirements

This plugin requires:

- `@sanity/sdk-react` for document state management
- The document must exist in the Sanity dataset
npm package: @portabletext/react-native
Description: *Experimental*: Render Portable Text with React Native
Author: Sanity.io
Latest version: 3.0.0

# @portabletext/react-native

**Note: Experimental!** Please report issues and feedback.

Render [Portable Text](https://portabletext.org/) with React Native.

Utilizes [@portabletext/react](https://github.com/portabletext/react-portabletext) under the hood, and thus has the exact same API, but will render React Native views instead of HTML.

## Installation

```
npm install --save @portabletext/react-native
```

## Basic usage

```js
import {PortableText} from '@portabletext/react-native'

<PortableText
  value={[/* array of portable text blocks */]}
  components={/* optional object of custom components to use */}
/>
```

## Styling the output

The rendered views has very little or no styling applied, so you will quite often want to pass [custom components](#customizing-components) to override the built-in ones.

## Customizing components

Customizing components are done in the same way as in [@portabletext/react](https://github.com/portabletext/react-portabletext#customizing-components) - see the [README](https://github.com/portabletext/react-portabletext#customizing-components) for more details.

## License

MIT © [Sanity.io](https://www.sanity.io/)
npm package: @portabletext/sanity-bridge
Description: Convert a Sanity Schema to a Portable Text Schema
Author: Sanity.io
Latest version: 3.0.0

# `@portabletext/sanity-bridge`

A TypeScript library for converting between Sanity schemas and Portable Text schemas, enabling seamless integration between Sanity CMS and Portable Text editors.

## Installation

```bash
npm install @portabletext/sanity-bridge
```

## Usage

### Convert Sanity Schema to Portable Text Schema

```ts
import {Schema} from '@sanity/schema'
import {defineField, defineType} from '@sanity/types'

/**
 * Define the Sanity Schema
 */

const imageType = defineType({
  name: 'custom image',
  title: 'Image',
  type: 'object',
  fields: [
    defineField({
      name: 'url',
      type: 'string',
    }),
  ],
})

const stockTickerType = defineType({
  name: 'stock-ticker',
  type: 'object',
  fields: [
    defineField({
      name: 'symbol',
      type: 'string',
    }),
  ],
})

const portableTextType = defineType({
  type: 'array',
  name: 'body',
  of: [
    {
      type: 'block',
      name: 'block',
      styles: [
        {title: 'Normal', value: 'normal'},
        {title: 'H1', value: 'h1'},
        {title: 'H2', value: 'h2'},
        {title: 'H3', value: 'h3'},
        {title: 'H4', value: 'h4'},
        {title: 'H5', value: 'h5'},
        {title: 'H6', value: 'h6'},
        {title: 'Quote', value: 'blockquote'},
      ],
      marks: {
        annotations: [
          {
            name: 'comment',
            type: 'object',
            fields: [{type: 'string', name: 'text'}],
          },
          {
            name: 'link',
            type: 'object',
            fields: [{type: 'string', name: 'href'}],
          },
        ],
      },
      of: [{type: 'stock-ticker'}],
    },
    {type: 'custom image'},
  ],
})

/**
 * Compile the Sanity Schema
 */
const sanitySchema = Schema.compile({
  types: [portableTextType, imageType, stockTickerType],
}).get('body')

/**
 * Turn the Sanity Schema into a Portable Text Schema
 */
const portableTextSchema = sanitySchemaToPortableTextSchema(sanitySchema)
```

### Convert Portable Text Schema to Sanity Schema

```ts
import {compileSchemaDefinitionToPortableTextMemberSchemaTypes} from '@portabletext/sanity-bridge'

// Convert Portable Text schema definition to Sanity types
const sanityMemberTypes =
  compileSchemaDefinitionToPortableTextMemberSchemaTypes({
    styles: [{name: 'normal'}, {name: 'h1'}],
    decorators: [{name: 'strong'}, {name: 'em'}],
    annotations: [{name: 'link'}],
    blockObjects: [{name: 'image', fields: [{name: 'url', type: 'url'}]}],
  })
```

### Additional helper functions

```ts
import {
  createPortableTextMemberSchemaTypes,
  portableTextMemberSchemaTypesToSchema,
} from '@portabletext/sanity-bridge'

// Extract Portable Text member types from Sanity schema
const memberTypes = createPortableTextMemberSchemaTypes(sanityPortableTextType)

// Convert to first-class Portable Text schema
const portableTextSchema = portableTextMemberSchemaTypesToSchema(memberTypes)
```
npm package: @portabletext/schema
Description: Portable Text Schema
Author: Sanity.io
Latest version: 2.1.1

# `@portabletext/schema`

A TypeScript library for defining and compiling Portable Text schemas with full type safety and editor support.

## Installation

```bash
npm install @portabletext/schema
```

## Usage

### Define a Schema

```ts
import {defineSchema} from '@portabletext/schema'

const schemaDefinition = defineSchema({
  styles: [{name: 'normal'}, {name: 'h1'}, {name: 'h2'}, {name: 'blockquote'}],
  decorators: [{name: 'strong'}, {name: 'em'}],
  annotations: [{name: 'link'}],
  lists: [{name: 'bullet'}, {name: 'numbered'}],
})
```

### Compile Schema

```ts
import {compileSchema} from '@portabletext/schema'

const schema = compileSchema(schemaDefinition)
```
npm package: @portabletext/solid
Description: Render Portable Text with Solid JS
Author: nonphoto
Latest version: 1.0.8

# @portabletext/solid

[![npm version](https://img.shields.io/npm/v/@portabletext/solid.svg?style=flat-square)](https://www.npmjs.com/package/@portabletext/solid)[![npm bundle size](https://img.shields.io/bundlephobia/minzip/@portabletext/solid?style=flat-square)](https://bundlephobia.com/result?p=@portabletext/solid)

Render [Portable Text](https://portabletext.org/) with Solid JS.

## Table of contents

- [Installation](#installation)
- [Basic usage](#basic-usage)

## Installation

```
npm install --save @portabletext/solid
```

## Basic usage

```tsx
import { PortableText, type PortableTextComponents } from '@portabletext/solid'
import type { PortableTextBlock } from '@portabletext/types'
import type { Component } from 'solid-js'

const blocks: PortableTextBlock[] = [
  /* array of portable text blocks */
]

const components: PortableTextComponents = {
  /* optional object of custom components to use */
}

const App: Component = () => {
  return <PortableText value={blocks} components={components} />
}
```

## Credits

This repository is based on [`solid-portabletext`](https://github.com/nonphoto/solid-portabletext/tree/main), shoutout to [@nonphoto](https://github.com/nonphoto) for the original work 💖

## License

MIT
npm package: @portabletext/test
Description: Testing utilities for the Portable Text Editor
Author: Sanity.io
Latest version: 1.0.3

# @portabletext/test

Testing utilities for the Portable Text Editor.

## Terse PT

A compact syntax for writing Portable Text in tests, making test data more readable and maintainable.

### Parsing Terse PT

```ts
const tersePt = [
  'h1:Hello, world!',
  '{image}',
  '>-:Here are some unordered list items',
  '>-:With a nested ordered list:',
  '>>#:Ordered list item A',
  '>>#:Ordered list item B',
  'And here is a paragraph with an inline ,{stock-ticker},',
  'q:And a quote',
]

const blocks = parseTersePt(
  {
    schema: compileSchema(
      defineSchema({
        blockObjects: [{name: 'image'}],
        inlineObjects: [{name: 'stock-ticker'}],
        lists: [{name: 'bullet'}, {name: 'number'}],
        styles: [{name: 'h1'}, {name: 'blockquote'}],
      }),
    ),
    keyGenerator: createTestKeyGenerator(),
  },
  tersePt,
)
// [{_key: 'k0', _type: 'block', children: [...], style: 'h1'}, ...]
```

### Producing Terse PT

```ts
const blocks = [
  {
    _key: 'k0',
    _type: 'block',
    children: [{_key: 'k1', _type: 'span', text: 'foo'}],
  },
  {
    _key: 'k2',
    _type: 'block',
    children: [{_key: 'k3', _type: 'span', text: 'bar'}],
  },
]

const tersePt = getTersePt({
  schema: compileSchema(defineSchema({})),
  value: blocks,
})
// ['foo', 'bar']
```

## Key Generator

Generate predictable keys for test fixtures:

```ts
import {createTestKeyGenerator} from '@portabletext/test'

const keyGenerator = createTestKeyGenerator('test-')

keyGenerator() // 'test-k0'
keyGenerator() // 'test-k1'
keyGenerator() // 'test-k2'
```

## License

MIT © [Sanity.io](https://www.sanity.io/)
npm package: @portabletext/toolkit
Description: Toolkit of handy utility functions for dealing with Portable Text
Author: Sanity.io
Latest version: 5.0.2

# @portabletext/toolkit

[![npm version](https://img.shields.io/npm/v/@portabletext/toolkit.svg?style=flat-square)](https://www.npmjs.com/package/@portabletext/toolkit)[![npm bundle size](https://img.shields.io/bundlephobia/minzip/@portabletext/toolkit?style=flat-square)](https://bundlephobia.com/result?p=@portabletext/toolkit)[![Build Status](https://img.shields.io/github/actions/workflow/status/portabletext/toolkit/main.yml?branch=main&style=flat-square)](https://github.com/portabletext/toolkit/actions?query=workflow%3Atest)

Javascript toolkit of handy utility functions for dealing with Portable Text.

Particularly useful for building rendering libraries for Portable Text that outputs HTML.

## Installation

```
npm install --save @portabletext/toolkit
```

## Documentation

See [https://portabletext.github.io/toolkit/](https://portabletext.github.io/toolkit/)

## Usage

```ts
import {toPlainText} from '@portabletext/toolkit'

console.log(toPlainText(myPortableTextBlocks))
```

## License

MIT © [Sanity.io](https://www.sanity.io/)
npm package: @portabletext/types
Description: Shared TypeScript definitions for core Portable Text data structures
Author: Sanity.io
Latest version: 4.0.2

# @portabletext/types

[![npm version](https://img.shields.io/npm/v/@portabletext/types.svg?style=flat-square)](https://www.npmjs.com/package/@portabletext/types)[![Build Status](https://img.shields.io/github/actions/workflow/status/portabletext/types/main.yml?branch=main&style=flat-square)](https://github.com/portabletext/types/actions?query=workflow%3Atest)

TypeScript types for Portable Text

## Installation

```
npm install --save @portabletext/types
```

## Documentation

See [https://portabletext.github.io/types/](https://portabletext.github.io/types/)

## Usage

```ts
import type {
  PortableTextBlock,
  PortableTextSpan,
  PortableTextLink
} from '@portabletext/types'

const headingSpan: PortableTextSpan = {
  _type: 'span',
  _key: '5p4n',
  text: 'A simple Portable Text heading block',
  marks: [],
}

const myBlocks: PortableTextBlock[] = [
  {
    _type: 'block',
    _key: 'abc123',
    style: 'h1',
    children: [headingSpan],
    markDefs: [],
  },
  {
    _type: 'block',
    _key: 'xyz987',
    style: 'normal',
    children: [
      {_type: 'span', _key: 'c7', text: 'Check out the ', marks: []}
      {_type: 'span', _key: 'x2', text: 'TypeScript definitions', marks: ['m4hl1nk']},
      {_type: 'span', _key: 'u5', text: ' if you are using TS!', marks: []}
    ],
    markDefs: [
      {
        _key: 'm4hl1nk',
        _type: 'link',
        href: 'https://github.com/portabletext/types'
      }
    ],
  },
]

/**
 * Very specific Portable Text block, where:
 * - Only link and author references (custom) are allowed as marks
 * - Only Portable Text spans and `localCurrency` objects can be inline children
 * - Blocks can only be of style `normal` or `call-to-action` (custom)
 * - List items can only be of type `bullet`
 */
type MyCustomBlock = PortableTextListItemBlock<
  PortableTextLink | AuthorReference, // `M`: Marks
  PortableTextSpan | LocalCurrency,   // `C`: Children
  'normal' | 'call-to-action',        // `S`: Styles
  'bullet'                            // `L`: List item types
>
```

## License

MIT © [Sanity.io](https://www.sanity.io/)
npm package: @portacall/sdk
Description: Minimal server-side SDK for calling a Portacall agent.
Latest version: 0.1.0

# portacall

Minimal server-side SDK for calling a Portacall agent.

## Install

```bash
bun add @portacall/sdk
```

```bash
npm install @portacall/sdk
```

```bash
pnpm add @portacall/sdk
```

```bash
yarn add @portacall/sdk
```

## Usage

Use the SDK on your backend only. `secretKey` must never be exposed to the browser.

```ts
import { portacall } from "@portacall/sdk";

const agent = portacall({
  agentId: process.env.PORTACALL_AGENT_ID ?? "",
  secretKey: process.env.PORTACALL_SECRET_KEY ?? "",
});

const content = await agent.chat("Hello");
```

## Streaming

Use `stream()` when you want chunks as they arrive.

```ts
import { portacall } from "@portacall/sdk";

const agent = portacall({
  agentId: process.env.PORTACALL_AGENT_ID ?? "",
  secretKey: process.env.PORTACALL_SECRET_KEY ?? "",
});

let content = "";

for await (const chunk of agent.stream("Write a short welcome message")) {
  content += chunk;
  process.stdout.write(chunk);
}
```

## Error handling

```ts
import { portacall, PortacallError } from "@portacall/sdk";

const agent = portacall({
  agentId: process.env.PORTACALL_AGENT_ID ?? "",
  secretKey: process.env.PORTACALL_SECRET_KEY ?? "",
});

try {
  const content = await agent.chat("Hello");
  console.log(content);
} catch (error) {
  if (error instanceof PortacallError) {
    console.error(error.status, error.code, error.message);
  }

  throw error;
}
```

## Custom API URL

By default, the SDK sends requests to `https://api.portacall.ai`.

```ts
import { portacall } from "@portacall/sdk";

const agent = portacall({
  agentId: process.env.PORTACALL_AGENT_ID ?? "",
  secretKey: process.env.PORTACALL_SECRET_KEY ?? "",
  baseURL: "http://localhost:3000",
});

const content = await agent.chat("Hello from local development");
```

## Publishing

For the first publish:

```bash
npm login
npm whoami
bun run release:dry
bun run release
```

This package is org-scoped, so publishes go out as a public package under `@portacall/sdk`.

For later releases, bump the version first:

```bash
npm version patch
git push --follow-tags
bun run release
```

`release:dry` and `release` automatically trigger `prepublishOnly`, which runs:

```bash
bun run check
bun run build
```