#
tokens: 28975/50000 21/22 files (page 1/2)
lines: off (toggle) GitHub
raw markdown copy
This is page 1 of 2. Use http://codebase.md/orellazri/coda-mcp?page={x} to view the full context.

# Directory Structure

```
├── .github
│   └── workflows
│       ├── release-docker.yaml
│       └── release-npm.yaml
├── .gitignore
├── .prettierrc
├── Dockerfile
├── eslint.config.js
├── LICENSE
├── openapi-ts.config.ts
├── package.json
├── pnpm-lock.yaml
├── pnpm-workspace.yaml
├── README.md
├── release.sh
├── src
│   ├── client
│   │   ├── client.gen.ts
│   │   ├── helpers.ts
│   │   ├── index.ts
│   │   ├── sdk.gen.ts
│   │   └── types.gen.ts
│   ├── config.ts
│   ├── index.ts
│   ├── server.test.ts
│   └── server.ts
├── tsconfig.json
└── vitest.config.js
```

# Files

--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------

```
node_modules/
dist/
coverage/
.DS_Store
.env
.claude/

```

--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------

```
{
  "singleQuote": false,
  "trailingComma": "all",
  "printWidth": 120,
  "tabWidth": 2
}

```

--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------

```markdown
# Coda MCP Server

This project implements a Model Context Protocol (MCP) server that acts as a bridge to interact with the [Coda](https://coda.io/) API. It allows an MCP client (like an AI assistant) to perform actions on Coda pages, such as listing, creating, reading, updating, duplicating, and renaming.

## Features

The server exposes the following tools to the MCP client:

- **`coda_list_documents`**: Lists all documents available to the user.
- **`coda_list_pages`**: Lists all pages within the configured Coda document with pagination support.
- **`coda_create_page`**: Creates a new page in the document, optionally under a specified parent page (creating a subpage) and populating it with initial markdown content.
- **`coda_get_page_content`**: Retrieves the content of a specified page (by ID or name) as markdown.
- **`coda_replace_page_content`**: Replaces the content of a specified page with new markdown content.
- **`coda_append_page_content`**: Appends new markdown content to the end of a specified page.
- **`coda_duplicate_page`**: Creates a copy of an existing page with a new name.
- **`coda_rename_page`**: Renames an existing page.
- **`coda_peek_page`**: Peek into the beginning of a page and return a limited number of lines.
- **`coda_resolve_link`**: Resolve metadata given a browser link to a Coda object.

## Usage

Add the MCP server to Cursor/Claude Desktop/etc. like so:

```json
{
  "mcpServers": {
    "coda": {
      "command": "npx",
      "args": ["-y", "coda-mcp@latest"],
      "env": {
        "API_KEY": "..."
      }
    }
  }
}
```

Required environment variables:

- `API_KEY`: Your Coda API key. You can generate one from your Coda account settings.

This MCP server is also available with Docker, like so:

```json
{
  "mcpServers": {
    "coda": {
      "command": "docker",
      "args": ["run", "-i", "--rm", "-e", "API_KEY", "reaperberri/coda-mcp:latest"],
      "env": {
        "API_KEY": "..."
      }
    }
  }
}
```

## Local Setup

1.  **Prerequisites:**

    - Node.js
    - pnpm

2.  **Clone the repository:**

    ```bash
    git clone <repository-url>
    cd coda-mcp
    ```

3.  **Install dependencies:**

    ```bash
    pnpm install
    ```

4.  **Build the project:**
    ```bash
    pnpm build
    ```
    This compiles the TypeScript code to JavaScript in the `dist/` directory.

## Running the Server

The MCP server communicates over standard input/output (stdio). To run it, set the environment variables and run the compiled JavaScript file - `dist/index.js`.

```

--------------------------------------------------------------------------------
/pnpm-workspace.yaml:
--------------------------------------------------------------------------------

```yaml
onlyBuiltDependencies:
  - esbuild

```

--------------------------------------------------------------------------------
/src/config.ts:
--------------------------------------------------------------------------------

```typescript
type Config = {
  apiKey: string;
};

export const config: Config = {
  apiKey: process.env.API_KEY!,
};

```

--------------------------------------------------------------------------------
/src/client/index.ts:
--------------------------------------------------------------------------------

```typescript
// This file is auto-generated by @hey-api/openapi-ts
export * from "./types.gen";
export * from "./sdk.gen";

```

--------------------------------------------------------------------------------
/vitest.config.js:
--------------------------------------------------------------------------------

```javascript
import { defineConfig } from "vitest/config";

export default defineConfig({
  test: {
    coverage: {
      include: ["src/server.ts"],
    },
  },
});

```

--------------------------------------------------------------------------------
/openapi-ts.config.ts:
--------------------------------------------------------------------------------

```typescript
import { defineConfig } from "@hey-api/openapi-ts";

export default defineConfig({
  input: "https://coda.io/apis/v1/openapi.yaml",
  output: {
    format: "prettier",
    path: "src/client",
  },
  plugins: ["@hey-api/client-axios"],
});

```

--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------

```dockerfile
FROM node:23-alpine AS base

ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"
RUN corepack enable

WORKDIR /app

COPY package.json pnpm-lock.yaml pnpm-workspace.yaml ./
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm install --frozen-lockfile

COPY . /app

RUN pnpm run build

RUN addgroup -g 1001 -S appgroup && \
    adduser -S appuser -u 1001 -G appgroup
RUN chown -R appuser:appgroup /app
USER appuser

CMD ["node", "dist/index.js"]

```

--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------

```json
{
  "$schema": "https://json.schemastore.org/tsconfig",
  "display": "Node 23",
  "_version": "23.0.0",

  "compilerOptions": {
    "lib": ["es2024"],
    "module": "nodenext",
    "target": "es2024",

    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "moduleResolution": "node16",
    "resolveJsonModule": true,

    "rootDir": "src",
    "outDir": "dist"
  },
  "exclude": ["node_modules", "dist", "openapi-ts.config.ts"]
}

```

--------------------------------------------------------------------------------
/eslint.config.js:
--------------------------------------------------------------------------------

```javascript
import js from "@eslint/js";
import { defineConfig } from "eslint/config";
import globals from "globals";
import tseslint from "typescript-eslint";

export default defineConfig([
  { files: ["**/*.{js,mjs,cjs,ts}"], plugins: { js }, extends: ["js/recommended"] },
  { files: ["**/*.{js,mjs,cjs,ts}"], languageOptions: { globals: globals.browser } },
  tseslint.configs.recommended,
  {
    ignores: ["dist", "src/api/openapi.ts"],
  },
  {
    rules: {
      "@typescript-eslint/no-explicit-any": "off",
    },
  },
]);

```

--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------

```typescript
#!/usr/bin/env node

import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { client } from "./client/client.gen";
import { config } from "./config";
import { server } from "./server";

async function main() {
  // Initialize Axios Client
  client.setConfig({
    baseURL: "https://coda.io/apis/v1",
    headers: {
      Authorization: `Bearer ${config.apiKey}`,
    },
  });

  // Initialize MCP Server
  const transport = new StdioServerTransport();
  await server.connect(transport);
  console.error("Coda MCP server running on stdio");
}

main().catch((error) => {
  console.error("Fatal error in main():", error);
  process.exit(1);
});

```

--------------------------------------------------------------------------------
/release.sh:
--------------------------------------------------------------------------------

```bash
#!/bin/bash

# Get current version
CURRENT_VERSION=$(pnpm dlx json -f package.json version)
echo "Current version: $CURRENT_VERSION"

# Prompt for the new version tag
echo "Enter the new version tag (without 'v' prefix, e.g. 1.0.1):"
read VERSION

# Validate version format
if ! [[ $VERSION =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then
  echo "Error: Version must be in format X.Y.Z (e.g. 1.0.1)"
  exit 1
fi

# Update package.json version
pnpm dlx json -I -f package.json -e "this.version='$VERSION'"

# Commit the change
git add package.json
git commit -m "chore: bump version to $VERSION"

# Create and push the tag
git tag "v$VERSION"
git push origin main
git push --tags

echo "✅ Version bumped to $VERSION and tag v$VERSION pushed!" 

```

--------------------------------------------------------------------------------
/.github/workflows/release-npm.yaml:
--------------------------------------------------------------------------------

```yaml
name: Release and Publish to npm

on:
  push:
    tags:
      - "v*"

permissions:
  contents: write
  id-token: write

jobs:
  release:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Set up pnpm
        uses: pnpm/action-setup@v4

      - name: Set up Node.js
        uses: actions/setup-node@v4
        with:
          node-version: "23.x"
          registry-url: "https://registry.npmjs.org/"
          cache: "pnpm"

      - name: Install dependencies
        run: pnpm install

      - name: Build project
        run: pnpm build

      - name: Publish package to npm registry
        run: pnpm publish --provenance --access public --no-git-checks
        env:
          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

```

--------------------------------------------------------------------------------
/src/client/client.gen.ts:
--------------------------------------------------------------------------------

```typescript
// This file is auto-generated by @hey-api/openapi-ts

import type { ClientOptions } from "./types.gen";
import {
  type Config,
  type ClientOptions as DefaultClientOptions,
  createClient,
  createConfig,
} from "@hey-api/client-axios";

/**
 * The `createClientConfig()` function will be called on client initialization
 * and the returned object will become the client's initial configuration.
 *
 * You may want to initialize your client this way instead of calling
 * `setConfig()`. This is useful for example if you're using Next.js
 * to ensure your client always has the correct values.
 */
export type CreateClientConfig<T extends DefaultClientOptions = ClientOptions> = (
  override?: Config<DefaultClientOptions & T>,
) => Config<Required<DefaultClientOptions> & T>;

export const client = createClient(
  createConfig<ClientOptions>({
    baseURL: "https://coda.io/apis/v1",
  }),
);

```

--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------

```json
{
  "name": "coda-mcp",
  "version": "1.5.1",
  "description": "MCP Server for Coda",
  "repository": {
    "url": "https://github.com/orellazri/coda-mcp"
  },
  "bin": {
    "coda": "./dist/index.js"
  },
  "files": [
    "dist"
  ],
  "scripts": {
    "build": "tsc && chmod 755 dist/index.js",
    "lint": "eslint .",
    "format": "prettier --write .",
    "test": "vitest run --coverage",
    "test:watch": "vitest",
    "openapi-ts": "openapi-ts",
    "inspect": "pnpm dlx @modelcontextprotocol/inspector dist/index.js"
  },
  "dependencies": {
    "@hey-api/client-axios": "^0.7.0",
    "@modelcontextprotocol/sdk": "^1.11.2",
    "axios": "^1.9.0",
    "zod": "^3.24.4"
  },
  "devDependencies": {
    "@eslint/js": "^9.26.0",
    "@hey-api/openapi-ts": "^0.67.3",
    "@types/node": "^22.15.17",
    "@vitest/coverage-v8": "3.1.4",
    "eslint": "^9.26.0",
    "globals": "^16.1.0",
    "mcp-testing-kit": "^0.2.0",
    "prettier": "^3.5.3",
    "typescript": "^5.8.3",
    "typescript-eslint": "^8.32.1",
    "vitest": "^3.1.4"
  },
  "packageManager": "[email protected]"
}

```

--------------------------------------------------------------------------------
/src/client/helpers.ts:
--------------------------------------------------------------------------------

```typescript
import axios from "axios";
import { beginPageContentExport, getPageContentExportStatus } from "./sdk.gen";

export async function getPageContent(docId: string, pageIdOrName: string) {
  let requestId: string | undefined;
  try {
    // Begin page export
    const beginExportResp = await beginPageContentExport({
      path: {
        docId,
        pageIdOrName,
      },
      body: {
        outputFormat: "markdown",
      },
      throwOnError: true,
    });

    if (!beginExportResp.data) {
      throw new Error("Failed to begin page content export");
    }

    requestId = beginExportResp.data.id;
  } catch (error) {
    throw new Error(`Failed to get page content: ${error}`);
  }

  // Poll for export status
  let retries = 0;
  const maxRetries = 5;
  let downloadLink: string | undefined;

  while (retries < maxRetries) {
    // Wait for 5 seconds
    await new Promise((resolve) => setTimeout(resolve, 5000));

    try {
      const exportStatusResp = await getPageContentExportStatus({
        path: {
          docId,
          pageIdOrName,
          requestId,
        },
        throwOnError: true,
      });

      if (exportStatusResp.data?.status === "complete") {
        downloadLink = exportStatusResp.data.downloadLink;
        break;
      }
    } catch (error) {
      throw new Error(`Failed to get page content export status: ${error}`);
    }

    retries++;
    if (retries >= maxRetries) {
      throw new Error(`Page content export did not complete after ${maxRetries} retries.`);
    }
  }

  if (!downloadLink) {
    throw new Error("Failed to get page content export status");
  }

  try {
    const downloadResponse = await axios.get<string>(downloadLink, {
      responseType: "text",
    });

    const markdownContent = downloadResponse.data;

    return markdownContent;
  } catch {
    throw new Error(`Failed to download exported page content from ${downloadLink}. `);
  }
}

```

--------------------------------------------------------------------------------
/.github/workflows/release-docker.yaml:
--------------------------------------------------------------------------------

```yaml
name: Release and Publish to Docker Hub

on:
  push:
    tags:
      - "v*"

permissions:
  contents: write
  id-token: write

jobs:
  release:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v2

      - name: Log in to Docker Hub
        uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a
        with:
          username: ${{ secrets.DOCKERHUB_USERNAME }}
          password: ${{ secrets.DOCKERHUB_PASSWORD }}

      - name: Build and Push Docker image
        run: |
          VERSION_TAG=${GITHUB_REF#refs/tags/v}
          docker buildx build --push --platform linux/amd64,linux/arm64/v8 \
            --tag reaperberri/coda-mcp:latest \
            --tag reaperberri/coda-mcp:${VERSION_TAG} .

      - name: Build Changelog
        uses: mikepenz/release-changelog-builder-action@v5
        with:
          mode: "COMMIT"
          configurationJson: |
            {
              "template": "#{{CHANGELOG}}",
              "categories": [
                {
                    "title": "## Feature",
                    "labels": ["feat", "feature"]
                },
                {
                    "title": "## Fix",
                    "labels": ["fix", "bug"]
                },
                {
                    "title": "## Other",
                    "labels": []
                }
              ],
              "label_extractor": [
                {
                  "pattern": "^(build|chore|ci|docs|feat|fix|perf|refactor|revert|style|test){1}(\\([\\w\\-\\.]+\\))?(!)?: ([\\w ])+([\\s\\S]*)",
                  "on_property": "title",
                  "target": "$1"
                }
              ]
            }
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

      - name: Create Release
        uses: mikepenz/[email protected]
        with:
          body: ${{steps.github_release.outputs.changelog}}

```

--------------------------------------------------------------------------------
/src/server.ts:
--------------------------------------------------------------------------------

```typescript
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
import z from "zod";
import packageJson from "../package.json";
import { getPageContent } from "./client/helpers";
import { createPage, listDocs, listPages, resolveBrowserLink, updatePage } from "./client/sdk.gen";

export const server = new McpServer({
  name: "coda",
  version: packageJson.version,
  capabilities: {
    resources: {},
    tools: {},
  },
});

server.tool(
  "coda_list_documents",
  "List or search available documents",
  {
    query: z.string().optional().describe("The query to search for documents by - optional"),
  },
  async ({ query }): Promise<CallToolResult> => {
    try {
      const resp = await listDocs({ query: { query }, throwOnError: true });

      return { content: [{ type: "text", text: JSON.stringify(resp.data) }] };
    } catch (error) {
      return { content: [{ type: "text", text: `Failed to list documents: ${error}` }], isError: true };
    }
  },
);

server.tool(
  "coda_list_pages",
  "List pages in the current document with pagination",
  {
    docId: z.string().describe("The ID of the document to list pages from"),
    limit: z.number().int().positive().optional().describe("The number of pages to return - optional, defaults to 25"),
    nextPageToken: z
      .string()
      .optional()
      .describe(
        "The token need to get the next page of results, returned from a previous call to this tool - optional",
      ),
  },
  async ({ docId, limit, nextPageToken }): Promise<CallToolResult> => {
    try {
      const listLimit = nextPageToken ? undefined : limit;

      const resp = await listPages({
        path: { docId },
        query: { limit: listLimit, pageToken: nextPageToken ?? undefined },
        throwOnError: true,
      });

      return {
        content: [{ type: "text", text: JSON.stringify(resp.data) }],
      };
    } catch (error) {
      return {
        content: [{ type: "text", text: `Failed to list pages: ${error}` }],
        isError: true,
      };
    }
  },
);

server.tool(
  "coda_create_page",
  "Create a page in the current document",
  {
    docId: z.string().describe("The ID of the document to create the page in"),
    name: z.string().describe("The name of the page to create"),
    content: z.string().optional().describe("The markdown content of the page to create - optional"),
    parentPageId: z.string().optional().describe("The ID of the parent page to create this page under - optional"),
  },
  async ({ docId, name, content, parentPageId }): Promise<CallToolResult> => {
    try {
      const resp = await createPage({
        path: { docId },
        body: {
          name,
          parentPageId: parentPageId ?? undefined,
          pageContent: {
            type: "canvas",
            canvasContent: { format: "markdown", content: content ?? " " },
          },
        },
        throwOnError: true,
      });

      return {
        content: [{ type: "text", text: JSON.stringify(resp.data) }],
      };
    } catch (error) {
      return { content: [{ type: "text", text: `Failed to create page: ${error}` }], isError: true };
    }
  },
);

server.tool(
  "coda_get_page_content",
  "Get the content of a page as markdown",
  {
    docId: z.string().describe("The ID of the document that contains the page to get the content of"),
    pageIdOrName: z.string().describe("The ID or name of the page to get the content of"),
  },
  async ({ docId, pageIdOrName }): Promise<CallToolResult> => {
    try {
      const content = await getPageContent(docId, pageIdOrName);

      if (content === undefined) {
        throw new Error("Unknown error has occurred");
      }

      return { content: [{ type: "text", text: content }] };
    } catch (error) {
      return { content: [{ type: "text", text: `Failed to get page content: ${error}` }], isError: true };
    }
  },
);

server.tool(
  "coda_peek_page",
  "Peek into the beginning of a page and return a limited number of lines",
  {
    docId: z.string().describe("The ID of the document that contains the page to peek into"),
    pageIdOrName: z.string().describe("The ID or name of the page to peek into"),
    numLines: z
      .number()
      .int()
      .positive()
      .describe("The number of lines to return from the start of the page - usually 30 lines is enough"),
  },
  async ({ docId, pageIdOrName, numLines }): Promise<CallToolResult> => {
    try {
      const content = await getPageContent(docId, pageIdOrName);

      if (!content) {
        throw new Error("Unknown error has occurred");
      }

      const preview = content.split(/\r?\n/).slice(0, numLines).join("\n");

      return { content: [{ type: "text", text: preview }] };
    } catch (error) {
      return {
        content: [{ type: "text", text: `Failed to peek page: ${error}` }],
        isError: true,
      };
    }
  },
);

server.tool(
  "coda_replace_page_content",
  "Replace the content of a page with new markdown content",
  {
    docId: z.string().describe("The ID of the document that contains the page to replace the content of"),
    pageIdOrName: z.string().describe("The ID or name of the page to replace the content of"),
    content: z.string().describe("The markdown content to replace the page with"),
  },
  async ({ docId, pageIdOrName, content }): Promise<CallToolResult> => {
    try {
      const resp = await updatePage({
        path: {
          docId,
          pageIdOrName,
        },
        body: {
          // @ts-expect-error auto-generated client types
          contentUpdate: {
            insertionMode: "replace",
            canvasContent: { format: "markdown", content },
          },
        },
        throwOnError: true,
      });

      return { content: [{ type: "text", text: JSON.stringify(resp.data) }] };
    } catch (error) {
      return { content: [{ type: "text", text: `Failed to replace page content: ${error}` }], isError: true };
    }
  },
);

server.tool(
  "coda_append_page_content",
  "Append new markdown content to the end of a page",
  {
    docId: z.string().describe("The ID of the document that contains the page to append the content to"),
    pageIdOrName: z.string().describe("The ID or name of the page to append the content to"),
    content: z.string().describe("The markdown content to append to the page"),
  },
  async ({ docId, pageIdOrName, content }): Promise<CallToolResult> => {
    try {
      const resp = await updatePage({
        path: {
          docId,
          pageIdOrName,
        },
        body: {
          // @ts-expect-error auto-generated client types
          contentUpdate: {
            insertionMode: "append",
            canvasContent: { format: "markdown", content },
          },
        },
        throwOnError: true,
      });

      return { content: [{ type: "text", text: JSON.stringify(resp.data) }] };
    } catch (error) {
      return { content: [{ type: "text", text: `Failed to append page content: ${error}` }], isError: true };
    }
  },
);

server.tool(
  "coda_duplicate_page",
  "Duplicate a page in the current document",
  {
    docId: z.string().describe("The ID of the document that contains the page to duplicate"),
    pageIdOrName: z.string().describe("The ID or name of the page to duplicate"),
    newName: z.string().describe("The name of the new page"),
  },
  async ({ docId, pageIdOrName, newName }): Promise<CallToolResult> => {
    try {
      const pageContent = await getPageContent(docId, pageIdOrName);
      const createResp = await createPage({
        path: { docId },
        body: {
          name: newName,
          pageContent: { type: "canvas", canvasContent: { format: "markdown", content: pageContent } },
        },
        throwOnError: true,
      });

      return { content: [{ type: "text", text: JSON.stringify(createResp.data) }] };
    } catch (error) {
      return { content: [{ type: "text", text: `Failed to duplicate page: ${error}` }], isError: true };
    }
  },
);

server.tool(
  "coda_rename_page",
  "Rename a page in the current document",
  {
    docId: z.string().describe("The ID of the document that contains the page to rename"),
    pageIdOrName: z.string().describe("The ID or name of the page to rename"),
    newName: z.string().describe("The new name of the page"),
  },
  async ({ docId, pageIdOrName, newName }): Promise<CallToolResult> => {
    try {
      const resp = await updatePage({
        path: { docId, pageIdOrName },
        body: {
          name: newName,
        },
        throwOnError: true,
      });

      return { content: [{ type: "text", text: JSON.stringify(resp.data) }] };
    } catch (error) {
      return { content: [{ type: "text", text: `Failed to rename page: ${error}` }], isError: true };
    }
  },
);

server.tool(
  "coda_resolve_link",
  "Resolve metadata given a browser link to a Coda object",
  {
    url: z.string().describe("The URL to resolve"),
  },
  async ({ url }): Promise<CallToolResult> => {
    try {
      const resp = await resolveBrowserLink({
        query: { url },
        throwOnError: true,
      });

      return { content: [{ type: "text", text: JSON.stringify(resp.data) }] };
    } catch (error) {
      return { content: [{ type: "text", text: `Failed to resolve link: ${error}` }], isError: true };
    }
  },
);

```

--------------------------------------------------------------------------------
/src/server.test.ts:
--------------------------------------------------------------------------------

```typescript
import { close, connect } from "mcp-testing-kit";
import { afterEach, describe, expect, it, vi } from "vitest";
import * as helpers from "./client/helpers";
import * as sdk from "./client/sdk.gen";
import { server as mcpServer } from "./server";

vi.mock("./client/sdk.gen");
vi.mock("./client/helpers");
vi.mock("axios");

describe("MCP Server", () => {
  afterEach(async () => {
    await close(mcpServer.server);
    vi.clearAllMocks();
  });

  it("should have all tools", async () => {
    const client = await connect(mcpServer.server);
    const result = await client.listTools();
    expect(result.tools).toEqual([
      expect.objectContaining({ name: "coda_list_documents" }),
      expect.objectContaining({ name: "coda_list_pages" }),
      expect.objectContaining({ name: "coda_create_page" }),
      expect.objectContaining({ name: "coda_get_page_content" }),
      expect.objectContaining({ name: "coda_peek_page" }),
      expect.objectContaining({ name: "coda_replace_page_content" }),
      expect.objectContaining({ name: "coda_append_page_content" }),
      expect.objectContaining({ name: "coda_duplicate_page" }),
      expect.objectContaining({ name: "coda_rename_page" }),
      expect.objectContaining({ name: "coda_resolve_link" }),
    ]);
  });
});

describe("coda_list_documents", () => {
  it("should list documents without query", async () => {
    vi.mocked(sdk.listDocs).mockResolvedValue({
      data: {
        items: [
          { id: "123", name: "Test Document" },
          { id: "456", name: "Another Document" },
        ],
      },
    } as any);

    const client = await connect(mcpServer.server);
    const result = await client.callTool("coda_list_documents", { query: "" });
    expect(result.content).toEqual([
      {
        type: "text",
        text: JSON.stringify({
          items: [
            { id: "123", name: "Test Document" },
            { id: "456", name: "Another Document" },
          ],
        }),
      },
    ]);
  });

  it("should list documents with query", async () => {
    vi.mocked(sdk.listDocs).mockResolvedValue({
      data: {
        items: [{ id: "123", name: "Test Document" }],
      },
    } as any);

    const client = await connect(mcpServer.server);
    const result = await client.callTool("coda_list_documents", { query: "test" });
    expect(result.content).toEqual([
      {
        type: "text",
        text: JSON.stringify({
          items: [{ id: "123", name: "Test Document" }],
        }),
      },
    ]);
  });

  it("should show error if list documents throws", async () => {
    vi.mocked(sdk.listDocs).mockRejectedValue(new Error("foo"));

    const client = await connect(mcpServer.server);
    const result = await client.callTool("coda_list_documents", { query: "test" });
    expect(result.content).toEqual([{ type: "text", text: "Failed to list documents: Error: foo" }]);
  });
});

describe("coda_list_pages", () => {
  it("should list pages successfully without limit or nextPageToken", async () => {
    vi.mocked(sdk.listPages).mockResolvedValue({
      data: {
        items: [
          { id: "page-123", name: "Test Page 1" },
          { id: "page-456", name: "Test Page 2" },
        ],
      },
    } as any);

    const client = await connect(mcpServer.server);
    const result = await client.callTool("coda_list_pages", { docId: "doc-123" });
    expect(result.content).toEqual([
      {
        type: "text",
        text: JSON.stringify({
          items: [
            { id: "page-123", name: "Test Page 1" },
            { id: "page-456", name: "Test Page 2" },
          ],
        }),
      },
    ]);
    expect(sdk.listPages).toHaveBeenCalledWith({
      path: { docId: "doc-123" },
      query: { limit: undefined, pageToken: undefined },
      throwOnError: true,
    });
  });

  it("should list pages with limit", async () => {
    vi.mocked(sdk.listPages).mockResolvedValue({
      data: {
        items: [
          { id: "page-123", name: "Test Page 1" },
          { id: "page-456", name: "Test Page 2" },
        ],
        nextPageToken: "token-123",
      },
    } as any);

    const client = await connect(mcpServer.server);
    const result = await client.callTool("coda_list_pages", { docId: "doc-123", limit: 10 });
    expect(result.content).toEqual([
      {
        type: "text",
        text: JSON.stringify({
          items: [
            { id: "page-123", name: "Test Page 1" },
            { id: "page-456", name: "Test Page 2" },
          ],
          nextPageToken: "token-123",
        }),
      },
    ]);
    expect(sdk.listPages).toHaveBeenCalledWith({
      path: { docId: "doc-123" },
      query: { limit: 10, pageToken: undefined },
      throwOnError: true,
    });
  });

  it("should list pages with nextPageToken", async () => {
    vi.mocked(sdk.listPages).mockResolvedValue({
      data: {
        items: [
          { id: "page-789", name: "Test Page 3" },
          { id: "page-101", name: "Test Page 4" },
        ],
      },
    } as any);

    const client = await connect(mcpServer.server);
    const result = await client.callTool("coda_list_pages", {
      docId: "doc-123",
      nextPageToken: "token-123",
    });
    expect(result.content).toEqual([
      {
        type: "text",
        text: JSON.stringify({
          items: [
            { id: "page-789", name: "Test Page 3" },
            { id: "page-101", name: "Test Page 4" },
          ],
        }),
      },
    ]);
    expect(sdk.listPages).toHaveBeenCalledWith({
      path: { docId: "doc-123" },
      query: { limit: undefined, pageToken: "token-123" },
      throwOnError: true,
    });
  });

  it("should prioritize nextPageToken over limit", async () => {
    vi.mocked(sdk.listPages).mockResolvedValue({
      data: {
        items: [{ id: "page-789", name: "Test Page 3" }],
      },
    } as any);

    const client = await connect(mcpServer.server);
    const result = await client.callTool("coda_list_pages", {
      docId: "doc-123",
      limit: 5,
      nextPageToken: "token-123",
    });
    expect(result.content).toEqual([
      {
        type: "text",
        text: JSON.stringify({
          items: [{ id: "page-789", name: "Test Page 3" }],
        }),
      },
    ]);
    // When nextPageToken is provided, limit should be undefined
    expect(sdk.listPages).toHaveBeenCalledWith({
      path: { docId: "doc-123" },
      query: { limit: undefined, pageToken: "token-123" },
      throwOnError: true,
    });
  });

  it("should show error if list pages throws", async () => {
    vi.mocked(sdk.listPages).mockRejectedValue(new Error("Access denied"));

    const client = await connect(mcpServer.server);
    const result = await client.callTool("coda_list_pages", { docId: "doc-123" });
    expect(result.content).toEqual([{ type: "text", text: "Failed to list pages: Error: Access denied" }]);
  });
});

describe("coda_create_page", () => {
  it("should create page with content", async () => {
    vi.mocked(sdk.createPage).mockResolvedValue({
      data: {
        id: "page-new",
        requestId: "req-123",
      },
    } as any);

    const client = await connect(mcpServer.server);
    const result = await client.callTool("coda_create_page", {
      docId: "doc-123",
      name: "New Page",
      content: "# Hello World",
    });
    expect(result.content).toEqual([
      {
        type: "text",
        text: JSON.stringify({
          id: "page-new",
          requestId: "req-123",
        }),
      },
    ]);
    expect(sdk.createPage).toHaveBeenCalledWith({
      path: { docId: "doc-123" },
      body: {
        name: "New Page",
        pageContent: {
          type: "canvas",
          canvasContent: { format: "markdown", content: "# Hello World" },
        },
      },
      throwOnError: true,
    });
  });

  it("should create page without content", async () => {
    vi.mocked(sdk.createPage).mockResolvedValue({
      data: {
        id: "page-new",
        requestId: "req-124",
      },
    } as any);

    const client = await connect(mcpServer.server);
    await client.callTool("coda_create_page", {
      docId: "doc-123",
      name: "Empty Page",
    });
    expect(sdk.createPage).toHaveBeenCalledWith({
      path: { docId: "doc-123" },
      body: {
        name: "Empty Page",
        pageContent: {
          type: "canvas",
          canvasContent: { format: "markdown", content: " " },
        },
      },
      throwOnError: true,
    });
  });

  it("should create page with parent page id and content", async () => {
    vi.mocked(sdk.createPage).mockResolvedValue({
      data: {
        id: "page-sub",
        requestId: "req-125",
      },
    } as any);

    const client = await connect(mcpServer.server);
    const result = await client.callTool("coda_create_page", {
      docId: "doc-123",
      name: "Subpage",
      parentPageId: "page-456",
      content: "## Subheading",
    });
    expect(result.content).toEqual([
      {
        type: "text",
        text: JSON.stringify({ id: "page-sub", requestId: "req-125" }),
      },
    ]);
    expect(sdk.createPage).toHaveBeenCalledWith({
      path: { docId: "doc-123" },
      body: {
        name: "Subpage",
        parentPageId: "page-456",
        pageContent: {
          type: "canvas",
          canvasContent: { format: "markdown", content: "## Subheading" },
        },
      },
      throwOnError: true,
    });
  });

  it("should show error if create page throws", async () => {
    vi.mocked(sdk.createPage).mockRejectedValue(new Error("Insufficient permissions"));

    const client = await connect(mcpServer.server);
    const result = await client.callTool("coda_create_page", {
      docId: "doc-123",
      name: "New Page",
    });
    expect(result.content).toEqual([{ type: "text", text: "Failed to create page: Error: Insufficient permissions" }]);
  });
});

describe("coda_get_page_content", () => {
  it("should get page content successfully", async () => {
    vi.mocked(helpers.getPageContent).mockResolvedValue("# Page Title\n\nThis is the content.");

    const client = await connect(mcpServer.server);
    const result = await client.callTool("coda_get_page_content", {
      docId: "doc-123",
      pageIdOrName: "page-456",
    });
    expect(result.content).toEqual([
      {
        type: "text",
        text: "# Page Title\n\nThis is the content.",
      },
    ]);
    expect(helpers.getPageContent).toHaveBeenCalledWith("doc-123", "page-456");
  });

  it("should handle empty page content", async () => {
    vi.mocked(helpers.getPageContent).mockResolvedValue("");

    const client = await connect(mcpServer.server);
    const result = await client.callTool("coda_get_page_content", {
      docId: "doc-123",
      pageIdOrName: "page-456",
    });
    expect(result.content).toEqual([
      {
        type: "text",
        text: "",
      },
    ]);
  });

  it("should show error if getPageContent returns undefined", async () => {
    vi.mocked(helpers.getPageContent).mockResolvedValue(undefined as any);

    const client = await connect(mcpServer.server);
    const result = await client.callTool("coda_get_page_content", {
      docId: "doc-123",
      pageIdOrName: "page-456",
    });
    expect(result.content).toEqual([
      { type: "text", text: "Failed to get page content: Error: Unknown error has occurred" },
    ]);
  });

  it("should show error if getPageContent throws", async () => {
    vi.mocked(helpers.getPageContent).mockRejectedValue(new Error("Export failed"));

    const client = await connect(mcpServer.server);
    const result = await client.callTool("coda_get_page_content", {
      docId: "doc-123",
      pageIdOrName: "page-456",
    });
    expect(result.content).toEqual([{ type: "text", text: "Failed to get page content: Error: Export failed" }]);
  });
});

describe("coda_peek_page", () => {
  it("should peek page content successfully", async () => {
    vi.mocked(helpers.getPageContent).mockResolvedValue("# Title\nLine 1\nLine 2\nLine 3");

    const client = await connect(mcpServer.server);
    const result = await client.callTool("coda_peek_page", {
      docId: "doc-123",
      pageIdOrName: "page-456",
      numLines: 2,
    });
    expect(result.content).toEqual([
      {
        type: "text",
        text: "# Title\nLine 1",
      },
    ]);
    expect(helpers.getPageContent).toHaveBeenCalledWith("doc-123", "page-456");
  });

  it("should show error if getPageContent returns undefined", async () => {
    vi.mocked(helpers.getPageContent).mockResolvedValue(undefined as any);

    const client = await connect(mcpServer.server);
    const result = await client.callTool("coda_peek_page", {
      docId: "doc-123",
      pageIdOrName: "page-456",
      numLines: 1,
    });
    expect(result.content).toEqual([{ type: "text", text: "Failed to peek page: Error: Unknown error has occurred" }]);
  });

  it("should show error if getPageContent throws", async () => {
    vi.mocked(helpers.getPageContent).mockRejectedValue(new Error("Export failed"));

    const client = await connect(mcpServer.server);
    const result = await client.callTool("coda_peek_page", {
      docId: "doc-123",
      pageIdOrName: "page-456",
      numLines: 3,
    });
    expect(result.content).toEqual([{ type: "text", text: "Failed to peek page: Error: Export failed" }]);
  });
});

describe("coda_replace_page_content", () => {
  it("should replace page content successfully", async () => {
    vi.mocked(sdk.updatePage).mockResolvedValue({
      data: {
        id: "page-456",
        requestId: "req-125",
      },
    } as any);

    const client = await connect(mcpServer.server);
    const result = await client.callTool("coda_replace_page_content", {
      docId: "doc-123",
      pageIdOrName: "page-456",
      content: "# New Content\n\nReplaced content.",
    });
    expect(result.content).toEqual([
      {
        type: "text",
        text: JSON.stringify({
          id: "page-456",
          requestId: "req-125",
        }),
      },
    ]);
    expect(sdk.updatePage).toHaveBeenCalledWith({
      path: { docId: "doc-123", pageIdOrName: "page-456" },
      body: {
        contentUpdate: {
          insertionMode: "replace",
          canvasContent: { format: "markdown", content: "# New Content\n\nReplaced content." },
        },
      },
      throwOnError: true,
    });
  });

  it("should show error if replace page content throws", async () => {
    vi.mocked(sdk.updatePage).mockRejectedValue(new Error("Update failed"));

    const client = await connect(mcpServer.server);
    const result = await client.callTool("coda_replace_page_content", {
      docId: "doc-123",
      pageIdOrName: "page-456",
      content: "# New Content",
    });
    expect(result.content).toEqual([{ type: "text", text: "Failed to replace page content: Error: Update failed" }]);
  });
});

describe("coda_append_page_content", () => {
  it("should append page content successfully", async () => {
    vi.mocked(sdk.updatePage).mockResolvedValue({
      data: {
        id: "page-456",
        requestId: "req-126",
      },
    } as any);

    const client = await connect(mcpServer.server);
    const result = await client.callTool("coda_append_page_content", {
      docId: "doc-123",
      pageIdOrName: "page-456",
      content: "\n\n## Appended Section\n\nNew content.",
    });
    expect(result.content).toEqual([
      {
        type: "text",
        text: JSON.stringify({
          id: "page-456",
          requestId: "req-126",
        }),
      },
    ]);
    expect(sdk.updatePage).toHaveBeenCalledWith({
      path: { docId: "doc-123", pageIdOrName: "page-456" },
      body: {
        contentUpdate: {
          insertionMode: "append",
          canvasContent: { format: "markdown", content: "\n\n## Appended Section\n\nNew content." },
        },
      },
      throwOnError: true,
    });
  });

  it("should show error if append page content throws", async () => {
    vi.mocked(sdk.updatePage).mockRejectedValue(new Error("Append failed"));

    const client = await connect(mcpServer.server);
    const result = await client.callTool("coda_append_page_content", {
      docId: "doc-123",
      pageIdOrName: "page-456",
      content: "Additional content",
    });
    expect(result.content).toEqual([{ type: "text", text: "Failed to append page content: Error: Append failed" }]);
  });
});

describe("coda_duplicate_page", () => {
  it("should duplicate page successfully", async () => {
    vi.mocked(helpers.getPageContent).mockResolvedValue("# Original Page\n\nOriginal content.");
    vi.mocked(sdk.createPage).mockResolvedValue({
      data: {
        id: "page-duplicate",
        requestId: "req-127",
      },
    } as any);

    const client = await connect(mcpServer.server);
    const result = await client.callTool("coda_duplicate_page", {
      docId: "doc-123",
      pageIdOrName: "page-456",
      newName: "Duplicated Page",
    });
    expect(result.content).toEqual([
      {
        type: "text",
        text: JSON.stringify({
          id: "page-duplicate",
          requestId: "req-127",
        }),
      },
    ]);
    expect(helpers.getPageContent).toHaveBeenCalledWith("doc-123", "page-456");
    expect(sdk.createPage).toHaveBeenCalledWith({
      path: { docId: "doc-123" },
      body: {
        name: "Duplicated Page",
        pageContent: {
          type: "canvas",
          canvasContent: { format: "markdown", content: "# Original Page\n\nOriginal content." },
        },
      },
      throwOnError: true,
    });
  });

  it("should show error if getPageContent fails during duplication", async () => {
    vi.mocked(helpers.getPageContent).mockRejectedValue(new Error("Content fetch failed"));

    const client = await connect(mcpServer.server);
    const result = await client.callTool("coda_duplicate_page", {
      docId: "doc-123",
      pageIdOrName: "page-456",
      newName: "Duplicated Page",
    });
    expect(result.content).toEqual([{ type: "text", text: "Failed to duplicate page: Error: Content fetch failed" }]);
  });

  it("should show error if createPage fails during duplication", async () => {
    vi.mocked(helpers.getPageContent).mockResolvedValue("# Original Page");
    vi.mocked(sdk.createPage).mockRejectedValue(new Error("Create failed"));

    const client = await connect(mcpServer.server);
    const result = await client.callTool("coda_duplicate_page", {
      docId: "doc-123",
      pageIdOrName: "page-456",
      newName: "Duplicated Page",
    });
    expect(result.content).toEqual([{ type: "text", text: "Failed to duplicate page: Error: Create failed" }]);
  });
});

describe("coda_rename_page", () => {
  it("should rename page successfully", async () => {
    vi.mocked(sdk.updatePage).mockResolvedValue({
      data: {
        id: "page-456",
        requestId: "req-128",
      },
    } as any);

    const client = await connect(mcpServer.server);
    const result = await client.callTool("coda_rename_page", {
      docId: "doc-123",
      pageIdOrName: "page-456",
      newName: "Renamed Page",
    });
    expect(result.content).toEqual([
      {
        type: "text",
        text: JSON.stringify({
          id: "page-456",
          requestId: "req-128",
        }),
      },
    ]);
    expect(sdk.updatePage).toHaveBeenCalledWith({
      path: { docId: "doc-123", pageIdOrName: "page-456" },
      body: {
        name: "Renamed Page",
      },
      throwOnError: true,
    });
  });

  it("should show error if rename page throws", async () => {
    vi.mocked(sdk.updatePage).mockRejectedValue(new Error("Rename failed"));

    const client = await connect(mcpServer.server);
    const result = await client.callTool("coda_rename_page", {
      docId: "doc-123",
      pageIdOrName: "page-456",
      newName: "Renamed Page",
    });
    expect(result.content).toEqual([{ type: "text", text: "Failed to rename page: Error: Rename failed" }]);
  });
});

describe("coda_resolve_link", () => {
  it("should resolve browser link successfully", async () => {
    vi.mocked(sdk.resolveBrowserLink).mockResolvedValue({
      data: {
        resource: {
          id: "doc-123",
          type: "doc",
          name: "Test Document",
          href: "https://coda.io/d/doc-123",
        },
        browserLink: "https://coda.io/d/doc-123/Test-Page_ptest123",
      },
    } as any);

    const client = await connect(mcpServer.server);
    const result = await client.callTool("coda_resolve_link", {
      url: "https://coda.io/d/doc-123/Test-Page_ptest123",
    });
    expect(result.content).toEqual([
      {
        type: "text",
        text: JSON.stringify({
          resource: {
            id: "doc-123",
            type: "doc",
            name: "Test Document",
            href: "https://coda.io/d/doc-123",
          },
          browserLink: "https://coda.io/d/doc-123/Test-Page_ptest123",
        }),
      },
    ]);
    expect(sdk.resolveBrowserLink).toHaveBeenCalledWith({
      query: { url: "https://coda.io/d/doc-123/Test-Page_ptest123" },
      throwOnError: true,
    });
  });

  it("should resolve page link successfully", async () => {
    vi.mocked(sdk.resolveBrowserLink).mockResolvedValue({
      data: {
        resource: {
          id: "page-456",
          type: "page",
          name: "Test Page",
          href: "https://coda.io/d/doc-123/Test-Page_ptest456",
        },
        browserLink: "https://coda.io/d/doc-123/Test-Page_ptest456",
      },
    } as any);

    const client = await connect(mcpServer.server);
    const result = await client.callTool("coda_resolve_link", {
      url: "https://coda.io/d/doc-123/Test-Page_ptest456",
    });
    expect(result.content).toEqual([
      {
        type: "text",
        text: JSON.stringify({
          resource: {
            id: "page-456",
            type: "page",
            name: "Test Page",
            href: "https://coda.io/d/doc-123/Test-Page_ptest456",
          },
          browserLink: "https://coda.io/d/doc-123/Test-Page_ptest456",
        }),
      },
    ]);
    expect(sdk.resolveBrowserLink).toHaveBeenCalledWith({
      query: { url: "https://coda.io/d/doc-123/Test-Page_ptest456" },
      throwOnError: true,
    });
  });

  it("should resolve table link successfully", async () => {
    vi.mocked(sdk.resolveBrowserLink).mockResolvedValue({
      data: {
        resource: {
          id: "table-789",
          type: "table",
          name: "Test Table",
          href: "https://coda.io/d/doc-123/Test-Table_ttable789",
        },
        browserLink: "https://coda.io/d/doc-123/Test-Table_ttable789",
      },
    } as any);

    const client = await connect(mcpServer.server);
    const result = await client.callTool("coda_resolve_link", {
      url: "https://coda.io/d/doc-123/Test-Table_ttable789",
    });
    expect(result.content).toEqual([
      {
        type: "text",
        text: JSON.stringify({
          resource: {
            id: "table-789",
            type: "table",
            name: "Test Table",
            href: "https://coda.io/d/doc-123/Test-Table_ttable789",
          },
          browserLink: "https://coda.io/d/doc-123/Test-Table_ttable789",
        }),
      },
    ]);
  });

  it("should handle empty URL parameter", async () => {
    vi.mocked(sdk.resolveBrowserLink).mockResolvedValue({
      data: {
        resource: null,
        browserLink: "",
      },
    } as any);

    const client = await connect(mcpServer.server);
    const result = await client.callTool("coda_resolve_link", {
      url: "",
    });
    expect(result.content).toEqual([
      {
        type: "text",
        text: JSON.stringify({
          resource: null,
          browserLink: "",
        }),
      },
    ]);
    expect(sdk.resolveBrowserLink).toHaveBeenCalledWith({
      query: { url: "" },
      throwOnError: true,
    });
  });

  it("should show error if resolve link throws due to invalid URL", async () => {
    vi.mocked(sdk.resolveBrowserLink).mockRejectedValue(new Error("Invalid URL format"));

    const client = await connect(mcpServer.server);
    const result = await client.callTool("coda_resolve_link", {
      url: "not-a-valid-url",
    });
    expect(result.content).toEqual([{ type: "text", text: "Failed to resolve link: Error: Invalid URL format" }]);
    expect(result.isError).toBe(true);
  });

  it("should show error if resolve link throws due to access denied", async () => {
    vi.mocked(sdk.resolveBrowserLink).mockRejectedValue(new Error("Access denied"));

    const client = await connect(mcpServer.server);
    const result = await client.callTool("coda_resolve_link", {
      url: "https://coda.io/d/private-doc-123",
    });
    expect(result.content).toEqual([{ type: "text", text: "Failed to resolve link: Error: Access denied" }]);
    expect(result.isError).toBe(true);
  });

  it("should show error if resolve link throws due to not found", async () => {
    vi.mocked(sdk.resolveBrowserLink).mockRejectedValue(new Error("Resource not found"));

    const client = await connect(mcpServer.server);
    const result = await client.callTool("coda_resolve_link", {
      url: "https://coda.io/d/nonexistent-doc-456",
    });
    expect(result.content).toEqual([{ type: "text", text: "Failed to resolve link: Error: Resource not found" }]);
    expect(result.isError).toBe(true);
  });
});

```

--------------------------------------------------------------------------------
/src/client/sdk.gen.ts:
--------------------------------------------------------------------------------

```typescript
// This file is auto-generated by @hey-api/openapi-ts

import type { Options as ClientOptions, TDataShape, Client } from "@hey-api/client-axios";
import type {
  ListCategoriesData,
  ListCategoriesResponse,
  ListCategoriesError,
  ListDocsData,
  ListDocsResponse,
  ListDocsError,
  CreateDocData,
  CreateDocResponse,
  CreateDocError,
  DeleteDocData,
  DeleteDocResponse,
  DeleteDocError,
  GetDocData,
  GetDocResponse,
  GetDocError,
  UpdateDocData,
  UpdateDocResponse,
  UpdateDocError,
  GetSharingMetadataData,
  GetSharingMetadataResponse,
  GetSharingMetadataError,
  GetPermissionsData,
  GetPermissionsResponse,
  GetPermissionsError,
  AddPermissionData,
  AddPermissionResponse,
  AddPermissionError,
  DeletePermissionData,
  DeletePermissionResponse,
  DeletePermissionError,
  SearchPrincipalsData,
  SearchPrincipalsResponse2,
  SearchPrincipalsError,
  GetAclSettingsData,
  GetAclSettingsResponse,
  GetAclSettingsError,
  UpdateAclSettingsData,
  UpdateAclSettingsResponse,
  UpdateAclSettingsError,
  UnpublishDocData,
  UnpublishDocResponse,
  UnpublishDocError,
  PublishDocData,
  PublishDocResponse,
  PublishDocError,
  ListPagesData,
  ListPagesResponse,
  ListPagesError,
  CreatePageData,
  CreatePageResponse,
  CreatePageError,
  DeletePageData,
  DeletePageResponse,
  DeletePageError,
  GetPageData,
  GetPageResponse,
  GetPageError,
  UpdatePageData,
  UpdatePageResponse,
  UpdatePageError,
  BeginPageContentExportData,
  BeginPageContentExportResponse2,
  BeginPageContentExportError,
  GetPageContentExportStatusData,
  GetPageContentExportStatusResponse,
  GetPageContentExportStatusError,
  ListTablesData,
  ListTablesResponse,
  ListTablesError,
  GetTableData,
  GetTableResponse,
  GetTableError,
  ListColumnsData,
  ListColumnsResponse,
  ListColumnsError,
  DeleteRowsData,
  DeleteRowsResponse,
  DeleteRowsError,
  ListRowsData,
  ListRowsResponse,
  ListRowsError,
  UpsertRowsData,
  UpsertRowsResponse,
  UpsertRowsError,
  DeleteRowData,
  DeleteRowResponse,
  DeleteRowError,
  GetRowData,
  GetRowResponse,
  GetRowError,
  UpdateRowData,
  UpdateRowResponse,
  UpdateRowError,
  PushButtonData,
  PushButtonResponse,
  PushButtonError,
  GetColumnData,
  GetColumnResponse,
  GetColumnError,
  ListFormulasData,
  ListFormulasResponse,
  ListFormulasError,
  GetFormulaData,
  GetFormulaResponse,
  GetFormulaError,
  ListControlsData,
  ListControlsResponse,
  ListControlsError,
  GetControlData,
  GetControlResponse,
  GetControlError,
  ListCustomDocDomainsData,
  ListCustomDocDomainsResponse,
  ListCustomDocDomainsError,
  AddCustomDocDomainData,
  AddCustomDocDomainResponse2,
  AddCustomDocDomainError,
  DeleteCustomDocDomainData,
  DeleteCustomDocDomainResponse2,
  DeleteCustomDocDomainError,
  UpdateCustomDocDomainData,
  UpdateCustomDocDomainResponse2,
  UpdateCustomDocDomainError,
  GetCustomDocDomainProviderData,
  GetCustomDocDomainProviderResponse,
  GetCustomDocDomainProviderError,
  WhoamiData,
  WhoamiResponse,
  WhoamiError,
  ResolveBrowserLinkData,
  ResolveBrowserLinkResponse,
  ResolveBrowserLinkError,
  GetMutationStatusData,
  GetMutationStatusResponse,
  GetMutationStatusError,
  TriggerWebhookAutomationData,
  TriggerWebhookAutomationResponse,
  TriggerWebhookAutomationError,
  ListDocAnalyticsData,
  ListDocAnalyticsResponse,
  ListDocAnalyticsError,
  ListPageAnalyticsData,
  ListPageAnalyticsResponse,
  ListPageAnalyticsError,
  ListDocAnalyticsSummaryData,
  ListDocAnalyticsSummaryResponse,
  ListDocAnalyticsSummaryError,
  ListPackAnalyticsData,
  ListPackAnalyticsResponse,
  ListPackAnalyticsError,
  ListPackAnalyticsSummaryData,
  ListPackAnalyticsSummaryResponse,
  ListPackAnalyticsSummaryError,
  ListPackFormulaAnalyticsData,
  ListPackFormulaAnalyticsResponse,
  ListPackFormulaAnalyticsError,
  GetAnalyticsLastUpdatedData,
  GetAnalyticsLastUpdatedResponse,
  GetAnalyticsLastUpdatedError,
  ListWorkspaceMembersData,
  ListWorkspaceMembersResponse,
  ListWorkspaceMembersError,
  ChangeUserRoleData,
  ChangeUserRoleResponse,
  ChangeUserRoleError,
  ListWorkspaceRoleActivityData,
  ListWorkspaceRoleActivityResponse,
  ListWorkspaceRoleActivityError,
  ListPacksData,
  ListPacksResponse,
  ListPacksError,
  CreatePackData,
  CreatePackResponse2,
  CreatePackError,
  DeletePackData,
  DeletePackResponse2,
  DeletePackError,
  GetPackData,
  GetPackResponse,
  GetPackError,
  UpdatePackData,
  UpdatePackResponse,
  UpdatePackError,
  GetPackConfigurationSchemaData,
  GetPackConfigurationSchemaResponse,
  GetPackConfigurationSchemaError,
  ListPackVersionsData,
  ListPackVersionsResponse,
  ListPackVersionsError,
  GetNextPackVersionData,
  GetNextPackVersionResponse,
  GetNextPackVersionError,
  GetPackVersionDiffsData,
  GetPackVersionDiffsResponse,
  GetPackVersionDiffsError,
  RegisterPackVersionData,
  RegisterPackVersionResponse,
  RegisterPackVersionError,
  PackVersionUploadCompleteData,
  PackVersionUploadCompleteResponse,
  PackVersionUploadCompleteError,
  ListPackReleasesData,
  ListPackReleasesResponse,
  ListPackReleasesError,
  CreatePackReleaseData,
  CreatePackReleaseResponse,
  CreatePackReleaseError,
  UpdatePackReleaseData,
  UpdatePackReleaseResponse,
  UpdatePackReleaseError,
  GetPackOauthConfigData,
  GetPackOauthConfigResponse,
  GetPackOauthConfigError,
  SetPackOauthConfigData,
  SetPackOauthConfigResponse,
  SetPackOauthConfigError,
  GetPackSystemConnectionData,
  GetPackSystemConnectionResponse,
  GetPackSystemConnectionError,
  PatchPackSystemConnectionData,
  PatchPackSystemConnectionResponse,
  PatchPackSystemConnectionError,
  SetPackSystemConnectionData,
  SetPackSystemConnectionResponse,
  SetPackSystemConnectionError,
  GetPackPermissionsData,
  GetPackPermissionsResponse,
  GetPackPermissionsError,
  AddPackPermissionData,
  AddPackPermissionResponse2,
  AddPackPermissionError,
  DeletePackPermissionData,
  DeletePackPermissionResponse2,
  DeletePackPermissionError,
  ListPackMakersData,
  ListPackMakersResponse2,
  ListPackMakersError,
  AddPackMakerData,
  AddPackMakerResponse2,
  AddPackMakerError,
  DeletePackMakerData,
  DeletePackMakerResponse2,
  DeletePackMakerError,
  ListPackCategoriesData,
  ListPackCategoriesResponse2,
  ListPackCategoriesError,
  AddPackCategoryData,
  AddPackCategoryResponse2,
  AddPackCategoryError,
  DeletePackCategoryData,
  DeletePackCategoryResponse2,
  DeletePackCategoryError,
  UploadPackAssetData,
  UploadPackAssetResponse,
  UploadPackAssetError,
  UploadPackSourceCodeData,
  UploadPackSourceCodeResponse,
  UploadPackSourceCodeError,
  PackAssetUploadCompleteData,
  PackAssetUploadCompleteResponse2,
  PackAssetUploadCompleteError,
  PackSourceCodeUploadCompleteData,
  PackSourceCodeUploadCompleteResponse2,
  PackSourceCodeUploadCompleteError,
  GetPackSourceCodeData,
  GetPackSourceCodeResponse,
  GetPackSourceCodeError,
  ListPackListingsData,
  ListPackListingsResponse,
  ListPackListingsError,
  GetPackListingData,
  GetPackListingResponse,
  GetPackListingError,
  ListPackLogsData,
  ListPackLogsResponse,
  ListPackLogsError,
  ListIngestionLogsData,
  ListIngestionLogsResponse,
  ListIngestionLogsError,
  ListGroupedPackLogsData,
  ListGroupedPackLogsResponse,
  ListGroupedPackLogsError,
  ListGroupedIngestionLogsData,
  ListGroupedIngestionLogsResponse,
  ListGroupedIngestionLogsError,
  ListIngestionExecutionsData,
  ListIngestionExecutionsResponse,
  ListIngestionExecutionsError,
  ListIngestionExecutionAttemptsData,
  ListIngestionExecutionAttemptsResponse,
  ListIngestionExecutionAttemptsError,
  GetPackLogDetailsData,
  GetPackLogDetailsResponse,
  GetPackLogDetailsError,
  ListPackFeaturedDocsData,
  ListPackFeaturedDocsResponse,
  ListPackFeaturedDocsError,
  UpdatePackFeaturedDocsData,
  UpdatePackFeaturedDocsResponse2,
  UpdatePackFeaturedDocsError,
  AddGoLinkData,
  AddGoLinkResponse,
  AddGoLinkError,
} from "./types.gen";
import { client as _heyApiClient } from "./client.gen";

export type Options<TData extends TDataShape = TDataShape, ThrowOnError extends boolean = boolean> = ClientOptions<
  TData,
  ThrowOnError
> & {
  /**
   * You can provide a client instance returned by `createClient()` instead of
   * individual options. This might be also useful if you want to implement a
   * custom client.
   */
  client?: Client;
  /**
   * You can pass arbitrary values through the `meta` object. This can be
   * used to access values that aren't defined as part of the SDK function.
   */
  meta?: Record<string, unknown>;
};

/**
 * Get doc categories
 * Gets all available doc categories.
 */
export const listCategories = <ThrowOnError extends boolean = false>(
  options?: Options<ListCategoriesData, ThrowOnError>,
) => {
  return (options?.client ?? _heyApiClient).get<ListCategoriesResponse, ListCategoriesError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/categories",
    ...options,
  });
};

/**
 * List available docs
 * Returns a list of Coda docs accessible by the user, and which they have opened at least once. These are returned in the same order as on the docs page: reverse chronological by the latest event relevant to the user (last viewed, edited, or shared).
 *
 */
export const listDocs = <ThrowOnError extends boolean = false>(options?: Options<ListDocsData, ThrowOnError>) => {
  return (options?.client ?? _heyApiClient).get<ListDocsResponse, ListDocsError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/docs",
    ...options,
  });
};

/**
 * Create doc
 * Creates a new Coda doc, optionally copying an existing doc. Note that creating a doc requires you to be a Doc Maker in the applicable workspace (or be auto-promoted to one).
 *
 */
export const createDoc = <ThrowOnError extends boolean = false>(options: Options<CreateDocData, ThrowOnError>) => {
  return (options.client ?? _heyApiClient).post<CreateDocResponse, CreateDocError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/docs",
    ...options,
    headers: {
      "Content-Type": "application/json",
      ...options?.headers,
    },
  });
};

/**
 * Delete doc
 * Deletes a doc.
 */
export const deleteDoc = <ThrowOnError extends boolean = false>(options: Options<DeleteDocData, ThrowOnError>) => {
  return (options.client ?? _heyApiClient).delete<DeleteDocResponse, DeleteDocError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/docs/{docId}",
    ...options,
  });
};

/**
 * Get info about a doc
 * Returns metadata for the specified doc.
 */
export const getDoc = <ThrowOnError extends boolean = false>(options: Options<GetDocData, ThrowOnError>) => {
  return (options.client ?? _heyApiClient).get<GetDocResponse, GetDocError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/docs/{docId}",
    ...options,
  });
};

/**
 * Update doc
 * Updates metadata for a doc. Note that updating a doc title requires you to be a Doc Maker in the applicable workspace.
 */
export const updateDoc = <ThrowOnError extends boolean = false>(options: Options<UpdateDocData, ThrowOnError>) => {
  return (options.client ?? _heyApiClient).patch<UpdateDocResponse, UpdateDocError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/docs/{docId}",
    ...options,
    headers: {
      "Content-Type": "application/json",
      ...options?.headers,
    },
  });
};

/**
 * Get sharing metadata
 * Returns metadata associated with sharing for this Coda doc.
 */
export const getSharingMetadata = <ThrowOnError extends boolean = false>(
  options: Options<GetSharingMetadataData, ThrowOnError>,
) => {
  return (options.client ?? _heyApiClient).get<GetSharingMetadataResponse, GetSharingMetadataError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/docs/{docId}/acl/metadata",
    ...options,
  });
};

/**
 * List permissions
 * Returns a list of permissions for this Coda doc.
 */
export const getPermissions = <ThrowOnError extends boolean = false>(
  options: Options<GetPermissionsData, ThrowOnError>,
) => {
  return (options.client ?? _heyApiClient).get<GetPermissionsResponse, GetPermissionsError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/docs/{docId}/acl/permissions",
    ...options,
  });
};

/**
 * Add permission
 * Adds a new permission to the doc.
 *
 */
export const addPermission = <ThrowOnError extends boolean = false>(
  options: Options<AddPermissionData, ThrowOnError>,
) => {
  return (options.client ?? _heyApiClient).post<AddPermissionResponse, AddPermissionError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/docs/{docId}/acl/permissions",
    ...options,
    headers: {
      "Content-Type": "application/json",
      ...options?.headers,
    },
  });
};

/**
 * Delete permission
 * Deletes an existing permission.
 *
 */
export const deletePermission = <ThrowOnError extends boolean = false>(
  options: Options<DeletePermissionData, ThrowOnError>,
) => {
  return (options.client ?? _heyApiClient).delete<DeletePermissionResponse, DeletePermissionError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/docs/{docId}/acl/permissions/{permissionId}",
    ...options,
  });
};

/**
 * Search principals
 * Searches for user and group principals matching the query that this doc can be shared with.
 * At most 20 results will be returned for both users and groups. If no query is given then no results are returned.
 *
 */
export const searchPrincipals = <ThrowOnError extends boolean = false>(
  options: Options<SearchPrincipalsData, ThrowOnError>,
) => {
  return (options.client ?? _heyApiClient).get<SearchPrincipalsResponse2, SearchPrincipalsError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/docs/{docId}/acl/principals/search",
    ...options,
  });
};

/**
 * Get ACL settings
 * Returns settings associated with ACLs for this Coda doc.
 */
export const getAclSettings = <ThrowOnError extends boolean = false>(
  options: Options<GetAclSettingsData, ThrowOnError>,
) => {
  return (options.client ?? _heyApiClient).get<GetAclSettingsResponse, GetAclSettingsError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/docs/{docId}/acl/settings",
    ...options,
  });
};

/**
 * Update ACL settings
 * Update settings associated with ACLs for this Coda doc.
 */
export const updateAclSettings = <ThrowOnError extends boolean = false>(
  options: Options<UpdateAclSettingsData, ThrowOnError>,
) => {
  return (options.client ?? _heyApiClient).patch<UpdateAclSettingsResponse, UpdateAclSettingsError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/docs/{docId}/acl/settings",
    ...options,
    headers: {
      "Content-Type": "application/json",
      ...options?.headers,
    },
  });
};

/**
 * Unpublish doc
 * Unpublishes a doc.
 */
export const unpublishDoc = <ThrowOnError extends boolean = false>(
  options: Options<UnpublishDocData, ThrowOnError>,
) => {
  return (options.client ?? _heyApiClient).delete<UnpublishDocResponse, UnpublishDocError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/docs/{docId}/publish",
    ...options,
  });
};

/**
 * Publish doc
 * Update publish settings for a doc.
 */
export const publishDoc = <ThrowOnError extends boolean = false>(options: Options<PublishDocData, ThrowOnError>) => {
  return (options.client ?? _heyApiClient).put<PublishDocResponse, PublishDocError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/docs/{docId}/publish",
    ...options,
    headers: {
      "Content-Type": "application/json",
      ...options?.headers,
    },
  });
};

/**
 * List pages
 * Returns a list of pages in a Coda doc.
 */
export const listPages = <ThrowOnError extends boolean = false>(options: Options<ListPagesData, ThrowOnError>) => {
  return (options.client ?? _heyApiClient).get<ListPagesResponse, ListPagesError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/docs/{docId}/pages",
    ...options,
  });
};

/**
 * Create a page
 * Create a new page in a doc. Note that creating a page requires you to be a Doc Maker in the applicable workspace.
 *
 */
export const createPage = <ThrowOnError extends boolean = false>(options: Options<CreatePageData, ThrowOnError>) => {
  return (options.client ?? _heyApiClient).post<CreatePageResponse, CreatePageError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/docs/{docId}/pages",
    ...options,
    headers: {
      "Content-Type": "application/json",
      ...options?.headers,
    },
  });
};

/**
 * Delete a page
 * Deletes the specified page.
 */
export const deletePage = <ThrowOnError extends boolean = false>(options: Options<DeletePageData, ThrowOnError>) => {
  return (options.client ?? _heyApiClient).delete<DeletePageResponse, DeletePageError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/docs/{docId}/pages/{pageIdOrName}",
    ...options,
  });
};

/**
 * Get a page
 * Returns details about a page.
 */
export const getPage = <ThrowOnError extends boolean = false>(options: Options<GetPageData, ThrowOnError>) => {
  return (options.client ?? _heyApiClient).get<GetPageResponse, GetPageError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/docs/{docId}/pages/{pageIdOrName}",
    ...options,
  });
};

/**
 * Update a page
 * Update properties for a page. Note that updating a page title or icon requires you to be a Doc Maker in the applicable workspace.
 *
 */
export const updatePage = <ThrowOnError extends boolean = false>(options: Options<UpdatePageData, ThrowOnError>) => {
  return (options.client ?? _heyApiClient).put<UpdatePageResponse, UpdatePageError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/docs/{docId}/pages/{pageIdOrName}",
    ...options,
    headers: {
      "Content-Type": "application/json",
      ...options?.headers,
    },
  });
};

/**
 * Begin content export
 * Initiate an export of content for the given page.
 */
export const beginPageContentExport = <ThrowOnError extends boolean = false>(
  options: Options<BeginPageContentExportData, ThrowOnError>,
) => {
  return (options.client ?? _heyApiClient).post<
    BeginPageContentExportResponse2,
    BeginPageContentExportError,
    ThrowOnError
  >({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/docs/{docId}/pages/{pageIdOrName}/export",
    ...options,
    headers: {
      "Content-Type": "application/json",
      ...options?.headers,
    },
  });
};

/**
 * Content export status
 * Check the status of a page content export
 */
export const getPageContentExportStatus = <ThrowOnError extends boolean = false>(
  options: Options<GetPageContentExportStatusData, ThrowOnError>,
) => {
  return (options.client ?? _heyApiClient).get<
    GetPageContentExportStatusResponse,
    GetPageContentExportStatusError,
    ThrowOnError
  >({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/docs/{docId}/pages/{pageIdOrName}/export/{requestId}",
    ...options,
  });
};

/**
 * List tables
 * Returns a list of tables in a Coda doc.
 */
export const listTables = <ThrowOnError extends boolean = false>(options: Options<ListTablesData, ThrowOnError>) => {
  return (options.client ?? _heyApiClient).get<ListTablesResponse, ListTablesError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    querySerializer: {
      array: {
        explode: false,
        style: "form",
      },
    },
    url: "/docs/{docId}/tables",
    ...options,
  });
};

/**
 * Get a table
 * Returns details about a specific table or view.
 */
export const getTable = <ThrowOnError extends boolean = false>(options: Options<GetTableData, ThrowOnError>) => {
  return (options.client ?? _heyApiClient).get<GetTableResponse, GetTableError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/docs/{docId}/tables/{tableIdOrName}",
    ...options,
  });
};

/**
 * List columns
 * Returns a list of columns in a table.
 */
export const listColumns = <ThrowOnError extends boolean = false>(options: Options<ListColumnsData, ThrowOnError>) => {
  return (options.client ?? _heyApiClient).get<ListColumnsResponse, ListColumnsError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/docs/{docId}/tables/{tableIdOrName}/columns",
    ...options,
  });
};

/**
 * Delete multiple rows
 * Deletes the specified rows from the table or view. This endpoint will always return a 202. Row deletions are generally processed within several seconds.
 *
 */
export const deleteRows = <ThrowOnError extends boolean = false>(options: Options<DeleteRowsData, ThrowOnError>) => {
  return (options.client ?? _heyApiClient).delete<DeleteRowsResponse, DeleteRowsError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/docs/{docId}/tables/{tableIdOrName}/rows",
    ...options,
    headers: {
      "Content-Type": "application/json",
      ...options?.headers,
    },
  });
};

/**
 * List table rows
 * Returns a list of rows in a table.
 * ### Value results
 * The `valueFormat` parameter dictates in what format the API should return values for individual cells.
 * * `simple` (default): Returns cell values as the following JSON values: `string`, `number`, or `boolean`. Array values (like multiselects) are returned as comma-delimited strings.
 * * `simpleWithArrays`: Singleton values are returned as `simple`. Array values are returned as JSON arrays and the values within are `simple` values (including nested arrays).
 * * `rich`: If applicable, returns many values with further encoding, allowing API users to have lossless access to data in Coda.
 * * For `text` values, returns data in Markdown syntax. If the text field is simple text (e.g. has no formatting),
 * the field will be fully escaped with triple-ticks. E.g
 * `
 * ```This is plain text```
 * `
 * * For `currency`, `lookup`, `image`, `person` and `hyperlink` values, the value will be encoded in [JSON-LD](https://json-ld.org/) format.
 *
 * ```
 * // Currency
 * {
 * "@context": "http://schema.org",
 * "@type": "MonetaryAmount",
 * "currency": "USD",
 * "amount": 42.42
 * }
 *
 * // Lookup
 * {
 * "@context": "http://schema.org",
 * "@type": "StructuredValue",
 * "additionalType": "row",
 * "name": "Row Name",
 * "rowId": "i-123456789",
 * "tableId": "grid-123456789",
 * "tableUrl": "https://coda.io/d/_d123456789/grid-123456789",
 * "url": "https://coda.io/d/_d123456789/grid-123456789#_r42",
 * }
 *
 * // Hyperlink
 * {
 * "@context": "http://schema.org",
 * "@type": "WebPage",
 * "name": "Coda",
 * "url": "https://coda.io"
 * }
 *
 * // Image
 * {
 * "@context": "http://schema.org",
 * "@type": "ImageObject",
 * "name": "Coda logo",
 * "url": "https://coda.io/logo.jpg"
 * }
 *
 * // People
 * {
 * "@context": "http://schema.org",
 * "@type": "Person",
 * "name": "Art Vandalay",
 * "email": "[email protected]"
 * }
 * ```
 *
 */
export const listRows = <ThrowOnError extends boolean = false>(options: Options<ListRowsData, ThrowOnError>) => {
  return (options.client ?? _heyApiClient).get<ListRowsResponse, ListRowsError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/docs/{docId}/tables/{tableIdOrName}/rows",
    ...options,
  });
};

/**
 * Insert/upsert rows
 * Inserts rows into a table, optionally updating existing rows if any upsert key columns are provided. This endpoint will always return a 202, so long as the doc and table exist and are accessible (and the update is structurally valid). Row inserts/upserts are generally processed within several seconds. Note: this endpoint only works for base tables, not views.
 * When upserting, if multiple rows match the specified key column(s), they will all be updated with the specified value.
 *
 */
export const upsertRows = <ThrowOnError extends boolean = false>(options: Options<UpsertRowsData, ThrowOnError>) => {
  return (options.client ?? _heyApiClient).post<UpsertRowsResponse, UpsertRowsError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/docs/{docId}/tables/{tableIdOrName}/rows",
    ...options,
    headers: {
      "Content-Type": "application/json",
      ...options?.headers,
    },
  });
};

/**
 * Delete row
 * Deletes the specified row from the table or view. This endpoint will always return a 202, so long as the row exists and is accessible (and the update is structurally valid). Row deletions are generally processed within several seconds. When deleting using a name as opposed to an ID, an arbitrary row will be removed.
 *
 */
export const deleteRow = <ThrowOnError extends boolean = false>(options: Options<DeleteRowData, ThrowOnError>) => {
  return (options.client ?? _heyApiClient).delete<DeleteRowResponse, DeleteRowError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/docs/{docId}/tables/{tableIdOrName}/rows/{rowIdOrName}",
    ...options,
  });
};

/**
 * Get a row
 * Returns details about a row in a table.
 */
export const getRow = <ThrowOnError extends boolean = false>(options: Options<GetRowData, ThrowOnError>) => {
  return (options.client ?? _heyApiClient).get<GetRowResponse, GetRowError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/docs/{docId}/tables/{tableIdOrName}/rows/{rowIdOrName}",
    ...options,
  });
};

/**
 * Update row
 * Updates the specified row in the table. This endpoint will always return a 202, so long as the row exists and is accessible (and the update is structurally valid). Row updates are generally processed within several seconds. When updating using a name as opposed to an ID, an arbitrary row will be affected.
 *
 */
export const updateRow = <ThrowOnError extends boolean = false>(options: Options<UpdateRowData, ThrowOnError>) => {
  return (options.client ?? _heyApiClient).put<UpdateRowResponse, UpdateRowError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/docs/{docId}/tables/{tableIdOrName}/rows/{rowIdOrName}",
    ...options,
    headers: {
      "Content-Type": "application/json",
      ...options?.headers,
    },
  });
};

/**
 * Push a button
 * Pushes a button on a row in a table.
 * Authorization note: This action is available to API tokens that are authorized to write to the table. However, the underlying button can perform any action on the document, including writing to other tables and performing Pack actions.
 *
 */
export const pushButton = <ThrowOnError extends boolean = false>(options: Options<PushButtonData, ThrowOnError>) => {
  return (options.client ?? _heyApiClient).post<PushButtonResponse, PushButtonError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/docs/{docId}/tables/{tableIdOrName}/rows/{rowIdOrName}/buttons/{columnIdOrName}",
    ...options,
  });
};

/**
 * Get a column
 * Returns details about a column in a table.
 */
export const getColumn = <ThrowOnError extends boolean = false>(options: Options<GetColumnData, ThrowOnError>) => {
  return (options.client ?? _heyApiClient).get<GetColumnResponse, GetColumnError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/docs/{docId}/tables/{tableIdOrName}/columns/{columnIdOrName}",
    ...options,
  });
};

/**
 * List formulas
 * Returns a list of named formulas in a Coda doc.
 */
export const listFormulas = <ThrowOnError extends boolean = false>(
  options: Options<ListFormulasData, ThrowOnError>,
) => {
  return (options.client ?? _heyApiClient).get<ListFormulasResponse, ListFormulasError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/docs/{docId}/formulas",
    ...options,
  });
};

/**
 * Get a formula
 * Returns info on a formula.
 */
export const getFormula = <ThrowOnError extends boolean = false>(options: Options<GetFormulaData, ThrowOnError>) => {
  return (options.client ?? _heyApiClient).get<GetFormulaResponse, GetFormulaError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/docs/{docId}/formulas/{formulaIdOrName}",
    ...options,
  });
};

/**
 * List controls
 * Returns a list of controls in a Coda doc.
 */
export const listControls = <ThrowOnError extends boolean = false>(
  options: Options<ListControlsData, ThrowOnError>,
) => {
  return (options.client ?? _heyApiClient).get<ListControlsResponse, ListControlsError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/docs/{docId}/controls",
    ...options,
  });
};

/**
 * Get a control
 * Returns info on a control.
 */
export const getControl = <ThrowOnError extends boolean = false>(options: Options<GetControlData, ThrowOnError>) => {
  return (options.client ?? _heyApiClient).get<GetControlResponse, GetControlError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/docs/{docId}/controls/{controlIdOrName}",
    ...options,
  });
};

/**
 * List custom doc domains
 * List all custom domains for a published doc.
 */
export const listCustomDocDomains = <ThrowOnError extends boolean = false>(
  options: Options<ListCustomDocDomainsData, ThrowOnError>,
) => {
  return (options.client ?? _heyApiClient).get<ListCustomDocDomainsResponse, ListCustomDocDomainsError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/docs/${docId}/domains",
    ...options,
  });
};

/**
 * Add custom domain
 * Add a custom domain to a published doc.
 */
export const addCustomDocDomain = <ThrowOnError extends boolean = false>(
  options: Options<AddCustomDocDomainData, ThrowOnError>,
) => {
  return (options.client ?? _heyApiClient).post<AddCustomDocDomainResponse2, AddCustomDocDomainError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/docs/${docId}/domains",
    ...options,
    headers: {
      "Content-Type": "application/json",
      ...options?.headers,
    },
  });
};

/**
 * Deletes a custom domain
 * Deletes a custom domain from a published doc.
 */
export const deleteCustomDocDomain = <ThrowOnError extends boolean = false>(
  options: Options<DeleteCustomDocDomainData, ThrowOnError>,
) => {
  return (options.client ?? _heyApiClient).delete<
    DeleteCustomDocDomainResponse2,
    DeleteCustomDocDomainError,
    ThrowOnError
  >({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/docs/{docId}/domains/{customDocDomain}",
    ...options,
  });
};

/**
 * Updates a custom domain
 * Updates properties of a document's custom domain.
 */
export const updateCustomDocDomain = <ThrowOnError extends boolean = false>(
  options: Options<UpdateCustomDocDomainData, ThrowOnError>,
) => {
  return (options.client ?? _heyApiClient).patch<
    UpdateCustomDocDomainResponse2,
    UpdateCustomDocDomainError,
    ThrowOnError
  >({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/docs/{docId}/domains/{customDocDomain}",
    ...options,
    headers: {
      "Content-Type": "application/json",
      ...options?.headers,
    },
  });
};

/**
 * Gets custom doc domains providers
 * Gets the provider (ie. GoDaddy) of a custom domain.
 */
export const getCustomDocDomainProvider = <ThrowOnError extends boolean = false>(
  options: Options<GetCustomDocDomainProviderData, ThrowOnError>,
) => {
  return (options.client ?? _heyApiClient).get<
    GetCustomDocDomainProviderResponse,
    GetCustomDocDomainProviderError,
    ThrowOnError
  >({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/domains/provider/{customDocDomain}",
    ...options,
  });
};

/**
 * Get user info
 * Returns basic info about the current user.
 */
export const whoami = <ThrowOnError extends boolean = false>(options?: Options<WhoamiData, ThrowOnError>) => {
  return (options?.client ?? _heyApiClient).get<WhoamiResponse, WhoamiError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/whoami",
    ...options,
  });
};

/**
 * Resolve browser link
 * Given a browser link to a Coda object, attempts to find it and return metadata that can be used to get more info on it. Returns a 400 if the URL does not appear to be a Coda URL or a 404 if the resource cannot be located with the current credentials.
 *
 */
export const resolveBrowserLink = <ThrowOnError extends boolean = false>(
  options: Options<ResolveBrowserLinkData, ThrowOnError>,
) => {
  return (options.client ?? _heyApiClient).get<ResolveBrowserLinkResponse, ResolveBrowserLinkError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/resolveBrowserLink",
    ...options,
  });
};

/**
 * Get mutation status
 * Get the status for an asynchronous mutation to know whether or not it has been completed. Each API endpoint that mutates a document will return a request id that you can pass to this endpoint to check the completion status. Status information is not guaranteed to be available for more than one day after the mutation was completed. It is intended to be used shortly after the request was made.
 *
 */
export const getMutationStatus = <ThrowOnError extends boolean = false>(
  options: Options<GetMutationStatusData, ThrowOnError>,
) => {
  return (options.client ?? _heyApiClient).get<GetMutationStatusResponse, GetMutationStatusError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/mutationStatus/{requestId}",
    ...options,
  });
};

/**
 * Trigger automation
 * Triggers webhook-invoked automation
 */
export const triggerWebhookAutomation = <ThrowOnError extends boolean = false>(
  options: Options<TriggerWebhookAutomationData, ThrowOnError>,
) => {
  return (options.client ?? _heyApiClient).post<
    TriggerWebhookAutomationResponse,
    TriggerWebhookAutomationError,
    ThrowOnError
  >({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/docs/{docId}/hooks/automation/{ruleId}",
    ...options,
    headers: {
      "Content-Type": "application/json",
      ...options?.headers,
    },
  });
};

/**
 * List doc analytics
 * Returns analytics data for available docs per day.
 *
 */
export const listDocAnalytics = <ThrowOnError extends boolean = false>(
  options?: Options<ListDocAnalyticsData, ThrowOnError>,
) => {
  return (options?.client ?? _heyApiClient).get<ListDocAnalyticsResponse, ListDocAnalyticsError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    querySerializer: {
      array: {
        explode: false,
        style: "form",
      },
    },
    url: "/analytics/docs",
    ...options,
  });
};

/**
 * List page analytics
 * Returns analytics data for a given doc within the day.
 * This method will return a 401 if the given doc is not in an Enterprise workspace.
 *
 */
export const listPageAnalytics = <ThrowOnError extends boolean = false>(
  options: Options<ListPageAnalyticsData, ThrowOnError>,
) => {
  return (options.client ?? _heyApiClient).get<ListPageAnalyticsResponse, ListPageAnalyticsError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/analytics/docs/{docId}/pages",
    ...options,
  });
};

/**
 * Get doc analytics summary
 * Returns summarized analytics data for available docs.
 *
 */
export const listDocAnalyticsSummary = <ThrowOnError extends boolean = false>(
  options?: Options<ListDocAnalyticsSummaryData, ThrowOnError>,
) => {
  return (options?.client ?? _heyApiClient).get<
    ListDocAnalyticsSummaryResponse,
    ListDocAnalyticsSummaryError,
    ThrowOnError
  >({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/analytics/docs/summary",
    ...options,
  });
};

/**
 * List Pack analytics
 * Returns analytics data for Packs the user can edit.
 *
 */
export const listPackAnalytics = <ThrowOnError extends boolean = false>(
  options?: Options<ListPackAnalyticsData, ThrowOnError>,
) => {
  return (options?.client ?? _heyApiClient).get<ListPackAnalyticsResponse, ListPackAnalyticsError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    querySerializer: {
      array: {
        explode: false,
        style: "form",
      },
    },
    url: "/analytics/packs",
    ...options,
  });
};

/**
 * Get Pack analytics summary
 * Returns summarized analytics data for Packs the user can edit.
 *
 */
export const listPackAnalyticsSummary = <ThrowOnError extends boolean = false>(
  options?: Options<ListPackAnalyticsSummaryData, ThrowOnError>,
) => {
  return (options?.client ?? _heyApiClient).get<
    ListPackAnalyticsSummaryResponse,
    ListPackAnalyticsSummaryError,
    ThrowOnError
  >({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    querySerializer: {
      array: {
        explode: false,
        style: "form",
      },
    },
    url: "/analytics/packs/summary",
    ...options,
  });
};

/**
 * List Pack formula analytics
 * Returns analytics data for Pack formulas.
 *
 */
export const listPackFormulaAnalytics = <ThrowOnError extends boolean = false>(
  options: Options<ListPackFormulaAnalyticsData, ThrowOnError>,
) => {
  return (options.client ?? _heyApiClient).get<
    ListPackFormulaAnalyticsResponse,
    ListPackFormulaAnalyticsError,
    ThrowOnError
  >({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    querySerializer: {
      array: {
        explode: false,
        style: "form",
      },
    },
    url: "/analytics/packs/{packId}/formulas",
    ...options,
  });
};

/**
 * Get analytics last updated day
 * Returns days based on Pacific Standard Time when analytics were last updated.
 *
 */
export const getAnalyticsLastUpdated = <ThrowOnError extends boolean = false>(
  options?: Options<GetAnalyticsLastUpdatedData, ThrowOnError>,
) => {
  return (options?.client ?? _heyApiClient).get<
    GetAnalyticsLastUpdatedResponse,
    GetAnalyticsLastUpdatedError,
    ThrowOnError
  >({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/analytics/updated",
    ...options,
  });
};

/**
 * List workspace users
 * Returns a list of members in the given workspace. This list will be ordered with the requesting user first and then ordered by role.
 *
 */
export const listWorkspaceMembers = <ThrowOnError extends boolean = false>(
  options: Options<ListWorkspaceMembersData, ThrowOnError>,
) => {
  return (options.client ?? _heyApiClient).get<ListWorkspaceMembersResponse, ListWorkspaceMembersError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    querySerializer: {
      array: {
        explode: false,
        style: "form",
      },
    },
    url: "/workspaces/{workspaceId}/users",
    ...options,
  });
};

/**
 * Updates user role
 * Updates the workspace user role of a user that matches the parameters. Only succeeds if the requesting user has admin permissions in the workspace.
 *
 */
export const changeUserRole = <ThrowOnError extends boolean = false>(
  options: Options<ChangeUserRoleData, ThrowOnError>,
) => {
  return (options.client ?? _heyApiClient).post<ChangeUserRoleResponse, ChangeUserRoleError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/workspaces/{workspaceId}/users/role",
    ...options,
    headers: {
      "Content-Type": "application/json",
      ...options?.headers,
    },
  });
};

/**
 * List workspace roles
 * Returns a list of the counts of users over time by role for the workspace.
 *
 */
export const listWorkspaceRoleActivity = <ThrowOnError extends boolean = false>(
  options: Options<ListWorkspaceRoleActivityData, ThrowOnError>,
) => {
  return (options.client ?? _heyApiClient).get<
    ListWorkspaceRoleActivityResponse,
    ListWorkspaceRoleActivityError,
    ThrowOnError
  >({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/workspaces/{workspaceId}/roles",
    ...options,
  });
};

/**
 * List Packs
 * Get the list of accessible Packs.
 *
 */
export const listPacks = <ThrowOnError extends boolean = false>(options?: Options<ListPacksData, ThrowOnError>) => {
  return (options?.client ?? _heyApiClient).get<ListPacksResponse, ListPacksError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    querySerializer: {
      array: {
        explode: false,
        style: "form",
      },
    },
    url: "/packs",
    ...options,
  });
};

/**
 * Create Pack
 * Creates a new Pack, essentially registering a new Pack ID. The contents of the Pack will be uploaded separately.
 *
 */
export const createPack = <ThrowOnError extends boolean = false>(options: Options<CreatePackData, ThrowOnError>) => {
  return (options.client ?? _heyApiClient).post<CreatePackResponse2, CreatePackError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/packs",
    ...options,
    headers: {
      "Content-Type": "application/json",
      ...options?.headers,
    },
  });
};

/**
 * Delete Pack
 * Delete a given Pack.
 *
 */
export const deletePack = <ThrowOnError extends boolean = false>(options: Options<DeletePackData, ThrowOnError>) => {
  return (options.client ?? _heyApiClient).delete<DeletePackResponse2, DeletePackError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/packs/{packId}",
    ...options,
  });
};

/**
 * Get a single Pack
 * Returns a single Pack.
 *
 */
export const getPack = <ThrowOnError extends boolean = false>(options: Options<GetPackData, ThrowOnError>) => {
  return (options.client ?? _heyApiClient).get<GetPackResponse, GetPackError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/packs/{packId}",
    ...options,
  });
};

/**
 * Update Pack
 * Update an existing Pack for non-versioned fields.
 *
 */
export const updatePack = <ThrowOnError extends boolean = false>(options: Options<UpdatePackData, ThrowOnError>) => {
  return (options.client ?? _heyApiClient).patch<UpdatePackResponse, UpdatePackError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/packs/{packId}",
    ...options,
    headers: {
      "Content-Type": "application/json",
      ...options?.headers,
    },
  });
};

/**
 * Gets the JSON Schema for Pack configuration.
 * Returns a JSON Schema applicable for customizing the pack using Pack configurations.
 *
 */
export const getPackConfigurationSchema = <ThrowOnError extends boolean = false>(
  options: Options<GetPackConfigurationSchemaData, ThrowOnError>,
) => {
  return (options.client ?? _heyApiClient).get<
    GetPackConfigurationSchemaResponse,
    GetPackConfigurationSchemaError,
    ThrowOnError
  >({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/packs/{packId}/configurations/schema",
    ...options,
  });
};

/**
 * List the versions for a Pack.
 * Get the list of versions of a Pack.
 *
 */
export const listPackVersions = <ThrowOnError extends boolean = false>(
  options: Options<ListPackVersionsData, ThrowOnError>,
) => {
  return (options.client ?? _heyApiClient).get<ListPackVersionsResponse, ListPackVersionsError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/packs/{packId}/versions",
    ...options,
  });
};

/**
 * Get the next valid version for a Pack.
 * Get the next valid version based on the proposed metadata.
 *
 */
export const getNextPackVersion = <ThrowOnError extends boolean = false>(
  options: Options<GetNextPackVersionData, ThrowOnError>,
) => {
  return (options.client ?? _heyApiClient).post<GetNextPackVersionResponse, GetNextPackVersionError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/packs/{packId}/nextVersion",
    ...options,
    headers: {
      "Content-Type": "application/json",
      ...options?.headers,
    },
  });
};

/**
 * Get the difference between two pack versions.
 * Gets information about the difference between the specified previous version and next version of a Pack.
 *
 */
export const getPackVersionDiffs = <ThrowOnError extends boolean = false>(
  options: Options<GetPackVersionDiffsData, ThrowOnError>,
) => {
  return (options.client ?? _heyApiClient).get<GetPackVersionDiffsResponse, GetPackVersionDiffsError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/packs/{packId}/versions/{basePackVersion}/diff/{targetPackVersion}",
    ...options,
  });
};

/**
 * Register Pack version
 * Registers a new Pack version. This simply returns a signed URL to use for uploading the Pack version definition. Following the completion of the upload, POST to /apis/v1/packs/{packId}/versions/{packVersion} trigger the rest of the creation process.
 *
 */
export const registerPackVersion = <ThrowOnError extends boolean = false>(
  options: Options<RegisterPackVersionData, ThrowOnError>,
) => {
  return (options.client ?? _heyApiClient).post<RegisterPackVersionResponse, RegisterPackVersionError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/packs/{packId}/versions/{packVersion}/register",
    ...options,
    headers: {
      "Content-Type": "application/json",
      ...options?.headers,
    },
  });
};

/**
 * Pack version upload complete
 * Note the completion of the upload of a Pack version bundle in order to create that Pack version.
 *
 */
export const packVersionUploadComplete = <ThrowOnError extends boolean = false>(
  options: Options<PackVersionUploadCompleteData, ThrowOnError>,
) => {
  return (options.client ?? _heyApiClient).post<
    PackVersionUploadCompleteResponse,
    PackVersionUploadCompleteError,
    ThrowOnError
  >({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/packs/{packId}/versions/{packVersion}/uploadComplete",
    ...options,
    headers: {
      "Content-Type": "application/json",
      ...options?.headers,
    },
  });
};

/**
 * List the releases for a Pack.
 * Get the list of releases of a Pack.
 *
 */
export const listPackReleases = <ThrowOnError extends boolean = false>(
  options: Options<ListPackReleasesData, ThrowOnError>,
) => {
  return (options.client ?? _heyApiClient).get<ListPackReleasesResponse, ListPackReleasesError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/packs/{packId}/releases",
    ...options,
  });
};

/**
 * Create a new Pack release.
 * Creates a new Pack release based on an existing Pack version.
 *
 */
export const createPackRelease = <ThrowOnError extends boolean = false>(
  options: Options<CreatePackReleaseData, ThrowOnError>,
) => {
  return (options.client ?? _heyApiClient).post<CreatePackReleaseResponse, CreatePackReleaseError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/packs/{packId}/releases",
    ...options,
    headers: {
      "Content-Type": "application/json",
      ...options?.headers,
    },
  });
};

/**
 * Update an existing Pack release.
 * Update details of a Pack release.
 *
 */
export const updatePackRelease = <ThrowOnError extends boolean = false>(
  options: Options<UpdatePackReleaseData, ThrowOnError>,
) => {
  return (options.client ?? _heyApiClient).put<UpdatePackReleaseResponse, UpdatePackReleaseError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/packs/{packId}/releases/{packReleaseId}",
    ...options,
    headers: {
      "Content-Type": "application/json",
      ...options?.headers,
    },
  });
};

/**
 * Retrieve the OAuth configuration of the Pack.
 * Retrieve the OAuth configuration of the Pack for display purpose. Secrets will be returned with masks.
 *
 */
export const getPackOauthConfig = <ThrowOnError extends boolean = false>(
  options: Options<GetPackOauthConfigData, ThrowOnError>,
) => {
  return (options.client ?? _heyApiClient).get<GetPackOauthConfigResponse, GetPackOauthConfigError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/packs/{packId}/oauthConfig",
    ...options,
  });
};

/**
 * Set the OAuth configurations of the Pack.
 * Set the OAuth configurations of the Pack, including client id and secret.
 *
 */
export const setPackOauthConfig = <ThrowOnError extends boolean = false>(
  options: Options<SetPackOauthConfigData, ThrowOnError>,
) => {
  return (options.client ?? _heyApiClient).put<SetPackOauthConfigResponse, SetPackOauthConfigError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/packs/{packId}/oauthConfig",
    ...options,
    headers: {
      "Content-Type": "application/json",
      ...options?.headers,
    },
  });
};

/**
 * Retrieve the system connection metadata of the Pack.
 * Retrieve the system connection metadata of the Pack.
 *
 */
export const getPackSystemConnection = <ThrowOnError extends boolean = false>(
  options: Options<GetPackSystemConnectionData, ThrowOnError>,
) => {
  return (options.client ?? _heyApiClient).get<
    GetPackSystemConnectionResponse,
    GetPackSystemConnectionError,
    ThrowOnError
  >({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/packs/{packId}/systemConnection",
    ...options,
  });
};

/**
 * Patch the system connection credentials of the Pack.
 * Patch the system connection credentials of the Pack.
 *
 */
export const patchPackSystemConnection = <ThrowOnError extends boolean = false>(
  options: Options<PatchPackSystemConnectionData, ThrowOnError>,
) => {
  return (options.client ?? _heyApiClient).patch<
    PatchPackSystemConnectionResponse,
    PatchPackSystemConnectionError,
    ThrowOnError
  >({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/packs/{packId}/systemConnection",
    ...options,
    headers: {
      "Content-Type": "application/json",
      ...options?.headers,
    },
  });
};

/**
 * Set the system connection credentials of the Pack.
 * Set the system connection credentials of the Pack.
 *
 */
export const setPackSystemConnection = <ThrowOnError extends boolean = false>(
  options: Options<SetPackSystemConnectionData, ThrowOnError>,
) => {
  return (options.client ?? _heyApiClient).put<
    SetPackSystemConnectionResponse,
    SetPackSystemConnectionError,
    ThrowOnError
  >({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/packs/{packId}/systemConnection",
    ...options,
    headers: {
      "Content-Type": "application/json",
      ...options?.headers,
    },
  });
};

/**
 * List permissions for a Pack
 * Get user, workspace, and/or global permissions for a given Pack.
 *
 */
export const getPackPermissions = <ThrowOnError extends boolean = false>(
  options: Options<GetPackPermissionsData, ThrowOnError>,
) => {
  return (options.client ?? _heyApiClient).get<GetPackPermissionsResponse, GetPackPermissionsError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/packs/{packId}/permissions",
    ...options,
  });
};

/**
 * Add a permission for Pack
 * Create or modify user, workspace, or global permissions for a given Pack.
 *
 */
export const addPackPermission = <ThrowOnError extends boolean = false>(
  options: Options<AddPackPermissionData, ThrowOnError>,
) => {
  return (options.client ?? _heyApiClient).post<AddPackPermissionResponse2, AddPackPermissionError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/packs/{packId}/permissions",
    ...options,
    headers: {
      "Content-Type": "application/json",
      ...options?.headers,
    },
  });
};

/**
 * Delete a permission for Pack
 * Delete user, workspace, or global permissions for a given Pack.
 *
 */
export const deletePackPermission = <ThrowOnError extends boolean = false>(
  options: Options<DeletePackPermissionData, ThrowOnError>,
) => {
  return (options.client ?? _heyApiClient).delete<
    DeletePackPermissionResponse2,
    DeletePackPermissionError,
    ThrowOnError
  >({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/packs/{packId}/permissions/{permissionId}",
    ...options,
  });
};

/**
 * List makers for Pack
 * List makers for a given pack.
 *
 */
export const listPackMakers = <ThrowOnError extends boolean = false>(
  options: Options<ListPackMakersData, ThrowOnError>,
) => {
  return (options.client ?? _heyApiClient).get<ListPackMakersResponse2, ListPackMakersError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/packs/{packId}/makers",
    ...options,
  });
};

/**
 * Add a maker for Pack
 * Set a maker for a given Pack. Used to display makers for a pack in the corresponding packs page.
 *
 */
export const addPackMaker = <ThrowOnError extends boolean = false>(
  options: Options<AddPackMakerData, ThrowOnError>,
) => {
  return (options.client ?? _heyApiClient).post<AddPackMakerResponse2, AddPackMakerError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/packs/{packId}/maker",
    ...options,
    headers: {
      "Content-Type": "application/json",
      ...options?.headers,
    },
  });
};

/**
 * Delete a maker for Pack
 * Delete a maker for a given Pack, who will not be displayed in the corresponding packs page.
 *
 */
export const deletePackMaker = <ThrowOnError extends boolean = false>(
  options: Options<DeletePackMakerData, ThrowOnError>,
) => {
  return (options.client ?? _heyApiClient).delete<DeletePackMakerResponse2, DeletePackMakerError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/packs/{packId}/maker/{loginId}",
    ...options,
  });
};

/**
 * List categories for Pack
 * List publishing categories for a given pack.
 *
 */
export const listPackCategories = <ThrowOnError extends boolean = false>(
  options: Options<ListPackCategoriesData, ThrowOnError>,
) => {
  return (options.client ?? _heyApiClient).get<ListPackCategoriesResponse2, ListPackCategoriesError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/packs/{packId}/categories",
    ...options,
  });
};

/**
 * Add a category for Pack
 * Add a publishing category for a given pack.
 *
 */
export const addPackCategory = <ThrowOnError extends boolean = false>(
  options: Options<AddPackCategoryData, ThrowOnError>,
) => {
  return (options.client ?? _heyApiClient).post<AddPackCategoryResponse2, AddPackCategoryError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/packs/{packId}/category",
    ...options,
    headers: {
      "Content-Type": "application/json",
      ...options?.headers,
    },
  });
};

/**
 * Delete a category for Pack
 * Delete a publishing category for a given pack.
 *
 */
export const deletePackCategory = <ThrowOnError extends boolean = false>(
  options: Options<DeletePackCategoryData, ThrowOnError>,
) => {
  return (options.client ?? _heyApiClient).delete<DeletePackCategoryResponse2, DeletePackCategoryError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/packs/{packId}/category/{categoryName}",
    ...options,
  });
};

/**
 * Upload a Pack asset.
 * Request a signed s3 URL to upload your Pack asset.
 *
 */
export const uploadPackAsset = <ThrowOnError extends boolean = false>(
  options: Options<UploadPackAssetData, ThrowOnError>,
) => {
  return (options.client ?? _heyApiClient).post<UploadPackAssetResponse, UploadPackAssetError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/packs/{packId}/uploadAsset",
    ...options,
    headers: {
      "Content-Type": "application/json",
      ...options?.headers,
    },
  });
};

/**
 * Upload Pack source code.
 * Request a signed s3 URL to upload your Pack source code.
 *
 */
export const uploadPackSourceCode = <ThrowOnError extends boolean = false>(
  options: Options<UploadPackSourceCodeData, ThrowOnError>,
) => {
  return (options.client ?? _heyApiClient).post<UploadPackSourceCodeResponse, UploadPackSourceCodeError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/packs/{packId}/uploadSourceCode",
    ...options,
    headers: {
      "Content-Type": "application/json",
      ...options?.headers,
    },
  });
};

/**
 * Pack asset upload complete
 * Note the completion of the upload of a Pack asset.
 *
 */
export const packAssetUploadComplete = <ThrowOnError extends boolean = false>(
  options: Options<PackAssetUploadCompleteData, ThrowOnError>,
) => {
  return (options.client ?? _heyApiClient).post<
    PackAssetUploadCompleteResponse2,
    PackAssetUploadCompleteError,
    ThrowOnError
  >({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/packs/{packId}/assets/{packAssetId}/assetType/{packAssetType}/uploadComplete",
    ...options,
  });
};

/**
 * Pack source code upload complete
 * Note the completion of the upload of a Pack source code.
 *
 */
export const packSourceCodeUploadComplete = <ThrowOnError extends boolean = false>(
  options: Options<PackSourceCodeUploadCompleteData, ThrowOnError>,
) => {
  return (options.client ?? _heyApiClient).post<
    PackSourceCodeUploadCompleteResponse2,
    PackSourceCodeUploadCompleteError,
    ThrowOnError
  >({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/packs/{packId}/versions/{packVersion}/sourceCode/uploadComplete",
    ...options,
    headers: {
      "Content-Type": "application/json",
      ...options?.headers,
    },
  });
};

/**
 * get the source code for a Pack version.
 * Get temporary links used to download the source code for the given packId and version
 *
 */
export const getPackSourceCode = <ThrowOnError extends boolean = false>(
  options: Options<GetPackSourceCodeData, ThrowOnError>,
) => {
  return (options.client ?? _heyApiClient).get<GetPackSourceCodeResponse, GetPackSourceCodeError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/packs/{packId}/versions/{packVersion}/sourceCode",
    ...options,
  });
};

/**
 * List the Pack listings accessible to a user.
 * Get listings of public Packs and Packs created by you.
 *
 */
export const listPackListings = <ThrowOnError extends boolean = false>(
  options?: Options<ListPackListingsData, ThrowOnError>,
) => {
  return (options?.client ?? _heyApiClient).get<ListPackListingsResponse, ListPackListingsError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    querySerializer: {
      array: {
        explode: false,
        style: "form",
      },
    },
    url: "/packs/listings",
    ...options,
  });
};

/**
 * Get detailed listing information for a Pack.
 * Get detailed listing information for a Pack.
 *
 */
export const getPackListing = <ThrowOnError extends boolean = false>(
  options: Options<GetPackListingData, ThrowOnError>,
) => {
  return (options.client ?? _heyApiClient).get<GetPackListingResponse, GetPackListingError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/packs/{packId}/listing",
    ...options,
  });
};

/**
 * Retrieve the logs of a Pack.
 * Retrieve the logs of a Pack for debugging purpose.
 *
 */
export const listPackLogs = <ThrowOnError extends boolean = false>(
  options: Options<ListPackLogsData, ThrowOnError>,
) => {
  return (options.client ?? _heyApiClient).get<ListPackLogsResponse, ListPackLogsError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    querySerializer: {
      array: {
        explode: false,
        style: "form",
      },
    },
    url: "/packs/{packId}/docs/{docId}/logs",
    ...options,
  });
};

/**
 * Retrieve the logs of a Ingestion.
 * Retrieve the logs of a Ingestion for debugging purpose.
 */
export const listIngestionLogs = <ThrowOnError extends boolean = false>(
  options: Options<ListIngestionLogsData, ThrowOnError>,
) => {
  return (options.client ?? _heyApiClient).get<ListIngestionLogsResponse, ListIngestionLogsError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    querySerializer: {
      array: {
        explode: false,
        style: "form",
      },
    },
    url: "/packs/{packId}/organizationId/{organizationId}/rootIngestionId/{rootIngestionId}/logs",
    ...options,
  });
};

/**
 * Retrieve the grouped logs of a Pack.
 * Retrieve the grouped logs of a Pack for debugging purpose.
 *
 */
export const listGroupedPackLogs = <ThrowOnError extends boolean = false>(
  options: Options<ListGroupedPackLogsData, ThrowOnError>,
) => {
  return (options.client ?? _heyApiClient).get<ListGroupedPackLogsResponse, ListGroupedPackLogsError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/packs/{packId}/docs/{docId}/groupedLogs",
    ...options,
  });
};

/**
 * Retrieve the grouped logs of a Pack for a specific ingestionExecutionId.
 * Retrieve the grouped logs of a Pack for debugging purpose.
 *
 */
export const listGroupedIngestionLogs = <ThrowOnError extends boolean = false>(
  options: Options<ListGroupedIngestionLogsData, ThrowOnError>,
) => {
  return (options.client ?? _heyApiClient).get<
    ListGroupedIngestionLogsResponse,
    ListGroupedIngestionLogsError,
    ThrowOnError
  >({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/packs/{packId}/organizationId/{organizationId}/rootIngestionId/{rootIngestionId}/groupedLogs",
    ...options,
  });
};

/**
 * Retrieve a list of ingestion execution ids for the given root ingestion id.
 * Retrieve the ingestion execution ids of a root ingestion for debugging purpose.
 *
 */
export const listIngestionExecutions = <ThrowOnError extends boolean = false>(
  options: Options<ListIngestionExecutionsData, ThrowOnError>,
) => {
  return (options.client ?? _heyApiClient).get<
    ListIngestionExecutionsResponse,
    ListIngestionExecutionsError,
    ThrowOnError
  >({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/packs/{packId}/organizationId/{organizationId}/rootIngestionId/{rootIngestionId}/ingestionExecutions",
    ...options,
  });
};

/**
 * Retrieve a list of ingestion execution ids for the given root ingestion id.
 * Retrieve the ingestion execution ids of a root ingestion for debugging purpose.
 *
 */
export const listIngestionExecutionAttempts = <ThrowOnError extends boolean = false>(
  options: Options<ListIngestionExecutionAttemptsData, ThrowOnError>,
) => {
  return (options.client ?? _heyApiClient).get<
    ListIngestionExecutionAttemptsResponse,
    ListIngestionExecutionAttemptsError,
    ThrowOnError
  >({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/packs/{packId}/organizationId/{organizationId}/rootIngestionId/{rootIngestionId}/ingestionExecutionId/{ingestionExecutionId}/attempts",
    ...options,
  });
};

/**
 * Retrieve the information for a specific log.
 * Retrieve the ingestion execution ids of a root ingestion for debugging purpose.
 *
 */
export const getPackLogDetails = <ThrowOnError extends boolean = false>(
  options: Options<GetPackLogDetailsData, ThrowOnError>,
) => {
  return (options.client ?? _heyApiClient).get<GetPackLogDetailsResponse, GetPackLogDetailsError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/packs/{packId}/organizationId/{organizationId}/rootIngestionId/{rootIngestionId}/logs/{logId}",
    ...options,
  });
};

/**
 * List featured docs for a Pack
 * Returns a list of featured doc ids for a Pack.
 *
 */
export const listPackFeaturedDocs = <ThrowOnError extends boolean = false>(
  options: Options<ListPackFeaturedDocsData, ThrowOnError>,
) => {
  return (options.client ?? _heyApiClient).get<ListPackFeaturedDocsResponse, ListPackFeaturedDocsError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/packs/{packId}/featuredDocs",
    ...options,
  });
};

/**
 * Update featured docs for a Pack
 * Create or replace the featured docs for a Pack.
 *
 */
export const updatePackFeaturedDocs = <ThrowOnError extends boolean = false>(
  options: Options<UpdatePackFeaturedDocsData, ThrowOnError>,
) => {
  return (options.client ?? _heyApiClient).put<
    UpdatePackFeaturedDocsResponse2,
    UpdatePackFeaturedDocsError,
    ThrowOnError
  >({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/packs/{packId}/featuredDocs",
    ...options,
    headers: {
      "Content-Type": "application/json",
      ...options?.headers,
    },
  });
};

/**
 * Add a go link
 * Adds a new go link for the organization.
 */
export const addGoLink = <ThrowOnError extends boolean = false>(options: Options<AddGoLinkData, ThrowOnError>) => {
  return (options.client ?? _heyApiClient).post<AddGoLinkResponse, AddGoLinkError, ThrowOnError>({
    security: [
      {
        scheme: "bearer",
        type: "http",
      },
    ],
    url: "/organizations/{organizationId}/goLinks",
    ...options,
    headers: {
      "Content-Type": "application/json",
      ...options?.headers,
    },
  });
};

```
Page 1/2FirstPrevNextLast