diff --git a/.fern/metadata.json b/.fern/metadata.json new file mode 100644 index 0000000..59369b9 --- /dev/null +++ b/.fern/metadata.json @@ -0,0 +1,22 @@ +{ + "cliVersion": "5.91.0", + "generatorName": "fernapi/fern-typescript-sdk", + "generatorVersion": "3.87.2", + "generatorConfig": { + "packageJson": { + "name": "@cloudpdf/sdk", + "description": "The official TypeScript SDK for the CloudPDF API.", + "license": "Apache-2.0", + "repository": { + "type": "git", + "url": "git+https://github.com/embedpdf/cloudpdf-sdk-typescript.git" + } + } + }, + "originGitCommit": "232d5e0240d5673a73c9ea7c7ae9e7b937fdd5b3", + "originGitCommitIsDirty": false, + "invokedBy": "ci", + "requestedVersion": "3.0.0-next.1", + "ciProvider": "github", + "sdkVersion": "3.0.0-next.1" +} diff --git a/.fern/verify.sh b/.fern/verify.sh new file mode 100755 index 0000000..a224ac8 --- /dev/null +++ b/.fern/verify.sh @@ -0,0 +1,5 @@ +#!/bin/bash +set -euo pipefail +pnpm install +pnpm build +pnpm test diff --git a/.github/workflows/sdk-ci.yml b/.github/workflows/sdk-ci.yml new file mode 100644 index 0000000..d4f84ac --- /dev/null +++ b/.github/workflows/sdk-ci.yml @@ -0,0 +1,22 @@ +name: SDK CI + +on: + pull_request: + push: + branches: [main] + +permissions: + contents: read + +jobs: + build: + name: Build and validate + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: 22 + - run: corepack enable + - run: pnpm install --lockfile=false --ignore-scripts + - run: pnpm build diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..72271e0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +node_modules +.DS_Store +/dist \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..fe5bc2f --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,133 @@ +# Contributing + +Thanks for your interest in contributing to this SDK! This document provides guidelines for contributing to the project. + +## Getting Started + +### Prerequisites + +- Node.js 20 or higher +- pnpm package manager + +### Installation + +Install the project dependencies: + +```bash +pnpm install +``` + +### Building + +Build the project: + +```bash +pnpm build +``` + +### Testing + +Run the test suite: + +```bash +pnpm test +``` + +Run specific test types: +- `pnpm test:unit` - Run unit tests +- `pnpm test:wire` - Run wire/integration tests + +### Linting and Formatting + +Check code style: + +```bash +pnpm run lint +pnpm run format:check +``` + +Fix code style issues: + +```bash +pnpm run lint:fix +pnpm run format:fix +``` + +Or use the combined check command: + +```bash +pnpm run check:fix +``` + +## About Generated Code + +**Important**: Most files in this SDK are automatically generated by [Fern](https://buildwithfern.com) from the API definition. Direct modifications to generated files will be overwritten the next time the SDK is generated. + +### Generated Files + +The following directories contain generated code: +- `src/api/` - API client classes and types +- `src/serialization/` - Serialization/deserialization logic +- Most TypeScript files in `src/` + +### How to Customize + +If you need to customize the SDK, you have two options: + +#### Option 1: Use `.fernignore` + +For custom code that should persist across SDK regenerations: + +1. Create a `.fernignore` file in the project root +2. Add file patterns for files you want to preserve (similar to `.gitignore` syntax) +3. Add your custom code to those files + +Files listed in `.fernignore` will not be overwritten when the SDK is regenerated. + +For more information, see the [Fern documentation on custom code](https://buildwithfern.com/learn/sdks/overview/custom-code). + +#### Option 2: Contribute to the Generator + +If you want to change how code is generated for all users of this SDK: + +1. The TypeScript SDK generator lives in the [Fern repository](https://github.com/fern-api/fern) +2. Generator code is located at `generators/typescript/sdk/` +3. Follow the [Fern contributing guidelines](https://github.com/fern-api/fern/blob/main/CONTRIBUTING.md) +4. Submit a pull request with your changes to the generator + +This approach is best for: +- Bug fixes in generated code +- New features that would benefit all users +- Improvements to code generation patterns + +## Making Changes + +### Workflow + +1. Create a new branch for your changes +2. Make your modifications +3. Run tests to ensure nothing breaks: `pnpm test` +4. Run linting and formatting: `pnpm run check:fix` +5. Build the project: `pnpm build` +6. Commit your changes with a clear commit message +7. Push your branch and create a pull request + +### Commit Messages + +Write clear, descriptive commit messages that explain what changed and why. + +### Code Style + +This project uses automated code formatting and linting. Run `pnpm run check:fix` before committing to ensure your code meets the project's style guidelines. + +## Questions or Issues? + +If you have questions or run into issues: + +1. Check the [Fern documentation](https://buildwithfern.com) +2. Search existing [GitHub issues](https://github.com/fern-api/fern/issues) +3. Open a new issue if your question hasn't been addressed + +## License + +By contributing to this project, you agree that your contributions will be licensed under the same license as the project. diff --git a/LICENSE b/LICENSE index 261eeb9..2c656ef 100644 --- a/LICENSE +++ b/LICENSE @@ -1,3 +1,19 @@ +Copyright 2026 CloudPDF LTD + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use files in this distribution except in compliance with the License. +You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +----------------------------------------------------------------------- + Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ @@ -174,28 +190,3 @@ of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/README.md b/README.md index 0011583..817fc44 100644 --- a/README.md +++ b/README.md @@ -1 +1,733 @@ -# cloudpdf-sdk-typescript \ No newline at end of file +# Cloudpdf TypeScript Library + +[![fern shield](https://img.shields.io/badge/%F0%9F%8C%BF-Built%20with%20Fern-brightgreen)](https://buildwithfern.com?utm_source=github&utm_medium=github&utm_campaign=readme&utm_source=Cloudpdf%2FTypeScript) +[![npm shield](https://img.shields.io/npm/v/@cloudpdf/sdk)](https://www.npmjs.com/package/@cloudpdf/sdk) + +The Cloudpdf TypeScript library provides convenient access to the Cloudpdf APIs from TypeScript. + +## Table of Contents + +- [Installation](#installation) +- [Reference](#reference) +- [Usage](#usage) +- [Request and Response Types](#request-and-response-types) +- [Exception Handling](#exception-handling) +- [File Uploads](#file-uploads) +- [Binary Response](#binary-response) +- [Advanced](#advanced) + - [Subpackage Exports](#subpackage-exports) + - [Additional Headers](#additional-headers) + - [Additional Query String Parameters](#additional-query-string-parameters) + - [Retries](#retries) + - [Timeouts](#timeouts) + - [Aborting Requests](#aborting-requests) + - [Access Raw Response Data](#access-raw-response-data) + - [Logging](#logging) + - [Custom Fetch](#custom-fetch) + - [Runtime Compatibility](#runtime-compatibility) +- [Contributing](#contributing) + +## Installation + +```sh +npm i -s @cloudpdf/sdk +``` + +## Reference + +A full reference for this library is available [here](./reference.md). + +## Usage + +Instantiate and use the client with the following: + +```typescript +import { CloudpdfApiClient } from "@cloudpdf/sdk"; + +const client = new CloudpdfApiClient({ baseUrl: "YOUR_BASE_URL", token: "YOUR_TOKEN" }); +await client.tenants.create({ + id: "id" +}); +``` + +## Request and Response Types + +The SDK exports all request and response types as TypeScript interfaces. Simply import them with the +following namespace: + +```typescript +import { CloudpdfApi } from "@cloudpdf/sdk"; + +const request: CloudpdfApi.HeadDocRequest = { + ... +}; +``` + +## Exception Handling + +When the API returns a non-success status code (4xx or 5xx response), a subclass of the following error +will be thrown. + +```typescript +import { CloudpdfApiError } from "@cloudpdf/sdk"; + +try { + await client.tenants.create(...); +} catch (err) { + if (err instanceof CloudpdfApiError) { + console.log(err.statusCode); + console.log(err.message); + console.log(err.body); + console.log(err.rawResponse); + } +} +``` + +## File Uploads + +You can upload files using the client: + +```typescript +import { createReadStream } from "fs"; + +await client.documents.uploadDirect(createReadStream("path/to/file"), ...); +await client.documents.uploadDirect(new ReadableStream(), ...); +await client.documents.uploadDirect(Buffer.from('binary data'), ...); +await client.documents.uploadDirect(new Blob(['binary data'], { type: 'audio/mpeg' }), ...); +await client.documents.uploadDirect(new File(['binary data'], 'file.mp3'), ...); +await client.documents.uploadDirect(new ArrayBuffer(8), ...); +await client.documents.uploadDirect(new Uint8Array([0, 1, 2]), ...); +``` +The client accepts a variety of types for file upload parameters: +* Stream types: `fs.ReadStream`, `stream.Readable`, and `ReadableStream` +* Buffered types: `Buffer`, `Blob`, `File`, `ArrayBuffer`, `ArrayBufferView`, and `Uint8Array` + +### Metadata + +You can configure metadata when uploading a file: +```typescript +const file: Uploadable.WithMetadata = { + data: createReadStream("path/to/file"), + filename: "my-file", // optional + contentType: "audio/mpeg", // optional + contentLength: 1949, // optional +}; +``` + +Alternatively, you can upload a file directly from a file path: +```typescript +const file : Uploadable.FromPath = { + path: "path/to/file", + filename: "my-file", // optional + contentType: "audio/mpeg", // optional + contentLength: 1949, // optional +}; +``` + +The metadata is used to set the `Content-Length`, `Content-Type`, and `Content-Disposition` headers. If not provided, the client will attempt to determine them automatically. +For example, `fs.ReadStream` has a `path` property which the SDK uses to retrieve the file size from the filesystem without loading it into memory. + + +## Binary Response + +You can consume binary data from endpoints using the `BinaryResponse` type which lets you choose how to consume the data: + +```typescript +const response = await client.doc.download(...); +const stream: ReadableStream = response.stream(); +// const arrayBuffer: ArrayBuffer = await response.arrayBuffer(); +// const blob: Blob = response.blob(); +// const bytes: Uint8Array = response.bytes(); +// You can only use the response body once, so you must choose one of the above methods. +// If you want to check if the response body has been used, you can use the following property. +const bodyUsed = response.bodyUsed; +``` +
+Save binary response to a file + +
+
+Node.js + +
+
+ReadableStream (most-efficient) + +```ts +import { createWriteStream } from 'fs'; +import { Readable } from 'stream'; +import { pipeline } from 'stream/promises'; + +const response = await client.doc.download(...); + +const stream = response.stream(); +const nodeStream = Readable.fromWeb(stream); +const writeStream = createWriteStream('path/to/file'); + +await pipeline(nodeStream, writeStream); +``` + +
+
+ +
+
+ArrayBuffer + +```ts +import { writeFile } from 'fs/promises'; + +const response = await client.doc.download(...); + +const arrayBuffer = await response.arrayBuffer(); +await writeFile('path/to/file', Buffer.from(arrayBuffer)); +``` + +
+
+ +
+
+Blob + +```ts +import { writeFile } from 'fs/promises'; + +const response = await client.doc.download(...); + +const blob = await response.blob(); +const arrayBuffer = await blob.arrayBuffer(); +await writeFile('output.bin', Buffer.from(arrayBuffer)); +``` + +
+
+ +
+
+Bytes (UIntArray8) + +```ts +import { writeFile } from 'fs/promises'; + +const response = await client.doc.download(...); + +const bytes = await response.bytes(); +await writeFile('path/to/file', bytes); +``` + +
+
+ +
+
+ +
+
+Bun + +
+
+ReadableStream (most-efficient) + +```ts +const response = await client.doc.download(...); + +const stream = response.stream(); +await Bun.write('path/to/file', stream); +``` + +
+
+ +
+
+ArrayBuffer + +```ts +const response = await client.doc.download(...); + +const arrayBuffer = await response.arrayBuffer(); +await Bun.write('path/to/file', arrayBuffer); +``` + +
+
+ +
+
+Blob + +```ts +const response = await client.doc.download(...); + +const blob = await response.blob(); +await Bun.write('path/to/file', blob); +``` + +
+
+ +
+
+Bytes (UIntArray8) + +```ts +const response = await client.doc.download(...); + +const bytes = await response.bytes(); +await Bun.write('path/to/file', bytes); +``` + +
+
+ +
+
+ +
+
+Deno + +
+
+ReadableStream (most-efficient) + +```ts +const response = await client.doc.download(...); + +const stream = response.stream(); +const file = await Deno.open('path/to/file', { write: true, create: true }); +await stream.pipeTo(file.writable); +``` + +
+
+ +
+
+ArrayBuffer + +```ts +const response = await client.doc.download(...); + +const arrayBuffer = await response.arrayBuffer(); +await Deno.writeFile('path/to/file', new Uint8Array(arrayBuffer)); +``` + +
+
+ +
+
+Blob + +```ts +const response = await client.doc.download(...); + +const blob = await response.blob(); +const arrayBuffer = await blob.arrayBuffer(); +await Deno.writeFile('path/to/file', new Uint8Array(arrayBuffer)); +``` + +
+
+ +
+
+Bytes (UIntArray8) + +```ts +const response = await client.doc.download(...); + +const bytes = await response.bytes(); +await Deno.writeFile('path/to/file', bytes); +``` + +
+
+ +
+
+ +
+
+Browser + +
+
+Blob (most-efficient) + +```ts +const response = await client.doc.download(...); + +const blob = await response.blob(); +const url = URL.createObjectURL(blob); + +// trigger download +const a = document.createElement('a'); +a.href = url; +a.download = 'filename'; +a.click(); +URL.revokeObjectURL(url); +``` + +
+
+ +
+
+ReadableStream + +```ts +const response = await client.doc.download(...); + +const stream = response.stream(); +const reader = stream.getReader(); +const chunks = []; + +while (true) { + const { done, value } = await reader.read(); + if (done) break; + chunks.push(value); +} + +const blob = new Blob(chunks); +const url = URL.createObjectURL(blob); + +// trigger download +const a = document.createElement('a'); +a.href = url; +a.download = 'filename'; +a.click(); +URL.revokeObjectURL(url); +``` + +
+
+ +
+
+ArrayBuffer + +```ts +const response = await client.doc.download(...); + +const arrayBuffer = await response.arrayBuffer(); +const blob = new Blob([arrayBuffer]); +const url = URL.createObjectURL(blob); + +// trigger download +const a = document.createElement('a'); +a.href = url; +a.download = 'filename'; +a.click(); +URL.revokeObjectURL(url); +``` + +
+
+ +
+
+Bytes (UIntArray8) + +```ts +const response = await client.doc.download(...); + +const bytes = await response.bytes(); +const blob = new Blob([bytes]); +const url = URL.createObjectURL(blob); + +// trigger download +const a = document.createElement('a'); +a.href = url; +a.download = 'filename'; +a.click(); +URL.revokeObjectURL(url); +``` + +
+
+ +
+
+ +
+ + +
+Convert binary response to text + +
+
+ReadableStream + +```ts +const response = await client.doc.download(...); + +const stream = response.stream(); +const text = await new Response(stream).text(); +``` + +
+
+ +
+
+ArrayBuffer + +```ts +const response = await client.doc.download(...); + +const arrayBuffer = await response.arrayBuffer(); +const text = new TextDecoder().decode(arrayBuffer); +``` + +
+
+ +
+
+Blob + +```ts +const response = await client.doc.download(...); + +const blob = await response.blob(); +const text = await blob.text(); +``` + +
+
+ +
+
+Bytes (UIntArray8) + +```ts +const response = await client.doc.download(...); + +const bytes = await response.bytes(); +const text = new TextDecoder().decode(bytes); +``` + +
+
+ +
+ +## Advanced + +### Subpackage Exports + +This SDK supports direct imports of subpackage clients, which allows JavaScript bundlers to tree-shake and include only the imported subpackage code. This results in much smaller bundle sizes. + +```typescript +import { DeploymentClient } from '@cloudpdf/sdk/deployment'; + +const client = new DeploymentClient({...}); +``` + +### Additional Headers + +If you would like to send additional headers as part of the request, use the `headers` request option. + +```typescript +import { CloudpdfApiClient } from "@cloudpdf/sdk"; + +const client = new CloudpdfApiClient({ + ... + headers: { + 'X-Custom-Header': 'custom value' + } +}); + +const response = await client.tenants.create(..., { + headers: { + 'X-Custom-Header': 'custom value' + } +}); +``` + +### Additional Query String Parameters + +If you would like to send additional query string parameters as part of the request, use the `queryParams` request option. + +```typescript +const response = await client.tenants.create(..., { + queryParams: { + 'customQueryParamKey': 'custom query param value' + } +}); +``` + +### Retries + +The SDK is instrumented with automatic retries with exponential backoff. A request will be retried as long +as the request is deemed retryable and the number of retry attempts has not grown larger than the configured +retry limit (default: 2). + +Which status codes are retried depends on the `retryStatusCodes` generator configuration: + +**`legacy`** (current default): retries on +- [408](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/408) (Timeout) +- [429](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/429) (Too Many Requests) +- [5XX](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#server_error_responses) (All server errors, including 500) + +**`recommended`**: retries on +- [408](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/408) (Timeout) +- [429](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/429) (Too Many Requests) +- [502](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/502) (Bad Gateway) +- [503](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/503) (Service Unavailable) +- [504](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/504) (Gateway Timeout) + +Use the `maxRetries` request option to configure this behavior. + +```typescript +const response = await client.tenants.create(..., { + maxRetries: 0 // override maxRetries at the request level +}); +``` + +### Timeouts + +The SDK defaults to a 60 second timeout. Use the `timeoutInSeconds` option to configure this behavior. + +```typescript +const response = await client.tenants.create(..., { + timeoutInSeconds: 30 // override timeout to 30s +}); +``` + +### Aborting Requests + +The SDK allows users to abort requests at any point by passing in an abort signal. + +```typescript +const controller = new AbortController(); +const response = await client.tenants.create(..., { + abortSignal: controller.signal +}); +controller.abort(); // aborts the request +``` + +### Access Raw Response Data + +The SDK provides access to raw response data, including headers, through the `.withRawResponse()` method. +The `.withRawResponse()` method returns a promise that results to an object with a `data` and a `rawResponse` property. + +```typescript +const { data, rawResponse } = await client.tenants.create(...).withRawResponse(); + +console.log(data); +console.log(rawResponse.headers['X-My-Header']); +``` + +### Logging + +The SDK supports logging. You can configure the logger by passing in a `logging` object to the client options. + +```typescript +import { CloudpdfApiClient, logging } from "@cloudpdf/sdk"; + +const client = new CloudpdfApiClient({ + ... + logging: { + level: logging.LogLevel.Debug, // defaults to logging.LogLevel.Info + logger: new logging.ConsoleLogger(), // defaults to ConsoleLogger + silent: false, // defaults to true, set to false to enable logging + } +}); +``` +The `logging` object can have the following properties: +- `level`: The log level to use. Defaults to `logging.LogLevel.Info`. +- `logger`: The logger to use. Defaults to a `logging.ConsoleLogger`. +- `silent`: Whether to silence the logger. Defaults to `true`. + +The `level` property can be one of the following values: +- `logging.LogLevel.Debug` +- `logging.LogLevel.Info` +- `logging.LogLevel.Warn` +- `logging.LogLevel.Error` + +To provide a custom logger, you can pass in an object that implements the `logging.ILogger` interface. + +
+Custom logger examples + +Here's an example using the popular `winston` logging library. +```ts +import winston from 'winston'; + +const winstonLogger = winston.createLogger({...}); + +const logger: logging.ILogger = { + debug: (msg, ...args) => winstonLogger.debug(msg, ...args), + info: (msg, ...args) => winstonLogger.info(msg, ...args), + warn: (msg, ...args) => winstonLogger.warn(msg, ...args), + error: (msg, ...args) => winstonLogger.error(msg, ...args), +}; +``` + +Here's an example using the popular `pino` logging library. + +```ts +import pino from 'pino'; + +const pinoLogger = pino({...}); + +const logger: logging.ILogger = { + debug: (msg, ...args) => pinoLogger.debug(args, msg), + info: (msg, ...args) => pinoLogger.info(args, msg), + warn: (msg, ...args) => pinoLogger.warn(args, msg), + error: (msg, ...args) => pinoLogger.error(args, msg), +}; +``` +
+ + +### Custom Fetch + +The SDK provides a low-level `fetch` method for making custom HTTP requests while still +benefiting from SDK-level configuration like authentication, retries, timeouts, and logging. +This is useful for calling API endpoints not yet supported in the SDK. + +```typescript +const response = await client.fetch("/v1/custom/endpoint", { + method: "GET", +}, { + timeoutInSeconds: 30, + maxRetries: 3, + headers: { + "X-Custom-Header": "custom-value", + }, +}); + +const data = await response.json(); +``` + +### Runtime Compatibility + + +The SDK works in the following runtimes: + + + +- Node.js 18+ +- Vercel +- Cloudflare Workers +- Deno v1.25+ +- Bun 1.0+ +- React Native + + +## Contributing + +While we value open-source contributions to this SDK, this library is generated programmatically. +Additions made directly to this library would have to be moved over to our generation code, +otherwise they would be overwritten upon the next generated release. Feel free to open a PR as +a proof of concept, but know that we will not be able to merge it as-is. We suggest opening +an issue first to discuss with us! + +On the other hand, contributions to the README are always very welcome! diff --git a/biome.json b/biome.json new file mode 100644 index 0000000..6b89164 --- /dev/null +++ b/biome.json @@ -0,0 +1,74 @@ +{ + "$schema": "https://biomejs.dev/schemas/2.4.10/schema.json", + "root": true, + "vcs": { + "enabled": false + }, + "files": { + "ignoreUnknown": true, + "includes": [ + "**", + "!!dist", + "!!**/dist", + "!!lib", + "!!**/lib", + "!!_tmp_*", + "!!**/_tmp_*", + "!!*.tmp", + "!!**/*.tmp", + "!!.tmp/", + "!!**/.tmp/", + "!!*.log", + "!!**/*.log", + "!!**/.DS_Store", + "!!**/Thumbs.db" + ] + }, + "formatter": { + "enabled": true, + "indentStyle": "space", + "indentWidth": 4, + "lineWidth": 120 + }, + "javascript": { + "formatter": { + "quoteStyle": "double" + } + }, + "assist": { + "enabled": true, + "actions": { + "source": { + "organizeImports": "on" + } + } + }, + "linter": { + "rules": { + "style": { + "useNodejsImportProtocol": "off" + }, + "suspicious": { + "noAssignInExpressions": "warn", + "noUselessEscapeInString": { + "level": "warn", + "fix": "none", + "options": {} + }, + "noThenProperty": "warn", + "useIterableCallbackReturn": "warn", + "noShadowRestrictedNames": "warn", + "noTsIgnore": { + "level": "warn", + "fix": "none", + "options": {} + }, + "noConfusingVoidType": { + "level": "warn", + "fix": "none", + "options": {} + } + } + } + } +} diff --git a/cloudpdf-generation.json b/cloudpdf-generation.json new file mode 100644 index 0000000..b57a8e2 --- /dev/null +++ b/cloudpdf-generation.json @@ -0,0 +1,17 @@ +{ + "language": "typescript", + "canonicalVersion": "3.0.0-next.1", + "sdkVersion": "3.0.0-next.1", + "source": { + "repository": "embedpdf/embed-pdf-viewer", + "openapi": "cloudpdf/contract/openapi.json", + "openapiSha256": "6858ce7912e9063d8fb171ade95fc473db01c5971a3af241a612dda79cc05100", + "gitCommit": "232d5e0240d5673a73c9ea7c7ae9e7b937fdd5b3", + "gitCommitIsDirty": false + }, + "fern": { + "cliVersion": "5.91.0", + "generatorName": "fernapi/fern-typescript-sdk", + "generatorVersion": "3.87.2" + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..f9050e3 --- /dev/null +++ b/package.json @@ -0,0 +1,181 @@ +{ + "name": "@cloudpdf/sdk", + "version": "3.0.0-next.1", + "private": false, + "license": "Apache-2.0", + "type": "commonjs", + "main": "./dist/cjs/index.js", + "module": "./dist/esm/index.mjs", + "types": "./dist/cjs/index.d.ts", + "exports": { + ".": { + "import": { + "types": "./dist/esm/index.d.mts", + "default": "./dist/esm/index.mjs" + }, + "require": { + "types": "./dist/cjs/index.d.ts", + "default": "./dist/cjs/index.js" + }, + "default": "./dist/cjs/index.js" + }, + "./deployment": { + "import": { + "types": "./dist/esm/api/resources/deployment/exports.d.mts", + "default": "./dist/esm/api/resources/deployment/exports.mjs" + }, + "require": { + "types": "./dist/cjs/api/resources/deployment/exports.d.ts", + "default": "./dist/cjs/api/resources/deployment/exports.js" + }, + "default": "./dist/cjs/api/resources/deployment/exports.js" + }, + "./doc": { + "import": { + "types": "./dist/esm/api/resources/doc/exports.d.mts", + "default": "./dist/esm/api/resources/doc/exports.mjs" + }, + "require": { + "types": "./dist/cjs/api/resources/doc/exports.d.ts", + "default": "./dist/cjs/api/resources/doc/exports.js" + }, + "default": "./dist/cjs/api/resources/doc/exports.js" + }, + "./tenants": { + "import": { + "types": "./dist/esm/api/resources/tenants/exports.d.mts", + "default": "./dist/esm/api/resources/tenants/exports.mjs" + }, + "require": { + "types": "./dist/cjs/api/resources/tenants/exports.d.ts", + "default": "./dist/cjs/api/resources/tenants/exports.js" + }, + "default": "./dist/cjs/api/resources/tenants/exports.js" + }, + "./documents": { + "import": { + "types": "./dist/esm/api/resources/documents/exports.d.mts", + "default": "./dist/esm/api/resources/documents/exports.mjs" + }, + "require": { + "types": "./dist/cjs/api/resources/documents/exports.d.ts", + "default": "./dist/cjs/api/resources/documents/exports.js" + }, + "default": "./dist/cjs/api/resources/documents/exports.js" + }, + "./tokens": { + "import": { + "types": "./dist/esm/api/resources/tokens/exports.d.mts", + "default": "./dist/esm/api/resources/tokens/exports.mjs" + }, + "require": { + "types": "./dist/cjs/api/resources/tokens/exports.d.ts", + "default": "./dist/cjs/api/resources/tokens/exports.js" + }, + "default": "./dist/cjs/api/resources/tokens/exports.js" + }, + "./doc/annotations": { + "import": { + "types": "./dist/esm/api/resources/doc/resources/annotations/exports.d.mts", + "default": "./dist/esm/api/resources/doc/resources/annotations/exports.mjs" + }, + "require": { + "types": "./dist/cjs/api/resources/doc/resources/annotations/exports.d.ts", + "default": "./dist/cjs/api/resources/doc/resources/annotations/exports.js" + }, + "default": "./dist/cjs/api/resources/doc/resources/annotations/exports.js" + }, + "./doc/forms": { + "import": { + "types": "./dist/esm/api/resources/doc/resources/forms/exports.d.mts", + "default": "./dist/esm/api/resources/doc/resources/forms/exports.mjs" + }, + "require": { + "types": "./dist/cjs/api/resources/doc/resources/forms/exports.d.ts", + "default": "./dist/cjs/api/resources/doc/resources/forms/exports.js" + }, + "default": "./dist/cjs/api/resources/doc/resources/forms/exports.js" + }, + "./doc/metadata": { + "import": { + "types": "./dist/esm/api/resources/doc/resources/metadata/exports.d.mts", + "default": "./dist/esm/api/resources/doc/resources/metadata/exports.mjs" + }, + "require": { + "types": "./dist/cjs/api/resources/doc/resources/metadata/exports.d.ts", + "default": "./dist/cjs/api/resources/doc/resources/metadata/exports.js" + }, + "default": "./dist/cjs/api/resources/doc/resources/metadata/exports.js" + }, + "./doc/pages": { + "import": { + "types": "./dist/esm/api/resources/doc/resources/pages/exports.d.mts", + "default": "./dist/esm/api/resources/doc/resources/pages/exports.mjs" + }, + "require": { + "types": "./dist/cjs/api/resources/doc/resources/pages/exports.d.ts", + "default": "./dist/cjs/api/resources/doc/resources/pages/exports.js" + }, + "default": "./dist/cjs/api/resources/doc/resources/pages/exports.js" + }, + "./doc/redactions": { + "import": { + "types": "./dist/esm/api/resources/doc/resources/redactions/exports.d.mts", + "default": "./dist/esm/api/resources/doc/resources/redactions/exports.mjs" + }, + "require": { + "types": "./dist/cjs/api/resources/doc/resources/redactions/exports.d.ts", + "default": "./dist/cjs/api/resources/doc/resources/redactions/exports.js" + }, + "default": "./dist/cjs/api/resources/doc/resources/redactions/exports.js" + }, + "./package.json": "./package.json" + }, + "files": [ + "dist", + "reference.md", + "README.md", + "LICENSE" + ], + "scripts": { + "format": "biome format --write --skip-parse-errors --no-errors-on-unmatched --max-diagnostics=none", + "format:check": "biome format --skip-parse-errors --no-errors-on-unmatched --max-diagnostics=none", + "lint": "biome lint --skip-parse-errors --no-errors-on-unmatched --max-diagnostics=none", + "lint:fix": "biome lint --fix --unsafe --skip-parse-errors --no-errors-on-unmatched --max-diagnostics=none", + "check": "biome check --skip-parse-errors --no-errors-on-unmatched --max-diagnostics=none", + "check:fix": "biome check --fix --unsafe --skip-parse-errors --no-errors-on-unmatched --max-diagnostics=none", + "build": "pnpm build:cjs && pnpm build:esm", + "build:cjs": "tsc --project ./tsconfig.cjs.json", + "build:esm": "tsc --project ./tsconfig.esm.json && node scripts/rename-to-esm-files.js dist/esm", + "test": "vitest", + "test:unit": "vitest --project unit", + "test:wire": "vitest --project wire" + }, + "dependencies": {}, + "devDependencies": { + "webpack": "^5.105.4", + "ts-loader": "^9.5.4", + "vitest": "^4.1.1", + "msw": "2.11.2", + "@types/node": "^20.0.0", + "typescript": "~5.9.3", + "@biomejs/biome": "2.4.10" + }, + "browser": { + "fs": false, + "os": false, + "path": false, + "stream": false, + "crypto": false + }, + "packageManager": "pnpm@10.33.0", + "engines": { + "node": ">=18.0.0" + }, + "sideEffects": false, + "description": "The official TypeScript SDK for the CloudPDF API.", + "repository": { + "type": "git", + "url": "git+https://github.com/embedpdf/cloudpdf-sdk-typescript.git" + } +} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml new file mode 100644 index 0000000..6e4c395 --- /dev/null +++ b/pnpm-workspace.yaml @@ -0,0 +1 @@ +packages: ['.'] \ No newline at end of file diff --git a/reference.md b/reference.md new file mode 100644 index 0000000..6e2d343 --- /dev/null +++ b/reference.md @@ -0,0 +1,1875 @@ +# Reference +## Deployment +
client.deployment.licenseStatus() -> CloudpdfApi.DeploymentLicenseStatusResponse +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.deployment.licenseStatus(); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**requestOptions:** `DeploymentClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +## Doc +
client.doc.head({ ...params }) -> CloudpdfApi.DocHead200Response +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.doc.head({ + docId: "docId" +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `CloudpdfApi.HeadDocRequest` + +
+
+ +
+
+ +**requestOptions:** `DocClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +
client.doc.download({ ...params }) -> core.BinaryResponse +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.doc.download({ + docId: "docId", + layerName: "layerName" +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `CloudpdfApi.DownloadDocRequest` + +
+
+ +
+
+ +**requestOptions:** `DocClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +
client.doc.manifest({ ...params }) -> CloudpdfApi.DocManifest200Response +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.doc.manifest({ + docId: "docId", + layerName: "layerName" +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `CloudpdfApi.ManifestDocRequest` + +
+
+ +
+
+ +**requestOptions:** `DocClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +
client.doc.render({ ...params }) -> core.BinaryResponse +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Render parameters (viewport, format) pass as flat dotted query keys, e.g. `?viewport.kind=width&viewport.width=800`; the full grammar is documented with the viewer. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.doc.render({ + docId: "docId", + layerName: "layerName", + pon: 1 +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `CloudpdfApi.RenderDocRequest` + +
+
+ +
+
+ +**requestOptions:** `DocClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +
client.doc.text({ ...params }) -> CloudpdfApi.DocText200Response +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.doc.text({ + docId: "docId", + layerName: "layerName", + pon: 1 +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `CloudpdfApi.TextDocRequest` + +
+
+ +
+
+ +**requestOptions:** `DocClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +## Tenants +
client.tenants.list({ ...params }) -> CloudpdfApi.TenantsList200Response +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.tenants.list(); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `CloudpdfApi.ListTenantsRequest` + +
+
+ +
+
+ +**requestOptions:** `TenantsClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +
client.tenants.create({ ...params }) -> CloudpdfApi.TenantsCreate200Response +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.tenants.create({ + id: "id" +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `CloudpdfApi.TenantsCreateRequest` + +
+
+ +
+
+ +**requestOptions:** `TenantsClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +
client.tenants.get({ ...params }) -> CloudpdfApi.TenantsGet200Response +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.tenants.get({ + tenantId: "tenantId" +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `CloudpdfApi.GetTenantsRequest` + +
+
+ +
+
+ +**requestOptions:** `TenantsClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +
client.tenants.delete({ ...params }) -> void +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Destroys the tenant and everything in its namespace — documents, layers, stored bytes, audit history. Irreversible. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.tenants.delete({ + tenantId: "tenantId" +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `CloudpdfApi.DeleteTenantsRequest` + +
+
+ +
+
+ +**requestOptions:** `TenantsClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +## Documents +
client.documents.list({ ...params }) -> CloudpdfApi.DocumentsList200Response +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.documents.list({ + tenantId: "tenantId" +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `CloudpdfApi.ListDocumentsRequest` + +
+
+ +
+
+ +**requestOptions:** `DocumentsClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +
client.documents.get({ ...params }) -> CloudpdfApi.DocumentsGet200Response +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.documents.get({ + tenantId: "tenantId", + id: "id" +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `CloudpdfApi.GetDocumentsRequest` + +
+
+ +
+
+ +**requestOptions:** `DocumentsClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +
client.documents.delete({ ...params }) -> void +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.documents.delete({ + tenantId: "tenantId", + id: "id" +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `CloudpdfApi.DeleteDocumentsRequest` + +
+
+ +
+
+ +**requestOptions:** `DocumentsClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +
client.documents.commit({ ...params }) -> CloudpdfApi.DocumentsCommit200Response +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.documents.commit({ + tenantId: "tenantId", + id: "id", + sha256: "sha256" +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `CloudpdfApi.DocumentsCommitRequest` + +
+
+ +
+
+ +**requestOptions:** `DocumentsClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +
client.documents.download({ ...params }) -> core.BinaryResponse +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.documents.download({ + tenantId: "tenantId", + id: "id" +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `CloudpdfApi.DownloadDocumentsRequest` + +
+
+ +
+
+ +**requestOptions:** `DocumentsClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +
client.documents.thumbnail({ ...params }) -> core.BinaryResponse +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.documents.thumbnail({ + tenantId: "tenantId", + id: "id" +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `CloudpdfApi.ThumbnailDocumentsRequest` + +
+
+ +
+
+ +**requestOptions:** `DocumentsClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +
client.documents.init({ ...params }) -> CloudpdfApi.DocumentsInit200Response +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.documents.init({ + tenantId: "tenantId", + contentLength: 1.1, + contentSha256: "contentSha256" +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `CloudpdfApi.DocumentsInitRequest` + +
+
+ +
+
+ +**requestOptions:** `DocumentsClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +## Tokens +
client.tokens.issue({ ...params }) -> CloudpdfApi.TokensIssue200Response +
+
+ +#### 📝 Description + +
+
+ +
+
+ +kind "tenant" requires the API token — authority mints only downward. Mounted only when the deployment can sign (HS256 mode); asymmetric deployments mint with their own private key. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.tokens.issue({ + tenantId: "tenantId", + body: { + kind: "doc", + sub: "sub", + docId: "docId", + scope: ["scope"], + expiresIn: 1 + } +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `CloudpdfApi.IssueTokensRequest` + +
+
+ +
+
+ +**requestOptions:** `TokensClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +
client.tokens.revoke({ ...params }) -> void +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Mounted only when the deployment enables token revocation. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.tokens.revoke({ + tenantId: "tenantId", + jti: "jti" +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `CloudpdfApi.TokensRevokeRequest` + +
+
+ +
+
+ +**requestOptions:** `TokensClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +## Doc Annotations +
client.doc.annotations.list({ ...params }) -> CloudpdfApi.DocAnnotationsList200Response +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.doc.annotations.list({ + docId: "docId", + layerName: "layerName", + pon: 1 +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `CloudpdfApi.doc.ListAnnotationsRequest` + +
+
+ +
+
+ +**requestOptions:** `AnnotationsClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +
client.doc.annotations.create({ ...params }) -> CloudpdfApi.DocAnnotationsCreate200Response +
+
+ +#### 📝 Description + +
+
+ +
+
+ +Doc JWTs may instead carry collab scopes (annotations:create:self, …) that refine per-annotation authorship rules; the API token is exempt from both. +
+
+
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.doc.annotations.create({ + docId: "docId", + layerName: "layerName", + pon: 1, + body: { + "key": "value" + } +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `CloudpdfApi.doc.CreateAnnotationsRequest` + +
+
+ +
+
+ +**requestOptions:** `AnnotationsClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +
client.doc.annotations.delete({ ...params }) -> CloudpdfApi.DocAnnotationsDelete200Response +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.doc.annotations.delete({ + docId: "docId", + layerName: "layerName", + pon: 1, + annotKey: "annotKey" +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `CloudpdfApi.doc.DeleteAnnotationsRequest` + +
+
+ +
+
+ +**requestOptions:** `AnnotationsClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +
client.doc.annotations.update({ ...params }) -> CloudpdfApi.DocAnnotationsUpdate200Response +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.doc.annotations.update({ + docId: "docId", + layerName: "layerName", + pon: 1, + annotKey: "annotKey", + body: { + "key": "value" + } +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `CloudpdfApi.doc.UpdateAnnotationsRequest` + +
+
+ +
+
+ +**requestOptions:** `AnnotationsClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +## Doc Forms +
client.doc.forms.get({ ...params }) -> CloudpdfApi.DocFormsGet200Response +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.doc.forms.get({ + docId: "docId", + layerName: "layerName" +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `CloudpdfApi.doc.GetFormsRequest` + +
+
+ +
+
+ +**requestOptions:** `FormsClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +
client.doc.forms.exportData({ ...params }) -> core.BinaryResponse +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.doc.forms.exportData({ + docId: "docId", + layerName: "layerName" +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `CloudpdfApi.doc.ExportDataFormsRequest` + +
+
+ +
+
+ +**requestOptions:** `FormsClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +
client.doc.forms.importData({ ...params }) -> CloudpdfApi.DocFormsImportData200Response +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.doc.forms.importData({ + docId: "docId", + layerName: "layerName", + body: { + "key": "value" + } +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `CloudpdfApi.doc.ImportDataFormsRequest` + +
+
+ +
+
+ +**requestOptions:** `FormsClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +
client.doc.forms.reset({ ...params }) -> CloudpdfApi.DocFormsReset200Response +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.doc.forms.reset({ + docId: "docId", + layerName: "layerName", + fieldKey: "fieldKey" +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `CloudpdfApi.doc.ResetFormsRequest` + +
+
+ +
+
+ +**requestOptions:** `FormsClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +
client.doc.forms.setValue({ ...params }) -> CloudpdfApi.DocFormsSetValue200Response +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.doc.forms.setValue({ + docId: "docId", + layerName: "layerName", + fieldKey: "fieldKey", + body: { + "key": "value" + } +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `CloudpdfApi.doc.SetValueFormsRequest` + +
+
+ +
+
+ +**requestOptions:** `FormsClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +## Doc Metadata +
client.doc.metadata.get({ ...params }) -> CloudpdfApi.DocMetadataGet200Response +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.doc.metadata.get({ + docId: "docId", + layerName: "layerName" +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `CloudpdfApi.doc.GetMetadataRequest` + +
+
+ +
+
+ +**requestOptions:** `MetadataClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +## Doc Pages +
client.doc.pages.delete({ ...params }) -> CloudpdfApi.DocPagesDelete200Response +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.doc.pages.delete({ + docId: "docId", + layerName: "layerName", + body: { + "key": "value" + } +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `CloudpdfApi.doc.DeletePagesRequest` + +
+
+ +
+
+ +**requestOptions:** `PagesClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +
client.doc.pages.flatten({ ...params }) -> CloudpdfApi.DocPagesFlatten200Response +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.doc.pages.flatten({ + docId: "docId", + layerName: "layerName", + body: { + "key": "value" + } +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `CloudpdfApi.doc.FlattenPagesRequest` + +
+
+ +
+
+ +**requestOptions:** `PagesClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +
client.doc.pages.move({ ...params }) -> CloudpdfApi.DocPagesMove200Response +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.doc.pages.move({ + docId: "docId", + layerName: "layerName", + body: { + "key": "value" + } +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `CloudpdfApi.doc.MovePagesRequest` + +
+
+ +
+
+ +**requestOptions:** `PagesClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +
client.doc.pages.rotate({ ...params }) -> CloudpdfApi.DocPagesRotate200Response +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.doc.pages.rotate({ + docId: "docId", + layerName: "layerName", + body: { + "key": "value" + } +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `CloudpdfApi.doc.RotatePagesRequest` + +
+
+ +
+
+ +**requestOptions:** `PagesClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ +## Doc Redactions +
client.doc.redactions.apply({ ...params }) -> CloudpdfApi.DocRedactionsApply200Response +
+
+ +#### 🔌 Usage + +
+
+ +
+
+ +```typescript +await client.doc.redactions.apply({ + docId: "docId", + layerName: "layerName", + body: { + "key": "value" + } +}); + +``` +
+
+
+
+ +#### ⚙️ Parameters + +
+
+ +
+
+ +**request:** `CloudpdfApi.doc.ApplyRedactionsRequest` + +
+
+ +
+
+ +**requestOptions:** `RedactionsClient.RequestOptions` + +
+
+
+
+ + +
+
+
+ diff --git a/scripts/rename-to-esm-files.js b/scripts/rename-to-esm-files.js new file mode 100644 index 0000000..0a03de1 --- /dev/null +++ b/scripts/rename-to-esm-files.js @@ -0,0 +1,188 @@ +#!/usr/bin/env node + +const fs = require("fs").promises; +const fsSync = require("fs"); +const path = require("path"); + +const extensionMap = { + ".js": ".mjs", + ".d.ts": ".d.mts", +}; +const oldExtensions = Object.keys(extensionMap); + +async function findFiles(rootPath) { + const files = []; + + async function scan(directory) { + const entries = await fs.readdir(directory, { withFileTypes: true }); + + for (const entry of entries) { + const fullPath = path.join(directory, entry.name); + + if (entry.isDirectory()) { + if (entry.name !== "node_modules" && !entry.name.startsWith(".")) { + await scan(fullPath); + } + } else if (entry.isFile()) { + if (oldExtensions.some((ext) => entry.name.endsWith(ext))) { + files.push(fullPath); + } + } + } + } + + await scan(rootPath); + return files; +} + +async function updateFiles(files) { + const updatedFiles = []; + for (const file of files) { + const updated = await updateFileContents(file); + updatedFiles.push(updated); + } + + console.log(`Updated imports in ${updatedFiles.length} files.`); +} + +const KNOWN_EXTENSIONS = new Set([".js", ".mjs", ".cjs", ".jsx", ".json", ".ts", ".mts", ".cts", ".tsx", ".node"]); + +function hasFileExtension(importPath) { + const basename = path.basename(importPath); + const dotIndex = basename.lastIndexOf("."); + if (dotIndex <= 0) { + return false; + } + return KNOWN_EXTENSIONS.has(basename.slice(dotIndex).toLowerCase()); +} + +function resolveExtensionlessImport(dir, importPath) { + const resolvedPath = path.resolve(dir, importPath); + if (fsSync.existsSync(`${resolvedPath}.js`)) { + return `${importPath}.mjs`; + } + const indexPath = path.join(resolvedPath, "index.js"); + if (fsSync.existsSync(indexPath)) { + return `${importPath}/index.mjs`; + } + return null; +} + +async function updateFileContents(file) { + const content = await fs.readFile(file, "utf8"); + const dir = path.dirname(file); + + let newContent = content; + // Update each extension type defined in the map + for (const [oldExt, newExt] of Object.entries(extensionMap)) { + // Handle static imports/exports + const staticRegex = new RegExp(`(import|export)(.+from\\s+['"])(\\.\\.?\\/[^'"]+)(\\${oldExt})(['"])`, "g"); + newContent = newContent.replace(staticRegex, `$1$2$3${newExt}$5`); + + // Handle dynamic imports (yield import, await import, regular import()) + const dynamicRegex = new RegExp( + `(yield\\s+import|await\\s+import|import)\\s*\\(\\s*['"](\\.\\.\?\\/[^'"]+)(\\${oldExt})['"]\\s*\\)`, + "g", + ); + newContent = newContent.replace(dynamicRegex, `$1("$2${newExt}")`); + } + + // Handle extensionless relative imports (e.g. from "./oauth" or from "../utils"). + // These violate the ESM spec and break Node's ESM loader and Turbopack. + const staticExtensionless = /(import|export)(.+from\s+['"])(\.\.?\/[^'"]+?)(['"])/g; + const staticReplacements = []; + let match; + while ((match = staticExtensionless.exec(newContent)) !== null) { + const importPath = match[3]; + if (hasFileExtension(importPath)) continue; + const resolved = resolveExtensionlessImport(dir, importPath); + if (resolved != null) { + staticReplacements.push({ + start: match.index, + end: match.index + match[0].length, + replacement: `${match[1]}${match[2]}${resolved}${match[4]}`, + }); + } + } + for (const { start, end, replacement } of staticReplacements.reverse()) { + newContent = newContent.slice(0, start) + replacement + newContent.slice(end); + } + + // Handle extensionless dynamic imports + const dynamicExtensionless = /(yield\s+import|await\s+import|import)\s*\(\s*['"](\.\.?\/[^'"]+?)['"]\s*\)/g; + const dynamicReplacements = []; + while ((match = dynamicExtensionless.exec(newContent)) !== null) { + const importPath = match[2]; + if (hasFileExtension(importPath)) continue; + const resolved = resolveExtensionlessImport(dir, importPath); + if (resolved != null) { + dynamicReplacements.push({ + start: match.index, + end: match.index + match[0].length, + replacement: `${match[1]}("${resolved}")`, + }); + } + } + for (const { start, end, replacement } of dynamicReplacements.reverse()) { + newContent = newContent.slice(0, start) + replacement + newContent.slice(end); + } + + if (content !== newContent) { + await fs.writeFile(file, newContent, "utf8"); + return true; + } + return false; +} + +async function renameFiles(files) { + let counter = 0; + for (const file of files) { + const ext = oldExtensions.find((ext) => file.endsWith(ext)); + const newExt = extensionMap[ext]; + + if (newExt) { + const newPath = file.slice(0, -ext.length) + newExt; + await fs.rename(file, newPath); + counter++; + } + } + + console.log(`Renamed ${counter} files.`); +} + +async function main() { + try { + const targetDir = process.argv[2]; + if (!targetDir) { + console.error("Please provide a target directory"); + process.exit(1); + } + + const targetPath = path.resolve(targetDir); + const targetStats = await fs.stat(targetPath); + + if (!targetStats.isDirectory()) { + console.error("The provided path is not a directory"); + process.exit(1); + } + + console.log(`Scanning directory: ${targetDir}`); + + const files = await findFiles(targetDir); + + if (files.length === 0) { + console.log("No matching files found."); + process.exit(0); + } + + console.log(`Found ${files.length} files.`); + await updateFiles(files); + await renameFiles(files); + console.log("\nDone!"); + } catch (error) { + console.error("An error occurred:", error.message); + process.exit(1); + } +} + +main(); diff --git a/src/BaseClient.ts b/src/BaseClient.ts new file mode 100644 index 0000000..0b1d6ef --- /dev/null +++ b/src/BaseClient.ts @@ -0,0 +1,115 @@ +// This file was auto-generated by Fern from our API Definition. + +import { BearerAuthProvider } from "./auth/BearerAuthProvider.js"; +import { mergeHeaders } from "./core/headers.js"; +import * as core from "./core/index.js"; + +export type AuthOption = + | false + | core.AuthProvider["getAuthRequest"] + | core.AuthProvider + | BearerAuthProvider.AuthOptions; + +export type BaseClientOptions = { + environment: core.Supplier; + /** Specify a custom URL to connect the client to. */ + baseUrl?: core.Supplier; + /** Additional headers to include in requests. */ + headers?: Record | null | undefined>; + /** The default maximum time to wait for a response in seconds. */ + timeoutInSeconds?: number; + /** The default number of times to retry the request. Defaults to 2. */ + maxRetries?: number; + /** Provide a custom fetch implementation. Useful for platforms that don't have a built-in fetch or need a custom implementation. */ + fetch?: typeof fetch; + /** Configure logging for the client. */ + logging?: core.logging.LogConfig | core.logging.Logger; + /** Default options for SSE stream reconnection behavior. Has no effect on non-resumable endpoints. */ + stream?: { reconnectionEnabled?: boolean; maxReconnectionAttempts?: number }; + /** Override auth. Pass false to disable, a function returning auth headers, an AuthProvider, or auth options. */ + auth?: AuthOption; +} & BearerAuthProvider.AuthOptions; + +export interface BaseRequestOptions { + /** The maximum time to wait for a response in seconds. */ + timeoutInSeconds?: number; + /** The number of times to retry the request. Defaults to 2. */ + maxRetries?: number; + /** A hook to abort the request. */ + abortSignal?: AbortSignal; + /** Additional query string parameters to include in the request. */ + queryParams?: Record; + /** A dictionary containing additional parameters to spread into the request's body. */ + additionalBodyParameters?: Record; + /** Additional headers to include in the request. */ + headers?: Record | null | undefined>; + /** Options for SSE stream reconnection behavior. Has no effect on non-resumable endpoints. */ + stream?: { reconnectionEnabled?: boolean; maxReconnectionAttempts?: number }; +} + +export type NormalizedClientOptions = T & { + logging: core.logging.Logger; + authProvider?: core.AuthProvider; +}; + +export type NormalizedClientOptionsWithAuth = + NormalizedClientOptions & { + authProvider: core.AuthProvider; + }; + +export function normalizeClientOptions( + options: T, +): NormalizedClientOptions { + const headers = mergeHeaders( + { + "X-Fern-Language": "JavaScript", + "X-Fern-SDK-Name": "@cloudpdf/sdk", + "X-Fern-SDK-Version": "3.0.0-next.1", + "User-Agent": "@cloudpdf/sdk/3.0.0-next.1", + "X-Fern-Runtime": core.RUNTIME.type, + "X-Fern-Runtime-Version": core.RUNTIME.version, + }, + options?.headers, + ); + + return { + ...options, + logging: core.logging.createLogger(options?.logging), + headers, + } as NormalizedClientOptions; +} + +export function normalizeClientOptionsWithAuth( + options: T, +): NormalizedClientOptionsWithAuth { + const normalized = normalizeClientOptions(options) as NormalizedClientOptionsWithAuth; + + if (options.auth === false) { + normalized.authProvider = new core.NoOpAuthProvider(); + return normalized; + } + if (options.auth != null) { + if (typeof options.auth === "function") { + normalized.authProvider = { getAuthRequest: options.auth }; + return normalized; + } + if (core.isAuthProvider(options.auth)) { + normalized.authProvider = options.auth; + return normalized; + } + Object.assign(normalized, options.auth); + } + + const normalizedWithNoOpAuthProvider = withNoOpAuthProvider(normalized); + normalized.authProvider ??= new BearerAuthProvider(normalizedWithNoOpAuthProvider); + return normalized; +} + +function withNoOpAuthProvider( + options: NormalizedClientOptions, +): NormalizedClientOptionsWithAuth { + return { + ...options, + authProvider: new core.NoOpAuthProvider(), + }; +} diff --git a/src/Client.ts b/src/Client.ts new file mode 100644 index 0000000..696cbe9 --- /dev/null +++ b/src/Client.ts @@ -0,0 +1,80 @@ +// This file was auto-generated by Fern from our API Definition. + +import { DeploymentClient } from "./api/resources/deployment/client/Client.js"; +import { DocClient } from "./api/resources/doc/client/Client.js"; +import { DocumentsClient } from "./api/resources/documents/client/Client.js"; +import { TenantsClient } from "./api/resources/tenants/client/Client.js"; +import { TokensClient } from "./api/resources/tokens/client/Client.js"; +import type { BaseClientOptions, BaseRequestOptions } from "./BaseClient.js"; +import { type NormalizedClientOptionsWithAuth, normalizeClientOptionsWithAuth } from "./BaseClient.js"; +import * as core from "./core/index.js"; + +export declare namespace CloudpdfApiClient { + export type Options = BaseClientOptions; + + export interface RequestOptions extends BaseRequestOptions {} +} + +export class CloudpdfApiClient { + protected readonly _options: NormalizedClientOptionsWithAuth; + protected _deployment: DeploymentClient | undefined; + protected _doc: DocClient | undefined; + protected _tenants: TenantsClient | undefined; + protected _documents: DocumentsClient | undefined; + protected _tokens: TokensClient | undefined; + + constructor(options: CloudpdfApiClient.Options) { + this._options = normalizeClientOptionsWithAuth(options); + } + + public get deployment(): DeploymentClient { + return (this._deployment ??= new DeploymentClient(this._options)); + } + + public get doc(): DocClient { + return (this._doc ??= new DocClient(this._options)); + } + + public get tenants(): TenantsClient { + return (this._tenants ??= new TenantsClient(this._options)); + } + + public get documents(): DocumentsClient { + return (this._documents ??= new DocumentsClient(this._options)); + } + + public get tokens(): TokensClient { + return (this._tokens ??= new TokensClient(this._options)); + } + + /** + * Make a passthrough request using the SDK's configured auth, retry, logging, etc. + * This is useful for making requests to endpoints not yet supported in the SDK. + * The input can be a URL string, URL object, or Request object. Relative paths are resolved against the configured base URL. + * + * @param {Request | string | URL} input - The URL, path, or Request object. + * @param {RequestInit} init - Standard fetch RequestInit options. + * @param {core.PassthroughRequest.RequestOptions} requestOptions - Per-request overrides (timeout, retries, headers, abort signal). + * @returns {Promise} A standard Response object. + */ + public async fetch( + input: Request | string | URL, + init?: RequestInit, + requestOptions?: core.PassthroughRequest.RequestOptions, + ): Promise { + return core.makePassthroughRequest( + input, + init, + { + baseUrl: this._options.baseUrl ?? this._options.environment, + headers: this._options.headers, + timeoutInSeconds: this._options.timeoutInSeconds, + maxRetries: this._options.maxRetries, + fetch: this._options.fetch, + logging: this._options.logging, + getAuthHeaders: async () => (await this._options.authProvider.getAuthRequest()).headers, + }, + requestOptions, + ); + } +} diff --git a/src/api/errors/BadRequestError.ts b/src/api/errors/BadRequestError.ts new file mode 100644 index 0000000..017c985 --- /dev/null +++ b/src/api/errors/BadRequestError.ts @@ -0,0 +1,21 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as core from "../../core/index.js"; +import * as errors from "../../errors/index.js"; + +export class BadRequestError extends errors.CloudpdfApiError { + constructor(body?: unknown, rawResponse?: core.RawResponse) { + super({ + message: "BadRequestError", + statusCode: 400, + body: body, + rawResponse: rawResponse, + }); + Object.setPrototypeOf(this, new.target.prototype); + if (Error.captureStackTrace) { + Error.captureStackTrace(this, this.constructor); + } + + this.name = "BadRequestError"; + } +} diff --git a/src/api/errors/ForbiddenError.ts b/src/api/errors/ForbiddenError.ts new file mode 100644 index 0000000..3df644d --- /dev/null +++ b/src/api/errors/ForbiddenError.ts @@ -0,0 +1,21 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as core from "../../core/index.js"; +import * as errors from "../../errors/index.js"; + +export class ForbiddenError extends errors.CloudpdfApiError { + constructor(body?: unknown, rawResponse?: core.RawResponse) { + super({ + message: "ForbiddenError", + statusCode: 403, + body: body, + rawResponse: rawResponse, + }); + Object.setPrototypeOf(this, new.target.prototype); + if (Error.captureStackTrace) { + Error.captureStackTrace(this, this.constructor); + } + + this.name = "ForbiddenError"; + } +} diff --git a/src/api/errors/NotFoundError.ts b/src/api/errors/NotFoundError.ts new file mode 100644 index 0000000..a573c42 --- /dev/null +++ b/src/api/errors/NotFoundError.ts @@ -0,0 +1,21 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as core from "../../core/index.js"; +import * as errors from "../../errors/index.js"; + +export class NotFoundError extends errors.CloudpdfApiError { + constructor(body?: unknown, rawResponse?: core.RawResponse) { + super({ + message: "NotFoundError", + statusCode: 404, + body: body, + rawResponse: rawResponse, + }); + Object.setPrototypeOf(this, new.target.prototype); + if (Error.captureStackTrace) { + Error.captureStackTrace(this, this.constructor); + } + + this.name = "NotFoundError"; + } +} diff --git a/src/api/errors/index.ts b/src/api/errors/index.ts new file mode 100644 index 0000000..1101820 --- /dev/null +++ b/src/api/errors/index.ts @@ -0,0 +1,3 @@ +export * from "./BadRequestError.js"; +export * from "./ForbiddenError.js"; +export * from "./NotFoundError.js"; diff --git a/src/api/index.ts b/src/api/index.ts new file mode 100644 index 0000000..6ed44b0 --- /dev/null +++ b/src/api/index.ts @@ -0,0 +1,3 @@ +export * from "./errors/index.js"; +export * from "./resources/index.js"; +export * from "./types/index.js"; diff --git a/src/api/resources/deployment/client/Client.ts b/src/api/resources/deployment/client/Client.ts new file mode 100644 index 0000000..b00d20d --- /dev/null +++ b/src/api/resources/deployment/client/Client.ts @@ -0,0 +1,80 @@ +// This file was auto-generated by Fern from our API Definition. + +import type { BaseClientOptions, BaseRequestOptions } from "../../../../BaseClient.js"; +import { type NormalizedClientOptionsWithAuth, normalizeClientOptionsWithAuth } from "../../../../BaseClient.js"; +import { mergeHeaders } from "../../../../core/headers.js"; +import * as core from "../../../../core/index.js"; +import { handleNonStatusCodeError } from "../../../../errors/handleNonStatusCodeError.js"; +import * as errors from "../../../../errors/index.js"; +import type * as CloudpdfApi from "../../../index.js"; + +export declare namespace DeploymentClient { + export type Options = BaseClientOptions; + + export interface RequestOptions extends BaseRequestOptions {} +} + +export class DeploymentClient { + protected readonly _options: NormalizedClientOptionsWithAuth; + + constructor(options: DeploymentClient.Options) { + this._options = normalizeClientOptionsWithAuth(options); + } + + /** + * @param {DeploymentClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link errors.CloudpdfApiError} + * @throws {@link errors.CloudpdfApiTimeoutError} + * + * @example + * await client.deployment.licenseStatus() + */ + public licenseStatus( + requestOptions?: DeploymentClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__licenseStatus(requestOptions)); + } + + private async __licenseStatus( + requestOptions?: DeploymentClient.RequestOptions, + ): Promise> { + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + requestOptions?.headers, + ); + const _response = await core.fetcher({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)), + "v1/deployment/license/status", + ), + method: "GET", + headers: _headers, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, + }); + if (_response.ok) { + return { + data: _response.body as CloudpdfApi.DeploymentLicenseStatusResponse, + rawResponse: _response.rawResponse, + }; + } + + if (_response.error.reason === "status-code") { + throw new errors.CloudpdfApiError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + + return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/deployment/license/status"); + } +} diff --git a/src/api/resources/deployment/client/index.ts b/src/api/resources/deployment/client/index.ts new file mode 100644 index 0000000..cb0ff5c --- /dev/null +++ b/src/api/resources/deployment/client/index.ts @@ -0,0 +1 @@ +export {}; diff --git a/src/api/resources/deployment/exports.ts b/src/api/resources/deployment/exports.ts new file mode 100644 index 0000000..8f51426 --- /dev/null +++ b/src/api/resources/deployment/exports.ts @@ -0,0 +1,4 @@ +// This file was auto-generated by Fern from our API Definition. + +export { DeploymentClient } from "./client/Client.js"; +export * from "./client/index.js"; diff --git a/src/api/resources/deployment/index.ts b/src/api/resources/deployment/index.ts new file mode 100644 index 0000000..914b8c3 --- /dev/null +++ b/src/api/resources/deployment/index.ts @@ -0,0 +1 @@ +export * from "./client/index.js"; diff --git a/src/api/resources/doc/client/Client.ts b/src/api/resources/doc/client/Client.ts new file mode 100644 index 0000000..9fd6372 --- /dev/null +++ b/src/api/resources/doc/client/Client.ts @@ -0,0 +1,399 @@ +// This file was auto-generated by Fern from our API Definition. + +import type { BaseClientOptions, BaseRequestOptions } from "../../../../BaseClient.js"; +import { type NormalizedClientOptionsWithAuth, normalizeClientOptionsWithAuth } from "../../../../BaseClient.js"; +import { mergeHeaders, mergeOnlyDefinedHeaders } from "../../../../core/headers.js"; +import * as core from "../../../../core/index.js"; +import { handleNonStatusCodeError } from "../../../../errors/handleNonStatusCodeError.js"; +import * as errors from "../../../../errors/index.js"; +import * as CloudpdfApi from "../../../index.js"; +import { AnnotationsClient } from "../resources/annotations/client/Client.js"; +import { FormsClient } from "../resources/forms/client/Client.js"; +import { MetadataClient } from "../resources/metadata/client/Client.js"; +import { PagesClient } from "../resources/pages/client/Client.js"; +import { RedactionsClient } from "../resources/redactions/client/Client.js"; + +export declare namespace DocClient { + export type Options = BaseClientOptions; + + export interface RequestOptions extends BaseRequestOptions {} +} + +export class DocClient { + protected readonly _options: NormalizedClientOptionsWithAuth; + protected _annotations: AnnotationsClient | undefined; + protected _forms: FormsClient | undefined; + protected _metadata: MetadataClient | undefined; + protected _pages: PagesClient | undefined; + protected _redactions: RedactionsClient | undefined; + + constructor(options: DocClient.Options) { + this._options = normalizeClientOptionsWithAuth(options); + } + + public get annotations(): AnnotationsClient { + return (this._annotations ??= new AnnotationsClient(this._options)); + } + + public get forms(): FormsClient { + return (this._forms ??= new FormsClient(this._options)); + } + + public get metadata(): MetadataClient { + return (this._metadata ??= new MetadataClient(this._options)); + } + + public get pages(): PagesClient { + return (this._pages ??= new PagesClient(this._options)); + } + + public get redactions(): RedactionsClient { + return (this._redactions ??= new RedactionsClient(this._options)); + } + + /** + * @param {CloudpdfApi.HeadDocRequest} request + * @param {DocClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link CloudpdfApi.NotFoundError} + * @throws {@link errors.CloudpdfApiError} + * @throws {@link errors.CloudpdfApiTimeoutError} + * + * @example + * await client.doc.head({ + * docId: "docId" + * }) + */ + public head( + request: CloudpdfApi.HeadDocRequest, + requestOptions?: DocClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__head(request, requestOptions)); + } + + private async __head( + request: CloudpdfApi.HeadDocRequest, + requestOptions?: DocClient.RequestOptions, + ): Promise> { + const { docId, "X-Document-Password": documentPassword } = request; + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + mergeOnlyDefinedHeaders({ "X-Document-Password": documentPassword }), + requestOptions?.headers, + ); + const _response = await core.fetcher({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)), + `v1/docs/${core.url.encodePathParam(docId)}/head`, + ), + method: "GET", + headers: _headers, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, + }); + if (_response.ok) { + return { data: _response.body as CloudpdfApi.DocHead200Response, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 404: + throw new CloudpdfApi.NotFoundError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.CloudpdfApiError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/docs/{docId}/head"); + } + + /** + * @throws {@link CloudpdfApi.NotFoundError} + * @throws {@link errors.CloudpdfApiError} + * @throws {@link errors.CloudpdfApiTimeoutError} + */ + public download( + request: CloudpdfApi.DownloadDocRequest, + requestOptions?: DocClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__download(request, requestOptions)); + } + + private async __download( + request: CloudpdfApi.DownloadDocRequest, + requestOptions?: DocClient.RequestOptions, + ): Promise> { + const { docId, layerName, "X-Document-Password": documentPassword } = request; + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + mergeOnlyDefinedHeaders({ "X-Document-Password": documentPassword }), + requestOptions?.headers, + ); + const _response = await core.fetcher({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)), + `v1/docs/${core.url.encodePathParam(docId)}/layers/${core.url.encodePathParam(layerName)}/download`, + ), + method: "GET", + headers: _headers, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), + responseType: "binary-response", + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, + }); + if (_response.ok) { + return { data: _response.body, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 404: + throw new CloudpdfApi.NotFoundError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.CloudpdfApiError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + return handleNonStatusCodeError( + _response.error, + _response.rawResponse, + "GET", + "/v1/docs/{docId}/layers/{layerName}/download", + ); + } + + /** + * @param {CloudpdfApi.ManifestDocRequest} request + * @param {DocClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link CloudpdfApi.NotFoundError} + * @throws {@link errors.CloudpdfApiError} + * @throws {@link errors.CloudpdfApiTimeoutError} + * + * @example + * await client.doc.manifest({ + * docId: "docId", + * layerName: "layerName" + * }) + */ + public manifest( + request: CloudpdfApi.ManifestDocRequest, + requestOptions?: DocClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__manifest(request, requestOptions)); + } + + private async __manifest( + request: CloudpdfApi.ManifestDocRequest, + requestOptions?: DocClient.RequestOptions, + ): Promise> { + const { docId, layerName, "X-Document-Password": documentPassword } = request; + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + mergeOnlyDefinedHeaders({ "X-Document-Password": documentPassword }), + requestOptions?.headers, + ); + const _response = await core.fetcher({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)), + `v1/docs/${core.url.encodePathParam(docId)}/layers/${core.url.encodePathParam(layerName)}/manifest`, + ), + method: "GET", + headers: _headers, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, + }); + if (_response.ok) { + return { data: _response.body as CloudpdfApi.DocManifest200Response, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 404: + throw new CloudpdfApi.NotFoundError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.CloudpdfApiError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + return handleNonStatusCodeError( + _response.error, + _response.rawResponse, + "GET", + "/v1/docs/{docId}/layers/{layerName}/manifest", + ); + } + + /** + * Render parameters (viewport, format) pass as flat dotted query keys, e.g. `?viewport.kind=width&viewport.width=800`; the full grammar is documented with the viewer. + * + * @throws {@link CloudpdfApi.NotFoundError} + * @throws {@link errors.CloudpdfApiError} + * @throws {@link errors.CloudpdfApiTimeoutError} + */ + public render( + request: CloudpdfApi.RenderDocRequest, + requestOptions?: DocClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__render(request, requestOptions)); + } + + private async __render( + request: CloudpdfApi.RenderDocRequest, + requestOptions?: DocClient.RequestOptions, + ): Promise> { + const { docId, layerName, pon, "X-Document-Password": documentPassword } = request; + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + mergeOnlyDefinedHeaders({ "X-Document-Password": documentPassword }), + requestOptions?.headers, + ); + const _response = await core.fetcher({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)), + `v1/docs/${core.url.encodePathParam(docId)}/layers/${core.url.encodePathParam(layerName)}/render/pages/${core.url.encodePathParam(pon)}/data`, + ), + method: "GET", + headers: _headers, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), + responseType: "binary-response", + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, + }); + if (_response.ok) { + return { data: _response.body, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 404: + throw new CloudpdfApi.NotFoundError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.CloudpdfApiError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + return handleNonStatusCodeError( + _response.error, + _response.rawResponse, + "GET", + "/v1/docs/{docId}/layers/{layerName}/render/pages/{pon}/data", + ); + } + + /** + * @param {CloudpdfApi.TextDocRequest} request + * @param {DocClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link CloudpdfApi.NotFoundError} + * @throws {@link errors.CloudpdfApiError} + * @throws {@link errors.CloudpdfApiTimeoutError} + * + * @example + * await client.doc.text({ + * docId: "docId", + * layerName: "layerName", + * pon: 1 + * }) + */ + public text( + request: CloudpdfApi.TextDocRequest, + requestOptions?: DocClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__text(request, requestOptions)); + } + + private async __text( + request: CloudpdfApi.TextDocRequest, + requestOptions?: DocClient.RequestOptions, + ): Promise> { + const { docId, layerName, pon, "X-Document-Password": documentPassword } = request; + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + mergeOnlyDefinedHeaders({ "X-Document-Password": documentPassword }), + requestOptions?.headers, + ); + const _response = await core.fetcher({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)), + `v1/docs/${core.url.encodePathParam(docId)}/layers/${core.url.encodePathParam(layerName)}/text/pages/${core.url.encodePathParam(pon)}/data`, + ), + method: "GET", + headers: _headers, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, + }); + if (_response.ok) { + return { data: _response.body as CloudpdfApi.DocText200Response, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 404: + throw new CloudpdfApi.NotFoundError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.CloudpdfApiError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + return handleNonStatusCodeError( + _response.error, + _response.rawResponse, + "GET", + "/v1/docs/{docId}/layers/{layerName}/text/pages/{pon}/data", + ); + } +} diff --git a/src/api/resources/doc/client/index.ts b/src/api/resources/doc/client/index.ts new file mode 100644 index 0000000..195f9aa --- /dev/null +++ b/src/api/resources/doc/client/index.ts @@ -0,0 +1 @@ +export * from "./requests/index.js"; diff --git a/src/api/resources/doc/client/requests/DownloadDocRequest.ts b/src/api/resources/doc/client/requests/DownloadDocRequest.ts new file mode 100644 index 0000000..45e61e0 --- /dev/null +++ b/src/api/resources/doc/client/requests/DownloadDocRequest.ts @@ -0,0 +1,15 @@ +// This file was auto-generated by Fern from our API Definition. + +/** + * @example + * { + * docId: "docId", + * layerName: "layerName" + * } + */ +export interface DownloadDocRequest { + docId: string; + layerName: string; + /** Base64-encoded password for an encrypted document. Valid only with the API token (403 anywhere else). An encrypted document answers 422 DocPasswordRequired when the header is absent. Viewer doc JWTs use the SDK password-session flow instead. */ + "X-Document-Password"?: string; +} diff --git a/src/api/resources/doc/client/requests/HeadDocRequest.ts b/src/api/resources/doc/client/requests/HeadDocRequest.ts new file mode 100644 index 0000000..d9910f6 --- /dev/null +++ b/src/api/resources/doc/client/requests/HeadDocRequest.ts @@ -0,0 +1,13 @@ +// This file was auto-generated by Fern from our API Definition. + +/** + * @example + * { + * docId: "docId" + * } + */ +export interface HeadDocRequest { + docId: string; + /** Base64-encoded password for an encrypted document. Valid only with the API token (403 anywhere else). An encrypted document answers 422 DocPasswordRequired when the header is absent. Viewer doc JWTs use the SDK password-session flow instead. */ + "X-Document-Password"?: string; +} diff --git a/src/api/resources/doc/client/requests/ManifestDocRequest.ts b/src/api/resources/doc/client/requests/ManifestDocRequest.ts new file mode 100644 index 0000000..b8e77e0 --- /dev/null +++ b/src/api/resources/doc/client/requests/ManifestDocRequest.ts @@ -0,0 +1,15 @@ +// This file was auto-generated by Fern from our API Definition. + +/** + * @example + * { + * docId: "docId", + * layerName: "layerName" + * } + */ +export interface ManifestDocRequest { + docId: string; + layerName: string; + /** Base64-encoded password for an encrypted document. Valid only with the API token (403 anywhere else). An encrypted document answers 422 DocPasswordRequired when the header is absent. Viewer doc JWTs use the SDK password-session flow instead. */ + "X-Document-Password"?: string; +} diff --git a/src/api/resources/doc/client/requests/RenderDocRequest.ts b/src/api/resources/doc/client/requests/RenderDocRequest.ts new file mode 100644 index 0000000..6d49e8c --- /dev/null +++ b/src/api/resources/doc/client/requests/RenderDocRequest.ts @@ -0,0 +1,17 @@ +// This file was auto-generated by Fern from our API Definition. + +/** + * @example + * { + * docId: "docId", + * layerName: "layerName", + * pon: 1 + * } + */ +export interface RenderDocRequest { + docId: string; + layerName: string; + pon: number; + /** Base64-encoded password for an encrypted document. Valid only with the API token (403 anywhere else). An encrypted document answers 422 DocPasswordRequired when the header is absent. Viewer doc JWTs use the SDK password-session flow instead. */ + "X-Document-Password"?: string; +} diff --git a/src/api/resources/doc/client/requests/TextDocRequest.ts b/src/api/resources/doc/client/requests/TextDocRequest.ts new file mode 100644 index 0000000..83f2944 --- /dev/null +++ b/src/api/resources/doc/client/requests/TextDocRequest.ts @@ -0,0 +1,17 @@ +// This file was auto-generated by Fern from our API Definition. + +/** + * @example + * { + * docId: "docId", + * layerName: "layerName", + * pon: 1 + * } + */ +export interface TextDocRequest { + docId: string; + layerName: string; + pon: number; + /** Base64-encoded password for an encrypted document. Valid only with the API token (403 anywhere else). An encrypted document answers 422 DocPasswordRequired when the header is absent. Viewer doc JWTs use the SDK password-session flow instead. */ + "X-Document-Password"?: string; +} diff --git a/src/api/resources/doc/client/requests/index.ts b/src/api/resources/doc/client/requests/index.ts new file mode 100644 index 0000000..14d546c --- /dev/null +++ b/src/api/resources/doc/client/requests/index.ts @@ -0,0 +1,5 @@ +export type { DownloadDocRequest } from "./DownloadDocRequest.js"; +export type { HeadDocRequest } from "./HeadDocRequest.js"; +export type { ManifestDocRequest } from "./ManifestDocRequest.js"; +export type { RenderDocRequest } from "./RenderDocRequest.js"; +export type { TextDocRequest } from "./TextDocRequest.js"; diff --git a/src/api/resources/doc/exports.ts b/src/api/resources/doc/exports.ts new file mode 100644 index 0000000..73ea934 --- /dev/null +++ b/src/api/resources/doc/exports.ts @@ -0,0 +1,5 @@ +// This file was auto-generated by Fern from our API Definition. + +export { DocClient } from "./client/Client.js"; +export * from "./client/index.js"; +export * from "./resources/index.js"; diff --git a/src/api/resources/doc/index.ts b/src/api/resources/doc/index.ts new file mode 100644 index 0000000..9eb1192 --- /dev/null +++ b/src/api/resources/doc/index.ts @@ -0,0 +1,2 @@ +export * from "./client/index.js"; +export * from "./resources/index.js"; diff --git a/src/api/resources/doc/resources/annotations/client/Client.ts b/src/api/resources/doc/resources/annotations/client/Client.ts new file mode 100644 index 0000000..3896184 --- /dev/null +++ b/src/api/resources/doc/resources/annotations/client/Client.ts @@ -0,0 +1,354 @@ +// This file was auto-generated by Fern from our API Definition. + +import type { BaseClientOptions, BaseRequestOptions } from "../../../../../../BaseClient.js"; +import { type NormalizedClientOptionsWithAuth, normalizeClientOptionsWithAuth } from "../../../../../../BaseClient.js"; +import { mergeHeaders, mergeOnlyDefinedHeaders } from "../../../../../../core/headers.js"; +import * as core from "../../../../../../core/index.js"; +import { mergeAdditionalBodyParameters } from "../../../../../../core/requestBody.js"; +import { handleNonStatusCodeError } from "../../../../../../errors/handleNonStatusCodeError.js"; +import * as errors from "../../../../../../errors/index.js"; +import * as CloudpdfApi from "../../../../../index.js"; + +export declare namespace AnnotationsClient { + export type Options = BaseClientOptions; + + export interface RequestOptions extends BaseRequestOptions {} +} + +export class AnnotationsClient { + protected readonly _options: NormalizedClientOptionsWithAuth; + + constructor(options: AnnotationsClient.Options) { + this._options = normalizeClientOptionsWithAuth(options); + } + + /** + * @param {CloudpdfApi.doc.ListAnnotationsRequest} request + * @param {AnnotationsClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link CloudpdfApi.NotFoundError} + * @throws {@link errors.CloudpdfApiError} + * @throws {@link errors.CloudpdfApiTimeoutError} + * + * @example + * await client.doc.annotations.list({ + * docId: "docId", + * layerName: "layerName", + * pon: 1 + * }) + */ + public list( + request: CloudpdfApi.doc.ListAnnotationsRequest, + requestOptions?: AnnotationsClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__list(request, requestOptions)); + } + + private async __list( + request: CloudpdfApi.doc.ListAnnotationsRequest, + requestOptions?: AnnotationsClient.RequestOptions, + ): Promise> { + const { docId, layerName, pon, "X-Document-Password": documentPassword } = request; + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + mergeOnlyDefinedHeaders({ "X-Document-Password": documentPassword }), + requestOptions?.headers, + ); + const _response = await core.fetcher({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)), + `v1/docs/${core.url.encodePathParam(docId)}/layers/${core.url.encodePathParam(layerName)}/annotations/pages/${core.url.encodePathParam(pon)}/items`, + ), + method: "GET", + headers: _headers, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, + }); + if (_response.ok) { + return { + data: _response.body as CloudpdfApi.DocAnnotationsList200Response, + rawResponse: _response.rawResponse, + }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 404: + throw new CloudpdfApi.NotFoundError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.CloudpdfApiError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + return handleNonStatusCodeError( + _response.error, + _response.rawResponse, + "GET", + "/v1/docs/{docId}/layers/{layerName}/annotations/pages/{pon}/items", + ); + } + + /** + * Doc JWTs may instead carry collab scopes (annotations:create:self, …) that refine per-annotation authorship rules; the API token is exempt from both. + * + * @param {CloudpdfApi.doc.CreateAnnotationsRequest} request + * @param {AnnotationsClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link CloudpdfApi.BadRequestError} + * @throws {@link CloudpdfApi.NotFoundError} + * @throws {@link errors.CloudpdfApiError} + * @throws {@link errors.CloudpdfApiTimeoutError} + * + * @example + * await client.doc.annotations.create({ + * docId: "docId", + * layerName: "layerName", + * pon: 1, + * body: { + * "key": "value" + * } + * }) + */ + public create( + request: CloudpdfApi.doc.CreateAnnotationsRequest, + requestOptions?: AnnotationsClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__create(request, requestOptions)); + } + + private async __create( + request: CloudpdfApi.doc.CreateAnnotationsRequest, + requestOptions?: AnnotationsClient.RequestOptions, + ): Promise> { + const { docId, layerName, pon, "X-Document-Password": documentPassword, body: _body } = request; + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + mergeOnlyDefinedHeaders({ "X-Document-Password": documentPassword }), + requestOptions?.headers, + ); + const _response = await core.fetcher({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)), + `v1/docs/${core.url.encodePathParam(docId)}/layers/${core.url.encodePathParam(layerName)}/annotations/pages/${core.url.encodePathParam(pon)}/items`, + ), + method: "POST", + headers: _headers, + contentType: "application/json", + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), + requestType: "json", + body: mergeAdditionalBodyParameters(_body, requestOptions?.additionalBodyParameters), + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, + }); + if (_response.ok) { + return { + data: _response.body as CloudpdfApi.DocAnnotationsCreate200Response, + rawResponse: _response.rawResponse, + }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new CloudpdfApi.BadRequestError(_response.error.body as unknown, _response.rawResponse); + case 404: + throw new CloudpdfApi.NotFoundError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.CloudpdfApiError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + return handleNonStatusCodeError( + _response.error, + _response.rawResponse, + "POST", + "/v1/docs/{docId}/layers/{layerName}/annotations/pages/{pon}/items", + ); + } + + /** + * @param {CloudpdfApi.doc.DeleteAnnotationsRequest} request + * @param {AnnotationsClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link CloudpdfApi.NotFoundError} + * @throws {@link errors.CloudpdfApiError} + * @throws {@link errors.CloudpdfApiTimeoutError} + * + * @example + * await client.doc.annotations.delete({ + * docId: "docId", + * layerName: "layerName", + * pon: 1, + * annotKey: "annotKey" + * }) + */ + public delete( + request: CloudpdfApi.doc.DeleteAnnotationsRequest, + requestOptions?: AnnotationsClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__delete(request, requestOptions)); + } + + private async __delete( + request: CloudpdfApi.doc.DeleteAnnotationsRequest, + requestOptions?: AnnotationsClient.RequestOptions, + ): Promise> { + const { docId, layerName, pon, annotKey, "X-Document-Password": documentPassword } = request; + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + mergeOnlyDefinedHeaders({ "X-Document-Password": documentPassword }), + requestOptions?.headers, + ); + const _response = await core.fetcher({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)), + `v1/docs/${core.url.encodePathParam(docId)}/layers/${core.url.encodePathParam(layerName)}/annotations/pages/${core.url.encodePathParam(pon)}/items/${core.url.encodePathParam(annotKey)}`, + ), + method: "DELETE", + headers: _headers, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, + }); + if (_response.ok) { + return { + data: _response.body as CloudpdfApi.DocAnnotationsDelete200Response, + rawResponse: _response.rawResponse, + }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 404: + throw new CloudpdfApi.NotFoundError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.CloudpdfApiError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + return handleNonStatusCodeError( + _response.error, + _response.rawResponse, + "DELETE", + "/v1/docs/{docId}/layers/{layerName}/annotations/pages/{pon}/items/{annotKey}", + ); + } + + /** + * @param {CloudpdfApi.doc.UpdateAnnotationsRequest} request + * @param {AnnotationsClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link CloudpdfApi.BadRequestError} + * @throws {@link CloudpdfApi.NotFoundError} + * @throws {@link errors.CloudpdfApiError} + * @throws {@link errors.CloudpdfApiTimeoutError} + * + * @example + * await client.doc.annotations.update({ + * docId: "docId", + * layerName: "layerName", + * pon: 1, + * annotKey: "annotKey", + * body: { + * "key": "value" + * } + * }) + */ + public update( + request: CloudpdfApi.doc.UpdateAnnotationsRequest, + requestOptions?: AnnotationsClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__update(request, requestOptions)); + } + + private async __update( + request: CloudpdfApi.doc.UpdateAnnotationsRequest, + requestOptions?: AnnotationsClient.RequestOptions, + ): Promise> { + const { docId, layerName, pon, annotKey, "X-Document-Password": documentPassword, body: _body } = request; + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + mergeOnlyDefinedHeaders({ "X-Document-Password": documentPassword }), + requestOptions?.headers, + ); + const _response = await core.fetcher({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)), + `v1/docs/${core.url.encodePathParam(docId)}/layers/${core.url.encodePathParam(layerName)}/annotations/pages/${core.url.encodePathParam(pon)}/items/${core.url.encodePathParam(annotKey)}`, + ), + method: "PATCH", + headers: _headers, + contentType: "application/json", + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), + requestType: "json", + body: mergeAdditionalBodyParameters(_body, requestOptions?.additionalBodyParameters), + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, + }); + if (_response.ok) { + return { + data: _response.body as CloudpdfApi.DocAnnotationsUpdate200Response, + rawResponse: _response.rawResponse, + }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new CloudpdfApi.BadRequestError(_response.error.body as unknown, _response.rawResponse); + case 404: + throw new CloudpdfApi.NotFoundError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.CloudpdfApiError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + return handleNonStatusCodeError( + _response.error, + _response.rawResponse, + "PATCH", + "/v1/docs/{docId}/layers/{layerName}/annotations/pages/{pon}/items/{annotKey}", + ); + } +} diff --git a/src/api/resources/doc/resources/annotations/client/index.ts b/src/api/resources/doc/resources/annotations/client/index.ts new file mode 100644 index 0000000..195f9aa --- /dev/null +++ b/src/api/resources/doc/resources/annotations/client/index.ts @@ -0,0 +1 @@ +export * from "./requests/index.js"; diff --git a/src/api/resources/doc/resources/annotations/client/requests/CreateAnnotationsRequest.ts b/src/api/resources/doc/resources/annotations/client/requests/CreateAnnotationsRequest.ts new file mode 100644 index 0000000..bced045 --- /dev/null +++ b/src/api/resources/doc/resources/annotations/client/requests/CreateAnnotationsRequest.ts @@ -0,0 +1,23 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../../../../../../index.js"; + +/** + * @example + * { + * docId: "docId", + * layerName: "layerName", + * pon: 1, + * body: { + * "key": "value" + * } + * } + */ +export interface CreateAnnotationsRequest { + docId: string; + layerName: string; + pon: number; + /** Base64-encoded password for an encrypted document. Valid only with the API token (403 anywhere else). An encrypted document answers 422 DocPasswordRequired when the header is absent. Viewer doc JWTs use the SDK password-session flow instead. */ + "X-Document-Password"?: string; + body: CloudpdfApi.DocAnnotationsCreateRequest; +} diff --git a/src/api/resources/doc/resources/annotations/client/requests/DeleteAnnotationsRequest.ts b/src/api/resources/doc/resources/annotations/client/requests/DeleteAnnotationsRequest.ts new file mode 100644 index 0000000..525d0ad --- /dev/null +++ b/src/api/resources/doc/resources/annotations/client/requests/DeleteAnnotationsRequest.ts @@ -0,0 +1,19 @@ +// This file was auto-generated by Fern from our API Definition. + +/** + * @example + * { + * docId: "docId", + * layerName: "layerName", + * pon: 1, + * annotKey: "annotKey" + * } + */ +export interface DeleteAnnotationsRequest { + docId: string; + layerName: string; + pon: number; + annotKey: string; + /** Base64-encoded password for an encrypted document. Valid only with the API token (403 anywhere else). An encrypted document answers 422 DocPasswordRequired when the header is absent. Viewer doc JWTs use the SDK password-session flow instead. */ + "X-Document-Password"?: string; +} diff --git a/src/api/resources/doc/resources/annotations/client/requests/ListAnnotationsRequest.ts b/src/api/resources/doc/resources/annotations/client/requests/ListAnnotationsRequest.ts new file mode 100644 index 0000000..b1d1f16 --- /dev/null +++ b/src/api/resources/doc/resources/annotations/client/requests/ListAnnotationsRequest.ts @@ -0,0 +1,17 @@ +// This file was auto-generated by Fern from our API Definition. + +/** + * @example + * { + * docId: "docId", + * layerName: "layerName", + * pon: 1 + * } + */ +export interface ListAnnotationsRequest { + docId: string; + layerName: string; + pon: number; + /** Base64-encoded password for an encrypted document. Valid only with the API token (403 anywhere else). An encrypted document answers 422 DocPasswordRequired when the header is absent. Viewer doc JWTs use the SDK password-session flow instead. */ + "X-Document-Password"?: string; +} diff --git a/src/api/resources/doc/resources/annotations/client/requests/UpdateAnnotationsRequest.ts b/src/api/resources/doc/resources/annotations/client/requests/UpdateAnnotationsRequest.ts new file mode 100644 index 0000000..26d3f37 --- /dev/null +++ b/src/api/resources/doc/resources/annotations/client/requests/UpdateAnnotationsRequest.ts @@ -0,0 +1,25 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../../../../../../index.js"; + +/** + * @example + * { + * docId: "docId", + * layerName: "layerName", + * pon: 1, + * annotKey: "annotKey", + * body: { + * "key": "value" + * } + * } + */ +export interface UpdateAnnotationsRequest { + docId: string; + layerName: string; + pon: number; + annotKey: string; + /** Base64-encoded password for an encrypted document. Valid only with the API token (403 anywhere else). An encrypted document answers 422 DocPasswordRequired when the header is absent. Viewer doc JWTs use the SDK password-session flow instead. */ + "X-Document-Password"?: string; + body: CloudpdfApi.DocAnnotationsUpdateRequest; +} diff --git a/src/api/resources/doc/resources/annotations/client/requests/index.ts b/src/api/resources/doc/resources/annotations/client/requests/index.ts new file mode 100644 index 0000000..b105733 --- /dev/null +++ b/src/api/resources/doc/resources/annotations/client/requests/index.ts @@ -0,0 +1,4 @@ +export type { CreateAnnotationsRequest } from "./CreateAnnotationsRequest.js"; +export type { DeleteAnnotationsRequest } from "./DeleteAnnotationsRequest.js"; +export type { ListAnnotationsRequest } from "./ListAnnotationsRequest.js"; +export type { UpdateAnnotationsRequest } from "./UpdateAnnotationsRequest.js"; diff --git a/src/api/resources/doc/resources/annotations/exports.ts b/src/api/resources/doc/resources/annotations/exports.ts new file mode 100644 index 0000000..8f7fe44 --- /dev/null +++ b/src/api/resources/doc/resources/annotations/exports.ts @@ -0,0 +1,4 @@ +// This file was auto-generated by Fern from our API Definition. + +export { AnnotationsClient } from "./client/Client.js"; +export * from "./client/index.js"; diff --git a/src/api/resources/doc/resources/annotations/index.ts b/src/api/resources/doc/resources/annotations/index.ts new file mode 100644 index 0000000..914b8c3 --- /dev/null +++ b/src/api/resources/doc/resources/annotations/index.ts @@ -0,0 +1 @@ +export * from "./client/index.js"; diff --git a/src/api/resources/doc/resources/forms/client/Client.ts b/src/api/resources/doc/resources/forms/client/Client.ts new file mode 100644 index 0000000..984b107 --- /dev/null +++ b/src/api/resources/doc/resources/forms/client/Client.ts @@ -0,0 +1,414 @@ +// This file was auto-generated by Fern from our API Definition. + +import type { BaseClientOptions, BaseRequestOptions } from "../../../../../../BaseClient.js"; +import { type NormalizedClientOptionsWithAuth, normalizeClientOptionsWithAuth } from "../../../../../../BaseClient.js"; +import { mergeHeaders, mergeOnlyDefinedHeaders } from "../../../../../../core/headers.js"; +import * as core from "../../../../../../core/index.js"; +import { mergeAdditionalBodyParameters } from "../../../../../../core/requestBody.js"; +import { handleNonStatusCodeError } from "../../../../../../errors/handleNonStatusCodeError.js"; +import * as errors from "../../../../../../errors/index.js"; +import * as CloudpdfApi from "../../../../../index.js"; + +export declare namespace FormsClient { + export type Options = BaseClientOptions; + + export interface RequestOptions extends BaseRequestOptions {} +} + +export class FormsClient { + protected readonly _options: NormalizedClientOptionsWithAuth; + + constructor(options: FormsClient.Options) { + this._options = normalizeClientOptionsWithAuth(options); + } + + /** + * @param {CloudpdfApi.doc.GetFormsRequest} request + * @param {FormsClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link CloudpdfApi.NotFoundError} + * @throws {@link errors.CloudpdfApiError} + * @throws {@link errors.CloudpdfApiTimeoutError} + * + * @example + * await client.doc.forms.get({ + * docId: "docId", + * layerName: "layerName" + * }) + */ + public get( + request: CloudpdfApi.doc.GetFormsRequest, + requestOptions?: FormsClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__get(request, requestOptions)); + } + + private async __get( + request: CloudpdfApi.doc.GetFormsRequest, + requestOptions?: FormsClient.RequestOptions, + ): Promise> { + const { docId, layerName, "X-Document-Password": documentPassword } = request; + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + mergeOnlyDefinedHeaders({ "X-Document-Password": documentPassword }), + requestOptions?.headers, + ); + const _response = await core.fetcher({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)), + `v1/docs/${core.url.encodePathParam(docId)}/layers/${core.url.encodePathParam(layerName)}/form`, + ), + method: "GET", + headers: _headers, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, + }); + if (_response.ok) { + return { data: _response.body as CloudpdfApi.DocFormsGet200Response, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 404: + throw new CloudpdfApi.NotFoundError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.CloudpdfApiError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + return handleNonStatusCodeError( + _response.error, + _response.rawResponse, + "GET", + "/v1/docs/{docId}/layers/{layerName}/form", + ); + } + + /** + * @throws {@link CloudpdfApi.NotFoundError} + * @throws {@link errors.CloudpdfApiError} + * @throws {@link errors.CloudpdfApiTimeoutError} + */ + public exportData( + request: CloudpdfApi.doc.ExportDataFormsRequest, + requestOptions?: FormsClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__exportData(request, requestOptions)); + } + + private async __exportData( + request: CloudpdfApi.doc.ExportDataFormsRequest, + requestOptions?: FormsClient.RequestOptions, + ): Promise> { + const { docId, layerName, format, "X-Document-Password": documentPassword } = request; + const _queryParams: Record = { + format: format != null ? format : undefined, + }; + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + mergeOnlyDefinedHeaders({ "X-Document-Password": documentPassword }), + requestOptions?.headers, + ); + const _response = await core.fetcher({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)), + `v1/docs/${core.url.encodePathParam(docId)}/layers/${core.url.encodePathParam(layerName)}/form/data`, + ), + method: "GET", + headers: _headers, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), + responseType: "binary-response", + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, + }); + if (_response.ok) { + return { data: _response.body, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 404: + throw new CloudpdfApi.NotFoundError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.CloudpdfApiError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + return handleNonStatusCodeError( + _response.error, + _response.rawResponse, + "GET", + "/v1/docs/{docId}/layers/{layerName}/form/data", + ); + } + + /** + * @param {CloudpdfApi.doc.ImportDataFormsRequest} request + * @param {FormsClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link CloudpdfApi.BadRequestError} + * @throws {@link CloudpdfApi.NotFoundError} + * @throws {@link errors.CloudpdfApiError} + * @throws {@link errors.CloudpdfApiTimeoutError} + * + * @example + * await client.doc.forms.importData({ + * docId: "docId", + * layerName: "layerName", + * body: { + * "key": "value" + * } + * }) + */ + public importData( + request: CloudpdfApi.doc.ImportDataFormsRequest, + requestOptions?: FormsClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__importData(request, requestOptions)); + } + + private async __importData( + request: CloudpdfApi.doc.ImportDataFormsRequest, + requestOptions?: FormsClient.RequestOptions, + ): Promise> { + const { docId, layerName, "X-Document-Password": documentPassword, body: _body } = request; + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + mergeOnlyDefinedHeaders({ "X-Document-Password": documentPassword }), + requestOptions?.headers, + ); + const _response = await core.fetcher({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)), + `v1/docs/${core.url.encodePathParam(docId)}/layers/${core.url.encodePathParam(layerName)}/form/data`, + ), + method: "POST", + headers: _headers, + contentType: "application/json", + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), + requestType: "json", + body: mergeAdditionalBodyParameters(_body, requestOptions?.additionalBodyParameters), + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, + }); + if (_response.ok) { + return { + data: _response.body as CloudpdfApi.DocFormsImportData200Response, + rawResponse: _response.rawResponse, + }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new CloudpdfApi.BadRequestError(_response.error.body as unknown, _response.rawResponse); + case 404: + throw new CloudpdfApi.NotFoundError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.CloudpdfApiError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + return handleNonStatusCodeError( + _response.error, + _response.rawResponse, + "POST", + "/v1/docs/{docId}/layers/{layerName}/form/data", + ); + } + + /** + * @param {CloudpdfApi.doc.ResetFormsRequest} request + * @param {FormsClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link CloudpdfApi.NotFoundError} + * @throws {@link errors.CloudpdfApiError} + * @throws {@link errors.CloudpdfApiTimeoutError} + * + * @example + * await client.doc.forms.reset({ + * docId: "docId", + * layerName: "layerName", + * fieldKey: "fieldKey" + * }) + */ + public reset( + request: CloudpdfApi.doc.ResetFormsRequest, + requestOptions?: FormsClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__reset(request, requestOptions)); + } + + private async __reset( + request: CloudpdfApi.doc.ResetFormsRequest, + requestOptions?: FormsClient.RequestOptions, + ): Promise> { + const { docId, layerName, fieldKey, "X-Document-Password": documentPassword } = request; + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + mergeOnlyDefinedHeaders({ "X-Document-Password": documentPassword }), + requestOptions?.headers, + ); + const _response = await core.fetcher({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)), + `v1/docs/${core.url.encodePathParam(docId)}/layers/${core.url.encodePathParam(layerName)}/form/fields/${core.url.encodePathParam(fieldKey)}/reset`, + ), + method: "POST", + headers: _headers, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, + }); + if (_response.ok) { + return { data: _response.body as CloudpdfApi.DocFormsReset200Response, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 404: + throw new CloudpdfApi.NotFoundError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.CloudpdfApiError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + return handleNonStatusCodeError( + _response.error, + _response.rawResponse, + "POST", + "/v1/docs/{docId}/layers/{layerName}/form/fields/{fieldKey}/reset", + ); + } + + /** + * @param {CloudpdfApi.doc.SetValueFormsRequest} request + * @param {FormsClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link CloudpdfApi.BadRequestError} + * @throws {@link CloudpdfApi.NotFoundError} + * @throws {@link errors.CloudpdfApiError} + * @throws {@link errors.CloudpdfApiTimeoutError} + * + * @example + * await client.doc.forms.setValue({ + * docId: "docId", + * layerName: "layerName", + * fieldKey: "fieldKey", + * body: { + * "key": "value" + * } + * }) + */ + public setValue( + request: CloudpdfApi.doc.SetValueFormsRequest, + requestOptions?: FormsClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__setValue(request, requestOptions)); + } + + private async __setValue( + request: CloudpdfApi.doc.SetValueFormsRequest, + requestOptions?: FormsClient.RequestOptions, + ): Promise> { + const { docId, layerName, fieldKey, "X-Document-Password": documentPassword, body: _body } = request; + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + mergeOnlyDefinedHeaders({ "X-Document-Password": documentPassword }), + requestOptions?.headers, + ); + const _response = await core.fetcher({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)), + `v1/docs/${core.url.encodePathParam(docId)}/layers/${core.url.encodePathParam(layerName)}/form/fields/${core.url.encodePathParam(fieldKey)}/value`, + ), + method: "POST", + headers: _headers, + contentType: "application/json", + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), + requestType: "json", + body: mergeAdditionalBodyParameters(_body, requestOptions?.additionalBodyParameters), + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, + }); + if (_response.ok) { + return { + data: _response.body as CloudpdfApi.DocFormsSetValue200Response, + rawResponse: _response.rawResponse, + }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new CloudpdfApi.BadRequestError(_response.error.body as unknown, _response.rawResponse); + case 404: + throw new CloudpdfApi.NotFoundError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.CloudpdfApiError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + return handleNonStatusCodeError( + _response.error, + _response.rawResponse, + "POST", + "/v1/docs/{docId}/layers/{layerName}/form/fields/{fieldKey}/value", + ); + } +} diff --git a/src/api/resources/doc/resources/forms/client/index.ts b/src/api/resources/doc/resources/forms/client/index.ts new file mode 100644 index 0000000..195f9aa --- /dev/null +++ b/src/api/resources/doc/resources/forms/client/index.ts @@ -0,0 +1 @@ +export * from "./requests/index.js"; diff --git a/src/api/resources/doc/resources/forms/client/requests/ExportDataFormsRequest.ts b/src/api/resources/doc/resources/forms/client/requests/ExportDataFormsRequest.ts new file mode 100644 index 0000000..64c315f --- /dev/null +++ b/src/api/resources/doc/resources/forms/client/requests/ExportDataFormsRequest.ts @@ -0,0 +1,18 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../../../../../../index.js"; + +/** + * @example + * { + * docId: "docId", + * layerName: "layerName" + * } + */ +export interface ExportDataFormsRequest { + docId: string; + layerName: string; + format?: CloudpdfApi.doc.ExportDataFormsRequestFormat; + /** Base64-encoded password for an encrypted document. Valid only with the API token (403 anywhere else). An encrypted document answers 422 DocPasswordRequired when the header is absent. Viewer doc JWTs use the SDK password-session flow instead. */ + "X-Document-Password"?: string; +} diff --git a/src/api/resources/doc/resources/forms/client/requests/GetFormsRequest.ts b/src/api/resources/doc/resources/forms/client/requests/GetFormsRequest.ts new file mode 100644 index 0000000..8d6ab7c --- /dev/null +++ b/src/api/resources/doc/resources/forms/client/requests/GetFormsRequest.ts @@ -0,0 +1,15 @@ +// This file was auto-generated by Fern from our API Definition. + +/** + * @example + * { + * docId: "docId", + * layerName: "layerName" + * } + */ +export interface GetFormsRequest { + docId: string; + layerName: string; + /** Base64-encoded password for an encrypted document. Valid only with the API token (403 anywhere else). An encrypted document answers 422 DocPasswordRequired when the header is absent. Viewer doc JWTs use the SDK password-session flow instead. */ + "X-Document-Password"?: string; +} diff --git a/src/api/resources/doc/resources/forms/client/requests/ImportDataFormsRequest.ts b/src/api/resources/doc/resources/forms/client/requests/ImportDataFormsRequest.ts new file mode 100644 index 0000000..d0accab --- /dev/null +++ b/src/api/resources/doc/resources/forms/client/requests/ImportDataFormsRequest.ts @@ -0,0 +1,21 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../../../../../../index.js"; + +/** + * @example + * { + * docId: "docId", + * layerName: "layerName", + * body: { + * "key": "value" + * } + * } + */ +export interface ImportDataFormsRequest { + docId: string; + layerName: string; + /** Base64-encoded password for an encrypted document. Valid only with the API token (403 anywhere else). An encrypted document answers 422 DocPasswordRequired when the header is absent. Viewer doc JWTs use the SDK password-session flow instead. */ + "X-Document-Password"?: string; + body: CloudpdfApi.DocFormsImportDataRequest; +} diff --git a/src/api/resources/doc/resources/forms/client/requests/ResetFormsRequest.ts b/src/api/resources/doc/resources/forms/client/requests/ResetFormsRequest.ts new file mode 100644 index 0000000..65b56ec --- /dev/null +++ b/src/api/resources/doc/resources/forms/client/requests/ResetFormsRequest.ts @@ -0,0 +1,17 @@ +// This file was auto-generated by Fern from our API Definition. + +/** + * @example + * { + * docId: "docId", + * layerName: "layerName", + * fieldKey: "fieldKey" + * } + */ +export interface ResetFormsRequest { + docId: string; + layerName: string; + fieldKey: string; + /** Base64-encoded password for an encrypted document. Valid only with the API token (403 anywhere else). An encrypted document answers 422 DocPasswordRequired when the header is absent. Viewer doc JWTs use the SDK password-session flow instead. */ + "X-Document-Password"?: string; +} diff --git a/src/api/resources/doc/resources/forms/client/requests/SetValueFormsRequest.ts b/src/api/resources/doc/resources/forms/client/requests/SetValueFormsRequest.ts new file mode 100644 index 0000000..633dce5 --- /dev/null +++ b/src/api/resources/doc/resources/forms/client/requests/SetValueFormsRequest.ts @@ -0,0 +1,23 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../../../../../../index.js"; + +/** + * @example + * { + * docId: "docId", + * layerName: "layerName", + * fieldKey: "fieldKey", + * body: { + * "key": "value" + * } + * } + */ +export interface SetValueFormsRequest { + docId: string; + layerName: string; + fieldKey: string; + /** Base64-encoded password for an encrypted document. Valid only with the API token (403 anywhere else). An encrypted document answers 422 DocPasswordRequired when the header is absent. Viewer doc JWTs use the SDK password-session flow instead. */ + "X-Document-Password"?: string; + body: CloudpdfApi.DocFormsSetValueRequest; +} diff --git a/src/api/resources/doc/resources/forms/client/requests/index.ts b/src/api/resources/doc/resources/forms/client/requests/index.ts new file mode 100644 index 0000000..f2b36fd --- /dev/null +++ b/src/api/resources/doc/resources/forms/client/requests/index.ts @@ -0,0 +1,5 @@ +export type { ExportDataFormsRequest } from "./ExportDataFormsRequest.js"; +export type { GetFormsRequest } from "./GetFormsRequest.js"; +export type { ImportDataFormsRequest } from "./ImportDataFormsRequest.js"; +export type { ResetFormsRequest } from "./ResetFormsRequest.js"; +export type { SetValueFormsRequest } from "./SetValueFormsRequest.js"; diff --git a/src/api/resources/doc/resources/forms/exports.ts b/src/api/resources/doc/resources/forms/exports.ts new file mode 100644 index 0000000..0a0bf32 --- /dev/null +++ b/src/api/resources/doc/resources/forms/exports.ts @@ -0,0 +1,4 @@ +// This file was auto-generated by Fern from our API Definition. + +export { FormsClient } from "./client/Client.js"; +export * from "./client/index.js"; diff --git a/src/api/resources/doc/resources/forms/index.ts b/src/api/resources/doc/resources/forms/index.ts new file mode 100644 index 0000000..d9adb1a --- /dev/null +++ b/src/api/resources/doc/resources/forms/index.ts @@ -0,0 +1,2 @@ +export * from "./client/index.js"; +export * from "./types/index.js"; diff --git a/src/api/resources/doc/resources/forms/types/ExportDataFormsRequestFormat.ts b/src/api/resources/doc/resources/forms/types/ExportDataFormsRequestFormat.ts new file mode 100644 index 0000000..49f1d7a --- /dev/null +++ b/src/api/resources/doc/resources/forms/types/ExportDataFormsRequestFormat.ts @@ -0,0 +1,8 @@ +// This file was auto-generated by Fern from our API Definition. + +export const ExportDataFormsRequestFormat = { + Fdf: "fdf", + Xfdf: "xfdf", +} as const; +export type ExportDataFormsRequestFormat = + (typeof ExportDataFormsRequestFormat)[keyof typeof ExportDataFormsRequestFormat]; diff --git a/src/api/resources/doc/resources/forms/types/index.ts b/src/api/resources/doc/resources/forms/types/index.ts new file mode 100644 index 0000000..2c2066f --- /dev/null +++ b/src/api/resources/doc/resources/forms/types/index.ts @@ -0,0 +1 @@ +export * from "./ExportDataFormsRequestFormat.js"; diff --git a/src/api/resources/doc/resources/index.ts b/src/api/resources/doc/resources/index.ts new file mode 100644 index 0000000..6a00fc2 --- /dev/null +++ b/src/api/resources/doc/resources/index.ts @@ -0,0 +1,11 @@ +export * from "./annotations/client/requests/index.js"; +export * as annotations from "./annotations/index.js"; +export * from "./forms/client/requests/index.js"; +export * as forms from "./forms/index.js"; +export * from "./forms/types/index.js"; +export * from "./metadata/client/requests/index.js"; +export * as metadata from "./metadata/index.js"; +export * from "./pages/client/requests/index.js"; +export * as pages from "./pages/index.js"; +export * from "./redactions/client/requests/index.js"; +export * as redactions from "./redactions/index.js"; diff --git a/src/api/resources/doc/resources/metadata/client/Client.ts b/src/api/resources/doc/resources/metadata/client/Client.ts new file mode 100644 index 0000000..6a0ee90 --- /dev/null +++ b/src/api/resources/doc/resources/metadata/client/Client.ts @@ -0,0 +1,99 @@ +// This file was auto-generated by Fern from our API Definition. + +import type { BaseClientOptions, BaseRequestOptions } from "../../../../../../BaseClient.js"; +import { type NormalizedClientOptionsWithAuth, normalizeClientOptionsWithAuth } from "../../../../../../BaseClient.js"; +import { mergeHeaders, mergeOnlyDefinedHeaders } from "../../../../../../core/headers.js"; +import * as core from "../../../../../../core/index.js"; +import { handleNonStatusCodeError } from "../../../../../../errors/handleNonStatusCodeError.js"; +import * as errors from "../../../../../../errors/index.js"; +import * as CloudpdfApi from "../../../../../index.js"; + +export declare namespace MetadataClient { + export type Options = BaseClientOptions; + + export interface RequestOptions extends BaseRequestOptions {} +} + +export class MetadataClient { + protected readonly _options: NormalizedClientOptionsWithAuth; + + constructor(options: MetadataClient.Options) { + this._options = normalizeClientOptionsWithAuth(options); + } + + /** + * @param {CloudpdfApi.doc.GetMetadataRequest} request + * @param {MetadataClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link CloudpdfApi.NotFoundError} + * @throws {@link errors.CloudpdfApiError} + * @throws {@link errors.CloudpdfApiTimeoutError} + * + * @example + * await client.doc.metadata.get({ + * docId: "docId", + * layerName: "layerName" + * }) + */ + public get( + request: CloudpdfApi.doc.GetMetadataRequest, + requestOptions?: MetadataClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__get(request, requestOptions)); + } + + private async __get( + request: CloudpdfApi.doc.GetMetadataRequest, + requestOptions?: MetadataClient.RequestOptions, + ): Promise> { + const { docId, layerName, "X-Document-Password": documentPassword } = request; + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + mergeOnlyDefinedHeaders({ "X-Document-Password": documentPassword }), + requestOptions?.headers, + ); + const _response = await core.fetcher({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)), + `v1/docs/${core.url.encodePathParam(docId)}/layers/${core.url.encodePathParam(layerName)}/metadata`, + ), + method: "GET", + headers: _headers, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, + }); + if (_response.ok) { + return { + data: _response.body as CloudpdfApi.DocMetadataGet200Response, + rawResponse: _response.rawResponse, + }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 404: + throw new CloudpdfApi.NotFoundError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.CloudpdfApiError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + return handleNonStatusCodeError( + _response.error, + _response.rawResponse, + "GET", + "/v1/docs/{docId}/layers/{layerName}/metadata", + ); + } +} diff --git a/src/api/resources/doc/resources/metadata/client/index.ts b/src/api/resources/doc/resources/metadata/client/index.ts new file mode 100644 index 0000000..195f9aa --- /dev/null +++ b/src/api/resources/doc/resources/metadata/client/index.ts @@ -0,0 +1 @@ +export * from "./requests/index.js"; diff --git a/src/api/resources/doc/resources/metadata/client/requests/GetMetadataRequest.ts b/src/api/resources/doc/resources/metadata/client/requests/GetMetadataRequest.ts new file mode 100644 index 0000000..9489cb3 --- /dev/null +++ b/src/api/resources/doc/resources/metadata/client/requests/GetMetadataRequest.ts @@ -0,0 +1,15 @@ +// This file was auto-generated by Fern from our API Definition. + +/** + * @example + * { + * docId: "docId", + * layerName: "layerName" + * } + */ +export interface GetMetadataRequest { + docId: string; + layerName: string; + /** Base64-encoded password for an encrypted document. Valid only with the API token (403 anywhere else). An encrypted document answers 422 DocPasswordRequired when the header is absent. Viewer doc JWTs use the SDK password-session flow instead. */ + "X-Document-Password"?: string; +} diff --git a/src/api/resources/doc/resources/metadata/client/requests/index.ts b/src/api/resources/doc/resources/metadata/client/requests/index.ts new file mode 100644 index 0000000..5fb8da7 --- /dev/null +++ b/src/api/resources/doc/resources/metadata/client/requests/index.ts @@ -0,0 +1 @@ +export type { GetMetadataRequest } from "./GetMetadataRequest.js"; diff --git a/src/api/resources/doc/resources/metadata/exports.ts b/src/api/resources/doc/resources/metadata/exports.ts new file mode 100644 index 0000000..3703ef6 --- /dev/null +++ b/src/api/resources/doc/resources/metadata/exports.ts @@ -0,0 +1,4 @@ +// This file was auto-generated by Fern from our API Definition. + +export { MetadataClient } from "./client/Client.js"; +export * from "./client/index.js"; diff --git a/src/api/resources/doc/resources/metadata/index.ts b/src/api/resources/doc/resources/metadata/index.ts new file mode 100644 index 0000000..914b8c3 --- /dev/null +++ b/src/api/resources/doc/resources/metadata/index.ts @@ -0,0 +1 @@ +export * from "./client/index.js"; diff --git a/src/api/resources/doc/resources/pages/client/Client.ts b/src/api/resources/doc/resources/pages/client/Client.ts new file mode 100644 index 0000000..30f1da8 --- /dev/null +++ b/src/api/resources/doc/resources/pages/client/Client.ts @@ -0,0 +1,361 @@ +// This file was auto-generated by Fern from our API Definition. + +import type { BaseClientOptions, BaseRequestOptions } from "../../../../../../BaseClient.js"; +import { type NormalizedClientOptionsWithAuth, normalizeClientOptionsWithAuth } from "../../../../../../BaseClient.js"; +import { mergeHeaders, mergeOnlyDefinedHeaders } from "../../../../../../core/headers.js"; +import * as core from "../../../../../../core/index.js"; +import { mergeAdditionalBodyParameters } from "../../../../../../core/requestBody.js"; +import { handleNonStatusCodeError } from "../../../../../../errors/handleNonStatusCodeError.js"; +import * as errors from "../../../../../../errors/index.js"; +import * as CloudpdfApi from "../../../../../index.js"; + +export declare namespace PagesClient { + export type Options = BaseClientOptions; + + export interface RequestOptions extends BaseRequestOptions {} +} + +export class PagesClient { + protected readonly _options: NormalizedClientOptionsWithAuth; + + constructor(options: PagesClient.Options) { + this._options = normalizeClientOptionsWithAuth(options); + } + + /** + * @param {CloudpdfApi.doc.DeletePagesRequest} request + * @param {PagesClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link CloudpdfApi.BadRequestError} + * @throws {@link CloudpdfApi.NotFoundError} + * @throws {@link errors.CloudpdfApiError} + * @throws {@link errors.CloudpdfApiTimeoutError} + * + * @example + * await client.doc.pages.delete({ + * docId: "docId", + * layerName: "layerName", + * body: { + * "key": "value" + * } + * }) + */ + public delete( + request: CloudpdfApi.doc.DeletePagesRequest, + requestOptions?: PagesClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__delete(request, requestOptions)); + } + + private async __delete( + request: CloudpdfApi.doc.DeletePagesRequest, + requestOptions?: PagesClient.RequestOptions, + ): Promise> { + const { docId, layerName, "X-Document-Password": documentPassword, body: _body } = request; + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + mergeOnlyDefinedHeaders({ "X-Document-Password": documentPassword }), + requestOptions?.headers, + ); + const _response = await core.fetcher({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)), + `v1/docs/${core.url.encodePathParam(docId)}/layers/${core.url.encodePathParam(layerName)}/pages/delete`, + ), + method: "POST", + headers: _headers, + contentType: "application/json", + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), + requestType: "json", + body: mergeAdditionalBodyParameters(_body, requestOptions?.additionalBodyParameters), + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, + }); + if (_response.ok) { + return { + data: _response.body as CloudpdfApi.DocPagesDelete200Response, + rawResponse: _response.rawResponse, + }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new CloudpdfApi.BadRequestError(_response.error.body as unknown, _response.rawResponse); + case 404: + throw new CloudpdfApi.NotFoundError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.CloudpdfApiError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + return handleNonStatusCodeError( + _response.error, + _response.rawResponse, + "POST", + "/v1/docs/{docId}/layers/{layerName}/pages/delete", + ); + } + + /** + * @param {CloudpdfApi.doc.FlattenPagesRequest} request + * @param {PagesClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link CloudpdfApi.BadRequestError} + * @throws {@link CloudpdfApi.NotFoundError} + * @throws {@link errors.CloudpdfApiError} + * @throws {@link errors.CloudpdfApiTimeoutError} + * + * @example + * await client.doc.pages.flatten({ + * docId: "docId", + * layerName: "layerName", + * body: { + * "key": "value" + * } + * }) + */ + public flatten( + request: CloudpdfApi.doc.FlattenPagesRequest, + requestOptions?: PagesClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__flatten(request, requestOptions)); + } + + private async __flatten( + request: CloudpdfApi.doc.FlattenPagesRequest, + requestOptions?: PagesClient.RequestOptions, + ): Promise> { + const { docId, layerName, "X-Document-Password": documentPassword, body: _body } = request; + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + mergeOnlyDefinedHeaders({ "X-Document-Password": documentPassword }), + requestOptions?.headers, + ); + const _response = await core.fetcher({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)), + `v1/docs/${core.url.encodePathParam(docId)}/layers/${core.url.encodePathParam(layerName)}/pages/flatten`, + ), + method: "POST", + headers: _headers, + contentType: "application/json", + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), + requestType: "json", + body: mergeAdditionalBodyParameters(_body, requestOptions?.additionalBodyParameters), + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, + }); + if (_response.ok) { + return { + data: _response.body as CloudpdfApi.DocPagesFlatten200Response, + rawResponse: _response.rawResponse, + }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new CloudpdfApi.BadRequestError(_response.error.body as unknown, _response.rawResponse); + case 404: + throw new CloudpdfApi.NotFoundError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.CloudpdfApiError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + return handleNonStatusCodeError( + _response.error, + _response.rawResponse, + "POST", + "/v1/docs/{docId}/layers/{layerName}/pages/flatten", + ); + } + + /** + * @param {CloudpdfApi.doc.MovePagesRequest} request + * @param {PagesClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link CloudpdfApi.BadRequestError} + * @throws {@link CloudpdfApi.NotFoundError} + * @throws {@link errors.CloudpdfApiError} + * @throws {@link errors.CloudpdfApiTimeoutError} + * + * @example + * await client.doc.pages.move({ + * docId: "docId", + * layerName: "layerName", + * body: { + * "key": "value" + * } + * }) + */ + public move( + request: CloudpdfApi.doc.MovePagesRequest, + requestOptions?: PagesClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__move(request, requestOptions)); + } + + private async __move( + request: CloudpdfApi.doc.MovePagesRequest, + requestOptions?: PagesClient.RequestOptions, + ): Promise> { + const { docId, layerName, "X-Document-Password": documentPassword, body: _body } = request; + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + mergeOnlyDefinedHeaders({ "X-Document-Password": documentPassword }), + requestOptions?.headers, + ); + const _response = await core.fetcher({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)), + `v1/docs/${core.url.encodePathParam(docId)}/layers/${core.url.encodePathParam(layerName)}/pages/move`, + ), + method: "POST", + headers: _headers, + contentType: "application/json", + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), + requestType: "json", + body: mergeAdditionalBodyParameters(_body, requestOptions?.additionalBodyParameters), + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, + }); + if (_response.ok) { + return { data: _response.body as CloudpdfApi.DocPagesMove200Response, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new CloudpdfApi.BadRequestError(_response.error.body as unknown, _response.rawResponse); + case 404: + throw new CloudpdfApi.NotFoundError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.CloudpdfApiError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + return handleNonStatusCodeError( + _response.error, + _response.rawResponse, + "POST", + "/v1/docs/{docId}/layers/{layerName}/pages/move", + ); + } + + /** + * @param {CloudpdfApi.doc.RotatePagesRequest} request + * @param {PagesClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link CloudpdfApi.BadRequestError} + * @throws {@link CloudpdfApi.NotFoundError} + * @throws {@link errors.CloudpdfApiError} + * @throws {@link errors.CloudpdfApiTimeoutError} + * + * @example + * await client.doc.pages.rotate({ + * docId: "docId", + * layerName: "layerName", + * body: { + * "key": "value" + * } + * }) + */ + public rotate( + request: CloudpdfApi.doc.RotatePagesRequest, + requestOptions?: PagesClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__rotate(request, requestOptions)); + } + + private async __rotate( + request: CloudpdfApi.doc.RotatePagesRequest, + requestOptions?: PagesClient.RequestOptions, + ): Promise> { + const { docId, layerName, "X-Document-Password": documentPassword, body: _body } = request; + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + mergeOnlyDefinedHeaders({ "X-Document-Password": documentPassword }), + requestOptions?.headers, + ); + const _response = await core.fetcher({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)), + `v1/docs/${core.url.encodePathParam(docId)}/layers/${core.url.encodePathParam(layerName)}/pages/rotate`, + ), + method: "POST", + headers: _headers, + contentType: "application/json", + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), + requestType: "json", + body: mergeAdditionalBodyParameters(_body, requestOptions?.additionalBodyParameters), + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, + }); + if (_response.ok) { + return { + data: _response.body as CloudpdfApi.DocPagesRotate200Response, + rawResponse: _response.rawResponse, + }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new CloudpdfApi.BadRequestError(_response.error.body as unknown, _response.rawResponse); + case 404: + throw new CloudpdfApi.NotFoundError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.CloudpdfApiError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + return handleNonStatusCodeError( + _response.error, + _response.rawResponse, + "POST", + "/v1/docs/{docId}/layers/{layerName}/pages/rotate", + ); + } +} diff --git a/src/api/resources/doc/resources/pages/client/index.ts b/src/api/resources/doc/resources/pages/client/index.ts new file mode 100644 index 0000000..195f9aa --- /dev/null +++ b/src/api/resources/doc/resources/pages/client/index.ts @@ -0,0 +1 @@ +export * from "./requests/index.js"; diff --git a/src/api/resources/doc/resources/pages/client/requests/DeletePagesRequest.ts b/src/api/resources/doc/resources/pages/client/requests/DeletePagesRequest.ts new file mode 100644 index 0000000..ee60763 --- /dev/null +++ b/src/api/resources/doc/resources/pages/client/requests/DeletePagesRequest.ts @@ -0,0 +1,21 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../../../../../../index.js"; + +/** + * @example + * { + * docId: "docId", + * layerName: "layerName", + * body: { + * "key": "value" + * } + * } + */ +export interface DeletePagesRequest { + docId: string; + layerName: string; + /** Base64-encoded password for an encrypted document. Valid only with the API token (403 anywhere else). An encrypted document answers 422 DocPasswordRequired when the header is absent. Viewer doc JWTs use the SDK password-session flow instead. */ + "X-Document-Password"?: string; + body: CloudpdfApi.DocPagesDeleteRequest; +} diff --git a/src/api/resources/doc/resources/pages/client/requests/FlattenPagesRequest.ts b/src/api/resources/doc/resources/pages/client/requests/FlattenPagesRequest.ts new file mode 100644 index 0000000..3d643e2 --- /dev/null +++ b/src/api/resources/doc/resources/pages/client/requests/FlattenPagesRequest.ts @@ -0,0 +1,21 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../../../../../../index.js"; + +/** + * @example + * { + * docId: "docId", + * layerName: "layerName", + * body: { + * "key": "value" + * } + * } + */ +export interface FlattenPagesRequest { + docId: string; + layerName: string; + /** Base64-encoded password for an encrypted document. Valid only with the API token (403 anywhere else). An encrypted document answers 422 DocPasswordRequired when the header is absent. Viewer doc JWTs use the SDK password-session flow instead. */ + "X-Document-Password"?: string; + body: CloudpdfApi.DocPagesFlattenRequest; +} diff --git a/src/api/resources/doc/resources/pages/client/requests/MovePagesRequest.ts b/src/api/resources/doc/resources/pages/client/requests/MovePagesRequest.ts new file mode 100644 index 0000000..6e84574 --- /dev/null +++ b/src/api/resources/doc/resources/pages/client/requests/MovePagesRequest.ts @@ -0,0 +1,21 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../../../../../../index.js"; + +/** + * @example + * { + * docId: "docId", + * layerName: "layerName", + * body: { + * "key": "value" + * } + * } + */ +export interface MovePagesRequest { + docId: string; + layerName: string; + /** Base64-encoded password for an encrypted document. Valid only with the API token (403 anywhere else). An encrypted document answers 422 DocPasswordRequired when the header is absent. Viewer doc JWTs use the SDK password-session flow instead. */ + "X-Document-Password"?: string; + body: CloudpdfApi.DocPagesMoveRequest; +} diff --git a/src/api/resources/doc/resources/pages/client/requests/RotatePagesRequest.ts b/src/api/resources/doc/resources/pages/client/requests/RotatePagesRequest.ts new file mode 100644 index 0000000..9571d88 --- /dev/null +++ b/src/api/resources/doc/resources/pages/client/requests/RotatePagesRequest.ts @@ -0,0 +1,21 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../../../../../../index.js"; + +/** + * @example + * { + * docId: "docId", + * layerName: "layerName", + * body: { + * "key": "value" + * } + * } + */ +export interface RotatePagesRequest { + docId: string; + layerName: string; + /** Base64-encoded password for an encrypted document. Valid only with the API token (403 anywhere else). An encrypted document answers 422 DocPasswordRequired when the header is absent. Viewer doc JWTs use the SDK password-session flow instead. */ + "X-Document-Password"?: string; + body: CloudpdfApi.DocPagesRotateRequest; +} diff --git a/src/api/resources/doc/resources/pages/client/requests/index.ts b/src/api/resources/doc/resources/pages/client/requests/index.ts new file mode 100644 index 0000000..10717d3 --- /dev/null +++ b/src/api/resources/doc/resources/pages/client/requests/index.ts @@ -0,0 +1,4 @@ +export type { DeletePagesRequest } from "./DeletePagesRequest.js"; +export type { FlattenPagesRequest } from "./FlattenPagesRequest.js"; +export type { MovePagesRequest } from "./MovePagesRequest.js"; +export type { RotatePagesRequest } from "./RotatePagesRequest.js"; diff --git a/src/api/resources/doc/resources/pages/exports.ts b/src/api/resources/doc/resources/pages/exports.ts new file mode 100644 index 0000000..2422848 --- /dev/null +++ b/src/api/resources/doc/resources/pages/exports.ts @@ -0,0 +1,4 @@ +// This file was auto-generated by Fern from our API Definition. + +export { PagesClient } from "./client/Client.js"; +export * from "./client/index.js"; diff --git a/src/api/resources/doc/resources/pages/index.ts b/src/api/resources/doc/resources/pages/index.ts new file mode 100644 index 0000000..914b8c3 --- /dev/null +++ b/src/api/resources/doc/resources/pages/index.ts @@ -0,0 +1 @@ +export * from "./client/index.js"; diff --git a/src/api/resources/doc/resources/redactions/client/Client.ts b/src/api/resources/doc/resources/redactions/client/Client.ts new file mode 100644 index 0000000..43b9d21 --- /dev/null +++ b/src/api/resources/doc/resources/redactions/client/Client.ts @@ -0,0 +1,109 @@ +// This file was auto-generated by Fern from our API Definition. + +import type { BaseClientOptions, BaseRequestOptions } from "../../../../../../BaseClient.js"; +import { type NormalizedClientOptionsWithAuth, normalizeClientOptionsWithAuth } from "../../../../../../BaseClient.js"; +import { mergeHeaders, mergeOnlyDefinedHeaders } from "../../../../../../core/headers.js"; +import * as core from "../../../../../../core/index.js"; +import { mergeAdditionalBodyParameters } from "../../../../../../core/requestBody.js"; +import { handleNonStatusCodeError } from "../../../../../../errors/handleNonStatusCodeError.js"; +import * as errors from "../../../../../../errors/index.js"; +import * as CloudpdfApi from "../../../../../index.js"; + +export declare namespace RedactionsClient { + export type Options = BaseClientOptions; + + export interface RequestOptions extends BaseRequestOptions {} +} + +export class RedactionsClient { + protected readonly _options: NormalizedClientOptionsWithAuth; + + constructor(options: RedactionsClient.Options) { + this._options = normalizeClientOptionsWithAuth(options); + } + + /** + * @param {CloudpdfApi.doc.ApplyRedactionsRequest} request + * @param {RedactionsClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link CloudpdfApi.BadRequestError} + * @throws {@link CloudpdfApi.NotFoundError} + * @throws {@link errors.CloudpdfApiError} + * @throws {@link errors.CloudpdfApiTimeoutError} + * + * @example + * await client.doc.redactions.apply({ + * docId: "docId", + * layerName: "layerName", + * body: { + * "key": "value" + * } + * }) + */ + public apply( + request: CloudpdfApi.doc.ApplyRedactionsRequest, + requestOptions?: RedactionsClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__apply(request, requestOptions)); + } + + private async __apply( + request: CloudpdfApi.doc.ApplyRedactionsRequest, + requestOptions?: RedactionsClient.RequestOptions, + ): Promise> { + const { docId, layerName, "X-Document-Password": documentPassword, body: _body } = request; + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + mergeOnlyDefinedHeaders({ "X-Document-Password": documentPassword }), + requestOptions?.headers, + ); + const _response = await core.fetcher({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)), + `v1/docs/${core.url.encodePathParam(docId)}/layers/${core.url.encodePathParam(layerName)}/redactions/apply`, + ), + method: "POST", + headers: _headers, + contentType: "application/json", + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), + requestType: "json", + body: mergeAdditionalBodyParameters(_body, requestOptions?.additionalBodyParameters), + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, + }); + if (_response.ok) { + return { + data: _response.body as CloudpdfApi.DocRedactionsApply200Response, + rawResponse: _response.rawResponse, + }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new CloudpdfApi.BadRequestError(_response.error.body as unknown, _response.rawResponse); + case 404: + throw new CloudpdfApi.NotFoundError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.CloudpdfApiError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + return handleNonStatusCodeError( + _response.error, + _response.rawResponse, + "POST", + "/v1/docs/{docId}/layers/{layerName}/redactions/apply", + ); + } +} diff --git a/src/api/resources/doc/resources/redactions/client/index.ts b/src/api/resources/doc/resources/redactions/client/index.ts new file mode 100644 index 0000000..195f9aa --- /dev/null +++ b/src/api/resources/doc/resources/redactions/client/index.ts @@ -0,0 +1 @@ +export * from "./requests/index.js"; diff --git a/src/api/resources/doc/resources/redactions/client/requests/ApplyRedactionsRequest.ts b/src/api/resources/doc/resources/redactions/client/requests/ApplyRedactionsRequest.ts new file mode 100644 index 0000000..fc30eb5 --- /dev/null +++ b/src/api/resources/doc/resources/redactions/client/requests/ApplyRedactionsRequest.ts @@ -0,0 +1,21 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../../../../../../index.js"; + +/** + * @example + * { + * docId: "docId", + * layerName: "layerName", + * body: { + * "key": "value" + * } + * } + */ +export interface ApplyRedactionsRequest { + docId: string; + layerName: string; + /** Base64-encoded password for an encrypted document. Valid only with the API token (403 anywhere else). An encrypted document answers 422 DocPasswordRequired when the header is absent. Viewer doc JWTs use the SDK password-session flow instead. */ + "X-Document-Password"?: string; + body: CloudpdfApi.DocRedactionsApplyRequest; +} diff --git a/src/api/resources/doc/resources/redactions/client/requests/index.ts b/src/api/resources/doc/resources/redactions/client/requests/index.ts new file mode 100644 index 0000000..acbf4a1 --- /dev/null +++ b/src/api/resources/doc/resources/redactions/client/requests/index.ts @@ -0,0 +1 @@ +export type { ApplyRedactionsRequest } from "./ApplyRedactionsRequest.js"; diff --git a/src/api/resources/doc/resources/redactions/exports.ts b/src/api/resources/doc/resources/redactions/exports.ts new file mode 100644 index 0000000..04a9559 --- /dev/null +++ b/src/api/resources/doc/resources/redactions/exports.ts @@ -0,0 +1,4 @@ +// This file was auto-generated by Fern from our API Definition. + +export { RedactionsClient } from "./client/Client.js"; +export * from "./client/index.js"; diff --git a/src/api/resources/doc/resources/redactions/index.ts b/src/api/resources/doc/resources/redactions/index.ts new file mode 100644 index 0000000..914b8c3 --- /dev/null +++ b/src/api/resources/doc/resources/redactions/index.ts @@ -0,0 +1 @@ +export * from "./client/index.js"; diff --git a/src/api/resources/documents/client/Client.ts b/src/api/resources/documents/client/Client.ts new file mode 100644 index 0000000..984aea2 --- /dev/null +++ b/src/api/resources/documents/client/Client.ts @@ -0,0 +1,623 @@ +// This file was auto-generated by Fern from our API Definition. + +import type { BaseClientOptions, BaseRequestOptions } from "../../../../BaseClient.js"; +import { type NormalizedClientOptionsWithAuth, normalizeClientOptionsWithAuth } from "../../../../BaseClient.js"; +import { mergeHeaders } from "../../../../core/headers.js"; +import * as core from "../../../../core/index.js"; +import { mergeAdditionalBodyParameters } from "../../../../core/requestBody.js"; +import { handleNonStatusCodeError } from "../../../../errors/handleNonStatusCodeError.js"; +import * as errors from "../../../../errors/index.js"; +import * as CloudpdfApi from "../../../index.js"; + +export declare namespace DocumentsClient { + export type Options = BaseClientOptions; + + export interface RequestOptions extends BaseRequestOptions {} +} + +export class DocumentsClient { + protected readonly _options: NormalizedClientOptionsWithAuth; + + constructor(options: DocumentsClient.Options) { + this._options = normalizeClientOptionsWithAuth(options); + } + + /** + * @param {CloudpdfApi.ListDocumentsRequest} request + * @param {DocumentsClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link CloudpdfApi.BadRequestError} + * @throws {@link errors.CloudpdfApiError} + * @throws {@link errors.CloudpdfApiTimeoutError} + * + * @example + * await client.documents.list({ + * tenantId: "tenantId" + * }) + */ + public list( + request: CloudpdfApi.ListDocumentsRequest, + requestOptions?: DocumentsClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__list(request, requestOptions)); + } + + private async __list( + request: CloudpdfApi.ListDocumentsRequest, + requestOptions?: DocumentsClient.RequestOptions, + ): Promise> { + const { tenantId, limit, cursor, state } = request; + const _queryParams: Record = { + limit, + cursor, + state: state != null ? state : undefined, + }; + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + requestOptions?.headers, + ); + const _response = await core.fetcher({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)), + `v1/tenants/${core.url.encodePathParam(tenantId)}/documents`, + ), + method: "GET", + headers: _headers, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, + }); + if (_response.ok) { + return { data: _response.body as CloudpdfApi.DocumentsList200Response, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new CloudpdfApi.BadRequestError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.CloudpdfApiError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + return handleNonStatusCodeError( + _response.error, + _response.rawResponse, + "GET", + "/v1/tenants/{tenantId}/documents", + ); + } + + /** + * @param {CloudpdfApi.GetDocumentsRequest} request + * @param {DocumentsClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link CloudpdfApi.ForbiddenError} + * @throws {@link CloudpdfApi.NotFoundError} + * @throws {@link errors.CloudpdfApiError} + * @throws {@link errors.CloudpdfApiTimeoutError} + * + * @example + * await client.documents.get({ + * tenantId: "tenantId", + * id: "id" + * }) + */ + public get( + request: CloudpdfApi.GetDocumentsRequest, + requestOptions?: DocumentsClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__get(request, requestOptions)); + } + + private async __get( + request: CloudpdfApi.GetDocumentsRequest, + requestOptions?: DocumentsClient.RequestOptions, + ): Promise> { + const { tenantId, id } = request; + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + requestOptions?.headers, + ); + const _response = await core.fetcher({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)), + `v1/tenants/${core.url.encodePathParam(tenantId)}/documents/${core.url.encodePathParam(id)}`, + ), + method: "GET", + headers: _headers, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, + }); + if (_response.ok) { + return { data: _response.body as CloudpdfApi.DocumentsGet200Response, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 403: + throw new CloudpdfApi.ForbiddenError(_response.error.body as unknown, _response.rawResponse); + case 404: + throw new CloudpdfApi.NotFoundError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.CloudpdfApiError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + return handleNonStatusCodeError( + _response.error, + _response.rawResponse, + "GET", + "/v1/tenants/{tenantId}/documents/{id}", + ); + } + + /** + * @param {CloudpdfApi.DeleteDocumentsRequest} request + * @param {DocumentsClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link CloudpdfApi.ForbiddenError} + * @throws {@link CloudpdfApi.NotFoundError} + * @throws {@link errors.CloudpdfApiError} + * @throws {@link errors.CloudpdfApiTimeoutError} + * + * @example + * await client.documents.delete({ + * tenantId: "tenantId", + * id: "id" + * }) + */ + public delete( + request: CloudpdfApi.DeleteDocumentsRequest, + requestOptions?: DocumentsClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__delete(request, requestOptions)); + } + + private async __delete( + request: CloudpdfApi.DeleteDocumentsRequest, + requestOptions?: DocumentsClient.RequestOptions, + ): Promise> { + const { tenantId, id } = request; + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + requestOptions?.headers, + ); + const _response = await core.fetcher({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)), + `v1/tenants/${core.url.encodePathParam(tenantId)}/documents/${core.url.encodePathParam(id)}`, + ), + method: "DELETE", + headers: _headers, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, + }); + if (_response.ok) { + return { data: undefined, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 403: + throw new CloudpdfApi.ForbiddenError(_response.error.body as unknown, _response.rawResponse); + case 404: + throw new CloudpdfApi.NotFoundError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.CloudpdfApiError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + return handleNonStatusCodeError( + _response.error, + _response.rawResponse, + "DELETE", + "/v1/tenants/{tenantId}/documents/{id}", + ); + } + + /** + * @param {CloudpdfApi.DocumentsCommitRequest} request + * @param {DocumentsClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link CloudpdfApi.BadRequestError} + * @throws {@link CloudpdfApi.NotFoundError} + * @throws {@link errors.CloudpdfApiError} + * @throws {@link errors.CloudpdfApiTimeoutError} + * + * @example + * await client.documents.commit({ + * tenantId: "tenantId", + * id: "id", + * sha256: "sha256" + * }) + */ + public commit( + request: CloudpdfApi.DocumentsCommitRequest, + requestOptions?: DocumentsClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__commit(request, requestOptions)); + } + + private async __commit( + request: CloudpdfApi.DocumentsCommitRequest, + requestOptions?: DocumentsClient.RequestOptions, + ): Promise> { + const { tenantId, id, ..._body } = request; + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + requestOptions?.headers, + ); + const _response = await core.fetcher({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)), + `v1/tenants/${core.url.encodePathParam(tenantId)}/documents/${core.url.encodePathParam(id)}/commit`, + ), + method: "POST", + headers: _headers, + contentType: "application/json", + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), + requestType: "json", + body: mergeAdditionalBodyParameters(_body, requestOptions?.additionalBodyParameters), + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, + }); + if (_response.ok) { + return { + data: _response.body as CloudpdfApi.DocumentsCommit200Response, + rawResponse: _response.rawResponse, + }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new CloudpdfApi.BadRequestError(_response.error.body as unknown, _response.rawResponse); + case 404: + throw new CloudpdfApi.NotFoundError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.CloudpdfApiError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + return handleNonStatusCodeError( + _response.error, + _response.rawResponse, + "POST", + "/v1/tenants/{tenantId}/documents/{id}/commit", + ); + } + + /** + * @throws {@link CloudpdfApi.ForbiddenError} + * @throws {@link CloudpdfApi.NotFoundError} + * @throws {@link errors.CloudpdfApiError} + * @throws {@link errors.CloudpdfApiTimeoutError} + */ + public download( + request: CloudpdfApi.DownloadDocumentsRequest, + requestOptions?: DocumentsClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__download(request, requestOptions)); + } + + private async __download( + request: CloudpdfApi.DownloadDocumentsRequest, + requestOptions?: DocumentsClient.RequestOptions, + ): Promise> { + const { tenantId, id } = request; + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + requestOptions?.headers, + ); + const _response = await core.fetcher({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)), + `v1/tenants/${core.url.encodePathParam(tenantId)}/documents/${core.url.encodePathParam(id)}/download`, + ), + method: "GET", + headers: _headers, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), + responseType: "binary-response", + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, + }); + if (_response.ok) { + return { data: _response.body, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 403: + throw new CloudpdfApi.ForbiddenError(_response.error.body as unknown, _response.rawResponse); + case 404: + throw new CloudpdfApi.NotFoundError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.CloudpdfApiError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + return handleNonStatusCodeError( + _response.error, + _response.rawResponse, + "GET", + "/v1/tenants/{tenantId}/documents/{id}/download", + ); + } + + /** + * @throws {@link CloudpdfApi.NotFoundError} + * @throws {@link errors.CloudpdfApiError} + * @throws {@link errors.CloudpdfApiTimeoutError} + */ + public thumbnail( + request: CloudpdfApi.ThumbnailDocumentsRequest, + requestOptions?: DocumentsClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__thumbnail(request, requestOptions)); + } + + private async __thumbnail( + request: CloudpdfApi.ThumbnailDocumentsRequest, + requestOptions?: DocumentsClient.RequestOptions, + ): Promise> { + const { tenantId, id } = request; + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + requestOptions?.headers, + ); + const _response = await core.fetcher({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)), + `v1/tenants/${core.url.encodePathParam(tenantId)}/documents/${core.url.encodePathParam(id)}/thumbnail`, + ), + method: "GET", + headers: _headers, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), + responseType: "binary-response", + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, + }); + if (_response.ok) { + return { data: _response.body, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 404: + throw new CloudpdfApi.NotFoundError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.CloudpdfApiError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + return handleNonStatusCodeError( + _response.error, + _response.rawResponse, + "GET", + "/v1/tenants/{tenantId}/documents/{id}/thumbnail", + ); + } + + /** + * @param {core.file.Uploadable} uploadable + * @param {string} tenantId + * @param {string} id + * @param {DocumentsClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link CloudpdfApi.BadRequestError} + * @throws {@link errors.CloudpdfApiError} + * @throws {@link errors.CloudpdfApiTimeoutError} + */ + public uploadDirect( + uploadable: core.file.Uploadable, + tenantId: string, + id: string, + requestOptions?: DocumentsClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__uploadDirect(uploadable, tenantId, id, requestOptions)); + } + + private async __uploadDirect( + uploadable: core.file.Uploadable, + tenantId: string, + id: string, + requestOptions?: DocumentsClient.RequestOptions, + ): Promise> { + const _binaryUploadRequest = await core.file.toBinaryUploadRequest(uploadable); + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + _binaryUploadRequest.headers, + requestOptions?.headers, + ); + const _response = await core.fetcher({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)), + `v1/tenants/${core.url.encodePathParam(tenantId)}/documents/${core.url.encodePathParam(id)}/upload-direct`, + ), + method: "POST", + headers: _headers, + contentType: "application/pdf", + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), + requestType: "bytes", + duplex: "half", + body: _binaryUploadRequest.body, + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, + }); + if (_response.ok) { + return { + data: _response.body as CloudpdfApi.DocumentsUploadDirect200Response, + rawResponse: _response.rawResponse, + }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new CloudpdfApi.BadRequestError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.CloudpdfApiError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + return handleNonStatusCodeError( + _response.error, + _response.rawResponse, + "POST", + "/v1/tenants/{tenantId}/documents/{id}/upload-direct", + ); + } + + /** + * @param {CloudpdfApi.DocumentsInitRequest} request + * @param {DocumentsClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link CloudpdfApi.BadRequestError} + * @throws {@link errors.CloudpdfApiError} + * @throws {@link errors.CloudpdfApiTimeoutError} + * + * @example + * await client.documents.init({ + * tenantId: "tenantId", + * contentLength: 1.1, + * contentSha256: "contentSha256" + * }) + */ + public init( + request: CloudpdfApi.DocumentsInitRequest, + requestOptions?: DocumentsClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__init(request, requestOptions)); + } + + private async __init( + request: CloudpdfApi.DocumentsInitRequest, + requestOptions?: DocumentsClient.RequestOptions, + ): Promise> { + const { tenantId, ..._body } = request; + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + requestOptions?.headers, + ); + const _response = await core.fetcher({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)), + `v1/tenants/${core.url.encodePathParam(tenantId)}/documents/init`, + ), + method: "POST", + headers: _headers, + contentType: "application/json", + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), + requestType: "json", + body: mergeAdditionalBodyParameters(_body, requestOptions?.additionalBodyParameters), + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, + }); + if (_response.ok) { + return { data: _response.body as CloudpdfApi.DocumentsInit200Response, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new CloudpdfApi.BadRequestError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.CloudpdfApiError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + return handleNonStatusCodeError( + _response.error, + _response.rawResponse, + "POST", + "/v1/tenants/{tenantId}/documents/init", + ); + } +} diff --git a/src/api/resources/documents/client/index.ts b/src/api/resources/documents/client/index.ts new file mode 100644 index 0000000..195f9aa --- /dev/null +++ b/src/api/resources/documents/client/index.ts @@ -0,0 +1 @@ +export * from "./requests/index.js"; diff --git a/src/api/resources/documents/client/requests/DeleteDocumentsRequest.ts b/src/api/resources/documents/client/requests/DeleteDocumentsRequest.ts new file mode 100644 index 0000000..ecbe451 --- /dev/null +++ b/src/api/resources/documents/client/requests/DeleteDocumentsRequest.ts @@ -0,0 +1,13 @@ +// This file was auto-generated by Fern from our API Definition. + +/** + * @example + * { + * tenantId: "tenantId", + * id: "id" + * } + */ +export interface DeleteDocumentsRequest { + tenantId: string; + id: string; +} diff --git a/src/api/resources/documents/client/requests/DocumentsCommitRequest.ts b/src/api/resources/documents/client/requests/DocumentsCommitRequest.ts new file mode 100644 index 0000000..b8059e5 --- /dev/null +++ b/src/api/resources/documents/client/requests/DocumentsCommitRequest.ts @@ -0,0 +1,15 @@ +// This file was auto-generated by Fern from our API Definition. + +/** + * @example + * { + * tenantId: "tenantId", + * id: "id", + * sha256: "sha256" + * } + */ +export interface DocumentsCommitRequest { + tenantId: string; + id: string; + sha256: string; +} diff --git a/src/api/resources/documents/client/requests/DocumentsInitRequest.ts b/src/api/resources/documents/client/requests/DocumentsInitRequest.ts new file mode 100644 index 0000000..017a771 --- /dev/null +++ b/src/api/resources/documents/client/requests/DocumentsInitRequest.ts @@ -0,0 +1,28 @@ +// This file was auto-generated by Fern from our API Definition. + +/** + * @example + * { + * tenantId: "tenantId", + * contentLength: 1.1, + * contentSha256: "contentSha256" + * } + */ +export interface DocumentsInitRequest { + tenantId: string; + contentLength: number; + contentSha256: string; + metadata?: Record; + idempotencyKey?: string; + dedupMode?: DocumentsInitRequest.DedupMode; + docId?: string; + uploadTtlSec?: number; +} + +export namespace DocumentsInitRequest { + export const DedupMode = { + AlwaysCreate: "always-create", + ReuseExisting: "reuse-existing", + } as const; + export type DedupMode = (typeof DedupMode)[keyof typeof DedupMode]; +} diff --git a/src/api/resources/documents/client/requests/DownloadDocumentsRequest.ts b/src/api/resources/documents/client/requests/DownloadDocumentsRequest.ts new file mode 100644 index 0000000..ecc530c --- /dev/null +++ b/src/api/resources/documents/client/requests/DownloadDocumentsRequest.ts @@ -0,0 +1,13 @@ +// This file was auto-generated by Fern from our API Definition. + +/** + * @example + * { + * tenantId: "tenantId", + * id: "id" + * } + */ +export interface DownloadDocumentsRequest { + tenantId: string; + id: string; +} diff --git a/src/api/resources/documents/client/requests/GetDocumentsRequest.ts b/src/api/resources/documents/client/requests/GetDocumentsRequest.ts new file mode 100644 index 0000000..41edd5a --- /dev/null +++ b/src/api/resources/documents/client/requests/GetDocumentsRequest.ts @@ -0,0 +1,13 @@ +// This file was auto-generated by Fern from our API Definition. + +/** + * @example + * { + * tenantId: "tenantId", + * id: "id" + * } + */ +export interface GetDocumentsRequest { + tenantId: string; + id: string; +} diff --git a/src/api/resources/documents/client/requests/ListDocumentsRequest.ts b/src/api/resources/documents/client/requests/ListDocumentsRequest.ts new file mode 100644 index 0000000..924ecb5 --- /dev/null +++ b/src/api/resources/documents/client/requests/ListDocumentsRequest.ts @@ -0,0 +1,16 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../../../../index.js"; + +/** + * @example + * { + * tenantId: "tenantId" + * } + */ +export interface ListDocumentsRequest { + tenantId: string; + limit?: number; + cursor?: string; + state?: CloudpdfApi.ListDocumentsRequestState; +} diff --git a/src/api/resources/documents/client/requests/ThumbnailDocumentsRequest.ts b/src/api/resources/documents/client/requests/ThumbnailDocumentsRequest.ts new file mode 100644 index 0000000..a5c683d --- /dev/null +++ b/src/api/resources/documents/client/requests/ThumbnailDocumentsRequest.ts @@ -0,0 +1,13 @@ +// This file was auto-generated by Fern from our API Definition. + +/** + * @example + * { + * tenantId: "tenantId", + * id: "id" + * } + */ +export interface ThumbnailDocumentsRequest { + tenantId: string; + id: string; +} diff --git a/src/api/resources/documents/client/requests/index.ts b/src/api/resources/documents/client/requests/index.ts new file mode 100644 index 0000000..f909fdc --- /dev/null +++ b/src/api/resources/documents/client/requests/index.ts @@ -0,0 +1,7 @@ +export type { DeleteDocumentsRequest } from "./DeleteDocumentsRequest.js"; +export type { DocumentsCommitRequest } from "./DocumentsCommitRequest.js"; +export { DocumentsInitRequest } from "./DocumentsInitRequest.js"; +export type { DownloadDocumentsRequest } from "./DownloadDocumentsRequest.js"; +export type { GetDocumentsRequest } from "./GetDocumentsRequest.js"; +export type { ListDocumentsRequest } from "./ListDocumentsRequest.js"; +export type { ThumbnailDocumentsRequest } from "./ThumbnailDocumentsRequest.js"; diff --git a/src/api/resources/documents/exports.ts b/src/api/resources/documents/exports.ts new file mode 100644 index 0000000..221bb09 --- /dev/null +++ b/src/api/resources/documents/exports.ts @@ -0,0 +1,4 @@ +// This file was auto-generated by Fern from our API Definition. + +export { DocumentsClient } from "./client/Client.js"; +export * from "./client/index.js"; diff --git a/src/api/resources/documents/index.ts b/src/api/resources/documents/index.ts new file mode 100644 index 0000000..d9adb1a --- /dev/null +++ b/src/api/resources/documents/index.ts @@ -0,0 +1,2 @@ +export * from "./client/index.js"; +export * from "./types/index.js"; diff --git a/src/api/resources/documents/types/ListDocumentsRequestState.ts b/src/api/resources/documents/types/ListDocumentsRequestState.ts new file mode 100644 index 0000000..b07714e --- /dev/null +++ b/src/api/resources/documents/types/ListDocumentsRequestState.ts @@ -0,0 +1,9 @@ +// This file was auto-generated by Fern from our API Definition. + +export const ListDocumentsRequestState = { + Pending: "pending", + Ready: "ready", + Failed: "failed", + Deleting: "deleting", +} as const; +export type ListDocumentsRequestState = (typeof ListDocumentsRequestState)[keyof typeof ListDocumentsRequestState]; diff --git a/src/api/resources/documents/types/index.ts b/src/api/resources/documents/types/index.ts new file mode 100644 index 0000000..fd2ee7d --- /dev/null +++ b/src/api/resources/documents/types/index.ts @@ -0,0 +1 @@ +export * from "./ListDocumentsRequestState.js"; diff --git a/src/api/resources/index.ts b/src/api/resources/index.ts new file mode 100644 index 0000000..8fe9fde --- /dev/null +++ b/src/api/resources/index.ts @@ -0,0 +1,10 @@ +export * as deployment from "./deployment/index.js"; +export * from "./doc/client/requests/index.js"; +export * as doc from "./doc/index.js"; +export * from "./documents/client/requests/index.js"; +export * as documents from "./documents/index.js"; +export * from "./documents/types/index.js"; +export * from "./tenants/client/requests/index.js"; +export * as tenants from "./tenants/index.js"; +export * from "./tokens/client/requests/index.js"; +export * as tokens from "./tokens/index.js"; diff --git a/src/api/resources/tenants/client/Client.ts b/src/api/resources/tenants/client/Client.ts new file mode 100644 index 0000000..4a6923c --- /dev/null +++ b/src/api/resources/tenants/client/Client.ts @@ -0,0 +1,298 @@ +// This file was auto-generated by Fern from our API Definition. + +import type { BaseClientOptions, BaseRequestOptions } from "../../../../BaseClient.js"; +import { type NormalizedClientOptionsWithAuth, normalizeClientOptionsWithAuth } from "../../../../BaseClient.js"; +import { mergeHeaders } from "../../../../core/headers.js"; +import * as core from "../../../../core/index.js"; +import { mergeAdditionalBodyParameters } from "../../../../core/requestBody.js"; +import { handleNonStatusCodeError } from "../../../../errors/handleNonStatusCodeError.js"; +import * as errors from "../../../../errors/index.js"; +import * as CloudpdfApi from "../../../index.js"; + +export declare namespace TenantsClient { + export type Options = BaseClientOptions; + + export interface RequestOptions extends BaseRequestOptions {} +} + +export class TenantsClient { + protected readonly _options: NormalizedClientOptionsWithAuth; + + constructor(options: TenantsClient.Options) { + this._options = normalizeClientOptionsWithAuth(options); + } + + /** + * @param {CloudpdfApi.ListTenantsRequest} request + * @param {TenantsClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link CloudpdfApi.BadRequestError} + * @throws {@link errors.CloudpdfApiError} + * @throws {@link errors.CloudpdfApiTimeoutError} + * + * @example + * await client.tenants.list() + */ + public list( + request: CloudpdfApi.ListTenantsRequest = {}, + requestOptions?: TenantsClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__list(request, requestOptions)); + } + + private async __list( + request: CloudpdfApi.ListTenantsRequest = {}, + requestOptions?: TenantsClient.RequestOptions, + ): Promise> { + const { limit, cursor } = request; + const _queryParams: Record = { + limit, + cursor, + }; + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + requestOptions?.headers, + ); + const _response = await core.fetcher({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)), + "v1/tenants", + ), + method: "GET", + headers: _headers, + queryString: core.url + .queryBuilder() + .addMany(_queryParams) + .mergeAdditional(requestOptions?.queryParams) + .build(), + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, + }); + if (_response.ok) { + return { data: _response.body as CloudpdfApi.TenantsList200Response, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new CloudpdfApi.BadRequestError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.CloudpdfApiError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/tenants"); + } + + /** + * @param {CloudpdfApi.TenantsCreateRequest} request + * @param {TenantsClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link CloudpdfApi.BadRequestError} + * @throws {@link errors.CloudpdfApiError} + * @throws {@link errors.CloudpdfApiTimeoutError} + * + * @example + * await client.tenants.create({ + * id: "id" + * }) + */ + public create( + request: CloudpdfApi.TenantsCreateRequest, + requestOptions?: TenantsClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__create(request, requestOptions)); + } + + private async __create( + request: CloudpdfApi.TenantsCreateRequest, + requestOptions?: TenantsClient.RequestOptions, + ): Promise> { + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + requestOptions?.headers, + ); + const _response = await core.fetcher({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)), + "v1/tenants", + ), + method: "POST", + headers: _headers, + contentType: "application/json", + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), + requestType: "json", + body: mergeAdditionalBodyParameters(request, requestOptions?.additionalBodyParameters), + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, + }); + if (_response.ok) { + return { data: _response.body as CloudpdfApi.TenantsCreate200Response, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new CloudpdfApi.BadRequestError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.CloudpdfApiError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + return handleNonStatusCodeError(_response.error, _response.rawResponse, "POST", "/v1/tenants"); + } + + /** + * @param {CloudpdfApi.GetTenantsRequest} request + * @param {TenantsClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link CloudpdfApi.NotFoundError} + * @throws {@link errors.CloudpdfApiError} + * @throws {@link errors.CloudpdfApiTimeoutError} + * + * @example + * await client.tenants.get({ + * tenantId: "tenantId" + * }) + */ + public get( + request: CloudpdfApi.GetTenantsRequest, + requestOptions?: TenantsClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__get(request, requestOptions)); + } + + private async __get( + request: CloudpdfApi.GetTenantsRequest, + requestOptions?: TenantsClient.RequestOptions, + ): Promise> { + const { tenantId } = request; + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + requestOptions?.headers, + ); + const _response = await core.fetcher({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)), + `v1/tenants/${core.url.encodePathParam(tenantId)}`, + ), + method: "GET", + headers: _headers, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, + }); + if (_response.ok) { + return { data: _response.body as CloudpdfApi.TenantsGet200Response, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 404: + throw new CloudpdfApi.NotFoundError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.CloudpdfApiError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + return handleNonStatusCodeError(_response.error, _response.rawResponse, "GET", "/v1/tenants/{tenantId}"); + } + + /** + * Destroys the tenant and everything in its namespace — documents, layers, stored bytes, audit history. Irreversible. + * + * @param {CloudpdfApi.DeleteTenantsRequest} request + * @param {TenantsClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link CloudpdfApi.NotFoundError} + * @throws {@link errors.CloudpdfApiError} + * @throws {@link errors.CloudpdfApiTimeoutError} + * + * @example + * await client.tenants.delete({ + * tenantId: "tenantId" + * }) + */ + public delete( + request: CloudpdfApi.DeleteTenantsRequest, + requestOptions?: TenantsClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__delete(request, requestOptions)); + } + + private async __delete( + request: CloudpdfApi.DeleteTenantsRequest, + requestOptions?: TenantsClient.RequestOptions, + ): Promise> { + const { tenantId } = request; + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + requestOptions?.headers, + ); + const _response = await core.fetcher({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)), + `v1/tenants/${core.url.encodePathParam(tenantId)}`, + ), + method: "DELETE", + headers: _headers, + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, + }); + if (_response.ok) { + return { data: undefined, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 404: + throw new CloudpdfApi.NotFoundError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.CloudpdfApiError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + return handleNonStatusCodeError(_response.error, _response.rawResponse, "DELETE", "/v1/tenants/{tenantId}"); + } +} diff --git a/src/api/resources/tenants/client/index.ts b/src/api/resources/tenants/client/index.ts new file mode 100644 index 0000000..195f9aa --- /dev/null +++ b/src/api/resources/tenants/client/index.ts @@ -0,0 +1 @@ +export * from "./requests/index.js"; diff --git a/src/api/resources/tenants/client/requests/DeleteTenantsRequest.ts b/src/api/resources/tenants/client/requests/DeleteTenantsRequest.ts new file mode 100644 index 0000000..21e5711 --- /dev/null +++ b/src/api/resources/tenants/client/requests/DeleteTenantsRequest.ts @@ -0,0 +1,11 @@ +// This file was auto-generated by Fern from our API Definition. + +/** + * @example + * { + * tenantId: "tenantId" + * } + */ +export interface DeleteTenantsRequest { + tenantId: string; +} diff --git a/src/api/resources/tenants/client/requests/GetTenantsRequest.ts b/src/api/resources/tenants/client/requests/GetTenantsRequest.ts new file mode 100644 index 0000000..82c6de8 --- /dev/null +++ b/src/api/resources/tenants/client/requests/GetTenantsRequest.ts @@ -0,0 +1,11 @@ +// This file was auto-generated by Fern from our API Definition. + +/** + * @example + * { + * tenantId: "tenantId" + * } + */ +export interface GetTenantsRequest { + tenantId: string; +} diff --git a/src/api/resources/tenants/client/requests/ListTenantsRequest.ts b/src/api/resources/tenants/client/requests/ListTenantsRequest.ts new file mode 100644 index 0000000..f6e4ae4 --- /dev/null +++ b/src/api/resources/tenants/client/requests/ListTenantsRequest.ts @@ -0,0 +1,10 @@ +// This file was auto-generated by Fern from our API Definition. + +/** + * @example + * {} + */ +export interface ListTenantsRequest { + limit?: number; + cursor?: string; +} diff --git a/src/api/resources/tenants/client/requests/TenantsCreateRequest.ts b/src/api/resources/tenants/client/requests/TenantsCreateRequest.ts new file mode 100644 index 0000000..88a0368 --- /dev/null +++ b/src/api/resources/tenants/client/requests/TenantsCreateRequest.ts @@ -0,0 +1,12 @@ +// This file was auto-generated by Fern from our API Definition. + +/** + * @example + * { + * id: "id" + * } + */ +export interface TenantsCreateRequest { + id: string; + name?: string; +} diff --git a/src/api/resources/tenants/client/requests/index.ts b/src/api/resources/tenants/client/requests/index.ts new file mode 100644 index 0000000..aef4390 --- /dev/null +++ b/src/api/resources/tenants/client/requests/index.ts @@ -0,0 +1,4 @@ +export type { DeleteTenantsRequest } from "./DeleteTenantsRequest.js"; +export type { GetTenantsRequest } from "./GetTenantsRequest.js"; +export type { ListTenantsRequest } from "./ListTenantsRequest.js"; +export type { TenantsCreateRequest } from "./TenantsCreateRequest.js"; diff --git a/src/api/resources/tenants/exports.ts b/src/api/resources/tenants/exports.ts new file mode 100644 index 0000000..6500bc0 --- /dev/null +++ b/src/api/resources/tenants/exports.ts @@ -0,0 +1,4 @@ +// This file was auto-generated by Fern from our API Definition. + +export { TenantsClient } from "./client/Client.js"; +export * from "./client/index.js"; diff --git a/src/api/resources/tenants/index.ts b/src/api/resources/tenants/index.ts new file mode 100644 index 0000000..914b8c3 --- /dev/null +++ b/src/api/resources/tenants/index.ts @@ -0,0 +1 @@ +export * from "./client/index.js"; diff --git a/src/api/resources/tokens/client/Client.ts b/src/api/resources/tokens/client/Client.ts new file mode 100644 index 0000000..5a9a5c0 --- /dev/null +++ b/src/api/resources/tokens/client/Client.ts @@ -0,0 +1,190 @@ +// This file was auto-generated by Fern from our API Definition. + +import type { BaseClientOptions, BaseRequestOptions } from "../../../../BaseClient.js"; +import { type NormalizedClientOptionsWithAuth, normalizeClientOptionsWithAuth } from "../../../../BaseClient.js"; +import { mergeHeaders } from "../../../../core/headers.js"; +import * as core from "../../../../core/index.js"; +import { mergeAdditionalBodyParameters } from "../../../../core/requestBody.js"; +import { handleNonStatusCodeError } from "../../../../errors/handleNonStatusCodeError.js"; +import * as errors from "../../../../errors/index.js"; +import * as CloudpdfApi from "../../../index.js"; + +export declare namespace TokensClient { + export type Options = BaseClientOptions; + + export interface RequestOptions extends BaseRequestOptions {} +} + +export class TokensClient { + protected readonly _options: NormalizedClientOptionsWithAuth; + + constructor(options: TokensClient.Options) { + this._options = normalizeClientOptionsWithAuth(options); + } + + /** + * kind "tenant" requires the API token — authority mints only downward. Mounted only when the deployment can sign (HS256 mode); asymmetric deployments mint with their own private key. + * + * @param {CloudpdfApi.IssueTokensRequest} request + * @param {TokensClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link CloudpdfApi.BadRequestError} + * @throws {@link CloudpdfApi.ForbiddenError} + * @throws {@link CloudpdfApi.NotFoundError} + * @throws {@link errors.CloudpdfApiError} + * @throws {@link errors.CloudpdfApiTimeoutError} + * + * @example + * await client.tokens.issue({ + * tenantId: "tenantId", + * body: { + * kind: "doc", + * sub: "sub", + * docId: "docId", + * scope: ["scope"], + * expiresIn: 1 + * } + * }) + */ + public issue( + request: CloudpdfApi.IssueTokensRequest, + requestOptions?: TokensClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__issue(request, requestOptions)); + } + + private async __issue( + request: CloudpdfApi.IssueTokensRequest, + requestOptions?: TokensClient.RequestOptions, + ): Promise> { + const { tenantId, body: _body } = request; + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + requestOptions?.headers, + ); + const _response = await core.fetcher({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)), + `v1/tenants/${core.url.encodePathParam(tenantId)}/tokens`, + ), + method: "POST", + headers: _headers, + contentType: "application/json", + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), + requestType: "json", + body: mergeAdditionalBodyParameters(_body, requestOptions?.additionalBodyParameters), + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, + }); + if (_response.ok) { + return { data: _response.body as CloudpdfApi.TokensIssue200Response, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new CloudpdfApi.BadRequestError(_response.error.body as unknown, _response.rawResponse); + case 403: + throw new CloudpdfApi.ForbiddenError(_response.error.body as unknown, _response.rawResponse); + case 404: + throw new CloudpdfApi.NotFoundError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.CloudpdfApiError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + return handleNonStatusCodeError( + _response.error, + _response.rawResponse, + "POST", + "/v1/tenants/{tenantId}/tokens", + ); + } + + /** + * Mounted only when the deployment enables token revocation. + * + * @param {CloudpdfApi.TokensRevokeRequest} request + * @param {TokensClient.RequestOptions} requestOptions - Request-specific configuration. + * + * @throws {@link CloudpdfApi.BadRequestError} + * @throws {@link errors.CloudpdfApiError} + * @throws {@link errors.CloudpdfApiTimeoutError} + * + * @example + * await client.tokens.revoke({ + * tenantId: "tenantId", + * jti: "jti" + * }) + */ + public revoke( + request: CloudpdfApi.TokensRevokeRequest, + requestOptions?: TokensClient.RequestOptions, + ): core.HttpResponsePromise { + return core.HttpResponsePromise.fromPromise(this.__revoke(request, requestOptions)); + } + + private async __revoke( + request: CloudpdfApi.TokensRevokeRequest, + requestOptions?: TokensClient.RequestOptions, + ): Promise> { + const { tenantId, jti, ..._body } = request; + const _authRequest: core.AuthRequest = await this._options.authProvider.getAuthRequest(); + const _headers: core.Fetcher.Args["headers"] = mergeHeaders( + _authRequest.headers, + this._options?.headers, + requestOptions?.headers, + ); + const _response = await core.fetcher({ + url: core.url.join( + (await core.Supplier.get(this._options.baseUrl)) ?? + (await core.Supplier.get(this._options.environment)), + `v1/tenants/${core.url.encodePathParam(tenantId)}/tokens/${core.url.encodePathParam(jti)}/revoke`, + ), + method: "POST", + headers: _headers, + contentType: "application/json", + queryString: core.url.queryBuilder().mergeAdditional(requestOptions?.queryParams).build(), + requestType: "json", + body: mergeAdditionalBodyParameters(_body, requestOptions?.additionalBodyParameters), + timeoutMs: (requestOptions?.timeoutInSeconds ?? this._options?.timeoutInSeconds ?? 60) * 1000, + maxRetries: requestOptions?.maxRetries ?? this._options?.maxRetries, + abortSignal: requestOptions?.abortSignal, + fetchFn: this._options?.fetch, + logging: this._options.logging, + }); + if (_response.ok) { + return { data: undefined, rawResponse: _response.rawResponse }; + } + + if (_response.error.reason === "status-code") { + switch (_response.error.statusCode) { + case 400: + throw new CloudpdfApi.BadRequestError(_response.error.body as unknown, _response.rawResponse); + default: + throw new errors.CloudpdfApiError({ + statusCode: _response.error.statusCode, + body: _response.error.body, + rawResponse: _response.rawResponse, + }); + } + } + + return handleNonStatusCodeError( + _response.error, + _response.rawResponse, + "POST", + "/v1/tenants/{tenantId}/tokens/{jti}/revoke", + ); + } +} diff --git a/src/api/resources/tokens/client/index.ts b/src/api/resources/tokens/client/index.ts new file mode 100644 index 0000000..195f9aa --- /dev/null +++ b/src/api/resources/tokens/client/index.ts @@ -0,0 +1 @@ +export * from "./requests/index.js"; diff --git a/src/api/resources/tokens/client/requests/IssueTokensRequest.ts b/src/api/resources/tokens/client/requests/IssueTokensRequest.ts new file mode 100644 index 0000000..dcce744 --- /dev/null +++ b/src/api/resources/tokens/client/requests/IssueTokensRequest.ts @@ -0,0 +1,21 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../../../../index.js"; + +/** + * @example + * { + * tenantId: "tenantId", + * body: { + * kind: "doc", + * sub: "sub", + * docId: "docId", + * scope: ["scope"], + * expiresIn: 1 + * } + * } + */ +export interface IssueTokensRequest { + tenantId: string; + body: CloudpdfApi.TokensIssueRequest; +} diff --git a/src/api/resources/tokens/client/requests/TokensRevokeRequest.ts b/src/api/resources/tokens/client/requests/TokensRevokeRequest.ts new file mode 100644 index 0000000..5550b1d --- /dev/null +++ b/src/api/resources/tokens/client/requests/TokensRevokeRequest.ts @@ -0,0 +1,15 @@ +// This file was auto-generated by Fern from our API Definition. + +/** + * @example + * { + * tenantId: "tenantId", + * jti: "jti" + * } + */ +export interface TokensRevokeRequest { + tenantId: string; + jti: string; + reason?: string; + expiresAtSeconds?: number; +} diff --git a/src/api/resources/tokens/client/requests/index.ts b/src/api/resources/tokens/client/requests/index.ts new file mode 100644 index 0000000..6908590 --- /dev/null +++ b/src/api/resources/tokens/client/requests/index.ts @@ -0,0 +1,2 @@ +export type { IssueTokensRequest } from "./IssueTokensRequest.js"; +export type { TokensRevokeRequest } from "./TokensRevokeRequest.js"; diff --git a/src/api/resources/tokens/exports.ts b/src/api/resources/tokens/exports.ts new file mode 100644 index 0000000..6b51ec1 --- /dev/null +++ b/src/api/resources/tokens/exports.ts @@ -0,0 +1,4 @@ +// This file was auto-generated by Fern from our API Definition. + +export { TokensClient } from "./client/Client.js"; +export * from "./client/index.js"; diff --git a/src/api/resources/tokens/index.ts b/src/api/resources/tokens/index.ts new file mode 100644 index 0000000..914b8c3 --- /dev/null +++ b/src/api/resources/tokens/index.ts @@ -0,0 +1 @@ +export * from "./client/index.js"; diff --git a/src/api/types/AdminErrorPayload.ts b/src/api/types/AdminErrorPayload.ts new file mode 100644 index 0000000..abc968f --- /dev/null +++ b/src/api/types/AdminErrorPayload.ts @@ -0,0 +1,12 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface AdminErrorPayload { + error: AdminErrorPayload.Error_; +} + +export namespace AdminErrorPayload { + export interface Error_ { + code: string; + message: string; + } +} diff --git a/src/api/types/DeploymentLicenseStatusResponse.ts b/src/api/types/DeploymentLicenseStatusResponse.ts new file mode 100644 index 0000000..64a180d --- /dev/null +++ b/src/api/types/DeploymentLicenseStatusResponse.ts @@ -0,0 +1,7 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface DeploymentLicenseStatusResponse { + license?: unknown | undefined; + reporting?: (unknown | null) | undefined; + usage?: (unknown | null) | undefined; +} diff --git a/src/api/types/DocAnnotationsCreate200Response.ts b/src/api/types/DocAnnotationsCreate200Response.ts new file mode 100644 index 0000000..695529a --- /dev/null +++ b/src/api/types/DocAnnotationsCreate200Response.ts @@ -0,0 +1,60 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export interface DocAnnotationsCreate200Response { + meta: DocAnnotationsCreate200Response.Meta; + /** Accepts any additional properties */ + [key: string]: any; +} + +export namespace DocAnnotationsCreate200Response { + export interface Meta { + affectedPages: Meta.AffectedPages.Item[]; + cacheDelta: Meta.CacheDelta | null; + } + + export namespace Meta { + export type AffectedPages = AffectedPages.Item[]; + + export namespace AffectedPages { + export interface Item { + pageObjectNumber: number; + revision: Item.Revision; + weakAnnotationState: CloudpdfApi.DocAnnotationsCreate200ResponseMetaAffectedPagesItemWeakAnnotationState; + } + + export namespace Item { + export interface Revision { + docSessionId: string; + pageObjectNumber: number; + generation: number; + } + } + } + + export interface CacheDelta { + previousDocVersion: number; + docVersion: number; + pages: CacheDelta.Pages.Item[]; + } + + export namespace CacheDelta { + export type Pages = Pages.Item[]; + + export namespace Pages { + export interface Item { + pageObjectNumber: number; + cache: Item.Cache; + } + + export namespace Item { + export interface Cache { + contentVersion: number; + annotationVersion: number; + } + } + } + } + } +} diff --git a/src/api/types/DocAnnotationsCreate200ResponseMetaAffectedPagesItemWeakAnnotationState.ts b/src/api/types/DocAnnotationsCreate200ResponseMetaAffectedPagesItemWeakAnnotationState.ts new file mode 100644 index 0000000..234fbc1 --- /dev/null +++ b/src/api/types/DocAnnotationsCreate200ResponseMetaAffectedPagesItemWeakAnnotationState.ts @@ -0,0 +1,18 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocAnnotationsCreate200ResponseMetaAffectedPagesItemWeakAnnotationState = + | CloudpdfApi.DocAnnotationsCreate200ResponseMetaAffectedPagesItemWeakAnnotationState.Unknown + | CloudpdfApi.DocAnnotationsCreate200ResponseMetaAffectedPagesItemWeakAnnotationState.Known; + +export namespace DocAnnotationsCreate200ResponseMetaAffectedPagesItemWeakAnnotationState { + export interface Unknown { + kind: "unknown"; + } + + export interface Known { + kind: "known"; + hasAnyWeakAnnotations: boolean; + } +} diff --git a/src/api/types/DocAnnotationsCreate400Response.ts b/src/api/types/DocAnnotationsCreate400Response.ts new file mode 100644 index 0000000..20d48f0 --- /dev/null +++ b/src/api/types/DocAnnotationsCreate400Response.ts @@ -0,0 +1,36 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface DocAnnotationsCreate400Response { + name: DocAnnotationsCreate400Response.Name; + code: DocAnnotationsCreate400Response.Code; + message: string; + details?: Record | undefined; +} + +export namespace DocAnnotationsCreate400Response { + export const Name = { + EngineError: "EngineError", + } as const; + export type Name = (typeof Name)[keyof typeof Name]; + export const Code = { + Unknown: "Unknown", + InvalidArg: "InvalidArg", + DocNotOpen: "DocNotOpen", + DocOpenFailed: "DocOpenFailed", + DocPasswordRequired: "DocPasswordRequired", + DocPasswordIncorrect: "DocPasswordIncorrect", + Aborted: "Aborted", + Network: "Network", + Unauthenticated: "Unauthenticated", + Forbidden: "Forbidden", + NotFound: "NotFound", + WireFormat: "WireFormat", + RuntimeUnavailable: "RuntimeUnavailable", + InvalidReference: "InvalidReference", + WeakAnnotationSessionConflict: "WeakAnnotationSessionConflict", + LayerVersionConflict: "LayerVersionConflict", + NotImplemented: "NotImplemented", + MalformedPdf: "MalformedPdf", + } as const; + export type Code = (typeof Code)[keyof typeof Code]; +} diff --git a/src/api/types/DocAnnotationsCreate404Response.ts b/src/api/types/DocAnnotationsCreate404Response.ts new file mode 100644 index 0000000..848c427 --- /dev/null +++ b/src/api/types/DocAnnotationsCreate404Response.ts @@ -0,0 +1,36 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface DocAnnotationsCreate404Response { + name: DocAnnotationsCreate404Response.Name; + code: DocAnnotationsCreate404Response.Code; + message: string; + details?: Record | undefined; +} + +export namespace DocAnnotationsCreate404Response { + export const Name = { + EngineError: "EngineError", + } as const; + export type Name = (typeof Name)[keyof typeof Name]; + export const Code = { + Unknown: "Unknown", + InvalidArg: "InvalidArg", + DocNotOpen: "DocNotOpen", + DocOpenFailed: "DocOpenFailed", + DocPasswordRequired: "DocPasswordRequired", + DocPasswordIncorrect: "DocPasswordIncorrect", + Aborted: "Aborted", + Network: "Network", + Unauthenticated: "Unauthenticated", + Forbidden: "Forbidden", + NotFound: "NotFound", + WireFormat: "WireFormat", + RuntimeUnavailable: "RuntimeUnavailable", + InvalidReference: "InvalidReference", + WeakAnnotationSessionConflict: "WeakAnnotationSessionConflict", + LayerVersionConflict: "LayerVersionConflict", + NotImplemented: "NotImplemented", + MalformedPdf: "MalformedPdf", + } as const; + export type Code = (typeof Code)[keyof typeof Code]; +} diff --git a/src/api/types/DocAnnotationsCreateRequest.ts b/src/api/types/DocAnnotationsCreateRequest.ts new file mode 100644 index 0000000..2aa7bb4 --- /dev/null +++ b/src/api/types/DocAnnotationsCreateRequest.ts @@ -0,0 +1,3 @@ +// This file was auto-generated by Fern from our API Definition. + +export type DocAnnotationsCreateRequest = Record; diff --git a/src/api/types/DocAnnotationsDelete200Response.ts b/src/api/types/DocAnnotationsDelete200Response.ts new file mode 100644 index 0000000..bcb774a --- /dev/null +++ b/src/api/types/DocAnnotationsDelete200Response.ts @@ -0,0 +1,60 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export interface DocAnnotationsDelete200Response { + meta: DocAnnotationsDelete200Response.Meta; + /** Accepts any additional properties */ + [key: string]: any; +} + +export namespace DocAnnotationsDelete200Response { + export interface Meta { + affectedPages: Meta.AffectedPages.Item[]; + cacheDelta: Meta.CacheDelta | null; + } + + export namespace Meta { + export type AffectedPages = AffectedPages.Item[]; + + export namespace AffectedPages { + export interface Item { + pageObjectNumber: number; + revision: Item.Revision; + weakAnnotationState: CloudpdfApi.DocAnnotationsDelete200ResponseMetaAffectedPagesItemWeakAnnotationState; + } + + export namespace Item { + export interface Revision { + docSessionId: string; + pageObjectNumber: number; + generation: number; + } + } + } + + export interface CacheDelta { + previousDocVersion: number; + docVersion: number; + pages: CacheDelta.Pages.Item[]; + } + + export namespace CacheDelta { + export type Pages = Pages.Item[]; + + export namespace Pages { + export interface Item { + pageObjectNumber: number; + cache: Item.Cache; + } + + export namespace Item { + export interface Cache { + contentVersion: number; + annotationVersion: number; + } + } + } + } + } +} diff --git a/src/api/types/DocAnnotationsDelete200ResponseMetaAffectedPagesItemWeakAnnotationState.ts b/src/api/types/DocAnnotationsDelete200ResponseMetaAffectedPagesItemWeakAnnotationState.ts new file mode 100644 index 0000000..b26f30a --- /dev/null +++ b/src/api/types/DocAnnotationsDelete200ResponseMetaAffectedPagesItemWeakAnnotationState.ts @@ -0,0 +1,18 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocAnnotationsDelete200ResponseMetaAffectedPagesItemWeakAnnotationState = + | CloudpdfApi.DocAnnotationsDelete200ResponseMetaAffectedPagesItemWeakAnnotationState.Unknown + | CloudpdfApi.DocAnnotationsDelete200ResponseMetaAffectedPagesItemWeakAnnotationState.Known; + +export namespace DocAnnotationsDelete200ResponseMetaAffectedPagesItemWeakAnnotationState { + export interface Unknown { + kind: "unknown"; + } + + export interface Known { + kind: "known"; + hasAnyWeakAnnotations: boolean; + } +} diff --git a/src/api/types/DocAnnotationsDelete404Response.ts b/src/api/types/DocAnnotationsDelete404Response.ts new file mode 100644 index 0000000..c210889 --- /dev/null +++ b/src/api/types/DocAnnotationsDelete404Response.ts @@ -0,0 +1,36 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface DocAnnotationsDelete404Response { + name: DocAnnotationsDelete404Response.Name; + code: DocAnnotationsDelete404Response.Code; + message: string; + details?: Record | undefined; +} + +export namespace DocAnnotationsDelete404Response { + export const Name = { + EngineError: "EngineError", + } as const; + export type Name = (typeof Name)[keyof typeof Name]; + export const Code = { + Unknown: "Unknown", + InvalidArg: "InvalidArg", + DocNotOpen: "DocNotOpen", + DocOpenFailed: "DocOpenFailed", + DocPasswordRequired: "DocPasswordRequired", + DocPasswordIncorrect: "DocPasswordIncorrect", + Aborted: "Aborted", + Network: "Network", + Unauthenticated: "Unauthenticated", + Forbidden: "Forbidden", + NotFound: "NotFound", + WireFormat: "WireFormat", + RuntimeUnavailable: "RuntimeUnavailable", + InvalidReference: "InvalidReference", + WeakAnnotationSessionConflict: "WeakAnnotationSessionConflict", + LayerVersionConflict: "LayerVersionConflict", + NotImplemented: "NotImplemented", + MalformedPdf: "MalformedPdf", + } as const; + export type Code = (typeof Code)[keyof typeof Code]; +} diff --git a/src/api/types/DocAnnotationsList200Response.ts b/src/api/types/DocAnnotationsList200Response.ts new file mode 100644 index 0000000..4bd2a47 --- /dev/null +++ b/src/api/types/DocAnnotationsList200Response.ts @@ -0,0 +1,24 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export interface DocAnnotationsList200Response { + pageState: DocAnnotationsList200Response.PageState; + annotations: CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItem[]; +} + +export namespace DocAnnotationsList200Response { + export interface PageState { + pageObjectNumber: number; + revision: PageState.Revision; + weakAnnotationState: CloudpdfApi.DocAnnotationsList200ResponsePageStateWeakAnnotationState; + } + + export namespace PageState { + export interface Revision { + docSessionId: string; + pageObjectNumber: number; + generation: number; + } + } +} diff --git a/src/api/types/DocAnnotationsList200ResponseAnnotationsItem.ts b/src/api/types/DocAnnotationsList200ResponseAnnotationsItem.ts new file mode 100644 index 0000000..39078c2 --- /dev/null +++ b/src/api/types/DocAnnotationsList200ResponseAnnotationsItem.ts @@ -0,0 +1,13466 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocAnnotationsList200ResponseAnnotationsItem = + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItem.Highlight + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItem.Underline + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItem.Squiggly + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItem.Strikeout + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItem.Circle + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItem.Square + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItem.Polygon + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItem.Polyline + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItem.Line + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItem.Link + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItem.Ink + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItem.FreeText + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItem.Caret + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItem.Text + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItem.Stamp + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItem.FileAttachment + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItem.Widget + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItem.Redact + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItem.Unsupported; + +export namespace DocAnnotationsList200ResponseAnnotationsItem { + export interface Highlight { + subtype: "highlight"; + ref: CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemHighlightRef; + pageObjectNumber: number; + index: number; + identityQuality: DocAnnotationsList200ResponseAnnotationsItemHighlight.IdentityQuality; + nm: string | null; + flags: DocAnnotationsList200ResponseAnnotationsItemHighlight.Flags; + rect: DocAnnotationsList200ResponseAnnotationsItemHighlight.Rect; + contents: string | null; + author: string | null; + created: string | null; + modified: string | null; + blendMode: DocAnnotationsList200ResponseAnnotationsItemHighlight.BlendMode; + inReplyTo: CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemHighlightInReplyTo | null; + replyType: DocAnnotationsList200ResponseAnnotationsItemHighlight.ReplyType | null; + userId?: string | undefined; + groupId?: string | undefined; + createdBy?: string | undefined; + updatedBy?: string | undefined; + actions?: DocAnnotationsList200ResponseAnnotationsItemHighlight.Actions | undefined; + color: DocAnnotationsList200ResponseAnnotationsItemHighlight.Color; + opacity: number; + quadPoints: DocAnnotationsList200ResponseAnnotationsItemHighlight.QuadPoints.Item[]; + } + + export namespace DocAnnotationsList200ResponseAnnotationsItemHighlight { + export const IdentityQuality = { + Durable: "durable", + Weak: "weak", + } as const; + export type IdentityQuality = (typeof IdentityQuality)[keyof typeof IdentityQuality]; + + export interface Flags { + invisible: boolean; + hidden: boolean; + print: boolean; + noZoom: boolean; + noRotate: boolean; + noView: boolean; + readOnly: boolean; + locked: boolean; + toggleNoView: boolean; + lockedContents: boolean; + } + + export interface Rect { + left: number; + bottom: number; + right: number; + top: number; + } + + export const BlendMode = { + Normal: "normal", + Multiply: "multiply", + Screen: "screen", + Overlay: "overlay", + Darken: "darken", + Lighten: "lighten", + ColorDodge: "color-dodge", + ColorBurn: "color-burn", + HardLight: "hard-light", + SoftLight: "soft-light", + Difference: "difference", + Exclusion: "exclusion", + Hue: "hue", + Saturation: "saturation", + Color: "color", + Luminosity: "luminosity", + } as const; + export type BlendMode = (typeof BlendMode)[keyof typeof BlendMode]; + export const ReplyType = { + Reply: "reply", + Group: "group", + } as const; + export type ReplyType = (typeof ReplyType)[keyof typeof ReplyType]; + + export interface Actions { + activate?: Actions.Activate | undefined; + cursorEnter?: Actions.CursorEnter | undefined; + cursorExit?: Actions.CursorExit | undefined; + mouseDown?: Actions.MouseDown | undefined; + mouseUp?: Actions.MouseUp | undefined; + focus?: Actions.Focus | undefined; + blur?: Actions.Blur | undefined; + pageOpen?: Actions.PageOpen | undefined; + pageClose?: Actions.PageClose | undefined; + pageVisible?: Actions.PageVisible | undefined; + pageInvisible?: Actions.PageInvisible | undefined; + } + + export namespace Actions { + export interface Activate { + root: Activate.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Activate.Warnings.Item[]; + } + + export namespace Activate { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface CursorEnter { + root: CursorEnter.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: CursorEnter.Warnings.Item[]; + } + + export namespace CursorEnter { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface CursorExit { + root: CursorExit.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: CursorExit.Warnings.Item[]; + } + + export namespace CursorExit { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface MouseDown { + root: MouseDown.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: MouseDown.Warnings.Item[]; + } + + export namespace MouseDown { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface MouseUp { + root: MouseUp.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: MouseUp.Warnings.Item[]; + } + + export namespace MouseUp { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface Focus { + root: Focus.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Focus.Warnings.Item[]; + } + + export namespace Focus { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface Blur { + root: Blur.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Blur.Warnings.Item[]; + } + + export namespace Blur { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageOpen { + root: PageOpen.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageOpen.Warnings.Item[]; + } + + export namespace PageOpen { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageClose { + root: PageClose.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageClose.Warnings.Item[]; + } + + export namespace PageClose { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageVisible { + root: PageVisible.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageVisible.Warnings.Item[]; + } + + export namespace PageVisible { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageInvisible { + root: PageInvisible.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageInvisible.Warnings.Item[]; + } + + export namespace PageInvisible { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + } + + export interface Color { + r: number; + g: number; + b: number; + } + + export type QuadPoints = QuadPoints.Item[]; + + export namespace QuadPoints { + export interface Item { + p1: Item.P1; + p2: Item.P2; + p3: Item.P3; + p4: Item.P4; + } + + export namespace Item { + export interface P1 { + x: number; + y: number; + } + + export interface P2 { + x: number; + y: number; + } + + export interface P3 { + x: number; + y: number; + } + + export interface P4 { + x: number; + y: number; + } + } + } + } + + export interface Underline { + subtype: "underline"; + ref: CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemUnderlineRef; + pageObjectNumber: number; + index: number; + identityQuality: DocAnnotationsList200ResponseAnnotationsItemUnderline.IdentityQuality; + nm: string | null; + flags: DocAnnotationsList200ResponseAnnotationsItemUnderline.Flags; + rect: DocAnnotationsList200ResponseAnnotationsItemUnderline.Rect; + contents: string | null; + author: string | null; + created: string | null; + modified: string | null; + blendMode: DocAnnotationsList200ResponseAnnotationsItemUnderline.BlendMode; + inReplyTo: CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemUnderlineInReplyTo | null; + replyType: DocAnnotationsList200ResponseAnnotationsItemUnderline.ReplyType | null; + userId?: string | undefined; + groupId?: string | undefined; + createdBy?: string | undefined; + updatedBy?: string | undefined; + actions?: DocAnnotationsList200ResponseAnnotationsItemUnderline.Actions | undefined; + color: DocAnnotationsList200ResponseAnnotationsItemUnderline.Color; + opacity: number; + quadPoints: DocAnnotationsList200ResponseAnnotationsItemUnderline.QuadPoints.Item[]; + } + + export namespace DocAnnotationsList200ResponseAnnotationsItemUnderline { + export const IdentityQuality = { + Durable: "durable", + Weak: "weak", + } as const; + export type IdentityQuality = (typeof IdentityQuality)[keyof typeof IdentityQuality]; + + export interface Flags { + invisible: boolean; + hidden: boolean; + print: boolean; + noZoom: boolean; + noRotate: boolean; + noView: boolean; + readOnly: boolean; + locked: boolean; + toggleNoView: boolean; + lockedContents: boolean; + } + + export interface Rect { + left: number; + bottom: number; + right: number; + top: number; + } + + export const BlendMode = { + Normal: "normal", + Multiply: "multiply", + Screen: "screen", + Overlay: "overlay", + Darken: "darken", + Lighten: "lighten", + ColorDodge: "color-dodge", + ColorBurn: "color-burn", + HardLight: "hard-light", + SoftLight: "soft-light", + Difference: "difference", + Exclusion: "exclusion", + Hue: "hue", + Saturation: "saturation", + Color: "color", + Luminosity: "luminosity", + } as const; + export type BlendMode = (typeof BlendMode)[keyof typeof BlendMode]; + export const ReplyType = { + Reply: "reply", + Group: "group", + } as const; + export type ReplyType = (typeof ReplyType)[keyof typeof ReplyType]; + + export interface Actions { + activate?: Actions.Activate | undefined; + cursorEnter?: Actions.CursorEnter | undefined; + cursorExit?: Actions.CursorExit | undefined; + mouseDown?: Actions.MouseDown | undefined; + mouseUp?: Actions.MouseUp | undefined; + focus?: Actions.Focus | undefined; + blur?: Actions.Blur | undefined; + pageOpen?: Actions.PageOpen | undefined; + pageClose?: Actions.PageClose | undefined; + pageVisible?: Actions.PageVisible | undefined; + pageInvisible?: Actions.PageInvisible | undefined; + } + + export namespace Actions { + export interface Activate { + root: Activate.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Activate.Warnings.Item[]; + } + + export namespace Activate { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface CursorEnter { + root: CursorEnter.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: CursorEnter.Warnings.Item[]; + } + + export namespace CursorEnter { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface CursorExit { + root: CursorExit.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: CursorExit.Warnings.Item[]; + } + + export namespace CursorExit { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface MouseDown { + root: MouseDown.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: MouseDown.Warnings.Item[]; + } + + export namespace MouseDown { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface MouseUp { + root: MouseUp.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: MouseUp.Warnings.Item[]; + } + + export namespace MouseUp { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface Focus { + root: Focus.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Focus.Warnings.Item[]; + } + + export namespace Focus { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface Blur { + root: Blur.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Blur.Warnings.Item[]; + } + + export namespace Blur { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageOpen { + root: PageOpen.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageOpen.Warnings.Item[]; + } + + export namespace PageOpen { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageClose { + root: PageClose.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageClose.Warnings.Item[]; + } + + export namespace PageClose { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageVisible { + root: PageVisible.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageVisible.Warnings.Item[]; + } + + export namespace PageVisible { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageInvisible { + root: PageInvisible.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageInvisible.Warnings.Item[]; + } + + export namespace PageInvisible { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + } + + export interface Color { + r: number; + g: number; + b: number; + } + + export type QuadPoints = QuadPoints.Item[]; + + export namespace QuadPoints { + export interface Item { + p1: Item.P1; + p2: Item.P2; + p3: Item.P3; + p4: Item.P4; + } + + export namespace Item { + export interface P1 { + x: number; + y: number; + } + + export interface P2 { + x: number; + y: number; + } + + export interface P3 { + x: number; + y: number; + } + + export interface P4 { + x: number; + y: number; + } + } + } + } + + export interface Squiggly { + subtype: "squiggly"; + ref: CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemSquigglyRef; + pageObjectNumber: number; + index: number; + identityQuality: DocAnnotationsList200ResponseAnnotationsItemSquiggly.IdentityQuality; + nm: string | null; + flags: DocAnnotationsList200ResponseAnnotationsItemSquiggly.Flags; + rect: DocAnnotationsList200ResponseAnnotationsItemSquiggly.Rect; + contents: string | null; + author: string | null; + created: string | null; + modified: string | null; + blendMode: DocAnnotationsList200ResponseAnnotationsItemSquiggly.BlendMode; + inReplyTo: CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemSquigglyInReplyTo | null; + replyType: DocAnnotationsList200ResponseAnnotationsItemSquiggly.ReplyType | null; + userId?: string | undefined; + groupId?: string | undefined; + createdBy?: string | undefined; + updatedBy?: string | undefined; + actions?: DocAnnotationsList200ResponseAnnotationsItemSquiggly.Actions | undefined; + color: DocAnnotationsList200ResponseAnnotationsItemSquiggly.Color; + opacity: number; + quadPoints: DocAnnotationsList200ResponseAnnotationsItemSquiggly.QuadPoints.Item[]; + } + + export namespace DocAnnotationsList200ResponseAnnotationsItemSquiggly { + export const IdentityQuality = { + Durable: "durable", + Weak: "weak", + } as const; + export type IdentityQuality = (typeof IdentityQuality)[keyof typeof IdentityQuality]; + + export interface Flags { + invisible: boolean; + hidden: boolean; + print: boolean; + noZoom: boolean; + noRotate: boolean; + noView: boolean; + readOnly: boolean; + locked: boolean; + toggleNoView: boolean; + lockedContents: boolean; + } + + export interface Rect { + left: number; + bottom: number; + right: number; + top: number; + } + + export const BlendMode = { + Normal: "normal", + Multiply: "multiply", + Screen: "screen", + Overlay: "overlay", + Darken: "darken", + Lighten: "lighten", + ColorDodge: "color-dodge", + ColorBurn: "color-burn", + HardLight: "hard-light", + SoftLight: "soft-light", + Difference: "difference", + Exclusion: "exclusion", + Hue: "hue", + Saturation: "saturation", + Color: "color", + Luminosity: "luminosity", + } as const; + export type BlendMode = (typeof BlendMode)[keyof typeof BlendMode]; + export const ReplyType = { + Reply: "reply", + Group: "group", + } as const; + export type ReplyType = (typeof ReplyType)[keyof typeof ReplyType]; + + export interface Actions { + activate?: Actions.Activate | undefined; + cursorEnter?: Actions.CursorEnter | undefined; + cursorExit?: Actions.CursorExit | undefined; + mouseDown?: Actions.MouseDown | undefined; + mouseUp?: Actions.MouseUp | undefined; + focus?: Actions.Focus | undefined; + blur?: Actions.Blur | undefined; + pageOpen?: Actions.PageOpen | undefined; + pageClose?: Actions.PageClose | undefined; + pageVisible?: Actions.PageVisible | undefined; + pageInvisible?: Actions.PageInvisible | undefined; + } + + export namespace Actions { + export interface Activate { + root: Activate.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Activate.Warnings.Item[]; + } + + export namespace Activate { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface CursorEnter { + root: CursorEnter.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: CursorEnter.Warnings.Item[]; + } + + export namespace CursorEnter { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface CursorExit { + root: CursorExit.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: CursorExit.Warnings.Item[]; + } + + export namespace CursorExit { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface MouseDown { + root: MouseDown.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: MouseDown.Warnings.Item[]; + } + + export namespace MouseDown { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface MouseUp { + root: MouseUp.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: MouseUp.Warnings.Item[]; + } + + export namespace MouseUp { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface Focus { + root: Focus.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Focus.Warnings.Item[]; + } + + export namespace Focus { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface Blur { + root: Blur.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Blur.Warnings.Item[]; + } + + export namespace Blur { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageOpen { + root: PageOpen.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageOpen.Warnings.Item[]; + } + + export namespace PageOpen { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageClose { + root: PageClose.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageClose.Warnings.Item[]; + } + + export namespace PageClose { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageVisible { + root: PageVisible.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageVisible.Warnings.Item[]; + } + + export namespace PageVisible { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageInvisible { + root: PageInvisible.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageInvisible.Warnings.Item[]; + } + + export namespace PageInvisible { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + } + + export interface Color { + r: number; + g: number; + b: number; + } + + export type QuadPoints = QuadPoints.Item[]; + + export namespace QuadPoints { + export interface Item { + p1: Item.P1; + p2: Item.P2; + p3: Item.P3; + p4: Item.P4; + } + + export namespace Item { + export interface P1 { + x: number; + y: number; + } + + export interface P2 { + x: number; + y: number; + } + + export interface P3 { + x: number; + y: number; + } + + export interface P4 { + x: number; + y: number; + } + } + } + } + + export interface Strikeout { + subtype: "strikeout"; + ref: CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemStrikeoutRef; + pageObjectNumber: number; + index: number; + identityQuality: DocAnnotationsList200ResponseAnnotationsItemStrikeout.IdentityQuality; + nm: string | null; + flags: DocAnnotationsList200ResponseAnnotationsItemStrikeout.Flags; + rect: DocAnnotationsList200ResponseAnnotationsItemStrikeout.Rect; + contents: string | null; + author: string | null; + created: string | null; + modified: string | null; + blendMode: DocAnnotationsList200ResponseAnnotationsItemStrikeout.BlendMode; + inReplyTo: CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemStrikeoutInReplyTo | null; + replyType: DocAnnotationsList200ResponseAnnotationsItemStrikeout.ReplyType | null; + userId?: string | undefined; + groupId?: string | undefined; + createdBy?: string | undefined; + updatedBy?: string | undefined; + actions?: DocAnnotationsList200ResponseAnnotationsItemStrikeout.Actions | undefined; + color: DocAnnotationsList200ResponseAnnotationsItemStrikeout.Color; + opacity: number; + quadPoints: DocAnnotationsList200ResponseAnnotationsItemStrikeout.QuadPoints.Item[]; + intent: DocAnnotationsList200ResponseAnnotationsItemStrikeout.Intent | null; + } + + export namespace DocAnnotationsList200ResponseAnnotationsItemStrikeout { + export const IdentityQuality = { + Durable: "durable", + Weak: "weak", + } as const; + export type IdentityQuality = (typeof IdentityQuality)[keyof typeof IdentityQuality]; + + export interface Flags { + invisible: boolean; + hidden: boolean; + print: boolean; + noZoom: boolean; + noRotate: boolean; + noView: boolean; + readOnly: boolean; + locked: boolean; + toggleNoView: boolean; + lockedContents: boolean; + } + + export interface Rect { + left: number; + bottom: number; + right: number; + top: number; + } + + export const BlendMode = { + Normal: "normal", + Multiply: "multiply", + Screen: "screen", + Overlay: "overlay", + Darken: "darken", + Lighten: "lighten", + ColorDodge: "color-dodge", + ColorBurn: "color-burn", + HardLight: "hard-light", + SoftLight: "soft-light", + Difference: "difference", + Exclusion: "exclusion", + Hue: "hue", + Saturation: "saturation", + Color: "color", + Luminosity: "luminosity", + } as const; + export type BlendMode = (typeof BlendMode)[keyof typeof BlendMode]; + export const ReplyType = { + Reply: "reply", + Group: "group", + } as const; + export type ReplyType = (typeof ReplyType)[keyof typeof ReplyType]; + + export interface Actions { + activate?: Actions.Activate | undefined; + cursorEnter?: Actions.CursorEnter | undefined; + cursorExit?: Actions.CursorExit | undefined; + mouseDown?: Actions.MouseDown | undefined; + mouseUp?: Actions.MouseUp | undefined; + focus?: Actions.Focus | undefined; + blur?: Actions.Blur | undefined; + pageOpen?: Actions.PageOpen | undefined; + pageClose?: Actions.PageClose | undefined; + pageVisible?: Actions.PageVisible | undefined; + pageInvisible?: Actions.PageInvisible | undefined; + } + + export namespace Actions { + export interface Activate { + root: Activate.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Activate.Warnings.Item[]; + } + + export namespace Activate { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface CursorEnter { + root: CursorEnter.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: CursorEnter.Warnings.Item[]; + } + + export namespace CursorEnter { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface CursorExit { + root: CursorExit.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: CursorExit.Warnings.Item[]; + } + + export namespace CursorExit { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface MouseDown { + root: MouseDown.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: MouseDown.Warnings.Item[]; + } + + export namespace MouseDown { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface MouseUp { + root: MouseUp.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: MouseUp.Warnings.Item[]; + } + + export namespace MouseUp { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface Focus { + root: Focus.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Focus.Warnings.Item[]; + } + + export namespace Focus { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface Blur { + root: Blur.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Blur.Warnings.Item[]; + } + + export namespace Blur { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageOpen { + root: PageOpen.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageOpen.Warnings.Item[]; + } + + export namespace PageOpen { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageClose { + root: PageClose.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageClose.Warnings.Item[]; + } + + export namespace PageClose { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageVisible { + root: PageVisible.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageVisible.Warnings.Item[]; + } + + export namespace PageVisible { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageInvisible { + root: PageInvisible.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageInvisible.Warnings.Item[]; + } + + export namespace PageInvisible { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + } + + export interface Color { + r: number; + g: number; + b: number; + } + + export type QuadPoints = QuadPoints.Item[]; + + export namespace QuadPoints { + export interface Item { + p1: Item.P1; + p2: Item.P2; + p3: Item.P3; + p4: Item.P4; + } + + export namespace Item { + export interface P1 { + x: number; + y: number; + } + + export interface P2 { + x: number; + y: number; + } + + export interface P3 { + x: number; + y: number; + } + + export interface P4 { + x: number; + y: number; + } + } + } + + export const Intent = { + StrikeoutTextEdit: "strikeout-text-edit", + } as const; + export type Intent = (typeof Intent)[keyof typeof Intent]; + } + + export interface Circle { + subtype: "circle"; + ref: CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemCircleRef; + pageObjectNumber: number; + index: number; + identityQuality: DocAnnotationsList200ResponseAnnotationsItemCircle.IdentityQuality; + nm: string | null; + flags: DocAnnotationsList200ResponseAnnotationsItemCircle.Flags; + rect: DocAnnotationsList200ResponseAnnotationsItemCircle.Rect; + contents: string | null; + author: string | null; + created: string | null; + modified: string | null; + blendMode: DocAnnotationsList200ResponseAnnotationsItemCircle.BlendMode; + inReplyTo: CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemCircleInReplyTo | null; + replyType: DocAnnotationsList200ResponseAnnotationsItemCircle.ReplyType | null; + userId?: string | undefined; + groupId?: string | undefined; + createdBy?: string | undefined; + updatedBy?: string | undefined; + actions?: DocAnnotationsList200ResponseAnnotationsItemCircle.Actions | undefined; + color: DocAnnotationsList200ResponseAnnotationsItemCircle.Color; + opacity: number; + strokeWidth: number; + borderStyle: DocAnnotationsList200ResponseAnnotationsItemCircle.BorderStyle; + dashArray?: number[] | undefined; + interiorColor: DocAnnotationsList200ResponseAnnotationsItemCircle.InteriorColor | null; + cloudyIntensity: number | null; + rectDifferences: DocAnnotationsList200ResponseAnnotationsItemCircle.RectDifferences | null; + rotation?: number | undefined; + unrotatedRect?: DocAnnotationsList200ResponseAnnotationsItemCircle.UnrotatedRect | undefined; + } + + export namespace DocAnnotationsList200ResponseAnnotationsItemCircle { + export const IdentityQuality = { + Durable: "durable", + Weak: "weak", + } as const; + export type IdentityQuality = (typeof IdentityQuality)[keyof typeof IdentityQuality]; + + export interface Flags { + invisible: boolean; + hidden: boolean; + print: boolean; + noZoom: boolean; + noRotate: boolean; + noView: boolean; + readOnly: boolean; + locked: boolean; + toggleNoView: boolean; + lockedContents: boolean; + } + + export interface Rect { + left: number; + bottom: number; + right: number; + top: number; + } + + export const BlendMode = { + Normal: "normal", + Multiply: "multiply", + Screen: "screen", + Overlay: "overlay", + Darken: "darken", + Lighten: "lighten", + ColorDodge: "color-dodge", + ColorBurn: "color-burn", + HardLight: "hard-light", + SoftLight: "soft-light", + Difference: "difference", + Exclusion: "exclusion", + Hue: "hue", + Saturation: "saturation", + Color: "color", + Luminosity: "luminosity", + } as const; + export type BlendMode = (typeof BlendMode)[keyof typeof BlendMode]; + export const ReplyType = { + Reply: "reply", + Group: "group", + } as const; + export type ReplyType = (typeof ReplyType)[keyof typeof ReplyType]; + + export interface Actions { + activate?: Actions.Activate | undefined; + cursorEnter?: Actions.CursorEnter | undefined; + cursorExit?: Actions.CursorExit | undefined; + mouseDown?: Actions.MouseDown | undefined; + mouseUp?: Actions.MouseUp | undefined; + focus?: Actions.Focus | undefined; + blur?: Actions.Blur | undefined; + pageOpen?: Actions.PageOpen | undefined; + pageClose?: Actions.PageClose | undefined; + pageVisible?: Actions.PageVisible | undefined; + pageInvisible?: Actions.PageInvisible | undefined; + } + + export namespace Actions { + export interface Activate { + root: Activate.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Activate.Warnings.Item[]; + } + + export namespace Activate { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface CursorEnter { + root: CursorEnter.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: CursorEnter.Warnings.Item[]; + } + + export namespace CursorEnter { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface CursorExit { + root: CursorExit.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: CursorExit.Warnings.Item[]; + } + + export namespace CursorExit { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface MouseDown { + root: MouseDown.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: MouseDown.Warnings.Item[]; + } + + export namespace MouseDown { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface MouseUp { + root: MouseUp.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: MouseUp.Warnings.Item[]; + } + + export namespace MouseUp { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface Focus { + root: Focus.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Focus.Warnings.Item[]; + } + + export namespace Focus { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface Blur { + root: Blur.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Blur.Warnings.Item[]; + } + + export namespace Blur { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageOpen { + root: PageOpen.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageOpen.Warnings.Item[]; + } + + export namespace PageOpen { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageClose { + root: PageClose.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageClose.Warnings.Item[]; + } + + export namespace PageClose { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageVisible { + root: PageVisible.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageVisible.Warnings.Item[]; + } + + export namespace PageVisible { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageInvisible { + root: PageInvisible.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageInvisible.Warnings.Item[]; + } + + export namespace PageInvisible { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + } + + export interface Color { + r: number; + g: number; + b: number; + } + + export const BorderStyle = { + Solid: "solid", + Dashed: "dashed", + Beveled: "beveled", + Inset: "inset", + } as const; + export type BorderStyle = (typeof BorderStyle)[keyof typeof BorderStyle]; + + export interface InteriorColor { + r: number; + g: number; + b: number; + } + + export interface RectDifferences { + left: number; + top: number; + right: number; + bottom: number; + } + + export interface UnrotatedRect { + left: number; + bottom: number; + right: number; + top: number; + } + } + + export interface Square { + subtype: "square"; + ref: CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemSquareRef; + pageObjectNumber: number; + index: number; + identityQuality: DocAnnotationsList200ResponseAnnotationsItemSquare.IdentityQuality; + nm: string | null; + flags: DocAnnotationsList200ResponseAnnotationsItemSquare.Flags; + rect: DocAnnotationsList200ResponseAnnotationsItemSquare.Rect; + contents: string | null; + author: string | null; + created: string | null; + modified: string | null; + blendMode: DocAnnotationsList200ResponseAnnotationsItemSquare.BlendMode; + inReplyTo: CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemSquareInReplyTo | null; + replyType: DocAnnotationsList200ResponseAnnotationsItemSquare.ReplyType | null; + userId?: string | undefined; + groupId?: string | undefined; + createdBy?: string | undefined; + updatedBy?: string | undefined; + actions?: DocAnnotationsList200ResponseAnnotationsItemSquare.Actions | undefined; + color: DocAnnotationsList200ResponseAnnotationsItemSquare.Color; + opacity: number; + strokeWidth: number; + borderStyle: DocAnnotationsList200ResponseAnnotationsItemSquare.BorderStyle; + dashArray?: number[] | undefined; + interiorColor: DocAnnotationsList200ResponseAnnotationsItemSquare.InteriorColor | null; + cloudyIntensity: number | null; + rectDifferences: DocAnnotationsList200ResponseAnnotationsItemSquare.RectDifferences | null; + rotation?: number | undefined; + unrotatedRect?: DocAnnotationsList200ResponseAnnotationsItemSquare.UnrotatedRect | undefined; + } + + export namespace DocAnnotationsList200ResponseAnnotationsItemSquare { + export const IdentityQuality = { + Durable: "durable", + Weak: "weak", + } as const; + export type IdentityQuality = (typeof IdentityQuality)[keyof typeof IdentityQuality]; + + export interface Flags { + invisible: boolean; + hidden: boolean; + print: boolean; + noZoom: boolean; + noRotate: boolean; + noView: boolean; + readOnly: boolean; + locked: boolean; + toggleNoView: boolean; + lockedContents: boolean; + } + + export interface Rect { + left: number; + bottom: number; + right: number; + top: number; + } + + export const BlendMode = { + Normal: "normal", + Multiply: "multiply", + Screen: "screen", + Overlay: "overlay", + Darken: "darken", + Lighten: "lighten", + ColorDodge: "color-dodge", + ColorBurn: "color-burn", + HardLight: "hard-light", + SoftLight: "soft-light", + Difference: "difference", + Exclusion: "exclusion", + Hue: "hue", + Saturation: "saturation", + Color: "color", + Luminosity: "luminosity", + } as const; + export type BlendMode = (typeof BlendMode)[keyof typeof BlendMode]; + export const ReplyType = { + Reply: "reply", + Group: "group", + } as const; + export type ReplyType = (typeof ReplyType)[keyof typeof ReplyType]; + + export interface Actions { + activate?: Actions.Activate | undefined; + cursorEnter?: Actions.CursorEnter | undefined; + cursorExit?: Actions.CursorExit | undefined; + mouseDown?: Actions.MouseDown | undefined; + mouseUp?: Actions.MouseUp | undefined; + focus?: Actions.Focus | undefined; + blur?: Actions.Blur | undefined; + pageOpen?: Actions.PageOpen | undefined; + pageClose?: Actions.PageClose | undefined; + pageVisible?: Actions.PageVisible | undefined; + pageInvisible?: Actions.PageInvisible | undefined; + } + + export namespace Actions { + export interface Activate { + root: Activate.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Activate.Warnings.Item[]; + } + + export namespace Activate { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface CursorEnter { + root: CursorEnter.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: CursorEnter.Warnings.Item[]; + } + + export namespace CursorEnter { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface CursorExit { + root: CursorExit.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: CursorExit.Warnings.Item[]; + } + + export namespace CursorExit { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface MouseDown { + root: MouseDown.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: MouseDown.Warnings.Item[]; + } + + export namespace MouseDown { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface MouseUp { + root: MouseUp.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: MouseUp.Warnings.Item[]; + } + + export namespace MouseUp { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface Focus { + root: Focus.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Focus.Warnings.Item[]; + } + + export namespace Focus { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface Blur { + root: Blur.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Blur.Warnings.Item[]; + } + + export namespace Blur { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageOpen { + root: PageOpen.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageOpen.Warnings.Item[]; + } + + export namespace PageOpen { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageClose { + root: PageClose.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageClose.Warnings.Item[]; + } + + export namespace PageClose { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageVisible { + root: PageVisible.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageVisible.Warnings.Item[]; + } + + export namespace PageVisible { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageInvisible { + root: PageInvisible.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageInvisible.Warnings.Item[]; + } + + export namespace PageInvisible { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + } + + export interface Color { + r: number; + g: number; + b: number; + } + + export const BorderStyle = { + Solid: "solid", + Dashed: "dashed", + Beveled: "beveled", + Inset: "inset", + } as const; + export type BorderStyle = (typeof BorderStyle)[keyof typeof BorderStyle]; + + export interface InteriorColor { + r: number; + g: number; + b: number; + } + + export interface RectDifferences { + left: number; + top: number; + right: number; + bottom: number; + } + + export interface UnrotatedRect { + left: number; + bottom: number; + right: number; + top: number; + } + } + + export interface Polygon { + subtype: "polygon"; + ref: CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemPolygonRef; + pageObjectNumber: number; + index: number; + identityQuality: DocAnnotationsList200ResponseAnnotationsItemPolygon.IdentityQuality; + nm: string | null; + flags: DocAnnotationsList200ResponseAnnotationsItemPolygon.Flags; + rect: DocAnnotationsList200ResponseAnnotationsItemPolygon.Rect; + contents: string | null; + author: string | null; + created: string | null; + modified: string | null; + blendMode: DocAnnotationsList200ResponseAnnotationsItemPolygon.BlendMode; + inReplyTo: CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemPolygonInReplyTo | null; + replyType: DocAnnotationsList200ResponseAnnotationsItemPolygon.ReplyType | null; + userId?: string | undefined; + groupId?: string | undefined; + createdBy?: string | undefined; + updatedBy?: string | undefined; + actions?: DocAnnotationsList200ResponseAnnotationsItemPolygon.Actions | undefined; + color: DocAnnotationsList200ResponseAnnotationsItemPolygon.Color; + opacity: number; + strokeWidth: number; + borderStyle: DocAnnotationsList200ResponseAnnotationsItemPolygon.BorderStyle; + dashArray?: number[] | undefined; + interiorColor: DocAnnotationsList200ResponseAnnotationsItemPolygon.InteriorColor | null; + vertices: DocAnnotationsList200ResponseAnnotationsItemPolygon.Vertices.Item[]; + rotation?: number | undefined; + cloudyIntensity: number | null; + } + + export namespace DocAnnotationsList200ResponseAnnotationsItemPolygon { + export const IdentityQuality = { + Durable: "durable", + Weak: "weak", + } as const; + export type IdentityQuality = (typeof IdentityQuality)[keyof typeof IdentityQuality]; + + export interface Flags { + invisible: boolean; + hidden: boolean; + print: boolean; + noZoom: boolean; + noRotate: boolean; + noView: boolean; + readOnly: boolean; + locked: boolean; + toggleNoView: boolean; + lockedContents: boolean; + } + + export interface Rect { + left: number; + bottom: number; + right: number; + top: number; + } + + export const BlendMode = { + Normal: "normal", + Multiply: "multiply", + Screen: "screen", + Overlay: "overlay", + Darken: "darken", + Lighten: "lighten", + ColorDodge: "color-dodge", + ColorBurn: "color-burn", + HardLight: "hard-light", + SoftLight: "soft-light", + Difference: "difference", + Exclusion: "exclusion", + Hue: "hue", + Saturation: "saturation", + Color: "color", + Luminosity: "luminosity", + } as const; + export type BlendMode = (typeof BlendMode)[keyof typeof BlendMode]; + export const ReplyType = { + Reply: "reply", + Group: "group", + } as const; + export type ReplyType = (typeof ReplyType)[keyof typeof ReplyType]; + + export interface Actions { + activate?: Actions.Activate | undefined; + cursorEnter?: Actions.CursorEnter | undefined; + cursorExit?: Actions.CursorExit | undefined; + mouseDown?: Actions.MouseDown | undefined; + mouseUp?: Actions.MouseUp | undefined; + focus?: Actions.Focus | undefined; + blur?: Actions.Blur | undefined; + pageOpen?: Actions.PageOpen | undefined; + pageClose?: Actions.PageClose | undefined; + pageVisible?: Actions.PageVisible | undefined; + pageInvisible?: Actions.PageInvisible | undefined; + } + + export namespace Actions { + export interface Activate { + root: Activate.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Activate.Warnings.Item[]; + } + + export namespace Activate { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface CursorEnter { + root: CursorEnter.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: CursorEnter.Warnings.Item[]; + } + + export namespace CursorEnter { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface CursorExit { + root: CursorExit.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: CursorExit.Warnings.Item[]; + } + + export namespace CursorExit { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface MouseDown { + root: MouseDown.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: MouseDown.Warnings.Item[]; + } + + export namespace MouseDown { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface MouseUp { + root: MouseUp.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: MouseUp.Warnings.Item[]; + } + + export namespace MouseUp { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface Focus { + root: Focus.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Focus.Warnings.Item[]; + } + + export namespace Focus { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface Blur { + root: Blur.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Blur.Warnings.Item[]; + } + + export namespace Blur { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageOpen { + root: PageOpen.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageOpen.Warnings.Item[]; + } + + export namespace PageOpen { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageClose { + root: PageClose.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageClose.Warnings.Item[]; + } + + export namespace PageClose { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageVisible { + root: PageVisible.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageVisible.Warnings.Item[]; + } + + export namespace PageVisible { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageInvisible { + root: PageInvisible.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageInvisible.Warnings.Item[]; + } + + export namespace PageInvisible { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + } + + export interface Color { + r: number; + g: number; + b: number; + } + + export const BorderStyle = { + Solid: "solid", + Dashed: "dashed", + Beveled: "beveled", + Inset: "inset", + } as const; + export type BorderStyle = (typeof BorderStyle)[keyof typeof BorderStyle]; + + export interface InteriorColor { + r: number; + g: number; + b: number; + } + + export type Vertices = Vertices.Item[]; + + export namespace Vertices { + export interface Item { + x: number; + y: number; + } + } + } + + export interface Polyline { + subtype: "polyline"; + ref: CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemPolylineRef; + pageObjectNumber: number; + index: number; + identityQuality: DocAnnotationsList200ResponseAnnotationsItemPolyline.IdentityQuality; + nm: string | null; + flags: DocAnnotationsList200ResponseAnnotationsItemPolyline.Flags; + rect: DocAnnotationsList200ResponseAnnotationsItemPolyline.Rect; + contents: string | null; + author: string | null; + created: string | null; + modified: string | null; + blendMode: DocAnnotationsList200ResponseAnnotationsItemPolyline.BlendMode; + inReplyTo: CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemPolylineInReplyTo | null; + replyType: DocAnnotationsList200ResponseAnnotationsItemPolyline.ReplyType | null; + userId?: string | undefined; + groupId?: string | undefined; + createdBy?: string | undefined; + updatedBy?: string | undefined; + actions?: DocAnnotationsList200ResponseAnnotationsItemPolyline.Actions | undefined; + color: DocAnnotationsList200ResponseAnnotationsItemPolyline.Color; + opacity: number; + strokeWidth: number; + borderStyle: DocAnnotationsList200ResponseAnnotationsItemPolyline.BorderStyle; + dashArray?: number[] | undefined; + interiorColor: DocAnnotationsList200ResponseAnnotationsItemPolyline.InteriorColor | null; + vertices: DocAnnotationsList200ResponseAnnotationsItemPolyline.Vertices.Item[]; + rotation?: number | undefined; + lineEndings: DocAnnotationsList200ResponseAnnotationsItemPolyline.LineEndings; + } + + export namespace DocAnnotationsList200ResponseAnnotationsItemPolyline { + export const IdentityQuality = { + Durable: "durable", + Weak: "weak", + } as const; + export type IdentityQuality = (typeof IdentityQuality)[keyof typeof IdentityQuality]; + + export interface Flags { + invisible: boolean; + hidden: boolean; + print: boolean; + noZoom: boolean; + noRotate: boolean; + noView: boolean; + readOnly: boolean; + locked: boolean; + toggleNoView: boolean; + lockedContents: boolean; + } + + export interface Rect { + left: number; + bottom: number; + right: number; + top: number; + } + + export const BlendMode = { + Normal: "normal", + Multiply: "multiply", + Screen: "screen", + Overlay: "overlay", + Darken: "darken", + Lighten: "lighten", + ColorDodge: "color-dodge", + ColorBurn: "color-burn", + HardLight: "hard-light", + SoftLight: "soft-light", + Difference: "difference", + Exclusion: "exclusion", + Hue: "hue", + Saturation: "saturation", + Color: "color", + Luminosity: "luminosity", + } as const; + export type BlendMode = (typeof BlendMode)[keyof typeof BlendMode]; + export const ReplyType = { + Reply: "reply", + Group: "group", + } as const; + export type ReplyType = (typeof ReplyType)[keyof typeof ReplyType]; + + export interface Actions { + activate?: Actions.Activate | undefined; + cursorEnter?: Actions.CursorEnter | undefined; + cursorExit?: Actions.CursorExit | undefined; + mouseDown?: Actions.MouseDown | undefined; + mouseUp?: Actions.MouseUp | undefined; + focus?: Actions.Focus | undefined; + blur?: Actions.Blur | undefined; + pageOpen?: Actions.PageOpen | undefined; + pageClose?: Actions.PageClose | undefined; + pageVisible?: Actions.PageVisible | undefined; + pageInvisible?: Actions.PageInvisible | undefined; + } + + export namespace Actions { + export interface Activate { + root: Activate.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Activate.Warnings.Item[]; + } + + export namespace Activate { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface CursorEnter { + root: CursorEnter.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: CursorEnter.Warnings.Item[]; + } + + export namespace CursorEnter { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface CursorExit { + root: CursorExit.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: CursorExit.Warnings.Item[]; + } + + export namespace CursorExit { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface MouseDown { + root: MouseDown.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: MouseDown.Warnings.Item[]; + } + + export namespace MouseDown { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface MouseUp { + root: MouseUp.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: MouseUp.Warnings.Item[]; + } + + export namespace MouseUp { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface Focus { + root: Focus.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Focus.Warnings.Item[]; + } + + export namespace Focus { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface Blur { + root: Blur.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Blur.Warnings.Item[]; + } + + export namespace Blur { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageOpen { + root: PageOpen.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageOpen.Warnings.Item[]; + } + + export namespace PageOpen { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageClose { + root: PageClose.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageClose.Warnings.Item[]; + } + + export namespace PageClose { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageVisible { + root: PageVisible.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageVisible.Warnings.Item[]; + } + + export namespace PageVisible { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageInvisible { + root: PageInvisible.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageInvisible.Warnings.Item[]; + } + + export namespace PageInvisible { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + } + + export interface Color { + r: number; + g: number; + b: number; + } + + export const BorderStyle = { + Solid: "solid", + Dashed: "dashed", + Beveled: "beveled", + Inset: "inset", + } as const; + export type BorderStyle = (typeof BorderStyle)[keyof typeof BorderStyle]; + + export interface InteriorColor { + r: number; + g: number; + b: number; + } + + export type Vertices = Vertices.Item[]; + + export namespace Vertices { + export interface Item { + x: number; + y: number; + } + } + + export interface LineEndings { + start: LineEndings.Start; + end: LineEndings.End; + } + + export namespace LineEndings { + export const Start = { + None: "none", + Square: "square", + Circle: "circle", + Diamond: "diamond", + OpenArrow: "open-arrow", + ClosedArrow: "closed-arrow", + Butt: "butt", + ROpenArrow: "r-open-arrow", + RClosedArrow: "r-closed-arrow", + Slash: "slash", + } as const; + export type Start = (typeof Start)[keyof typeof Start]; + export const End = { + None: "none", + Square: "square", + Circle: "circle", + Diamond: "diamond", + OpenArrow: "open-arrow", + ClosedArrow: "closed-arrow", + Butt: "butt", + ROpenArrow: "r-open-arrow", + RClosedArrow: "r-closed-arrow", + Slash: "slash", + } as const; + export type End = (typeof End)[keyof typeof End]; + } + } + + export interface Line { + subtype: "line"; + ref: CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemLineRef; + pageObjectNumber: number; + index: number; + identityQuality: DocAnnotationsList200ResponseAnnotationsItemLine.IdentityQuality; + nm: string | null; + flags: DocAnnotationsList200ResponseAnnotationsItemLine.Flags; + rect: DocAnnotationsList200ResponseAnnotationsItemLine.Rect; + contents: string | null; + author: string | null; + created: string | null; + modified: string | null; + blendMode: DocAnnotationsList200ResponseAnnotationsItemLine.BlendMode; + inReplyTo: CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemLineInReplyTo | null; + replyType: DocAnnotationsList200ResponseAnnotationsItemLine.ReplyType | null; + userId?: string | undefined; + groupId?: string | undefined; + createdBy?: string | undefined; + updatedBy?: string | undefined; + actions?: DocAnnotationsList200ResponseAnnotationsItemLine.Actions | undefined; + color: DocAnnotationsList200ResponseAnnotationsItemLine.Color; + opacity: number; + strokeWidth: number; + borderStyle: DocAnnotationsList200ResponseAnnotationsItemLine.BorderStyle; + dashArray?: number[] | undefined; + interiorColor: DocAnnotationsList200ResponseAnnotationsItemLine.InteriorColor | null; + linePoints: DocAnnotationsList200ResponseAnnotationsItemLine.LinePoints; + lineEndings: DocAnnotationsList200ResponseAnnotationsItemLine.LineEndings; + rotation?: number | undefined; + } + + export namespace DocAnnotationsList200ResponseAnnotationsItemLine { + export const IdentityQuality = { + Durable: "durable", + Weak: "weak", + } as const; + export type IdentityQuality = (typeof IdentityQuality)[keyof typeof IdentityQuality]; + + export interface Flags { + invisible: boolean; + hidden: boolean; + print: boolean; + noZoom: boolean; + noRotate: boolean; + noView: boolean; + readOnly: boolean; + locked: boolean; + toggleNoView: boolean; + lockedContents: boolean; + } + + export interface Rect { + left: number; + bottom: number; + right: number; + top: number; + } + + export const BlendMode = { + Normal: "normal", + Multiply: "multiply", + Screen: "screen", + Overlay: "overlay", + Darken: "darken", + Lighten: "lighten", + ColorDodge: "color-dodge", + ColorBurn: "color-burn", + HardLight: "hard-light", + SoftLight: "soft-light", + Difference: "difference", + Exclusion: "exclusion", + Hue: "hue", + Saturation: "saturation", + Color: "color", + Luminosity: "luminosity", + } as const; + export type BlendMode = (typeof BlendMode)[keyof typeof BlendMode]; + export const ReplyType = { + Reply: "reply", + Group: "group", + } as const; + export type ReplyType = (typeof ReplyType)[keyof typeof ReplyType]; + + export interface Actions { + activate?: Actions.Activate | undefined; + cursorEnter?: Actions.CursorEnter | undefined; + cursorExit?: Actions.CursorExit | undefined; + mouseDown?: Actions.MouseDown | undefined; + mouseUp?: Actions.MouseUp | undefined; + focus?: Actions.Focus | undefined; + blur?: Actions.Blur | undefined; + pageOpen?: Actions.PageOpen | undefined; + pageClose?: Actions.PageClose | undefined; + pageVisible?: Actions.PageVisible | undefined; + pageInvisible?: Actions.PageInvisible | undefined; + } + + export namespace Actions { + export interface Activate { + root: Activate.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Activate.Warnings.Item[]; + } + + export namespace Activate { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface CursorEnter { + root: CursorEnter.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: CursorEnter.Warnings.Item[]; + } + + export namespace CursorEnter { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface CursorExit { + root: CursorExit.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: CursorExit.Warnings.Item[]; + } + + export namespace CursorExit { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface MouseDown { + root: MouseDown.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: MouseDown.Warnings.Item[]; + } + + export namespace MouseDown { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface MouseUp { + root: MouseUp.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: MouseUp.Warnings.Item[]; + } + + export namespace MouseUp { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface Focus { + root: Focus.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Focus.Warnings.Item[]; + } + + export namespace Focus { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface Blur { + root: Blur.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Blur.Warnings.Item[]; + } + + export namespace Blur { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageOpen { + root: PageOpen.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageOpen.Warnings.Item[]; + } + + export namespace PageOpen { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageClose { + root: PageClose.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageClose.Warnings.Item[]; + } + + export namespace PageClose { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageVisible { + root: PageVisible.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageVisible.Warnings.Item[]; + } + + export namespace PageVisible { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageInvisible { + root: PageInvisible.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageInvisible.Warnings.Item[]; + } + + export namespace PageInvisible { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + } + + export interface Color { + r: number; + g: number; + b: number; + } + + export const BorderStyle = { + Solid: "solid", + Dashed: "dashed", + Beveled: "beveled", + Inset: "inset", + } as const; + export type BorderStyle = (typeof BorderStyle)[keyof typeof BorderStyle]; + + export interface InteriorColor { + r: number; + g: number; + b: number; + } + + export interface LinePoints { + start: LinePoints.Start; + end: LinePoints.End; + } + + export namespace LinePoints { + export interface Start { + x: number; + y: number; + } + + export interface End { + x: number; + y: number; + } + } + + export interface LineEndings { + start: LineEndings.Start; + end: LineEndings.End; + } + + export namespace LineEndings { + export const Start = { + None: "none", + Square: "square", + Circle: "circle", + Diamond: "diamond", + OpenArrow: "open-arrow", + ClosedArrow: "closed-arrow", + Butt: "butt", + ROpenArrow: "r-open-arrow", + RClosedArrow: "r-closed-arrow", + Slash: "slash", + } as const; + export type Start = (typeof Start)[keyof typeof Start]; + export const End = { + None: "none", + Square: "square", + Circle: "circle", + Diamond: "diamond", + OpenArrow: "open-arrow", + ClosedArrow: "closed-arrow", + Butt: "butt", + ROpenArrow: "r-open-arrow", + RClosedArrow: "r-closed-arrow", + Slash: "slash", + } as const; + export type End = (typeof End)[keyof typeof End]; + } + } + + export interface Link { + subtype: "link"; + ref: CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemLinkRef; + pageObjectNumber: number; + index: number; + identityQuality: DocAnnotationsList200ResponseAnnotationsItemLink.IdentityQuality; + nm: string | null; + flags: DocAnnotationsList200ResponseAnnotationsItemLink.Flags; + rect: DocAnnotationsList200ResponseAnnotationsItemLink.Rect; + contents: string | null; + author: string | null; + created: string | null; + modified: string | null; + blendMode: DocAnnotationsList200ResponseAnnotationsItemLink.BlendMode; + inReplyTo: CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemLinkInReplyTo | null; + replyType: DocAnnotationsList200ResponseAnnotationsItemLink.ReplyType | null; + userId?: string | undefined; + groupId?: string | undefined; + createdBy?: string | undefined; + updatedBy?: string | undefined; + actions?: DocAnnotationsList200ResponseAnnotationsItemLink.Actions | undefined; + target: CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemLinkTarget | null; + } + + export namespace DocAnnotationsList200ResponseAnnotationsItemLink { + export const IdentityQuality = { + Durable: "durable", + Weak: "weak", + } as const; + export type IdentityQuality = (typeof IdentityQuality)[keyof typeof IdentityQuality]; + + export interface Flags { + invisible: boolean; + hidden: boolean; + print: boolean; + noZoom: boolean; + noRotate: boolean; + noView: boolean; + readOnly: boolean; + locked: boolean; + toggleNoView: boolean; + lockedContents: boolean; + } + + export interface Rect { + left: number; + bottom: number; + right: number; + top: number; + } + + export const BlendMode = { + Normal: "normal", + Multiply: "multiply", + Screen: "screen", + Overlay: "overlay", + Darken: "darken", + Lighten: "lighten", + ColorDodge: "color-dodge", + ColorBurn: "color-burn", + HardLight: "hard-light", + SoftLight: "soft-light", + Difference: "difference", + Exclusion: "exclusion", + Hue: "hue", + Saturation: "saturation", + Color: "color", + Luminosity: "luminosity", + } as const; + export type BlendMode = (typeof BlendMode)[keyof typeof BlendMode]; + export const ReplyType = { + Reply: "reply", + Group: "group", + } as const; + export type ReplyType = (typeof ReplyType)[keyof typeof ReplyType]; + + export interface Actions { + activate?: Actions.Activate | undefined; + cursorEnter?: Actions.CursorEnter | undefined; + cursorExit?: Actions.CursorExit | undefined; + mouseDown?: Actions.MouseDown | undefined; + mouseUp?: Actions.MouseUp | undefined; + focus?: Actions.Focus | undefined; + blur?: Actions.Blur | undefined; + pageOpen?: Actions.PageOpen | undefined; + pageClose?: Actions.PageClose | undefined; + pageVisible?: Actions.PageVisible | undefined; + pageInvisible?: Actions.PageInvisible | undefined; + } + + export namespace Actions { + export interface Activate { + root: Activate.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Activate.Warnings.Item[]; + } + + export namespace Activate { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface CursorEnter { + root: CursorEnter.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: CursorEnter.Warnings.Item[]; + } + + export namespace CursorEnter { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface CursorExit { + root: CursorExit.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: CursorExit.Warnings.Item[]; + } + + export namespace CursorExit { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface MouseDown { + root: MouseDown.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: MouseDown.Warnings.Item[]; + } + + export namespace MouseDown { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface MouseUp { + root: MouseUp.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: MouseUp.Warnings.Item[]; + } + + export namespace MouseUp { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface Focus { + root: Focus.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Focus.Warnings.Item[]; + } + + export namespace Focus { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface Blur { + root: Blur.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Blur.Warnings.Item[]; + } + + export namespace Blur { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageOpen { + root: PageOpen.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageOpen.Warnings.Item[]; + } + + export namespace PageOpen { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageClose { + root: PageClose.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageClose.Warnings.Item[]; + } + + export namespace PageClose { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageVisible { + root: PageVisible.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageVisible.Warnings.Item[]; + } + + export namespace PageVisible { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageInvisible { + root: PageInvisible.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageInvisible.Warnings.Item[]; + } + + export namespace PageInvisible { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + } + } + + export interface Ink { + subtype: "ink"; + ref: CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemInkRef; + pageObjectNumber: number; + index: number; + identityQuality: DocAnnotationsList200ResponseAnnotationsItemInk.IdentityQuality; + nm: string | null; + flags: DocAnnotationsList200ResponseAnnotationsItemInk.Flags; + rect: DocAnnotationsList200ResponseAnnotationsItemInk.Rect; + contents: string | null; + author: string | null; + created: string | null; + modified: string | null; + blendMode: DocAnnotationsList200ResponseAnnotationsItemInk.BlendMode; + inReplyTo: CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemInkInReplyTo | null; + replyType: DocAnnotationsList200ResponseAnnotationsItemInk.ReplyType | null; + userId?: string | undefined; + groupId?: string | undefined; + createdBy?: string | undefined; + updatedBy?: string | undefined; + actions?: DocAnnotationsList200ResponseAnnotationsItemInk.Actions | undefined; + color: DocAnnotationsList200ResponseAnnotationsItemInk.Color; + opacity: number; + strokeWidth: number; + borderStyle: DocAnnotationsList200ResponseAnnotationsItemInk.BorderStyle; + dashArray?: number[] | undefined; + intent: DocAnnotationsList200ResponseAnnotationsItemInk.Intent | null; + inkList: DocAnnotationsList200ResponseAnnotationsItemInk.InkList.Item[][]; + rotation?: number | undefined; + } + + export namespace DocAnnotationsList200ResponseAnnotationsItemInk { + export const IdentityQuality = { + Durable: "durable", + Weak: "weak", + } as const; + export type IdentityQuality = (typeof IdentityQuality)[keyof typeof IdentityQuality]; + + export interface Flags { + invisible: boolean; + hidden: boolean; + print: boolean; + noZoom: boolean; + noRotate: boolean; + noView: boolean; + readOnly: boolean; + locked: boolean; + toggleNoView: boolean; + lockedContents: boolean; + } + + export interface Rect { + left: number; + bottom: number; + right: number; + top: number; + } + + export const BlendMode = { + Normal: "normal", + Multiply: "multiply", + Screen: "screen", + Overlay: "overlay", + Darken: "darken", + Lighten: "lighten", + ColorDodge: "color-dodge", + ColorBurn: "color-burn", + HardLight: "hard-light", + SoftLight: "soft-light", + Difference: "difference", + Exclusion: "exclusion", + Hue: "hue", + Saturation: "saturation", + Color: "color", + Luminosity: "luminosity", + } as const; + export type BlendMode = (typeof BlendMode)[keyof typeof BlendMode]; + export const ReplyType = { + Reply: "reply", + Group: "group", + } as const; + export type ReplyType = (typeof ReplyType)[keyof typeof ReplyType]; + + export interface Actions { + activate?: Actions.Activate | undefined; + cursorEnter?: Actions.CursorEnter | undefined; + cursorExit?: Actions.CursorExit | undefined; + mouseDown?: Actions.MouseDown | undefined; + mouseUp?: Actions.MouseUp | undefined; + focus?: Actions.Focus | undefined; + blur?: Actions.Blur | undefined; + pageOpen?: Actions.PageOpen | undefined; + pageClose?: Actions.PageClose | undefined; + pageVisible?: Actions.PageVisible | undefined; + pageInvisible?: Actions.PageInvisible | undefined; + } + + export namespace Actions { + export interface Activate { + root: Activate.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Activate.Warnings.Item[]; + } + + export namespace Activate { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface CursorEnter { + root: CursorEnter.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: CursorEnter.Warnings.Item[]; + } + + export namespace CursorEnter { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface CursorExit { + root: CursorExit.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: CursorExit.Warnings.Item[]; + } + + export namespace CursorExit { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface MouseDown { + root: MouseDown.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: MouseDown.Warnings.Item[]; + } + + export namespace MouseDown { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface MouseUp { + root: MouseUp.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: MouseUp.Warnings.Item[]; + } + + export namespace MouseUp { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface Focus { + root: Focus.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Focus.Warnings.Item[]; + } + + export namespace Focus { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface Blur { + root: Blur.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Blur.Warnings.Item[]; + } + + export namespace Blur { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageOpen { + root: PageOpen.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageOpen.Warnings.Item[]; + } + + export namespace PageOpen { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageClose { + root: PageClose.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageClose.Warnings.Item[]; + } + + export namespace PageClose { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageVisible { + root: PageVisible.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageVisible.Warnings.Item[]; + } + + export namespace PageVisible { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageInvisible { + root: PageInvisible.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageInvisible.Warnings.Item[]; + } + + export namespace PageInvisible { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + } + + export interface Color { + r: number; + g: number; + b: number; + } + + export const BorderStyle = { + Solid: "solid", + Dashed: "dashed", + Beveled: "beveled", + Inset: "inset", + } as const; + export type BorderStyle = (typeof BorderStyle)[keyof typeof BorderStyle]; + export const Intent = { + InkHighlight: "ink-highlight", + } as const; + export type Intent = (typeof Intent)[keyof typeof Intent]; + export type InkList = InkList.Item[]; + + export namespace InkList { + export interface Item { + x: number; + y: number; + } + } + } + + export interface FreeText { + subtype: "free-text"; + ref: CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemFreeTextRef; + pageObjectNumber: number; + index: number; + identityQuality: DocAnnotationsList200ResponseAnnotationsItemFreeText.IdentityQuality; + nm: string | null; + flags: DocAnnotationsList200ResponseAnnotationsItemFreeText.Flags; + rect: DocAnnotationsList200ResponseAnnotationsItemFreeText.Rect; + contents: string | null; + author: string | null; + created: string | null; + modified: string | null; + blendMode: DocAnnotationsList200ResponseAnnotationsItemFreeText.BlendMode; + inReplyTo: CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemFreeTextInReplyTo | null; + replyType: DocAnnotationsList200ResponseAnnotationsItemFreeText.ReplyType | null; + userId?: string | undefined; + groupId?: string | undefined; + createdBy?: string | undefined; + updatedBy?: string | undefined; + actions?: DocAnnotationsList200ResponseAnnotationsItemFreeText.Actions | undefined; + intent: DocAnnotationsList200ResponseAnnotationsItemFreeText.Intent; + fontFamily: DocAnnotationsList200ResponseAnnotationsItemFreeText.FontFamily; + fontSize: number; + textAlign: DocAnnotationsList200ResponseAnnotationsItemFreeText.TextAlign; + color: DocAnnotationsList200ResponseAnnotationsItemFreeText.Color; + fontColor?: DocAnnotationsList200ResponseAnnotationsItemFreeText.FontColor | undefined; + interiorColor: DocAnnotationsList200ResponseAnnotationsItemFreeText.InteriorColor | null; + opacity: number; + strokeWidth: number; + borderStyle: DocAnnotationsList200ResponseAnnotationsItemFreeText.BorderStyle; + dashArray?: number[] | undefined; + rectDifferences: DocAnnotationsList200ResponseAnnotationsItemFreeText.RectDifferences | null; + calloutLine?: unknown[] | undefined; + lineEnding?: DocAnnotationsList200ResponseAnnotationsItemFreeText.LineEnding | undefined; + rotation?: number | undefined; + unrotatedRect?: DocAnnotationsList200ResponseAnnotationsItemFreeText.UnrotatedRect | undefined; + } + + export namespace DocAnnotationsList200ResponseAnnotationsItemFreeText { + export const IdentityQuality = { + Durable: "durable", + Weak: "weak", + } as const; + export type IdentityQuality = (typeof IdentityQuality)[keyof typeof IdentityQuality]; + + export interface Flags { + invisible: boolean; + hidden: boolean; + print: boolean; + noZoom: boolean; + noRotate: boolean; + noView: boolean; + readOnly: boolean; + locked: boolean; + toggleNoView: boolean; + lockedContents: boolean; + } + + export interface Rect { + left: number; + bottom: number; + right: number; + top: number; + } + + export const BlendMode = { + Normal: "normal", + Multiply: "multiply", + Screen: "screen", + Overlay: "overlay", + Darken: "darken", + Lighten: "lighten", + ColorDodge: "color-dodge", + ColorBurn: "color-burn", + HardLight: "hard-light", + SoftLight: "soft-light", + Difference: "difference", + Exclusion: "exclusion", + Hue: "hue", + Saturation: "saturation", + Color: "color", + Luminosity: "luminosity", + } as const; + export type BlendMode = (typeof BlendMode)[keyof typeof BlendMode]; + export const ReplyType = { + Reply: "reply", + Group: "group", + } as const; + export type ReplyType = (typeof ReplyType)[keyof typeof ReplyType]; + + export interface Actions { + activate?: Actions.Activate | undefined; + cursorEnter?: Actions.CursorEnter | undefined; + cursorExit?: Actions.CursorExit | undefined; + mouseDown?: Actions.MouseDown | undefined; + mouseUp?: Actions.MouseUp | undefined; + focus?: Actions.Focus | undefined; + blur?: Actions.Blur | undefined; + pageOpen?: Actions.PageOpen | undefined; + pageClose?: Actions.PageClose | undefined; + pageVisible?: Actions.PageVisible | undefined; + pageInvisible?: Actions.PageInvisible | undefined; + } + + export namespace Actions { + export interface Activate { + root: Activate.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Activate.Warnings.Item[]; + } + + export namespace Activate { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface CursorEnter { + root: CursorEnter.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: CursorEnter.Warnings.Item[]; + } + + export namespace CursorEnter { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface CursorExit { + root: CursorExit.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: CursorExit.Warnings.Item[]; + } + + export namespace CursorExit { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface MouseDown { + root: MouseDown.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: MouseDown.Warnings.Item[]; + } + + export namespace MouseDown { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface MouseUp { + root: MouseUp.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: MouseUp.Warnings.Item[]; + } + + export namespace MouseUp { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface Focus { + root: Focus.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Focus.Warnings.Item[]; + } + + export namespace Focus { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface Blur { + root: Blur.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Blur.Warnings.Item[]; + } + + export namespace Blur { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageOpen { + root: PageOpen.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageOpen.Warnings.Item[]; + } + + export namespace PageOpen { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageClose { + root: PageClose.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageClose.Warnings.Item[]; + } + + export namespace PageClose { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageVisible { + root: PageVisible.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageVisible.Warnings.Item[]; + } + + export namespace PageVisible { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageInvisible { + root: PageInvisible.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageInvisible.Warnings.Item[]; + } + + export namespace PageInvisible { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + } + + export const Intent = { + FreeText: "free-text", + FreeTextCallout: "free-text-callout", + } as const; + export type Intent = (typeof Intent)[keyof typeof Intent]; + export const FontFamily = { + Courier: "courier", + CourierBold: "courier-bold", + CourierBoldOblique: "courier-bold-oblique", + CourierOblique: "courier-oblique", + Helvetica: "helvetica", + HelveticaBold: "helvetica-bold", + HelveticaBoldOblique: "helvetica-bold-oblique", + HelveticaOblique: "helvetica-oblique", + TimesRoman: "times-roman", + TimesBold: "times-bold", + TimesBoldItalic: "times-bold-italic", + TimesItalic: "times-italic", + Symbol: "symbol", + ZapfDingbats: "zapf-dingbats", + } as const; + export type FontFamily = (typeof FontFamily)[keyof typeof FontFamily]; + export const TextAlign = { + Left: "left", + Center: "center", + Right: "right", + } as const; + export type TextAlign = (typeof TextAlign)[keyof typeof TextAlign]; + + export interface Color { + r: number; + g: number; + b: number; + } + + export interface FontColor { + r: number; + g: number; + b: number; + } + + export interface InteriorColor { + r: number; + g: number; + b: number; + } + + export const BorderStyle = { + Solid: "solid", + Dashed: "dashed", + Beveled: "beveled", + Inset: "inset", + } as const; + export type BorderStyle = (typeof BorderStyle)[keyof typeof BorderStyle]; + + export interface RectDifferences { + left: number; + top: number; + right: number; + bottom: number; + } + + export const LineEnding = { + None: "none", + Square: "square", + Circle: "circle", + Diamond: "diamond", + OpenArrow: "open-arrow", + ClosedArrow: "closed-arrow", + Butt: "butt", + ROpenArrow: "r-open-arrow", + RClosedArrow: "r-closed-arrow", + Slash: "slash", + } as const; + export type LineEnding = (typeof LineEnding)[keyof typeof LineEnding]; + + export interface UnrotatedRect { + left: number; + bottom: number; + right: number; + top: number; + } + } + + export interface Caret { + subtype: "caret"; + ref: CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemCaretRef; + pageObjectNumber: number; + index: number; + identityQuality: DocAnnotationsList200ResponseAnnotationsItemCaret.IdentityQuality; + nm: string | null; + flags: DocAnnotationsList200ResponseAnnotationsItemCaret.Flags; + rect: DocAnnotationsList200ResponseAnnotationsItemCaret.Rect; + contents: string | null; + author: string | null; + created: string | null; + modified: string | null; + blendMode: DocAnnotationsList200ResponseAnnotationsItemCaret.BlendMode; + inReplyTo: CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemCaretInReplyTo | null; + replyType: DocAnnotationsList200ResponseAnnotationsItemCaret.ReplyType | null; + userId?: string | undefined; + groupId?: string | undefined; + createdBy?: string | undefined; + updatedBy?: string | undefined; + actions?: DocAnnotationsList200ResponseAnnotationsItemCaret.Actions | undefined; + color: DocAnnotationsList200ResponseAnnotationsItemCaret.Color; + opacity: number; + intent: DocAnnotationsList200ResponseAnnotationsItemCaret.Intent | null; + rectDifferences: DocAnnotationsList200ResponseAnnotationsItemCaret.RectDifferences | null; + } + + export namespace DocAnnotationsList200ResponseAnnotationsItemCaret { + export const IdentityQuality = { + Durable: "durable", + Weak: "weak", + } as const; + export type IdentityQuality = (typeof IdentityQuality)[keyof typeof IdentityQuality]; + + export interface Flags { + invisible: boolean; + hidden: boolean; + print: boolean; + noZoom: boolean; + noRotate: boolean; + noView: boolean; + readOnly: boolean; + locked: boolean; + toggleNoView: boolean; + lockedContents: boolean; + } + + export interface Rect { + left: number; + bottom: number; + right: number; + top: number; + } + + export const BlendMode = { + Normal: "normal", + Multiply: "multiply", + Screen: "screen", + Overlay: "overlay", + Darken: "darken", + Lighten: "lighten", + ColorDodge: "color-dodge", + ColorBurn: "color-burn", + HardLight: "hard-light", + SoftLight: "soft-light", + Difference: "difference", + Exclusion: "exclusion", + Hue: "hue", + Saturation: "saturation", + Color: "color", + Luminosity: "luminosity", + } as const; + export type BlendMode = (typeof BlendMode)[keyof typeof BlendMode]; + export const ReplyType = { + Reply: "reply", + Group: "group", + } as const; + export type ReplyType = (typeof ReplyType)[keyof typeof ReplyType]; + + export interface Actions { + activate?: Actions.Activate | undefined; + cursorEnter?: Actions.CursorEnter | undefined; + cursorExit?: Actions.CursorExit | undefined; + mouseDown?: Actions.MouseDown | undefined; + mouseUp?: Actions.MouseUp | undefined; + focus?: Actions.Focus | undefined; + blur?: Actions.Blur | undefined; + pageOpen?: Actions.PageOpen | undefined; + pageClose?: Actions.PageClose | undefined; + pageVisible?: Actions.PageVisible | undefined; + pageInvisible?: Actions.PageInvisible | undefined; + } + + export namespace Actions { + export interface Activate { + root: Activate.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Activate.Warnings.Item[]; + } + + export namespace Activate { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface CursorEnter { + root: CursorEnter.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: CursorEnter.Warnings.Item[]; + } + + export namespace CursorEnter { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface CursorExit { + root: CursorExit.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: CursorExit.Warnings.Item[]; + } + + export namespace CursorExit { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface MouseDown { + root: MouseDown.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: MouseDown.Warnings.Item[]; + } + + export namespace MouseDown { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface MouseUp { + root: MouseUp.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: MouseUp.Warnings.Item[]; + } + + export namespace MouseUp { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface Focus { + root: Focus.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Focus.Warnings.Item[]; + } + + export namespace Focus { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface Blur { + root: Blur.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Blur.Warnings.Item[]; + } + + export namespace Blur { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageOpen { + root: PageOpen.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageOpen.Warnings.Item[]; + } + + export namespace PageOpen { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageClose { + root: PageClose.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageClose.Warnings.Item[]; + } + + export namespace PageClose { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageVisible { + root: PageVisible.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageVisible.Warnings.Item[]; + } + + export namespace PageVisible { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageInvisible { + root: PageInvisible.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageInvisible.Warnings.Item[]; + } + + export namespace PageInvisible { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + } + + export interface Color { + r: number; + g: number; + b: number; + } + + export const Intent = { + Replace: "replace", + } as const; + export type Intent = (typeof Intent)[keyof typeof Intent]; + + export interface RectDifferences { + left: number; + top: number; + right: number; + bottom: number; + } + } + + export interface Text { + subtype: "text"; + ref: CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemTextRef; + pageObjectNumber: number; + index: number; + identityQuality: DocAnnotationsList200ResponseAnnotationsItemText.IdentityQuality; + nm: string | null; + flags: DocAnnotationsList200ResponseAnnotationsItemText.Flags; + rect: DocAnnotationsList200ResponseAnnotationsItemText.Rect; + contents: string | null; + author: string | null; + created: string | null; + modified: string | null; + blendMode: DocAnnotationsList200ResponseAnnotationsItemText.BlendMode; + inReplyTo: CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemTextInReplyTo | null; + replyType: DocAnnotationsList200ResponseAnnotationsItemText.ReplyType | null; + userId?: string | undefined; + groupId?: string | undefined; + createdBy?: string | undefined; + updatedBy?: string | undefined; + actions?: DocAnnotationsList200ResponseAnnotationsItemText.Actions | undefined; + color: DocAnnotationsList200ResponseAnnotationsItemText.Color; + opacity: number; + icon: DocAnnotationsList200ResponseAnnotationsItemText.Icon; + } + + export namespace DocAnnotationsList200ResponseAnnotationsItemText { + export const IdentityQuality = { + Durable: "durable", + Weak: "weak", + } as const; + export type IdentityQuality = (typeof IdentityQuality)[keyof typeof IdentityQuality]; + + export interface Flags { + invisible: boolean; + hidden: boolean; + print: boolean; + noZoom: boolean; + noRotate: boolean; + noView: boolean; + readOnly: boolean; + locked: boolean; + toggleNoView: boolean; + lockedContents: boolean; + } + + export interface Rect { + left: number; + bottom: number; + right: number; + top: number; + } + + export const BlendMode = { + Normal: "normal", + Multiply: "multiply", + Screen: "screen", + Overlay: "overlay", + Darken: "darken", + Lighten: "lighten", + ColorDodge: "color-dodge", + ColorBurn: "color-burn", + HardLight: "hard-light", + SoftLight: "soft-light", + Difference: "difference", + Exclusion: "exclusion", + Hue: "hue", + Saturation: "saturation", + Color: "color", + Luminosity: "luminosity", + } as const; + export type BlendMode = (typeof BlendMode)[keyof typeof BlendMode]; + export const ReplyType = { + Reply: "reply", + Group: "group", + } as const; + export type ReplyType = (typeof ReplyType)[keyof typeof ReplyType]; + + export interface Actions { + activate?: Actions.Activate | undefined; + cursorEnter?: Actions.CursorEnter | undefined; + cursorExit?: Actions.CursorExit | undefined; + mouseDown?: Actions.MouseDown | undefined; + mouseUp?: Actions.MouseUp | undefined; + focus?: Actions.Focus | undefined; + blur?: Actions.Blur | undefined; + pageOpen?: Actions.PageOpen | undefined; + pageClose?: Actions.PageClose | undefined; + pageVisible?: Actions.PageVisible | undefined; + pageInvisible?: Actions.PageInvisible | undefined; + } + + export namespace Actions { + export interface Activate { + root: Activate.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Activate.Warnings.Item[]; + } + + export namespace Activate { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface CursorEnter { + root: CursorEnter.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: CursorEnter.Warnings.Item[]; + } + + export namespace CursorEnter { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface CursorExit { + root: CursorExit.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: CursorExit.Warnings.Item[]; + } + + export namespace CursorExit { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface MouseDown { + root: MouseDown.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: MouseDown.Warnings.Item[]; + } + + export namespace MouseDown { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface MouseUp { + root: MouseUp.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: MouseUp.Warnings.Item[]; + } + + export namespace MouseUp { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface Focus { + root: Focus.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Focus.Warnings.Item[]; + } + + export namespace Focus { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface Blur { + root: Blur.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Blur.Warnings.Item[]; + } + + export namespace Blur { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageOpen { + root: PageOpen.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageOpen.Warnings.Item[]; + } + + export namespace PageOpen { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageClose { + root: PageClose.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageClose.Warnings.Item[]; + } + + export namespace PageClose { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageVisible { + root: PageVisible.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageVisible.Warnings.Item[]; + } + + export namespace PageVisible { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageInvisible { + root: PageInvisible.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageInvisible.Warnings.Item[]; + } + + export namespace PageInvisible { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + } + + export interface Color { + r: number; + g: number; + b: number; + } + + export const Icon = { + Comment: "comment", + Key: "key", + Note: "note", + Help: "help", + NewParagraph: "new-paragraph", + Paragraph: "paragraph", + Insert: "insert", + } as const; + export type Icon = (typeof Icon)[keyof typeof Icon]; + } + + export interface Stamp { + subtype: "stamp"; + ref: CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemStampRef; + pageObjectNumber: number; + index: number; + identityQuality: DocAnnotationsList200ResponseAnnotationsItemStamp.IdentityQuality; + nm: string | null; + flags: DocAnnotationsList200ResponseAnnotationsItemStamp.Flags; + rect: DocAnnotationsList200ResponseAnnotationsItemStamp.Rect; + contents: string | null; + author: string | null; + created: string | null; + modified: string | null; + blendMode: DocAnnotationsList200ResponseAnnotationsItemStamp.BlendMode; + inReplyTo: CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemStampInReplyTo | null; + replyType: DocAnnotationsList200ResponseAnnotationsItemStamp.ReplyType | null; + userId?: string | undefined; + groupId?: string | undefined; + createdBy?: string | undefined; + updatedBy?: string | undefined; + actions?: DocAnnotationsList200ResponseAnnotationsItemStamp.Actions | undefined; + name: string | null; + rotation?: number | undefined; + unrotatedRect?: DocAnnotationsList200ResponseAnnotationsItemStamp.UnrotatedRect | undefined; + } + + export namespace DocAnnotationsList200ResponseAnnotationsItemStamp { + export const IdentityQuality = { + Durable: "durable", + Weak: "weak", + } as const; + export type IdentityQuality = (typeof IdentityQuality)[keyof typeof IdentityQuality]; + + export interface Flags { + invisible: boolean; + hidden: boolean; + print: boolean; + noZoom: boolean; + noRotate: boolean; + noView: boolean; + readOnly: boolean; + locked: boolean; + toggleNoView: boolean; + lockedContents: boolean; + } + + export interface Rect { + left: number; + bottom: number; + right: number; + top: number; + } + + export const BlendMode = { + Normal: "normal", + Multiply: "multiply", + Screen: "screen", + Overlay: "overlay", + Darken: "darken", + Lighten: "lighten", + ColorDodge: "color-dodge", + ColorBurn: "color-burn", + HardLight: "hard-light", + SoftLight: "soft-light", + Difference: "difference", + Exclusion: "exclusion", + Hue: "hue", + Saturation: "saturation", + Color: "color", + Luminosity: "luminosity", + } as const; + export type BlendMode = (typeof BlendMode)[keyof typeof BlendMode]; + export const ReplyType = { + Reply: "reply", + Group: "group", + } as const; + export type ReplyType = (typeof ReplyType)[keyof typeof ReplyType]; + + export interface Actions { + activate?: Actions.Activate | undefined; + cursorEnter?: Actions.CursorEnter | undefined; + cursorExit?: Actions.CursorExit | undefined; + mouseDown?: Actions.MouseDown | undefined; + mouseUp?: Actions.MouseUp | undefined; + focus?: Actions.Focus | undefined; + blur?: Actions.Blur | undefined; + pageOpen?: Actions.PageOpen | undefined; + pageClose?: Actions.PageClose | undefined; + pageVisible?: Actions.PageVisible | undefined; + pageInvisible?: Actions.PageInvisible | undefined; + } + + export namespace Actions { + export interface Activate { + root: Activate.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Activate.Warnings.Item[]; + } + + export namespace Activate { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface CursorEnter { + root: CursorEnter.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: CursorEnter.Warnings.Item[]; + } + + export namespace CursorEnter { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface CursorExit { + root: CursorExit.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: CursorExit.Warnings.Item[]; + } + + export namespace CursorExit { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface MouseDown { + root: MouseDown.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: MouseDown.Warnings.Item[]; + } + + export namespace MouseDown { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface MouseUp { + root: MouseUp.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: MouseUp.Warnings.Item[]; + } + + export namespace MouseUp { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface Focus { + root: Focus.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Focus.Warnings.Item[]; + } + + export namespace Focus { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface Blur { + root: Blur.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Blur.Warnings.Item[]; + } + + export namespace Blur { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageOpen { + root: PageOpen.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageOpen.Warnings.Item[]; + } + + export namespace PageOpen { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageClose { + root: PageClose.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageClose.Warnings.Item[]; + } + + export namespace PageClose { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageVisible { + root: PageVisible.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageVisible.Warnings.Item[]; + } + + export namespace PageVisible { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageInvisible { + root: PageInvisible.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageInvisible.Warnings.Item[]; + } + + export namespace PageInvisible { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + } + + export interface UnrotatedRect { + left: number; + bottom: number; + right: number; + top: number; + } + } + + export interface FileAttachment { + subtype: "file-attachment"; + ref: CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemFileAttachmentRef; + pageObjectNumber: number; + index: number; + identityQuality: DocAnnotationsList200ResponseAnnotationsItemFileAttachment.IdentityQuality; + nm: string | null; + flags: DocAnnotationsList200ResponseAnnotationsItemFileAttachment.Flags; + rect: DocAnnotationsList200ResponseAnnotationsItemFileAttachment.Rect; + contents: string | null; + author: string | null; + created: string | null; + modified: string | null; + blendMode: DocAnnotationsList200ResponseAnnotationsItemFileAttachment.BlendMode; + inReplyTo: CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemFileAttachmentInReplyTo | null; + replyType: DocAnnotationsList200ResponseAnnotationsItemFileAttachment.ReplyType | null; + userId?: string | undefined; + groupId?: string | undefined; + createdBy?: string | undefined; + updatedBy?: string | undefined; + actions?: DocAnnotationsList200ResponseAnnotationsItemFileAttachment.Actions | undefined; + color: DocAnnotationsList200ResponseAnnotationsItemFileAttachment.Color; + opacity: number; + icon: DocAnnotationsList200ResponseAnnotationsItemFileAttachment.Icon; + file: DocAnnotationsList200ResponseAnnotationsItemFileAttachment.File_; + } + + export namespace DocAnnotationsList200ResponseAnnotationsItemFileAttachment { + export const IdentityQuality = { + Durable: "durable", + Weak: "weak", + } as const; + export type IdentityQuality = (typeof IdentityQuality)[keyof typeof IdentityQuality]; + + export interface Flags { + invisible: boolean; + hidden: boolean; + print: boolean; + noZoom: boolean; + noRotate: boolean; + noView: boolean; + readOnly: boolean; + locked: boolean; + toggleNoView: boolean; + lockedContents: boolean; + } + + export interface Rect { + left: number; + bottom: number; + right: number; + top: number; + } + + export const BlendMode = { + Normal: "normal", + Multiply: "multiply", + Screen: "screen", + Overlay: "overlay", + Darken: "darken", + Lighten: "lighten", + ColorDodge: "color-dodge", + ColorBurn: "color-burn", + HardLight: "hard-light", + SoftLight: "soft-light", + Difference: "difference", + Exclusion: "exclusion", + Hue: "hue", + Saturation: "saturation", + Color: "color", + Luminosity: "luminosity", + } as const; + export type BlendMode = (typeof BlendMode)[keyof typeof BlendMode]; + export const ReplyType = { + Reply: "reply", + Group: "group", + } as const; + export type ReplyType = (typeof ReplyType)[keyof typeof ReplyType]; + + export interface Actions { + activate?: Actions.Activate | undefined; + cursorEnter?: Actions.CursorEnter | undefined; + cursorExit?: Actions.CursorExit | undefined; + mouseDown?: Actions.MouseDown | undefined; + mouseUp?: Actions.MouseUp | undefined; + focus?: Actions.Focus | undefined; + blur?: Actions.Blur | undefined; + pageOpen?: Actions.PageOpen | undefined; + pageClose?: Actions.PageClose | undefined; + pageVisible?: Actions.PageVisible | undefined; + pageInvisible?: Actions.PageInvisible | undefined; + } + + export namespace Actions { + export interface Activate { + root: Activate.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Activate.Warnings.Item[]; + } + + export namespace Activate { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface CursorEnter { + root: CursorEnter.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: CursorEnter.Warnings.Item[]; + } + + export namespace CursorEnter { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface CursorExit { + root: CursorExit.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: CursorExit.Warnings.Item[]; + } + + export namespace CursorExit { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface MouseDown { + root: MouseDown.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: MouseDown.Warnings.Item[]; + } + + export namespace MouseDown { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface MouseUp { + root: MouseUp.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: MouseUp.Warnings.Item[]; + } + + export namespace MouseUp { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface Focus { + root: Focus.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Focus.Warnings.Item[]; + } + + export namespace Focus { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface Blur { + root: Blur.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Blur.Warnings.Item[]; + } + + export namespace Blur { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageOpen { + root: PageOpen.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageOpen.Warnings.Item[]; + } + + export namespace PageOpen { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageClose { + root: PageClose.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageClose.Warnings.Item[]; + } + + export namespace PageClose { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageVisible { + root: PageVisible.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageVisible.Warnings.Item[]; + } + + export namespace PageVisible { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageInvisible { + root: PageInvisible.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageInvisible.Warnings.Item[]; + } + + export namespace PageInvisible { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + } + + export interface Color { + r: number; + g: number; + b: number; + } + + export const Icon = { + PushPin: "push-pin", + Paperclip: "paperclip", + Graph: "graph", + Tag: "tag", + } as const; + export type Icon = (typeof Icon)[keyof typeof Icon]; + + export interface File_ { + name: string; + mimeType?: string | undefined; + description?: string | undefined; + size?: number | undefined; + checksum?: string | undefined; + creationDate?: string | undefined; + } + } + + export interface Widget { + subtype: "widget"; + ref: CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemWidgetRef; + pageObjectNumber: number; + index: number; + identityQuality: DocAnnotationsList200ResponseAnnotationsItemWidget.IdentityQuality; + nm: string | null; + flags: DocAnnotationsList200ResponseAnnotationsItemWidget.Flags; + rect: DocAnnotationsList200ResponseAnnotationsItemWidget.Rect; + contents: string | null; + author: string | null; + created: string | null; + modified: string | null; + blendMode: DocAnnotationsList200ResponseAnnotationsItemWidget.BlendMode; + inReplyTo: CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemWidgetInReplyTo | null; + replyType: DocAnnotationsList200ResponseAnnotationsItemWidget.ReplyType | null; + userId?: string | undefined; + groupId?: string | undefined; + createdBy?: string | undefined; + updatedBy?: string | undefined; + actions?: DocAnnotationsList200ResponseAnnotationsItemWidget.Actions | undefined; + color: DocAnnotationsList200ResponseAnnotationsItemWidget.Color | null; + interiorColor: DocAnnotationsList200ResponseAnnotationsItemWidget.InteriorColor | null; + strokeWidth: number; + borderStyle: DocAnnotationsList200ResponseAnnotationsItemWidget.BorderStyle; + fontFamily?: DocAnnotationsList200ResponseAnnotationsItemWidget.FontFamily | undefined; + fontSize?: number | undefined; + fontColor?: DocAnnotationsList200ResponseAnnotationsItemWidget.FontColor | undefined; + textAlign: DocAnnotationsList200ResponseAnnotationsItemWidget.TextAlign; + fieldObjectNumber: number; + fieldFamily: DocAnnotationsList200ResponseAnnotationsItemWidget.FieldFamily; + } + + export namespace DocAnnotationsList200ResponseAnnotationsItemWidget { + export const IdentityQuality = { + Durable: "durable", + Weak: "weak", + } as const; + export type IdentityQuality = (typeof IdentityQuality)[keyof typeof IdentityQuality]; + + export interface Flags { + invisible: boolean; + hidden: boolean; + print: boolean; + noZoom: boolean; + noRotate: boolean; + noView: boolean; + readOnly: boolean; + locked: boolean; + toggleNoView: boolean; + lockedContents: boolean; + } + + export interface Rect { + left: number; + bottom: number; + right: number; + top: number; + } + + export const BlendMode = { + Normal: "normal", + Multiply: "multiply", + Screen: "screen", + Overlay: "overlay", + Darken: "darken", + Lighten: "lighten", + ColorDodge: "color-dodge", + ColorBurn: "color-burn", + HardLight: "hard-light", + SoftLight: "soft-light", + Difference: "difference", + Exclusion: "exclusion", + Hue: "hue", + Saturation: "saturation", + Color: "color", + Luminosity: "luminosity", + } as const; + export type BlendMode = (typeof BlendMode)[keyof typeof BlendMode]; + export const ReplyType = { + Reply: "reply", + Group: "group", + } as const; + export type ReplyType = (typeof ReplyType)[keyof typeof ReplyType]; + + export interface Actions { + activate?: Actions.Activate | undefined; + cursorEnter?: Actions.CursorEnter | undefined; + cursorExit?: Actions.CursorExit | undefined; + mouseDown?: Actions.MouseDown | undefined; + mouseUp?: Actions.MouseUp | undefined; + focus?: Actions.Focus | undefined; + blur?: Actions.Blur | undefined; + pageOpen?: Actions.PageOpen | undefined; + pageClose?: Actions.PageClose | undefined; + pageVisible?: Actions.PageVisible | undefined; + pageInvisible?: Actions.PageInvisible | undefined; + } + + export namespace Actions { + export interface Activate { + root: Activate.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Activate.Warnings.Item[]; + } + + export namespace Activate { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface CursorEnter { + root: CursorEnter.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: CursorEnter.Warnings.Item[]; + } + + export namespace CursorEnter { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface CursorExit { + root: CursorExit.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: CursorExit.Warnings.Item[]; + } + + export namespace CursorExit { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface MouseDown { + root: MouseDown.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: MouseDown.Warnings.Item[]; + } + + export namespace MouseDown { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface MouseUp { + root: MouseUp.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: MouseUp.Warnings.Item[]; + } + + export namespace MouseUp { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface Focus { + root: Focus.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Focus.Warnings.Item[]; + } + + export namespace Focus { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface Blur { + root: Blur.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Blur.Warnings.Item[]; + } + + export namespace Blur { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageOpen { + root: PageOpen.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageOpen.Warnings.Item[]; + } + + export namespace PageOpen { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageClose { + root: PageClose.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageClose.Warnings.Item[]; + } + + export namespace PageClose { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageVisible { + root: PageVisible.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageVisible.Warnings.Item[]; + } + + export namespace PageVisible { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageInvisible { + root: PageInvisible.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageInvisible.Warnings.Item[]; + } + + export namespace PageInvisible { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + } + + export interface Color { + r: number; + g: number; + b: number; + } + + export interface InteriorColor { + r: number; + g: number; + b: number; + } + + export const BorderStyle = { + Solid: "solid", + Dashed: "dashed", + Beveled: "beveled", + Inset: "inset", + } as const; + export type BorderStyle = (typeof BorderStyle)[keyof typeof BorderStyle]; + export const FontFamily = { + Courier: "courier", + CourierBold: "courier-bold", + CourierBoldOblique: "courier-bold-oblique", + CourierOblique: "courier-oblique", + Helvetica: "helvetica", + HelveticaBold: "helvetica-bold", + HelveticaBoldOblique: "helvetica-bold-oblique", + HelveticaOblique: "helvetica-oblique", + TimesRoman: "times-roman", + TimesBold: "times-bold", + TimesBoldItalic: "times-bold-italic", + TimesItalic: "times-italic", + Symbol: "symbol", + ZapfDingbats: "zapf-dingbats", + } as const; + export type FontFamily = (typeof FontFamily)[keyof typeof FontFamily]; + + export interface FontColor { + r: number; + g: number; + b: number; + } + + export const TextAlign = { + Left: "left", + Center: "center", + Right: "right", + } as const; + export type TextAlign = (typeof TextAlign)[keyof typeof TextAlign]; + export const FieldFamily = { + Text: "text", + Checkbox: "checkbox", + Radio: "radio", + Combobox: "combobox", + Listbox: "listbox", + Pushbutton: "pushbutton", + Signature: "signature", + Unknown: "unknown", + } as const; + export type FieldFamily = (typeof FieldFamily)[keyof typeof FieldFamily]; + } + + export interface Redact { + subtype: "redact"; + ref: CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemRedactRef; + pageObjectNumber: number; + index: number; + identityQuality: DocAnnotationsList200ResponseAnnotationsItemRedact.IdentityQuality; + nm: string | null; + flags: DocAnnotationsList200ResponseAnnotationsItemRedact.Flags; + rect: DocAnnotationsList200ResponseAnnotationsItemRedact.Rect; + contents: string | null; + author: string | null; + created: string | null; + modified: string | null; + blendMode: DocAnnotationsList200ResponseAnnotationsItemRedact.BlendMode; + inReplyTo: CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemRedactInReplyTo | null; + replyType: DocAnnotationsList200ResponseAnnotationsItemRedact.ReplyType | null; + userId?: string | undefined; + groupId?: string | undefined; + createdBy?: string | undefined; + updatedBy?: string | undefined; + actions?: DocAnnotationsList200ResponseAnnotationsItemRedact.Actions | undefined; + quadPoints: DocAnnotationsList200ResponseAnnotationsItemRedact.QuadPoints.Item[]; + color: DocAnnotationsList200ResponseAnnotationsItemRedact.Color; + opacity: number; + interiorColor: DocAnnotationsList200ResponseAnnotationsItemRedact.InteriorColor | null; + overlayText: string | null; + repeat: boolean; + fontFamily: DocAnnotationsList200ResponseAnnotationsItemRedact.FontFamily; + fontSize: number; + fontColor: DocAnnotationsList200ResponseAnnotationsItemRedact.FontColor; + textAlign: DocAnnotationsList200ResponseAnnotationsItemRedact.TextAlign; + } + + export namespace DocAnnotationsList200ResponseAnnotationsItemRedact { + export const IdentityQuality = { + Durable: "durable", + Weak: "weak", + } as const; + export type IdentityQuality = (typeof IdentityQuality)[keyof typeof IdentityQuality]; + + export interface Flags { + invisible: boolean; + hidden: boolean; + print: boolean; + noZoom: boolean; + noRotate: boolean; + noView: boolean; + readOnly: boolean; + locked: boolean; + toggleNoView: boolean; + lockedContents: boolean; + } + + export interface Rect { + left: number; + bottom: number; + right: number; + top: number; + } + + export const BlendMode = { + Normal: "normal", + Multiply: "multiply", + Screen: "screen", + Overlay: "overlay", + Darken: "darken", + Lighten: "lighten", + ColorDodge: "color-dodge", + ColorBurn: "color-burn", + HardLight: "hard-light", + SoftLight: "soft-light", + Difference: "difference", + Exclusion: "exclusion", + Hue: "hue", + Saturation: "saturation", + Color: "color", + Luminosity: "luminosity", + } as const; + export type BlendMode = (typeof BlendMode)[keyof typeof BlendMode]; + export const ReplyType = { + Reply: "reply", + Group: "group", + } as const; + export type ReplyType = (typeof ReplyType)[keyof typeof ReplyType]; + + export interface Actions { + activate?: Actions.Activate | undefined; + cursorEnter?: Actions.CursorEnter | undefined; + cursorExit?: Actions.CursorExit | undefined; + mouseDown?: Actions.MouseDown | undefined; + mouseUp?: Actions.MouseUp | undefined; + focus?: Actions.Focus | undefined; + blur?: Actions.Blur | undefined; + pageOpen?: Actions.PageOpen | undefined; + pageClose?: Actions.PageClose | undefined; + pageVisible?: Actions.PageVisible | undefined; + pageInvisible?: Actions.PageInvisible | undefined; + } + + export namespace Actions { + export interface Activate { + root: Activate.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Activate.Warnings.Item[]; + } + + export namespace Activate { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface CursorEnter { + root: CursorEnter.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: CursorEnter.Warnings.Item[]; + } + + export namespace CursorEnter { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface CursorExit { + root: CursorExit.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: CursorExit.Warnings.Item[]; + } + + export namespace CursorExit { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface MouseDown { + root: MouseDown.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: MouseDown.Warnings.Item[]; + } + + export namespace MouseDown { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface MouseUp { + root: MouseUp.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: MouseUp.Warnings.Item[]; + } + + export namespace MouseUp { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface Focus { + root: Focus.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Focus.Warnings.Item[]; + } + + export namespace Focus { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface Blur { + root: Blur.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Blur.Warnings.Item[]; + } + + export namespace Blur { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageOpen { + root: PageOpen.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageOpen.Warnings.Item[]; + } + + export namespace PageOpen { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageClose { + root: PageClose.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageClose.Warnings.Item[]; + } + + export namespace PageClose { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageVisible { + root: PageVisible.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageVisible.Warnings.Item[]; + } + + export namespace PageVisible { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageInvisible { + root: PageInvisible.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageInvisible.Warnings.Item[]; + } + + export namespace PageInvisible { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + } + + export type QuadPoints = QuadPoints.Item[]; + + export namespace QuadPoints { + export interface Item { + p1: Item.P1; + p2: Item.P2; + p3: Item.P3; + p4: Item.P4; + } + + export namespace Item { + export interface P1 { + x: number; + y: number; + } + + export interface P2 { + x: number; + y: number; + } + + export interface P3 { + x: number; + y: number; + } + + export interface P4 { + x: number; + y: number; + } + } + } + + export interface Color { + r: number; + g: number; + b: number; + } + + export interface InteriorColor { + r: number; + g: number; + b: number; + } + + export const FontFamily = { + Courier: "courier", + CourierBold: "courier-bold", + CourierBoldOblique: "courier-bold-oblique", + CourierOblique: "courier-oblique", + Helvetica: "helvetica", + HelveticaBold: "helvetica-bold", + HelveticaBoldOblique: "helvetica-bold-oblique", + HelveticaOblique: "helvetica-oblique", + TimesRoman: "times-roman", + TimesBold: "times-bold", + TimesBoldItalic: "times-bold-italic", + TimesItalic: "times-italic", + Symbol: "symbol", + ZapfDingbats: "zapf-dingbats", + } as const; + export type FontFamily = (typeof FontFamily)[keyof typeof FontFamily]; + + export interface FontColor { + r: number; + g: number; + b: number; + } + + export const TextAlign = { + Left: "left", + Center: "center", + Right: "right", + } as const; + export type TextAlign = (typeof TextAlign)[keyof typeof TextAlign]; + } + + export interface Unsupported { + subtype: "unsupported"; + ref: CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemUnsupportedRef; + pageObjectNumber: number; + index: number; + identityQuality: DocAnnotationsList200ResponseAnnotationsItemUnsupported.IdentityQuality; + nm: string | null; + flags: DocAnnotationsList200ResponseAnnotationsItemUnsupported.Flags; + rect: DocAnnotationsList200ResponseAnnotationsItemUnsupported.Rect; + contents: string | null; + author: string | null; + created: string | null; + modified: string | null; + blendMode: DocAnnotationsList200ResponseAnnotationsItemUnsupported.BlendMode; + inReplyTo: CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemUnsupportedInReplyTo | null; + replyType: DocAnnotationsList200ResponseAnnotationsItemUnsupported.ReplyType | null; + userId?: string | undefined; + groupId?: string | undefined; + createdBy?: string | undefined; + updatedBy?: string | undefined; + actions?: DocAnnotationsList200ResponseAnnotationsItemUnsupported.Actions | undefined; + rawSubtypeCode: number; + rawSubtypeName: string | null; + } + + export namespace DocAnnotationsList200ResponseAnnotationsItemUnsupported { + export const IdentityQuality = { + Durable: "durable", + Weak: "weak", + } as const; + export type IdentityQuality = (typeof IdentityQuality)[keyof typeof IdentityQuality]; + + export interface Flags { + invisible: boolean; + hidden: boolean; + print: boolean; + noZoom: boolean; + noRotate: boolean; + noView: boolean; + readOnly: boolean; + locked: boolean; + toggleNoView: boolean; + lockedContents: boolean; + } + + export interface Rect { + left: number; + bottom: number; + right: number; + top: number; + } + + export const BlendMode = { + Normal: "normal", + Multiply: "multiply", + Screen: "screen", + Overlay: "overlay", + Darken: "darken", + Lighten: "lighten", + ColorDodge: "color-dodge", + ColorBurn: "color-burn", + HardLight: "hard-light", + SoftLight: "soft-light", + Difference: "difference", + Exclusion: "exclusion", + Hue: "hue", + Saturation: "saturation", + Color: "color", + Luminosity: "luminosity", + } as const; + export type BlendMode = (typeof BlendMode)[keyof typeof BlendMode]; + export const ReplyType = { + Reply: "reply", + Group: "group", + } as const; + export type ReplyType = (typeof ReplyType)[keyof typeof ReplyType]; + + export interface Actions { + activate?: Actions.Activate | undefined; + cursorEnter?: Actions.CursorEnter | undefined; + cursorExit?: Actions.CursorExit | undefined; + mouseDown?: Actions.MouseDown | undefined; + mouseUp?: Actions.MouseUp | undefined; + focus?: Actions.Focus | undefined; + blur?: Actions.Blur | undefined; + pageOpen?: Actions.PageOpen | undefined; + pageClose?: Actions.PageClose | undefined; + pageVisible?: Actions.PageVisible | undefined; + pageInvisible?: Actions.PageInvisible | undefined; + } + + export namespace Actions { + export interface Activate { + root: Activate.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Activate.Warnings.Item[]; + } + + export namespace Activate { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface CursorEnter { + root: CursorEnter.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: CursorEnter.Warnings.Item[]; + } + + export namespace CursorEnter { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface CursorExit { + root: CursorExit.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: CursorExit.Warnings.Item[]; + } + + export namespace CursorExit { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface MouseDown { + root: MouseDown.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: MouseDown.Warnings.Item[]; + } + + export namespace MouseDown { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface MouseUp { + root: MouseUp.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: MouseUp.Warnings.Item[]; + } + + export namespace MouseUp { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface Focus { + root: Focus.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Focus.Warnings.Item[]; + } + + export namespace Focus { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface Blur { + root: Blur.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Blur.Warnings.Item[]; + } + + export namespace Blur { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageOpen { + root: PageOpen.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageOpen.Warnings.Item[]; + } + + export namespace PageOpen { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageClose { + root: PageClose.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageClose.Warnings.Item[]; + } + + export namespace PageClose { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageVisible { + root: PageVisible.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageVisible.Warnings.Item[]; + } + + export namespace PageVisible { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface PageInvisible { + root: PageInvisible.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: PageInvisible.Warnings.Item[]; + } + + export namespace PageInvisible { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + } + } +} diff --git a/src/api/types/DocAnnotationsList200ResponseAnnotationsItemCaretInReplyTo.ts b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemCaretInReplyTo.ts new file mode 100644 index 0000000..322eec9 --- /dev/null +++ b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemCaretInReplyTo.ts @@ -0,0 +1,37 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocAnnotationsList200ResponseAnnotationsItemCaretInReplyTo = + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemCaretInReplyTo.ObjectNumber + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemCaretInReplyTo.Nm + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemCaretInReplyTo.Index; + +export namespace DocAnnotationsList200ResponseAnnotationsItemCaretInReplyTo { + export interface ObjectNumber { + kind: "objectNumber"; + pageObjectNumber: number; + annotObjectNumber: number; + } + + export interface Nm { + kind: "nm"; + pageObjectNumber: number; + nm: string; + } + + export interface Index { + kind: "index"; + pageObjectNumber: number; + index: number; + revision: DocAnnotationsList200ResponseAnnotationsItemCaretInReplyToIndex.Revision; + } + + export namespace DocAnnotationsList200ResponseAnnotationsItemCaretInReplyToIndex { + export interface Revision { + docSessionId: string; + pageObjectNumber: number; + generation: number; + } + } +} diff --git a/src/api/types/DocAnnotationsList200ResponseAnnotationsItemCaretRef.ts b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemCaretRef.ts new file mode 100644 index 0000000..fec45fb --- /dev/null +++ b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemCaretRef.ts @@ -0,0 +1,37 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocAnnotationsList200ResponseAnnotationsItemCaretRef = + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemCaretRef.ObjectNumber + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemCaretRef.Nm + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemCaretRef.Index; + +export namespace DocAnnotationsList200ResponseAnnotationsItemCaretRef { + export interface ObjectNumber { + kind: "objectNumber"; + pageObjectNumber: number; + annotObjectNumber: number; + } + + export interface Nm { + kind: "nm"; + pageObjectNumber: number; + nm: string; + } + + export interface Index { + kind: "index"; + pageObjectNumber: number; + index: number; + revision: DocAnnotationsList200ResponseAnnotationsItemCaretRefIndex.Revision; + } + + export namespace DocAnnotationsList200ResponseAnnotationsItemCaretRefIndex { + export interface Revision { + docSessionId: string; + pageObjectNumber: number; + generation: number; + } + } +} diff --git a/src/api/types/DocAnnotationsList200ResponseAnnotationsItemCircleInReplyTo.ts b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemCircleInReplyTo.ts new file mode 100644 index 0000000..a61686e --- /dev/null +++ b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemCircleInReplyTo.ts @@ -0,0 +1,37 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocAnnotationsList200ResponseAnnotationsItemCircleInReplyTo = + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemCircleInReplyTo.ObjectNumber + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemCircleInReplyTo.Nm + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemCircleInReplyTo.Index; + +export namespace DocAnnotationsList200ResponseAnnotationsItemCircleInReplyTo { + export interface ObjectNumber { + kind: "objectNumber"; + pageObjectNumber: number; + annotObjectNumber: number; + } + + export interface Nm { + kind: "nm"; + pageObjectNumber: number; + nm: string; + } + + export interface Index { + kind: "index"; + pageObjectNumber: number; + index: number; + revision: DocAnnotationsList200ResponseAnnotationsItemCircleInReplyToIndex.Revision; + } + + export namespace DocAnnotationsList200ResponseAnnotationsItemCircleInReplyToIndex { + export interface Revision { + docSessionId: string; + pageObjectNumber: number; + generation: number; + } + } +} diff --git a/src/api/types/DocAnnotationsList200ResponseAnnotationsItemCircleRef.ts b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemCircleRef.ts new file mode 100644 index 0000000..4504758 --- /dev/null +++ b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemCircleRef.ts @@ -0,0 +1,37 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocAnnotationsList200ResponseAnnotationsItemCircleRef = + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemCircleRef.ObjectNumber + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemCircleRef.Nm + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemCircleRef.Index; + +export namespace DocAnnotationsList200ResponseAnnotationsItemCircleRef { + export interface ObjectNumber { + kind: "objectNumber"; + pageObjectNumber: number; + annotObjectNumber: number; + } + + export interface Nm { + kind: "nm"; + pageObjectNumber: number; + nm: string; + } + + export interface Index { + kind: "index"; + pageObjectNumber: number; + index: number; + revision: DocAnnotationsList200ResponseAnnotationsItemCircleRefIndex.Revision; + } + + export namespace DocAnnotationsList200ResponseAnnotationsItemCircleRefIndex { + export interface Revision { + docSessionId: string; + pageObjectNumber: number; + generation: number; + } + } +} diff --git a/src/api/types/DocAnnotationsList200ResponseAnnotationsItemFileAttachmentInReplyTo.ts b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemFileAttachmentInReplyTo.ts new file mode 100644 index 0000000..ea6a479 --- /dev/null +++ b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemFileAttachmentInReplyTo.ts @@ -0,0 +1,37 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocAnnotationsList200ResponseAnnotationsItemFileAttachmentInReplyTo = + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemFileAttachmentInReplyTo.ObjectNumber + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemFileAttachmentInReplyTo.Nm + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemFileAttachmentInReplyTo.Index; + +export namespace DocAnnotationsList200ResponseAnnotationsItemFileAttachmentInReplyTo { + export interface ObjectNumber { + kind: "objectNumber"; + pageObjectNumber: number; + annotObjectNumber: number; + } + + export interface Nm { + kind: "nm"; + pageObjectNumber: number; + nm: string; + } + + export interface Index { + kind: "index"; + pageObjectNumber: number; + index: number; + revision: DocAnnotationsList200ResponseAnnotationsItemFileAttachmentInReplyToIndex.Revision; + } + + export namespace DocAnnotationsList200ResponseAnnotationsItemFileAttachmentInReplyToIndex { + export interface Revision { + docSessionId: string; + pageObjectNumber: number; + generation: number; + } + } +} diff --git a/src/api/types/DocAnnotationsList200ResponseAnnotationsItemFileAttachmentRef.ts b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemFileAttachmentRef.ts new file mode 100644 index 0000000..79a86f4 --- /dev/null +++ b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemFileAttachmentRef.ts @@ -0,0 +1,37 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocAnnotationsList200ResponseAnnotationsItemFileAttachmentRef = + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemFileAttachmentRef.ObjectNumber + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemFileAttachmentRef.Nm + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemFileAttachmentRef.Index; + +export namespace DocAnnotationsList200ResponseAnnotationsItemFileAttachmentRef { + export interface ObjectNumber { + kind: "objectNumber"; + pageObjectNumber: number; + annotObjectNumber: number; + } + + export interface Nm { + kind: "nm"; + pageObjectNumber: number; + nm: string; + } + + export interface Index { + kind: "index"; + pageObjectNumber: number; + index: number; + revision: DocAnnotationsList200ResponseAnnotationsItemFileAttachmentRefIndex.Revision; + } + + export namespace DocAnnotationsList200ResponseAnnotationsItemFileAttachmentRefIndex { + export interface Revision { + docSessionId: string; + pageObjectNumber: number; + generation: number; + } + } +} diff --git a/src/api/types/DocAnnotationsList200ResponseAnnotationsItemFreeTextInReplyTo.ts b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemFreeTextInReplyTo.ts new file mode 100644 index 0000000..f9e035e --- /dev/null +++ b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemFreeTextInReplyTo.ts @@ -0,0 +1,37 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocAnnotationsList200ResponseAnnotationsItemFreeTextInReplyTo = + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemFreeTextInReplyTo.ObjectNumber + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemFreeTextInReplyTo.Nm + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemFreeTextInReplyTo.Index; + +export namespace DocAnnotationsList200ResponseAnnotationsItemFreeTextInReplyTo { + export interface ObjectNumber { + kind: "objectNumber"; + pageObjectNumber: number; + annotObjectNumber: number; + } + + export interface Nm { + kind: "nm"; + pageObjectNumber: number; + nm: string; + } + + export interface Index { + kind: "index"; + pageObjectNumber: number; + index: number; + revision: DocAnnotationsList200ResponseAnnotationsItemFreeTextInReplyToIndex.Revision; + } + + export namespace DocAnnotationsList200ResponseAnnotationsItemFreeTextInReplyToIndex { + export interface Revision { + docSessionId: string; + pageObjectNumber: number; + generation: number; + } + } +} diff --git a/src/api/types/DocAnnotationsList200ResponseAnnotationsItemFreeTextRef.ts b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemFreeTextRef.ts new file mode 100644 index 0000000..eacdfcb --- /dev/null +++ b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemFreeTextRef.ts @@ -0,0 +1,37 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocAnnotationsList200ResponseAnnotationsItemFreeTextRef = + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemFreeTextRef.ObjectNumber + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemFreeTextRef.Nm + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemFreeTextRef.Index; + +export namespace DocAnnotationsList200ResponseAnnotationsItemFreeTextRef { + export interface ObjectNumber { + kind: "objectNumber"; + pageObjectNumber: number; + annotObjectNumber: number; + } + + export interface Nm { + kind: "nm"; + pageObjectNumber: number; + nm: string; + } + + export interface Index { + kind: "index"; + pageObjectNumber: number; + index: number; + revision: DocAnnotationsList200ResponseAnnotationsItemFreeTextRefIndex.Revision; + } + + export namespace DocAnnotationsList200ResponseAnnotationsItemFreeTextRefIndex { + export interface Revision { + docSessionId: string; + pageObjectNumber: number; + generation: number; + } + } +} diff --git a/src/api/types/DocAnnotationsList200ResponseAnnotationsItemHighlightInReplyTo.ts b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemHighlightInReplyTo.ts new file mode 100644 index 0000000..933be77 --- /dev/null +++ b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemHighlightInReplyTo.ts @@ -0,0 +1,37 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocAnnotationsList200ResponseAnnotationsItemHighlightInReplyTo = + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemHighlightInReplyTo.ObjectNumber + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemHighlightInReplyTo.Nm + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemHighlightInReplyTo.Index; + +export namespace DocAnnotationsList200ResponseAnnotationsItemHighlightInReplyTo { + export interface ObjectNumber { + kind: "objectNumber"; + pageObjectNumber: number; + annotObjectNumber: number; + } + + export interface Nm { + kind: "nm"; + pageObjectNumber: number; + nm: string; + } + + export interface Index { + kind: "index"; + pageObjectNumber: number; + index: number; + revision: DocAnnotationsList200ResponseAnnotationsItemHighlightInReplyToIndex.Revision; + } + + export namespace DocAnnotationsList200ResponseAnnotationsItemHighlightInReplyToIndex { + export interface Revision { + docSessionId: string; + pageObjectNumber: number; + generation: number; + } + } +} diff --git a/src/api/types/DocAnnotationsList200ResponseAnnotationsItemHighlightRef.ts b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemHighlightRef.ts new file mode 100644 index 0000000..a878a0b --- /dev/null +++ b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemHighlightRef.ts @@ -0,0 +1,37 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocAnnotationsList200ResponseAnnotationsItemHighlightRef = + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemHighlightRef.ObjectNumber + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemHighlightRef.Nm + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemHighlightRef.Index; + +export namespace DocAnnotationsList200ResponseAnnotationsItemHighlightRef { + export interface ObjectNumber { + kind: "objectNumber"; + pageObjectNumber: number; + annotObjectNumber: number; + } + + export interface Nm { + kind: "nm"; + pageObjectNumber: number; + nm: string; + } + + export interface Index { + kind: "index"; + pageObjectNumber: number; + index: number; + revision: DocAnnotationsList200ResponseAnnotationsItemHighlightRefIndex.Revision; + } + + export namespace DocAnnotationsList200ResponseAnnotationsItemHighlightRefIndex { + export interface Revision { + docSessionId: string; + pageObjectNumber: number; + generation: number; + } + } +} diff --git a/src/api/types/DocAnnotationsList200ResponseAnnotationsItemInkInReplyTo.ts b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemInkInReplyTo.ts new file mode 100644 index 0000000..1fbfeb9 --- /dev/null +++ b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemInkInReplyTo.ts @@ -0,0 +1,37 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocAnnotationsList200ResponseAnnotationsItemInkInReplyTo = + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemInkInReplyTo.ObjectNumber + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemInkInReplyTo.Nm + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemInkInReplyTo.Index; + +export namespace DocAnnotationsList200ResponseAnnotationsItemInkInReplyTo { + export interface ObjectNumber { + kind: "objectNumber"; + pageObjectNumber: number; + annotObjectNumber: number; + } + + export interface Nm { + kind: "nm"; + pageObjectNumber: number; + nm: string; + } + + export interface Index { + kind: "index"; + pageObjectNumber: number; + index: number; + revision: DocAnnotationsList200ResponseAnnotationsItemInkInReplyToIndex.Revision; + } + + export namespace DocAnnotationsList200ResponseAnnotationsItemInkInReplyToIndex { + export interface Revision { + docSessionId: string; + pageObjectNumber: number; + generation: number; + } + } +} diff --git a/src/api/types/DocAnnotationsList200ResponseAnnotationsItemInkRef.ts b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemInkRef.ts new file mode 100644 index 0000000..e4dd989 --- /dev/null +++ b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemInkRef.ts @@ -0,0 +1,37 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocAnnotationsList200ResponseAnnotationsItemInkRef = + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemInkRef.ObjectNumber + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemInkRef.Nm + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemInkRef.Index; + +export namespace DocAnnotationsList200ResponseAnnotationsItemInkRef { + export interface ObjectNumber { + kind: "objectNumber"; + pageObjectNumber: number; + annotObjectNumber: number; + } + + export interface Nm { + kind: "nm"; + pageObjectNumber: number; + nm: string; + } + + export interface Index { + kind: "index"; + pageObjectNumber: number; + index: number; + revision: DocAnnotationsList200ResponseAnnotationsItemInkRefIndex.Revision; + } + + export namespace DocAnnotationsList200ResponseAnnotationsItemInkRefIndex { + export interface Revision { + docSessionId: string; + pageObjectNumber: number; + generation: number; + } + } +} diff --git a/src/api/types/DocAnnotationsList200ResponseAnnotationsItemLineInReplyTo.ts b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemLineInReplyTo.ts new file mode 100644 index 0000000..bec67f8 --- /dev/null +++ b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemLineInReplyTo.ts @@ -0,0 +1,37 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocAnnotationsList200ResponseAnnotationsItemLineInReplyTo = + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemLineInReplyTo.ObjectNumber + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemLineInReplyTo.Nm + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemLineInReplyTo.Index; + +export namespace DocAnnotationsList200ResponseAnnotationsItemLineInReplyTo { + export interface ObjectNumber { + kind: "objectNumber"; + pageObjectNumber: number; + annotObjectNumber: number; + } + + export interface Nm { + kind: "nm"; + pageObjectNumber: number; + nm: string; + } + + export interface Index { + kind: "index"; + pageObjectNumber: number; + index: number; + revision: DocAnnotationsList200ResponseAnnotationsItemLineInReplyToIndex.Revision; + } + + export namespace DocAnnotationsList200ResponseAnnotationsItemLineInReplyToIndex { + export interface Revision { + docSessionId: string; + pageObjectNumber: number; + generation: number; + } + } +} diff --git a/src/api/types/DocAnnotationsList200ResponseAnnotationsItemLineRef.ts b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemLineRef.ts new file mode 100644 index 0000000..5de526c --- /dev/null +++ b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemLineRef.ts @@ -0,0 +1,37 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocAnnotationsList200ResponseAnnotationsItemLineRef = + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemLineRef.ObjectNumber + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemLineRef.Nm + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemLineRef.Index; + +export namespace DocAnnotationsList200ResponseAnnotationsItemLineRef { + export interface ObjectNumber { + kind: "objectNumber"; + pageObjectNumber: number; + annotObjectNumber: number; + } + + export interface Nm { + kind: "nm"; + pageObjectNumber: number; + nm: string; + } + + export interface Index { + kind: "index"; + pageObjectNumber: number; + index: number; + revision: DocAnnotationsList200ResponseAnnotationsItemLineRefIndex.Revision; + } + + export namespace DocAnnotationsList200ResponseAnnotationsItemLineRefIndex { + export interface Revision { + docSessionId: string; + pageObjectNumber: number; + generation: number; + } + } +} diff --git a/src/api/types/DocAnnotationsList200ResponseAnnotationsItemLinkInReplyTo.ts b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemLinkInReplyTo.ts new file mode 100644 index 0000000..d4dbe56 --- /dev/null +++ b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemLinkInReplyTo.ts @@ -0,0 +1,37 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocAnnotationsList200ResponseAnnotationsItemLinkInReplyTo = + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemLinkInReplyTo.ObjectNumber + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemLinkInReplyTo.Nm + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemLinkInReplyTo.Index; + +export namespace DocAnnotationsList200ResponseAnnotationsItemLinkInReplyTo { + export interface ObjectNumber { + kind: "objectNumber"; + pageObjectNumber: number; + annotObjectNumber: number; + } + + export interface Nm { + kind: "nm"; + pageObjectNumber: number; + nm: string; + } + + export interface Index { + kind: "index"; + pageObjectNumber: number; + index: number; + revision: DocAnnotationsList200ResponseAnnotationsItemLinkInReplyToIndex.Revision; + } + + export namespace DocAnnotationsList200ResponseAnnotationsItemLinkInReplyToIndex { + export interface Revision { + docSessionId: string; + pageObjectNumber: number; + generation: number; + } + } +} diff --git a/src/api/types/DocAnnotationsList200ResponseAnnotationsItemLinkRef.ts b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemLinkRef.ts new file mode 100644 index 0000000..39abf4b --- /dev/null +++ b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemLinkRef.ts @@ -0,0 +1,37 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocAnnotationsList200ResponseAnnotationsItemLinkRef = + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemLinkRef.ObjectNumber + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemLinkRef.Nm + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemLinkRef.Index; + +export namespace DocAnnotationsList200ResponseAnnotationsItemLinkRef { + export interface ObjectNumber { + kind: "objectNumber"; + pageObjectNumber: number; + annotObjectNumber: number; + } + + export interface Nm { + kind: "nm"; + pageObjectNumber: number; + nm: string; + } + + export interface Index { + kind: "index"; + pageObjectNumber: number; + index: number; + revision: DocAnnotationsList200ResponseAnnotationsItemLinkRefIndex.Revision; + } + + export namespace DocAnnotationsList200ResponseAnnotationsItemLinkRefIndex { + export interface Revision { + docSessionId: string; + pageObjectNumber: number; + generation: number; + } + } +} diff --git a/src/api/types/DocAnnotationsList200ResponseAnnotationsItemLinkTarget.ts b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemLinkTarget.ts new file mode 100644 index 0000000..a1bd174 --- /dev/null +++ b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemLinkTarget.ts @@ -0,0 +1,47 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocAnnotationsList200ResponseAnnotationsItemLinkTarget = + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemLinkTarget.Goto + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemLinkTarget.Uri + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemLinkTarget.GotoRemote + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemLinkTarget.Launch + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemLinkTarget.Javascript + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemLinkTarget.Named + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemLinkTarget.Unsupported; + +export namespace DocAnnotationsList200ResponseAnnotationsItemLinkTarget { + export interface Goto { + kind: "goto"; + destination: CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemLinkTargetGotoDestination; + } + + export interface Uri { + kind: "uri"; + uri: string; + } + + export interface GotoRemote { + kind: "goto-remote"; + file: string; + } + + export interface Launch { + kind: "launch"; + path: string; + } + + export interface Javascript { + kind: "javascript"; + } + + export interface Named { + kind: "named"; + name: string; + } + + export interface Unsupported { + kind: "unsupported"; + } +} diff --git a/src/api/types/DocAnnotationsList200ResponseAnnotationsItemLinkTargetGotoDestination.ts b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemLinkTargetGotoDestination.ts new file mode 100644 index 0000000..e9d8e20 --- /dev/null +++ b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemLinkTargetGotoDestination.ts @@ -0,0 +1,66 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocAnnotationsList200ResponseAnnotationsItemLinkTargetGotoDestination = + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemLinkTargetGotoDestination.Xyz + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemLinkTargetGotoDestination.Fit + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemLinkTargetGotoDestination.FitH + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemLinkTargetGotoDestination.FitV + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemLinkTargetGotoDestination.FitR + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemLinkTargetGotoDestination.FitB + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemLinkTargetGotoDestination.FitBh + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemLinkTargetGotoDestination.FitBv; + +export namespace DocAnnotationsList200ResponseAnnotationsItemLinkTargetGotoDestination { + export interface Xyz { + kind: "xyz"; + pageObjectNumber: number; + left?: (number | null) | undefined; + top?: (number | null) | undefined; + zoom?: (number | null) | undefined; + } + + export interface Fit { + kind: "fit"; + pageObjectNumber: number; + } + + export interface FitH { + kind: "fitH"; + pageObjectNumber: number; + top?: (number | null) | undefined; + } + + export interface FitV { + kind: "fitV"; + pageObjectNumber: number; + left?: (number | null) | undefined; + } + + export interface FitR { + kind: "fitR"; + pageObjectNumber: number; + left: number; + bottom: number; + right: number; + top: number; + } + + export interface FitB { + kind: "fitB"; + pageObjectNumber: number; + } + + export interface FitBh { + kind: "fitBH"; + pageObjectNumber: number; + top?: (number | null) | undefined; + } + + export interface FitBv { + kind: "fitBV"; + pageObjectNumber: number; + left?: (number | null) | undefined; + } +} diff --git a/src/api/types/DocAnnotationsList200ResponseAnnotationsItemPolygonInReplyTo.ts b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemPolygonInReplyTo.ts new file mode 100644 index 0000000..bd26cb9 --- /dev/null +++ b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemPolygonInReplyTo.ts @@ -0,0 +1,37 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocAnnotationsList200ResponseAnnotationsItemPolygonInReplyTo = + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemPolygonInReplyTo.ObjectNumber + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemPolygonInReplyTo.Nm + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemPolygonInReplyTo.Index; + +export namespace DocAnnotationsList200ResponseAnnotationsItemPolygonInReplyTo { + export interface ObjectNumber { + kind: "objectNumber"; + pageObjectNumber: number; + annotObjectNumber: number; + } + + export interface Nm { + kind: "nm"; + pageObjectNumber: number; + nm: string; + } + + export interface Index { + kind: "index"; + pageObjectNumber: number; + index: number; + revision: DocAnnotationsList200ResponseAnnotationsItemPolygonInReplyToIndex.Revision; + } + + export namespace DocAnnotationsList200ResponseAnnotationsItemPolygonInReplyToIndex { + export interface Revision { + docSessionId: string; + pageObjectNumber: number; + generation: number; + } + } +} diff --git a/src/api/types/DocAnnotationsList200ResponseAnnotationsItemPolygonRef.ts b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemPolygonRef.ts new file mode 100644 index 0000000..8c80f45 --- /dev/null +++ b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemPolygonRef.ts @@ -0,0 +1,37 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocAnnotationsList200ResponseAnnotationsItemPolygonRef = + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemPolygonRef.ObjectNumber + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemPolygonRef.Nm + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemPolygonRef.Index; + +export namespace DocAnnotationsList200ResponseAnnotationsItemPolygonRef { + export interface ObjectNumber { + kind: "objectNumber"; + pageObjectNumber: number; + annotObjectNumber: number; + } + + export interface Nm { + kind: "nm"; + pageObjectNumber: number; + nm: string; + } + + export interface Index { + kind: "index"; + pageObjectNumber: number; + index: number; + revision: DocAnnotationsList200ResponseAnnotationsItemPolygonRefIndex.Revision; + } + + export namespace DocAnnotationsList200ResponseAnnotationsItemPolygonRefIndex { + export interface Revision { + docSessionId: string; + pageObjectNumber: number; + generation: number; + } + } +} diff --git a/src/api/types/DocAnnotationsList200ResponseAnnotationsItemPolylineInReplyTo.ts b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemPolylineInReplyTo.ts new file mode 100644 index 0000000..0dcff22 --- /dev/null +++ b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemPolylineInReplyTo.ts @@ -0,0 +1,37 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocAnnotationsList200ResponseAnnotationsItemPolylineInReplyTo = + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemPolylineInReplyTo.ObjectNumber + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemPolylineInReplyTo.Nm + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemPolylineInReplyTo.Index; + +export namespace DocAnnotationsList200ResponseAnnotationsItemPolylineInReplyTo { + export interface ObjectNumber { + kind: "objectNumber"; + pageObjectNumber: number; + annotObjectNumber: number; + } + + export interface Nm { + kind: "nm"; + pageObjectNumber: number; + nm: string; + } + + export interface Index { + kind: "index"; + pageObjectNumber: number; + index: number; + revision: DocAnnotationsList200ResponseAnnotationsItemPolylineInReplyToIndex.Revision; + } + + export namespace DocAnnotationsList200ResponseAnnotationsItemPolylineInReplyToIndex { + export interface Revision { + docSessionId: string; + pageObjectNumber: number; + generation: number; + } + } +} diff --git a/src/api/types/DocAnnotationsList200ResponseAnnotationsItemPolylineRef.ts b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemPolylineRef.ts new file mode 100644 index 0000000..3e5a28d --- /dev/null +++ b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemPolylineRef.ts @@ -0,0 +1,37 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocAnnotationsList200ResponseAnnotationsItemPolylineRef = + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemPolylineRef.ObjectNumber + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemPolylineRef.Nm + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemPolylineRef.Index; + +export namespace DocAnnotationsList200ResponseAnnotationsItemPolylineRef { + export interface ObjectNumber { + kind: "objectNumber"; + pageObjectNumber: number; + annotObjectNumber: number; + } + + export interface Nm { + kind: "nm"; + pageObjectNumber: number; + nm: string; + } + + export interface Index { + kind: "index"; + pageObjectNumber: number; + index: number; + revision: DocAnnotationsList200ResponseAnnotationsItemPolylineRefIndex.Revision; + } + + export namespace DocAnnotationsList200ResponseAnnotationsItemPolylineRefIndex { + export interface Revision { + docSessionId: string; + pageObjectNumber: number; + generation: number; + } + } +} diff --git a/src/api/types/DocAnnotationsList200ResponseAnnotationsItemRedactInReplyTo.ts b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemRedactInReplyTo.ts new file mode 100644 index 0000000..10c8d55 --- /dev/null +++ b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemRedactInReplyTo.ts @@ -0,0 +1,37 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocAnnotationsList200ResponseAnnotationsItemRedactInReplyTo = + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemRedactInReplyTo.ObjectNumber + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemRedactInReplyTo.Nm + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemRedactInReplyTo.Index; + +export namespace DocAnnotationsList200ResponseAnnotationsItemRedactInReplyTo { + export interface ObjectNumber { + kind: "objectNumber"; + pageObjectNumber: number; + annotObjectNumber: number; + } + + export interface Nm { + kind: "nm"; + pageObjectNumber: number; + nm: string; + } + + export interface Index { + kind: "index"; + pageObjectNumber: number; + index: number; + revision: DocAnnotationsList200ResponseAnnotationsItemRedactInReplyToIndex.Revision; + } + + export namespace DocAnnotationsList200ResponseAnnotationsItemRedactInReplyToIndex { + export interface Revision { + docSessionId: string; + pageObjectNumber: number; + generation: number; + } + } +} diff --git a/src/api/types/DocAnnotationsList200ResponseAnnotationsItemRedactRef.ts b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemRedactRef.ts new file mode 100644 index 0000000..0607c77 --- /dev/null +++ b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemRedactRef.ts @@ -0,0 +1,37 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocAnnotationsList200ResponseAnnotationsItemRedactRef = + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemRedactRef.ObjectNumber + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemRedactRef.Nm + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemRedactRef.Index; + +export namespace DocAnnotationsList200ResponseAnnotationsItemRedactRef { + export interface ObjectNumber { + kind: "objectNumber"; + pageObjectNumber: number; + annotObjectNumber: number; + } + + export interface Nm { + kind: "nm"; + pageObjectNumber: number; + nm: string; + } + + export interface Index { + kind: "index"; + pageObjectNumber: number; + index: number; + revision: DocAnnotationsList200ResponseAnnotationsItemRedactRefIndex.Revision; + } + + export namespace DocAnnotationsList200ResponseAnnotationsItemRedactRefIndex { + export interface Revision { + docSessionId: string; + pageObjectNumber: number; + generation: number; + } + } +} diff --git a/src/api/types/DocAnnotationsList200ResponseAnnotationsItemSquareInReplyTo.ts b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemSquareInReplyTo.ts new file mode 100644 index 0000000..9e82e76 --- /dev/null +++ b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemSquareInReplyTo.ts @@ -0,0 +1,37 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocAnnotationsList200ResponseAnnotationsItemSquareInReplyTo = + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemSquareInReplyTo.ObjectNumber + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemSquareInReplyTo.Nm + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemSquareInReplyTo.Index; + +export namespace DocAnnotationsList200ResponseAnnotationsItemSquareInReplyTo { + export interface ObjectNumber { + kind: "objectNumber"; + pageObjectNumber: number; + annotObjectNumber: number; + } + + export interface Nm { + kind: "nm"; + pageObjectNumber: number; + nm: string; + } + + export interface Index { + kind: "index"; + pageObjectNumber: number; + index: number; + revision: DocAnnotationsList200ResponseAnnotationsItemSquareInReplyToIndex.Revision; + } + + export namespace DocAnnotationsList200ResponseAnnotationsItemSquareInReplyToIndex { + export interface Revision { + docSessionId: string; + pageObjectNumber: number; + generation: number; + } + } +} diff --git a/src/api/types/DocAnnotationsList200ResponseAnnotationsItemSquareRef.ts b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemSquareRef.ts new file mode 100644 index 0000000..6842ee0 --- /dev/null +++ b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemSquareRef.ts @@ -0,0 +1,37 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocAnnotationsList200ResponseAnnotationsItemSquareRef = + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemSquareRef.ObjectNumber + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemSquareRef.Nm + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemSquareRef.Index; + +export namespace DocAnnotationsList200ResponseAnnotationsItemSquareRef { + export interface ObjectNumber { + kind: "objectNumber"; + pageObjectNumber: number; + annotObjectNumber: number; + } + + export interface Nm { + kind: "nm"; + pageObjectNumber: number; + nm: string; + } + + export interface Index { + kind: "index"; + pageObjectNumber: number; + index: number; + revision: DocAnnotationsList200ResponseAnnotationsItemSquareRefIndex.Revision; + } + + export namespace DocAnnotationsList200ResponseAnnotationsItemSquareRefIndex { + export interface Revision { + docSessionId: string; + pageObjectNumber: number; + generation: number; + } + } +} diff --git a/src/api/types/DocAnnotationsList200ResponseAnnotationsItemSquigglyInReplyTo.ts b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemSquigglyInReplyTo.ts new file mode 100644 index 0000000..3667cd3 --- /dev/null +++ b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemSquigglyInReplyTo.ts @@ -0,0 +1,37 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocAnnotationsList200ResponseAnnotationsItemSquigglyInReplyTo = + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemSquigglyInReplyTo.ObjectNumber + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemSquigglyInReplyTo.Nm + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemSquigglyInReplyTo.Index; + +export namespace DocAnnotationsList200ResponseAnnotationsItemSquigglyInReplyTo { + export interface ObjectNumber { + kind: "objectNumber"; + pageObjectNumber: number; + annotObjectNumber: number; + } + + export interface Nm { + kind: "nm"; + pageObjectNumber: number; + nm: string; + } + + export interface Index { + kind: "index"; + pageObjectNumber: number; + index: number; + revision: DocAnnotationsList200ResponseAnnotationsItemSquigglyInReplyToIndex.Revision; + } + + export namespace DocAnnotationsList200ResponseAnnotationsItemSquigglyInReplyToIndex { + export interface Revision { + docSessionId: string; + pageObjectNumber: number; + generation: number; + } + } +} diff --git a/src/api/types/DocAnnotationsList200ResponseAnnotationsItemSquigglyRef.ts b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemSquigglyRef.ts new file mode 100644 index 0000000..b88a90a --- /dev/null +++ b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemSquigglyRef.ts @@ -0,0 +1,37 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocAnnotationsList200ResponseAnnotationsItemSquigglyRef = + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemSquigglyRef.ObjectNumber + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemSquigglyRef.Nm + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemSquigglyRef.Index; + +export namespace DocAnnotationsList200ResponseAnnotationsItemSquigglyRef { + export interface ObjectNumber { + kind: "objectNumber"; + pageObjectNumber: number; + annotObjectNumber: number; + } + + export interface Nm { + kind: "nm"; + pageObjectNumber: number; + nm: string; + } + + export interface Index { + kind: "index"; + pageObjectNumber: number; + index: number; + revision: DocAnnotationsList200ResponseAnnotationsItemSquigglyRefIndex.Revision; + } + + export namespace DocAnnotationsList200ResponseAnnotationsItemSquigglyRefIndex { + export interface Revision { + docSessionId: string; + pageObjectNumber: number; + generation: number; + } + } +} diff --git a/src/api/types/DocAnnotationsList200ResponseAnnotationsItemStampInReplyTo.ts b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemStampInReplyTo.ts new file mode 100644 index 0000000..7a61a98 --- /dev/null +++ b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemStampInReplyTo.ts @@ -0,0 +1,37 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocAnnotationsList200ResponseAnnotationsItemStampInReplyTo = + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemStampInReplyTo.ObjectNumber + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemStampInReplyTo.Nm + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemStampInReplyTo.Index; + +export namespace DocAnnotationsList200ResponseAnnotationsItemStampInReplyTo { + export interface ObjectNumber { + kind: "objectNumber"; + pageObjectNumber: number; + annotObjectNumber: number; + } + + export interface Nm { + kind: "nm"; + pageObjectNumber: number; + nm: string; + } + + export interface Index { + kind: "index"; + pageObjectNumber: number; + index: number; + revision: DocAnnotationsList200ResponseAnnotationsItemStampInReplyToIndex.Revision; + } + + export namespace DocAnnotationsList200ResponseAnnotationsItemStampInReplyToIndex { + export interface Revision { + docSessionId: string; + pageObjectNumber: number; + generation: number; + } + } +} diff --git a/src/api/types/DocAnnotationsList200ResponseAnnotationsItemStampRef.ts b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemStampRef.ts new file mode 100644 index 0000000..44c2f8f --- /dev/null +++ b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemStampRef.ts @@ -0,0 +1,37 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocAnnotationsList200ResponseAnnotationsItemStampRef = + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemStampRef.ObjectNumber + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemStampRef.Nm + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemStampRef.Index; + +export namespace DocAnnotationsList200ResponseAnnotationsItemStampRef { + export interface ObjectNumber { + kind: "objectNumber"; + pageObjectNumber: number; + annotObjectNumber: number; + } + + export interface Nm { + kind: "nm"; + pageObjectNumber: number; + nm: string; + } + + export interface Index { + kind: "index"; + pageObjectNumber: number; + index: number; + revision: DocAnnotationsList200ResponseAnnotationsItemStampRefIndex.Revision; + } + + export namespace DocAnnotationsList200ResponseAnnotationsItemStampRefIndex { + export interface Revision { + docSessionId: string; + pageObjectNumber: number; + generation: number; + } + } +} diff --git a/src/api/types/DocAnnotationsList200ResponseAnnotationsItemStrikeoutInReplyTo.ts b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemStrikeoutInReplyTo.ts new file mode 100644 index 0000000..8262808 --- /dev/null +++ b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemStrikeoutInReplyTo.ts @@ -0,0 +1,37 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocAnnotationsList200ResponseAnnotationsItemStrikeoutInReplyTo = + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemStrikeoutInReplyTo.ObjectNumber + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemStrikeoutInReplyTo.Nm + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemStrikeoutInReplyTo.Index; + +export namespace DocAnnotationsList200ResponseAnnotationsItemStrikeoutInReplyTo { + export interface ObjectNumber { + kind: "objectNumber"; + pageObjectNumber: number; + annotObjectNumber: number; + } + + export interface Nm { + kind: "nm"; + pageObjectNumber: number; + nm: string; + } + + export interface Index { + kind: "index"; + pageObjectNumber: number; + index: number; + revision: DocAnnotationsList200ResponseAnnotationsItemStrikeoutInReplyToIndex.Revision; + } + + export namespace DocAnnotationsList200ResponseAnnotationsItemStrikeoutInReplyToIndex { + export interface Revision { + docSessionId: string; + pageObjectNumber: number; + generation: number; + } + } +} diff --git a/src/api/types/DocAnnotationsList200ResponseAnnotationsItemStrikeoutRef.ts b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemStrikeoutRef.ts new file mode 100644 index 0000000..4790599 --- /dev/null +++ b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemStrikeoutRef.ts @@ -0,0 +1,37 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocAnnotationsList200ResponseAnnotationsItemStrikeoutRef = + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemStrikeoutRef.ObjectNumber + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemStrikeoutRef.Nm + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemStrikeoutRef.Index; + +export namespace DocAnnotationsList200ResponseAnnotationsItemStrikeoutRef { + export interface ObjectNumber { + kind: "objectNumber"; + pageObjectNumber: number; + annotObjectNumber: number; + } + + export interface Nm { + kind: "nm"; + pageObjectNumber: number; + nm: string; + } + + export interface Index { + kind: "index"; + pageObjectNumber: number; + index: number; + revision: DocAnnotationsList200ResponseAnnotationsItemStrikeoutRefIndex.Revision; + } + + export namespace DocAnnotationsList200ResponseAnnotationsItemStrikeoutRefIndex { + export interface Revision { + docSessionId: string; + pageObjectNumber: number; + generation: number; + } + } +} diff --git a/src/api/types/DocAnnotationsList200ResponseAnnotationsItemTextInReplyTo.ts b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemTextInReplyTo.ts new file mode 100644 index 0000000..1e019d0 --- /dev/null +++ b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemTextInReplyTo.ts @@ -0,0 +1,37 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocAnnotationsList200ResponseAnnotationsItemTextInReplyTo = + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemTextInReplyTo.ObjectNumber + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemTextInReplyTo.Nm + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemTextInReplyTo.Index; + +export namespace DocAnnotationsList200ResponseAnnotationsItemTextInReplyTo { + export interface ObjectNumber { + kind: "objectNumber"; + pageObjectNumber: number; + annotObjectNumber: number; + } + + export interface Nm { + kind: "nm"; + pageObjectNumber: number; + nm: string; + } + + export interface Index { + kind: "index"; + pageObjectNumber: number; + index: number; + revision: DocAnnotationsList200ResponseAnnotationsItemTextInReplyToIndex.Revision; + } + + export namespace DocAnnotationsList200ResponseAnnotationsItemTextInReplyToIndex { + export interface Revision { + docSessionId: string; + pageObjectNumber: number; + generation: number; + } + } +} diff --git a/src/api/types/DocAnnotationsList200ResponseAnnotationsItemTextRef.ts b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemTextRef.ts new file mode 100644 index 0000000..84d7974 --- /dev/null +++ b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemTextRef.ts @@ -0,0 +1,37 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocAnnotationsList200ResponseAnnotationsItemTextRef = + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemTextRef.ObjectNumber + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemTextRef.Nm + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemTextRef.Index; + +export namespace DocAnnotationsList200ResponseAnnotationsItemTextRef { + export interface ObjectNumber { + kind: "objectNumber"; + pageObjectNumber: number; + annotObjectNumber: number; + } + + export interface Nm { + kind: "nm"; + pageObjectNumber: number; + nm: string; + } + + export interface Index { + kind: "index"; + pageObjectNumber: number; + index: number; + revision: DocAnnotationsList200ResponseAnnotationsItemTextRefIndex.Revision; + } + + export namespace DocAnnotationsList200ResponseAnnotationsItemTextRefIndex { + export interface Revision { + docSessionId: string; + pageObjectNumber: number; + generation: number; + } + } +} diff --git a/src/api/types/DocAnnotationsList200ResponseAnnotationsItemUnderlineInReplyTo.ts b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemUnderlineInReplyTo.ts new file mode 100644 index 0000000..3af4a9d --- /dev/null +++ b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemUnderlineInReplyTo.ts @@ -0,0 +1,37 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocAnnotationsList200ResponseAnnotationsItemUnderlineInReplyTo = + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemUnderlineInReplyTo.ObjectNumber + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemUnderlineInReplyTo.Nm + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemUnderlineInReplyTo.Index; + +export namespace DocAnnotationsList200ResponseAnnotationsItemUnderlineInReplyTo { + export interface ObjectNumber { + kind: "objectNumber"; + pageObjectNumber: number; + annotObjectNumber: number; + } + + export interface Nm { + kind: "nm"; + pageObjectNumber: number; + nm: string; + } + + export interface Index { + kind: "index"; + pageObjectNumber: number; + index: number; + revision: DocAnnotationsList200ResponseAnnotationsItemUnderlineInReplyToIndex.Revision; + } + + export namespace DocAnnotationsList200ResponseAnnotationsItemUnderlineInReplyToIndex { + export interface Revision { + docSessionId: string; + pageObjectNumber: number; + generation: number; + } + } +} diff --git a/src/api/types/DocAnnotationsList200ResponseAnnotationsItemUnderlineRef.ts b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemUnderlineRef.ts new file mode 100644 index 0000000..86230d8 --- /dev/null +++ b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemUnderlineRef.ts @@ -0,0 +1,37 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocAnnotationsList200ResponseAnnotationsItemUnderlineRef = + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemUnderlineRef.ObjectNumber + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemUnderlineRef.Nm + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemUnderlineRef.Index; + +export namespace DocAnnotationsList200ResponseAnnotationsItemUnderlineRef { + export interface ObjectNumber { + kind: "objectNumber"; + pageObjectNumber: number; + annotObjectNumber: number; + } + + export interface Nm { + kind: "nm"; + pageObjectNumber: number; + nm: string; + } + + export interface Index { + kind: "index"; + pageObjectNumber: number; + index: number; + revision: DocAnnotationsList200ResponseAnnotationsItemUnderlineRefIndex.Revision; + } + + export namespace DocAnnotationsList200ResponseAnnotationsItemUnderlineRefIndex { + export interface Revision { + docSessionId: string; + pageObjectNumber: number; + generation: number; + } + } +} diff --git a/src/api/types/DocAnnotationsList200ResponseAnnotationsItemUnsupportedInReplyTo.ts b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemUnsupportedInReplyTo.ts new file mode 100644 index 0000000..7046aec --- /dev/null +++ b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemUnsupportedInReplyTo.ts @@ -0,0 +1,37 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocAnnotationsList200ResponseAnnotationsItemUnsupportedInReplyTo = + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemUnsupportedInReplyTo.ObjectNumber + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemUnsupportedInReplyTo.Nm + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemUnsupportedInReplyTo.Index; + +export namespace DocAnnotationsList200ResponseAnnotationsItemUnsupportedInReplyTo { + export interface ObjectNumber { + kind: "objectNumber"; + pageObjectNumber: number; + annotObjectNumber: number; + } + + export interface Nm { + kind: "nm"; + pageObjectNumber: number; + nm: string; + } + + export interface Index { + kind: "index"; + pageObjectNumber: number; + index: number; + revision: DocAnnotationsList200ResponseAnnotationsItemUnsupportedInReplyToIndex.Revision; + } + + export namespace DocAnnotationsList200ResponseAnnotationsItemUnsupportedInReplyToIndex { + export interface Revision { + docSessionId: string; + pageObjectNumber: number; + generation: number; + } + } +} diff --git a/src/api/types/DocAnnotationsList200ResponseAnnotationsItemUnsupportedRef.ts b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemUnsupportedRef.ts new file mode 100644 index 0000000..7038e38 --- /dev/null +++ b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemUnsupportedRef.ts @@ -0,0 +1,37 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocAnnotationsList200ResponseAnnotationsItemUnsupportedRef = + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemUnsupportedRef.ObjectNumber + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemUnsupportedRef.Nm + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemUnsupportedRef.Index; + +export namespace DocAnnotationsList200ResponseAnnotationsItemUnsupportedRef { + export interface ObjectNumber { + kind: "objectNumber"; + pageObjectNumber: number; + annotObjectNumber: number; + } + + export interface Nm { + kind: "nm"; + pageObjectNumber: number; + nm: string; + } + + export interface Index { + kind: "index"; + pageObjectNumber: number; + index: number; + revision: DocAnnotationsList200ResponseAnnotationsItemUnsupportedRefIndex.Revision; + } + + export namespace DocAnnotationsList200ResponseAnnotationsItemUnsupportedRefIndex { + export interface Revision { + docSessionId: string; + pageObjectNumber: number; + generation: number; + } + } +} diff --git a/src/api/types/DocAnnotationsList200ResponseAnnotationsItemWidgetInReplyTo.ts b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemWidgetInReplyTo.ts new file mode 100644 index 0000000..d119f2b --- /dev/null +++ b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemWidgetInReplyTo.ts @@ -0,0 +1,37 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocAnnotationsList200ResponseAnnotationsItemWidgetInReplyTo = + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemWidgetInReplyTo.ObjectNumber + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemWidgetInReplyTo.Nm + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemWidgetInReplyTo.Index; + +export namespace DocAnnotationsList200ResponseAnnotationsItemWidgetInReplyTo { + export interface ObjectNumber { + kind: "objectNumber"; + pageObjectNumber: number; + annotObjectNumber: number; + } + + export interface Nm { + kind: "nm"; + pageObjectNumber: number; + nm: string; + } + + export interface Index { + kind: "index"; + pageObjectNumber: number; + index: number; + revision: DocAnnotationsList200ResponseAnnotationsItemWidgetInReplyToIndex.Revision; + } + + export namespace DocAnnotationsList200ResponseAnnotationsItemWidgetInReplyToIndex { + export interface Revision { + docSessionId: string; + pageObjectNumber: number; + generation: number; + } + } +} diff --git a/src/api/types/DocAnnotationsList200ResponseAnnotationsItemWidgetRef.ts b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemWidgetRef.ts new file mode 100644 index 0000000..40503a3 --- /dev/null +++ b/src/api/types/DocAnnotationsList200ResponseAnnotationsItemWidgetRef.ts @@ -0,0 +1,37 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocAnnotationsList200ResponseAnnotationsItemWidgetRef = + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemWidgetRef.ObjectNumber + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemWidgetRef.Nm + | CloudpdfApi.DocAnnotationsList200ResponseAnnotationsItemWidgetRef.Index; + +export namespace DocAnnotationsList200ResponseAnnotationsItemWidgetRef { + export interface ObjectNumber { + kind: "objectNumber"; + pageObjectNumber: number; + annotObjectNumber: number; + } + + export interface Nm { + kind: "nm"; + pageObjectNumber: number; + nm: string; + } + + export interface Index { + kind: "index"; + pageObjectNumber: number; + index: number; + revision: DocAnnotationsList200ResponseAnnotationsItemWidgetRefIndex.Revision; + } + + export namespace DocAnnotationsList200ResponseAnnotationsItemWidgetRefIndex { + export interface Revision { + docSessionId: string; + pageObjectNumber: number; + generation: number; + } + } +} diff --git a/src/api/types/DocAnnotationsList200ResponsePageStateWeakAnnotationState.ts b/src/api/types/DocAnnotationsList200ResponsePageStateWeakAnnotationState.ts new file mode 100644 index 0000000..2bef058 --- /dev/null +++ b/src/api/types/DocAnnotationsList200ResponsePageStateWeakAnnotationState.ts @@ -0,0 +1,18 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocAnnotationsList200ResponsePageStateWeakAnnotationState = + | CloudpdfApi.DocAnnotationsList200ResponsePageStateWeakAnnotationState.Unknown + | CloudpdfApi.DocAnnotationsList200ResponsePageStateWeakAnnotationState.Known; + +export namespace DocAnnotationsList200ResponsePageStateWeakAnnotationState { + export interface Unknown { + kind: "unknown"; + } + + export interface Known { + kind: "known"; + hasAnyWeakAnnotations: boolean; + } +} diff --git a/src/api/types/DocAnnotationsList404Response.ts b/src/api/types/DocAnnotationsList404Response.ts new file mode 100644 index 0000000..96ff752 --- /dev/null +++ b/src/api/types/DocAnnotationsList404Response.ts @@ -0,0 +1,36 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface DocAnnotationsList404Response { + name: DocAnnotationsList404Response.Name; + code: DocAnnotationsList404Response.Code; + message: string; + details?: Record | undefined; +} + +export namespace DocAnnotationsList404Response { + export const Name = { + EngineError: "EngineError", + } as const; + export type Name = (typeof Name)[keyof typeof Name]; + export const Code = { + Unknown: "Unknown", + InvalidArg: "InvalidArg", + DocNotOpen: "DocNotOpen", + DocOpenFailed: "DocOpenFailed", + DocPasswordRequired: "DocPasswordRequired", + DocPasswordIncorrect: "DocPasswordIncorrect", + Aborted: "Aborted", + Network: "Network", + Unauthenticated: "Unauthenticated", + Forbidden: "Forbidden", + NotFound: "NotFound", + WireFormat: "WireFormat", + RuntimeUnavailable: "RuntimeUnavailable", + InvalidReference: "InvalidReference", + WeakAnnotationSessionConflict: "WeakAnnotationSessionConflict", + LayerVersionConflict: "LayerVersionConflict", + NotImplemented: "NotImplemented", + MalformedPdf: "MalformedPdf", + } as const; + export type Code = (typeof Code)[keyof typeof Code]; +} diff --git a/src/api/types/DocAnnotationsUpdate200Response.ts b/src/api/types/DocAnnotationsUpdate200Response.ts new file mode 100644 index 0000000..3dfc625 --- /dev/null +++ b/src/api/types/DocAnnotationsUpdate200Response.ts @@ -0,0 +1,60 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export interface DocAnnotationsUpdate200Response { + meta: DocAnnotationsUpdate200Response.Meta; + /** Accepts any additional properties */ + [key: string]: any; +} + +export namespace DocAnnotationsUpdate200Response { + export interface Meta { + affectedPages: Meta.AffectedPages.Item[]; + cacheDelta: Meta.CacheDelta | null; + } + + export namespace Meta { + export type AffectedPages = AffectedPages.Item[]; + + export namespace AffectedPages { + export interface Item { + pageObjectNumber: number; + revision: Item.Revision; + weakAnnotationState: CloudpdfApi.DocAnnotationsUpdate200ResponseMetaAffectedPagesItemWeakAnnotationState; + } + + export namespace Item { + export interface Revision { + docSessionId: string; + pageObjectNumber: number; + generation: number; + } + } + } + + export interface CacheDelta { + previousDocVersion: number; + docVersion: number; + pages: CacheDelta.Pages.Item[]; + } + + export namespace CacheDelta { + export type Pages = Pages.Item[]; + + export namespace Pages { + export interface Item { + pageObjectNumber: number; + cache: Item.Cache; + } + + export namespace Item { + export interface Cache { + contentVersion: number; + annotationVersion: number; + } + } + } + } + } +} diff --git a/src/api/types/DocAnnotationsUpdate200ResponseMetaAffectedPagesItemWeakAnnotationState.ts b/src/api/types/DocAnnotationsUpdate200ResponseMetaAffectedPagesItemWeakAnnotationState.ts new file mode 100644 index 0000000..9c7ab4e --- /dev/null +++ b/src/api/types/DocAnnotationsUpdate200ResponseMetaAffectedPagesItemWeakAnnotationState.ts @@ -0,0 +1,18 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocAnnotationsUpdate200ResponseMetaAffectedPagesItemWeakAnnotationState = + | CloudpdfApi.DocAnnotationsUpdate200ResponseMetaAffectedPagesItemWeakAnnotationState.Unknown + | CloudpdfApi.DocAnnotationsUpdate200ResponseMetaAffectedPagesItemWeakAnnotationState.Known; + +export namespace DocAnnotationsUpdate200ResponseMetaAffectedPagesItemWeakAnnotationState { + export interface Unknown { + kind: "unknown"; + } + + export interface Known { + kind: "known"; + hasAnyWeakAnnotations: boolean; + } +} diff --git a/src/api/types/DocAnnotationsUpdate400Response.ts b/src/api/types/DocAnnotationsUpdate400Response.ts new file mode 100644 index 0000000..3bc24f7 --- /dev/null +++ b/src/api/types/DocAnnotationsUpdate400Response.ts @@ -0,0 +1,36 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface DocAnnotationsUpdate400Response { + name: DocAnnotationsUpdate400Response.Name; + code: DocAnnotationsUpdate400Response.Code; + message: string; + details?: Record | undefined; +} + +export namespace DocAnnotationsUpdate400Response { + export const Name = { + EngineError: "EngineError", + } as const; + export type Name = (typeof Name)[keyof typeof Name]; + export const Code = { + Unknown: "Unknown", + InvalidArg: "InvalidArg", + DocNotOpen: "DocNotOpen", + DocOpenFailed: "DocOpenFailed", + DocPasswordRequired: "DocPasswordRequired", + DocPasswordIncorrect: "DocPasswordIncorrect", + Aborted: "Aborted", + Network: "Network", + Unauthenticated: "Unauthenticated", + Forbidden: "Forbidden", + NotFound: "NotFound", + WireFormat: "WireFormat", + RuntimeUnavailable: "RuntimeUnavailable", + InvalidReference: "InvalidReference", + WeakAnnotationSessionConflict: "WeakAnnotationSessionConflict", + LayerVersionConflict: "LayerVersionConflict", + NotImplemented: "NotImplemented", + MalformedPdf: "MalformedPdf", + } as const; + export type Code = (typeof Code)[keyof typeof Code]; +} diff --git a/src/api/types/DocAnnotationsUpdate404Response.ts b/src/api/types/DocAnnotationsUpdate404Response.ts new file mode 100644 index 0000000..25cdd57 --- /dev/null +++ b/src/api/types/DocAnnotationsUpdate404Response.ts @@ -0,0 +1,36 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface DocAnnotationsUpdate404Response { + name: DocAnnotationsUpdate404Response.Name; + code: DocAnnotationsUpdate404Response.Code; + message: string; + details?: Record | undefined; +} + +export namespace DocAnnotationsUpdate404Response { + export const Name = { + EngineError: "EngineError", + } as const; + export type Name = (typeof Name)[keyof typeof Name]; + export const Code = { + Unknown: "Unknown", + InvalidArg: "InvalidArg", + DocNotOpen: "DocNotOpen", + DocOpenFailed: "DocOpenFailed", + DocPasswordRequired: "DocPasswordRequired", + DocPasswordIncorrect: "DocPasswordIncorrect", + Aborted: "Aborted", + Network: "Network", + Unauthenticated: "Unauthenticated", + Forbidden: "Forbidden", + NotFound: "NotFound", + WireFormat: "WireFormat", + RuntimeUnavailable: "RuntimeUnavailable", + InvalidReference: "InvalidReference", + WeakAnnotationSessionConflict: "WeakAnnotationSessionConflict", + LayerVersionConflict: "LayerVersionConflict", + NotImplemented: "NotImplemented", + MalformedPdf: "MalformedPdf", + } as const; + export type Code = (typeof Code)[keyof typeof Code]; +} diff --git a/src/api/types/DocAnnotationsUpdateRequest.ts b/src/api/types/DocAnnotationsUpdateRequest.ts new file mode 100644 index 0000000..d952795 --- /dev/null +++ b/src/api/types/DocAnnotationsUpdateRequest.ts @@ -0,0 +1,3 @@ +// This file was auto-generated by Fern from our API Definition. + +export type DocAnnotationsUpdateRequest = Record; diff --git a/src/api/types/DocDownloadResponse.ts b/src/api/types/DocDownloadResponse.ts new file mode 100644 index 0000000..38ec447 --- /dev/null +++ b/src/api/types/DocDownloadResponse.ts @@ -0,0 +1,36 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface DocDownloadResponse { + name: DocDownloadResponse.Name; + code: DocDownloadResponse.Code; + message: string; + details?: Record | undefined; +} + +export namespace DocDownloadResponse { + export const Name = { + EngineError: "EngineError", + } as const; + export type Name = (typeof Name)[keyof typeof Name]; + export const Code = { + Unknown: "Unknown", + InvalidArg: "InvalidArg", + DocNotOpen: "DocNotOpen", + DocOpenFailed: "DocOpenFailed", + DocPasswordRequired: "DocPasswordRequired", + DocPasswordIncorrect: "DocPasswordIncorrect", + Aborted: "Aborted", + Network: "Network", + Unauthenticated: "Unauthenticated", + Forbidden: "Forbidden", + NotFound: "NotFound", + WireFormat: "WireFormat", + RuntimeUnavailable: "RuntimeUnavailable", + InvalidReference: "InvalidReference", + WeakAnnotationSessionConflict: "WeakAnnotationSessionConflict", + LayerVersionConflict: "LayerVersionConflict", + NotImplemented: "NotImplemented", + MalformedPdf: "MalformedPdf", + } as const; + export type Code = (typeof Code)[keyof typeof Code]; +} diff --git a/src/api/types/DocFormsExportDataResponse.ts b/src/api/types/DocFormsExportDataResponse.ts new file mode 100644 index 0000000..5565894 --- /dev/null +++ b/src/api/types/DocFormsExportDataResponse.ts @@ -0,0 +1,36 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface DocFormsExportDataResponse { + name: DocFormsExportDataResponse.Name; + code: DocFormsExportDataResponse.Code; + message: string; + details?: Record | undefined; +} + +export namespace DocFormsExportDataResponse { + export const Name = { + EngineError: "EngineError", + } as const; + export type Name = (typeof Name)[keyof typeof Name]; + export const Code = { + Unknown: "Unknown", + InvalidArg: "InvalidArg", + DocNotOpen: "DocNotOpen", + DocOpenFailed: "DocOpenFailed", + DocPasswordRequired: "DocPasswordRequired", + DocPasswordIncorrect: "DocPasswordIncorrect", + Aborted: "Aborted", + Network: "Network", + Unauthenticated: "Unauthenticated", + Forbidden: "Forbidden", + NotFound: "NotFound", + WireFormat: "WireFormat", + RuntimeUnavailable: "RuntimeUnavailable", + InvalidReference: "InvalidReference", + WeakAnnotationSessionConflict: "WeakAnnotationSessionConflict", + LayerVersionConflict: "LayerVersionConflict", + NotImplemented: "NotImplemented", + MalformedPdf: "MalformedPdf", + } as const; + export type Code = (typeof Code)[keyof typeof Code]; +} diff --git a/src/api/types/DocFormsGet200Response.ts b/src/api/types/DocFormsGet200Response.ts new file mode 100644 index 0000000..6038da2 --- /dev/null +++ b/src/api/types/DocFormsGet200Response.ts @@ -0,0 +1,19 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export interface DocFormsGet200Response { + formKind: DocFormsGet200Response.FormKind; + needsAppearances: boolean; + fields: CloudpdfApi.DocFormsGet200ResponseFieldsItem[]; + calculationOrder: (CloudpdfApi.DocFormsGet200ResponseCalculationOrderItem | null)[]; +} + +export namespace DocFormsGet200Response { + export const FormKind = { + None: "none", + Acroform: "acroform", + Xfa: "xfa", + } as const; + export type FormKind = (typeof FormKind)[keyof typeof FormKind]; +} diff --git a/src/api/types/DocFormsGet200ResponseCalculationOrderItem.ts b/src/api/types/DocFormsGet200ResponseCalculationOrderItem.ts new file mode 100644 index 0000000..c0e3452 --- /dev/null +++ b/src/api/types/DocFormsGet200ResponseCalculationOrderItem.ts @@ -0,0 +1,19 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocFormsGet200ResponseCalculationOrderItem = + | CloudpdfApi.DocFormsGet200ResponseCalculationOrderItem.ObjectNumber + | CloudpdfApi.DocFormsGet200ResponseCalculationOrderItem.Fqn; + +export namespace DocFormsGet200ResponseCalculationOrderItem { + export interface ObjectNumber { + kind: "objectNumber"; + fieldObjectNumber: number; + } + + export interface Fqn { + kind: "fqn"; + name: string; + } +} diff --git a/src/api/types/DocFormsGet200ResponseFieldsItem.ts b/src/api/types/DocFormsGet200ResponseFieldsItem.ts new file mode 100644 index 0000000..84a2365 --- /dev/null +++ b/src/api/types/DocFormsGet200ResponseFieldsItem.ts @@ -0,0 +1,2108 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocFormsGet200ResponseFieldsItem = + | CloudpdfApi.DocFormsGet200ResponseFieldsItem.Text + | CloudpdfApi.DocFormsGet200ResponseFieldsItem.Checkbox + | CloudpdfApi.DocFormsGet200ResponseFieldsItem.Radio + | CloudpdfApi.DocFormsGet200ResponseFieldsItem.Combobox + | CloudpdfApi.DocFormsGet200ResponseFieldsItem.Listbox + | CloudpdfApi.DocFormsGet200ResponseFieldsItem.Pushbutton + | CloudpdfApi.DocFormsGet200ResponseFieldsItem.Signature + | CloudpdfApi.DocFormsGet200ResponseFieldsItem.Unknown; + +export namespace DocFormsGet200ResponseFieldsItem { + export interface Text { + family: "text"; + ref: CloudpdfApi.DocFormsGet200ResponseFieldsItemTextRef; + fieldObjectNumber: number; + name: string; + origin: DocFormsGet200ResponseFieldsItemText.Origin; + flags: DocFormsGet200ResponseFieldsItemText.Flags; + alternateName: string | null; + mappingName: string | null; + valueEntry: CloudpdfApi.DocFormsGet200ResponseFieldsItemTextValueEntry; + defaultValueEntry: CloudpdfApi.DocFormsGet200ResponseFieldsItemTextDefaultValueEntry; + actions?: DocFormsGet200ResponseFieldsItemText.Actions | undefined; + widgets: DocFormsGet200ResponseFieldsItemText.Widgets.Item[]; + value: string; + defaultValue: string; + maxLength: number | null; + multiline: boolean; + password: boolean; + comb: boolean; + } + + export namespace DocFormsGet200ResponseFieldsItemText { + export const Origin = { + Acroform: "acroform", + Recovered: "recovered", + } as const; + export type Origin = (typeof Origin)[keyof typeof Origin]; + + export interface Flags { + readOnly: boolean; + required: boolean; + noExport: boolean; + raw: number; + } + + export interface Actions { + keystroke?: Actions.Keystroke | undefined; + format?: Actions.Format | undefined; + validate?: Actions.Validate | undefined; + calculate?: Actions.Calculate | undefined; + } + + export namespace Actions { + export interface Keystroke { + root: Keystroke.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Keystroke.Warnings.Item[]; + } + + export namespace Keystroke { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface Format { + root: Format.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Format.Warnings.Item[]; + } + + export namespace Format { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface Validate { + root: Validate.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Validate.Warnings.Item[]; + } + + export namespace Validate { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface Calculate { + root: Calculate.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Calculate.Warnings.Item[]; + } + + export namespace Calculate { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + } + + export type Widgets = Widgets.Item[]; + + export namespace Widgets { + export interface Item { + annotObjectNumber: number; + pageObjectNumber: number; + } + } + } + + export interface Checkbox { + family: "checkbox"; + ref: CloudpdfApi.DocFormsGet200ResponseFieldsItemCheckboxRef; + fieldObjectNumber: number; + name: string; + origin: DocFormsGet200ResponseFieldsItemCheckbox.Origin; + flags: DocFormsGet200ResponseFieldsItemCheckbox.Flags; + alternateName: string | null; + mappingName: string | null; + valueEntry: CloudpdfApi.DocFormsGet200ResponseFieldsItemCheckboxValueEntry; + defaultValueEntry: CloudpdfApi.DocFormsGet200ResponseFieldsItemCheckboxDefaultValueEntry; + actions?: DocFormsGet200ResponseFieldsItemCheckbox.Actions | undefined; + widgets: DocFormsGet200ResponseFieldsItemCheckbox.Widgets.Item[]; + checked: boolean; + exportValue: string; + } + + export namespace DocFormsGet200ResponseFieldsItemCheckbox { + export const Origin = { + Acroform: "acroform", + Recovered: "recovered", + } as const; + export type Origin = (typeof Origin)[keyof typeof Origin]; + + export interface Flags { + readOnly: boolean; + required: boolean; + noExport: boolean; + raw: number; + } + + export interface Actions { + keystroke?: Actions.Keystroke | undefined; + format?: Actions.Format | undefined; + validate?: Actions.Validate | undefined; + calculate?: Actions.Calculate | undefined; + } + + export namespace Actions { + export interface Keystroke { + root: Keystroke.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Keystroke.Warnings.Item[]; + } + + export namespace Keystroke { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface Format { + root: Format.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Format.Warnings.Item[]; + } + + export namespace Format { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface Validate { + root: Validate.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Validate.Warnings.Item[]; + } + + export namespace Validate { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface Calculate { + root: Calculate.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Calculate.Warnings.Item[]; + } + + export namespace Calculate { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + } + + export type Widgets = Widgets.Item[]; + + export namespace Widgets { + export interface Item { + annotObjectNumber: number; + pageObjectNumber: number; + onState: string; + exportValue: string; + checked: boolean; + } + } + } + + export interface Radio { + family: "radio"; + ref: CloudpdfApi.DocFormsGet200ResponseFieldsItemRadioRef; + fieldObjectNumber: number; + name: string; + origin: DocFormsGet200ResponseFieldsItemRadio.Origin; + flags: DocFormsGet200ResponseFieldsItemRadio.Flags; + alternateName: string | null; + mappingName: string | null; + valueEntry: CloudpdfApi.DocFormsGet200ResponseFieldsItemRadioValueEntry; + defaultValueEntry: CloudpdfApi.DocFormsGet200ResponseFieldsItemRadioDefaultValueEntry; + actions?: DocFormsGet200ResponseFieldsItemRadio.Actions | undefined; + widgets: DocFormsGet200ResponseFieldsItemRadio.Widgets.Item[]; + value: string; + radiosInUnison: boolean; + noToggleToOff: boolean; + } + + export namespace DocFormsGet200ResponseFieldsItemRadio { + export const Origin = { + Acroform: "acroform", + Recovered: "recovered", + } as const; + export type Origin = (typeof Origin)[keyof typeof Origin]; + + export interface Flags { + readOnly: boolean; + required: boolean; + noExport: boolean; + raw: number; + } + + export interface Actions { + keystroke?: Actions.Keystroke | undefined; + format?: Actions.Format | undefined; + validate?: Actions.Validate | undefined; + calculate?: Actions.Calculate | undefined; + } + + export namespace Actions { + export interface Keystroke { + root: Keystroke.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Keystroke.Warnings.Item[]; + } + + export namespace Keystroke { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface Format { + root: Format.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Format.Warnings.Item[]; + } + + export namespace Format { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface Validate { + root: Validate.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Validate.Warnings.Item[]; + } + + export namespace Validate { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface Calculate { + root: Calculate.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Calculate.Warnings.Item[]; + } + + export namespace Calculate { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + } + + export type Widgets = Widgets.Item[]; + + export namespace Widgets { + export interface Item { + annotObjectNumber: number; + pageObjectNumber: number; + onState: string; + exportValue: string; + checked: boolean; + } + } + } + + export interface Combobox { + family: "combobox"; + ref: CloudpdfApi.DocFormsGet200ResponseFieldsItemComboboxRef; + fieldObjectNumber: number; + name: string; + origin: DocFormsGet200ResponseFieldsItemCombobox.Origin; + flags: DocFormsGet200ResponseFieldsItemCombobox.Flags; + alternateName: string | null; + mappingName: string | null; + valueEntry: CloudpdfApi.DocFormsGet200ResponseFieldsItemComboboxValueEntry; + defaultValueEntry: CloudpdfApi.DocFormsGet200ResponseFieldsItemComboboxDefaultValueEntry; + actions?: DocFormsGet200ResponseFieldsItemCombobox.Actions | undefined; + widgets: DocFormsGet200ResponseFieldsItemCombobox.Widgets.Item[]; + value: string; + defaultValue: string; + edit: boolean; + options: DocFormsGet200ResponseFieldsItemCombobox.Options.Item[]; + } + + export namespace DocFormsGet200ResponseFieldsItemCombobox { + export const Origin = { + Acroform: "acroform", + Recovered: "recovered", + } as const; + export type Origin = (typeof Origin)[keyof typeof Origin]; + + export interface Flags { + readOnly: boolean; + required: boolean; + noExport: boolean; + raw: number; + } + + export interface Actions { + keystroke?: Actions.Keystroke | undefined; + format?: Actions.Format | undefined; + validate?: Actions.Validate | undefined; + calculate?: Actions.Calculate | undefined; + } + + export namespace Actions { + export interface Keystroke { + root: Keystroke.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Keystroke.Warnings.Item[]; + } + + export namespace Keystroke { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface Format { + root: Format.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Format.Warnings.Item[]; + } + + export namespace Format { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface Validate { + root: Validate.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Validate.Warnings.Item[]; + } + + export namespace Validate { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface Calculate { + root: Calculate.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Calculate.Warnings.Item[]; + } + + export namespace Calculate { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + } + + export type Widgets = Widgets.Item[]; + + export namespace Widgets { + export interface Item { + annotObjectNumber: number; + pageObjectNumber: number; + } + } + + export type Options = Options.Item[]; + + export namespace Options { + export interface Item { + label: string; + value: string; + selected: boolean; + } + } + } + + export interface Listbox { + family: "listbox"; + ref: CloudpdfApi.DocFormsGet200ResponseFieldsItemListboxRef; + fieldObjectNumber: number; + name: string; + origin: DocFormsGet200ResponseFieldsItemListbox.Origin; + flags: DocFormsGet200ResponseFieldsItemListbox.Flags; + alternateName: string | null; + mappingName: string | null; + valueEntry: CloudpdfApi.DocFormsGet200ResponseFieldsItemListboxValueEntry; + defaultValueEntry: CloudpdfApi.DocFormsGet200ResponseFieldsItemListboxDefaultValueEntry; + actions?: DocFormsGet200ResponseFieldsItemListbox.Actions | undefined; + widgets: DocFormsGet200ResponseFieldsItemListbox.Widgets.Item[]; + selectedValues: string[]; + multiSelect: boolean; + options: DocFormsGet200ResponseFieldsItemListbox.Options.Item[]; + } + + export namespace DocFormsGet200ResponseFieldsItemListbox { + export const Origin = { + Acroform: "acroform", + Recovered: "recovered", + } as const; + export type Origin = (typeof Origin)[keyof typeof Origin]; + + export interface Flags { + readOnly: boolean; + required: boolean; + noExport: boolean; + raw: number; + } + + export interface Actions { + keystroke?: Actions.Keystroke | undefined; + format?: Actions.Format | undefined; + validate?: Actions.Validate | undefined; + calculate?: Actions.Calculate | undefined; + } + + export namespace Actions { + export interface Keystroke { + root: Keystroke.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Keystroke.Warnings.Item[]; + } + + export namespace Keystroke { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface Format { + root: Format.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Format.Warnings.Item[]; + } + + export namespace Format { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface Validate { + root: Validate.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Validate.Warnings.Item[]; + } + + export namespace Validate { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface Calculate { + root: Calculate.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Calculate.Warnings.Item[]; + } + + export namespace Calculate { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + } + + export type Widgets = Widgets.Item[]; + + export namespace Widgets { + export interface Item { + annotObjectNumber: number; + pageObjectNumber: number; + } + } + + export type Options = Options.Item[]; + + export namespace Options { + export interface Item { + label: string; + value: string; + selected: boolean; + } + } + } + + export interface Pushbutton { + family: "pushbutton"; + ref: CloudpdfApi.DocFormsGet200ResponseFieldsItemPushbuttonRef; + fieldObjectNumber: number; + name: string; + origin: DocFormsGet200ResponseFieldsItemPushbutton.Origin; + flags: DocFormsGet200ResponseFieldsItemPushbutton.Flags; + alternateName: string | null; + mappingName: string | null; + valueEntry: CloudpdfApi.DocFormsGet200ResponseFieldsItemPushbuttonValueEntry; + defaultValueEntry: CloudpdfApi.DocFormsGet200ResponseFieldsItemPushbuttonDefaultValueEntry; + actions?: DocFormsGet200ResponseFieldsItemPushbutton.Actions | undefined; + widgets: DocFormsGet200ResponseFieldsItemPushbutton.Widgets.Item[]; + } + + export namespace DocFormsGet200ResponseFieldsItemPushbutton { + export const Origin = { + Acroform: "acroform", + Recovered: "recovered", + } as const; + export type Origin = (typeof Origin)[keyof typeof Origin]; + + export interface Flags { + readOnly: boolean; + required: boolean; + noExport: boolean; + raw: number; + } + + export interface Actions { + keystroke?: Actions.Keystroke | undefined; + format?: Actions.Format | undefined; + validate?: Actions.Validate | undefined; + calculate?: Actions.Calculate | undefined; + } + + export namespace Actions { + export interface Keystroke { + root: Keystroke.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Keystroke.Warnings.Item[]; + } + + export namespace Keystroke { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface Format { + root: Format.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Format.Warnings.Item[]; + } + + export namespace Format { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface Validate { + root: Validate.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Validate.Warnings.Item[]; + } + + export namespace Validate { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface Calculate { + root: Calculate.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Calculate.Warnings.Item[]; + } + + export namespace Calculate { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + } + + export type Widgets = Widgets.Item[]; + + export namespace Widgets { + export interface Item { + annotObjectNumber: number; + pageObjectNumber: number; + } + } + } + + export interface Signature { + family: "signature"; + ref: CloudpdfApi.DocFormsGet200ResponseFieldsItemSignatureRef; + fieldObjectNumber: number; + name: string; + origin: DocFormsGet200ResponseFieldsItemSignature.Origin; + flags: DocFormsGet200ResponseFieldsItemSignature.Flags; + alternateName: string | null; + mappingName: string | null; + valueEntry: CloudpdfApi.DocFormsGet200ResponseFieldsItemSignatureValueEntry; + defaultValueEntry: CloudpdfApi.DocFormsGet200ResponseFieldsItemSignatureDefaultValueEntry; + actions?: DocFormsGet200ResponseFieldsItemSignature.Actions | undefined; + widgets: DocFormsGet200ResponseFieldsItemSignature.Widgets.Item[]; + } + + export namespace DocFormsGet200ResponseFieldsItemSignature { + export const Origin = { + Acroform: "acroform", + Recovered: "recovered", + } as const; + export type Origin = (typeof Origin)[keyof typeof Origin]; + + export interface Flags { + readOnly: boolean; + required: boolean; + noExport: boolean; + raw: number; + } + + export interface Actions { + keystroke?: Actions.Keystroke | undefined; + format?: Actions.Format | undefined; + validate?: Actions.Validate | undefined; + calculate?: Actions.Calculate | undefined; + } + + export namespace Actions { + export interface Keystroke { + root: Keystroke.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Keystroke.Warnings.Item[]; + } + + export namespace Keystroke { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface Format { + root: Format.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Format.Warnings.Item[]; + } + + export namespace Format { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface Validate { + root: Validate.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Validate.Warnings.Item[]; + } + + export namespace Validate { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface Calculate { + root: Calculate.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Calculate.Warnings.Item[]; + } + + export namespace Calculate { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + } + + export type Widgets = Widgets.Item[]; + + export namespace Widgets { + export interface Item { + annotObjectNumber: number; + pageObjectNumber: number; + } + } + } + + export interface Unknown { + family: "unknown"; + ref: CloudpdfApi.DocFormsGet200ResponseFieldsItemUnknownRef; + fieldObjectNumber: number; + name: string; + origin: DocFormsGet200ResponseFieldsItemUnknown.Origin; + flags: DocFormsGet200ResponseFieldsItemUnknown.Flags; + alternateName: string | null; + mappingName: string | null; + valueEntry: CloudpdfApi.DocFormsGet200ResponseFieldsItemUnknownValueEntry; + defaultValueEntry: CloudpdfApi.DocFormsGet200ResponseFieldsItemUnknownDefaultValueEntry; + actions?: DocFormsGet200ResponseFieldsItemUnknown.Actions | undefined; + widgets: DocFormsGet200ResponseFieldsItemUnknown.Widgets.Item[]; + rawValue: string; + } + + export namespace DocFormsGet200ResponseFieldsItemUnknown { + export const Origin = { + Acroform: "acroform", + Recovered: "recovered", + } as const; + export type Origin = (typeof Origin)[keyof typeof Origin]; + + export interface Flags { + readOnly: boolean; + required: boolean; + noExport: boolean; + raw: number; + } + + export interface Actions { + keystroke?: Actions.Keystroke | undefined; + format?: Actions.Format | undefined; + validate?: Actions.Validate | undefined; + calculate?: Actions.Calculate | undefined; + } + + export namespace Actions { + export interface Keystroke { + root: Keystroke.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Keystroke.Warnings.Item[]; + } + + export namespace Keystroke { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface Format { + root: Format.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Format.Warnings.Item[]; + } + + export namespace Format { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface Validate { + root: Validate.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Validate.Warnings.Item[]; + } + + export namespace Validate { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + + export interface Calculate { + root: Calculate.Root | null; + incomplete: boolean; + warningFlags: number; + warnings: Calculate.Warnings.Item[]; + } + + export namespace Calculate { + export interface Root { + type: Root.Type; + subtype: string; + script?: string | undefined; + next: unknown[]; + } + + export namespace Root { + export const Type = { + Unknown: "unknown", + Goto: "goto", + GotoRemote: "goto-remote", + GotoEmbedded: "goto-embedded", + Launch: "launch", + Thread: "thread", + Uri: "uri", + Sound: "sound", + Movie: "movie", + Hide: "hide", + Named: "named", + SubmitForm: "submit-form", + ResetForm: "reset-form", + ImportData: "import-data", + Javascript: "javascript", + SetOcgState: "set-ocg-state", + Rendition: "rendition", + Transition: "transition", + Goto3DView: "goto-3d-view", + } as const; + export type Type = (typeof Type)[keyof typeof Type]; + } + + export type Warnings = Warnings.Item[]; + + export namespace Warnings { + export const Item = { + CycleDropped: "cycle-dropped", + MalformedNext: "malformed-next", + Incomplete: "incomplete", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } + } + + export type Widgets = Widgets.Item[]; + + export namespace Widgets { + export interface Item { + annotObjectNumber: number; + pageObjectNumber: number; + } + } + } +} diff --git a/src/api/types/DocFormsGet200ResponseFieldsItemCheckboxDefaultValueEntry.ts b/src/api/types/DocFormsGet200ResponseFieldsItemCheckboxDefaultValueEntry.ts new file mode 100644 index 0000000..cc4310f --- /dev/null +++ b/src/api/types/DocFormsGet200ResponseFieldsItemCheckboxDefaultValueEntry.ts @@ -0,0 +1,29 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocFormsGet200ResponseFieldsItemCheckboxDefaultValueEntry = + | CloudpdfApi.DocFormsGet200ResponseFieldsItemCheckboxDefaultValueEntry.None + | CloudpdfApi.DocFormsGet200ResponseFieldsItemCheckboxDefaultValueEntry.Scalar + | CloudpdfApi.DocFormsGet200ResponseFieldsItemCheckboxDefaultValueEntry.Array + | CloudpdfApi.DocFormsGet200ResponseFieldsItemCheckboxDefaultValueEntry.Unsupported; + +export namespace DocFormsGet200ResponseFieldsItemCheckboxDefaultValueEntry { + export interface None { + kind: "none"; + } + + export interface Scalar { + kind: "scalar"; + value: string; + } + + export interface Array { + kind: "array"; + values: string[]; + } + + export interface Unsupported { + kind: "unsupported"; + } +} diff --git a/src/api/types/DocFormsGet200ResponseFieldsItemCheckboxRef.ts b/src/api/types/DocFormsGet200ResponseFieldsItemCheckboxRef.ts new file mode 100644 index 0000000..e25c5ca --- /dev/null +++ b/src/api/types/DocFormsGet200ResponseFieldsItemCheckboxRef.ts @@ -0,0 +1,19 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocFormsGet200ResponseFieldsItemCheckboxRef = + | CloudpdfApi.DocFormsGet200ResponseFieldsItemCheckboxRef.ObjectNumber + | CloudpdfApi.DocFormsGet200ResponseFieldsItemCheckboxRef.Fqn; + +export namespace DocFormsGet200ResponseFieldsItemCheckboxRef { + export interface ObjectNumber { + kind: "objectNumber"; + fieldObjectNumber: number; + } + + export interface Fqn { + kind: "fqn"; + name: string; + } +} diff --git a/src/api/types/DocFormsGet200ResponseFieldsItemCheckboxValueEntry.ts b/src/api/types/DocFormsGet200ResponseFieldsItemCheckboxValueEntry.ts new file mode 100644 index 0000000..375e46f --- /dev/null +++ b/src/api/types/DocFormsGet200ResponseFieldsItemCheckboxValueEntry.ts @@ -0,0 +1,29 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocFormsGet200ResponseFieldsItemCheckboxValueEntry = + | CloudpdfApi.DocFormsGet200ResponseFieldsItemCheckboxValueEntry.None + | CloudpdfApi.DocFormsGet200ResponseFieldsItemCheckboxValueEntry.Scalar + | CloudpdfApi.DocFormsGet200ResponseFieldsItemCheckboxValueEntry.Array + | CloudpdfApi.DocFormsGet200ResponseFieldsItemCheckboxValueEntry.Unsupported; + +export namespace DocFormsGet200ResponseFieldsItemCheckboxValueEntry { + export interface None { + kind: "none"; + } + + export interface Scalar { + kind: "scalar"; + value: string; + } + + export interface Array { + kind: "array"; + values: string[]; + } + + export interface Unsupported { + kind: "unsupported"; + } +} diff --git a/src/api/types/DocFormsGet200ResponseFieldsItemComboboxDefaultValueEntry.ts b/src/api/types/DocFormsGet200ResponseFieldsItemComboboxDefaultValueEntry.ts new file mode 100644 index 0000000..63ad14f --- /dev/null +++ b/src/api/types/DocFormsGet200ResponseFieldsItemComboboxDefaultValueEntry.ts @@ -0,0 +1,29 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocFormsGet200ResponseFieldsItemComboboxDefaultValueEntry = + | CloudpdfApi.DocFormsGet200ResponseFieldsItemComboboxDefaultValueEntry.None + | CloudpdfApi.DocFormsGet200ResponseFieldsItemComboboxDefaultValueEntry.Scalar + | CloudpdfApi.DocFormsGet200ResponseFieldsItemComboboxDefaultValueEntry.Array + | CloudpdfApi.DocFormsGet200ResponseFieldsItemComboboxDefaultValueEntry.Unsupported; + +export namespace DocFormsGet200ResponseFieldsItemComboboxDefaultValueEntry { + export interface None { + kind: "none"; + } + + export interface Scalar { + kind: "scalar"; + value: string; + } + + export interface Array { + kind: "array"; + values: string[]; + } + + export interface Unsupported { + kind: "unsupported"; + } +} diff --git a/src/api/types/DocFormsGet200ResponseFieldsItemComboboxRef.ts b/src/api/types/DocFormsGet200ResponseFieldsItemComboboxRef.ts new file mode 100644 index 0000000..1abfc46 --- /dev/null +++ b/src/api/types/DocFormsGet200ResponseFieldsItemComboboxRef.ts @@ -0,0 +1,19 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocFormsGet200ResponseFieldsItemComboboxRef = + | CloudpdfApi.DocFormsGet200ResponseFieldsItemComboboxRef.ObjectNumber + | CloudpdfApi.DocFormsGet200ResponseFieldsItemComboboxRef.Fqn; + +export namespace DocFormsGet200ResponseFieldsItemComboboxRef { + export interface ObjectNumber { + kind: "objectNumber"; + fieldObjectNumber: number; + } + + export interface Fqn { + kind: "fqn"; + name: string; + } +} diff --git a/src/api/types/DocFormsGet200ResponseFieldsItemComboboxValueEntry.ts b/src/api/types/DocFormsGet200ResponseFieldsItemComboboxValueEntry.ts new file mode 100644 index 0000000..b15877a --- /dev/null +++ b/src/api/types/DocFormsGet200ResponseFieldsItemComboboxValueEntry.ts @@ -0,0 +1,29 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocFormsGet200ResponseFieldsItemComboboxValueEntry = + | CloudpdfApi.DocFormsGet200ResponseFieldsItemComboboxValueEntry.None + | CloudpdfApi.DocFormsGet200ResponseFieldsItemComboboxValueEntry.Scalar + | CloudpdfApi.DocFormsGet200ResponseFieldsItemComboboxValueEntry.Array + | CloudpdfApi.DocFormsGet200ResponseFieldsItemComboboxValueEntry.Unsupported; + +export namespace DocFormsGet200ResponseFieldsItemComboboxValueEntry { + export interface None { + kind: "none"; + } + + export interface Scalar { + kind: "scalar"; + value: string; + } + + export interface Array { + kind: "array"; + values: string[]; + } + + export interface Unsupported { + kind: "unsupported"; + } +} diff --git a/src/api/types/DocFormsGet200ResponseFieldsItemListboxDefaultValueEntry.ts b/src/api/types/DocFormsGet200ResponseFieldsItemListboxDefaultValueEntry.ts new file mode 100644 index 0000000..71fbecf --- /dev/null +++ b/src/api/types/DocFormsGet200ResponseFieldsItemListboxDefaultValueEntry.ts @@ -0,0 +1,29 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocFormsGet200ResponseFieldsItemListboxDefaultValueEntry = + | CloudpdfApi.DocFormsGet200ResponseFieldsItemListboxDefaultValueEntry.None + | CloudpdfApi.DocFormsGet200ResponseFieldsItemListboxDefaultValueEntry.Scalar + | CloudpdfApi.DocFormsGet200ResponseFieldsItemListboxDefaultValueEntry.Array + | CloudpdfApi.DocFormsGet200ResponseFieldsItemListboxDefaultValueEntry.Unsupported; + +export namespace DocFormsGet200ResponseFieldsItemListboxDefaultValueEntry { + export interface None { + kind: "none"; + } + + export interface Scalar { + kind: "scalar"; + value: string; + } + + export interface Array { + kind: "array"; + values: string[]; + } + + export interface Unsupported { + kind: "unsupported"; + } +} diff --git a/src/api/types/DocFormsGet200ResponseFieldsItemListboxRef.ts b/src/api/types/DocFormsGet200ResponseFieldsItemListboxRef.ts new file mode 100644 index 0000000..c0d2b6b --- /dev/null +++ b/src/api/types/DocFormsGet200ResponseFieldsItemListboxRef.ts @@ -0,0 +1,19 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocFormsGet200ResponseFieldsItemListboxRef = + | CloudpdfApi.DocFormsGet200ResponseFieldsItemListboxRef.ObjectNumber + | CloudpdfApi.DocFormsGet200ResponseFieldsItemListboxRef.Fqn; + +export namespace DocFormsGet200ResponseFieldsItemListboxRef { + export interface ObjectNumber { + kind: "objectNumber"; + fieldObjectNumber: number; + } + + export interface Fqn { + kind: "fqn"; + name: string; + } +} diff --git a/src/api/types/DocFormsGet200ResponseFieldsItemListboxValueEntry.ts b/src/api/types/DocFormsGet200ResponseFieldsItemListboxValueEntry.ts new file mode 100644 index 0000000..0a2590b --- /dev/null +++ b/src/api/types/DocFormsGet200ResponseFieldsItemListboxValueEntry.ts @@ -0,0 +1,29 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocFormsGet200ResponseFieldsItemListboxValueEntry = + | CloudpdfApi.DocFormsGet200ResponseFieldsItemListboxValueEntry.None + | CloudpdfApi.DocFormsGet200ResponseFieldsItemListboxValueEntry.Scalar + | CloudpdfApi.DocFormsGet200ResponseFieldsItemListboxValueEntry.Array + | CloudpdfApi.DocFormsGet200ResponseFieldsItemListboxValueEntry.Unsupported; + +export namespace DocFormsGet200ResponseFieldsItemListboxValueEntry { + export interface None { + kind: "none"; + } + + export interface Scalar { + kind: "scalar"; + value: string; + } + + export interface Array { + kind: "array"; + values: string[]; + } + + export interface Unsupported { + kind: "unsupported"; + } +} diff --git a/src/api/types/DocFormsGet200ResponseFieldsItemPushbuttonDefaultValueEntry.ts b/src/api/types/DocFormsGet200ResponseFieldsItemPushbuttonDefaultValueEntry.ts new file mode 100644 index 0000000..ee4d12e --- /dev/null +++ b/src/api/types/DocFormsGet200ResponseFieldsItemPushbuttonDefaultValueEntry.ts @@ -0,0 +1,29 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocFormsGet200ResponseFieldsItemPushbuttonDefaultValueEntry = + | CloudpdfApi.DocFormsGet200ResponseFieldsItemPushbuttonDefaultValueEntry.None + | CloudpdfApi.DocFormsGet200ResponseFieldsItemPushbuttonDefaultValueEntry.Scalar + | CloudpdfApi.DocFormsGet200ResponseFieldsItemPushbuttonDefaultValueEntry.Array + | CloudpdfApi.DocFormsGet200ResponseFieldsItemPushbuttonDefaultValueEntry.Unsupported; + +export namespace DocFormsGet200ResponseFieldsItemPushbuttonDefaultValueEntry { + export interface None { + kind: "none"; + } + + export interface Scalar { + kind: "scalar"; + value: string; + } + + export interface Array { + kind: "array"; + values: string[]; + } + + export interface Unsupported { + kind: "unsupported"; + } +} diff --git a/src/api/types/DocFormsGet200ResponseFieldsItemPushbuttonRef.ts b/src/api/types/DocFormsGet200ResponseFieldsItemPushbuttonRef.ts new file mode 100644 index 0000000..ed8cf55 --- /dev/null +++ b/src/api/types/DocFormsGet200ResponseFieldsItemPushbuttonRef.ts @@ -0,0 +1,19 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocFormsGet200ResponseFieldsItemPushbuttonRef = + | CloudpdfApi.DocFormsGet200ResponseFieldsItemPushbuttonRef.ObjectNumber + | CloudpdfApi.DocFormsGet200ResponseFieldsItemPushbuttonRef.Fqn; + +export namespace DocFormsGet200ResponseFieldsItemPushbuttonRef { + export interface ObjectNumber { + kind: "objectNumber"; + fieldObjectNumber: number; + } + + export interface Fqn { + kind: "fqn"; + name: string; + } +} diff --git a/src/api/types/DocFormsGet200ResponseFieldsItemPushbuttonValueEntry.ts b/src/api/types/DocFormsGet200ResponseFieldsItemPushbuttonValueEntry.ts new file mode 100644 index 0000000..826369e --- /dev/null +++ b/src/api/types/DocFormsGet200ResponseFieldsItemPushbuttonValueEntry.ts @@ -0,0 +1,29 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocFormsGet200ResponseFieldsItemPushbuttonValueEntry = + | CloudpdfApi.DocFormsGet200ResponseFieldsItemPushbuttonValueEntry.None + | CloudpdfApi.DocFormsGet200ResponseFieldsItemPushbuttonValueEntry.Scalar + | CloudpdfApi.DocFormsGet200ResponseFieldsItemPushbuttonValueEntry.Array + | CloudpdfApi.DocFormsGet200ResponseFieldsItemPushbuttonValueEntry.Unsupported; + +export namespace DocFormsGet200ResponseFieldsItemPushbuttonValueEntry { + export interface None { + kind: "none"; + } + + export interface Scalar { + kind: "scalar"; + value: string; + } + + export interface Array { + kind: "array"; + values: string[]; + } + + export interface Unsupported { + kind: "unsupported"; + } +} diff --git a/src/api/types/DocFormsGet200ResponseFieldsItemRadioDefaultValueEntry.ts b/src/api/types/DocFormsGet200ResponseFieldsItemRadioDefaultValueEntry.ts new file mode 100644 index 0000000..a3f7a75 --- /dev/null +++ b/src/api/types/DocFormsGet200ResponseFieldsItemRadioDefaultValueEntry.ts @@ -0,0 +1,29 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocFormsGet200ResponseFieldsItemRadioDefaultValueEntry = + | CloudpdfApi.DocFormsGet200ResponseFieldsItemRadioDefaultValueEntry.None + | CloudpdfApi.DocFormsGet200ResponseFieldsItemRadioDefaultValueEntry.Scalar + | CloudpdfApi.DocFormsGet200ResponseFieldsItemRadioDefaultValueEntry.Array + | CloudpdfApi.DocFormsGet200ResponseFieldsItemRadioDefaultValueEntry.Unsupported; + +export namespace DocFormsGet200ResponseFieldsItemRadioDefaultValueEntry { + export interface None { + kind: "none"; + } + + export interface Scalar { + kind: "scalar"; + value: string; + } + + export interface Array { + kind: "array"; + values: string[]; + } + + export interface Unsupported { + kind: "unsupported"; + } +} diff --git a/src/api/types/DocFormsGet200ResponseFieldsItemRadioRef.ts b/src/api/types/DocFormsGet200ResponseFieldsItemRadioRef.ts new file mode 100644 index 0000000..0ff5e68 --- /dev/null +++ b/src/api/types/DocFormsGet200ResponseFieldsItemRadioRef.ts @@ -0,0 +1,19 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocFormsGet200ResponseFieldsItemRadioRef = + | CloudpdfApi.DocFormsGet200ResponseFieldsItemRadioRef.ObjectNumber + | CloudpdfApi.DocFormsGet200ResponseFieldsItemRadioRef.Fqn; + +export namespace DocFormsGet200ResponseFieldsItemRadioRef { + export interface ObjectNumber { + kind: "objectNumber"; + fieldObjectNumber: number; + } + + export interface Fqn { + kind: "fqn"; + name: string; + } +} diff --git a/src/api/types/DocFormsGet200ResponseFieldsItemRadioValueEntry.ts b/src/api/types/DocFormsGet200ResponseFieldsItemRadioValueEntry.ts new file mode 100644 index 0000000..32b8efa --- /dev/null +++ b/src/api/types/DocFormsGet200ResponseFieldsItemRadioValueEntry.ts @@ -0,0 +1,29 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocFormsGet200ResponseFieldsItemRadioValueEntry = + | CloudpdfApi.DocFormsGet200ResponseFieldsItemRadioValueEntry.None + | CloudpdfApi.DocFormsGet200ResponseFieldsItemRadioValueEntry.Scalar + | CloudpdfApi.DocFormsGet200ResponseFieldsItemRadioValueEntry.Array + | CloudpdfApi.DocFormsGet200ResponseFieldsItemRadioValueEntry.Unsupported; + +export namespace DocFormsGet200ResponseFieldsItemRadioValueEntry { + export interface None { + kind: "none"; + } + + export interface Scalar { + kind: "scalar"; + value: string; + } + + export interface Array { + kind: "array"; + values: string[]; + } + + export interface Unsupported { + kind: "unsupported"; + } +} diff --git a/src/api/types/DocFormsGet200ResponseFieldsItemSignatureDefaultValueEntry.ts b/src/api/types/DocFormsGet200ResponseFieldsItemSignatureDefaultValueEntry.ts new file mode 100644 index 0000000..6a1c1c3 --- /dev/null +++ b/src/api/types/DocFormsGet200ResponseFieldsItemSignatureDefaultValueEntry.ts @@ -0,0 +1,29 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocFormsGet200ResponseFieldsItemSignatureDefaultValueEntry = + | CloudpdfApi.DocFormsGet200ResponseFieldsItemSignatureDefaultValueEntry.None + | CloudpdfApi.DocFormsGet200ResponseFieldsItemSignatureDefaultValueEntry.Scalar + | CloudpdfApi.DocFormsGet200ResponseFieldsItemSignatureDefaultValueEntry.Array + | CloudpdfApi.DocFormsGet200ResponseFieldsItemSignatureDefaultValueEntry.Unsupported; + +export namespace DocFormsGet200ResponseFieldsItemSignatureDefaultValueEntry { + export interface None { + kind: "none"; + } + + export interface Scalar { + kind: "scalar"; + value: string; + } + + export interface Array { + kind: "array"; + values: string[]; + } + + export interface Unsupported { + kind: "unsupported"; + } +} diff --git a/src/api/types/DocFormsGet200ResponseFieldsItemSignatureRef.ts b/src/api/types/DocFormsGet200ResponseFieldsItemSignatureRef.ts new file mode 100644 index 0000000..041571f --- /dev/null +++ b/src/api/types/DocFormsGet200ResponseFieldsItemSignatureRef.ts @@ -0,0 +1,19 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocFormsGet200ResponseFieldsItemSignatureRef = + | CloudpdfApi.DocFormsGet200ResponseFieldsItemSignatureRef.ObjectNumber + | CloudpdfApi.DocFormsGet200ResponseFieldsItemSignatureRef.Fqn; + +export namespace DocFormsGet200ResponseFieldsItemSignatureRef { + export interface ObjectNumber { + kind: "objectNumber"; + fieldObjectNumber: number; + } + + export interface Fqn { + kind: "fqn"; + name: string; + } +} diff --git a/src/api/types/DocFormsGet200ResponseFieldsItemSignatureValueEntry.ts b/src/api/types/DocFormsGet200ResponseFieldsItemSignatureValueEntry.ts new file mode 100644 index 0000000..0a8931f --- /dev/null +++ b/src/api/types/DocFormsGet200ResponseFieldsItemSignatureValueEntry.ts @@ -0,0 +1,29 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocFormsGet200ResponseFieldsItemSignatureValueEntry = + | CloudpdfApi.DocFormsGet200ResponseFieldsItemSignatureValueEntry.None + | CloudpdfApi.DocFormsGet200ResponseFieldsItemSignatureValueEntry.Scalar + | CloudpdfApi.DocFormsGet200ResponseFieldsItemSignatureValueEntry.Array + | CloudpdfApi.DocFormsGet200ResponseFieldsItemSignatureValueEntry.Unsupported; + +export namespace DocFormsGet200ResponseFieldsItemSignatureValueEntry { + export interface None { + kind: "none"; + } + + export interface Scalar { + kind: "scalar"; + value: string; + } + + export interface Array { + kind: "array"; + values: string[]; + } + + export interface Unsupported { + kind: "unsupported"; + } +} diff --git a/src/api/types/DocFormsGet200ResponseFieldsItemTextDefaultValueEntry.ts b/src/api/types/DocFormsGet200ResponseFieldsItemTextDefaultValueEntry.ts new file mode 100644 index 0000000..728e53e --- /dev/null +++ b/src/api/types/DocFormsGet200ResponseFieldsItemTextDefaultValueEntry.ts @@ -0,0 +1,29 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocFormsGet200ResponseFieldsItemTextDefaultValueEntry = + | CloudpdfApi.DocFormsGet200ResponseFieldsItemTextDefaultValueEntry.None + | CloudpdfApi.DocFormsGet200ResponseFieldsItemTextDefaultValueEntry.Scalar + | CloudpdfApi.DocFormsGet200ResponseFieldsItemTextDefaultValueEntry.Array + | CloudpdfApi.DocFormsGet200ResponseFieldsItemTextDefaultValueEntry.Unsupported; + +export namespace DocFormsGet200ResponseFieldsItemTextDefaultValueEntry { + export interface None { + kind: "none"; + } + + export interface Scalar { + kind: "scalar"; + value: string; + } + + export interface Array { + kind: "array"; + values: string[]; + } + + export interface Unsupported { + kind: "unsupported"; + } +} diff --git a/src/api/types/DocFormsGet200ResponseFieldsItemTextRef.ts b/src/api/types/DocFormsGet200ResponseFieldsItemTextRef.ts new file mode 100644 index 0000000..faea92f --- /dev/null +++ b/src/api/types/DocFormsGet200ResponseFieldsItemTextRef.ts @@ -0,0 +1,19 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocFormsGet200ResponseFieldsItemTextRef = + | CloudpdfApi.DocFormsGet200ResponseFieldsItemTextRef.ObjectNumber + | CloudpdfApi.DocFormsGet200ResponseFieldsItemTextRef.Fqn; + +export namespace DocFormsGet200ResponseFieldsItemTextRef { + export interface ObjectNumber { + kind: "objectNumber"; + fieldObjectNumber: number; + } + + export interface Fqn { + kind: "fqn"; + name: string; + } +} diff --git a/src/api/types/DocFormsGet200ResponseFieldsItemTextValueEntry.ts b/src/api/types/DocFormsGet200ResponseFieldsItemTextValueEntry.ts new file mode 100644 index 0000000..7822758 --- /dev/null +++ b/src/api/types/DocFormsGet200ResponseFieldsItemTextValueEntry.ts @@ -0,0 +1,29 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocFormsGet200ResponseFieldsItemTextValueEntry = + | CloudpdfApi.DocFormsGet200ResponseFieldsItemTextValueEntry.None + | CloudpdfApi.DocFormsGet200ResponseFieldsItemTextValueEntry.Scalar + | CloudpdfApi.DocFormsGet200ResponseFieldsItemTextValueEntry.Array + | CloudpdfApi.DocFormsGet200ResponseFieldsItemTextValueEntry.Unsupported; + +export namespace DocFormsGet200ResponseFieldsItemTextValueEntry { + export interface None { + kind: "none"; + } + + export interface Scalar { + kind: "scalar"; + value: string; + } + + export interface Array { + kind: "array"; + values: string[]; + } + + export interface Unsupported { + kind: "unsupported"; + } +} diff --git a/src/api/types/DocFormsGet200ResponseFieldsItemUnknownDefaultValueEntry.ts b/src/api/types/DocFormsGet200ResponseFieldsItemUnknownDefaultValueEntry.ts new file mode 100644 index 0000000..0ecd349 --- /dev/null +++ b/src/api/types/DocFormsGet200ResponseFieldsItemUnknownDefaultValueEntry.ts @@ -0,0 +1,29 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocFormsGet200ResponseFieldsItemUnknownDefaultValueEntry = + | CloudpdfApi.DocFormsGet200ResponseFieldsItemUnknownDefaultValueEntry.None + | CloudpdfApi.DocFormsGet200ResponseFieldsItemUnknownDefaultValueEntry.Scalar + | CloudpdfApi.DocFormsGet200ResponseFieldsItemUnknownDefaultValueEntry.Array + | CloudpdfApi.DocFormsGet200ResponseFieldsItemUnknownDefaultValueEntry.Unsupported; + +export namespace DocFormsGet200ResponseFieldsItemUnknownDefaultValueEntry { + export interface None { + kind: "none"; + } + + export interface Scalar { + kind: "scalar"; + value: string; + } + + export interface Array { + kind: "array"; + values: string[]; + } + + export interface Unsupported { + kind: "unsupported"; + } +} diff --git a/src/api/types/DocFormsGet200ResponseFieldsItemUnknownRef.ts b/src/api/types/DocFormsGet200ResponseFieldsItemUnknownRef.ts new file mode 100644 index 0000000..5c8a509 --- /dev/null +++ b/src/api/types/DocFormsGet200ResponseFieldsItemUnknownRef.ts @@ -0,0 +1,19 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocFormsGet200ResponseFieldsItemUnknownRef = + | CloudpdfApi.DocFormsGet200ResponseFieldsItemUnknownRef.ObjectNumber + | CloudpdfApi.DocFormsGet200ResponseFieldsItemUnknownRef.Fqn; + +export namespace DocFormsGet200ResponseFieldsItemUnknownRef { + export interface ObjectNumber { + kind: "objectNumber"; + fieldObjectNumber: number; + } + + export interface Fqn { + kind: "fqn"; + name: string; + } +} diff --git a/src/api/types/DocFormsGet200ResponseFieldsItemUnknownValueEntry.ts b/src/api/types/DocFormsGet200ResponseFieldsItemUnknownValueEntry.ts new file mode 100644 index 0000000..e806398 --- /dev/null +++ b/src/api/types/DocFormsGet200ResponseFieldsItemUnknownValueEntry.ts @@ -0,0 +1,29 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocFormsGet200ResponseFieldsItemUnknownValueEntry = + | CloudpdfApi.DocFormsGet200ResponseFieldsItemUnknownValueEntry.None + | CloudpdfApi.DocFormsGet200ResponseFieldsItemUnknownValueEntry.Scalar + | CloudpdfApi.DocFormsGet200ResponseFieldsItemUnknownValueEntry.Array + | CloudpdfApi.DocFormsGet200ResponseFieldsItemUnknownValueEntry.Unsupported; + +export namespace DocFormsGet200ResponseFieldsItemUnknownValueEntry { + export interface None { + kind: "none"; + } + + export interface Scalar { + kind: "scalar"; + value: string; + } + + export interface Array { + kind: "array"; + values: string[]; + } + + export interface Unsupported { + kind: "unsupported"; + } +} diff --git a/src/api/types/DocFormsGet404Response.ts b/src/api/types/DocFormsGet404Response.ts new file mode 100644 index 0000000..ca74d73 --- /dev/null +++ b/src/api/types/DocFormsGet404Response.ts @@ -0,0 +1,36 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface DocFormsGet404Response { + name: DocFormsGet404Response.Name; + code: DocFormsGet404Response.Code; + message: string; + details?: Record | undefined; +} + +export namespace DocFormsGet404Response { + export const Name = { + EngineError: "EngineError", + } as const; + export type Name = (typeof Name)[keyof typeof Name]; + export const Code = { + Unknown: "Unknown", + InvalidArg: "InvalidArg", + DocNotOpen: "DocNotOpen", + DocOpenFailed: "DocOpenFailed", + DocPasswordRequired: "DocPasswordRequired", + DocPasswordIncorrect: "DocPasswordIncorrect", + Aborted: "Aborted", + Network: "Network", + Unauthenticated: "Unauthenticated", + Forbidden: "Forbidden", + NotFound: "NotFound", + WireFormat: "WireFormat", + RuntimeUnavailable: "RuntimeUnavailable", + InvalidReference: "InvalidReference", + WeakAnnotationSessionConflict: "WeakAnnotationSessionConflict", + LayerVersionConflict: "LayerVersionConflict", + NotImplemented: "NotImplemented", + MalformedPdf: "MalformedPdf", + } as const; + export type Code = (typeof Code)[keyof typeof Code]; +} diff --git a/src/api/types/DocFormsImportData200Response.ts b/src/api/types/DocFormsImportData200Response.ts new file mode 100644 index 0000000..39b88d4 --- /dev/null +++ b/src/api/types/DocFormsImportData200Response.ts @@ -0,0 +1,60 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export interface DocFormsImportData200Response { + meta: DocFormsImportData200Response.Meta; + /** Accepts any additional properties */ + [key: string]: any; +} + +export namespace DocFormsImportData200Response { + export interface Meta { + affectedPages: Meta.AffectedPages.Item[]; + cacheDelta: Meta.CacheDelta | null; + } + + export namespace Meta { + export type AffectedPages = AffectedPages.Item[]; + + export namespace AffectedPages { + export interface Item { + pageObjectNumber: number; + revision: Item.Revision; + weakAnnotationState: CloudpdfApi.DocFormsImportData200ResponseMetaAffectedPagesItemWeakAnnotationState; + } + + export namespace Item { + export interface Revision { + docSessionId: string; + pageObjectNumber: number; + generation: number; + } + } + } + + export interface CacheDelta { + previousDocVersion: number; + docVersion: number; + pages: CacheDelta.Pages.Item[]; + } + + export namespace CacheDelta { + export type Pages = Pages.Item[]; + + export namespace Pages { + export interface Item { + pageObjectNumber: number; + cache: Item.Cache; + } + + export namespace Item { + export interface Cache { + contentVersion: number; + annotationVersion: number; + } + } + } + } + } +} diff --git a/src/api/types/DocFormsImportData200ResponseMetaAffectedPagesItemWeakAnnotationState.ts b/src/api/types/DocFormsImportData200ResponseMetaAffectedPagesItemWeakAnnotationState.ts new file mode 100644 index 0000000..7bc2367 --- /dev/null +++ b/src/api/types/DocFormsImportData200ResponseMetaAffectedPagesItemWeakAnnotationState.ts @@ -0,0 +1,18 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocFormsImportData200ResponseMetaAffectedPagesItemWeakAnnotationState = + | CloudpdfApi.DocFormsImportData200ResponseMetaAffectedPagesItemWeakAnnotationState.Unknown + | CloudpdfApi.DocFormsImportData200ResponseMetaAffectedPagesItemWeakAnnotationState.Known; + +export namespace DocFormsImportData200ResponseMetaAffectedPagesItemWeakAnnotationState { + export interface Unknown { + kind: "unknown"; + } + + export interface Known { + kind: "known"; + hasAnyWeakAnnotations: boolean; + } +} diff --git a/src/api/types/DocFormsImportData400Response.ts b/src/api/types/DocFormsImportData400Response.ts new file mode 100644 index 0000000..9003006 --- /dev/null +++ b/src/api/types/DocFormsImportData400Response.ts @@ -0,0 +1,36 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface DocFormsImportData400Response { + name: DocFormsImportData400Response.Name; + code: DocFormsImportData400Response.Code; + message: string; + details?: Record | undefined; +} + +export namespace DocFormsImportData400Response { + export const Name = { + EngineError: "EngineError", + } as const; + export type Name = (typeof Name)[keyof typeof Name]; + export const Code = { + Unknown: "Unknown", + InvalidArg: "InvalidArg", + DocNotOpen: "DocNotOpen", + DocOpenFailed: "DocOpenFailed", + DocPasswordRequired: "DocPasswordRequired", + DocPasswordIncorrect: "DocPasswordIncorrect", + Aborted: "Aborted", + Network: "Network", + Unauthenticated: "Unauthenticated", + Forbidden: "Forbidden", + NotFound: "NotFound", + WireFormat: "WireFormat", + RuntimeUnavailable: "RuntimeUnavailable", + InvalidReference: "InvalidReference", + WeakAnnotationSessionConflict: "WeakAnnotationSessionConflict", + LayerVersionConflict: "LayerVersionConflict", + NotImplemented: "NotImplemented", + MalformedPdf: "MalformedPdf", + } as const; + export type Code = (typeof Code)[keyof typeof Code]; +} diff --git a/src/api/types/DocFormsImportData404Response.ts b/src/api/types/DocFormsImportData404Response.ts new file mode 100644 index 0000000..78e191e --- /dev/null +++ b/src/api/types/DocFormsImportData404Response.ts @@ -0,0 +1,36 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface DocFormsImportData404Response { + name: DocFormsImportData404Response.Name; + code: DocFormsImportData404Response.Code; + message: string; + details?: Record | undefined; +} + +export namespace DocFormsImportData404Response { + export const Name = { + EngineError: "EngineError", + } as const; + export type Name = (typeof Name)[keyof typeof Name]; + export const Code = { + Unknown: "Unknown", + InvalidArg: "InvalidArg", + DocNotOpen: "DocNotOpen", + DocOpenFailed: "DocOpenFailed", + DocPasswordRequired: "DocPasswordRequired", + DocPasswordIncorrect: "DocPasswordIncorrect", + Aborted: "Aborted", + Network: "Network", + Unauthenticated: "Unauthenticated", + Forbidden: "Forbidden", + NotFound: "NotFound", + WireFormat: "WireFormat", + RuntimeUnavailable: "RuntimeUnavailable", + InvalidReference: "InvalidReference", + WeakAnnotationSessionConflict: "WeakAnnotationSessionConflict", + LayerVersionConflict: "LayerVersionConflict", + NotImplemented: "NotImplemented", + MalformedPdf: "MalformedPdf", + } as const; + export type Code = (typeof Code)[keyof typeof Code]; +} diff --git a/src/api/types/DocFormsImportDataRequest.ts b/src/api/types/DocFormsImportDataRequest.ts new file mode 100644 index 0000000..df04ef9 --- /dev/null +++ b/src/api/types/DocFormsImportDataRequest.ts @@ -0,0 +1,3 @@ +// This file was auto-generated by Fern from our API Definition. + +export type DocFormsImportDataRequest = Record; diff --git a/src/api/types/DocFormsReset200Response.ts b/src/api/types/DocFormsReset200Response.ts new file mode 100644 index 0000000..791fddb --- /dev/null +++ b/src/api/types/DocFormsReset200Response.ts @@ -0,0 +1,60 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export interface DocFormsReset200Response { + meta: DocFormsReset200Response.Meta; + /** Accepts any additional properties */ + [key: string]: any; +} + +export namespace DocFormsReset200Response { + export interface Meta { + affectedPages: Meta.AffectedPages.Item[]; + cacheDelta: Meta.CacheDelta | null; + } + + export namespace Meta { + export type AffectedPages = AffectedPages.Item[]; + + export namespace AffectedPages { + export interface Item { + pageObjectNumber: number; + revision: Item.Revision; + weakAnnotationState: CloudpdfApi.DocFormsReset200ResponseMetaAffectedPagesItemWeakAnnotationState; + } + + export namespace Item { + export interface Revision { + docSessionId: string; + pageObjectNumber: number; + generation: number; + } + } + } + + export interface CacheDelta { + previousDocVersion: number; + docVersion: number; + pages: CacheDelta.Pages.Item[]; + } + + export namespace CacheDelta { + export type Pages = Pages.Item[]; + + export namespace Pages { + export interface Item { + pageObjectNumber: number; + cache: Item.Cache; + } + + export namespace Item { + export interface Cache { + contentVersion: number; + annotationVersion: number; + } + } + } + } + } +} diff --git a/src/api/types/DocFormsReset200ResponseMetaAffectedPagesItemWeakAnnotationState.ts b/src/api/types/DocFormsReset200ResponseMetaAffectedPagesItemWeakAnnotationState.ts new file mode 100644 index 0000000..26fa8c9 --- /dev/null +++ b/src/api/types/DocFormsReset200ResponseMetaAffectedPagesItemWeakAnnotationState.ts @@ -0,0 +1,18 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocFormsReset200ResponseMetaAffectedPagesItemWeakAnnotationState = + | CloudpdfApi.DocFormsReset200ResponseMetaAffectedPagesItemWeakAnnotationState.Unknown + | CloudpdfApi.DocFormsReset200ResponseMetaAffectedPagesItemWeakAnnotationState.Known; + +export namespace DocFormsReset200ResponseMetaAffectedPagesItemWeakAnnotationState { + export interface Unknown { + kind: "unknown"; + } + + export interface Known { + kind: "known"; + hasAnyWeakAnnotations: boolean; + } +} diff --git a/src/api/types/DocFormsReset404Response.ts b/src/api/types/DocFormsReset404Response.ts new file mode 100644 index 0000000..088ccc6 --- /dev/null +++ b/src/api/types/DocFormsReset404Response.ts @@ -0,0 +1,36 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface DocFormsReset404Response { + name: DocFormsReset404Response.Name; + code: DocFormsReset404Response.Code; + message: string; + details?: Record | undefined; +} + +export namespace DocFormsReset404Response { + export const Name = { + EngineError: "EngineError", + } as const; + export type Name = (typeof Name)[keyof typeof Name]; + export const Code = { + Unknown: "Unknown", + InvalidArg: "InvalidArg", + DocNotOpen: "DocNotOpen", + DocOpenFailed: "DocOpenFailed", + DocPasswordRequired: "DocPasswordRequired", + DocPasswordIncorrect: "DocPasswordIncorrect", + Aborted: "Aborted", + Network: "Network", + Unauthenticated: "Unauthenticated", + Forbidden: "Forbidden", + NotFound: "NotFound", + WireFormat: "WireFormat", + RuntimeUnavailable: "RuntimeUnavailable", + InvalidReference: "InvalidReference", + WeakAnnotationSessionConflict: "WeakAnnotationSessionConflict", + LayerVersionConflict: "LayerVersionConflict", + NotImplemented: "NotImplemented", + MalformedPdf: "MalformedPdf", + } as const; + export type Code = (typeof Code)[keyof typeof Code]; +} diff --git a/src/api/types/DocFormsSetValue200Response.ts b/src/api/types/DocFormsSetValue200Response.ts new file mode 100644 index 0000000..38550ad --- /dev/null +++ b/src/api/types/DocFormsSetValue200Response.ts @@ -0,0 +1,60 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export interface DocFormsSetValue200Response { + meta: DocFormsSetValue200Response.Meta; + /** Accepts any additional properties */ + [key: string]: any; +} + +export namespace DocFormsSetValue200Response { + export interface Meta { + affectedPages: Meta.AffectedPages.Item[]; + cacheDelta: Meta.CacheDelta | null; + } + + export namespace Meta { + export type AffectedPages = AffectedPages.Item[]; + + export namespace AffectedPages { + export interface Item { + pageObjectNumber: number; + revision: Item.Revision; + weakAnnotationState: CloudpdfApi.DocFormsSetValue200ResponseMetaAffectedPagesItemWeakAnnotationState; + } + + export namespace Item { + export interface Revision { + docSessionId: string; + pageObjectNumber: number; + generation: number; + } + } + } + + export interface CacheDelta { + previousDocVersion: number; + docVersion: number; + pages: CacheDelta.Pages.Item[]; + } + + export namespace CacheDelta { + export type Pages = Pages.Item[]; + + export namespace Pages { + export interface Item { + pageObjectNumber: number; + cache: Item.Cache; + } + + export namespace Item { + export interface Cache { + contentVersion: number; + annotationVersion: number; + } + } + } + } + } +} diff --git a/src/api/types/DocFormsSetValue200ResponseMetaAffectedPagesItemWeakAnnotationState.ts b/src/api/types/DocFormsSetValue200ResponseMetaAffectedPagesItemWeakAnnotationState.ts new file mode 100644 index 0000000..96438c7 --- /dev/null +++ b/src/api/types/DocFormsSetValue200ResponseMetaAffectedPagesItemWeakAnnotationState.ts @@ -0,0 +1,18 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocFormsSetValue200ResponseMetaAffectedPagesItemWeakAnnotationState = + | CloudpdfApi.DocFormsSetValue200ResponseMetaAffectedPagesItemWeakAnnotationState.Unknown + | CloudpdfApi.DocFormsSetValue200ResponseMetaAffectedPagesItemWeakAnnotationState.Known; + +export namespace DocFormsSetValue200ResponseMetaAffectedPagesItemWeakAnnotationState { + export interface Unknown { + kind: "unknown"; + } + + export interface Known { + kind: "known"; + hasAnyWeakAnnotations: boolean; + } +} diff --git a/src/api/types/DocFormsSetValue400Response.ts b/src/api/types/DocFormsSetValue400Response.ts new file mode 100644 index 0000000..1c8034c --- /dev/null +++ b/src/api/types/DocFormsSetValue400Response.ts @@ -0,0 +1,36 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface DocFormsSetValue400Response { + name: DocFormsSetValue400Response.Name; + code: DocFormsSetValue400Response.Code; + message: string; + details?: Record | undefined; +} + +export namespace DocFormsSetValue400Response { + export const Name = { + EngineError: "EngineError", + } as const; + export type Name = (typeof Name)[keyof typeof Name]; + export const Code = { + Unknown: "Unknown", + InvalidArg: "InvalidArg", + DocNotOpen: "DocNotOpen", + DocOpenFailed: "DocOpenFailed", + DocPasswordRequired: "DocPasswordRequired", + DocPasswordIncorrect: "DocPasswordIncorrect", + Aborted: "Aborted", + Network: "Network", + Unauthenticated: "Unauthenticated", + Forbidden: "Forbidden", + NotFound: "NotFound", + WireFormat: "WireFormat", + RuntimeUnavailable: "RuntimeUnavailable", + InvalidReference: "InvalidReference", + WeakAnnotationSessionConflict: "WeakAnnotationSessionConflict", + LayerVersionConflict: "LayerVersionConflict", + NotImplemented: "NotImplemented", + MalformedPdf: "MalformedPdf", + } as const; + export type Code = (typeof Code)[keyof typeof Code]; +} diff --git a/src/api/types/DocFormsSetValue404Response.ts b/src/api/types/DocFormsSetValue404Response.ts new file mode 100644 index 0000000..1815675 --- /dev/null +++ b/src/api/types/DocFormsSetValue404Response.ts @@ -0,0 +1,36 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface DocFormsSetValue404Response { + name: DocFormsSetValue404Response.Name; + code: DocFormsSetValue404Response.Code; + message: string; + details?: Record | undefined; +} + +export namespace DocFormsSetValue404Response { + export const Name = { + EngineError: "EngineError", + } as const; + export type Name = (typeof Name)[keyof typeof Name]; + export const Code = { + Unknown: "Unknown", + InvalidArg: "InvalidArg", + DocNotOpen: "DocNotOpen", + DocOpenFailed: "DocOpenFailed", + DocPasswordRequired: "DocPasswordRequired", + DocPasswordIncorrect: "DocPasswordIncorrect", + Aborted: "Aborted", + Network: "Network", + Unauthenticated: "Unauthenticated", + Forbidden: "Forbidden", + NotFound: "NotFound", + WireFormat: "WireFormat", + RuntimeUnavailable: "RuntimeUnavailable", + InvalidReference: "InvalidReference", + WeakAnnotationSessionConflict: "WeakAnnotationSessionConflict", + LayerVersionConflict: "LayerVersionConflict", + NotImplemented: "NotImplemented", + MalformedPdf: "MalformedPdf", + } as const; + export type Code = (typeof Code)[keyof typeof Code]; +} diff --git a/src/api/types/DocFormsSetValueRequest.ts b/src/api/types/DocFormsSetValueRequest.ts new file mode 100644 index 0000000..68f732c --- /dev/null +++ b/src/api/types/DocFormsSetValueRequest.ts @@ -0,0 +1,3 @@ +// This file was auto-generated by Fern from our API Definition. + +export type DocFormsSetValueRequest = Record; diff --git a/src/api/types/DocHead200Response.ts b/src/api/types/DocHead200Response.ts new file mode 100644 index 0000000..b178fe2 --- /dev/null +++ b/src/api/types/DocHead200Response.ts @@ -0,0 +1,74 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface DocHead200Response { + id: string; + baseSha: string; + storageSizeBytes: number; + docVersion: number; + state: DocHead200Response.State; + encryption: DocHead200Response.Encryption; + permissions: DocHead200Response.Permissions; + access: DocHead200Response.Access; +} + +export namespace DocHead200Response { + export const State = { + Pending: "pending", + Ready: "ready", + Failed: "failed", + Deleting: "deleting", + } as const; + export type State = (typeof State)[keyof typeof State]; + + export interface Encryption { + state: Encryption.State; + requiresPassword: boolean | null; + } + + export namespace Encryption { + export const State = { + Unknown: "unknown", + None: "none", + Encrypted: "encrypted", + Unsupported: "unsupported", + } as const; + export type State = (typeof State)[keyof typeof State]; + } + + export interface Permissions { + known: boolean; + bits: number | null; + allAllowed: boolean | null; + openedAs: Permissions.OpenedAs | null; + securityHandlerRevision: number | null; + canUpgradeToOwner: boolean; + } + + export namespace Permissions { + export const OpenedAs = { + None: "none", + User: "user", + Owner: "owner", + } as const; + export type OpenedAs = (typeof OpenedAs)[keyof typeof OpenedAs]; + } + + export interface Access { + required: boolean; + reasons: Access.Reasons.Item[]; + endpoint?: string | undefined; + } + + export namespace Access { + export type Reasons = Reasons.Item[]; + + export namespace Reasons { + export const Item = { + Password: "password", + Cdn: "cdn", + PermissionsUnknown: "permissions-unknown", + } as const; + export type Item = (typeof Item)[keyof typeof Item]; + } + } +} diff --git a/src/api/types/DocHead404Response.ts b/src/api/types/DocHead404Response.ts new file mode 100644 index 0000000..1a5c6ca --- /dev/null +++ b/src/api/types/DocHead404Response.ts @@ -0,0 +1,36 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface DocHead404Response { + name: DocHead404Response.Name; + code: DocHead404Response.Code; + message: string; + details?: Record | undefined; +} + +export namespace DocHead404Response { + export const Name = { + EngineError: "EngineError", + } as const; + export type Name = (typeof Name)[keyof typeof Name]; + export const Code = { + Unknown: "Unknown", + InvalidArg: "InvalidArg", + DocNotOpen: "DocNotOpen", + DocOpenFailed: "DocOpenFailed", + DocPasswordRequired: "DocPasswordRequired", + DocPasswordIncorrect: "DocPasswordIncorrect", + Aborted: "Aborted", + Network: "Network", + Unauthenticated: "Unauthenticated", + Forbidden: "Forbidden", + NotFound: "NotFound", + WireFormat: "WireFormat", + RuntimeUnavailable: "RuntimeUnavailable", + InvalidReference: "InvalidReference", + WeakAnnotationSessionConflict: "WeakAnnotationSessionConflict", + LayerVersionConflict: "LayerVersionConflict", + NotImplemented: "NotImplemented", + MalformedPdf: "MalformedPdf", + } as const; + export type Code = (typeof Code)[keyof typeof Code]; +} diff --git a/src/api/types/DocManifest200Response.ts b/src/api/types/DocManifest200Response.ts new file mode 100644 index 0000000..c31323e --- /dev/null +++ b/src/api/types/DocManifest200Response.ts @@ -0,0 +1,89 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export interface DocManifest200Response { + docVersion: number; + layoutVersion: number; + metadataVersion: number; + actionsVersion?: number | undefined; + attachmentsVersion?: number | undefined; + auditHead: number; + baseSha: string; + scopes?: DocManifest200Response.Scopes | undefined; + pages: DocManifest200Response.Pages.Item[]; +} + +export namespace DocManifest200Response { + export interface Scopes { + content: Scopes.Content; + annotations: Scopes.Annotations; + layout: Scopes.Layout; + attachments: Scopes.Attachments; + metadata: Scopes.Metadata; + actions: Scopes.Actions; + } + + export namespace Scopes { + export const Content = { + Base: "base", + Layer: "layer", + } as const; + export type Content = (typeof Content)[keyof typeof Content]; + export const Annotations = { + Base: "base", + Layer: "layer", + } as const; + export type Annotations = (typeof Annotations)[keyof typeof Annotations]; + export const Layout = { + Base: "base", + Layer: "layer", + } as const; + export type Layout = (typeof Layout)[keyof typeof Layout]; + export const Attachments = { + Base: "base", + Layer: "layer", + } as const; + export type Attachments = (typeof Attachments)[keyof typeof Attachments]; + export const Metadata = { + Base: "base", + Layer: "layer", + } as const; + export type Metadata = (typeof Metadata)[keyof typeof Metadata]; + export const Actions = { + Base: "base", + Layer: "layer", + } as const; + export type Actions = (typeof Actions)[keyof typeof Actions]; + } + + export type Pages = Pages.Item[]; + + export namespace Pages { + export interface Item { + state: Item.State; + cache: Item.Cache; + } + + export namespace Item { + export interface State { + pageObjectNumber: number; + revision: State.Revision; + weakAnnotationState: CloudpdfApi.DocManifest200ResponsePagesItemStateWeakAnnotationState; + } + + export namespace State { + export interface Revision { + docSessionId: string; + pageObjectNumber: number; + generation: number; + } + } + + export interface Cache { + contentVersion: number; + annotationVersion: number; + } + } + } +} diff --git a/src/api/types/DocManifest200ResponsePagesItemStateWeakAnnotationState.ts b/src/api/types/DocManifest200ResponsePagesItemStateWeakAnnotationState.ts new file mode 100644 index 0000000..ea8d7a3 --- /dev/null +++ b/src/api/types/DocManifest200ResponsePagesItemStateWeakAnnotationState.ts @@ -0,0 +1,18 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocManifest200ResponsePagesItemStateWeakAnnotationState = + | CloudpdfApi.DocManifest200ResponsePagesItemStateWeakAnnotationState.Unknown + | CloudpdfApi.DocManifest200ResponsePagesItemStateWeakAnnotationState.Known; + +export namespace DocManifest200ResponsePagesItemStateWeakAnnotationState { + export interface Unknown { + kind: "unknown"; + } + + export interface Known { + kind: "known"; + hasAnyWeakAnnotations: boolean; + } +} diff --git a/src/api/types/DocManifest404Response.ts b/src/api/types/DocManifest404Response.ts new file mode 100644 index 0000000..a41d1ba --- /dev/null +++ b/src/api/types/DocManifest404Response.ts @@ -0,0 +1,36 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface DocManifest404Response { + name: DocManifest404Response.Name; + code: DocManifest404Response.Code; + message: string; + details?: Record | undefined; +} + +export namespace DocManifest404Response { + export const Name = { + EngineError: "EngineError", + } as const; + export type Name = (typeof Name)[keyof typeof Name]; + export const Code = { + Unknown: "Unknown", + InvalidArg: "InvalidArg", + DocNotOpen: "DocNotOpen", + DocOpenFailed: "DocOpenFailed", + DocPasswordRequired: "DocPasswordRequired", + DocPasswordIncorrect: "DocPasswordIncorrect", + Aborted: "Aborted", + Network: "Network", + Unauthenticated: "Unauthenticated", + Forbidden: "Forbidden", + NotFound: "NotFound", + WireFormat: "WireFormat", + RuntimeUnavailable: "RuntimeUnavailable", + InvalidReference: "InvalidReference", + WeakAnnotationSessionConflict: "WeakAnnotationSessionConflict", + LayerVersionConflict: "LayerVersionConflict", + NotImplemented: "NotImplemented", + MalformedPdf: "MalformedPdf", + } as const; + export type Code = (typeof Code)[keyof typeof Code]; +} diff --git a/src/api/types/DocMetadataGet200Response.ts b/src/api/types/DocMetadataGet200Response.ts new file mode 100644 index 0000000..3e251dd --- /dev/null +++ b/src/api/types/DocMetadataGet200Response.ts @@ -0,0 +1,23 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface DocMetadataGet200Response { + title: string | null; + author: string | null; + subject: string | null; + keywords: string | null; + producer: string | null; + creator: string | null; + created: string | null; + modified: string | null; + trapped: DocMetadataGet200Response.Trapped; + custom: Record; +} + +export namespace DocMetadataGet200Response { + export const Trapped = { + True: "true", + False: "false", + Unknown: "unknown", + } as const; + export type Trapped = (typeof Trapped)[keyof typeof Trapped]; +} diff --git a/src/api/types/DocMetadataGet404Response.ts b/src/api/types/DocMetadataGet404Response.ts new file mode 100644 index 0000000..8f3a94f --- /dev/null +++ b/src/api/types/DocMetadataGet404Response.ts @@ -0,0 +1,36 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface DocMetadataGet404Response { + name: DocMetadataGet404Response.Name; + code: DocMetadataGet404Response.Code; + message: string; + details?: Record | undefined; +} + +export namespace DocMetadataGet404Response { + export const Name = { + EngineError: "EngineError", + } as const; + export type Name = (typeof Name)[keyof typeof Name]; + export const Code = { + Unknown: "Unknown", + InvalidArg: "InvalidArg", + DocNotOpen: "DocNotOpen", + DocOpenFailed: "DocOpenFailed", + DocPasswordRequired: "DocPasswordRequired", + DocPasswordIncorrect: "DocPasswordIncorrect", + Aborted: "Aborted", + Network: "Network", + Unauthenticated: "Unauthenticated", + Forbidden: "Forbidden", + NotFound: "NotFound", + WireFormat: "WireFormat", + RuntimeUnavailable: "RuntimeUnavailable", + InvalidReference: "InvalidReference", + WeakAnnotationSessionConflict: "WeakAnnotationSessionConflict", + LayerVersionConflict: "LayerVersionConflict", + NotImplemented: "NotImplemented", + MalformedPdf: "MalformedPdf", + } as const; + export type Code = (typeof Code)[keyof typeof Code]; +} diff --git a/src/api/types/DocPagesDelete200Response.ts b/src/api/types/DocPagesDelete200Response.ts new file mode 100644 index 0000000..682e760 --- /dev/null +++ b/src/api/types/DocPagesDelete200Response.ts @@ -0,0 +1,60 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export interface DocPagesDelete200Response { + meta: DocPagesDelete200Response.Meta; + /** Accepts any additional properties */ + [key: string]: any; +} + +export namespace DocPagesDelete200Response { + export interface Meta { + affectedPages: Meta.AffectedPages.Item[]; + cacheDelta: Meta.CacheDelta | null; + } + + export namespace Meta { + export type AffectedPages = AffectedPages.Item[]; + + export namespace AffectedPages { + export interface Item { + pageObjectNumber: number; + revision: Item.Revision; + weakAnnotationState: CloudpdfApi.DocPagesDelete200ResponseMetaAffectedPagesItemWeakAnnotationState; + } + + export namespace Item { + export interface Revision { + docSessionId: string; + pageObjectNumber: number; + generation: number; + } + } + } + + export interface CacheDelta { + previousDocVersion: number; + docVersion: number; + pages: CacheDelta.Pages.Item[]; + } + + export namespace CacheDelta { + export type Pages = Pages.Item[]; + + export namespace Pages { + export interface Item { + pageObjectNumber: number; + cache: Item.Cache; + } + + export namespace Item { + export interface Cache { + contentVersion: number; + annotationVersion: number; + } + } + } + } + } +} diff --git a/src/api/types/DocPagesDelete200ResponseMetaAffectedPagesItemWeakAnnotationState.ts b/src/api/types/DocPagesDelete200ResponseMetaAffectedPagesItemWeakAnnotationState.ts new file mode 100644 index 0000000..049869a --- /dev/null +++ b/src/api/types/DocPagesDelete200ResponseMetaAffectedPagesItemWeakAnnotationState.ts @@ -0,0 +1,18 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocPagesDelete200ResponseMetaAffectedPagesItemWeakAnnotationState = + | CloudpdfApi.DocPagesDelete200ResponseMetaAffectedPagesItemWeakAnnotationState.Unknown + | CloudpdfApi.DocPagesDelete200ResponseMetaAffectedPagesItemWeakAnnotationState.Known; + +export namespace DocPagesDelete200ResponseMetaAffectedPagesItemWeakAnnotationState { + export interface Unknown { + kind: "unknown"; + } + + export interface Known { + kind: "known"; + hasAnyWeakAnnotations: boolean; + } +} diff --git a/src/api/types/DocPagesDelete400Response.ts b/src/api/types/DocPagesDelete400Response.ts new file mode 100644 index 0000000..e566eee --- /dev/null +++ b/src/api/types/DocPagesDelete400Response.ts @@ -0,0 +1,36 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface DocPagesDelete400Response { + name: DocPagesDelete400Response.Name; + code: DocPagesDelete400Response.Code; + message: string; + details?: Record | undefined; +} + +export namespace DocPagesDelete400Response { + export const Name = { + EngineError: "EngineError", + } as const; + export type Name = (typeof Name)[keyof typeof Name]; + export const Code = { + Unknown: "Unknown", + InvalidArg: "InvalidArg", + DocNotOpen: "DocNotOpen", + DocOpenFailed: "DocOpenFailed", + DocPasswordRequired: "DocPasswordRequired", + DocPasswordIncorrect: "DocPasswordIncorrect", + Aborted: "Aborted", + Network: "Network", + Unauthenticated: "Unauthenticated", + Forbidden: "Forbidden", + NotFound: "NotFound", + WireFormat: "WireFormat", + RuntimeUnavailable: "RuntimeUnavailable", + InvalidReference: "InvalidReference", + WeakAnnotationSessionConflict: "WeakAnnotationSessionConflict", + LayerVersionConflict: "LayerVersionConflict", + NotImplemented: "NotImplemented", + MalformedPdf: "MalformedPdf", + } as const; + export type Code = (typeof Code)[keyof typeof Code]; +} diff --git a/src/api/types/DocPagesDelete404Response.ts b/src/api/types/DocPagesDelete404Response.ts new file mode 100644 index 0000000..707f07d --- /dev/null +++ b/src/api/types/DocPagesDelete404Response.ts @@ -0,0 +1,36 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface DocPagesDelete404Response { + name: DocPagesDelete404Response.Name; + code: DocPagesDelete404Response.Code; + message: string; + details?: Record | undefined; +} + +export namespace DocPagesDelete404Response { + export const Name = { + EngineError: "EngineError", + } as const; + export type Name = (typeof Name)[keyof typeof Name]; + export const Code = { + Unknown: "Unknown", + InvalidArg: "InvalidArg", + DocNotOpen: "DocNotOpen", + DocOpenFailed: "DocOpenFailed", + DocPasswordRequired: "DocPasswordRequired", + DocPasswordIncorrect: "DocPasswordIncorrect", + Aborted: "Aborted", + Network: "Network", + Unauthenticated: "Unauthenticated", + Forbidden: "Forbidden", + NotFound: "NotFound", + WireFormat: "WireFormat", + RuntimeUnavailable: "RuntimeUnavailable", + InvalidReference: "InvalidReference", + WeakAnnotationSessionConflict: "WeakAnnotationSessionConflict", + LayerVersionConflict: "LayerVersionConflict", + NotImplemented: "NotImplemented", + MalformedPdf: "MalformedPdf", + } as const; + export type Code = (typeof Code)[keyof typeof Code]; +} diff --git a/src/api/types/DocPagesDeleteRequest.ts b/src/api/types/DocPagesDeleteRequest.ts new file mode 100644 index 0000000..65575d2 --- /dev/null +++ b/src/api/types/DocPagesDeleteRequest.ts @@ -0,0 +1,3 @@ +// This file was auto-generated by Fern from our API Definition. + +export type DocPagesDeleteRequest = Record; diff --git a/src/api/types/DocPagesFlatten200Response.ts b/src/api/types/DocPagesFlatten200Response.ts new file mode 100644 index 0000000..6ed139d --- /dev/null +++ b/src/api/types/DocPagesFlatten200Response.ts @@ -0,0 +1,60 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export interface DocPagesFlatten200Response { + meta: DocPagesFlatten200Response.Meta; + /** Accepts any additional properties */ + [key: string]: any; +} + +export namespace DocPagesFlatten200Response { + export interface Meta { + affectedPages: Meta.AffectedPages.Item[]; + cacheDelta: Meta.CacheDelta | null; + } + + export namespace Meta { + export type AffectedPages = AffectedPages.Item[]; + + export namespace AffectedPages { + export interface Item { + pageObjectNumber: number; + revision: Item.Revision; + weakAnnotationState: CloudpdfApi.DocPagesFlatten200ResponseMetaAffectedPagesItemWeakAnnotationState; + } + + export namespace Item { + export interface Revision { + docSessionId: string; + pageObjectNumber: number; + generation: number; + } + } + } + + export interface CacheDelta { + previousDocVersion: number; + docVersion: number; + pages: CacheDelta.Pages.Item[]; + } + + export namespace CacheDelta { + export type Pages = Pages.Item[]; + + export namespace Pages { + export interface Item { + pageObjectNumber: number; + cache: Item.Cache; + } + + export namespace Item { + export interface Cache { + contentVersion: number; + annotationVersion: number; + } + } + } + } + } +} diff --git a/src/api/types/DocPagesFlatten200ResponseMetaAffectedPagesItemWeakAnnotationState.ts b/src/api/types/DocPagesFlatten200ResponseMetaAffectedPagesItemWeakAnnotationState.ts new file mode 100644 index 0000000..e59c729 --- /dev/null +++ b/src/api/types/DocPagesFlatten200ResponseMetaAffectedPagesItemWeakAnnotationState.ts @@ -0,0 +1,18 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocPagesFlatten200ResponseMetaAffectedPagesItemWeakAnnotationState = + | CloudpdfApi.DocPagesFlatten200ResponseMetaAffectedPagesItemWeakAnnotationState.Unknown + | CloudpdfApi.DocPagesFlatten200ResponseMetaAffectedPagesItemWeakAnnotationState.Known; + +export namespace DocPagesFlatten200ResponseMetaAffectedPagesItemWeakAnnotationState { + export interface Unknown { + kind: "unknown"; + } + + export interface Known { + kind: "known"; + hasAnyWeakAnnotations: boolean; + } +} diff --git a/src/api/types/DocPagesFlatten400Response.ts b/src/api/types/DocPagesFlatten400Response.ts new file mode 100644 index 0000000..86bb6de --- /dev/null +++ b/src/api/types/DocPagesFlatten400Response.ts @@ -0,0 +1,36 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface DocPagesFlatten400Response { + name: DocPagesFlatten400Response.Name; + code: DocPagesFlatten400Response.Code; + message: string; + details?: Record | undefined; +} + +export namespace DocPagesFlatten400Response { + export const Name = { + EngineError: "EngineError", + } as const; + export type Name = (typeof Name)[keyof typeof Name]; + export const Code = { + Unknown: "Unknown", + InvalidArg: "InvalidArg", + DocNotOpen: "DocNotOpen", + DocOpenFailed: "DocOpenFailed", + DocPasswordRequired: "DocPasswordRequired", + DocPasswordIncorrect: "DocPasswordIncorrect", + Aborted: "Aborted", + Network: "Network", + Unauthenticated: "Unauthenticated", + Forbidden: "Forbidden", + NotFound: "NotFound", + WireFormat: "WireFormat", + RuntimeUnavailable: "RuntimeUnavailable", + InvalidReference: "InvalidReference", + WeakAnnotationSessionConflict: "WeakAnnotationSessionConflict", + LayerVersionConflict: "LayerVersionConflict", + NotImplemented: "NotImplemented", + MalformedPdf: "MalformedPdf", + } as const; + export type Code = (typeof Code)[keyof typeof Code]; +} diff --git a/src/api/types/DocPagesFlatten404Response.ts b/src/api/types/DocPagesFlatten404Response.ts new file mode 100644 index 0000000..80743f8 --- /dev/null +++ b/src/api/types/DocPagesFlatten404Response.ts @@ -0,0 +1,36 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface DocPagesFlatten404Response { + name: DocPagesFlatten404Response.Name; + code: DocPagesFlatten404Response.Code; + message: string; + details?: Record | undefined; +} + +export namespace DocPagesFlatten404Response { + export const Name = { + EngineError: "EngineError", + } as const; + export type Name = (typeof Name)[keyof typeof Name]; + export const Code = { + Unknown: "Unknown", + InvalidArg: "InvalidArg", + DocNotOpen: "DocNotOpen", + DocOpenFailed: "DocOpenFailed", + DocPasswordRequired: "DocPasswordRequired", + DocPasswordIncorrect: "DocPasswordIncorrect", + Aborted: "Aborted", + Network: "Network", + Unauthenticated: "Unauthenticated", + Forbidden: "Forbidden", + NotFound: "NotFound", + WireFormat: "WireFormat", + RuntimeUnavailable: "RuntimeUnavailable", + InvalidReference: "InvalidReference", + WeakAnnotationSessionConflict: "WeakAnnotationSessionConflict", + LayerVersionConflict: "LayerVersionConflict", + NotImplemented: "NotImplemented", + MalformedPdf: "MalformedPdf", + } as const; + export type Code = (typeof Code)[keyof typeof Code]; +} diff --git a/src/api/types/DocPagesFlattenRequest.ts b/src/api/types/DocPagesFlattenRequest.ts new file mode 100644 index 0000000..27de7ca --- /dev/null +++ b/src/api/types/DocPagesFlattenRequest.ts @@ -0,0 +1,3 @@ +// This file was auto-generated by Fern from our API Definition. + +export type DocPagesFlattenRequest = Record; diff --git a/src/api/types/DocPagesMove200Response.ts b/src/api/types/DocPagesMove200Response.ts new file mode 100644 index 0000000..cdafc5a --- /dev/null +++ b/src/api/types/DocPagesMove200Response.ts @@ -0,0 +1,60 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export interface DocPagesMove200Response { + meta: DocPagesMove200Response.Meta; + /** Accepts any additional properties */ + [key: string]: any; +} + +export namespace DocPagesMove200Response { + export interface Meta { + affectedPages: Meta.AffectedPages.Item[]; + cacheDelta: Meta.CacheDelta | null; + } + + export namespace Meta { + export type AffectedPages = AffectedPages.Item[]; + + export namespace AffectedPages { + export interface Item { + pageObjectNumber: number; + revision: Item.Revision; + weakAnnotationState: CloudpdfApi.DocPagesMove200ResponseMetaAffectedPagesItemWeakAnnotationState; + } + + export namespace Item { + export interface Revision { + docSessionId: string; + pageObjectNumber: number; + generation: number; + } + } + } + + export interface CacheDelta { + previousDocVersion: number; + docVersion: number; + pages: CacheDelta.Pages.Item[]; + } + + export namespace CacheDelta { + export type Pages = Pages.Item[]; + + export namespace Pages { + export interface Item { + pageObjectNumber: number; + cache: Item.Cache; + } + + export namespace Item { + export interface Cache { + contentVersion: number; + annotationVersion: number; + } + } + } + } + } +} diff --git a/src/api/types/DocPagesMove200ResponseMetaAffectedPagesItemWeakAnnotationState.ts b/src/api/types/DocPagesMove200ResponseMetaAffectedPagesItemWeakAnnotationState.ts new file mode 100644 index 0000000..eadd4d3 --- /dev/null +++ b/src/api/types/DocPagesMove200ResponseMetaAffectedPagesItemWeakAnnotationState.ts @@ -0,0 +1,18 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocPagesMove200ResponseMetaAffectedPagesItemWeakAnnotationState = + | CloudpdfApi.DocPagesMove200ResponseMetaAffectedPagesItemWeakAnnotationState.Unknown + | CloudpdfApi.DocPagesMove200ResponseMetaAffectedPagesItemWeakAnnotationState.Known; + +export namespace DocPagesMove200ResponseMetaAffectedPagesItemWeakAnnotationState { + export interface Unknown { + kind: "unknown"; + } + + export interface Known { + kind: "known"; + hasAnyWeakAnnotations: boolean; + } +} diff --git a/src/api/types/DocPagesMove400Response.ts b/src/api/types/DocPagesMove400Response.ts new file mode 100644 index 0000000..7b52d97 --- /dev/null +++ b/src/api/types/DocPagesMove400Response.ts @@ -0,0 +1,36 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface DocPagesMove400Response { + name: DocPagesMove400Response.Name; + code: DocPagesMove400Response.Code; + message: string; + details?: Record | undefined; +} + +export namespace DocPagesMove400Response { + export const Name = { + EngineError: "EngineError", + } as const; + export type Name = (typeof Name)[keyof typeof Name]; + export const Code = { + Unknown: "Unknown", + InvalidArg: "InvalidArg", + DocNotOpen: "DocNotOpen", + DocOpenFailed: "DocOpenFailed", + DocPasswordRequired: "DocPasswordRequired", + DocPasswordIncorrect: "DocPasswordIncorrect", + Aborted: "Aborted", + Network: "Network", + Unauthenticated: "Unauthenticated", + Forbidden: "Forbidden", + NotFound: "NotFound", + WireFormat: "WireFormat", + RuntimeUnavailable: "RuntimeUnavailable", + InvalidReference: "InvalidReference", + WeakAnnotationSessionConflict: "WeakAnnotationSessionConflict", + LayerVersionConflict: "LayerVersionConflict", + NotImplemented: "NotImplemented", + MalformedPdf: "MalformedPdf", + } as const; + export type Code = (typeof Code)[keyof typeof Code]; +} diff --git a/src/api/types/DocPagesMove404Response.ts b/src/api/types/DocPagesMove404Response.ts new file mode 100644 index 0000000..84f5df1 --- /dev/null +++ b/src/api/types/DocPagesMove404Response.ts @@ -0,0 +1,36 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface DocPagesMove404Response { + name: DocPagesMove404Response.Name; + code: DocPagesMove404Response.Code; + message: string; + details?: Record | undefined; +} + +export namespace DocPagesMove404Response { + export const Name = { + EngineError: "EngineError", + } as const; + export type Name = (typeof Name)[keyof typeof Name]; + export const Code = { + Unknown: "Unknown", + InvalidArg: "InvalidArg", + DocNotOpen: "DocNotOpen", + DocOpenFailed: "DocOpenFailed", + DocPasswordRequired: "DocPasswordRequired", + DocPasswordIncorrect: "DocPasswordIncorrect", + Aborted: "Aborted", + Network: "Network", + Unauthenticated: "Unauthenticated", + Forbidden: "Forbidden", + NotFound: "NotFound", + WireFormat: "WireFormat", + RuntimeUnavailable: "RuntimeUnavailable", + InvalidReference: "InvalidReference", + WeakAnnotationSessionConflict: "WeakAnnotationSessionConflict", + LayerVersionConflict: "LayerVersionConflict", + NotImplemented: "NotImplemented", + MalformedPdf: "MalformedPdf", + } as const; + export type Code = (typeof Code)[keyof typeof Code]; +} diff --git a/src/api/types/DocPagesMoveRequest.ts b/src/api/types/DocPagesMoveRequest.ts new file mode 100644 index 0000000..3adc7c9 --- /dev/null +++ b/src/api/types/DocPagesMoveRequest.ts @@ -0,0 +1,3 @@ +// This file was auto-generated by Fern from our API Definition. + +export type DocPagesMoveRequest = Record; diff --git a/src/api/types/DocPagesRotate200Response.ts b/src/api/types/DocPagesRotate200Response.ts new file mode 100644 index 0000000..6bb2935 --- /dev/null +++ b/src/api/types/DocPagesRotate200Response.ts @@ -0,0 +1,60 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export interface DocPagesRotate200Response { + meta: DocPagesRotate200Response.Meta; + /** Accepts any additional properties */ + [key: string]: any; +} + +export namespace DocPagesRotate200Response { + export interface Meta { + affectedPages: Meta.AffectedPages.Item[]; + cacheDelta: Meta.CacheDelta | null; + } + + export namespace Meta { + export type AffectedPages = AffectedPages.Item[]; + + export namespace AffectedPages { + export interface Item { + pageObjectNumber: number; + revision: Item.Revision; + weakAnnotationState: CloudpdfApi.DocPagesRotate200ResponseMetaAffectedPagesItemWeakAnnotationState; + } + + export namespace Item { + export interface Revision { + docSessionId: string; + pageObjectNumber: number; + generation: number; + } + } + } + + export interface CacheDelta { + previousDocVersion: number; + docVersion: number; + pages: CacheDelta.Pages.Item[]; + } + + export namespace CacheDelta { + export type Pages = Pages.Item[]; + + export namespace Pages { + export interface Item { + pageObjectNumber: number; + cache: Item.Cache; + } + + export namespace Item { + export interface Cache { + contentVersion: number; + annotationVersion: number; + } + } + } + } + } +} diff --git a/src/api/types/DocPagesRotate200ResponseMetaAffectedPagesItemWeakAnnotationState.ts b/src/api/types/DocPagesRotate200ResponseMetaAffectedPagesItemWeakAnnotationState.ts new file mode 100644 index 0000000..56c2ade --- /dev/null +++ b/src/api/types/DocPagesRotate200ResponseMetaAffectedPagesItemWeakAnnotationState.ts @@ -0,0 +1,18 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocPagesRotate200ResponseMetaAffectedPagesItemWeakAnnotationState = + | CloudpdfApi.DocPagesRotate200ResponseMetaAffectedPagesItemWeakAnnotationState.Unknown + | CloudpdfApi.DocPagesRotate200ResponseMetaAffectedPagesItemWeakAnnotationState.Known; + +export namespace DocPagesRotate200ResponseMetaAffectedPagesItemWeakAnnotationState { + export interface Unknown { + kind: "unknown"; + } + + export interface Known { + kind: "known"; + hasAnyWeakAnnotations: boolean; + } +} diff --git a/src/api/types/DocPagesRotate400Response.ts b/src/api/types/DocPagesRotate400Response.ts new file mode 100644 index 0000000..4da4ec2 --- /dev/null +++ b/src/api/types/DocPagesRotate400Response.ts @@ -0,0 +1,36 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface DocPagesRotate400Response { + name: DocPagesRotate400Response.Name; + code: DocPagesRotate400Response.Code; + message: string; + details?: Record | undefined; +} + +export namespace DocPagesRotate400Response { + export const Name = { + EngineError: "EngineError", + } as const; + export type Name = (typeof Name)[keyof typeof Name]; + export const Code = { + Unknown: "Unknown", + InvalidArg: "InvalidArg", + DocNotOpen: "DocNotOpen", + DocOpenFailed: "DocOpenFailed", + DocPasswordRequired: "DocPasswordRequired", + DocPasswordIncorrect: "DocPasswordIncorrect", + Aborted: "Aborted", + Network: "Network", + Unauthenticated: "Unauthenticated", + Forbidden: "Forbidden", + NotFound: "NotFound", + WireFormat: "WireFormat", + RuntimeUnavailable: "RuntimeUnavailable", + InvalidReference: "InvalidReference", + WeakAnnotationSessionConflict: "WeakAnnotationSessionConflict", + LayerVersionConflict: "LayerVersionConflict", + NotImplemented: "NotImplemented", + MalformedPdf: "MalformedPdf", + } as const; + export type Code = (typeof Code)[keyof typeof Code]; +} diff --git a/src/api/types/DocPagesRotate404Response.ts b/src/api/types/DocPagesRotate404Response.ts new file mode 100644 index 0000000..901120c --- /dev/null +++ b/src/api/types/DocPagesRotate404Response.ts @@ -0,0 +1,36 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface DocPagesRotate404Response { + name: DocPagesRotate404Response.Name; + code: DocPagesRotate404Response.Code; + message: string; + details?: Record | undefined; +} + +export namespace DocPagesRotate404Response { + export const Name = { + EngineError: "EngineError", + } as const; + export type Name = (typeof Name)[keyof typeof Name]; + export const Code = { + Unknown: "Unknown", + InvalidArg: "InvalidArg", + DocNotOpen: "DocNotOpen", + DocOpenFailed: "DocOpenFailed", + DocPasswordRequired: "DocPasswordRequired", + DocPasswordIncorrect: "DocPasswordIncorrect", + Aborted: "Aborted", + Network: "Network", + Unauthenticated: "Unauthenticated", + Forbidden: "Forbidden", + NotFound: "NotFound", + WireFormat: "WireFormat", + RuntimeUnavailable: "RuntimeUnavailable", + InvalidReference: "InvalidReference", + WeakAnnotationSessionConflict: "WeakAnnotationSessionConflict", + LayerVersionConflict: "LayerVersionConflict", + NotImplemented: "NotImplemented", + MalformedPdf: "MalformedPdf", + } as const; + export type Code = (typeof Code)[keyof typeof Code]; +} diff --git a/src/api/types/DocPagesRotateRequest.ts b/src/api/types/DocPagesRotateRequest.ts new file mode 100644 index 0000000..2a6aaa9 --- /dev/null +++ b/src/api/types/DocPagesRotateRequest.ts @@ -0,0 +1,3 @@ +// This file was auto-generated by Fern from our API Definition. + +export type DocPagesRotateRequest = Record; diff --git a/src/api/types/DocRedactionsApply200Response.ts b/src/api/types/DocRedactionsApply200Response.ts new file mode 100644 index 0000000..b34df98 --- /dev/null +++ b/src/api/types/DocRedactionsApply200Response.ts @@ -0,0 +1,60 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export interface DocRedactionsApply200Response { + meta: DocRedactionsApply200Response.Meta; + /** Accepts any additional properties */ + [key: string]: any; +} + +export namespace DocRedactionsApply200Response { + export interface Meta { + affectedPages: Meta.AffectedPages.Item[]; + cacheDelta: Meta.CacheDelta | null; + } + + export namespace Meta { + export type AffectedPages = AffectedPages.Item[]; + + export namespace AffectedPages { + export interface Item { + pageObjectNumber: number; + revision: Item.Revision; + weakAnnotationState: CloudpdfApi.DocRedactionsApply200ResponseMetaAffectedPagesItemWeakAnnotationState; + } + + export namespace Item { + export interface Revision { + docSessionId: string; + pageObjectNumber: number; + generation: number; + } + } + } + + export interface CacheDelta { + previousDocVersion: number; + docVersion: number; + pages: CacheDelta.Pages.Item[]; + } + + export namespace CacheDelta { + export type Pages = Pages.Item[]; + + export namespace Pages { + export interface Item { + pageObjectNumber: number; + cache: Item.Cache; + } + + export namespace Item { + export interface Cache { + contentVersion: number; + annotationVersion: number; + } + } + } + } + } +} diff --git a/src/api/types/DocRedactionsApply200ResponseMetaAffectedPagesItemWeakAnnotationState.ts b/src/api/types/DocRedactionsApply200ResponseMetaAffectedPagesItemWeakAnnotationState.ts new file mode 100644 index 0000000..1c2ce17 --- /dev/null +++ b/src/api/types/DocRedactionsApply200ResponseMetaAffectedPagesItemWeakAnnotationState.ts @@ -0,0 +1,18 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocRedactionsApply200ResponseMetaAffectedPagesItemWeakAnnotationState = + | CloudpdfApi.DocRedactionsApply200ResponseMetaAffectedPagesItemWeakAnnotationState.Unknown + | CloudpdfApi.DocRedactionsApply200ResponseMetaAffectedPagesItemWeakAnnotationState.Known; + +export namespace DocRedactionsApply200ResponseMetaAffectedPagesItemWeakAnnotationState { + export interface Unknown { + kind: "unknown"; + } + + export interface Known { + kind: "known"; + hasAnyWeakAnnotations: boolean; + } +} diff --git a/src/api/types/DocRedactionsApply400Response.ts b/src/api/types/DocRedactionsApply400Response.ts new file mode 100644 index 0000000..89c9b37 --- /dev/null +++ b/src/api/types/DocRedactionsApply400Response.ts @@ -0,0 +1,36 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface DocRedactionsApply400Response { + name: DocRedactionsApply400Response.Name; + code: DocRedactionsApply400Response.Code; + message: string; + details?: Record | undefined; +} + +export namespace DocRedactionsApply400Response { + export const Name = { + EngineError: "EngineError", + } as const; + export type Name = (typeof Name)[keyof typeof Name]; + export const Code = { + Unknown: "Unknown", + InvalidArg: "InvalidArg", + DocNotOpen: "DocNotOpen", + DocOpenFailed: "DocOpenFailed", + DocPasswordRequired: "DocPasswordRequired", + DocPasswordIncorrect: "DocPasswordIncorrect", + Aborted: "Aborted", + Network: "Network", + Unauthenticated: "Unauthenticated", + Forbidden: "Forbidden", + NotFound: "NotFound", + WireFormat: "WireFormat", + RuntimeUnavailable: "RuntimeUnavailable", + InvalidReference: "InvalidReference", + WeakAnnotationSessionConflict: "WeakAnnotationSessionConflict", + LayerVersionConflict: "LayerVersionConflict", + NotImplemented: "NotImplemented", + MalformedPdf: "MalformedPdf", + } as const; + export type Code = (typeof Code)[keyof typeof Code]; +} diff --git a/src/api/types/DocRedactionsApply404Response.ts b/src/api/types/DocRedactionsApply404Response.ts new file mode 100644 index 0000000..e7cdde6 --- /dev/null +++ b/src/api/types/DocRedactionsApply404Response.ts @@ -0,0 +1,36 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface DocRedactionsApply404Response { + name: DocRedactionsApply404Response.Name; + code: DocRedactionsApply404Response.Code; + message: string; + details?: Record | undefined; +} + +export namespace DocRedactionsApply404Response { + export const Name = { + EngineError: "EngineError", + } as const; + export type Name = (typeof Name)[keyof typeof Name]; + export const Code = { + Unknown: "Unknown", + InvalidArg: "InvalidArg", + DocNotOpen: "DocNotOpen", + DocOpenFailed: "DocOpenFailed", + DocPasswordRequired: "DocPasswordRequired", + DocPasswordIncorrect: "DocPasswordIncorrect", + Aborted: "Aborted", + Network: "Network", + Unauthenticated: "Unauthenticated", + Forbidden: "Forbidden", + NotFound: "NotFound", + WireFormat: "WireFormat", + RuntimeUnavailable: "RuntimeUnavailable", + InvalidReference: "InvalidReference", + WeakAnnotationSessionConflict: "WeakAnnotationSessionConflict", + LayerVersionConflict: "LayerVersionConflict", + NotImplemented: "NotImplemented", + MalformedPdf: "MalformedPdf", + } as const; + export type Code = (typeof Code)[keyof typeof Code]; +} diff --git a/src/api/types/DocRedactionsApplyRequest.ts b/src/api/types/DocRedactionsApplyRequest.ts new file mode 100644 index 0000000..f16f74c --- /dev/null +++ b/src/api/types/DocRedactionsApplyRequest.ts @@ -0,0 +1,3 @@ +// This file was auto-generated by Fern from our API Definition. + +export type DocRedactionsApplyRequest = Record; diff --git a/src/api/types/DocRenderResponse.ts b/src/api/types/DocRenderResponse.ts new file mode 100644 index 0000000..25f82ea --- /dev/null +++ b/src/api/types/DocRenderResponse.ts @@ -0,0 +1,36 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface DocRenderResponse { + name: DocRenderResponse.Name; + code: DocRenderResponse.Code; + message: string; + details?: Record | undefined; +} + +export namespace DocRenderResponse { + export const Name = { + EngineError: "EngineError", + } as const; + export type Name = (typeof Name)[keyof typeof Name]; + export const Code = { + Unknown: "Unknown", + InvalidArg: "InvalidArg", + DocNotOpen: "DocNotOpen", + DocOpenFailed: "DocOpenFailed", + DocPasswordRequired: "DocPasswordRequired", + DocPasswordIncorrect: "DocPasswordIncorrect", + Aborted: "Aborted", + Network: "Network", + Unauthenticated: "Unauthenticated", + Forbidden: "Forbidden", + NotFound: "NotFound", + WireFormat: "WireFormat", + RuntimeUnavailable: "RuntimeUnavailable", + InvalidReference: "InvalidReference", + WeakAnnotationSessionConflict: "WeakAnnotationSessionConflict", + LayerVersionConflict: "LayerVersionConflict", + NotImplemented: "NotImplemented", + MalformedPdf: "MalformedPdf", + } as const; + export type Code = (typeof Code)[keyof typeof Code]; +} diff --git a/src/api/types/DocText200Response.ts b/src/api/types/DocText200Response.ts new file mode 100644 index 0000000..b017f8d --- /dev/null +++ b/src/api/types/DocText200Response.ts @@ -0,0 +1,6 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface DocText200Response { + text: string; + charCount: number; +} diff --git a/src/api/types/DocText404Response.ts b/src/api/types/DocText404Response.ts new file mode 100644 index 0000000..bd1b9a9 --- /dev/null +++ b/src/api/types/DocText404Response.ts @@ -0,0 +1,36 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface DocText404Response { + name: DocText404Response.Name; + code: DocText404Response.Code; + message: string; + details?: Record | undefined; +} + +export namespace DocText404Response { + export const Name = { + EngineError: "EngineError", + } as const; + export type Name = (typeof Name)[keyof typeof Name]; + export const Code = { + Unknown: "Unknown", + InvalidArg: "InvalidArg", + DocNotOpen: "DocNotOpen", + DocOpenFailed: "DocOpenFailed", + DocPasswordRequired: "DocPasswordRequired", + DocPasswordIncorrect: "DocPasswordIncorrect", + Aborted: "Aborted", + Network: "Network", + Unauthenticated: "Unauthenticated", + Forbidden: "Forbidden", + NotFound: "NotFound", + WireFormat: "WireFormat", + RuntimeUnavailable: "RuntimeUnavailable", + InvalidReference: "InvalidReference", + WeakAnnotationSessionConflict: "WeakAnnotationSessionConflict", + LayerVersionConflict: "LayerVersionConflict", + NotImplemented: "NotImplemented", + MalformedPdf: "MalformedPdf", + } as const; + export type Code = (typeof Code)[keyof typeof Code]; +} diff --git a/src/api/types/DocumentsCommit200Response.ts b/src/api/types/DocumentsCommit200Response.ts new file mode 100644 index 0000000..e2d62dd --- /dev/null +++ b/src/api/types/DocumentsCommit200Response.ts @@ -0,0 +1,40 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface DocumentsCommit200Response { + document: DocumentsCommit200Response.Document; +} + +export namespace DocumentsCommit200Response { + export interface Document { + id: string; + tenantId: string; + state: Document.State; + baseSha: string | null; + storageSizeBytes: number | null; + metadata: Record | null; + idempotencyKey: string | null; + failureReason: string | null; + thumbnailState?: Document.ThumbnailState | undefined; + thumbnailUrl?: (string | null) | undefined; + createdAt: number; + updatedAt: number; + createdBy: string | null; + } + + export namespace Document { + export const State = { + Pending: "pending", + Ready: "ready", + Failed: "failed", + Deleting: "deleting", + } as const; + export type State = (typeof State)[keyof typeof State]; + export const ThumbnailState = { + Pending: "pending", + Ready: "ready", + Locked: "locked", + Failed: "failed", + } as const; + export type ThumbnailState = (typeof ThumbnailState)[keyof typeof ThumbnailState]; + } +} diff --git a/src/api/types/DocumentsCommit400Response.ts b/src/api/types/DocumentsCommit400Response.ts new file mode 100644 index 0000000..610a818 --- /dev/null +++ b/src/api/types/DocumentsCommit400Response.ts @@ -0,0 +1,12 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface DocumentsCommit400Response { + error: DocumentsCommit400Response.Error_; +} + +export namespace DocumentsCommit400Response { + export interface Error_ { + code: string; + message: string; + } +} diff --git a/src/api/types/DocumentsCommit404Response.ts b/src/api/types/DocumentsCommit404Response.ts new file mode 100644 index 0000000..04e05e0 --- /dev/null +++ b/src/api/types/DocumentsCommit404Response.ts @@ -0,0 +1,12 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface DocumentsCommit404Response { + error: DocumentsCommit404Response.Error_; +} + +export namespace DocumentsCommit404Response { + export interface Error_ { + code: string; + message: string; + } +} diff --git a/src/api/types/DocumentsDelete403Response.ts b/src/api/types/DocumentsDelete403Response.ts new file mode 100644 index 0000000..bde83e3 --- /dev/null +++ b/src/api/types/DocumentsDelete403Response.ts @@ -0,0 +1,12 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface DocumentsDelete403Response { + error: DocumentsDelete403Response.Error_; +} + +export namespace DocumentsDelete403Response { + export interface Error_ { + code: string; + message: string; + } +} diff --git a/src/api/types/DocumentsDelete404Response.ts b/src/api/types/DocumentsDelete404Response.ts new file mode 100644 index 0000000..3477e02 --- /dev/null +++ b/src/api/types/DocumentsDelete404Response.ts @@ -0,0 +1,12 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface DocumentsDelete404Response { + error: DocumentsDelete404Response.Error_; +} + +export namespace DocumentsDelete404Response { + export interface Error_ { + code: string; + message: string; + } +} diff --git a/src/api/types/DocumentsDownload403Response.ts b/src/api/types/DocumentsDownload403Response.ts new file mode 100644 index 0000000..6096a1f --- /dev/null +++ b/src/api/types/DocumentsDownload403Response.ts @@ -0,0 +1,12 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface DocumentsDownload403Response { + error: DocumentsDownload403Response.Error_; +} + +export namespace DocumentsDownload403Response { + export interface Error_ { + code: string; + message: string; + } +} diff --git a/src/api/types/DocumentsDownload404Response.ts b/src/api/types/DocumentsDownload404Response.ts new file mode 100644 index 0000000..0991501 --- /dev/null +++ b/src/api/types/DocumentsDownload404Response.ts @@ -0,0 +1,12 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface DocumentsDownload404Response { + error: DocumentsDownload404Response.Error_; +} + +export namespace DocumentsDownload404Response { + export interface Error_ { + code: string; + message: string; + } +} diff --git a/src/api/types/DocumentsGet200Response.ts b/src/api/types/DocumentsGet200Response.ts new file mode 100644 index 0000000..b5cacb5 --- /dev/null +++ b/src/api/types/DocumentsGet200Response.ts @@ -0,0 +1,40 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface DocumentsGet200Response { + document: DocumentsGet200Response.Document; +} + +export namespace DocumentsGet200Response { + export interface Document { + id: string; + tenantId: string; + state: Document.State; + baseSha: string | null; + storageSizeBytes: number | null; + metadata: Record | null; + idempotencyKey: string | null; + failureReason: string | null; + thumbnailState?: Document.ThumbnailState | undefined; + thumbnailUrl?: (string | null) | undefined; + createdAt: number; + updatedAt: number; + createdBy: string | null; + } + + export namespace Document { + export const State = { + Pending: "pending", + Ready: "ready", + Failed: "failed", + Deleting: "deleting", + } as const; + export type State = (typeof State)[keyof typeof State]; + export const ThumbnailState = { + Pending: "pending", + Ready: "ready", + Locked: "locked", + Failed: "failed", + } as const; + export type ThumbnailState = (typeof ThumbnailState)[keyof typeof ThumbnailState]; + } +} diff --git a/src/api/types/DocumentsGet403Response.ts b/src/api/types/DocumentsGet403Response.ts new file mode 100644 index 0000000..7cfb4eb --- /dev/null +++ b/src/api/types/DocumentsGet403Response.ts @@ -0,0 +1,12 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface DocumentsGet403Response { + error: DocumentsGet403Response.Error_; +} + +export namespace DocumentsGet403Response { + export interface Error_ { + code: string; + message: string; + } +} diff --git a/src/api/types/DocumentsGet404Response.ts b/src/api/types/DocumentsGet404Response.ts new file mode 100644 index 0000000..a3f186a --- /dev/null +++ b/src/api/types/DocumentsGet404Response.ts @@ -0,0 +1,12 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface DocumentsGet404Response { + error: DocumentsGet404Response.Error_; +} + +export namespace DocumentsGet404Response { + export interface Error_ { + code: string; + message: string; + } +} diff --git a/src/api/types/DocumentsInit200Response.ts b/src/api/types/DocumentsInit200Response.ts new file mode 100644 index 0000000..5325ef6 --- /dev/null +++ b/src/api/types/DocumentsInit200Response.ts @@ -0,0 +1,132 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocumentsInit200Response = + | CloudpdfApi.DocumentsInit200Response.Created + | CloudpdfApi.DocumentsInit200Response.Resumed + | CloudpdfApi.DocumentsInit200Response.Deduped; + +export namespace DocumentsInit200Response { + export interface Created { + tag: "created"; + document: DocumentsInit200ResponseCreated.Document; + upload: CloudpdfApi.DocumentsInit200ResponseCreatedUpload; + } + + export namespace DocumentsInit200ResponseCreated { + export interface Document { + id: string; + tenantId: string; + state: Document.State; + baseSha: string | null; + storageSizeBytes: number | null; + metadata: Record | null; + idempotencyKey: string | null; + failureReason: string | null; + thumbnailState?: Document.ThumbnailState | undefined; + thumbnailUrl?: (string | null) | undefined; + createdAt: number; + updatedAt: number; + createdBy: string | null; + } + + export namespace Document { + export const State = { + Pending: "pending", + Ready: "ready", + Failed: "failed", + Deleting: "deleting", + } as const; + export type State = (typeof State)[keyof typeof State]; + export const ThumbnailState = { + Pending: "pending", + Ready: "ready", + Locked: "locked", + Failed: "failed", + } as const; + export type ThumbnailState = (typeof ThumbnailState)[keyof typeof ThumbnailState]; + } + } + + export interface Resumed { + tag: "resumed"; + document: DocumentsInit200ResponseResumed.Document; + upload: CloudpdfApi.DocumentsInit200ResponseResumedUpload; + } + + export namespace DocumentsInit200ResponseResumed { + export interface Document { + id: string; + tenantId: string; + state: Document.State; + baseSha: string | null; + storageSizeBytes: number | null; + metadata: Record | null; + idempotencyKey: string | null; + failureReason: string | null; + thumbnailState?: Document.ThumbnailState | undefined; + thumbnailUrl?: (string | null) | undefined; + createdAt: number; + updatedAt: number; + createdBy: string | null; + } + + export namespace Document { + export const State = { + Pending: "pending", + Ready: "ready", + Failed: "failed", + Deleting: "deleting", + } as const; + export type State = (typeof State)[keyof typeof State]; + export const ThumbnailState = { + Pending: "pending", + Ready: "ready", + Locked: "locked", + Failed: "failed", + } as const; + export type ThumbnailState = (typeof ThumbnailState)[keyof typeof ThumbnailState]; + } + } + + export interface Deduped { + tag: "deduped"; + document: DocumentsInit200ResponseDeduped.Document; + } + + export namespace DocumentsInit200ResponseDeduped { + export interface Document { + id: string; + tenantId: string; + state: Document.State; + baseSha: string | null; + storageSizeBytes: number | null; + metadata: Record | null; + idempotencyKey: string | null; + failureReason: string | null; + thumbnailState?: Document.ThumbnailState | undefined; + thumbnailUrl?: (string | null) | undefined; + createdAt: number; + updatedAt: number; + createdBy: string | null; + } + + export namespace Document { + export const State = { + Pending: "pending", + Ready: "ready", + Failed: "failed", + Deleting: "deleting", + } as const; + export type State = (typeof State)[keyof typeof State]; + export const ThumbnailState = { + Pending: "pending", + Ready: "ready", + Locked: "locked", + Failed: "failed", + } as const; + export type ThumbnailState = (typeof ThumbnailState)[keyof typeof ThumbnailState]; + } + } +} diff --git a/src/api/types/DocumentsInit200ResponseCreatedUpload.ts b/src/api/types/DocumentsInit200ResponseCreatedUpload.ts new file mode 100644 index 0000000..e488092 --- /dev/null +++ b/src/api/types/DocumentsInit200ResponseCreatedUpload.ts @@ -0,0 +1,37 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocumentsInit200ResponseCreatedUpload = + | CloudpdfApi.DocumentsInit200ResponseCreatedUpload.Presigned + | CloudpdfApi.DocumentsInit200ResponseCreatedUpload.Direct; + +export namespace DocumentsInit200ResponseCreatedUpload { + export interface Presigned { + kind: "presigned"; + presigned: DocumentsInit200ResponseCreatedUploadPresigned.Presigned; + key: string; + } + + export namespace DocumentsInit200ResponseCreatedUploadPresigned { + export interface Presigned { + url: string; + headers: Record; + method: Presigned.Method; + expiresAt: number; + } + + export namespace Presigned { + export const Method = { + Put: "PUT", + } as const; + export type Method = (typeof Method)[keyof typeof Method]; + } + } + + export interface Direct { + kind: "direct"; + url: string; + key: string; + } +} diff --git a/src/api/types/DocumentsInit200ResponseResumedUpload.ts b/src/api/types/DocumentsInit200ResponseResumedUpload.ts new file mode 100644 index 0000000..3b52d53 --- /dev/null +++ b/src/api/types/DocumentsInit200ResponseResumedUpload.ts @@ -0,0 +1,37 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type DocumentsInit200ResponseResumedUpload = + | CloudpdfApi.DocumentsInit200ResponseResumedUpload.Presigned + | CloudpdfApi.DocumentsInit200ResponseResumedUpload.Direct; + +export namespace DocumentsInit200ResponseResumedUpload { + export interface Presigned { + kind: "presigned"; + presigned: DocumentsInit200ResponseResumedUploadPresigned.Presigned; + key: string; + } + + export namespace DocumentsInit200ResponseResumedUploadPresigned { + export interface Presigned { + url: string; + headers: Record; + method: Presigned.Method; + expiresAt: number; + } + + export namespace Presigned { + export const Method = { + Put: "PUT", + } as const; + export type Method = (typeof Method)[keyof typeof Method]; + } + } + + export interface Direct { + kind: "direct"; + url: string; + key: string; + } +} diff --git a/src/api/types/DocumentsInit400Response.ts b/src/api/types/DocumentsInit400Response.ts new file mode 100644 index 0000000..dc2317f --- /dev/null +++ b/src/api/types/DocumentsInit400Response.ts @@ -0,0 +1,12 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface DocumentsInit400Response { + error: DocumentsInit400Response.Error_; +} + +export namespace DocumentsInit400Response { + export interface Error_ { + code: string; + message: string; + } +} diff --git a/src/api/types/DocumentsList200Response.ts b/src/api/types/DocumentsList200Response.ts new file mode 100644 index 0000000..49e69a1 --- /dev/null +++ b/src/api/types/DocumentsList200Response.ts @@ -0,0 +1,45 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface DocumentsList200Response { + documents: DocumentsList200Response.Documents.Item[]; + nextCursor?: (string | null) | undefined; +} + +export namespace DocumentsList200Response { + export type Documents = Documents.Item[]; + + export namespace Documents { + export interface Item { + id: string; + tenantId: string; + state: Item.State; + baseSha: string | null; + storageSizeBytes: number | null; + metadata: Record | null; + idempotencyKey: string | null; + failureReason: string | null; + thumbnailState?: Item.ThumbnailState | undefined; + thumbnailUrl?: (string | null) | undefined; + createdAt: number; + updatedAt: number; + createdBy: string | null; + } + + export namespace Item { + export const State = { + Pending: "pending", + Ready: "ready", + Failed: "failed", + Deleting: "deleting", + } as const; + export type State = (typeof State)[keyof typeof State]; + export const ThumbnailState = { + Pending: "pending", + Ready: "ready", + Locked: "locked", + Failed: "failed", + } as const; + export type ThumbnailState = (typeof ThumbnailState)[keyof typeof ThumbnailState]; + } + } +} diff --git a/src/api/types/DocumentsList400Response.ts b/src/api/types/DocumentsList400Response.ts new file mode 100644 index 0000000..6a38bb3 --- /dev/null +++ b/src/api/types/DocumentsList400Response.ts @@ -0,0 +1,12 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface DocumentsList400Response { + error: DocumentsList400Response.Error_; +} + +export namespace DocumentsList400Response { + export interface Error_ { + code: string; + message: string; + } +} diff --git a/src/api/types/DocumentsThumbnailResponse.ts b/src/api/types/DocumentsThumbnailResponse.ts new file mode 100644 index 0000000..cb949c9 --- /dev/null +++ b/src/api/types/DocumentsThumbnailResponse.ts @@ -0,0 +1,13 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface DocumentsThumbnailResponse { + error: DocumentsThumbnailResponse.Error_; +} + +export namespace DocumentsThumbnailResponse { + export interface Error_ { + code: string; + message: string; + state: string; + } +} diff --git a/src/api/types/DocumentsUploadDirect200Response.ts b/src/api/types/DocumentsUploadDirect200Response.ts new file mode 100644 index 0000000..88a3b2c --- /dev/null +++ b/src/api/types/DocumentsUploadDirect200Response.ts @@ -0,0 +1,5 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface DocumentsUploadDirect200Response { + sha256: string; +} diff --git a/src/api/types/DocumentsUploadDirect400Response.ts b/src/api/types/DocumentsUploadDirect400Response.ts new file mode 100644 index 0000000..7f8602e --- /dev/null +++ b/src/api/types/DocumentsUploadDirect400Response.ts @@ -0,0 +1,12 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface DocumentsUploadDirect400Response { + error: DocumentsUploadDirect400Response.Error_; +} + +export namespace DocumentsUploadDirect400Response { + export interface Error_ { + code: string; + message: string; + } +} diff --git a/src/api/types/EngineErrorPayload.ts b/src/api/types/EngineErrorPayload.ts new file mode 100644 index 0000000..20b272e --- /dev/null +++ b/src/api/types/EngineErrorPayload.ts @@ -0,0 +1,36 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface EngineErrorPayload { + name: EngineErrorPayload.Name; + code: EngineErrorPayload.Code; + message: string; + details?: Record | undefined; +} + +export namespace EngineErrorPayload { + export const Name = { + EngineError: "EngineError", + } as const; + export type Name = (typeof Name)[keyof typeof Name]; + export const Code = { + Unknown: "Unknown", + InvalidArg: "InvalidArg", + DocNotOpen: "DocNotOpen", + DocOpenFailed: "DocOpenFailed", + DocPasswordRequired: "DocPasswordRequired", + DocPasswordIncorrect: "DocPasswordIncorrect", + Aborted: "Aborted", + Network: "Network", + Unauthenticated: "Unauthenticated", + Forbidden: "Forbidden", + NotFound: "NotFound", + WireFormat: "WireFormat", + RuntimeUnavailable: "RuntimeUnavailable", + InvalidReference: "InvalidReference", + WeakAnnotationSessionConflict: "WeakAnnotationSessionConflict", + LayerVersionConflict: "LayerVersionConflict", + NotImplemented: "NotImplemented", + MalformedPdf: "MalformedPdf", + } as const; + export type Code = (typeof Code)[keyof typeof Code]; +} diff --git a/src/api/types/TenantsCreate200Response.ts b/src/api/types/TenantsCreate200Response.ts new file mode 100644 index 0000000..da28ce5 --- /dev/null +++ b/src/api/types/TenantsCreate200Response.ts @@ -0,0 +1,15 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface TenantsCreate200Response { + tenant: TenantsCreate200Response.Tenant; + created: boolean; +} + +export namespace TenantsCreate200Response { + export interface Tenant { + id: string; + name: string; + autoProvisioned: boolean; + createdAt: number; + } +} diff --git a/src/api/types/TenantsCreate400Response.ts b/src/api/types/TenantsCreate400Response.ts new file mode 100644 index 0000000..b0f376c --- /dev/null +++ b/src/api/types/TenantsCreate400Response.ts @@ -0,0 +1,12 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface TenantsCreate400Response { + error: TenantsCreate400Response.Error_; +} + +export namespace TenantsCreate400Response { + export interface Error_ { + code: string; + message: string; + } +} diff --git a/src/api/types/TenantsDeleteResponse.ts b/src/api/types/TenantsDeleteResponse.ts new file mode 100644 index 0000000..fea4453 --- /dev/null +++ b/src/api/types/TenantsDeleteResponse.ts @@ -0,0 +1,12 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface TenantsDeleteResponse { + error: TenantsDeleteResponse.Error_; +} + +export namespace TenantsDeleteResponse { + export interface Error_ { + code: string; + message: string; + } +} diff --git a/src/api/types/TenantsGet200Response.ts b/src/api/types/TenantsGet200Response.ts new file mode 100644 index 0000000..645a69e --- /dev/null +++ b/src/api/types/TenantsGet200Response.ts @@ -0,0 +1,14 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface TenantsGet200Response { + tenant: TenantsGet200Response.Tenant; +} + +export namespace TenantsGet200Response { + export interface Tenant { + id: string; + name: string; + autoProvisioned: boolean; + createdAt: number; + } +} diff --git a/src/api/types/TenantsGet404Response.ts b/src/api/types/TenantsGet404Response.ts new file mode 100644 index 0000000..c894c33 --- /dev/null +++ b/src/api/types/TenantsGet404Response.ts @@ -0,0 +1,12 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface TenantsGet404Response { + error: TenantsGet404Response.Error_; +} + +export namespace TenantsGet404Response { + export interface Error_ { + code: string; + message: string; + } +} diff --git a/src/api/types/TenantsList200Response.ts b/src/api/types/TenantsList200Response.ts new file mode 100644 index 0000000..edc38b7 --- /dev/null +++ b/src/api/types/TenantsList200Response.ts @@ -0,0 +1,19 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface TenantsList200Response { + tenants: TenantsList200Response.Tenants.Item[]; + nextCursor?: (string | null) | undefined; +} + +export namespace TenantsList200Response { + export type Tenants = Tenants.Item[]; + + export namespace Tenants { + export interface Item { + id: string; + name: string; + autoProvisioned: boolean; + createdAt: number; + } + } +} diff --git a/src/api/types/TenantsList400Response.ts b/src/api/types/TenantsList400Response.ts new file mode 100644 index 0000000..ed67efa --- /dev/null +++ b/src/api/types/TenantsList400Response.ts @@ -0,0 +1,12 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface TenantsList400Response { + error: TenantsList400Response.Error_; +} + +export namespace TenantsList400Response { + export interface Error_ { + code: string; + message: string; + } +} diff --git a/src/api/types/TokensIssue200Response.ts b/src/api/types/TokensIssue200Response.ts new file mode 100644 index 0000000..a3bd7b8 --- /dev/null +++ b/src/api/types/TokensIssue200Response.ts @@ -0,0 +1,7 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface TokensIssue200Response { + token: string; + jti: string; + expiresAt: number; +} diff --git a/src/api/types/TokensIssue400Response.ts b/src/api/types/TokensIssue400Response.ts new file mode 100644 index 0000000..c057050 --- /dev/null +++ b/src/api/types/TokensIssue400Response.ts @@ -0,0 +1,12 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface TokensIssue400Response { + error: TokensIssue400Response.Error_; +} + +export namespace TokensIssue400Response { + export interface Error_ { + code: string; + message: string; + } +} diff --git a/src/api/types/TokensIssue403Response.ts b/src/api/types/TokensIssue403Response.ts new file mode 100644 index 0000000..f61a95d --- /dev/null +++ b/src/api/types/TokensIssue403Response.ts @@ -0,0 +1,12 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface TokensIssue403Response { + error: TokensIssue403Response.Error_; +} + +export namespace TokensIssue403Response { + export interface Error_ { + code: string; + message: string; + } +} diff --git a/src/api/types/TokensIssue404Response.ts b/src/api/types/TokensIssue404Response.ts new file mode 100644 index 0000000..6dc1c33 --- /dev/null +++ b/src/api/types/TokensIssue404Response.ts @@ -0,0 +1,12 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface TokensIssue404Response { + error: TokensIssue404Response.Error_; +} + +export namespace TokensIssue404Response { + export interface Error_ { + code: string; + message: string; + } +} diff --git a/src/api/types/TokensIssueRequest.ts b/src/api/types/TokensIssueRequest.ts new file mode 100644 index 0000000..d20dab3 --- /dev/null +++ b/src/api/types/TokensIssueRequest.ts @@ -0,0 +1,37 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as CloudpdfApi from "../index.js"; + +export type TokensIssueRequest = CloudpdfApi.TokensIssueRequest.Doc | CloudpdfApi.TokensIssueRequest.Tenant; + +export namespace TokensIssueRequest { + export interface Doc { + kind: "doc"; + sub: string; + docId: string; + layerName?: string | undefined; + scope: string[]; + userId?: string | undefined; + displayName?: string | undefined; + groupId?: string | undefined; + groups?: string[] | undefined; + expiresIn: number; + } + + export interface Tenant { + kind: "tenant"; + sub: string; + scope: TokensIssueRequestTenant.Scope.Item[]; + expiresIn: number; + } + + export namespace TokensIssueRequestTenant { + export type Scope = Scope.Item[]; + + export namespace Scope { + export type Item = + | "*" + | ("docs.create" | "docs.read" | "docs.delete" | "tokens.issue-doc" | "tokens.revoke"); + } + } +} diff --git a/src/api/types/TokensRevokeResponse.ts b/src/api/types/TokensRevokeResponse.ts new file mode 100644 index 0000000..9c19802 --- /dev/null +++ b/src/api/types/TokensRevokeResponse.ts @@ -0,0 +1,12 @@ +// This file was auto-generated by Fern from our API Definition. + +export interface TokensRevokeResponse { + error: TokensRevokeResponse.Error_; +} + +export namespace TokensRevokeResponse { + export interface Error_ { + code: string; + message: string; + } +} diff --git a/src/api/types/index.ts b/src/api/types/index.ts new file mode 100644 index 0000000..6462191 --- /dev/null +++ b/src/api/types/index.ts @@ -0,0 +1,170 @@ +export * from "./AdminErrorPayload.js"; +export * from "./DeploymentLicenseStatusResponse.js"; +export * from "./DocAnnotationsCreate200Response.js"; +export * from "./DocAnnotationsCreate200ResponseMetaAffectedPagesItemWeakAnnotationState.js"; +export * from "./DocAnnotationsCreate400Response.js"; +export * from "./DocAnnotationsCreate404Response.js"; +export * from "./DocAnnotationsCreateRequest.js"; +export * from "./DocAnnotationsDelete200Response.js"; +export * from "./DocAnnotationsDelete200ResponseMetaAffectedPagesItemWeakAnnotationState.js"; +export * from "./DocAnnotationsDelete404Response.js"; +export * from "./DocAnnotationsList200Response.js"; +export * from "./DocAnnotationsList200ResponseAnnotationsItem.js"; +export * from "./DocAnnotationsList200ResponseAnnotationsItemCaretInReplyTo.js"; +export * from "./DocAnnotationsList200ResponseAnnotationsItemCaretRef.js"; +export * from "./DocAnnotationsList200ResponseAnnotationsItemCircleInReplyTo.js"; +export * from "./DocAnnotationsList200ResponseAnnotationsItemCircleRef.js"; +export * from "./DocAnnotationsList200ResponseAnnotationsItemFileAttachmentInReplyTo.js"; +export * from "./DocAnnotationsList200ResponseAnnotationsItemFileAttachmentRef.js"; +export * from "./DocAnnotationsList200ResponseAnnotationsItemFreeTextInReplyTo.js"; +export * from "./DocAnnotationsList200ResponseAnnotationsItemFreeTextRef.js"; +export * from "./DocAnnotationsList200ResponseAnnotationsItemHighlightInReplyTo.js"; +export * from "./DocAnnotationsList200ResponseAnnotationsItemHighlightRef.js"; +export * from "./DocAnnotationsList200ResponseAnnotationsItemInkInReplyTo.js"; +export * from "./DocAnnotationsList200ResponseAnnotationsItemInkRef.js"; +export * from "./DocAnnotationsList200ResponseAnnotationsItemLineInReplyTo.js"; +export * from "./DocAnnotationsList200ResponseAnnotationsItemLineRef.js"; +export * from "./DocAnnotationsList200ResponseAnnotationsItemLinkInReplyTo.js"; +export * from "./DocAnnotationsList200ResponseAnnotationsItemLinkRef.js"; +export * from "./DocAnnotationsList200ResponseAnnotationsItemLinkTarget.js"; +export * from "./DocAnnotationsList200ResponseAnnotationsItemLinkTargetGotoDestination.js"; +export * from "./DocAnnotationsList200ResponseAnnotationsItemPolygonInReplyTo.js"; +export * from "./DocAnnotationsList200ResponseAnnotationsItemPolygonRef.js"; +export * from "./DocAnnotationsList200ResponseAnnotationsItemPolylineInReplyTo.js"; +export * from "./DocAnnotationsList200ResponseAnnotationsItemPolylineRef.js"; +export * from "./DocAnnotationsList200ResponseAnnotationsItemRedactInReplyTo.js"; +export * from "./DocAnnotationsList200ResponseAnnotationsItemRedactRef.js"; +export * from "./DocAnnotationsList200ResponseAnnotationsItemSquareInReplyTo.js"; +export * from "./DocAnnotationsList200ResponseAnnotationsItemSquareRef.js"; +export * from "./DocAnnotationsList200ResponseAnnotationsItemSquigglyInReplyTo.js"; +export * from "./DocAnnotationsList200ResponseAnnotationsItemSquigglyRef.js"; +export * from "./DocAnnotationsList200ResponseAnnotationsItemStampInReplyTo.js"; +export * from "./DocAnnotationsList200ResponseAnnotationsItemStampRef.js"; +export * from "./DocAnnotationsList200ResponseAnnotationsItemStrikeoutInReplyTo.js"; +export * from "./DocAnnotationsList200ResponseAnnotationsItemStrikeoutRef.js"; +export * from "./DocAnnotationsList200ResponseAnnotationsItemTextInReplyTo.js"; +export * from "./DocAnnotationsList200ResponseAnnotationsItemTextRef.js"; +export * from "./DocAnnotationsList200ResponseAnnotationsItemUnderlineInReplyTo.js"; +export * from "./DocAnnotationsList200ResponseAnnotationsItemUnderlineRef.js"; +export * from "./DocAnnotationsList200ResponseAnnotationsItemUnsupportedInReplyTo.js"; +export * from "./DocAnnotationsList200ResponseAnnotationsItemUnsupportedRef.js"; +export * from "./DocAnnotationsList200ResponseAnnotationsItemWidgetInReplyTo.js"; +export * from "./DocAnnotationsList200ResponseAnnotationsItemWidgetRef.js"; +export * from "./DocAnnotationsList200ResponsePageStateWeakAnnotationState.js"; +export * from "./DocAnnotationsList404Response.js"; +export * from "./DocAnnotationsUpdate200Response.js"; +export * from "./DocAnnotationsUpdate200ResponseMetaAffectedPagesItemWeakAnnotationState.js"; +export * from "./DocAnnotationsUpdate400Response.js"; +export * from "./DocAnnotationsUpdate404Response.js"; +export * from "./DocAnnotationsUpdateRequest.js"; +export * from "./DocDownloadResponse.js"; +export * from "./DocFormsExportDataResponse.js"; +export * from "./DocFormsGet200Response.js"; +export * from "./DocFormsGet200ResponseCalculationOrderItem.js"; +export * from "./DocFormsGet200ResponseFieldsItem.js"; +export * from "./DocFormsGet200ResponseFieldsItemCheckboxDefaultValueEntry.js"; +export * from "./DocFormsGet200ResponseFieldsItemCheckboxRef.js"; +export * from "./DocFormsGet200ResponseFieldsItemCheckboxValueEntry.js"; +export * from "./DocFormsGet200ResponseFieldsItemComboboxDefaultValueEntry.js"; +export * from "./DocFormsGet200ResponseFieldsItemComboboxRef.js"; +export * from "./DocFormsGet200ResponseFieldsItemComboboxValueEntry.js"; +export * from "./DocFormsGet200ResponseFieldsItemListboxDefaultValueEntry.js"; +export * from "./DocFormsGet200ResponseFieldsItemListboxRef.js"; +export * from "./DocFormsGet200ResponseFieldsItemListboxValueEntry.js"; +export * from "./DocFormsGet200ResponseFieldsItemPushbuttonDefaultValueEntry.js"; +export * from "./DocFormsGet200ResponseFieldsItemPushbuttonRef.js"; +export * from "./DocFormsGet200ResponseFieldsItemPushbuttonValueEntry.js"; +export * from "./DocFormsGet200ResponseFieldsItemRadioDefaultValueEntry.js"; +export * from "./DocFormsGet200ResponseFieldsItemRadioRef.js"; +export * from "./DocFormsGet200ResponseFieldsItemRadioValueEntry.js"; +export * from "./DocFormsGet200ResponseFieldsItemSignatureDefaultValueEntry.js"; +export * from "./DocFormsGet200ResponseFieldsItemSignatureRef.js"; +export * from "./DocFormsGet200ResponseFieldsItemSignatureValueEntry.js"; +export * from "./DocFormsGet200ResponseFieldsItemTextDefaultValueEntry.js"; +export * from "./DocFormsGet200ResponseFieldsItemTextRef.js"; +export * from "./DocFormsGet200ResponseFieldsItemTextValueEntry.js"; +export * from "./DocFormsGet200ResponseFieldsItemUnknownDefaultValueEntry.js"; +export * from "./DocFormsGet200ResponseFieldsItemUnknownRef.js"; +export * from "./DocFormsGet200ResponseFieldsItemUnknownValueEntry.js"; +export * from "./DocFormsGet404Response.js"; +export * from "./DocFormsImportData200Response.js"; +export * from "./DocFormsImportData200ResponseMetaAffectedPagesItemWeakAnnotationState.js"; +export * from "./DocFormsImportData400Response.js"; +export * from "./DocFormsImportData404Response.js"; +export * from "./DocFormsImportDataRequest.js"; +export * from "./DocFormsReset200Response.js"; +export * from "./DocFormsReset200ResponseMetaAffectedPagesItemWeakAnnotationState.js"; +export * from "./DocFormsReset404Response.js"; +export * from "./DocFormsSetValue200Response.js"; +export * from "./DocFormsSetValue200ResponseMetaAffectedPagesItemWeakAnnotationState.js"; +export * from "./DocFormsSetValue400Response.js"; +export * from "./DocFormsSetValue404Response.js"; +export * from "./DocFormsSetValueRequest.js"; +export * from "./DocHead200Response.js"; +export * from "./DocHead404Response.js"; +export * from "./DocManifest200Response.js"; +export * from "./DocManifest200ResponsePagesItemStateWeakAnnotationState.js"; +export * from "./DocManifest404Response.js"; +export * from "./DocMetadataGet200Response.js"; +export * from "./DocMetadataGet404Response.js"; +export * from "./DocPagesDelete200Response.js"; +export * from "./DocPagesDelete200ResponseMetaAffectedPagesItemWeakAnnotationState.js"; +export * from "./DocPagesDelete400Response.js"; +export * from "./DocPagesDelete404Response.js"; +export * from "./DocPagesDeleteRequest.js"; +export * from "./DocPagesFlatten200Response.js"; +export * from "./DocPagesFlatten200ResponseMetaAffectedPagesItemWeakAnnotationState.js"; +export * from "./DocPagesFlatten400Response.js"; +export * from "./DocPagesFlatten404Response.js"; +export * from "./DocPagesFlattenRequest.js"; +export * from "./DocPagesMove200Response.js"; +export * from "./DocPagesMove200ResponseMetaAffectedPagesItemWeakAnnotationState.js"; +export * from "./DocPagesMove400Response.js"; +export * from "./DocPagesMove404Response.js"; +export * from "./DocPagesMoveRequest.js"; +export * from "./DocPagesRotate200Response.js"; +export * from "./DocPagesRotate200ResponseMetaAffectedPagesItemWeakAnnotationState.js"; +export * from "./DocPagesRotate400Response.js"; +export * from "./DocPagesRotate404Response.js"; +export * from "./DocPagesRotateRequest.js"; +export * from "./DocRedactionsApply200Response.js"; +export * from "./DocRedactionsApply200ResponseMetaAffectedPagesItemWeakAnnotationState.js"; +export * from "./DocRedactionsApply400Response.js"; +export * from "./DocRedactionsApply404Response.js"; +export * from "./DocRedactionsApplyRequest.js"; +export * from "./DocRenderResponse.js"; +export * from "./DocText200Response.js"; +export * from "./DocText404Response.js"; +export * from "./DocumentsCommit200Response.js"; +export * from "./DocumentsCommit400Response.js"; +export * from "./DocumentsCommit404Response.js"; +export * from "./DocumentsDelete403Response.js"; +export * from "./DocumentsDelete404Response.js"; +export * from "./DocumentsDownload403Response.js"; +export * from "./DocumentsDownload404Response.js"; +export * from "./DocumentsGet200Response.js"; +export * from "./DocumentsGet403Response.js"; +export * from "./DocumentsGet404Response.js"; +export * from "./DocumentsInit200Response.js"; +export * from "./DocumentsInit200ResponseCreatedUpload.js"; +export * from "./DocumentsInit200ResponseResumedUpload.js"; +export * from "./DocumentsInit400Response.js"; +export * from "./DocumentsList200Response.js"; +export * from "./DocumentsList400Response.js"; +export * from "./DocumentsThumbnailResponse.js"; +export * from "./DocumentsUploadDirect200Response.js"; +export * from "./DocumentsUploadDirect400Response.js"; +export * from "./EngineErrorPayload.js"; +export * from "./TenantsCreate200Response.js"; +export * from "./TenantsCreate400Response.js"; +export * from "./TenantsDeleteResponse.js"; +export * from "./TenantsGet200Response.js"; +export * from "./TenantsGet404Response.js"; +export * from "./TenantsList200Response.js"; +export * from "./TenantsList400Response.js"; +export * from "./TokensIssue200Response.js"; +export * from "./TokensIssue400Response.js"; +export * from "./TokensIssue403Response.js"; +export * from "./TokensIssue404Response.js"; +export * from "./TokensIssueRequest.js"; +export * from "./TokensRevokeResponse.js"; diff --git a/src/auth/BearerAuthProvider.ts b/src/auth/BearerAuthProvider.ts new file mode 100644 index 0000000..8431ff8 --- /dev/null +++ b/src/auth/BearerAuthProvider.ts @@ -0,0 +1,47 @@ +// This file was auto-generated by Fern from our API Definition. + +import * as core from "../core/index.js"; +import * as errors from "../errors/index.js"; + +const TOKEN_PARAM = "token" as const; + +export class BearerAuthProvider implements core.AuthProvider { + private readonly options: BearerAuthProvider.Options; + + constructor(options: BearerAuthProvider.Options) { + this.options = options; + } + + public static canCreate(options: Partial): boolean { + return options?.[TOKEN_PARAM] != null; + } + + public async getAuthRequest({ + endpointMetadata, + }: { + endpointMetadata?: core.EndpointMetadata; + } = {}): Promise { + const token = await core.Supplier.get(this.options[TOKEN_PARAM]); + if (token == null) { + throw new errors.CloudpdfApiError({ + message: BearerAuthProvider.AUTH_CONFIG_ERROR_MESSAGE, + }); + } + + return { + headers: { Authorization: `Bearer ${token}` }, + }; + } +} + +export namespace BearerAuthProvider { + export const AUTH_SCHEME = "apiToken" as const; + export const AUTH_CONFIG_ERROR_MESSAGE: string = + `Please provide '${TOKEN_PARAM}' when initializing the client` as const; + export type Options = AuthOptions; + export type AuthOptions = { [TOKEN_PARAM]: core.Supplier }; + + export function createInstance(options: Options): core.AuthProvider { + return new BearerAuthProvider(options); + } +} diff --git a/src/auth/index.ts b/src/auth/index.ts new file mode 100644 index 0000000..0ecb12b --- /dev/null +++ b/src/auth/index.ts @@ -0,0 +1 @@ +export { BearerAuthProvider } from "./BearerAuthProvider.js"; diff --git a/src/core/auth/AuthProvider.ts b/src/core/auth/AuthProvider.ts new file mode 100644 index 0000000..c947866 --- /dev/null +++ b/src/core/auth/AuthProvider.ts @@ -0,0 +1,15 @@ +import type { EndpointMetadata } from "../fetcher/EndpointMetadata.js"; +import type { AuthRequest } from "./AuthRequest.js"; + +export interface AuthProvider { + getAuthRequest(arg?: { endpointMetadata?: EndpointMetadata }): Promise; +} + +export function isAuthProvider(value: unknown): value is AuthProvider { + return ( + typeof value === "object" && + value !== null && + "getAuthRequest" in value && + typeof value.getAuthRequest === "function" + ); +} diff --git a/src/core/auth/AuthRequest.ts b/src/core/auth/AuthRequest.ts new file mode 100644 index 0000000..f6218b4 --- /dev/null +++ b/src/core/auth/AuthRequest.ts @@ -0,0 +1,9 @@ +/** + * Request parameters for authentication requests. + */ +export interface AuthRequest { + /** + * The headers to be included in the request. + */ + headers: Record; +} diff --git a/src/core/auth/BasicAuth.ts b/src/core/auth/BasicAuth.ts new file mode 100644 index 0000000..f34fca5 --- /dev/null +++ b/src/core/auth/BasicAuth.ts @@ -0,0 +1,37 @@ +import { base64Decode, base64Encode } from "../base64.js"; + +export interface BasicAuth { + username?: string; + password?: string; +} + +const BASIC_AUTH_HEADER_PREFIX = /^Basic /i; + +export const BasicAuth = { + toAuthorizationHeader: (basicAuth: BasicAuth | undefined): string | undefined => { + if (basicAuth == null) { + return undefined; + } + const username = basicAuth.username ?? ""; + const password = basicAuth.password ?? ""; + if (username === "" && password === "") { + return undefined; + } + const token = base64Encode(`${username}:${password}`); + return `Basic ${token}`; + }, + fromAuthorizationHeader: (header: string): BasicAuth => { + const credentials = header.replace(BASIC_AUTH_HEADER_PREFIX, ""); + const decoded = base64Decode(credentials); + const [username, ...passwordParts] = decoded.split(":"); + const password = passwordParts.length > 0 ? passwordParts.join(":") : undefined; + + if (username == null || password == null) { + throw new Error("Invalid basic auth"); + } + return { + username, + password, + }; + }, +}; diff --git a/src/core/auth/BearerToken.ts b/src/core/auth/BearerToken.ts new file mode 100644 index 0000000..c44a06c --- /dev/null +++ b/src/core/auth/BearerToken.ts @@ -0,0 +1,20 @@ +export type BearerToken = string; + +const BEARER_AUTH_HEADER_PREFIX = /^Bearer /i; + +function toAuthorizationHeader(token: string | undefined): string | undefined { + if (token == null) { + return undefined; + } + return `Bearer ${token}`; +} + +export const BearerToken: { + toAuthorizationHeader: typeof toAuthorizationHeader; + fromAuthorizationHeader: (header: string) => BearerToken; +} = { + toAuthorizationHeader: toAuthorizationHeader, + fromAuthorizationHeader: (header: string): BearerToken => { + return header.replace(BEARER_AUTH_HEADER_PREFIX, "").trim() as BearerToken; + }, +}; diff --git a/src/core/auth/NoOpAuthProvider.ts b/src/core/auth/NoOpAuthProvider.ts new file mode 100644 index 0000000..5b7acfd --- /dev/null +++ b/src/core/auth/NoOpAuthProvider.ts @@ -0,0 +1,8 @@ +import type { AuthProvider } from "./AuthProvider.js"; +import type { AuthRequest } from "./AuthRequest.js"; + +export class NoOpAuthProvider implements AuthProvider { + public getAuthRequest(): Promise { + return Promise.resolve({ headers: {} }); + } +} diff --git a/src/core/auth/index.ts b/src/core/auth/index.ts new file mode 100644 index 0000000..77effd0 --- /dev/null +++ b/src/core/auth/index.ts @@ -0,0 +1,5 @@ +export { type AuthProvider, isAuthProvider } from "./AuthProvider.js"; +export type { AuthRequest } from "./AuthRequest.js"; +export { BasicAuth } from "./BasicAuth.js"; +export { BearerToken } from "./BearerToken.js"; +export { NoOpAuthProvider } from "./NoOpAuthProvider.js"; diff --git a/src/core/base64.ts b/src/core/base64.ts new file mode 100644 index 0000000..448a0db --- /dev/null +++ b/src/core/base64.ts @@ -0,0 +1,27 @@ +function base64ToBytes(base64: string): Uint8Array { + const binString = atob(base64); + return Uint8Array.from(binString, (m) => m.codePointAt(0)!); +} + +function bytesToBase64(bytes: Uint8Array): string { + const binString = String.fromCodePoint(...bytes); + return btoa(binString); +} + +export function base64Encode(input: string): string { + if (typeof Buffer !== "undefined") { + return Buffer.from(input, "utf8").toString("base64"); + } + + const bytes = new TextEncoder().encode(input); + return bytesToBase64(bytes); +} + +export function base64Decode(input: string): string { + if (typeof Buffer !== "undefined") { + return Buffer.from(input, "base64").toString("utf8"); + } + + const bytes = base64ToBytes(input); + return new TextDecoder().decode(bytes); +} diff --git a/src/core/exports.ts b/src/core/exports.ts new file mode 100644 index 0000000..358d1fb --- /dev/null +++ b/src/core/exports.ts @@ -0,0 +1,2 @@ +export * from "./file/exports.js"; +export * from "./logging/exports.js"; diff --git a/src/core/fetcher/APIResponse.ts b/src/core/fetcher/APIResponse.ts new file mode 100644 index 0000000..97ab83c --- /dev/null +++ b/src/core/fetcher/APIResponse.ts @@ -0,0 +1,23 @@ +import type { RawResponse } from "./RawResponse.js"; + +/** + * The response of an API call. + * It is a successful response or a failed response. + */ +export type APIResponse = SuccessfulResponse | FailedResponse; + +export interface SuccessfulResponse { + ok: true; + body: T; + /** + * @deprecated Use `rawResponse` instead + */ + headers?: Record; + rawResponse: RawResponse; +} + +export interface FailedResponse { + ok: false; + error: T; + rawResponse: RawResponse; +} diff --git a/src/core/fetcher/BinaryResponse.ts b/src/core/fetcher/BinaryResponse.ts new file mode 100644 index 0000000..b9e40fb --- /dev/null +++ b/src/core/fetcher/BinaryResponse.ts @@ -0,0 +1,34 @@ +export type BinaryResponse = { + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/bodyUsed) */ + bodyUsed: Response["bodyUsed"]; + /** + * Returns a ReadableStream of the response body. + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/body) + */ + stream: () => Response["body"]; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/arrayBuffer) */ + arrayBuffer: () => ReturnType; + /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/blob) */ + blob: () => ReturnType; + /** + * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Request/bytes) + * Some versions of the Fetch API may not support this method. + */ + bytes?(): Promise; +}; + +export function getBinaryResponse(response: Response): BinaryResponse { + const binaryResponse: BinaryResponse = { + get bodyUsed() { + return response.bodyUsed; + }, + stream: () => response.body, + arrayBuffer: response.arrayBuffer.bind(response), + blob: response.blob.bind(response), + }; + if ("bytes" in response && typeof response.bytes === "function") { + binaryResponse.bytes = response.bytes.bind(response); + } + + return binaryResponse; +} diff --git a/src/core/fetcher/EndpointMetadata.ts b/src/core/fetcher/EndpointMetadata.ts new file mode 100644 index 0000000..998d68f --- /dev/null +++ b/src/core/fetcher/EndpointMetadata.ts @@ -0,0 +1,13 @@ +export type SecuritySchemeKey = string; +/** + * A collection of security schemes, where the key is the name of the security scheme and the value is the list of scopes required for that scheme. + * All schemes in the collection must be satisfied for authentication to be successful. + */ +export type SecuritySchemeCollection = Record; +export type AuthScope = string; +export type EndpointMetadata = { + /** + * An array of security scheme collections. Each collection represents an alternative way to authenticate. + */ + security?: SecuritySchemeCollection[]; +}; diff --git a/src/core/fetcher/EndpointSupplier.ts b/src/core/fetcher/EndpointSupplier.ts new file mode 100644 index 0000000..aad81f0 --- /dev/null +++ b/src/core/fetcher/EndpointSupplier.ts @@ -0,0 +1,14 @@ +import type { EndpointMetadata } from "./EndpointMetadata.js"; +import type { Supplier } from "./Supplier.js"; + +type EndpointSupplierFn = (arg: { endpointMetadata?: EndpointMetadata }) => T | Promise; +export type EndpointSupplier = Supplier | EndpointSupplierFn; +export const EndpointSupplier = { + get: async (supplier: EndpointSupplier, arg: { endpointMetadata?: EndpointMetadata }): Promise => { + if (typeof supplier === "function") { + return (supplier as EndpointSupplierFn)(arg); + } else { + return supplier; + } + }, +}; diff --git a/src/core/fetcher/Fetcher.ts b/src/core/fetcher/Fetcher.ts new file mode 100644 index 0000000..cd5c579 --- /dev/null +++ b/src/core/fetcher/Fetcher.ts @@ -0,0 +1,311 @@ +import { toJson } from "../json.js"; +import { createLogger, type LogConfig, type Logger } from "../logging/logger.js"; +import type { APIResponse } from "./APIResponse.js"; +import { createRequestUrl } from "./createRequestUrl.js"; +import type { EndpointMetadata } from "./EndpointMetadata.js"; +import { EndpointSupplier } from "./EndpointSupplier.js"; +import { getErrorResponseBody } from "./getErrorResponseBody.js"; +import { getFetchFn } from "./getFetchFn.js"; +import { getRequestBody } from "./getRequestBody.js"; +import { getResponseBody } from "./getResponseBody.js"; +import { Headers } from "./Headers.js"; +import { makeRequest } from "./makeRequest.js"; +import { abortRawResponse, toRawResponse, unknownRawResponse } from "./RawResponse.js"; +import { redactUrl, SENSITIVE_QUERY_PARAMS } from "./redactUrl.js"; +import { requestWithRetries } from "./requestWithRetries.js"; + +export type FetchFunction = (args: Fetcher.Args) => Promise>; + +export declare namespace Fetcher { + export interface Args { + url: string; + method: string; + contentType?: string; + headers?: Record; + /** + * @deprecated Prefer `queryString` (produced by `core.url.queryBuilder()`). + * Retained for backwards compatibility with custom fetchers and callers that + * still construct request args with a query-parameter object. + */ + queryParameters?: Record; + queryString?: string; + body?: unknown; + timeoutMs?: number; + maxRetries?: number; + withCredentials?: boolean; + abortSignal?: AbortSignal; + requestType?: "json" | "file" | "bytes" | "form" | "other"; + responseType?: "json" | "blob" | "sse" | "streaming" | "text" | "arrayBuffer" | "binary-response"; + duplex?: "half"; + endpointMetadata?: EndpointMetadata; + fetchFn?: typeof fetch; + logging?: LogConfig | Logger; + } + + export type Error = FailedStatusCodeError | NonJsonError | BodyIsNullError | TimeoutError | UnknownError; + + export interface FailedStatusCodeError { + reason: "status-code"; + statusCode: number; + body: unknown; + } + + export interface NonJsonError { + reason: "non-json"; + statusCode: number; + rawBody: string; + } + + export interface BodyIsNullError { + reason: "body-is-null"; + statusCode: number; + } + + export interface TimeoutError { + reason: "timeout"; + cause?: unknown; + } + + export interface UnknownError { + reason: "unknown"; + errorMessage: string; + cause?: unknown; + } +} + +const SENSITIVE_HEADERS = new Set([ + "authorization", + "www-authenticate", + "x-api-key", + "api-key", + "apikey", + "x-api-token", + "x-auth-token", + "auth-token", + "cookie", + "set-cookie", + "proxy-authorization", + "proxy-authenticate", + "x-csrf-token", + "x-xsrf-token", + "x-session-token", + "x-access-token", +]); + +function redactHeaders(headers: Headers | Record): Record { + const filtered: Record = {}; + for (const [key, value] of headers instanceof Headers ? headers.entries() : Object.entries(headers)) { + if (SENSITIVE_HEADERS.has(key.toLowerCase())) { + filtered[key] = "[REDACTED]"; + } else { + filtered[key] = value; + } + } + return filtered; +} + +function redactQueryParameters( + queryParameters: Record | undefined, +): Record | undefined { + if (queryParameters == null) { + return undefined; + } + const redacted: Record = {}; + for (const [key, value] of Object.entries(queryParameters)) { + redacted[key] = SENSITIVE_QUERY_PARAMS.has(key.toLowerCase()) ? "[REDACTED]" : value; + } + return redacted; +} + +async function getHeaders(args: Fetcher.Args): Promise { + const newHeaders: Headers = new Headers(); + + newHeaders.set( + "Accept", + args.responseType === "json" + ? "application/json" + : args.responseType === "text" + ? "text/plain" + : args.responseType === "sse" + ? "text/event-stream" + : "*/*", + ); + if (args.body !== undefined && args.contentType != null) { + newHeaders.set("Content-Type", args.contentType); + } + + if (args.headers == null) { + return newHeaders; + } + + for (const [key, value] of Object.entries(args.headers)) { + const result = await EndpointSupplier.get(value, { endpointMetadata: args.endpointMetadata ?? {} }); + if (typeof result === "string") { + newHeaders.set(key, result); + continue; + } + if (result == null) { + continue; + } + newHeaders.set(key, `${result}`); + } + return newHeaders; +} + +export async function fetcherImpl(args: Fetcher.Args): Promise> { + let url = args.url; + if (args.queryString != null && args.queryString.length > 0) { + url = `${url}?${args.queryString}`; + } else { + url = createRequestUrl(args.url, args.queryParameters); + } + const requestBody: BodyInit | undefined = await getRequestBody({ + body: args.body, + type: args.requestType ?? "other", + }); + const fetchFn = args.fetchFn ?? (await getFetchFn()); + const headers = await getHeaders(args); + const logger = createLogger(args.logging); + + if (logger.isDebug()) { + const metadata = { + method: args.method, + url: redactUrl(url), + headers: redactHeaders(headers), + queryParameters: redactQueryParameters(args.queryParameters), + hasBody: requestBody != null, + }; + logger.debug("Making HTTP request", metadata); + } + + try { + const response = await requestWithRetries( + async () => + makeRequest( + fetchFn, + url, + args.method, + headers, + requestBody, + args.timeoutMs, + args.abortSignal, + args.withCredentials, + args.duplex, + args.responseType === "streaming" || args.responseType === "sse", + ), + args.maxRetries, + ); + + if (response.status >= 200 && response.status < 400) { + if (logger.isDebug()) { + const metadata = { + method: args.method, + url: redactUrl(url), + statusCode: response.status, + responseHeaders: redactHeaders(response.headers), + }; + logger.debug("HTTP request succeeded", metadata); + } + const body = await getResponseBody(response, args.responseType); + return { + ok: true, + body: body as R, + headers: response.headers, + rawResponse: toRawResponse(response), + }; + } else { + if (logger.isError()) { + const metadata = { + method: args.method, + url: redactUrl(url), + statusCode: response.status, + responseHeaders: redactHeaders(Object.fromEntries(response.headers.entries())), + }; + logger.error("HTTP request failed with error status", metadata); + } + return { + ok: false, + error: { + reason: "status-code", + statusCode: response.status, + body: await getErrorResponseBody(response), + }, + rawResponse: toRawResponse(response), + }; + } + } catch (error) { + if (args.abortSignal?.aborted) { + if (logger.isError()) { + const metadata = { + method: args.method, + url: redactUrl(url), + }; + logger.error("HTTP request was aborted", metadata); + } + return { + ok: false, + error: { + reason: "unknown", + errorMessage: "The user aborted a request", + cause: error, + }, + rawResponse: abortRawResponse, + }; + } else if (error instanceof Error && error.name === "AbortError") { + if (logger.isError()) { + const metadata = { + method: args.method, + url: redactUrl(url), + timeoutMs: args.timeoutMs, + }; + logger.error("HTTP request timed out", metadata); + } + return { + ok: false, + error: { + reason: "timeout", + cause: error, + }, + rawResponse: abortRawResponse, + }; + } else if (error instanceof Error) { + if (logger.isError()) { + const metadata = { + method: args.method, + url: redactUrl(url), + errorMessage: error.message, + }; + logger.error("HTTP request failed with error", metadata); + } + return { + ok: false, + error: { + reason: "unknown", + errorMessage: error.message, + cause: error, + }, + rawResponse: unknownRawResponse, + }; + } + + if (logger.isError()) { + const metadata = { + method: args.method, + url: redactUrl(url), + error: toJson(error), + }; + logger.error("HTTP request failed with unknown error", metadata); + } + return { + ok: false, + error: { + reason: "unknown", + errorMessage: toJson(error), + cause: error, + }, + rawResponse: unknownRawResponse, + }; + } +} + +export const fetcher: FetchFunction = fetcherImpl; diff --git a/src/core/fetcher/Headers.ts b/src/core/fetcher/Headers.ts new file mode 100644 index 0000000..f02246c --- /dev/null +++ b/src/core/fetcher/Headers.ts @@ -0,0 +1,93 @@ +let Headers: typeof globalThis.Headers; + +if (typeof globalThis.Headers !== "undefined") { + Headers = globalThis.Headers; +} else { + Headers = class Headers implements Headers { + private headers: Map; + + constructor(init?: HeadersInit) { + this.headers = new Map(); + + if (init) { + if (init instanceof Headers) { + init.forEach((value, key) => this.append(key, value)); + } else if (Array.isArray(init)) { + for (const [key, value] of init) { + if (typeof key === "string" && typeof value === "string") { + this.append(key, value); + } else { + throw new TypeError("Each header entry must be a [string, string] tuple"); + } + } + } else { + for (const [key, value] of Object.entries(init)) { + if (typeof value === "string") { + this.append(key, value); + } else { + throw new TypeError("Header values must be strings"); + } + } + } + } + } + + append(name: string, value: string): void { + const key = name.toLowerCase(); + const existing = this.headers.get(key) || []; + this.headers.set(key, [...existing, value]); + } + + delete(name: string): void { + const key = name.toLowerCase(); + this.headers.delete(key); + } + + get(name: string): string | null { + const key = name.toLowerCase(); + const values = this.headers.get(key); + return values ? values.join(", ") : null; + } + + has(name: string): boolean { + const key = name.toLowerCase(); + return this.headers.has(key); + } + + set(name: string, value: string): void { + const key = name.toLowerCase(); + this.headers.set(key, [value]); + } + + forEach(callbackfn: (value: string, key: string, parent: Headers) => void, thisArg?: unknown): void { + const boundCallback = thisArg ? callbackfn.bind(thisArg) : callbackfn; + this.headers.forEach((values, key) => boundCallback(values.join(", "), key, this)); + } + + getSetCookie(): string[] { + return this.headers.get("set-cookie") || []; + } + + *entries(): IterableIterator<[string, string]> { + for (const [key, values] of this.headers.entries()) { + yield [key, values.join(", ")]; + } + } + + *keys(): IterableIterator { + yield* this.headers.keys(); + } + + *values(): IterableIterator { + for (const values of this.headers.values()) { + yield values.join(", "); + } + } + + [Symbol.iterator](): IterableIterator<[string, string]> { + return this.entries(); + } + }; +} + +export { Headers }; diff --git a/src/core/fetcher/HttpResponsePromise.ts b/src/core/fetcher/HttpResponsePromise.ts new file mode 100644 index 0000000..692ca7d --- /dev/null +++ b/src/core/fetcher/HttpResponsePromise.ts @@ -0,0 +1,116 @@ +import type { WithRawResponse } from "./RawResponse.js"; + +/** + * A promise that returns the parsed response and lets you retrieve the raw response too. + */ +export class HttpResponsePromise extends Promise { + private innerPromise: Promise>; + private unwrappedPromise: Promise | undefined; + + private constructor(promise: Promise>) { + // Initialize with a no-op to avoid premature parsing + super((resolve) => { + resolve(undefined as unknown as T); + }); + this.innerPromise = promise; + } + + /** + * Creates an `HttpResponsePromise` from a function that returns a promise. + * + * @param fn - A function that returns a promise resolving to a `WithRawResponse` object. + * @param args - Arguments to pass to the function. + * @returns An `HttpResponsePromise` instance. + */ + public static fromFunction Promise>, T>( + fn: F, + ...args: Parameters + ): HttpResponsePromise { + return new HttpResponsePromise(fn(...args)); + } + + /** + * Creates a function that returns an `HttpResponsePromise` from a function that returns a promise. + * + * @param fn - A function that returns a promise resolving to a `WithRawResponse` object. + * @returns A function that returns an `HttpResponsePromise` instance. + */ + public static interceptFunction< + F extends (...args: never[]) => Promise>, + T = Awaited>["data"], + >(fn: F): (...args: Parameters) => HttpResponsePromise { + return (...args: Parameters): HttpResponsePromise => { + return HttpResponsePromise.fromPromise(fn(...args)); + }; + } + + /** + * Creates an `HttpResponsePromise` from an existing promise. + * + * @param promise - A promise resolving to a `WithRawResponse` object. + * @returns An `HttpResponsePromise` instance. + */ + public static fromPromise(promise: Promise>): HttpResponsePromise { + return new HttpResponsePromise(promise); + } + + /** + * Creates an `HttpResponsePromise` from an executor function. + * + * @param executor - A function that takes resolve and reject callbacks to create a promise. + * @returns An `HttpResponsePromise` instance. + */ + public static fromExecutor( + executor: (resolve: (value: WithRawResponse) => void, reject: (reason?: unknown) => void) => void, + ): HttpResponsePromise { + const promise = new Promise>(executor); + return new HttpResponsePromise(promise); + } + + /** + * Creates an `HttpResponsePromise` from a resolved result. + * + * @param result - A `WithRawResponse` object to resolve immediately. + * @returns An `HttpResponsePromise` instance. + */ + public static fromResult(result: WithRawResponse): HttpResponsePromise { + const promise = Promise.resolve(result); + return new HttpResponsePromise(promise); + } + + private unwrap(): Promise { + if (!this.unwrappedPromise) { + this.unwrappedPromise = this.innerPromise.then(({ data }) => data); + } + return this.unwrappedPromise; + } + + /** @inheritdoc */ + public override then( + onfulfilled?: ((value: T) => TResult1 | PromiseLike) | null, + onrejected?: ((reason: unknown) => TResult2 | PromiseLike) | null, + ): Promise { + return this.unwrap().then(onfulfilled, onrejected); + } + + /** @inheritdoc */ + public override catch( + onrejected?: ((reason: unknown) => TResult | PromiseLike) | null, + ): Promise { + return this.unwrap().catch(onrejected); + } + + /** @inheritdoc */ + public override finally(onfinally?: (() => void) | null): Promise { + return this.unwrap().finally(onfinally); + } + + /** + * Retrieves the data and raw response. + * + * @returns A promise resolving to a `WithRawResponse` object. + */ + public async withRawResponse(): Promise> { + return await this.innerPromise; + } +} diff --git a/src/core/fetcher/RawResponse.ts b/src/core/fetcher/RawResponse.ts new file mode 100644 index 0000000..37fb44e --- /dev/null +++ b/src/core/fetcher/RawResponse.ts @@ -0,0 +1,61 @@ +import { Headers } from "./Headers.js"; + +/** + * The raw response from the fetch call excluding the body. + */ +export type RawResponse = Omit< + { + [K in keyof Response as Response[K] extends Function ? never : K]: Response[K]; // strips out functions + }, + "ok" | "body" | "bodyUsed" +>; // strips out body and bodyUsed + +/** + * A raw response indicating that the request was aborted. + */ +export const abortRawResponse: RawResponse = { + headers: new Headers(), + redirected: false, + status: 499, + statusText: "Client Closed Request", + type: "error", + url: "", +} as const; + +/** + * A raw response indicating an unknown error. + */ +export const unknownRawResponse: RawResponse = { + headers: new Headers(), + redirected: false, + status: 0, + statusText: "Unknown Error", + type: "error", + url: "", +} as const; + +/** + * Converts a `RawResponse` object into a `RawResponse` by extracting its properties, + * excluding the `body` and `bodyUsed` fields. + * + * @param response - The `RawResponse` object to convert. + * @returns A `RawResponse` object containing the extracted properties of the input response. + */ +export function toRawResponse(response: Response): RawResponse { + return { + headers: response.headers, + redirected: response.redirected, + status: response.status, + statusText: response.statusText, + type: response.type, + url: response.url, + }; +} + +/** + * Creates a `RawResponse` from a standard `Response` object. + */ +export interface WithRawResponse { + readonly data: T; + readonly rawResponse: RawResponse; +} diff --git a/src/core/fetcher/Supplier.ts b/src/core/fetcher/Supplier.ts new file mode 100644 index 0000000..867c931 --- /dev/null +++ b/src/core/fetcher/Supplier.ts @@ -0,0 +1,11 @@ +export type Supplier = T | Promise | (() => T | Promise); + +export const Supplier = { + get: async (supplier: Supplier): Promise => { + if (typeof supplier === "function") { + return (supplier as () => T)(); + } else { + return supplier; + } + }, +}; diff --git a/src/core/fetcher/createRequestUrl.ts b/src/core/fetcher/createRequestUrl.ts new file mode 100644 index 0000000..88e1326 --- /dev/null +++ b/src/core/fetcher/createRequestUrl.ts @@ -0,0 +1,6 @@ +import { toQueryString } from "../url/qs.js"; + +export function createRequestUrl(baseUrl: string, queryParameters?: Record): string { + const queryString = toQueryString(queryParameters, { arrayFormat: "repeat" }); + return queryString ? `${baseUrl}?${queryString}` : baseUrl; +} diff --git a/src/core/fetcher/getErrorResponseBody.ts b/src/core/fetcher/getErrorResponseBody.ts new file mode 100644 index 0000000..7cf4e62 --- /dev/null +++ b/src/core/fetcher/getErrorResponseBody.ts @@ -0,0 +1,33 @@ +import { fromJson } from "../json.js"; +import { getResponseBody } from "./getResponseBody.js"; + +export async function getErrorResponseBody(response: Response): Promise { + let contentType = response.headers.get("Content-Type")?.toLowerCase(); + if (contentType == null || contentType.length === 0) { + return getResponseBody(response); + } + + if (contentType.indexOf(";") !== -1) { + contentType = contentType.split(";")[0]?.trim() ?? ""; + } + switch (contentType) { + case "application/hal+json": + case "application/json": + case "application/ld+json": + case "application/problem+json": + case "application/vnd.api+json": + case "text/json": { + const text = await response.text(); + return text.length > 0 ? fromJson(text) : undefined; + } + default: + if (contentType.startsWith("application/vnd.") && contentType.endsWith("+json")) { + const text = await response.text(); + return text.length > 0 ? fromJson(text) : undefined; + } + + // Fallback to plain text if content type is not recognized + // Even if no body is present, the response will be an empty string + return await response.text(); + } +} diff --git a/src/core/fetcher/getFetchFn.ts b/src/core/fetcher/getFetchFn.ts new file mode 100644 index 0000000..9f845b9 --- /dev/null +++ b/src/core/fetcher/getFetchFn.ts @@ -0,0 +1,3 @@ +export async function getFetchFn(): Promise { + return fetch; +} diff --git a/src/core/fetcher/getHeader.ts b/src/core/fetcher/getHeader.ts new file mode 100644 index 0000000..50f922b --- /dev/null +++ b/src/core/fetcher/getHeader.ts @@ -0,0 +1,8 @@ +export function getHeader(headers: Record, header: string): string | undefined { + for (const [headerKey, headerValue] of Object.entries(headers)) { + if (headerKey.toLowerCase() === header.toLowerCase()) { + return headerValue; + } + } + return undefined; +} diff --git a/src/core/fetcher/getRequestBody.ts b/src/core/fetcher/getRequestBody.ts new file mode 100644 index 0000000..91d9d81 --- /dev/null +++ b/src/core/fetcher/getRequestBody.ts @@ -0,0 +1,20 @@ +import { toJson } from "../json.js"; +import { toQueryString } from "../url/qs.js"; + +export declare namespace GetRequestBody { + interface Args { + body: unknown; + type: "json" | "file" | "bytes" | "form" | "other"; + } +} + +export async function getRequestBody({ body, type }: GetRequestBody.Args): Promise { + if (type === "form") { + return toQueryString(body, { arrayFormat: "repeat", encode: true }); + } + if (type.includes("json")) { + return toJson(body); + } else { + return body as BodyInit; + } +} diff --git a/src/core/fetcher/getResponseBody.ts b/src/core/fetcher/getResponseBody.ts new file mode 100644 index 0000000..2e831e4 --- /dev/null +++ b/src/core/fetcher/getResponseBody.ts @@ -0,0 +1,70 @@ +import { fromJson } from "../json.js"; +import { getBinaryResponse } from "./BinaryResponse.js"; + +// Pins the upstream Response so undici's FinalizationRegistry can't GC it and cancel the body stream. +function retainResponse(target: object, response: Response): void { + Object.defineProperty(target, "__fern_response_ref", { + value: response, + enumerable: false, + configurable: true, + writable: false, + }); +} + +export async function getResponseBody(response: Response, responseType?: string): Promise { + switch (responseType) { + case "binary-response": + return getBinaryResponse(response); + case "blob": + return await response.blob(); + case "arrayBuffer": + return await response.arrayBuffer(); + case "sse": + if (response.body == null) { + return { + ok: false, + error: { + reason: "body-is-null", + statusCode: response.status, + }, + }; + } + retainResponse(response.body, response); + return response.body; + case "streaming": + if (response.body == null) { + return { + ok: false, + error: { + reason: "body-is-null", + statusCode: response.status, + }, + }; + } + + retainResponse(response.body, response); + return response.body; + + case "text": + return await response.text(); + } + + // if responseType is "json" or not specified, try to parse as JSON + const text = await response.text(); + if (text.length > 0) { + try { + const responseBody = fromJson(text); + return responseBody; + } catch (_err) { + return { + ok: false, + error: { + reason: "non-json", + statusCode: response.status, + rawBody: text, + }, + }; + } + } + return undefined; +} diff --git a/src/core/fetcher/index.ts b/src/core/fetcher/index.ts new file mode 100644 index 0000000..bd5db36 --- /dev/null +++ b/src/core/fetcher/index.ts @@ -0,0 +1,13 @@ +export type { APIResponse } from "./APIResponse.js"; +export type { BinaryResponse } from "./BinaryResponse.js"; +export type { EndpointMetadata } from "./EndpointMetadata.js"; +export { EndpointSupplier } from "./EndpointSupplier.js"; +export type { Fetcher, FetchFunction } from "./Fetcher.js"; +export { fetcher } from "./Fetcher.js"; +export { getHeader } from "./getHeader.js"; +export { HttpResponsePromise } from "./HttpResponsePromise.js"; +export type { PassthroughRequest } from "./makePassthroughRequest.js"; +export { makePassthroughRequest } from "./makePassthroughRequest.js"; +export type { RawResponse, WithRawResponse } from "./RawResponse.js"; +export { abortRawResponse, toRawResponse, unknownRawResponse } from "./RawResponse.js"; +export { Supplier } from "./Supplier.js"; diff --git a/src/core/fetcher/makePassthroughRequest.ts b/src/core/fetcher/makePassthroughRequest.ts new file mode 100644 index 0000000..e8dceda --- /dev/null +++ b/src/core/fetcher/makePassthroughRequest.ts @@ -0,0 +1,211 @@ +import { createLogger, type LogConfig, type Logger } from "../logging/logger.js"; +import { join } from "../url/join.js"; +import { EndpointSupplier } from "./EndpointSupplier.js"; +import { getFetchFn } from "./getFetchFn.js"; +import { makeRequest } from "./makeRequest.js"; +import { redactUrl } from "./redactUrl.js"; +import { requestWithRetries } from "./requestWithRetries.js"; +import { Supplier } from "./Supplier.js"; + +export declare namespace PassthroughRequest { + /** + * Per-request options that can override the SDK client defaults. + */ + export interface RequestOptions { + /** Override the default timeout for this request (in seconds). */ + timeoutInSeconds?: number; + /** Override the default number of retries for this request. */ + maxRetries?: number; + /** Additional headers to include in this request. */ + headers?: Record; + /** Abort signal for this request. */ + abortSignal?: AbortSignal; + } + + /** + * SDK client configuration used by the passthrough fetch method. + */ + export interface ClientOptions { + /** The base URL or environment for the client. */ + environment?: Supplier; + /** Override the base URL. */ + baseUrl?: Supplier; + /** Default headers to include in requests. */ + headers?: Record; + /** Default maximum time to wait for a response in seconds. */ + timeoutInSeconds?: number; + /** Default number of times to retry the request. Defaults to 2. */ + maxRetries?: number; + /** A custom fetch function. */ + fetch?: typeof fetch; + /** Logging configuration. */ + logging?: LogConfig | Logger; + /** A function that returns auth headers. */ + getAuthHeaders?: () => Promise>; + } +} + +/** + * Makes a passthrough HTTP request using the SDK's configuration (auth, retry, logging, etc.) + * while mimicking the standard `fetch` API. + * + * @param input - The URL, path, or Request object. If a relative path, it will be resolved against the configured base URL. + * @param init - Standard RequestInit options (method, headers, body, signal, etc.) + * @param clientOptions - SDK client options (auth, default headers, logging, etc.) + * @param requestOptions - Per-request overrides (timeout, retries, extra headers, abort signal). + * @returns A standard Response object. + */ +export async function makePassthroughRequest( + input: Request | string | URL, + init: RequestInit | undefined, + clientOptions: PassthroughRequest.ClientOptions, + requestOptions?: PassthroughRequest.RequestOptions, +): Promise { + const logger = createLogger(clientOptions.logging); + + // Extract URL and default init properties from Request object if provided + let url: string; + let effectiveInit: RequestInit | undefined = init; + if (input instanceof Request) { + url = input.url; + // If no explicit init provided, extract properties from the Request object + if (init == null) { + effectiveInit = { + method: input.method, + headers: Object.fromEntries(input.headers.entries()), + body: input.body, + signal: input.signal, + credentials: input.credentials, + cache: input.cache as RequestCache, + redirect: input.redirect, + referrer: input.referrer, + integrity: input.integrity, + mode: input.mode, + }; + } + } else { + url = input instanceof URL ? input.toString() : input; + } + + // Resolve the base URL + const baseUrl = + (clientOptions.baseUrl != null ? await Supplier.get(clientOptions.baseUrl) : undefined) ?? + (clientOptions.environment != null ? await Supplier.get(clientOptions.environment) : undefined); + + // Determine the full URL + let fullUrl: string; + if (url.startsWith("http://") || url.startsWith("https://")) { + fullUrl = url; + } else if (baseUrl != null) { + fullUrl = join(baseUrl, url); + } else { + fullUrl = url; + } + + // Merge headers: SDK default headers -> auth headers -> user-provided headers + const mergedHeaders: Record = {}; + + // Apply SDK default headers (resolve suppliers) + if (clientOptions.headers != null) { + for (const [key, value] of Object.entries(clientOptions.headers)) { + const resolved = await EndpointSupplier.get(value, { endpointMetadata: {} }); + if (resolved != null) { + mergedHeaders[key.toLowerCase()] = `${resolved}`; + } + } + } + + // Apply auth headers, but only when the resolved URL targets the configured base URL. + // This prevents the SDK's credentials from leaking to an unrelated host when a caller + // passes an absolute cross-origin URL into the passthrough fetch escape hatch. + if (clientOptions.getAuthHeaders != null && targetsBaseUrl(fullUrl, baseUrl)) { + const authHeaders = await clientOptions.getAuthHeaders(); + for (const [key, value] of Object.entries(authHeaders)) { + mergedHeaders[key.toLowerCase()] = value; + } + } + + // Apply user-provided headers from init + if (effectiveInit?.headers != null) { + const initHeaders = + effectiveInit.headers instanceof Headers + ? Object.fromEntries(effectiveInit.headers.entries()) + : Array.isArray(effectiveInit.headers) + ? Object.fromEntries(effectiveInit.headers) + : effectiveInit.headers; + for (const [key, value] of Object.entries(initHeaders)) { + if (value != null) { + mergedHeaders[key.toLowerCase()] = value; + } + } + } + + // Apply per-request option headers (highest priority) + if (requestOptions?.headers != null) { + for (const [key, value] of Object.entries(requestOptions.headers)) { + mergedHeaders[key.toLowerCase()] = value; + } + } + + const method = effectiveInit?.method ?? "GET"; + const body = effectiveInit?.body; + const timeoutInSeconds = requestOptions?.timeoutInSeconds ?? clientOptions.timeoutInSeconds; + const timeoutMs = timeoutInSeconds != null ? timeoutInSeconds * 1000 : undefined; + const maxRetries = requestOptions?.maxRetries ?? clientOptions.maxRetries; + const abortSignal = requestOptions?.abortSignal ?? effectiveInit?.signal ?? undefined; + const fetchFn = clientOptions.fetch ?? (await getFetchFn()); + + if (logger.isDebug()) { + logger.debug("Making passthrough HTTP request", { + method, + url: redactUrl(fullUrl), + hasBody: body != null, + }); + } + + const response = await requestWithRetries( + async () => + makeRequest( + fetchFn, + fullUrl, + method, + mergedHeaders, + body ?? undefined, + timeoutMs, + abortSignal, + effectiveInit?.credentials === "include", + undefined, // duplex + false, // disableCache + ), + maxRetries, + ); + + if (logger.isDebug()) { + logger.debug("Passthrough HTTP request completed", { + method, + url: redactUrl(fullUrl), + statusCode: response.status, + }); + } + + return response; +} + +/** + * Returns true when the resolved request URL points at the same origin as the + * configured base URL. Relative paths are always joined onto the base URL, so + * they resolve to the base origin and return true. Absolute URLs only match when + * their origin equals the base origin. When there is no base URL to compare + * against, or either value is not a parseable absolute URL, this returns false so + * auth headers are not attached. + */ +function targetsBaseUrl(fullUrl: string, baseUrl: string | undefined): boolean { + if (baseUrl == null) { + return false; + } + try { + return new URL(fullUrl).origin === new URL(baseUrl).origin; + } catch { + return false; + } +} diff --git a/src/core/fetcher/makeRequest.ts b/src/core/fetcher/makeRequest.ts new file mode 100644 index 0000000..360a86d --- /dev/null +++ b/src/core/fetcher/makeRequest.ts @@ -0,0 +1,70 @@ +import { anySignal, getTimeoutSignal } from "./signals.js"; + +/** + * Cached result of checking whether the current runtime supports + * the `cache` option in `Request`. Some runtimes (e.g. Cloudflare Workers) + * throw a TypeError when this option is used. + */ +let _cacheNoStoreSupported: boolean | undefined; +export function isCacheNoStoreSupported(): boolean { + if (_cacheNoStoreSupported != null) { + return _cacheNoStoreSupported; + } + try { + new Request("http://localhost", { cache: "no-store" }); + _cacheNoStoreSupported = true; + } catch { + _cacheNoStoreSupported = false; + } + return _cacheNoStoreSupported; +} + +/** + * Reset the cached result of `isCacheNoStoreSupported`. Exposed for testing only. + */ +export function resetCacheNoStoreSupported(): void { + _cacheNoStoreSupported = undefined; +} + +export const makeRequest = async ( + fetchFn: (url: string, init: RequestInit) => Promise, + url: string, + method: string, + headers: Headers | Record, + requestBody: BodyInit | undefined, + timeoutMs?: number, + abortSignal?: AbortSignal, + withCredentials?: boolean, + duplex?: "half", + disableCache?: boolean, +): Promise => { + const signals: AbortSignal[] = []; + + let timeoutAbortId: ReturnType | undefined; + if (timeoutMs != null) { + const { signal, abortId } = getTimeoutSignal(timeoutMs); + timeoutAbortId = abortId; + signals.push(signal); + } + + if (abortSignal != null) { + signals.push(abortSignal); + } + const newSignals = anySignal(signals); + const response = await fetchFn(url, { + method: method, + headers, + body: requestBody, + signal: newSignals, + credentials: withCredentials ? "include" : undefined, + // @ts-ignore + duplex, + ...(disableCache && isCacheNoStoreSupported() ? { cache: "no-store" as RequestCache } : {}), + }); + + if (timeoutAbortId != null) { + clearTimeout(timeoutAbortId); + } + + return response; +}; diff --git a/src/core/fetcher/redactUrl.ts b/src/core/fetcher/redactUrl.ts new file mode 100644 index 0000000..3c2e897 --- /dev/null +++ b/src/core/fetcher/redactUrl.ts @@ -0,0 +1,102 @@ +export const SENSITIVE_QUERY_PARAMS: Set = new Set([ + "api_key", + "api-key", + "apikey", + "token", + "access_token", + "access-token", + "auth_token", + "auth-token", + "password", + "passwd", + "secret", + "api_secret", + "api-secret", + "apisecret", + "key", + "session", + "session_id", + "session-id", +]); + +export function redactUrl(url: string): string { + const protocolIndex = url.indexOf("://"); + if (protocolIndex === -1) return url; + + const afterProtocol = protocolIndex + 3; + + // Find the first delimiter that marks the end of the authority section + const pathStart = url.indexOf("/", afterProtocol); + let queryStart = url.indexOf("?", afterProtocol); + let fragmentStart = url.indexOf("#", afterProtocol); + + const firstDelimiter = Math.min( + pathStart === -1 ? url.length : pathStart, + queryStart === -1 ? url.length : queryStart, + fragmentStart === -1 ? url.length : fragmentStart, + ); + + // Find the LAST @ before the delimiter (handles multiple @ in credentials) + let atIndex = -1; + for (let i = afterProtocol; i < firstDelimiter; i++) { + if (url[i] === "@") { + atIndex = i; + } + } + + if (atIndex !== -1) { + url = `${url.slice(0, afterProtocol)}[REDACTED]@${url.slice(atIndex + 1)}`; + } + + // Recalculate queryStart since url might have changed + queryStart = url.indexOf("?"); + if (queryStart === -1) return url; + + fragmentStart = url.indexOf("#", queryStart); + const queryEnd = fragmentStart !== -1 ? fragmentStart : url.length; + const queryString = url.slice(queryStart + 1, queryEnd); + + if (queryString.length === 0) return url; + + // FAST PATH: Quick check if any sensitive keywords present + // Using indexOf is faster than regex for simple substring matching + const lower = queryString.toLowerCase(); + const hasSensitive = + lower.includes("token") || + lower.includes("key") || + lower.includes("password") || + lower.includes("passwd") || + lower.includes("secret") || + lower.includes("session") || + lower.includes("auth"); + + if (!hasSensitive) { + return url; + } + + // SLOW PATH: Parse and redact + const redactedParams: string[] = []; + const params = queryString.split("&"); + + for (const param of params) { + const equalIndex = param.indexOf("="); + if (equalIndex === -1) { + redactedParams.push(param); + continue; + } + + const key = param.slice(0, equalIndex); + let shouldRedact = SENSITIVE_QUERY_PARAMS.has(key.toLowerCase()); + + if (!shouldRedact && key.includes("%")) { + try { + const decodedKey = decodeURIComponent(key); + shouldRedact = SENSITIVE_QUERY_PARAMS.has(decodedKey.toLowerCase()); + } catch {} + } + + redactedParams.push(shouldRedact ? `${key}=[REDACTED]` : param); + } + + return url.slice(0, queryStart + 1) + redactedParams.join("&") + url.slice(queryEnd); +} diff --git a/src/core/fetcher/requestWithRetries.ts b/src/core/fetcher/requestWithRetries.ts new file mode 100644 index 0000000..5e66b93 --- /dev/null +++ b/src/core/fetcher/requestWithRetries.ts @@ -0,0 +1,68 @@ +const INITIAL_RETRY_DELAY = 1000; // in milliseconds +const MAX_RETRY_DELAY = 60000; // in milliseconds +const DEFAULT_MAX_RETRIES = 2; +const JITTER_FACTOR = 0.2; // 20% random jitter + +function isRetryableStatusCode(statusCode: number): boolean { + return [408, 429].includes(statusCode) || statusCode >= 500; +} + +function addPositiveJitter(delay: number): number { + const jitterMultiplier = 1 + Math.random() * JITTER_FACTOR; + return delay * jitterMultiplier; +} + +function addSymmetricJitter(delay: number): number { + const jitterMultiplier = 1 + (Math.random() - 0.5) * JITTER_FACTOR; + return delay * jitterMultiplier; +} + +function getRetryDelayFromHeaders(response: Response, retryAttempt: number): number { + const retryAfter = response.headers.get("Retry-After"); + if (retryAfter) { + const retryAfterSeconds = parseInt(retryAfter, 10); + if (!Number.isNaN(retryAfterSeconds) && retryAfterSeconds > 0) { + return Math.min(retryAfterSeconds * 1000, MAX_RETRY_DELAY); + } + + const retryAfterDate = new Date(retryAfter); + if (!Number.isNaN(retryAfterDate.getTime())) { + const delay = retryAfterDate.getTime() - Date.now(); + if (delay > 0) { + return Math.min(Math.max(delay, 0), MAX_RETRY_DELAY); + } + } + } + + const rateLimitReset = response.headers.get("X-RateLimit-Reset"); + if (rateLimitReset) { + const resetTime = parseInt(rateLimitReset, 10); + if (!Number.isNaN(resetTime)) { + const delay = resetTime * 1000 - Date.now(); + if (delay > 0) { + return addPositiveJitter(Math.min(delay, MAX_RETRY_DELAY)); + } + } + } + + return addSymmetricJitter(Math.min(INITIAL_RETRY_DELAY * 2 ** retryAttempt, MAX_RETRY_DELAY)); +} + +export async function requestWithRetries( + requestFn: () => Promise, + maxRetries: number = DEFAULT_MAX_RETRIES, +): Promise { + let response: Response = await requestFn(); + + for (let i = 0; i < maxRetries; ++i) { + if (isRetryableStatusCode(response.status)) { + const delay = getRetryDelayFromHeaders(response, i); + + await new Promise((resolve) => setTimeout(resolve, delay)); + response = await requestFn(); + } else { + break; + } + } + return response!; +} diff --git a/src/core/fetcher/signals.ts b/src/core/fetcher/signals.ts new file mode 100644 index 0000000..ba74c4d --- /dev/null +++ b/src/core/fetcher/signals.ts @@ -0,0 +1,35 @@ +const TIMEOUT = "timeout"; + +export function getTimeoutSignal(timeoutMs: number): { signal: AbortSignal; abortId: ReturnType } { + const controller = new AbortController(); + const abortId = setTimeout(() => controller.abort(TIMEOUT), timeoutMs); + return { signal: controller.signal, abortId }; +} + +export function anySignal(...args: AbortSignal[] | [AbortSignal[]]): AbortSignal { + const signals = (args.length === 1 && Array.isArray(args[0]) ? args[0] : args) as AbortSignal[]; + + const controller = new AbortController(); + + for (const signal of signals) { + if (signal.aborted) { + controller.abort((signal as any)?.reason); + return controller.signal; + } + + signal.addEventListener("abort", () => controller.abort((signal as any)?.reason), { + signal: controller.signal, + }); + + // Re-check after adding listener: the signal may have aborted + // between the initial `signal.aborted` check and the `addEventListener` + // call above. If it did, the abort event was already dispatched and + // the listener will never fire — we must manually abort. + if (signal.aborted) { + controller.abort((signal as any)?.reason); + return controller.signal; + } + } + + return controller.signal; +} diff --git a/src/core/file/exports.ts b/src/core/file/exports.ts new file mode 100644 index 0000000..3b0b396 --- /dev/null +++ b/src/core/file/exports.ts @@ -0,0 +1 @@ +export type { Uploadable } from "./types.js"; diff --git a/src/core/file/file.ts b/src/core/file/file.ts new file mode 100644 index 0000000..d4921eb --- /dev/null +++ b/src/core/file/file.ts @@ -0,0 +1,222 @@ +import type { Uploadable } from "./types.js"; + +export async function toBinaryUploadRequest( + file: Uploadable, +): Promise<{ body: Uploadable.FileLike; headers?: Record }> { + const { data, filename, contentLength, contentType } = await getFileWithMetadata(file); + const request = { + body: data, + headers: {} as Record, + }; + if (filename) { + request.headers["Content-Disposition"] = `attachment; filename="${filename}"`; + } + if (contentType) { + request.headers["Content-Type"] = contentType; + } + if (contentLength != null) { + request.headers["Content-Length"] = contentLength.toString(); + } + return request; +} + +export async function toMultipartDataPart( + file: Uploadable, +): Promise<{ data: Uploadable.FileLike; filename?: string; contentType?: string }> { + const { data, filename, contentType } = await getFileWithMetadata(file, { + noSniffFileSize: true, + }); + return { + data, + filename, + contentType, + }; +} + +async function getFileWithMetadata( + file: Uploadable, + { noSniffFileSize }: { noSniffFileSize?: boolean } = {}, +): Promise { + if (file == null) { + throw new Error( + `Expected file to be a Blob, Buffer, ReadableStream, or an object with a "path" or "data" property, but received ${file === null ? "null" : "undefined"}.`, + ); + } + if (isFileLike(file)) { + return getFileWithMetadata( + { + data: file, + }, + { noSniffFileSize }, + ); + } + + if ("path" in file) { + const fs = await import("fs"); + if (!fs?.createReadStream) { + throw new Error("File path uploads are not supported in this environment."); + } + const data = fs.createReadStream(file.path); + const contentLength = + file.contentLength ?? (noSniffFileSize === true ? undefined : await tryGetFileSizeFromPath(file.path)); + const filename = file.filename ?? getNameFromPath(file.path); + return { + data, + filename, + contentType: file.contentType, + contentLength, + }; + } + if ("data" in file) { + const data = file.data; + const contentLength = + file.contentLength ?? + (await tryGetContentLengthFromFileLike(data, { + noSniffFileSize, + })); + const filename = file.filename ?? tryGetNameFromFileLike(data); + return { + data, + filename, + contentType: file.contentType ?? tryGetContentTypeFromFileLike(data), + contentLength, + }; + } + + throw new Error(`Invalid FileUpload of type ${typeof file}: ${JSON.stringify(file)}`); +} + +function isFileLike(value: unknown): value is Uploadable.FileLike { + return ( + isBuffer(value) || + isArrayBufferView(value) || + isArrayBuffer(value) || + isUint8Array(value) || + isBlob(value) || + isFile(value) || + isStreamLike(value) || + isReadableStream(value) + ); +} + +async function tryGetFileSizeFromPath(path: string): Promise { + try { + const fs = await import("fs"); + if (!fs?.promises?.stat) { + return undefined; + } + const fileStat = await fs.promises.stat(path); + return fileStat.size; + } catch (_fallbackError) { + return undefined; + } +} + +function tryGetNameFromFileLike(data: Uploadable.FileLike): string | undefined { + if (isNamedValue(data)) { + return data.name; + } + if (isPathedValue(data)) { + return getNameFromPath(data.path.toString()); + } + return undefined; +} + +async function tryGetContentLengthFromFileLike( + data: Uploadable.FileLike, + { noSniffFileSize }: { noSniffFileSize?: boolean } = {}, +): Promise { + if (isBuffer(data)) { + return data.length; + } + if (isArrayBufferView(data)) { + return data.byteLength; + } + if (isArrayBuffer(data)) { + return data.byteLength; + } + if (isBlob(data)) { + return data.size; + } + if (isFile(data)) { + return data.size; + } + if (noSniffFileSize === true) { + return undefined; + } + if (isPathedValue(data)) { + return await tryGetFileSizeFromPath(data.path.toString()); + } + return undefined; +} + +function tryGetContentTypeFromFileLike(data: Uploadable.FileLike): string | undefined { + if (isBlob(data)) { + return data.type; + } + if (isFile(data)) { + return data.type; + } + + return undefined; +} + +function getNameFromPath(path: string): string | undefined { + const lastForwardSlash = path.lastIndexOf("/"); + const lastBackSlash = path.lastIndexOf("\\"); + const lastSlashIndex = Math.max(lastForwardSlash, lastBackSlash); + return lastSlashIndex >= 0 ? path.substring(lastSlashIndex + 1) : path; +} + +type NamedValue = { + name: string; +} & unknown; + +type PathedValue = { + path: string | { toString(): string }; +} & unknown; + +type StreamLike = { + read?: () => unknown; + pipe?: (dest: unknown) => unknown; +} & unknown; + +function isNamedValue(value: unknown): value is NamedValue { + return typeof value === "object" && value != null && "name" in value; +} + +function isPathedValue(value: unknown): value is PathedValue { + return typeof value === "object" && value != null && "path" in value; +} + +function isStreamLike(value: unknown): value is StreamLike { + return typeof value === "object" && value != null && ("read" in value || "pipe" in value); +} + +function isReadableStream(value: unknown): value is ReadableStream { + return typeof value === "object" && value != null && "getReader" in value; +} + +function isBuffer(value: unknown): value is Buffer { + return typeof Buffer !== "undefined" && Buffer.isBuffer && Buffer.isBuffer(value); +} + +function isArrayBufferView(value: unknown): value is ArrayBufferView { + return typeof ArrayBuffer !== "undefined" && ArrayBuffer.isView(value); +} + +function isArrayBuffer(value: unknown): value is ArrayBuffer { + return typeof ArrayBuffer !== "undefined" && value instanceof ArrayBuffer; +} + +function isUint8Array(value: unknown): value is Uint8Array { + return typeof Uint8Array !== "undefined" && value instanceof Uint8Array; +} + +function isBlob(value: unknown): value is Blob { + return typeof Blob !== "undefined" && value instanceof Blob; +} + +function isFile(value: unknown): value is File { + return typeof File !== "undefined" && value instanceof File; +} diff --git a/src/core/file/index.ts b/src/core/file/index.ts new file mode 100644 index 0000000..fc16dd5 --- /dev/null +++ b/src/core/file/index.ts @@ -0,0 +1,2 @@ +export * from "./file.js"; +export * from "./types.js"; diff --git a/src/core/file/types.ts b/src/core/file/types.ts new file mode 100644 index 0000000..531b692 --- /dev/null +++ b/src/core/file/types.ts @@ -0,0 +1,81 @@ +/** + * A file that can be uploaded. Can be a file-like object (stream, buffer, blob, etc.), + * a path to a file, or an object with a file-like object and metadata. + */ +export type Uploadable = Uploadable.FileLike | Uploadable.FromPath | Uploadable.WithMetadata; + +export namespace Uploadable { + /** + * Various file-like objects that can be used to upload a file. + */ + export type FileLike = + | ArrayBuffer + | ArrayBufferLike + | ArrayBufferView + | Uint8Array + | import("buffer").Buffer + | import("buffer").Blob + | import("buffer").File + | import("stream").Readable + | import("stream/web").ReadableStream + | globalThis.Blob + | globalThis.File + | ReadableStream; + + /** + * A file path with optional metadata, used for uploading a file from the file system. + */ + export type FromPath = { + /** The path to the file to upload */ + path: string; + /** + * Optional override for the file name (defaults to basename of path). + * This is used to set the `Content-Disposition` header in upload requests. + */ + filename?: string; + /** + * Optional MIME type of the file (e.g., 'image/jpeg', 'text/plain'). + * This is used to set the `Content-Type` header in upload requests. + */ + contentType?: string; + /** + * Optional file size in bytes. + * If not provided, the file size will be determined from the file system. + * The content length is used to set the `Content-Length` header in upload requests. + */ + contentLength?: number; + }; + + /** + * A file-like object with metadata, used for uploading files. + */ + export type WithMetadata = { + /** The file data */ + data: FileLike; + /** + * Optional override for the file name (defaults to basename of path). + * This is used to set the `Content-Disposition` header in upload requests. + */ + filename?: string; + /** + * Optional MIME type of the file (e.g., 'image/jpeg', 'text/plain'). + * This is used to set the `Content-Type` header in upload requests. + * + * If not provided, the content type may be determined from the data itself. + * * If the data is a `File`, `Blob`, or similar, the content type will be determined from the file itself, if the type is set. + * * Any other data type will not have a content type set, and the upload request will use `Content-Type: application/octet-stream` instead. + */ + contentType?: string; + /** + * Optional file size in bytes. + * The content length is used to set the `Content-Length` header in upload requests. + * If the content length is not provided and cannot be determined, the upload request will not include the `Content-Length` header, but will use `Transfer-Encoding: chunked` instead. + * + * If not provided, the file size will be determined depending on the data type. + * * If the data is of type `fs.ReadStream` (`createReadStream`), the size will be determined from the file system. + * * If the data is a `Buffer`, `ArrayBuffer`, `Uint8Array`, `Blob`, `File`, or similar, the size will be determined from the data itself. + * * If the data is a `Readable` or `ReadableStream`, the size will not be determined. + */ + contentLength?: number; + }; +} diff --git a/src/core/headers.ts b/src/core/headers.ts new file mode 100644 index 0000000..be45c45 --- /dev/null +++ b/src/core/headers.ts @@ -0,0 +1,33 @@ +export function mergeHeaders(...headersArray: (Record | null | undefined)[]): Record { + const result: Record = {}; + + for (const [key, value] of headersArray + .filter((headers) => headers != null) + .flatMap((headers) => Object.entries(headers))) { + const insensitiveKey = key.toLowerCase(); + if (value != null) { + result[insensitiveKey] = value; + } else if (insensitiveKey in result) { + delete result[insensitiveKey]; + } + } + + return result; +} + +export function mergeOnlyDefinedHeaders( + ...headersArray: (Record | null | undefined)[] +): Record { + const result: Record = {}; + + for (const [key, value] of headersArray + .filter((headers) => headers != null) + .flatMap((headers) => Object.entries(headers))) { + const insensitiveKey = key.toLowerCase(); + if (value != null) { + result[insensitiveKey] = value; + } + } + + return result; +} diff --git a/src/core/index.ts b/src/core/index.ts new file mode 100644 index 0000000..42fbe52 --- /dev/null +++ b/src/core/index.ts @@ -0,0 +1,7 @@ +export * from "./auth/index.js"; +export * from "./base64.js"; +export * from "./fetcher/index.js"; +export * as file from "./file/index.js"; +export * as logging from "./logging/index.js"; +export * from "./runtime/index.js"; +export * as url from "./url/index.js"; diff --git a/src/core/json.ts b/src/core/json.ts new file mode 100644 index 0000000..c052f32 --- /dev/null +++ b/src/core/json.ts @@ -0,0 +1,27 @@ +/** + * Serialize a value to JSON + * @param value A JavaScript value, usually an object or array, to be converted. + * @param replacer A function that transforms the results. + * @param space Adds indentation, white space, and line break characters to the return-value JSON text to make it easier to read. + * @returns JSON string + */ +export const toJson = ( + value: unknown, + replacer?: (this: unknown, key: string, value: unknown) => unknown, + space?: string | number, +): string => { + return JSON.stringify(value, replacer, space); +}; + +/** + * Parse JSON string to object, array, or other type + * @param text A valid JSON string. + * @param reviver A function that transforms the results. This function is called for each member of the object. If a member contains nested objects, the nested objects are transformed before the parent object is. + * @returns Parsed object, array, or other type + */ +export function fromJson( + text: string, + reviver?: (this: unknown, key: string, value: unknown) => unknown, +): T { + return JSON.parse(text, reviver); +} diff --git a/src/core/logging/exports.ts b/src/core/logging/exports.ts new file mode 100644 index 0000000..88f6c00 --- /dev/null +++ b/src/core/logging/exports.ts @@ -0,0 +1,19 @@ +import * as logger from "./logger.js"; + +export namespace logging { + /** + * Configuration for logger instances. + */ + export type LogConfig = logger.LogConfig; + export type LogLevel = logger.LogLevel; + export const LogLevel: typeof logger.LogLevel = logger.LogLevel; + export type ILogger = logger.ILogger; + /** + * Console logger implementation that outputs to the console. + */ + export type ConsoleLogger = logger.ConsoleLogger; + /** + * Console logger implementation that outputs to the console. + */ + export const ConsoleLogger: typeof logger.ConsoleLogger = logger.ConsoleLogger; +} diff --git a/src/core/logging/index.ts b/src/core/logging/index.ts new file mode 100644 index 0000000..d81cc32 --- /dev/null +++ b/src/core/logging/index.ts @@ -0,0 +1 @@ +export * from "./logger.js"; diff --git a/src/core/logging/logger.ts b/src/core/logging/logger.ts new file mode 100644 index 0000000..a3f3673 --- /dev/null +++ b/src/core/logging/logger.ts @@ -0,0 +1,203 @@ +export const LogLevel = { + Debug: "debug", + Info: "info", + Warn: "warn", + Error: "error", +} as const; +export type LogLevel = (typeof LogLevel)[keyof typeof LogLevel]; +const logLevelMap: Record = { + [LogLevel.Debug]: 1, + [LogLevel.Info]: 2, + [LogLevel.Warn]: 3, + [LogLevel.Error]: 4, +}; + +export interface ILogger { + /** + * Logs a debug message. + * @param message - The message to log + * @param args - Additional arguments to log + */ + debug(message: string, ...args: unknown[]): void; + /** + * Logs an info message. + * @param message - The message to log + * @param args - Additional arguments to log + */ + info(message: string, ...args: unknown[]): void; + /** + * Logs a warning message. + * @param message - The message to log + * @param args - Additional arguments to log + */ + warn(message: string, ...args: unknown[]): void; + /** + * Logs an error message. + * @param message - The message to log + * @param args - Additional arguments to log + */ + error(message: string, ...args: unknown[]): void; +} + +/** + * Configuration for logger initialization. + */ +export interface LogConfig { + /** + * Minimum log level to output. + * @default LogLevel.Info + */ + level?: LogLevel; + /** + * Logger implementation to use. + * @default new ConsoleLogger() + */ + logger?: ILogger; + /** + * Whether logging should be silenced. + * @default true + */ + silent?: boolean; +} + +/** + * Default console-based logger implementation. + */ +export class ConsoleLogger implements ILogger { + debug(message: string, ...args: unknown[]): void { + console.debug(message, ...args); + } + info(message: string, ...args: unknown[]): void { + console.info(message, ...args); + } + warn(message: string, ...args: unknown[]): void { + console.warn(message, ...args); + } + error(message: string, ...args: unknown[]): void { + console.error(message, ...args); + } +} + +/** + * Logger class that provides level-based logging functionality. + */ +export class Logger { + private readonly level: number; + private readonly logger: ILogger; + private readonly silent: boolean; + + /** + * Creates a new logger instance. + * @param config - Logger configuration + */ + constructor(config: Required) { + this.level = logLevelMap[config.level]; + this.logger = config.logger; + this.silent = config.silent; + } + + /** + * Checks if a log level should be output based on configuration. + * @param level - The log level to check + * @returns True if the level should be logged + */ + public shouldLog(level: LogLevel): boolean { + return !this.silent && this.level <= logLevelMap[level]; + } + + /** + * Checks if debug logging is enabled. + * @returns True if debug logs should be output + */ + public isDebug(): boolean { + return this.shouldLog(LogLevel.Debug); + } + + /** + * Logs a debug message if debug logging is enabled. + * @param message - The message to log + * @param args - Additional arguments to log + */ + public debug(message: string, ...args: unknown[]): void { + if (this.isDebug()) { + this.logger.debug(message, ...args); + } + } + + /** + * Checks if info logging is enabled. + * @returns True if info logs should be output + */ + public isInfo(): boolean { + return this.shouldLog(LogLevel.Info); + } + + /** + * Logs an info message if info logging is enabled. + * @param message - The message to log + * @param args - Additional arguments to log + */ + public info(message: string, ...args: unknown[]): void { + if (this.isInfo()) { + this.logger.info(message, ...args); + } + } + + /** + * Checks if warning logging is enabled. + * @returns True if warning logs should be output + */ + public isWarn(): boolean { + return this.shouldLog(LogLevel.Warn); + } + + /** + * Logs a warning message if warning logging is enabled. + * @param message - The message to log + * @param args - Additional arguments to log + */ + public warn(message: string, ...args: unknown[]): void { + if (this.isWarn()) { + this.logger.warn(message, ...args); + } + } + + /** + * Checks if error logging is enabled. + * @returns True if error logs should be output + */ + public isError(): boolean { + return this.shouldLog(LogLevel.Error); + } + + /** + * Logs an error message if error logging is enabled. + * @param message - The message to log + * @param args - Additional arguments to log + */ + public error(message: string, ...args: unknown[]): void { + if (this.isError()) { + this.logger.error(message, ...args); + } + } +} + +export function createLogger(config?: LogConfig | Logger): Logger { + if (config == null) { + return defaultLogger; + } + if (config instanceof Logger) { + return config; + } + config = config ?? {}; + config.level ??= LogLevel.Info; + config.logger ??= new ConsoleLogger(); + config.silent ??= true; + return new Logger(config as Required); +} + +const defaultLogger: Logger = new Logger({ + level: LogLevel.Info, + logger: new ConsoleLogger(), + silent: true, +}); diff --git a/src/core/requestBody.ts b/src/core/requestBody.ts new file mode 100644 index 0000000..d58ef59 --- /dev/null +++ b/src/core/requestBody.ts @@ -0,0 +1,26 @@ +/** + * Spreads caller-supplied `additionalBodyParameters` (from `requestOptions.additionalBodyParameters`) + * on top of the request body. Caller-supplied properties win over the endpoint body. When no + * additional body parameters are provided, the original body is returned unchanged so serialization + * is unaffected. + * + * The merge only applies to plain-object (JSON object) bodies. When the body is `null`/`undefined` + * the additional parameters become the body; when the body is an array or a primitive JSON value it + * is returned unchanged, since object properties cannot be spread into it. This mirrors the Python + * SDK, which only merges additional body parameters into mapping bodies. + */ +export function mergeAdditionalBodyParameters( + body: unknown, + additionalBodyParameters: Record | undefined, +): unknown { + if (additionalBodyParameters == null) { + return body; + } + if (body == null) { + return { ...additionalBodyParameters }; + } + if (typeof body === "object" && !Array.isArray(body)) { + return { ...body, ...additionalBodyParameters }; + } + return body; +} diff --git a/src/core/runtime/index.ts b/src/core/runtime/index.ts new file mode 100644 index 0000000..85a3272 --- /dev/null +++ b/src/core/runtime/index.ts @@ -0,0 +1 @@ +export { getUserAgent, RUNTIME } from "./runtime.js"; diff --git a/src/core/runtime/runtime.ts b/src/core/runtime/runtime.ts new file mode 100644 index 0000000..d367ce6 --- /dev/null +++ b/src/core/runtime/runtime.ts @@ -0,0 +1,231 @@ +interface DenoGlobal { + version: { + deno: string; + }; + build?: { + os?: string; + arch?: string; + }; +} + +interface BunGlobal { + version: string; +} + +declare const Deno: DenoGlobal | undefined; +declare const Bun: BunGlobal | undefined; +declare const EdgeRuntime: string | undefined; +declare const self: typeof globalThis.self & { + importScripts?: unknown; +}; + +/** + * A constant that indicates which environment and version the SDK is running in. + */ +export const RUNTIME: Runtime = evaluateRuntime(); + +export interface Runtime { + type: "browser" | "web-worker" | "deno" | "bun" | "node" | "react-native" | "unknown" | "workerd" | "edge-runtime"; + version?: string; + parsedVersion?: number; + /** + * The operating system the SDK is running on, when it can be determined + * (e.g. "linux", "darwin", "win32" on server runtimes). Undefined in + * environments where the OS is not observable (e.g. browsers). + */ + os?: string; + /** + * The CPU architecture the SDK is running on, when it can be determined + * (e.g. "x64", "arm64" on server runtimes). Undefined in environments where + * the architecture is not observable (e.g. browsers). + */ + arch?: string; +} + +function evaluateRuntime(): Runtime { + /** + * A constant that indicates whether the environment the code is running is a Web Browser. + */ + const isBrowser = typeof window !== "undefined" && typeof window.document !== "undefined"; + if (isBrowser) { + return { + type: "browser", + version: window.navigator.userAgent, + }; + } + + /** + * A constant that indicates whether the environment the code is running is Cloudflare. + * https://developers.cloudflare.com/workers/runtime-apis/web-standards/#navigatoruseragent + */ + const isCloudflare = typeof globalThis !== "undefined" && globalThis?.navigator?.userAgent === "Cloudflare-Workers"; + if (isCloudflare) { + return { + type: "workerd", + }; + } + + /** + * A constant that indicates whether the environment the code is running is Edge Runtime. + * https://vercel.com/docs/functions/runtimes/edge-runtime#check-if-you're-running-on-the-edge-runtime + */ + const isEdgeRuntime = typeof EdgeRuntime === "string"; + if (isEdgeRuntime) { + return { + type: "edge-runtime", + }; + } + + /** + * A constant that indicates whether the environment the code is running is a Web Worker. + */ + const isWebWorker = + typeof self === "object" && + typeof self?.importScripts === "function" && + (self.constructor?.name === "DedicatedWorkerGlobalScope" || + self.constructor?.name === "ServiceWorkerGlobalScope" || + self.constructor?.name === "SharedWorkerGlobalScope"); + if (isWebWorker) { + return { + type: "web-worker", + }; + } + + /** + * A constant that indicates whether the environment the code is running is Deno. + * FYI Deno spoofs process.versions.node, see https://deno.land/std@0.177.0/node/process.ts?s=versions + */ + const isDeno = + typeof Deno !== "undefined" && typeof Deno.version !== "undefined" && typeof Deno.version.deno !== "undefined"; + if (isDeno) { + return { + type: "deno", + version: Deno.version.deno, + os: Deno.build?.os, + arch: Deno.build?.arch, + }; + } + + /** + * A constant that indicates whether the environment the code is running is Bun.sh. + */ + const isBun = typeof Bun !== "undefined" && typeof Bun.version !== "undefined"; + if (isBun) { + return { + type: "bun", + version: Bun.version, + os: typeof process !== "undefined" ? process.platform : undefined, + arch: typeof process !== "undefined" ? process.arch : undefined, + }; + } + + /** + * A constant that indicates whether the environment the code is running is in React-Native. + * This check should come before Node.js detection since React Native may have a process polyfill. + * https://github.com/facebook/react-native/blob/main/packages/react-native/Libraries/Core/setUpNavigator.js + */ + const isReactNative = typeof navigator !== "undefined" && navigator?.product === "ReactNative"; + if (isReactNative) { + return { + type: "react-native", + }; + } + + /** + * A constant that indicates whether the environment the code is running is Node.JS. + * + * We assign `process` to a local variable first to avoid being flagged by + * bundlers that perform static analysis on `process.versions` (e.g. Next.js + * Edge Runtime warns about Node.js APIs even when they are guarded). + */ + const _process = typeof process !== "undefined" ? process : undefined; + const isNode = typeof _process !== "undefined" && typeof _process.versions?.node === "string"; + if (isNode) { + return { + type: "node", + version: _process.versions.node, + parsedVersion: Number(_process.versions.node.split(".")[0]), + os: _process.platform, + arch: _process.arch, + }; + } + + return { + type: "unknown", + }; +} + +/** + * Display names for the language runtimes whose version is meaningful to encode + * in a User-Agent. Environments where a version string is not useful (e.g. + * browsers, where `version` is the full navigator UA) are intentionally mapped + * to `undefined` so they are omitted from the User-Agent. + */ +const RUNTIME_DISPLAY_NAMES: Record = { + node: "Node", + deno: "Deno", + bun: "Bun", + browser: undefined, + "web-worker": undefined, + "react-native": undefined, + workerd: undefined, + "edge-runtime": undefined, + unknown: undefined, +}; + +/** + * CPU architecture aliases that all refer to 64-bit x86. They are normalized to + * the single canonical token `x86_64` so the User-Agent architecture label is + * consistent regardless of which runtime reports it (Node reports `x64`, others + * report `amd64` or `x86_64`). + */ +const X86_64_ARCH_ALIASES = new Set(["x64", "amd64", "x86_64"]); + +/** + * Normalizes a CPU architecture token, collapsing the 64-bit x86 aliases + * (`x64`, `amd64`, `x86_64`) to `x86_64`. Other architectures are returned + * unchanged. + */ +function normalizeArch(arch: string | undefined): string | undefined { + if (arch == null) { + return arch; + } + return X86_64_ARCH_ALIASES.has(arch.toLowerCase()) ? "x86_64" : arch; +} + +/** + * Percent-encodes the `@` and `/` characters in an npm package name so the + * User-Agent product token stays within the RFC 7230 token grammar. The + * original scoped package name can be recovered by URL-decoding (e.g. + * `@dummy/sdk` becomes `%40dummy%2Fsdk`). + */ +function encodeProductName(sdkName: string): string { + return sdkName.replace(/@/g, "%40").replace(/\//g, "%2F"); +} + +/** + * Builds a structured User-Agent string of the form + * `{sdkName}/{sdkVersion} ({os}; {arch}) {runtime}/{runtimeVersion}` + * where the platform group and runtime segment are omitted gracefully when the + * underlying values cannot be determined (e.g. in a browser). + */ +export function getUserAgent(sdkName: string, sdkVersion: string): string { + let userAgent = `${encodeProductName(sdkName)}/${sdkVersion}`; + + const platform = [RUNTIME.os, normalizeArch(RUNTIME.arch)].filter( + (part): part is string => part != null && part.length > 0, + ); + if (platform.length > 0) { + userAgent += ` (${platform.join("; ")})`; + } + + const runtimeName = RUNTIME_DISPLAY_NAMES[RUNTIME.type]; + if (runtimeName != null) { + userAgent += ` ${runtimeName}`; + if (RUNTIME.version != null && RUNTIME.version.length > 0) { + userAgent += `/${RUNTIME.version}`; + } + } + + return userAgent; +} diff --git a/src/core/url/QueryStringBuilder.ts b/src/core/url/QueryStringBuilder.ts new file mode 100644 index 0000000..b045221 --- /dev/null +++ b/src/core/url/QueryStringBuilder.ts @@ -0,0 +1,87 @@ +import { toQueryString } from "./qs.js"; + +/** + * Creates a fluent builder for constructing URL query strings. + * + * Each `.add()` call serializes its value immediately (like C#'s builder), + * so no format tracking is needed — the style is applied at add-time. + * + * Usage (generated code): + * + * const qs = core.url.queryBuilder() + * .add("limit", limit) + * .add("tags", tags, { style: "comma" }) // explode: false + * .mergeAdditional(requestOptions?.queryParams) + * .build(); + */ +export function queryBuilder(): QueryStringBuilder { + return new QueryStringBuilder(); +} + +class QueryStringBuilder { + private parts: Map = new Map(); + + /** + * Adds a query parameter, serializing it immediately. + * + * By default arrays use "repeat" format (`key=a&key=b`). + * Pass `{ style: "comma" }` for OpenAPI `explode: false` parameters + * to get comma-separated values (`key=a,b,c`). + * + * Null / undefined values are silently skipped. + */ + add(key: string, value: unknown, options?: { style?: "comma" }): this { + if (value === undefined || value === null) { + return this; + } + const serialized = toQueryString( + { [key]: value }, + { arrayFormat: options?.style === "comma" ? "comma" : "repeat" }, + ); + if (serialized.length > 0) { + this.parts.set(key, serialized); + } + return this; + } + + /** + * Adds multiple query parameters at once from a record. + * All parameters use the default "repeat" array format. + * Null / undefined values are silently skipped. + */ + addMany(params: Record): this { + if (params != null) { + for (const [key, value] of Object.entries(params)) { + this.add(key, value); + } + } + return this; + } + + /** + * Merges additional query parameters supplied at call-time via + * `requestOptions.queryParams`. Overrides existing keys (last-write-wins). + */ + mergeAdditional(additionalParams?: Record): this { + if (additionalParams != null) { + for (const [key, value] of Object.entries(additionalParams)) { + if (value === undefined || value === null) { + continue; + } + const serialized = toQueryString({ [key]: value }, { arrayFormat: "repeat" }); + if (serialized.length > 0) { + this.parts.set(key, serialized); + } + } + } + return this; + } + + /** + * Returns the assembled query string (without the leading `?`). + * Returns an empty string when no parameters were added. + */ + build(): string { + return [...this.parts.values()].join("&"); + } +} diff --git a/src/core/url/encodePathParam.ts b/src/core/url/encodePathParam.ts new file mode 100644 index 0000000..19b9012 --- /dev/null +++ b/src/core/url/encodePathParam.ts @@ -0,0 +1,18 @@ +export function encodePathParam(param: unknown): string { + if (param === null) { + return "null"; + } + const typeofParam = typeof param; + switch (typeofParam) { + case "undefined": + return "undefined"; + case "string": + case "number": + case "boolean": + break; + default: + param = String(param); + break; + } + return encodeURIComponent(param as string | number | boolean); +} diff --git a/src/core/url/index.ts b/src/core/url/index.ts new file mode 100644 index 0000000..ca9d4fb --- /dev/null +++ b/src/core/url/index.ts @@ -0,0 +1,4 @@ +export { encodePathParam } from "./encodePathParam.js"; +export { join } from "./join.js"; +export { queryBuilder } from "./QueryStringBuilder.js"; +export { toQueryString } from "./qs.js"; diff --git a/src/core/url/join.ts b/src/core/url/join.ts new file mode 100644 index 0000000..7ca7dae --- /dev/null +++ b/src/core/url/join.ts @@ -0,0 +1,79 @@ +export function join(base: string, ...segments: string[]): string { + if (!base) { + return ""; + } + + if (segments.length === 0) { + return base; + } + + if (base.includes("://")) { + let url: URL; + try { + url = new URL(base); + } catch { + return joinPath(base, ...segments); + } + + const lastSegment = segments[segments.length - 1]; + const shouldPreserveTrailingSlash = lastSegment?.endsWith("/"); + + for (const segment of segments) { + const cleanSegment = trimSlashes(segment); + if (cleanSegment) { + url.pathname = joinPathSegments(url.pathname, cleanSegment); + } + } + + if (shouldPreserveTrailingSlash && !url.pathname.endsWith("/")) { + url.pathname += "/"; + } + + return url.toString(); + } + + return joinPath(base, ...segments); +} + +function joinPath(base: string, ...segments: string[]): string { + if (segments.length === 0) { + return base; + } + + let result = base; + + const lastSegment = segments[segments.length - 1]; + const shouldPreserveTrailingSlash = lastSegment?.endsWith("/"); + + for (const segment of segments) { + const cleanSegment = trimSlashes(segment); + if (cleanSegment) { + result = joinPathSegments(result, cleanSegment); + } + } + + if (shouldPreserveTrailingSlash && !result.endsWith("/")) { + result += "/"; + } + + return result; +} + +function joinPathSegments(left: string, right: string): string { + if (left.endsWith("/")) { + return left + right; + } + return `${left}/${right}`; +} + +function trimSlashes(str: string): string { + if (!str) return str; + + let start = 0; + let end = str.length; + + if (str.startsWith("/")) start = 1; + if (str.endsWith("/")) end = str.length - 1; + + return start === 0 && end === str.length ? str : str.slice(start, end); +} diff --git a/src/core/url/qs.ts b/src/core/url/qs.ts new file mode 100644 index 0000000..aebb95a --- /dev/null +++ b/src/core/url/qs.ts @@ -0,0 +1,87 @@ +type ArrayFormat = "indices" | "repeat" | "comma"; + +interface QueryStringOptions { + arrayFormat?: ArrayFormat; + encode?: boolean; +} + +const defaultQsOptions: Required = { + arrayFormat: "indices", + encode: true, +} as const; + +function encodeValue(value: unknown, shouldEncode: boolean): string { + if (value === undefined) { + return ""; + } + if (value === null) { + return ""; + } + const stringValue = String(value); + return shouldEncode ? encodeURIComponent(stringValue) : stringValue; +} + +function stringifyObject(obj: Record, prefix = "", options: Required): string[] { + const parts: string[] = []; + + for (const [key, value] of Object.entries(obj)) { + const fullKey = prefix ? `${prefix}[${key}]` : key; + + if (value == null) { + continue; + } + + if (Array.isArray(value)) { + if (value.length === 0) { + continue; + } + const effectiveFormat = options.arrayFormat; + if (effectiveFormat === "comma") { + const encodedKey = options.encode ? encodeURIComponent(fullKey) : fullKey; + const encodedValues = value + .filter((item) => item !== undefined && item !== null) + .map((item) => encodeValue(item, options.encode)); + if (encodedValues.length > 0) { + parts.push(`${encodedKey}=${encodedValues.join(",")}`); + } + } else { + for (let i = 0; i < value.length; i++) { + const item = value[i]; + if (item == null) { + continue; + } + if (typeof item === "object" && !Array.isArray(item) && item !== null) { + const arrayKey = effectiveFormat === "indices" ? `${fullKey}[${i}]` : fullKey; + parts.push(...stringifyObject(item as Record, arrayKey, options)); + } else { + const arrayKey = effectiveFormat === "indices" ? `${fullKey}[${i}]` : fullKey; + const encodedKey = options.encode ? encodeURIComponent(arrayKey) : arrayKey; + parts.push(`${encodedKey}=${encodeValue(item, options.encode)}`); + } + } + } + } else if (typeof value === "object" && value !== null) { + if (Object.keys(value as Record).length === 0) { + continue; + } + parts.push(...stringifyObject(value as Record, fullKey, options)); + } else { + const encodedKey = options.encode ? encodeURIComponent(fullKey) : fullKey; + parts.push(`${encodedKey}=${encodeValue(value, options.encode)}`); + } + } + + return parts; +} + +export function toQueryString(obj: unknown, options?: QueryStringOptions): string { + if (obj == null || typeof obj !== "object") { + return ""; + } + + const parts = stringifyObject(obj as Record, "", { + ...defaultQsOptions, + ...options, + }); + return parts.join("&"); +} diff --git a/src/errors/CloudpdfApiError.ts b/src/errors/CloudpdfApiError.ts new file mode 100644 index 0000000..6f85dc7 --- /dev/null +++ b/src/errors/CloudpdfApiError.ts @@ -0,0 +1,68 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as core from "../core/index.js"; +import { toJson } from "../core/json.js"; + +export class CloudpdfApiError extends Error { + public readonly statusCode?: number; + public readonly body?: unknown; + public readonly rawResponse?: core.RawResponse; + public readonly cause?: unknown; + + constructor({ + message, + statusCode, + body, + rawResponse, + cause, + }: { + message?: string; + statusCode?: number; + body?: unknown; + rawResponse?: core.RawResponse; + cause?: unknown; + }) { + super(buildMessage({ message, statusCode, body })); + Object.setPrototypeOf(this, new.target.prototype); + if (Error.captureStackTrace) { + Error.captureStackTrace(this, this.constructor); + } + + this.name = "CloudpdfApiError"; + this.statusCode = statusCode; + this.body = body; + this.rawResponse = rawResponse; + if (cause != null) { + this.cause = cause; + } + } + + public get requestId(): string | undefined { + return this.rawResponse?.headers?.get("x-request-id") ?? undefined; + } +} + +function buildMessage({ + message, + statusCode, + body, +}: { + message: string | undefined; + statusCode: number | undefined; + body: unknown | undefined; +}): string { + const lines: string[] = []; + if (message != null) { + lines.push(message); + } + + if (statusCode != null) { + lines.push(`Status code: ${statusCode.toString()}`); + } + + if (body != null) { + lines.push(`Body: ${toJson(body, undefined, 2)}`); + } + + return lines.join("\n"); +} diff --git a/src/errors/CloudpdfApiTimeoutError.ts b/src/errors/CloudpdfApiTimeoutError.ts new file mode 100644 index 0000000..a92740e --- /dev/null +++ b/src/errors/CloudpdfApiTimeoutError.ts @@ -0,0 +1,18 @@ +// This file was auto-generated by Fern from our API Definition. + +import * as errors from "./index.js"; + +export class CloudpdfApiTimeoutError extends errors.CloudpdfApiError { + constructor(message: string, opts?: { cause?: unknown }) { + super({ + message: message, + cause: opts?.cause, + }); + Object.setPrototypeOf(this, new.target.prototype); + if (Error.captureStackTrace) { + Error.captureStackTrace(this, this.constructor); + } + + this.name = "CloudpdfApiTimeoutError"; + } +} diff --git a/src/errors/handleNonStatusCodeError.ts b/src/errors/handleNonStatusCodeError.ts new file mode 100644 index 0000000..a60256c --- /dev/null +++ b/src/errors/handleNonStatusCodeError.ts @@ -0,0 +1,40 @@ +// This file was auto-generated by Fern from our API Definition. + +import type * as core from "../core/index.js"; +import * as errors from "./index.js"; + +export function handleNonStatusCodeError( + error: core.Fetcher.Error, + rawResponse: core.RawResponse, + method: string, + path: string, +): never { + switch (error.reason) { + case "non-json": + throw new errors.CloudpdfApiError({ + statusCode: error.statusCode, + body: error.rawBody, + rawResponse: rawResponse, + }); + case "body-is-null": + throw new errors.CloudpdfApiError({ + statusCode: error.statusCode, + rawResponse: rawResponse, + }); + case "timeout": + throw new errors.CloudpdfApiTimeoutError(`Timeout exceeded when calling ${method} ${path}.`, { + cause: error.cause, + }); + case "unknown": + throw new errors.CloudpdfApiError({ + message: error.errorMessage, + rawResponse: rawResponse, + cause: error.cause, + }); + default: + throw new errors.CloudpdfApiError({ + message: "Unknown error", + rawResponse: rawResponse, + }); + } +} diff --git a/src/errors/index.ts b/src/errors/index.ts new file mode 100644 index 0000000..74212b5 --- /dev/null +++ b/src/errors/index.ts @@ -0,0 +1,2 @@ +export { CloudpdfApiError } from "./CloudpdfApiError.js"; +export { CloudpdfApiTimeoutError } from "./CloudpdfApiTimeoutError.js"; diff --git a/src/exports.ts b/src/exports.ts new file mode 100644 index 0000000..7b70ee1 --- /dev/null +++ b/src/exports.ts @@ -0,0 +1 @@ +export * from "./core/exports.js"; diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..8d3c173 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,5 @@ +export * as CloudpdfApi from "./api/index.js"; +export type { BaseClientOptions, BaseRequestOptions } from "./BaseClient.js"; +export { CloudpdfApiClient } from "./Client.js"; +export { CloudpdfApiError, CloudpdfApiTimeoutError } from "./errors/index.js"; +export * from "./exports.js"; diff --git a/src/version.ts b/src/version.ts new file mode 100644 index 0000000..71b2f62 --- /dev/null +++ b/src/version.ts @@ -0,0 +1 @@ +export const SDK_VERSION = "3.0.0-next.1"; diff --git a/tests/custom.test.ts b/tests/custom.test.ts new file mode 100644 index 0000000..7f5e031 --- /dev/null +++ b/tests/custom.test.ts @@ -0,0 +1,13 @@ +/** + * This is a custom test file, if you wish to add more tests + * to your SDK. + * Be sure to mark this file in `.fernignore`. + * + * If you include example requests/responses in your fern definition, + * you will have tests automatically generated for you. + */ +describe("test", () => { + it("default", () => { + expect(true).toBe(true); + }); +}); diff --git a/tests/mock-server/MockServer.ts b/tests/mock-server/MockServer.ts new file mode 100644 index 0000000..9548721 --- /dev/null +++ b/tests/mock-server/MockServer.ts @@ -0,0 +1,29 @@ +import type { RequestHandlerOptions } from "msw"; +import type { SetupServer } from "msw/node"; + +import { mockEndpointBuilder } from "./mockEndpointBuilder"; + +export interface MockServerOptions { + baseUrl: string; + server: SetupServer; +} + +export class MockServer { + private readonly server: SetupServer; + public readonly baseUrl: string; + + constructor({ baseUrl, server }: MockServerOptions) { + this.baseUrl = baseUrl.endsWith("/") ? baseUrl.slice(0, -1) : baseUrl; + this.server = server; + } + + public mockEndpoint(options?: RequestHandlerOptions): ReturnType { + const builder = mockEndpointBuilder({ + once: options?.once ?? true, + onBuild: (handler) => { + this.server.use(handler); + }, + }).baseUrl(this.baseUrl); + return builder; + } +} diff --git a/tests/mock-server/MockServerPool.ts b/tests/mock-server/MockServerPool.ts new file mode 100644 index 0000000..d7d891a --- /dev/null +++ b/tests/mock-server/MockServerPool.ts @@ -0,0 +1,106 @@ +import { setupServer } from "msw/node"; + +import { fromJson, toJson } from "../../src/core/json"; +import { MockServer } from "./MockServer"; +import { randomBaseUrl } from "./randomBaseUrl"; + +const mswServer = setupServer(); +interface MockServerOptions { + baseUrl?: string; +} + +async function formatHttpRequest(request: Request, id?: string): Promise { + try { + const clone = request.clone(); + const headers = [...clone.headers.entries()].map(([k, v]) => `${k}: ${v}`).join("\n"); + + let body = ""; + try { + const contentType = clone.headers.get("content-type"); + if (contentType?.includes("application/json")) { + body = toJson(fromJson(await clone.text()), undefined, 2); + } else if (clone.body) { + body = await clone.text(); + } + } catch (_e) { + body = "(unable to parse body)"; + } + + const title = id ? `### Request ${id} ###\n` : ""; + const firstLine = `${title}${request.method} ${request.url.toString()} HTTP/1.1`; + + return `\n${firstLine}\n${headers}\n\n${body || "(no body)"}\n`; + } catch (e) { + return `Error formatting request: ${e}`; + } +} + +async function formatHttpResponse(response: Response, id?: string): Promise { + try { + const clone = response.clone(); + const headers = [...clone.headers.entries()].map(([k, v]) => `${k}: ${v}`).join("\n"); + + let body = ""; + try { + const contentType = clone.headers.get("content-type"); + if (contentType?.includes("application/json")) { + body = toJson(fromJson(await clone.text()), undefined, 2); + } else if (clone.body) { + body = await clone.text(); + } + } catch (_e) { + body = "(unable to parse body)"; + } + + const title = id ? `### Response for ${id} ###\n` : ""; + const firstLine = `${title}HTTP/1.1 ${response.status} ${response.statusText}`; + + return `\n${firstLine}\n${headers}\n\n${body || "(no body)"}\n`; + } catch (e) { + return `Error formatting response: ${e}`; + } +} + +class MockServerPool { + private servers: MockServer[] = []; + + public createServer(options?: Partial): MockServer { + const baseUrl = options?.baseUrl || randomBaseUrl(); + const server = new MockServer({ baseUrl, server: mswServer }); + this.servers.push(server); + return server; + } + + public getServers(): MockServer[] { + return [...this.servers]; + } + + public listen(): void { + const onUnhandledRequest = process.env.LOG_LEVEL === "debug" ? "warn" : "bypass"; + mswServer.listen({ onUnhandledRequest }); + + if (process.env.LOG_LEVEL === "debug") { + mswServer.events.on("request:start", async ({ request, requestId }) => { + const formattedRequest = await formatHttpRequest(request, requestId); + console.debug(`request:start\n${formattedRequest}`); + }); + + mswServer.events.on("request:unhandled", async ({ request, requestId }) => { + const formattedRequest = await formatHttpRequest(request, requestId); + console.debug(`request:unhandled\n${formattedRequest}`); + }); + + mswServer.events.on("response:mocked", async ({ request, response, requestId }) => { + const formattedResponse = await formatHttpResponse(response, requestId); + console.debug(`response:mocked\n${formattedResponse}`); + }); + } + } + + public close(): void { + this.servers = []; + mswServer.close(); + } +} + +export const mockServerPool: MockServerPool = new MockServerPool(); diff --git a/tests/mock-server/mockEndpointBuilder.ts b/tests/mock-server/mockEndpointBuilder.ts new file mode 100644 index 0000000..3e8540a --- /dev/null +++ b/tests/mock-server/mockEndpointBuilder.ts @@ -0,0 +1,234 @@ +import { type DefaultBodyType, type HttpHandler, HttpResponse, type HttpResponseResolver, http } from "msw"; + +import { url } from "../../src/core"; +import { toJson } from "../../src/core/json"; +import { type WithFormUrlEncodedOptions, withFormUrlEncoded } from "./withFormUrlEncoded"; +import { withHeaders } from "./withHeaders"; +import { type WithJsonOptions, withJson } from "./withJson"; + +type HttpMethod = "all" | "get" | "post" | "put" | "delete" | "patch" | "options" | "head"; + +interface MethodStage { + baseUrl(baseUrl: string): MethodStage; + all(path: string): RequestHeadersStage; + get(path: string): RequestHeadersStage; + post(path: string): RequestHeadersStage; + put(path: string): RequestHeadersStage; + delete(path: string): RequestHeadersStage; + patch(path: string): RequestHeadersStage; + options(path: string): RequestHeadersStage; + head(path: string): RequestHeadersStage; +} + +interface RequestHeadersStage extends RequestBodyStage, ResponseStage { + header(name: string, value: string): RequestHeadersStage; + headers(headers: Record): RequestBodyStage; +} + +interface RequestBodyStage extends ResponseStage { + jsonBody(body: unknown, options?: WithJsonOptions): ResponseStage; + formUrlEncodedBody(body: unknown, options?: WithFormUrlEncodedOptions): ResponseStage; +} + +interface ResponseStage { + respondWith(): ResponseStatusStage; +} +interface ResponseStatusStage { + statusCode(statusCode: number): ResponseHeaderStage; +} + +interface ResponseHeaderStage extends ResponseBodyStage, BuildStage { + header(name: string, value: string): ResponseHeaderStage; + headers(headers: Record): ResponseHeaderStage; +} + +interface ResponseBodyStage { + jsonBody(body: unknown): BuildStage; + sseBody(body: string): BuildStage; +} + +interface BuildStage { + build(): HttpHandler; +} + +export interface HttpHandlerBuilderOptions { + onBuild?: (handler: HttpHandler) => void; + once?: boolean; +} + +class RequestBuilder implements MethodStage, RequestHeadersStage, RequestBodyStage, ResponseStage { + private method: HttpMethod = "get"; + private _baseUrl: string = ""; + private path: string = "/"; + private readonly predicates: ((resolver: HttpResponseResolver) => HttpResponseResolver)[] = []; + private readonly handlerOptions?: HttpHandlerBuilderOptions; + + constructor(options?: HttpHandlerBuilderOptions) { + this.handlerOptions = options; + } + + baseUrl(baseUrl: string): MethodStage { + this._baseUrl = baseUrl; + return this; + } + + all(path: string): RequestHeadersStage { + this.method = "all"; + this.path = path; + return this; + } + + get(path: string): RequestHeadersStage { + this.method = "get"; + this.path = path; + return this; + } + + post(path: string): RequestHeadersStage { + this.method = "post"; + this.path = path; + return this; + } + + put(path: string): RequestHeadersStage { + this.method = "put"; + this.path = path; + return this; + } + + delete(path: string): RequestHeadersStage { + this.method = "delete"; + this.path = path; + return this; + } + + patch(path: string): RequestHeadersStage { + this.method = "patch"; + this.path = path; + return this; + } + + options(path: string): RequestHeadersStage { + this.method = "options"; + this.path = path; + return this; + } + + head(path: string): RequestHeadersStage { + this.method = "head"; + this.path = path; + return this; + } + + header(name: string, value: string): RequestHeadersStage { + this.predicates.push((resolver) => withHeaders({ [name]: value }, resolver)); + return this; + } + + headers(headers: Record): RequestBodyStage { + this.predicates.push((resolver) => withHeaders(headers, resolver)); + return this; + } + + jsonBody(body: unknown, options?: WithJsonOptions): ResponseStage { + if (body === undefined) { + throw new Error("Undefined is not valid JSON. Do not call jsonBody if you want an empty body."); + } + this.predicates.push((resolver) => withJson(body, resolver, options)); + return this; + } + + formUrlEncodedBody(body: unknown, options?: WithFormUrlEncodedOptions): ResponseStage { + if (body === undefined) { + throw new Error( + "Undefined is not valid for form-urlencoded. Do not call formUrlEncodedBody if you want an empty body.", + ); + } + this.predicates.push((resolver) => withFormUrlEncoded(body, resolver, options)); + return this; + } + + respondWith(): ResponseStatusStage { + return new ResponseBuilder(this.method, this.buildUrl(), this.predicates, this.handlerOptions); + } + + private buildUrl(): string { + return url.join(this._baseUrl, this.path); + } +} + +class ResponseBuilder implements ResponseStatusStage, ResponseHeaderStage, ResponseBodyStage, BuildStage { + private readonly method: HttpMethod; + private readonly url: string; + private readonly requestPredicates: ((resolver: HttpResponseResolver) => HttpResponseResolver)[]; + private readonly handlerOptions?: HttpHandlerBuilderOptions; + + private responseStatusCode: number = 200; + private responseHeaders: Record = {}; + private responseBody: DefaultBodyType = undefined; + + constructor( + method: HttpMethod, + url: string, + requestPredicates: ((resolver: HttpResponseResolver) => HttpResponseResolver)[], + options?: HttpHandlerBuilderOptions, + ) { + this.method = method; + this.url = url; + this.requestPredicates = requestPredicates; + this.handlerOptions = options; + } + + public statusCode(code: number): ResponseHeaderStage { + this.responseStatusCode = code; + return this; + } + + public header(name: string, value: string): ResponseHeaderStage { + this.responseHeaders[name] = value; + return this; + } + + public headers(headers: Record): ResponseHeaderStage { + this.responseHeaders = { ...this.responseHeaders, ...headers }; + return this; + } + + public jsonBody(body: unknown): BuildStage { + if (body === undefined) { + throw new Error("Undefined is not valid JSON. Do not call jsonBody if you expect an empty body."); + } + this.responseBody = toJson(body); + return this; + } + + public sseBody(body: string): BuildStage { + this.responseHeaders["Content-Type"] = "text/event-stream"; + this.responseBody = body; + return this; + } + + public build(): HttpHandler { + const responseResolver: HttpResponseResolver = () => { + const response = new HttpResponse(this.responseBody, { + status: this.responseStatusCode, + headers: this.responseHeaders, + }); + // if no Content-Type header is set, delete the default text content type that is set + if (Object.keys(this.responseHeaders).some((key) => key.toLowerCase() === "content-type") === false) { + response.headers.delete("Content-Type"); + } + return response; + }; + + const finalResolver = this.requestPredicates.reduceRight((acc, predicate) => predicate(acc), responseResolver); + + const handler = http[this.method](this.url, finalResolver, this.handlerOptions); + this.handlerOptions?.onBuild?.(handler); + return handler; + } +} + +export function mockEndpointBuilder(options?: HttpHandlerBuilderOptions): MethodStage { + return new RequestBuilder(options); +} diff --git a/tests/mock-server/randomBaseUrl.ts b/tests/mock-server/randomBaseUrl.ts new file mode 100644 index 0000000..031aa64 --- /dev/null +++ b/tests/mock-server/randomBaseUrl.ts @@ -0,0 +1,4 @@ +export function randomBaseUrl(): string { + const randomString = Math.random().toString(36).substring(2, 15); + return `http://${randomString}.localhost`; +} diff --git a/tests/mock-server/setup.ts b/tests/mock-server/setup.ts new file mode 100644 index 0000000..aeb3a95 --- /dev/null +++ b/tests/mock-server/setup.ts @@ -0,0 +1,10 @@ +import { afterAll, beforeAll } from "vitest"; + +import { mockServerPool } from "./MockServerPool"; + +beforeAll(() => { + mockServerPool.listen(); +}); +afterAll(() => { + mockServerPool.close(); +}); diff --git a/tests/mock-server/withFormUrlEncoded.ts b/tests/mock-server/withFormUrlEncoded.ts new file mode 100644 index 0000000..2b23448 --- /dev/null +++ b/tests/mock-server/withFormUrlEncoded.ts @@ -0,0 +1,104 @@ +import { type HttpResponseResolver, passthrough } from "msw"; + +import { toJson } from "../../src/core/json"; + +export interface WithFormUrlEncodedOptions { + /** + * List of field names to ignore when comparing request bodies. + * This is useful for pagination cursor fields that change between requests. + */ + ignoredFields?: string[]; +} + +/** + * Creates a request matcher that validates if the request form-urlencoded body exactly matches the expected object + * @param expectedBody - The exact body object to match against + * @param resolver - Response resolver to execute if body matches + * @param options - Optional configuration including fields to ignore + */ +export function withFormUrlEncoded( + expectedBody: unknown, + resolver: HttpResponseResolver, + options?: WithFormUrlEncodedOptions, +): HttpResponseResolver { + const ignoredFields = options?.ignoredFields ?? []; + return async (args) => { + const { request } = args; + + let clonedRequest: Request; + let bodyText: string | undefined; + let actualBody: Record; + try { + clonedRequest = request.clone(); + bodyText = await clonedRequest.text(); + if (bodyText === "") { + // Empty body is valid if expected body is also empty + const isExpectedEmpty = + expectedBody != null && + typeof expectedBody === "object" && + Object.keys(expectedBody as Record).length === 0; + if (!isExpectedEmpty) { + console.error("Request body is empty, expected a form-urlencoded body."); + return passthrough(); + } + actualBody = {}; + } else { + const params = new URLSearchParams(bodyText); + actualBody = {}; + for (const [key, value] of params.entries()) { + actualBody[key] = value; + } + } + } catch (error) { + console.error(`Error processing form-urlencoded request body:\n\tError: ${error}\n\tBody: ${bodyText}`); + return passthrough(); + } + + const mismatches = findMismatches(actualBody, expectedBody); + const filteredMismatches = Object.keys(mismatches).filter((key) => !ignoredFields.includes(key)); + if (filteredMismatches.length > 0) { + console.error("Form-urlencoded body mismatch:", toJson(mismatches, undefined, 2)); + return passthrough(); + } + + return resolver(args); + }; +} + +function findMismatches(actual: any, expected: any): Record { + const mismatches: Record = {}; + + if (typeof actual !== typeof expected) { + return { value: { actual, expected } }; + } + + if (typeof actual !== "object" || actual === null || expected === null) { + if (actual !== expected) { + return { value: { actual, expected } }; + } + return {}; + } + + const actualKeys = Object.keys(actual); + const expectedKeys = Object.keys(expected); + + const allKeys = new Set([...actualKeys, ...expectedKeys]); + + for (const key of allKeys) { + if (!expectedKeys.includes(key)) { + if (actual[key] === undefined) { + continue; + } + mismatches[key] = { actual: actual[key], expected: undefined }; + } else if (!actualKeys.includes(key)) { + if (expected[key] === undefined) { + continue; + } + mismatches[key] = { actual: undefined, expected: expected[key] }; + } else if (actual[key] !== expected[key]) { + mismatches[key] = { actual: actual[key], expected: expected[key] }; + } + } + + return mismatches; +} diff --git a/tests/mock-server/withHeaders.ts b/tests/mock-server/withHeaders.ts new file mode 100644 index 0000000..6599d2b --- /dev/null +++ b/tests/mock-server/withHeaders.ts @@ -0,0 +1,70 @@ +import { type HttpResponseResolver, passthrough } from "msw"; + +/** + * Creates a request matcher that validates if request headers match specified criteria + * @param expectedHeaders - Headers to match against + * @param resolver - Response resolver to execute if headers match + */ +export function withHeaders( + expectedHeaders: Record boolean)>, + resolver: HttpResponseResolver, +): HttpResponseResolver { + return (args) => { + const { request } = args; + const { headers } = request; + + const mismatches: Record< + string, + { actual: string | null; expected: string | RegExp | ((value: string) => boolean) } + > = {}; + + for (const [key, expectedValue] of Object.entries(expectedHeaders)) { + const actualValue = headers.get(key); + + if (actualValue === null) { + mismatches[key] = { actual: null, expected: expectedValue }; + continue; + } + + if (typeof expectedValue === "function") { + if (!expectedValue(actualValue)) { + mismatches[key] = { actual: actualValue, expected: expectedValue }; + } + } else if (expectedValue instanceof RegExp) { + if (!expectedValue.test(actualValue)) { + mismatches[key] = { actual: actualValue, expected: expectedValue }; + } + } else if (expectedValue !== actualValue) { + mismatches[key] = { actual: actualValue, expected: expectedValue }; + } + } + + if (Object.keys(mismatches).length > 0) { + const formattedMismatches = formatHeaderMismatches(mismatches); + console.error("Header mismatch:", formattedMismatches); + return passthrough(); + } + + return resolver(args); + }; +} + +function formatHeaderMismatches( + mismatches: Record boolean) }>, +): Record { + const formatted: Record = {}; + + for (const [key, { actual, expected }] of Object.entries(mismatches)) { + formatted[key] = { + actual, + expected: + expected instanceof RegExp + ? expected.toString() + : typeof expected === "function" + ? "[Function]" + : expected, + }; + } + + return formatted; +} diff --git a/tests/mock-server/withJson.ts b/tests/mock-server/withJson.ts new file mode 100644 index 0000000..3e8800a --- /dev/null +++ b/tests/mock-server/withJson.ts @@ -0,0 +1,173 @@ +import { type HttpResponseResolver, passthrough } from "msw"; + +import { fromJson, toJson } from "../../src/core/json"; + +export interface WithJsonOptions { + /** + * List of field names to ignore when comparing request bodies. + * This is useful for pagination cursor fields that change between requests. + */ + ignoredFields?: string[]; +} + +/** + * Creates a request matcher that validates if the request JSON body exactly matches the expected object + * @param expectedBody - The exact body object to match against + * @param resolver - Response resolver to execute if body matches + * @param options - Optional configuration including fields to ignore + */ +export function withJson( + expectedBody: unknown, + resolver: HttpResponseResolver, + options?: WithJsonOptions, +): HttpResponseResolver { + const ignoredFields = options?.ignoredFields ?? []; + return async (args) => { + const { request } = args; + + let clonedRequest: Request; + let bodyText: string | undefined; + let actualBody: unknown; + try { + clonedRequest = request.clone(); + bodyText = await clonedRequest.text(); + if (bodyText === "") { + console.error("Request body is empty, expected a JSON object."); + return passthrough(); + } + actualBody = fromJson(bodyText); + } catch (error) { + console.error(`Error processing request body:\n\tError: ${error}\n\tBody: ${bodyText}`); + return passthrough(); + } + + const mismatches = findMismatches(actualBody, expectedBody); + const filteredMismatches = Object.keys(mismatches).filter((key) => !ignoredFields.includes(key)); + if (filteredMismatches.length > 0) { + console.error("JSON body mismatch:", toJson(mismatches, undefined, 2)); + return passthrough(); + } + + return resolver(args); + }; +} + +function findMismatches(actual: any, expected: any): Record { + const mismatches: Record = {}; + + if (typeof actual !== typeof expected) { + if (areEquivalent(actual, expected)) { + return {}; + } + return { value: { actual, expected } }; + } + + if (typeof actual !== "object" || actual === null || expected === null) { + if (actual !== expected) { + if (areEquivalent(actual, expected)) { + return {}; + } + return { value: { actual, expected } }; + } + return {}; + } + + if (Array.isArray(actual) && Array.isArray(expected)) { + if (actual.length !== expected.length) { + return { length: { actual: actual.length, expected: expected.length } }; + } + + const arrayMismatches: Record = {}; + for (let i = 0; i < actual.length; i++) { + const itemMismatches = findMismatches(actual[i], expected[i]); + if (Object.keys(itemMismatches).length > 0) { + for (const [mismatchKey, mismatchValue] of Object.entries(itemMismatches)) { + arrayMismatches[`[${i}]${mismatchKey === "value" ? "" : `.${mismatchKey}`}`] = mismatchValue; + } + } + } + return arrayMismatches; + } + + const actualKeys = Object.keys(actual); + const expectedKeys = Object.keys(expected); + + const allKeys = new Set([...actualKeys, ...expectedKeys]); + + for (const key of allKeys) { + if (!expectedKeys.includes(key)) { + if (actual[key] === undefined) { + continue; // Skip undefined values in actual + } + mismatches[key] = { actual: actual[key], expected: undefined }; + } else if (!actualKeys.includes(key)) { + if (expected[key] === undefined) { + continue; // Skip undefined values in expected + } + mismatches[key] = { actual: undefined, expected: expected[key] }; + } else if ( + typeof actual[key] === "object" && + actual[key] !== null && + typeof expected[key] === "object" && + expected[key] !== null + ) { + const nestedMismatches = findMismatches(actual[key], expected[key]); + if (Object.keys(nestedMismatches).length > 0) { + for (const [nestedKey, nestedValue] of Object.entries(nestedMismatches)) { + mismatches[`${key}${nestedKey === "value" ? "" : `.${nestedKey}`}`] = nestedValue; + } + } + } else if (actual[key] !== expected[key]) { + if (areEquivalent(actual[key], expected[key])) { + continue; + } + mismatches[key] = { actual: actual[key], expected: expected[key] }; + } + } + + return mismatches; +} + +function areEquivalent(actual: unknown, expected: unknown): boolean { + if (actual === expected) { + return true; + } + if (isEquivalentBigInt(actual, expected)) { + return true; + } + if (isEquivalentDatetime(actual, expected)) { + return true; + } + return false; +} + +function isEquivalentBigInt(actual: unknown, expected: unknown) { + if (typeof actual === "number") { + actual = BigInt(actual); + } + if (typeof expected === "number") { + expected = BigInt(expected); + } + if (typeof actual === "bigint" && typeof expected === "bigint") { + return actual === expected; + } + return false; +} + +function isEquivalentDatetime(str1: unknown, str2: unknown): boolean { + if (typeof str1 !== "string" || typeof str2 !== "string") { + return false; + } + const isoDatePattern = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{3})?Z$/; + if (!isoDatePattern.test(str1) || !isoDatePattern.test(str2)) { + return false; + } + + try { + const date1 = new Date(str1).getTime(); + const date2 = new Date(str2).getTime(); + return date1 === date2; + } catch { + return false; + } +} diff --git a/tests/setup.ts b/tests/setup.ts new file mode 100644 index 0000000..a5651f8 --- /dev/null +++ b/tests/setup.ts @@ -0,0 +1,80 @@ +import { expect } from "vitest"; + +interface CustomMatchers { + toContainHeaders(expectedHeaders: Record): R; +} + +declare module "vitest" { + interface Assertion extends CustomMatchers {} + interface AsymmetricMatchersContaining extends CustomMatchers {} +} + +expect.extend({ + toContainHeaders(actual: unknown, expectedHeaders: Record) { + const isHeaders = actual instanceof Headers; + const isPlainObject = typeof actual === "object" && actual !== null && !Array.isArray(actual); + + if (!isHeaders && !isPlainObject) { + throw new TypeError("Received value must be an instance of Headers or a plain object!"); + } + + if (typeof expectedHeaders !== "object" || expectedHeaders === null || Array.isArray(expectedHeaders)) { + throw new TypeError("Expected headers must be a plain object!"); + } + + const missingHeaders: string[] = []; + const mismatchedHeaders: Array<{ key: string; expected: string; actual: string | null }> = []; + + for (const [key, value] of Object.entries(expectedHeaders)) { + let actualValue: string | null = null; + + if (isHeaders) { + // Headers.get() is already case-insensitive + actualValue = (actual as Headers).get(key); + } else { + // For plain objects, do case-insensitive lookup + const actualObj = actual as Record; + const lowerKey = key.toLowerCase(); + const foundKey = Object.keys(actualObj).find((k) => k.toLowerCase() === lowerKey); + actualValue = foundKey ? actualObj[foundKey] : null; + } + + if (actualValue === null || actualValue === undefined) { + missingHeaders.push(key); + } else if (actualValue !== value) { + mismatchedHeaders.push({ key, expected: value, actual: actualValue }); + } + } + + const pass = missingHeaders.length === 0 && mismatchedHeaders.length === 0; + + const actualType = isHeaders ? "Headers" : "object"; + + if (pass) { + return { + message: () => `expected ${actualType} not to contain ${this.utils.printExpected(expectedHeaders)}`, + pass: true, + }; + } else { + const messages: string[] = []; + + if (missingHeaders.length > 0) { + messages.push(`Missing headers: ${this.utils.printExpected(missingHeaders.join(", "))}`); + } + + if (mismatchedHeaders.length > 0) { + const mismatches = mismatchedHeaders.map( + ({ key, expected, actual }) => + `${key}: expected ${this.utils.printExpected(expected)} but got ${this.utils.printReceived(actual)}`, + ); + messages.push(mismatches.join("\n")); + } + + return { + message: () => + `expected ${actualType} to contain ${this.utils.printExpected(expectedHeaders)}\n\n${messages.join("\n")}`, + pass: false, + }; + } + }, +}); diff --git a/tests/tsconfig.json b/tests/tsconfig.json new file mode 100644 index 0000000..ac39744 --- /dev/null +++ b/tests/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../tsconfig.base.json", + "compilerOptions": { + "outDir": null, + "rootDir": "..", + "types": ["vitest/globals"] + }, + "include": ["../src", "../tests"], + "exclude": [] +} diff --git a/tests/unit/auth/BasicAuth.test.ts b/tests/unit/auth/BasicAuth.test.ts new file mode 100644 index 0000000..8c82c1b --- /dev/null +++ b/tests/unit/auth/BasicAuth.test.ts @@ -0,0 +1,112 @@ +import { BasicAuth } from "../../../src/core/auth/BasicAuth"; + +describe("BasicAuth", () => { + interface ToHeaderTestCase { + description: string; + input: { username?: string; password?: string }; + expected: string | undefined; + } + + interface FromHeaderTestCase { + description: string; + input: string; + expected: { username: string; password: string }; + } + + interface ErrorTestCase { + description: string; + input: string; + expectedError: string; + } + + describe("toAuthorizationHeader", () => { + const toHeaderTests: ToHeaderTestCase[] = [ + { + description: "correctly converts to header with both username and password", + input: { username: "username", password: "password" }, + expected: "Basic dXNlcm5hbWU6cGFzc3dvcmQ=", + }, + { + description: "encodes username only with trailing colon", + input: { username: "username" }, + expected: "Basic dXNlcm5hbWU6", + }, + { + description: "encodes password only with leading colon", + input: { password: "password" }, + expected: "Basic OnBhc3N3b3Jk", + }, + { + description: "returns undefined when neither provided", + input: {}, + expected: undefined, + }, + { + description: "returns undefined when both are empty strings", + input: { username: "", password: "" }, + expected: undefined, + }, + ]; + + toHeaderTests.forEach(({ description, input, expected }) => { + it(description, () => { + expect(BasicAuth.toAuthorizationHeader(input)).toBe(expected); + }); + }); + }); + + describe("fromAuthorizationHeader", () => { + const fromHeaderTests: FromHeaderTestCase[] = [ + { + description: "correctly parses header", + input: "Basic dXNlcm5hbWU6cGFzc3dvcmQ=", + expected: { username: "username", password: "password" }, + }, + { + description: "handles password with colons", + input: "Basic dXNlcjpwYXNzOndvcmQ=", + expected: { username: "user", password: "pass:word" }, + }, + { + description: "handles empty username and password (just colon)", + input: "Basic Og==", + expected: { username: "", password: "" }, + }, + { + description: "handles empty username", + input: "Basic OnBhc3N3b3Jk", + expected: { username: "", password: "password" }, + }, + { + description: "handles empty password", + input: "Basic dXNlcm5hbWU6", + expected: { username: "username", password: "" }, + }, + ]; + + fromHeaderTests.forEach(({ description, input, expected }) => { + it(description, () => { + expect(BasicAuth.fromAuthorizationHeader(input)).toEqual(expected); + }); + }); + + const errorTests: ErrorTestCase[] = [ + { + description: "throws error for completely empty credentials", + input: "Basic ", + expectedError: "Invalid basic auth", + }, + { + description: "throws error for credentials without colon", + input: "Basic dXNlcm5hbWU=", + expectedError: "Invalid basic auth", + }, + ]; + + errorTests.forEach(({ description, input, expectedError }) => { + it(description, () => { + expect(() => BasicAuth.fromAuthorizationHeader(input)).toThrow(expectedError); + }); + }); + }); +}); diff --git a/tests/unit/auth/BearerToken.test.ts b/tests/unit/auth/BearerToken.test.ts new file mode 100644 index 0000000..7757b87 --- /dev/null +++ b/tests/unit/auth/BearerToken.test.ts @@ -0,0 +1,14 @@ +import { BearerToken } from "../../../src/core/auth/BearerToken"; + +describe("BearerToken", () => { + describe("toAuthorizationHeader", () => { + it("correctly converts to header", () => { + expect(BearerToken.toAuthorizationHeader("my-token")).toBe("Bearer my-token"); + }); + }); + describe("fromAuthorizationHeader", () => { + it("correctly parses header", () => { + expect(BearerToken.fromAuthorizationHeader("Bearer my-token")).toBe("my-token"); + }); + }); +}); diff --git a/tests/unit/base64.test.ts b/tests/unit/base64.test.ts new file mode 100644 index 0000000..939594c --- /dev/null +++ b/tests/unit/base64.test.ts @@ -0,0 +1,53 @@ +import { base64Decode, base64Encode } from "../../src/core/base64"; + +describe("base64", () => { + describe("base64Encode", () => { + it("should encode ASCII strings", () => { + expect(base64Encode("hello")).toBe("aGVsbG8="); + expect(base64Encode("")).toBe(""); + }); + + it("should encode UTF-8 strings", () => { + expect(base64Encode("café")).toBe("Y2Fmw6k="); + expect(base64Encode("🎉")).toBe("8J+OiQ=="); + }); + + it("should handle basic auth credentials", () => { + expect(base64Encode("username:password")).toBe("dXNlcm5hbWU6cGFzc3dvcmQ="); + }); + }); + + describe("base64Decode", () => { + it("should decode ASCII strings", () => { + expect(base64Decode("aGVsbG8=")).toBe("hello"); + expect(base64Decode("")).toBe(""); + }); + + it("should decode UTF-8 strings", () => { + expect(base64Decode("Y2Fmw6k=")).toBe("café"); + expect(base64Decode("8J+OiQ==")).toBe("🎉"); + }); + + it("should handle basic auth credentials", () => { + expect(base64Decode("dXNlcm5hbWU6cGFzc3dvcmQ=")).toBe("username:password"); + }); + }); + + describe("round-trip encoding", () => { + const testStrings = [ + "hello world", + "test@example.com", + "café", + "username:password", + "user@domain.com:super$ecret123!", + ]; + + testStrings.forEach((testString) => { + it(`should round-trip encode/decode: "${testString}"`, () => { + const encoded = base64Encode(testString); + const decoded = base64Decode(encoded); + expect(decoded).toBe(testString); + }); + }); + }); +}); diff --git a/tests/unit/fetcher/Fetcher.test.ts b/tests/unit/fetcher/Fetcher.test.ts new file mode 100644 index 0000000..6c17624 --- /dev/null +++ b/tests/unit/fetcher/Fetcher.test.ts @@ -0,0 +1,262 @@ +import fs from "fs"; +import { join } from "path"; +import stream from "stream"; +import type { BinaryResponse } from "../../../src/core"; +import { type Fetcher, fetcherImpl } from "../../../src/core/fetcher/Fetcher"; + +describe("Test fetcherImpl", () => { + it("should handle successful request", async () => { + const mockArgs: Fetcher.Args = { + url: "https://httpbin.org/post", + method: "POST", + headers: { "X-Test": "x-test-header" }, + body: { data: "test" }, + contentType: "application/json", + requestType: "json", + maxRetries: 0, + responseType: "json", + }; + + global.fetch = vi.fn().mockResolvedValue( + new Response(JSON.stringify({ data: "test" }), { + status: 200, + statusText: "OK", + }), + ); + + const result = await fetcherImpl(mockArgs); + expect(result.ok).toBe(true); + if (result.ok) { + expect(result.body).toEqual({ data: "test" }); + } + + expect(global.fetch).toHaveBeenCalledWith( + "https://httpbin.org/post", + expect.objectContaining({ + method: "POST", + headers: expect.toContainHeaders({ "X-Test": "x-test-header" }), + body: JSON.stringify({ data: "test" }), + }), + ); + }); + + it("should send octet stream", async () => { + const url = "https://httpbin.org/post/file"; + const mockArgs: Fetcher.Args = { + url, + method: "POST", + headers: { "X-Test": "x-test-header" }, + contentType: "application/octet-stream", + requestType: "bytes", + maxRetries: 0, + responseType: "json", + body: fs.createReadStream(join(__dirname, "test-file.txt")), + }; + + global.fetch = vi.fn().mockResolvedValue( + new Response(JSON.stringify({ data: "test" }), { + status: 200, + statusText: "OK", + }), + ); + + const result = await fetcherImpl(mockArgs); + + expect(global.fetch).toHaveBeenCalledWith( + url, + expect.objectContaining({ + method: "POST", + headers: expect.toContainHeaders({ "X-Test": "x-test-header" }), + body: expect.any(fs.ReadStream), + }), + ); + expect(result.ok).toBe(true); + if (result.ok) { + expect(result.body).toEqual({ data: "test" }); + } + }); + + it("should receive file as stream", async () => { + const url = "https://httpbin.org/post/file"; + const mockArgs: Fetcher.Args = { + url, + method: "GET", + headers: { "X-Test": "x-test-header" }, + maxRetries: 0, + responseType: "binary-response", + }; + + global.fetch = vi.fn().mockResolvedValue( + new Response( + stream.Readable.toWeb(fs.createReadStream(join(__dirname, "test-file.txt"))) as ReadableStream, + { + status: 200, + statusText: "OK", + }, + ), + ); + + const result = await fetcherImpl(mockArgs); + + expect(global.fetch).toHaveBeenCalledWith( + url, + expect.objectContaining({ + method: "GET", + headers: expect.toContainHeaders({ "X-Test": "x-test-header" }), + }), + ); + expect(result.ok).toBe(true); + if (result.ok) { + const body = result.body as BinaryResponse; + expect(body).toBeDefined(); + expect(body.bodyUsed).toBe(false); + expect(typeof body.stream).toBe("function"); + const stream = body.stream(); + expect(stream).toBeInstanceOf(ReadableStream); + const readableStream = stream as ReadableStream; + const reader = readableStream.getReader(); + const { value } = await reader.read(); + const decoder = new TextDecoder(); + const streamContent = decoder.decode(value); + expect(streamContent.trim()).toBe("This is a test file!"); + expect(body.bodyUsed).toBe(true); + } + }); + + it("should receive file as blob", async () => { + const url = "https://httpbin.org/post/file"; + const mockArgs: Fetcher.Args = { + url, + method: "GET", + headers: { "X-Test": "x-test-header" }, + maxRetries: 0, + responseType: "binary-response", + }; + + global.fetch = vi.fn().mockResolvedValue( + new Response( + stream.Readable.toWeb(fs.createReadStream(join(__dirname, "test-file.txt"))) as ReadableStream, + { + status: 200, + statusText: "OK", + }, + ), + ); + + const result = await fetcherImpl(mockArgs); + + expect(global.fetch).toHaveBeenCalledWith( + url, + expect.objectContaining({ + method: "GET", + headers: expect.toContainHeaders({ "X-Test": "x-test-header" }), + }), + ); + expect(result.ok).toBe(true); + if (result.ok) { + const body = result.body as BinaryResponse; + expect(body).toBeDefined(); + expect(body.bodyUsed).toBe(false); + expect(typeof body.blob).toBe("function"); + const blob = await body.blob(); + expect(blob).toBeInstanceOf(Blob); + const reader = blob.stream().getReader(); + const { value } = await reader.read(); + const decoder = new TextDecoder(); + const streamContent = decoder.decode(value); + expect(streamContent.trim()).toBe("This is a test file!"); + expect(body.bodyUsed).toBe(true); + } + }); + + it("should receive file as arraybuffer", async () => { + const url = "https://httpbin.org/post/file"; + const mockArgs: Fetcher.Args = { + url, + method: "GET", + headers: { "X-Test": "x-test-header" }, + maxRetries: 0, + responseType: "binary-response", + }; + + global.fetch = vi.fn().mockResolvedValue( + new Response( + stream.Readable.toWeb(fs.createReadStream(join(__dirname, "test-file.txt"))) as ReadableStream, + { + status: 200, + statusText: "OK", + }, + ), + ); + + const result = await fetcherImpl(mockArgs); + + expect(global.fetch).toHaveBeenCalledWith( + url, + expect.objectContaining({ + method: "GET", + headers: expect.toContainHeaders({ "X-Test": "x-test-header" }), + }), + ); + expect(result.ok).toBe(true); + if (result.ok) { + const body = result.body as BinaryResponse; + expect(body).toBeDefined(); + expect(body.bodyUsed).toBe(false); + expect(typeof body.arrayBuffer).toBe("function"); + const arrayBuffer = await body.arrayBuffer(); + expect(arrayBuffer).toBeInstanceOf(ArrayBuffer); + const decoder = new TextDecoder(); + const streamContent = decoder.decode(new Uint8Array(arrayBuffer)); + expect(streamContent.trim()).toBe("This is a test file!"); + expect(body.bodyUsed).toBe(true); + } + }); + + it("should receive file as bytes", async () => { + const url = "https://httpbin.org/post/file"; + const mockArgs: Fetcher.Args = { + url, + method: "GET", + headers: { "X-Test": "x-test-header" }, + maxRetries: 0, + responseType: "binary-response", + }; + + global.fetch = vi.fn().mockResolvedValue( + new Response( + stream.Readable.toWeb(fs.createReadStream(join(__dirname, "test-file.txt"))) as ReadableStream, + { + status: 200, + statusText: "OK", + }, + ), + ); + + const result = await fetcherImpl(mockArgs); + + expect(global.fetch).toHaveBeenCalledWith( + url, + expect.objectContaining({ + method: "GET", + headers: expect.toContainHeaders({ "X-Test": "x-test-header" }), + }), + ); + expect(result.ok).toBe(true); + if (result.ok) { + const body = result.body as BinaryResponse; + expect(body).toBeDefined(); + expect(body.bodyUsed).toBe(false); + expect(typeof body.bytes).toBe("function"); + if (!body.bytes) { + return; + } + const bytes = await body.bytes(); + expect(bytes).toBeInstanceOf(Uint8Array); + const decoder = new TextDecoder(); + const streamContent = decoder.decode(bytes); + expect(streamContent.trim()).toBe("This is a test file!"); + expect(body.bodyUsed).toBe(true); + } + }); +}); diff --git a/tests/unit/fetcher/HttpResponsePromise.test.ts b/tests/unit/fetcher/HttpResponsePromise.test.ts new file mode 100644 index 0000000..2ec008e --- /dev/null +++ b/tests/unit/fetcher/HttpResponsePromise.test.ts @@ -0,0 +1,143 @@ +import { beforeEach, describe, expect, it, vi } from "vitest"; + +import { HttpResponsePromise } from "../../../src/core/fetcher/HttpResponsePromise"; +import type { RawResponse, WithRawResponse } from "../../../src/core/fetcher/RawResponse"; + +describe("HttpResponsePromise", () => { + const mockRawResponse: RawResponse = { + headers: new Headers(), + redirected: false, + status: 200, + statusText: "OK", + type: "basic" as ResponseType, + url: "https://example.com", + }; + const mockData = { id: "123", name: "test" }; + const mockWithRawResponse: WithRawResponse = { + data: mockData, + rawResponse: mockRawResponse, + }; + + describe("fromFunction", () => { + it("should create an HttpResponsePromise from a function", async () => { + const mockFn = vi + .fn<(arg1: string, arg2: string) => Promise>>() + .mockResolvedValue(mockWithRawResponse); + + const responsePromise = HttpResponsePromise.fromFunction(mockFn, "arg1", "arg2"); + + const result = await responsePromise; + expect(result).toEqual(mockData); + expect(mockFn).toHaveBeenCalledWith("arg1", "arg2"); + + const resultWithRawResponse = await responsePromise.withRawResponse(); + expect(resultWithRawResponse).toEqual({ + data: mockData, + rawResponse: mockRawResponse, + }); + }); + }); + + describe("fromPromise", () => { + it("should create an HttpResponsePromise from a promise", async () => { + const promise = Promise.resolve(mockWithRawResponse); + + const responsePromise = HttpResponsePromise.fromPromise(promise); + + const result = await responsePromise; + expect(result).toEqual(mockData); + + const resultWithRawResponse = await responsePromise.withRawResponse(); + expect(resultWithRawResponse).toEqual({ + data: mockData, + rawResponse: mockRawResponse, + }); + }); + }); + + describe("fromExecutor", () => { + it("should create an HttpResponsePromise from an executor function", async () => { + const responsePromise = HttpResponsePromise.fromExecutor((resolve) => { + resolve(mockWithRawResponse); + }); + + const result = await responsePromise; + expect(result).toEqual(mockData); + + const resultWithRawResponse = await responsePromise.withRawResponse(); + expect(resultWithRawResponse).toEqual({ + data: mockData, + rawResponse: mockRawResponse, + }); + }); + }); + + describe("fromResult", () => { + it("should create an HttpResponsePromise from a result", async () => { + const responsePromise = HttpResponsePromise.fromResult(mockWithRawResponse); + + const result = await responsePromise; + expect(result).toEqual(mockData); + + const resultWithRawResponse = await responsePromise.withRawResponse(); + expect(resultWithRawResponse).toEqual({ + data: mockData, + rawResponse: mockRawResponse, + }); + }); + }); + + describe("Promise methods", () => { + let responsePromise: HttpResponsePromise; + + beforeEach(() => { + responsePromise = HttpResponsePromise.fromResult(mockWithRawResponse); + }); + + it("should support then() method", async () => { + const result = await responsePromise.then((data) => ({ + ...data, + modified: true, + })); + + expect(result).toEqual({ + ...mockData, + modified: true, + }); + }); + + it("should support catch() method", async () => { + const errorResponsePromise = HttpResponsePromise.fromExecutor((_, reject) => { + reject(new Error("Test error")); + }); + + const catchSpy = vi.fn(); + await errorResponsePromise.catch(catchSpy); + + expect(catchSpy).toHaveBeenCalled(); + const error = catchSpy.mock.calls[0]?.[0]; + expect(error).toBeInstanceOf(Error); + expect((error as Error).message).toBe("Test error"); + }); + + it("should support finally() method", async () => { + const finallySpy = vi.fn(); + await responsePromise.finally(finallySpy); + + expect(finallySpy).toHaveBeenCalled(); + }); + }); + + describe("withRawResponse", () => { + it("should return both data and raw response", async () => { + const responsePromise = HttpResponsePromise.fromResult(mockWithRawResponse); + + const result = await responsePromise.withRawResponse(); + + expect(result).toEqual({ + data: mockData, + rawResponse: mockRawResponse, + }); + }); + }); +}); diff --git a/tests/unit/fetcher/RawResponse.test.ts b/tests/unit/fetcher/RawResponse.test.ts new file mode 100644 index 0000000..375ee3f --- /dev/null +++ b/tests/unit/fetcher/RawResponse.test.ts @@ -0,0 +1,34 @@ +import { describe, expect, it } from "vitest"; + +import { toRawResponse } from "../../../src/core/fetcher/RawResponse"; + +describe("RawResponse", () => { + describe("toRawResponse", () => { + it("should convert Response to RawResponse by removing body, bodyUsed, and ok properties", () => { + const mockHeaders = new Headers({ "content-type": "application/json" }); + const mockResponse = { + body: "test body", + bodyUsed: false, + ok: true, + headers: mockHeaders, + redirected: false, + status: 200, + statusText: "OK", + type: "basic" as ResponseType, + url: "https://example.com", + }; + + const result = toRawResponse(mockResponse as unknown as Response); + + expect("body" in result).toBe(false); + expect("bodyUsed" in result).toBe(false); + expect("ok" in result).toBe(false); + expect(result.headers).toBe(mockHeaders); + expect(result.redirected).toBe(false); + expect(result.status).toBe(200); + expect(result.statusText).toBe("OK"); + expect(result.type).toBe("basic"); + expect(result.url).toBe("https://example.com"); + }); + }); +}); diff --git a/tests/unit/fetcher/createRequestUrl.test.ts b/tests/unit/fetcher/createRequestUrl.test.ts new file mode 100644 index 0000000..7787e55 --- /dev/null +++ b/tests/unit/fetcher/createRequestUrl.test.ts @@ -0,0 +1,167 @@ +import { createRequestUrl } from "../../../src/core/fetcher/createRequestUrl"; + +describe("Test createRequestUrl", () => { + const BASE_URL = "https://api.example.com"; + + interface TestCase { + description: string; + baseUrl: string; + queryParams?: Record; + expected: string; + } + + const testCases: TestCase[] = [ + { + description: "should return the base URL when no query parameters are provided", + baseUrl: BASE_URL, + expected: BASE_URL, + }, + { + description: "should append simple query parameters", + baseUrl: BASE_URL, + queryParams: { key: "value", another: "param" }, + expected: "https://api.example.com?key=value&another=param", + }, + { + description: "should handle array query parameters", + baseUrl: BASE_URL, + queryParams: { items: ["a", "b", "c"] }, + expected: "https://api.example.com?items=a&items=b&items=c", + }, + { + description: "should handle object query parameters", + baseUrl: BASE_URL, + queryParams: { filter: { name: "John", age: 30 } }, + expected: "https://api.example.com?filter%5Bname%5D=John&filter%5Bage%5D=30", + }, + { + description: "should handle mixed types of query parameters", + baseUrl: BASE_URL, + queryParams: { + simple: "value", + array: ["x", "y"], + object: { key: "value" }, + }, + expected: "https://api.example.com?simple=value&array=x&array=y&object%5Bkey%5D=value", + }, + { + description: "should handle empty query parameters object", + baseUrl: BASE_URL, + queryParams: {}, + expected: BASE_URL, + }, + { + description: "should encode special characters in query parameters", + baseUrl: BASE_URL, + queryParams: { special: "a&b=c d" }, + expected: "https://api.example.com?special=a%26b%3Dc%20d", + }, + { + description: "should handle numeric values", + baseUrl: BASE_URL, + queryParams: { count: 42, price: 19.99, active: 1, inactive: 0 }, + expected: "https://api.example.com?count=42&price=19.99&active=1&inactive=0", + }, + { + description: "should handle boolean values", + baseUrl: BASE_URL, + queryParams: { enabled: true, disabled: false }, + expected: "https://api.example.com?enabled=true&disabled=false", + }, + { + description: "should handle null and undefined values", + baseUrl: BASE_URL, + queryParams: { + valid: "value", + nullValue: null, + undefinedValue: undefined, + emptyString: "", + }, + expected: "https://api.example.com?valid=value&emptyString=", + }, + { + description: "should handle deeply nested objects", + baseUrl: BASE_URL, + queryParams: { + user: { + profile: { + name: "John", + settings: { theme: "dark" }, + }, + }, + }, + expected: + "https://api.example.com?user%5Bprofile%5D%5Bname%5D=John&user%5Bprofile%5D%5Bsettings%5D%5Btheme%5D=dark", + }, + { + description: "should handle arrays of objects", + baseUrl: BASE_URL, + queryParams: { + users: [ + { name: "John", age: 30 }, + { name: "Jane", age: 25 }, + ], + }, + expected: + "https://api.example.com?users%5Bname%5D=John&users%5Bage%5D=30&users%5Bname%5D=Jane&users%5Bage%5D=25", + }, + { + description: "should handle mixed arrays", + baseUrl: BASE_URL, + queryParams: { + mixed: ["string", 42, true, { key: "value" }], + }, + expected: "https://api.example.com?mixed=string&mixed=42&mixed=true&mixed%5Bkey%5D=value", + }, + { + description: "should handle empty arrays", + baseUrl: BASE_URL, + queryParams: { emptyArray: [] }, + expected: BASE_URL, + }, + { + description: "should handle empty objects", + baseUrl: BASE_URL, + queryParams: { emptyObject: {} }, + expected: BASE_URL, + }, + { + description: "should handle special characters in keys", + baseUrl: BASE_URL, + queryParams: { "key with spaces": "value", "key[with]brackets": "value" }, + expected: "https://api.example.com?key%20with%20spaces=value&key%5Bwith%5Dbrackets=value", + }, + { + description: "should handle URL with existing query parameters", + baseUrl: "https://api.example.com?existing=param", + queryParams: { new: "value" }, + expected: "https://api.example.com?existing=param?new=value", + }, + { + description: "should handle complex nested structures", + baseUrl: BASE_URL, + queryParams: { + filters: { + status: ["active", "pending"], + category: { + type: "electronics", + subcategories: ["phones", "laptops"], + }, + }, + sort: { field: "name", direction: "asc" }, + }, + expected: + "https://api.example.com?filters%5Bstatus%5D=active&filters%5Bstatus%5D=pending&filters%5Bcategory%5D%5Btype%5D=electronics&filters%5Bcategory%5D%5Bsubcategories%5D=phones&filters%5Bcategory%5D%5Bsubcategories%5D=laptops&sort%5Bfield%5D=name&sort%5Bdirection%5D=asc", + }, + ]; + + testCases.forEach(({ description, baseUrl, queryParams, expected }) => { + it(description, () => { + expect(createRequestUrl(baseUrl, queryParams)).toBe(expected); + }); + }); + + it("should default to repeat format for arrays", () => { + expect(createRequestUrl(BASE_URL, { items: ["a", "b"] })).toBe("https://api.example.com?items=a&items=b"); + }); +}); diff --git a/tests/unit/fetcher/getRequestBody.test.ts b/tests/unit/fetcher/getRequestBody.test.ts new file mode 100644 index 0000000..8a6c3a5 --- /dev/null +++ b/tests/unit/fetcher/getRequestBody.test.ts @@ -0,0 +1,129 @@ +import { getRequestBody } from "../../../src/core/fetcher/getRequestBody"; +import { RUNTIME } from "../../../src/core/runtime"; + +describe("Test getRequestBody", () => { + interface TestCase { + description: string; + input: any; + type: "json" | "form" | "file" | "bytes" | "other"; + expected: any; + skipCondition?: () => boolean; + } + + const testCases: TestCase[] = [ + { + description: "should stringify body if not FormData in Node environment", + input: { key: "value" }, + type: "json", + expected: '{"key":"value"}', + skipCondition: () => RUNTIME.type !== "node", + }, + { + description: "should stringify body if not FormData in browser environment", + input: { key: "value" }, + type: "json", + expected: '{"key":"value"}', + skipCondition: () => RUNTIME.type !== "browser", + }, + { + description: "should return the Uint8Array", + input: new Uint8Array([1, 2, 3]), + type: "bytes", + expected: new Uint8Array([1, 2, 3]), + }, + { + description: "should serialize objects for form-urlencoded content type", + input: { username: "johndoe", email: "john@example.com" }, + type: "form", + expected: "username=johndoe&email=john%40example.com", + }, + { + description: "should serialize complex nested objects and arrays for form-urlencoded content type", + input: { + user: { + profile: { + name: "John Doe", + settings: { + theme: "dark", + notifications: true, + }, + }, + tags: ["admin", "user"], + contacts: [ + { type: "email", value: "john@example.com" }, + { type: "phone", value: "+1234567890" }, + ], + }, + filters: { + status: ["active", "pending"], + metadata: { + created: "2024-01-01", + categories: ["electronics", "books"], + }, + }, + preferences: ["notifications", "updates"], + }, + type: "form", + expected: + "user%5Bprofile%5D%5Bname%5D=John%20Doe&" + + "user%5Bprofile%5D%5Bsettings%5D%5Btheme%5D=dark&" + + "user%5Bprofile%5D%5Bsettings%5D%5Bnotifications%5D=true&" + + "user%5Btags%5D=admin&" + + "user%5Btags%5D=user&" + + "user%5Bcontacts%5D%5Btype%5D=email&" + + "user%5Bcontacts%5D%5Bvalue%5D=john%40example.com&" + + "user%5Bcontacts%5D%5Btype%5D=phone&" + + "user%5Bcontacts%5D%5Bvalue%5D=%2B1234567890&" + + "filters%5Bstatus%5D=active&" + + "filters%5Bstatus%5D=pending&" + + "filters%5Bmetadata%5D%5Bcreated%5D=2024-01-01&" + + "filters%5Bmetadata%5D%5Bcategories%5D=electronics&" + + "filters%5Bmetadata%5D%5Bcategories%5D=books&" + + "preferences=notifications&" + + "preferences=updates", + }, + { + description: "should return the input for pre-serialized form-urlencoded strings", + input: "key=value&another=param", + type: "other", + expected: "key=value&another=param", + }, + { + description: "should JSON stringify objects", + input: { key: "value" }, + type: "json", + expected: '{"key":"value"}', + }, + ]; + + testCases.forEach(({ description, input, type, expected, skipCondition }) => { + it(description, async () => { + if (skipCondition?.()) { + return; + } + + const result = await getRequestBody({ + body: input, + type, + }); + + if (input instanceof Uint8Array) { + expect(result).toBe(input); + } else { + expect(result).toBe(expected); + } + }); + }); + + it("should return FormData in browser environment", async () => { + if (RUNTIME.type === "browser") { + const formData = new FormData(); + formData.append("key", "value"); + const result = await getRequestBody({ + body: formData, + type: "file", + }); + expect(result).toBe(formData); + } + }); +}); diff --git a/tests/unit/fetcher/getResponseBody.test.ts b/tests/unit/fetcher/getResponseBody.test.ts new file mode 100644 index 0000000..64ed746 --- /dev/null +++ b/tests/unit/fetcher/getResponseBody.test.ts @@ -0,0 +1,123 @@ +import { getResponseBody } from "../../../src/core/fetcher/getResponseBody"; + +import { RUNTIME } from "../../../src/core/runtime"; + +describe("Test getResponseBody", () => { + interface SimpleTestCase { + description: string; + responseData: string | Record; + responseType?: "blob" | "sse" | "streaming" | "text"; + expected: any; + skipCondition?: () => boolean; + } + + const simpleTestCases: SimpleTestCase[] = [ + { + description: "should handle text response type", + responseData: "test text", + responseType: "text", + expected: "test text", + }, + { + description: "should handle JSON response", + responseData: { key: "value" }, + expected: { key: "value" }, + }, + { + description: "should handle empty response", + responseData: "", + expected: undefined, + }, + { + description: "should handle non-JSON response", + responseData: "invalid json", + expected: { + ok: false, + error: { + reason: "non-json", + statusCode: 200, + rawBody: "invalid json", + }, + }, + }, + ]; + + simpleTestCases.forEach(({ description, responseData, responseType, expected, skipCondition }) => { + it(description, async () => { + if (skipCondition?.()) { + return; + } + + const mockResponse = new Response( + typeof responseData === "string" ? responseData : JSON.stringify(responseData), + ); + const result = await getResponseBody(mockResponse, responseType); + expect(result).toEqual(expected); + }); + }); + + it("should handle blob response type", async () => { + const mockBlob = new Blob(["test"], { type: "text/plain" }); + const mockResponse = new Response(mockBlob); + const result = await getResponseBody(mockResponse, "blob"); + // @ts-expect-error + expect(result.constructor.name).toBe("Blob"); + }); + + it("should handle sse response type", async () => { + if (RUNTIME.type === "node") { + const mockStream = new ReadableStream(); + const mockResponse = new Response(mockStream); + const result = await getResponseBody(mockResponse, "sse"); + expect(result).toBe(mockStream); + } + }); + + it("should retain a reference to the parent Response for sse responses", async () => { + if (RUNTIME.type === "node") { + const mockStream = new ReadableStream(); + const mockResponse = new Response(mockStream); + const result = (await getResponseBody(mockResponse, "sse")) as ReadableStream & { + __fern_response_ref?: Response; + }; + // Pins the parent Response so undici's FinalizationRegistry can't GC it and cancel the stream. + expect(result.__fern_response_ref).toBe(mockResponse); + // The pin must be non-enumerable so it does not leak through JSON.stringify or Object.keys. + const descriptor = Object.getOwnPropertyDescriptor(result, "__fern_response_ref"); + expect(descriptor?.enumerable).toBe(false); + } + }); + + it("should handle streaming response type", async () => { + const encoder = new TextEncoder(); + const testData = "test stream data"; + const mockStream = new ReadableStream({ + start(controller) { + controller.enqueue(encoder.encode(testData)); + controller.close(); + }, + }); + + const mockResponse = new Response(mockStream); + const result = (await getResponseBody(mockResponse, "streaming")) as ReadableStream; + + expect(result).toBeInstanceOf(ReadableStream); + + const reader = result.getReader(); + const decoder = new TextDecoder(); + const { value } = await reader.read(); + const streamContent = decoder.decode(value); + expect(streamContent).toBe(testData); + }); + + it("should retain a reference to the parent Response for streaming responses", async () => { + const mockStream = new ReadableStream(); + const mockResponse = new Response(mockStream); + const result = (await getResponseBody(mockResponse, "streaming")) as ReadableStream & { + __fern_response_ref?: Response; + }; + expect(result.__fern_response_ref).toBe(mockResponse); + const descriptor = Object.getOwnPropertyDescriptor(result, "__fern_response_ref"); + expect(descriptor?.enumerable).toBe(false); + }); +}); diff --git a/tests/unit/fetcher/logging.test.ts b/tests/unit/fetcher/logging.test.ts new file mode 100644 index 0000000..366c9b6 --- /dev/null +++ b/tests/unit/fetcher/logging.test.ts @@ -0,0 +1,517 @@ +import { fetcherImpl } from "../../../src/core/fetcher/Fetcher"; + +function createMockLogger() { + return { + debug: vi.fn(), + info: vi.fn(), + warn: vi.fn(), + error: vi.fn(), + }; +} + +function mockSuccessResponse(data: unknown = { data: "test" }, status = 200, statusText = "OK") { + global.fetch = vi.fn().mockResolvedValue( + new Response(JSON.stringify(data), { + status, + statusText, + }), + ); +} + +function mockErrorResponse(data: unknown = { error: "Error" }, status = 404, statusText = "Not Found") { + global.fetch = vi.fn().mockResolvedValue( + new Response(JSON.stringify(data), { + status, + statusText, + }), + ); +} + +describe("Fetcher Logging Integration", () => { + describe("Request Logging", () => { + it("should log successful request at debug level", async () => { + const mockLogger = createMockLogger(); + mockSuccessResponse(); + + await fetcherImpl({ + url: "https://example.com/api", + method: "POST", + headers: { "Content-Type": "application/json" }, + body: { test: "data" }, + contentType: "application/json", + requestType: "json", + responseType: "json", + maxRetries: 0, + logging: { + level: "debug", + logger: mockLogger, + silent: false, + }, + }); + + expect(mockLogger.debug).toHaveBeenCalledWith( + "Making HTTP request", + expect.objectContaining({ + method: "POST", + url: "https://example.com/api", + headers: expect.toContainHeaders({ + "Content-Type": "application/json", + }), + hasBody: true, + }), + ); + + expect(mockLogger.debug).toHaveBeenCalledWith( + "HTTP request succeeded", + expect.objectContaining({ + method: "POST", + url: "https://example.com/api", + statusCode: 200, + }), + ); + }); + + it("should not log debug messages at info level for successful requests", async () => { + const mockLogger = createMockLogger(); + mockSuccessResponse(); + + await fetcherImpl({ + url: "https://example.com/api", + method: "GET", + responseType: "json", + maxRetries: 0, + logging: { + level: "info", + logger: mockLogger, + silent: false, + }, + }); + + expect(mockLogger.debug).not.toHaveBeenCalled(); + expect(mockLogger.info).not.toHaveBeenCalled(); + }); + + it("should log request with body flag", async () => { + const mockLogger = createMockLogger(); + mockSuccessResponse(); + + await fetcherImpl({ + url: "https://example.com/api", + method: "POST", + body: { data: "test" }, + contentType: "application/json", + requestType: "json", + responseType: "json", + maxRetries: 0, + logging: { + level: "debug", + logger: mockLogger, + silent: false, + }, + }); + + expect(mockLogger.debug).toHaveBeenCalledWith( + "Making HTTP request", + expect.objectContaining({ + hasBody: true, + }), + ); + }); + + it("should log request without body flag", async () => { + const mockLogger = createMockLogger(); + mockSuccessResponse(); + + await fetcherImpl({ + url: "https://example.com/api", + method: "GET", + responseType: "json", + maxRetries: 0, + logging: { + level: "debug", + logger: mockLogger, + silent: false, + }, + }); + + expect(mockLogger.debug).toHaveBeenCalledWith( + "Making HTTP request", + expect.objectContaining({ + hasBody: false, + }), + ); + }); + + it("should not log when silent mode is enabled", async () => { + const mockLogger = createMockLogger(); + mockSuccessResponse(); + + await fetcherImpl({ + url: "https://example.com/api", + method: "GET", + responseType: "json", + maxRetries: 0, + logging: { + level: "debug", + logger: mockLogger, + silent: true, + }, + }); + + expect(mockLogger.debug).not.toHaveBeenCalled(); + expect(mockLogger.info).not.toHaveBeenCalled(); + expect(mockLogger.warn).not.toHaveBeenCalled(); + expect(mockLogger.error).not.toHaveBeenCalled(); + }); + + it("should not log when no logging config is provided", async () => { + const mockLogger = createMockLogger(); + mockSuccessResponse(); + + await fetcherImpl({ + url: "https://example.com/api", + method: "GET", + responseType: "json", + maxRetries: 0, + }); + + expect(mockLogger.debug).not.toHaveBeenCalled(); + }); + }); + + describe("Error Logging", () => { + it("should log 4xx errors at error level", async () => { + const mockLogger = createMockLogger(); + mockErrorResponse({ error: "Not found" }, 404, "Not Found"); + + const result = await fetcherImpl({ + url: "https://example.com/api", + method: "GET", + responseType: "json", + maxRetries: 0, + logging: { + level: "error", + logger: mockLogger, + silent: false, + }, + }); + + expect(result.ok).toBe(false); + expect(mockLogger.error).toHaveBeenCalledWith( + "HTTP request failed with error status", + expect.objectContaining({ + method: "GET", + url: "https://example.com/api", + statusCode: 404, + }), + ); + }); + + it("should log 5xx errors at error level", async () => { + const mockLogger = createMockLogger(); + mockErrorResponse({ error: "Internal error" }, 500, "Internal Server Error"); + + const result = await fetcherImpl({ + url: "https://example.com/api", + method: "GET", + responseType: "json", + maxRetries: 0, + logging: { + level: "error", + logger: mockLogger, + silent: false, + }, + }); + + expect(result.ok).toBe(false); + expect(mockLogger.error).toHaveBeenCalledWith( + "HTTP request failed with error status", + expect.objectContaining({ + method: "GET", + url: "https://example.com/api", + statusCode: 500, + }), + ); + }); + + it("should log aborted request errors", async () => { + const mockLogger = createMockLogger(); + + const abortController = new AbortController(); + abortController.abort(); + + global.fetch = vi.fn().mockRejectedValue(new Error("Aborted")); + + const result = await fetcherImpl({ + url: "https://example.com/api", + method: "GET", + responseType: "json", + abortSignal: abortController.signal, + maxRetries: 0, + logging: { + level: "error", + logger: mockLogger, + silent: false, + }, + }); + + expect(result.ok).toBe(false); + expect(mockLogger.error).toHaveBeenCalledWith( + "HTTP request was aborted", + expect.objectContaining({ + method: "GET", + url: "https://example.com/api", + }), + ); + }); + + it("should log timeout errors", async () => { + const mockLogger = createMockLogger(); + + const timeoutError = new Error("Request timeout"); + timeoutError.name = "AbortError"; + + global.fetch = vi.fn().mockRejectedValue(timeoutError); + + const result = await fetcherImpl({ + url: "https://example.com/api", + method: "GET", + responseType: "json", + maxRetries: 0, + logging: { + level: "error", + logger: mockLogger, + silent: false, + }, + }); + + expect(result.ok).toBe(false); + expect(mockLogger.error).toHaveBeenCalledWith( + "HTTP request timed out", + expect.objectContaining({ + method: "GET", + url: "https://example.com/api", + timeoutMs: undefined, + }), + ); + }); + + it("should log unknown errors", async () => { + const mockLogger = createMockLogger(); + + const unknownError = new Error("Unknown error"); + + global.fetch = vi.fn().mockRejectedValue(unknownError); + + const result = await fetcherImpl({ + url: "https://example.com/api", + method: "GET", + responseType: "json", + maxRetries: 0, + logging: { + level: "error", + logger: mockLogger, + silent: false, + }, + }); + + expect(result.ok).toBe(false); + expect(mockLogger.error).toHaveBeenCalledWith( + "HTTP request failed with error", + expect.objectContaining({ + method: "GET", + url: "https://example.com/api", + errorMessage: "Unknown error", + }), + ); + }); + }); + + describe("Logging with Redaction", () => { + it("should redact sensitive data in error logs", async () => { + const mockLogger = createMockLogger(); + mockErrorResponse({ error: "Unauthorized" }, 401, "Unauthorized"); + + await fetcherImpl({ + url: "https://example.com/api?api_key=secret", + method: "GET", + responseType: "json", + maxRetries: 0, + logging: { + level: "error", + logger: mockLogger, + silent: false, + }, + }); + + expect(mockLogger.error).toHaveBeenCalledWith( + "HTTP request failed with error status", + expect.objectContaining({ + url: "https://example.com/api?api_key=[REDACTED]", + }), + ); + }); + }); + + describe("Different HTTP Methods", () => { + it("should log GET requests", async () => { + const mockLogger = createMockLogger(); + mockSuccessResponse(); + + await fetcherImpl({ + url: "https://example.com/api", + method: "GET", + responseType: "json", + maxRetries: 0, + logging: { + level: "debug", + logger: mockLogger, + silent: false, + }, + }); + + expect(mockLogger.debug).toHaveBeenCalledWith( + "Making HTTP request", + expect.objectContaining({ + method: "GET", + }), + ); + }); + + it("should log POST requests", async () => { + const mockLogger = createMockLogger(); + mockSuccessResponse({ data: "test" }, 201, "Created"); + + await fetcherImpl({ + url: "https://example.com/api", + method: "POST", + body: { data: "test" }, + contentType: "application/json", + requestType: "json", + responseType: "json", + maxRetries: 0, + logging: { + level: "debug", + logger: mockLogger, + silent: false, + }, + }); + + expect(mockLogger.debug).toHaveBeenCalledWith( + "Making HTTP request", + expect.objectContaining({ + method: "POST", + }), + ); + }); + + it("should log PUT requests", async () => { + const mockLogger = createMockLogger(); + mockSuccessResponse(); + + await fetcherImpl({ + url: "https://example.com/api", + method: "PUT", + body: { data: "test" }, + contentType: "application/json", + requestType: "json", + responseType: "json", + maxRetries: 0, + logging: { + level: "debug", + logger: mockLogger, + silent: false, + }, + }); + + expect(mockLogger.debug).toHaveBeenCalledWith( + "Making HTTP request", + expect.objectContaining({ + method: "PUT", + }), + ); + }); + + it("should log DELETE requests", async () => { + const mockLogger = createMockLogger(); + global.fetch = vi.fn().mockResolvedValue( + new Response(null, { + status: 200, + statusText: "OK", + }), + ); + + await fetcherImpl({ + url: "https://example.com/api", + method: "DELETE", + responseType: "json", + maxRetries: 0, + logging: { + level: "debug", + logger: mockLogger, + silent: false, + }, + }); + + expect(mockLogger.debug).toHaveBeenCalledWith( + "Making HTTP request", + expect.objectContaining({ + method: "DELETE", + }), + ); + }); + }); + + describe("Status Code Logging", () => { + it("should log 2xx success status codes", async () => { + const mockLogger = createMockLogger(); + mockSuccessResponse({ data: "test" }, 201, "Created"); + + await fetcherImpl({ + url: "https://example.com/api", + method: "POST", + body: { data: "test" }, + contentType: "application/json", + requestType: "json", + responseType: "json", + maxRetries: 0, + logging: { + level: "debug", + logger: mockLogger, + silent: false, + }, + }); + + expect(mockLogger.debug).toHaveBeenCalledWith( + "HTTP request succeeded", + expect.objectContaining({ + statusCode: 201, + }), + ); + }); + + it("should log 3xx redirect status codes as success", async () => { + const mockLogger = createMockLogger(); + mockSuccessResponse({ data: "test" }, 301, "Moved Permanently"); + + await fetcherImpl({ + url: "https://example.com/api", + method: "GET", + responseType: "json", + maxRetries: 0, + logging: { + level: "debug", + logger: mockLogger, + silent: false, + }, + }); + + expect(mockLogger.debug).toHaveBeenCalledWith( + "HTTP request succeeded", + expect.objectContaining({ + statusCode: 301, + }), + ); + }); + }); +}); diff --git a/tests/unit/fetcher/makePassthroughRequest.test.ts b/tests/unit/fetcher/makePassthroughRequest.test.ts new file mode 100644 index 0000000..07cb846 --- /dev/null +++ b/tests/unit/fetcher/makePassthroughRequest.test.ts @@ -0,0 +1,504 @@ +import type { Mock } from "vitest"; +import { makePassthroughRequest } from "../../../src/core/fetcher/makePassthroughRequest"; + +describe("makePassthroughRequest", () => { + let mockFetch: Mock; + + beforeEach(() => { + mockFetch = vi.fn(); + mockFetch.mockResolvedValue(new Response(JSON.stringify({ ok: true }), { status: 200 })); + }); + + describe("URL resolution", () => { + it("should use absolute URL directly", async () => { + await makePassthroughRequest("https://api.example.com/v1/users", undefined, { + fetch: mockFetch, + }); + const [calledUrl] = mockFetch.mock.calls[0]; + expect(calledUrl).toBe("https://api.example.com/v1/users"); + }); + + it("should resolve relative path against baseUrl", async () => { + await makePassthroughRequest("/v1/users", undefined, { + baseUrl: "https://api.example.com", + fetch: mockFetch, + }); + const [calledUrl] = mockFetch.mock.calls[0]; + expect(calledUrl).toBe("https://api.example.com/v1/users"); + }); + + it("should resolve relative path against environment when baseUrl is not set", async () => { + await makePassthroughRequest("/v1/users", undefined, { + environment: "https://env.example.com", + fetch: mockFetch, + }); + const [calledUrl] = mockFetch.mock.calls[0]; + expect(calledUrl).toBe("https://env.example.com/v1/users"); + }); + + it("should prefer baseUrl over environment", async () => { + await makePassthroughRequest("/v1/users", undefined, { + baseUrl: "https://base.example.com", + environment: "https://env.example.com", + fetch: mockFetch, + }); + const [calledUrl] = mockFetch.mock.calls[0]; + expect(calledUrl).toBe("https://base.example.com/v1/users"); + }); + + it("should pass relative URL through as-is when no baseUrl or environment", async () => { + await makePassthroughRequest("/v1/users", undefined, { + fetch: mockFetch, + }); + const [calledUrl] = mockFetch.mock.calls[0]; + expect(calledUrl).toBe("/v1/users"); + }); + + it("should resolve baseUrl supplier", async () => { + await makePassthroughRequest("/v1/users", undefined, { + baseUrl: () => "https://dynamic.example.com", + fetch: mockFetch, + }); + const [calledUrl] = mockFetch.mock.calls[0]; + expect(calledUrl).toBe("https://dynamic.example.com/v1/users"); + }); + + it("should ignore absolute URL even when baseUrl is set", async () => { + await makePassthroughRequest("https://other.example.com/path", undefined, { + baseUrl: "https://base.example.com", + fetch: mockFetch, + }); + const [calledUrl] = mockFetch.mock.calls[0]; + expect(calledUrl).toBe("https://other.example.com/path"); + }); + + it("should accept a URL object", async () => { + await makePassthroughRequest(new URL("https://api.example.com/v1/users"), undefined, { + fetch: mockFetch, + }); + const [calledUrl] = mockFetch.mock.calls[0]; + expect(calledUrl).toBe("https://api.example.com/v1/users"); + }); + }); + + describe("header merge order", () => { + it("should merge headers in correct priority: SDK defaults < auth < init < requestOptions", async () => { + await makePassthroughRequest( + "https://api.example.com", + { + headers: { "X-Custom": "from-init", Authorization: "from-init" }, + }, + { + baseUrl: "https://api.example.com", + headers: { + "X-Custom": "from-sdk", + "X-SDK-Only": "sdk-value", + Authorization: "from-sdk", + }, + getAuthHeaders: async () => ({ + Authorization: "Bearer auth-token", + "X-Auth-Only": "auth-value", + }), + fetch: mockFetch, + }, + { + headers: { Authorization: "from-request-options" }, + }, + ); + const [, calledOptions] = mockFetch.mock.calls[0]; + const headers = calledOptions.headers; + + // requestOptions.headers wins for Authorization (highest priority) + expect(headers.authorization).toBe("from-request-options"); + // init.headers wins over SDK defaults for X-Custom + expect(headers["x-custom"]).toBe("from-init"); + // SDK-only header is preserved + expect(headers["x-sdk-only"]).toBe("sdk-value"); + // Auth-only header is preserved + expect(headers["x-auth-only"]).toBe("auth-value"); + }); + + it("should lowercase all header keys", async () => { + await makePassthroughRequest( + "https://api.example.com", + { + headers: { "Content-Type": "application/json" }, + }, + { + headers: { "X-Fern-Language": "JavaScript" }, + fetch: mockFetch, + }, + ); + const [, calledOptions] = mockFetch.mock.calls[0]; + const headers = calledOptions.headers; + expect(headers["content-type"]).toBe("application/json"); + expect(headers["x-fern-language"]).toBe("JavaScript"); + expect(headers["Content-Type"]).toBeUndefined(); + expect(headers["X-Fern-Language"]).toBeUndefined(); + }); + + it("should handle Headers object in init", async () => { + const initHeaders = new Headers(); + initHeaders.set("X-From-Headers-Object", "value"); + await makePassthroughRequest("https://api.example.com", { headers: initHeaders }, { fetch: mockFetch }); + const [, calledOptions] = mockFetch.mock.calls[0]; + expect(calledOptions.headers["x-from-headers-object"]).toBe("value"); + }); + + it("should handle array-style headers in init", async () => { + await makePassthroughRequest( + "https://api.example.com", + { headers: [["X-Array-Header", "array-value"]] }, + { fetch: mockFetch }, + ); + const [, calledOptions] = mockFetch.mock.calls[0]; + expect(calledOptions.headers["x-array-header"]).toBe("array-value"); + }); + + it("should skip null SDK default header values", async () => { + await makePassthroughRequest("https://api.example.com", undefined, { + headers: { "X-Present": "value", "X-Null": null }, + fetch: mockFetch, + }); + const [, calledOptions] = mockFetch.mock.calls[0]; + expect(calledOptions.headers["x-present"]).toBe("value"); + expect(calledOptions.headers["x-null"]).toBeUndefined(); + }); + }); + + describe("auth headers", () => { + it("should include auth headers when getAuthHeaders is provided", async () => { + await makePassthroughRequest("https://api.example.com", undefined, { + baseUrl: "https://api.example.com", + getAuthHeaders: async () => ({ Authorization: "Bearer my-token" }), + fetch: mockFetch, + }); + const [, calledOptions] = mockFetch.mock.calls[0]; + expect(calledOptions.headers.authorization).toBe("Bearer my-token"); + }); + + it("should work without auth headers", async () => { + await makePassthroughRequest("https://api.example.com", undefined, { + fetch: mockFetch, + }); + const [, calledOptions] = mockFetch.mock.calls[0]; + expect(calledOptions.headers.authorization).toBeUndefined(); + }); + + it("should allow init headers to override auth headers", async () => { + await makePassthroughRequest( + "https://api.example.com", + { headers: { Authorization: "Bearer override" } }, + { + baseUrl: "https://api.example.com", + getAuthHeaders: async () => ({ Authorization: "Bearer sdk-auth" }), + fetch: mockFetch, + }, + ); + const [, calledOptions] = mockFetch.mock.calls[0]; + expect(calledOptions.headers.authorization).toBe("Bearer override"); + }); + }); + + describe("auth header origin scoping", () => { + it("should attach auth headers to relative paths resolved against baseUrl", async () => { + await makePassthroughRequest("/v1/users", undefined, { + baseUrl: "https://api.example.com", + getAuthHeaders: async () => ({ Authorization: "Bearer my-token" }), + fetch: mockFetch, + }); + const [, calledOptions] = mockFetch.mock.calls[0]; + expect(calledOptions.headers.authorization).toBe("Bearer my-token"); + }); + + it("should attach auth headers to same-origin absolute URLs", async () => { + await makePassthroughRequest("https://api.example.com/v1/users", undefined, { + baseUrl: "https://api.example.com", + getAuthHeaders: async () => ({ Authorization: "Bearer my-token" }), + fetch: mockFetch, + }); + const [, calledOptions] = mockFetch.mock.calls[0]; + expect(calledOptions.headers.authorization).toBe("Bearer my-token"); + }); + + it("should attach auth headers when the absolute URL matches the environment origin", async () => { + await makePassthroughRequest("https://env.example.com/v1/users", undefined, { + environment: "https://env.example.com", + getAuthHeaders: async () => ({ Authorization: "Bearer my-token" }), + fetch: mockFetch, + }); + const [, calledOptions] = mockFetch.mock.calls[0]; + expect(calledOptions.headers.authorization).toBe("Bearer my-token"); + }); + + it("should NOT attach auth headers to a cross-origin absolute URL", async () => { + await makePassthroughRequest("https://evil.example.com/steal", undefined, { + baseUrl: "https://api.example.com", + getAuthHeaders: async () => ({ Authorization: "Bearer my-token" }), + fetch: mockFetch, + }); + const [, calledOptions] = mockFetch.mock.calls[0]; + expect(calledOptions.headers.authorization).toBeUndefined(); + }); + + it("should NOT attach auth headers to a cross-origin URL differing only by port", async () => { + await makePassthroughRequest("https://api.example.com:9999/steal", undefined, { + baseUrl: "https://api.example.com", + getAuthHeaders: async () => ({ Authorization: "Bearer my-token" }), + fetch: mockFetch, + }); + const [, calledOptions] = mockFetch.mock.calls[0]; + expect(calledOptions.headers.authorization).toBeUndefined(); + }); + + it("should NOT attach auth headers when no baseUrl or environment is configured", async () => { + await makePassthroughRequest("https://api.example.com/v1/users", undefined, { + getAuthHeaders: async () => ({ Authorization: "Bearer my-token" }), + fetch: mockFetch, + }); + const [, calledOptions] = mockFetch.mock.calls[0]; + expect(calledOptions.headers.authorization).toBeUndefined(); + }); + + it("should still allow explicit init headers on cross-origin requests", async () => { + await makePassthroughRequest( + "https://evil.example.com/steal", + { headers: { "X-Custom": "keep-me" } }, + { + baseUrl: "https://api.example.com", + getAuthHeaders: async () => ({ Authorization: "Bearer my-token" }), + fetch: mockFetch, + }, + ); + const [, calledOptions] = mockFetch.mock.calls[0]; + expect(calledOptions.headers.authorization).toBeUndefined(); + expect(calledOptions.headers["x-custom"]).toBe("keep-me"); + }); + }); + + describe("method and body", () => { + it("should default to GET when no method specified", async () => { + await makePassthroughRequest("https://api.example.com", undefined, { + fetch: mockFetch, + }); + const [, calledOptions] = mockFetch.mock.calls[0]; + expect(calledOptions.method).toBe("GET"); + }); + + it("should use the method from init", async () => { + await makePassthroughRequest( + "https://api.example.com", + { method: "POST", body: JSON.stringify({ key: "value" }) }, + { fetch: mockFetch }, + ); + const [, calledOptions] = mockFetch.mock.calls[0]; + expect(calledOptions.method).toBe("POST"); + expect(calledOptions.body).toBe(JSON.stringify({ key: "value" })); + }); + + it("should pass body as undefined when not provided", async () => { + await makePassthroughRequest("https://api.example.com", { method: "GET" }, { fetch: mockFetch }); + const [, calledOptions] = mockFetch.mock.calls[0]; + expect(calledOptions.body).toBeUndefined(); + }); + }); + + describe("timeout and retries", () => { + it("should use requestOptions timeout over client timeout", async () => { + await makePassthroughRequest( + "https://api.example.com", + undefined, + { timeoutInSeconds: 30, fetch: mockFetch }, + { timeoutInSeconds: 10 }, + ); + // The timeout is passed to makeRequest which converts to ms + // We verify via the signal timing behavior (indirectly tested through makeRequest) + expect(mockFetch).toHaveBeenCalledTimes(1); + }); + + it("should use client timeout when requestOptions timeout is not set", async () => { + await makePassthroughRequest("https://api.example.com", undefined, { + timeoutInSeconds: 30, + fetch: mockFetch, + }); + expect(mockFetch).toHaveBeenCalledTimes(1); + }); + + it("should use requestOptions maxRetries over client maxRetries", async () => { + mockFetch.mockResolvedValue(new Response("", { status: 502 })); + vi.spyOn(global, "setTimeout").mockImplementation((callback: (args: void) => void) => { + process.nextTick(callback); + return null as any; + }); + + await makePassthroughRequest( + "https://api.example.com", + undefined, + { maxRetries: 5, fetch: mockFetch }, + { maxRetries: 1 }, + ); + // 1 initial + 1 retry = 2 calls + expect(mockFetch).toHaveBeenCalledTimes(2); + + vi.restoreAllMocks(); + }); + }); + + describe("abort signal", () => { + it("should use requestOptions.abortSignal over init.signal", async () => { + const initController = new AbortController(); + const requestController = new AbortController(); + + await makePassthroughRequest( + "https://api.example.com", + { signal: initController.signal }, + { fetch: mockFetch }, + { abortSignal: requestController.signal }, + ); + const [, calledOptions] = mockFetch.mock.calls[0]; + // The signal passed to makeRequest is combined with timeout signal via anySignal, + // but the requestOptions.abortSignal should be the one that's used (not init.signal) + expect(calledOptions.signal).toBeDefined(); + }); + + it("should use init.signal when requestOptions.abortSignal is not set", async () => { + const initController = new AbortController(); + + await makePassthroughRequest( + "https://api.example.com", + { signal: initController.signal }, + { fetch: mockFetch }, + ); + const [, calledOptions] = mockFetch.mock.calls[0]; + expect(calledOptions.signal).toBeDefined(); + }); + }); + + describe("credentials", () => { + it("should pass credentials include when set", async () => { + await makePassthroughRequest("https://api.example.com", { credentials: "include" }, { fetch: mockFetch }); + const [, calledOptions] = mockFetch.mock.calls[0]; + expect(calledOptions.credentials).toBe("include"); + }); + + it("should not pass credentials when not set to include", async () => { + await makePassthroughRequest( + "https://api.example.com", + { credentials: "same-origin" }, + { + fetch: mockFetch, + }, + ); + const [, calledOptions] = mockFetch.mock.calls[0]; + expect(calledOptions.credentials).toBeUndefined(); + }); + }); + + describe("response", () => { + it("should return the Response object from fetch", async () => { + const mockResponse = new Response(JSON.stringify({ data: "test" }), { + status: 200, + headers: { "Content-Type": "application/json" }, + }); + mockFetch.mockResolvedValue(mockResponse); + + const response = await makePassthroughRequest("https://api.example.com", undefined, { + fetch: mockFetch, + }); + expect(response).toBe(mockResponse); + expect(response.status).toBe(200); + }); + + it("should return error responses without throwing", async () => { + const errorResponse = new Response("Not Found", { status: 404 }); + mockFetch.mockResolvedValue(errorResponse); + + const response = await makePassthroughRequest("https://api.example.com", undefined, { + fetch: mockFetch, + }); + expect(response.status).toBe(404); + }); + }); + + describe("Request object input", () => { + it("should extract URL from Request object", async () => { + const request = new Request("https://api.example.com/v1/resource", { method: "POST" }); + await makePassthroughRequest(request, undefined, { + fetch: mockFetch, + }); + const [calledUrl, calledOptions] = mockFetch.mock.calls[0]; + expect(calledUrl).toBe("https://api.example.com/v1/resource"); + expect(calledOptions.method).toBe("POST"); + }); + + it("should extract headers from Request object when no init provided", async () => { + const request = new Request("https://api.example.com", { + headers: { "X-From-Request": "request-value" }, + }); + await makePassthroughRequest(request, undefined, { + fetch: mockFetch, + }); + const [, calledOptions] = mockFetch.mock.calls[0]; + expect(calledOptions.headers["x-from-request"]).toBe("request-value"); + }); + + it("should use explicit init over Request object properties", async () => { + const request = new Request("https://api.example.com", { + method: "POST", + headers: { "X-From-Request": "request-value" }, + }); + await makePassthroughRequest( + request, + { method: "PUT", headers: { "X-From-Init": "init-value" } }, + { fetch: mockFetch }, + ); + const [, calledOptions] = mockFetch.mock.calls[0]; + expect(calledOptions.method).toBe("PUT"); + expect(calledOptions.headers["x-from-init"]).toBe("init-value"); + // Request headers should NOT be present since explicit init was provided + expect(calledOptions.headers["x-from-request"]).toBeUndefined(); + }); + }); + + describe("SDK default header suppliers", () => { + it("should resolve supplier functions for SDK default headers", async () => { + await makePassthroughRequest("https://api.example.com", undefined, { + headers: { + "X-Static": "static-value", + "X-Dynamic": () => "dynamic-value", + }, + fetch: mockFetch, + }); + const [, calledOptions] = mockFetch.mock.calls[0]; + expect(calledOptions.headers["x-static"]).toBe("static-value"); + expect(calledOptions.headers["x-dynamic"]).toBe("dynamic-value"); + }); + }); + + describe("debug logging", () => { + it("should redact credentials in the logged request URL", async () => { + const mockLogger = { + debug: vi.fn(), + info: vi.fn(), + warn: vi.fn(), + error: vi.fn(), + }; + await makePassthroughRequest("https://user:password@api.example.com/v1/users?token=secret", undefined, { + fetch: mockFetch, + logging: { + level: "debug", + logger: mockLogger, + silent: false, + }, + }); + + const loggedUrls = mockLogger.debug.mock.calls.map(([, meta]) => (meta as { url: string }).url); + expect(loggedUrls.length).toBeGreaterThan(0); + for (const loggedUrl of loggedUrls) { + expect(loggedUrl).toBe("https://[REDACTED]@api.example.com/v1/users?token=[REDACTED]"); + expect(loggedUrl).not.toContain("password"); + expect(loggedUrl).not.toContain("secret"); + } + }); + }); +}); diff --git a/tests/unit/fetcher/makeRequest.test.ts b/tests/unit/fetcher/makeRequest.test.ts new file mode 100644 index 0000000..bde1945 --- /dev/null +++ b/tests/unit/fetcher/makeRequest.test.ts @@ -0,0 +1,158 @@ +import type { Mock } from "vitest"; +import { + isCacheNoStoreSupported, + makeRequest, + resetCacheNoStoreSupported, +} from "../../../src/core/fetcher/makeRequest"; + +describe("Test makeRequest", () => { + const mockPostUrl = "https://httpbin.org/post"; + const mockGetUrl = "https://httpbin.org/get"; + const mockHeaders = { "Content-Type": "application/json" }; + const mockBody = JSON.stringify({ key: "value" }); + + let mockFetch: Mock; + + beforeEach(() => { + mockFetch = vi.fn(); + mockFetch.mockResolvedValue(new Response(JSON.stringify({ test: "successful" }), { status: 200 })); + resetCacheNoStoreSupported(); + }); + + it("should handle POST request correctly", async () => { + const response = await makeRequest(mockFetch, mockPostUrl, "POST", mockHeaders, mockBody); + const responseBody = await response.json(); + expect(responseBody).toEqual({ test: "successful" }); + expect(mockFetch).toHaveBeenCalledTimes(1); + const [calledUrl, calledOptions] = mockFetch.mock.calls[0]; + expect(calledUrl).toBe(mockPostUrl); + expect(calledOptions).toEqual( + expect.objectContaining({ + method: "POST", + headers: mockHeaders, + body: mockBody, + credentials: undefined, + }), + ); + expect(calledOptions.signal).toBeDefined(); + expect(calledOptions.signal).toBeInstanceOf(AbortSignal); + }); + + it("should handle GET request correctly", async () => { + const response = await makeRequest(mockFetch, mockGetUrl, "GET", mockHeaders, undefined); + const responseBody = await response.json(); + expect(responseBody).toEqual({ test: "successful" }); + expect(mockFetch).toHaveBeenCalledTimes(1); + const [calledUrl, calledOptions] = mockFetch.mock.calls[0]; + expect(calledUrl).toBe(mockGetUrl); + expect(calledOptions).toEqual( + expect.objectContaining({ + method: "GET", + headers: mockHeaders, + body: undefined, + credentials: undefined, + }), + ); + expect(calledOptions.signal).toBeDefined(); + expect(calledOptions.signal).toBeInstanceOf(AbortSignal); + }); + + it("should not include cache option when disableCache is not set", async () => { + await makeRequest(mockFetch, mockGetUrl, "GET", mockHeaders, undefined); + const [, calledOptions] = mockFetch.mock.calls[0]; + expect(calledOptions.cache).toBeUndefined(); + }); + + it("should not include cache option when disableCache is false", async () => { + await makeRequest( + mockFetch, + mockGetUrl, + "GET", + mockHeaders, + undefined, + undefined, + undefined, + undefined, + undefined, + false, + ); + const [, calledOptions] = mockFetch.mock.calls[0]; + expect(calledOptions.cache).toBeUndefined(); + }); + + it("should include cache: no-store when disableCache is true and runtime supports it", async () => { + // In Node.js test environment, Request supports the cache option + expect(isCacheNoStoreSupported()).toBe(true); + await makeRequest( + mockFetch, + mockGetUrl, + "GET", + mockHeaders, + undefined, + undefined, + undefined, + undefined, + undefined, + true, + ); + const [, calledOptions] = mockFetch.mock.calls[0]; + expect(calledOptions.cache).toBe("no-store"); + }); + + it("should cache the result of isCacheNoStoreSupported", () => { + const first = isCacheNoStoreSupported(); + const second = isCacheNoStoreSupported(); + expect(first).toBe(second); + }); + + it("should reset cache detection state with resetCacheNoStoreSupported", () => { + // First call caches the result + const first = isCacheNoStoreSupported(); + expect(first).toBe(true); + + // Reset clears the cache + resetCacheNoStoreSupported(); + + // After reset, it should re-detect (and still return true in Node.js) + const second = isCacheNoStoreSupported(); + expect(second).toBe(true); + }); + + it("should not include cache option when runtime does not support it (e.g. Cloudflare Workers)", async () => { + // Mock Request constructor to throw when cache option is passed, + // simulating runtimes like Cloudflare Workers + const OriginalRequest = globalThis.Request; + globalThis.Request = class MockRequest { + constructor(_url: string, init?: RequestInit) { + if (init?.cache != null) { + throw new TypeError("The 'cache' field on 'RequestInitializerDict' is not implemented."); + } + } + } as unknown as typeof Request; + + try { + // Reset so the detection runs fresh with the mocked Request + resetCacheNoStoreSupported(); + expect(isCacheNoStoreSupported()).toBe(false); + + await makeRequest( + mockFetch, + mockGetUrl, + "GET", + mockHeaders, + undefined, + undefined, + undefined, + undefined, + undefined, + true, + ); + const [, calledOptions] = mockFetch.mock.calls[0]; + expect(calledOptions.cache).toBeUndefined(); + } finally { + // Restore original Request + globalThis.Request = OriginalRequest; + resetCacheNoStoreSupported(); + } + }); +}); diff --git a/tests/unit/fetcher/redacting.test.ts b/tests/unit/fetcher/redacting.test.ts new file mode 100644 index 0000000..685f1dd --- /dev/null +++ b/tests/unit/fetcher/redacting.test.ts @@ -0,0 +1,1221 @@ +import { fetcherImpl } from "../../../src/core/fetcher/Fetcher"; + +function createMockLogger() { + return { + debug: vi.fn(), + info: vi.fn(), + warn: vi.fn(), + error: vi.fn(), + }; +} + +function mockSuccessResponse(data: unknown = { data: "test" }, status = 200, statusText = "OK") { + global.fetch = vi.fn().mockResolvedValue( + new Response(JSON.stringify(data), { + status, + statusText, + }), + ); +} + +describe("Redacting Logic", () => { + describe("Header Redaction", () => { + it("should redact authorization header", async () => { + const mockLogger = createMockLogger(); + mockSuccessResponse(); + + await fetcherImpl({ + url: "https://example.com/api", + method: "GET", + headers: { Authorization: "Bearer secret-token-12345" }, + responseType: "json", + maxRetries: 0, + logging: { + level: "debug", + logger: mockLogger, + silent: false, + }, + }); + + expect(mockLogger.debug).toHaveBeenCalledWith( + "Making HTTP request", + expect.objectContaining({ + headers: expect.toContainHeaders({ + Authorization: "[REDACTED]", + }), + }), + ); + }); + + it("should redact api-key header (case-insensitive)", async () => { + const mockLogger = createMockLogger(); + mockSuccessResponse(); + + await fetcherImpl({ + url: "https://example.com/api", + method: "GET", + headers: { "X-API-KEY": "secret-api-key" }, + responseType: "json", + maxRetries: 0, + logging: { + level: "debug", + logger: mockLogger, + silent: false, + }, + }); + + expect(mockLogger.debug).toHaveBeenCalledWith( + "Making HTTP request", + expect.objectContaining({ + headers: expect.toContainHeaders({ + "X-API-KEY": "[REDACTED]", + }), + }), + ); + }); + + it("should redact cookie header", async () => { + const mockLogger = createMockLogger(); + mockSuccessResponse(); + + await fetcherImpl({ + url: "https://example.com/api", + method: "GET", + headers: { Cookie: "session=abc123; token=xyz789" }, + responseType: "json", + maxRetries: 0, + logging: { + level: "debug", + logger: mockLogger, + silent: false, + }, + }); + + expect(mockLogger.debug).toHaveBeenCalledWith( + "Making HTTP request", + expect.objectContaining({ + headers: expect.toContainHeaders({ + Cookie: "[REDACTED]", + }), + }), + ); + }); + + it("should redact x-auth-token header", async () => { + const mockLogger = createMockLogger(); + mockSuccessResponse(); + + await fetcherImpl({ + url: "https://example.com/api", + method: "GET", + headers: { "x-auth-token": "auth-token-12345" }, + responseType: "json", + maxRetries: 0, + logging: { + level: "debug", + logger: mockLogger, + silent: false, + }, + }); + + expect(mockLogger.debug).toHaveBeenCalledWith( + "Making HTTP request", + expect.objectContaining({ + headers: expect.toContainHeaders({ + "x-auth-token": "[REDACTED]", + }), + }), + ); + }); + + it("should redact proxy-authorization header", async () => { + const mockLogger = createMockLogger(); + mockSuccessResponse(); + + await fetcherImpl({ + url: "https://example.com/api", + method: "GET", + headers: { "Proxy-Authorization": "Basic credentials" }, + responseType: "json", + maxRetries: 0, + logging: { + level: "debug", + logger: mockLogger, + silent: false, + }, + }); + + expect(mockLogger.debug).toHaveBeenCalledWith( + "Making HTTP request", + expect.objectContaining({ + headers: expect.toContainHeaders({ + "Proxy-Authorization": "[REDACTED]", + }), + }), + ); + }); + + it("should redact x-csrf-token header", async () => { + const mockLogger = createMockLogger(); + mockSuccessResponse(); + + await fetcherImpl({ + url: "https://example.com/api", + method: "GET", + headers: { "X-CSRF-Token": "csrf-token-abc" }, + responseType: "json", + maxRetries: 0, + logging: { + level: "debug", + logger: mockLogger, + silent: false, + }, + }); + + expect(mockLogger.debug).toHaveBeenCalledWith( + "Making HTTP request", + expect.objectContaining({ + headers: expect.toContainHeaders({ + "X-CSRF-Token": "[REDACTED]", + }), + }), + ); + }); + + it("should redact www-authenticate header", async () => { + const mockLogger = createMockLogger(); + mockSuccessResponse(); + + await fetcherImpl({ + url: "https://example.com/api", + method: "GET", + headers: { "WWW-Authenticate": "Bearer realm=example" }, + responseType: "json", + maxRetries: 0, + logging: { + level: "debug", + logger: mockLogger, + silent: false, + }, + }); + + expect(mockLogger.debug).toHaveBeenCalledWith( + "Making HTTP request", + expect.objectContaining({ + headers: expect.toContainHeaders({ + "WWW-Authenticate": "[REDACTED]", + }), + }), + ); + }); + + it("should redact x-session-token header", async () => { + const mockLogger = createMockLogger(); + mockSuccessResponse(); + + await fetcherImpl({ + url: "https://example.com/api", + method: "GET", + headers: { "X-Session-Token": "session-token-xyz" }, + responseType: "json", + maxRetries: 0, + logging: { + level: "debug", + logger: mockLogger, + silent: false, + }, + }); + + expect(mockLogger.debug).toHaveBeenCalledWith( + "Making HTTP request", + expect.objectContaining({ + headers: expect.toContainHeaders({ + "X-Session-Token": "[REDACTED]", + }), + }), + ); + }); + + it("should not redact non-sensitive headers", async () => { + const mockLogger = createMockLogger(); + mockSuccessResponse(); + + await fetcherImpl({ + url: "https://example.com/api", + method: "GET", + headers: { + "Content-Type": "application/json", + "User-Agent": "Test/1.0", + Accept: "application/json", + }, + responseType: "json", + maxRetries: 0, + logging: { + level: "debug", + logger: mockLogger, + silent: false, + }, + }); + + expect(mockLogger.debug).toHaveBeenCalledWith( + "Making HTTP request", + expect.objectContaining({ + headers: expect.toContainHeaders({ + "Content-Type": "application/json", + "User-Agent": "Test/1.0", + Accept: "application/json", + }), + }), + ); + }); + + it("should redact multiple sensitive headers at once", async () => { + const mockLogger = createMockLogger(); + mockSuccessResponse(); + + await fetcherImpl({ + url: "https://example.com/api", + method: "GET", + headers: { + Authorization: "Bearer token", + "X-API-Key": "api-key", + Cookie: "session=123", + "Content-Type": "application/json", + }, + responseType: "json", + maxRetries: 0, + logging: { + level: "debug", + logger: mockLogger, + silent: false, + }, + }); + + expect(mockLogger.debug).toHaveBeenCalledWith( + "Making HTTP request", + expect.objectContaining({ + headers: expect.toContainHeaders({ + Authorization: "[REDACTED]", + "X-API-Key": "[REDACTED]", + Cookie: "[REDACTED]", + "Content-Type": "application/json", + }), + }), + ); + }); + }); + + describe("Response Header Redaction", () => { + it("should redact Set-Cookie in response headers", async () => { + const mockLogger = createMockLogger(); + + const mockHeaders = new Headers(); + mockHeaders.set("Set-Cookie", "session=abc123; HttpOnly; Secure"); + mockHeaders.set("Content-Type", "application/json"); + + global.fetch = vi.fn().mockResolvedValue( + new Response(JSON.stringify({ data: "test" }), { + status: 200, + statusText: "OK", + headers: mockHeaders, + }), + ); + + await fetcherImpl({ + url: "https://example.com/api", + method: "GET", + responseType: "json", + maxRetries: 0, + logging: { + level: "debug", + logger: mockLogger, + silent: false, + }, + }); + + expect(mockLogger.debug).toHaveBeenCalledWith( + "HTTP request succeeded", + expect.objectContaining({ + responseHeaders: expect.toContainHeaders({ + "set-cookie": "[REDACTED]", + "content-type": "application/json", + }), + }), + ); + }); + + it("should redact authorization in response headers", async () => { + const mockLogger = createMockLogger(); + + const mockHeaders = new Headers(); + mockHeaders.set("Authorization", "Bearer token-123"); + mockHeaders.set("Content-Type", "application/json"); + + global.fetch = vi.fn().mockResolvedValue( + new Response(JSON.stringify({ data: "test" }), { + status: 200, + statusText: "OK", + headers: mockHeaders, + }), + ); + + await fetcherImpl({ + url: "https://example.com/api", + method: "GET", + responseType: "json", + maxRetries: 0, + logging: { + level: "debug", + logger: mockLogger, + silent: false, + }, + }); + + expect(mockLogger.debug).toHaveBeenCalledWith( + "HTTP request succeeded", + expect.objectContaining({ + responseHeaders: expect.toContainHeaders({ + authorization: "[REDACTED]", + "content-type": "application/json", + }), + }), + ); + }); + + it("should redact response headers in error responses", async () => { + const mockLogger = createMockLogger(); + + const mockHeaders = new Headers(); + mockHeaders.set("WWW-Authenticate", "Bearer realm=example"); + mockHeaders.set("Content-Type", "application/json"); + + global.fetch = vi.fn().mockResolvedValue( + new Response(JSON.stringify({ error: "Unauthorized" }), { + status: 401, + statusText: "Unauthorized", + headers: mockHeaders, + }), + ); + + await fetcherImpl({ + url: "https://example.com/api", + method: "GET", + responseType: "json", + maxRetries: 0, + logging: { + level: "error", + logger: mockLogger, + silent: false, + }, + }); + + expect(mockLogger.error).toHaveBeenCalledWith( + "HTTP request failed with error status", + expect.objectContaining({ + responseHeaders: expect.toContainHeaders({ + "www-authenticate": "[REDACTED]", + "content-type": "application/json", + }), + }), + ); + }); + }); + + describe("Query Parameter Redaction", () => { + it("should redact api_key query parameter", async () => { + const mockLogger = createMockLogger(); + mockSuccessResponse(); + + await fetcherImpl({ + url: "https://example.com/api", + method: "GET", + queryParameters: { api_key: "secret-key" }, + responseType: "json", + maxRetries: 0, + logging: { + level: "debug", + logger: mockLogger, + silent: false, + }, + }); + + expect(mockLogger.debug).toHaveBeenCalledWith( + "Making HTTP request", + expect.objectContaining({ + queryParameters: expect.objectContaining({ + api_key: "[REDACTED]", + }), + }), + ); + }); + + it("should redact token query parameter", async () => { + const mockLogger = createMockLogger(); + mockSuccessResponse(); + + await fetcherImpl({ + url: "https://example.com/api", + method: "GET", + queryParameters: { token: "secret-token" }, + responseType: "json", + maxRetries: 0, + logging: { + level: "debug", + logger: mockLogger, + silent: false, + }, + }); + + expect(mockLogger.debug).toHaveBeenCalledWith( + "Making HTTP request", + expect.objectContaining({ + queryParameters: expect.objectContaining({ + token: "[REDACTED]", + }), + }), + ); + }); + + it("should redact access_token query parameter", async () => { + const mockLogger = createMockLogger(); + mockSuccessResponse(); + + await fetcherImpl({ + url: "https://example.com/api", + method: "GET", + queryParameters: { access_token: "secret-access-token" }, + responseType: "json", + maxRetries: 0, + logging: { + level: "debug", + logger: mockLogger, + silent: false, + }, + }); + + expect(mockLogger.debug).toHaveBeenCalledWith( + "Making HTTP request", + expect.objectContaining({ + queryParameters: expect.objectContaining({ + access_token: "[REDACTED]", + }), + }), + ); + }); + + it("should redact password query parameter", async () => { + const mockLogger = createMockLogger(); + mockSuccessResponse(); + + await fetcherImpl({ + url: "https://example.com/api", + method: "GET", + queryParameters: { password: "secret-password" }, + responseType: "json", + maxRetries: 0, + logging: { + level: "debug", + logger: mockLogger, + silent: false, + }, + }); + + expect(mockLogger.debug).toHaveBeenCalledWith( + "Making HTTP request", + expect.objectContaining({ + queryParameters: expect.objectContaining({ + password: "[REDACTED]", + }), + }), + ); + }); + + it("should redact secret query parameter", async () => { + const mockLogger = createMockLogger(); + mockSuccessResponse(); + + await fetcherImpl({ + url: "https://example.com/api", + method: "GET", + queryParameters: { secret: "secret-value" }, + responseType: "json", + maxRetries: 0, + logging: { + level: "debug", + logger: mockLogger, + silent: false, + }, + }); + + expect(mockLogger.debug).toHaveBeenCalledWith( + "Making HTTP request", + expect.objectContaining({ + queryParameters: expect.objectContaining({ + secret: "[REDACTED]", + }), + }), + ); + }); + + it("should redact session_id query parameter", async () => { + const mockLogger = createMockLogger(); + mockSuccessResponse(); + + await fetcherImpl({ + url: "https://example.com/api", + method: "GET", + queryParameters: { session_id: "session-123" }, + responseType: "json", + maxRetries: 0, + logging: { + level: "debug", + logger: mockLogger, + silent: false, + }, + }); + + expect(mockLogger.debug).toHaveBeenCalledWith( + "Making HTTP request", + expect.objectContaining({ + queryParameters: expect.objectContaining({ + session_id: "[REDACTED]", + }), + }), + ); + }); + + it("should not redact non-sensitive query parameters", async () => { + const mockLogger = createMockLogger(); + mockSuccessResponse(); + + await fetcherImpl({ + url: "https://example.com/api", + method: "GET", + queryParameters: { + page: "1", + limit: "10", + sort: "name", + }, + responseType: "json", + maxRetries: 0, + logging: { + level: "debug", + logger: mockLogger, + silent: false, + }, + }); + + expect(mockLogger.debug).toHaveBeenCalledWith( + "Making HTTP request", + expect.objectContaining({ + queryParameters: expect.objectContaining({ + page: "1", + limit: "10", + sort: "name", + }), + }), + ); + }); + + it("should not redact parameters containing 'auth' substring like 'author'", async () => { + const mockLogger = createMockLogger(); + mockSuccessResponse(); + + await fetcherImpl({ + url: "https://example.com/api", + method: "GET", + queryParameters: { + author: "john", + authenticate: "false", + authorization_level: "user", + }, + responseType: "json", + maxRetries: 0, + logging: { + level: "debug", + logger: mockLogger, + silent: false, + }, + }); + + expect(mockLogger.debug).toHaveBeenCalledWith( + "Making HTTP request", + expect.objectContaining({ + queryParameters: expect.objectContaining({ + author: "john", + authenticate: "false", + authorization_level: "user", + }), + }), + ); + }); + + it("should handle undefined query parameters", async () => { + const mockLogger = createMockLogger(); + mockSuccessResponse(); + + await fetcherImpl({ + url: "https://example.com/api", + method: "GET", + responseType: "json", + maxRetries: 0, + logging: { + level: "debug", + logger: mockLogger, + silent: false, + }, + }); + + expect(mockLogger.debug).toHaveBeenCalledWith( + "Making HTTP request", + expect.objectContaining({ + queryParameters: undefined, + }), + ); + }); + + it("should redact case-insensitive query parameters", async () => { + const mockLogger = createMockLogger(); + mockSuccessResponse(); + + await fetcherImpl({ + url: "https://example.com/api", + method: "GET", + queryParameters: { API_KEY: "secret-key", Token: "secret-token" }, + responseType: "json", + maxRetries: 0, + logging: { + level: "debug", + logger: mockLogger, + silent: false, + }, + }); + + expect(mockLogger.debug).toHaveBeenCalledWith( + "Making HTTP request", + expect.objectContaining({ + queryParameters: expect.objectContaining({ + API_KEY: "[REDACTED]", + Token: "[REDACTED]", + }), + }), + ); + }); + }); + + describe("Query String Redaction", () => { + it("should redact api_key in queryString via URL", async () => { + const mockLogger = createMockLogger(); + mockSuccessResponse(); + + await fetcherImpl({ + url: "https://example.com/api", + method: "GET", + queryString: "api_key=secret-key&page=1", + responseType: "json", + maxRetries: 0, + logging: { + level: "debug", + logger: mockLogger, + silent: false, + }, + }); + + expect(mockLogger.debug).toHaveBeenCalledWith( + "Making HTTP request", + expect.objectContaining({ + url: "https://example.com/api?api_key=[REDACTED]&page=1", + }), + ); + }); + + it("should redact multiple sensitive params in queryString", async () => { + const mockLogger = createMockLogger(); + mockSuccessResponse(); + + await fetcherImpl({ + url: "https://example.com/api", + method: "GET", + queryString: "token=t&password=p&page=1", + responseType: "json", + maxRetries: 0, + logging: { + level: "debug", + logger: mockLogger, + silent: false, + }, + }); + + expect(mockLogger.debug).toHaveBeenCalledWith( + "Making HTTP request", + expect.objectContaining({ + url: "https://example.com/api?token=[REDACTED]&password=[REDACTED]&page=1", + }), + ); + }); + + it("should not redact non-sensitive params in queryString", async () => { + const mockLogger = createMockLogger(); + mockSuccessResponse(); + + await fetcherImpl({ + url: "https://example.com/api", + method: "GET", + queryString: "page=1&limit=10&sort=name", + responseType: "json", + maxRetries: 0, + logging: { + level: "debug", + logger: mockLogger, + silent: false, + }, + }); + + expect(mockLogger.debug).toHaveBeenCalledWith( + "Making HTTP request", + expect.objectContaining({ + url: "https://example.com/api?page=1&limit=10&sort=name", + }), + ); + }); + + it("should prefer queryString over queryParameters when both provided", async () => { + const mockLogger = createMockLogger(); + mockSuccessResponse(); + + await fetcherImpl({ + url: "https://example.com/api", + method: "GET", + queryString: "page=1", + queryParameters: { api_key: "secret-key" }, + responseType: "json", + maxRetries: 0, + logging: { + level: "debug", + logger: mockLogger, + silent: false, + }, + }); + + expect(mockLogger.debug).toHaveBeenCalledWith( + "Making HTTP request", + expect.objectContaining({ + url: "https://example.com/api?page=1", + queryParameters: expect.objectContaining({ + api_key: "[REDACTED]", + }), + }), + ); + }); + }); + + describe("URL Redaction", () => { + it("should redact credentials in URL", async () => { + const mockLogger = createMockLogger(); + mockSuccessResponse(); + + await fetcherImpl({ + url: "https://user:password@example.com/api", + method: "GET", + responseType: "json", + maxRetries: 0, + logging: { + level: "debug", + logger: mockLogger, + silent: false, + }, + }); + + expect(mockLogger.debug).toHaveBeenCalledWith( + "Making HTTP request", + expect.objectContaining({ + url: "https://[REDACTED]@example.com/api", + }), + ); + }); + + it("should redact api_key in query string", async () => { + const mockLogger = createMockLogger(); + mockSuccessResponse(); + + await fetcherImpl({ + url: "https://example.com/api?api_key=secret-key&page=1", + method: "GET", + responseType: "json", + maxRetries: 0, + logging: { + level: "debug", + logger: mockLogger, + silent: false, + }, + }); + + expect(mockLogger.debug).toHaveBeenCalledWith( + "Making HTTP request", + expect.objectContaining({ + url: "https://example.com/api?api_key=[REDACTED]&page=1", + }), + ); + }); + + it("should redact token in query string", async () => { + const mockLogger = createMockLogger(); + mockSuccessResponse(); + + await fetcherImpl({ + url: "https://example.com/api?token=secret-token", + method: "GET", + responseType: "json", + maxRetries: 0, + logging: { + level: "debug", + logger: mockLogger, + silent: false, + }, + }); + + expect(mockLogger.debug).toHaveBeenCalledWith( + "Making HTTP request", + expect.objectContaining({ + url: "https://example.com/api?token=[REDACTED]", + }), + ); + }); + + it("should redact password in query string", async () => { + const mockLogger = createMockLogger(); + mockSuccessResponse(); + + await fetcherImpl({ + url: "https://example.com/api?username=user&password=secret", + method: "GET", + responseType: "json", + maxRetries: 0, + logging: { + level: "debug", + logger: mockLogger, + silent: false, + }, + }); + + expect(mockLogger.debug).toHaveBeenCalledWith( + "Making HTTP request", + expect.objectContaining({ + url: "https://example.com/api?username=user&password=[REDACTED]", + }), + ); + }); + + it("should not redact non-sensitive query strings", async () => { + const mockLogger = createMockLogger(); + mockSuccessResponse(); + + await fetcherImpl({ + url: "https://example.com/api?page=1&limit=10&sort=name", + method: "GET", + responseType: "json", + maxRetries: 0, + logging: { + level: "debug", + logger: mockLogger, + silent: false, + }, + }); + + expect(mockLogger.debug).toHaveBeenCalledWith( + "Making HTTP request", + expect.objectContaining({ + url: "https://example.com/api?page=1&limit=10&sort=name", + }), + ); + }); + + it("should not redact URL parameters containing 'auth' substring like 'author'", async () => { + const mockLogger = createMockLogger(); + mockSuccessResponse(); + + await fetcherImpl({ + url: "https://example.com/api?author=john&authenticate=false&page=1", + method: "GET", + responseType: "json", + maxRetries: 0, + logging: { + level: "debug", + logger: mockLogger, + silent: false, + }, + }); + + expect(mockLogger.debug).toHaveBeenCalledWith( + "Making HTTP request", + expect.objectContaining({ + url: "https://example.com/api?author=john&authenticate=false&page=1", + }), + ); + }); + + it("should handle URL with fragment", async () => { + const mockLogger = createMockLogger(); + mockSuccessResponse(); + + await fetcherImpl({ + url: "https://example.com/api?token=secret#section", + method: "GET", + responseType: "json", + maxRetries: 0, + logging: { + level: "debug", + logger: mockLogger, + silent: false, + }, + }); + + expect(mockLogger.debug).toHaveBeenCalledWith( + "Making HTTP request", + expect.objectContaining({ + url: "https://example.com/api?token=[REDACTED]#section", + }), + ); + }); + + it("should redact URL-encoded query parameters", async () => { + const mockLogger = createMockLogger(); + mockSuccessResponse(); + + await fetcherImpl({ + url: "https://example.com/api?api%5Fkey=secret", + method: "GET", + responseType: "json", + maxRetries: 0, + logging: { + level: "debug", + logger: mockLogger, + silent: false, + }, + }); + + expect(mockLogger.debug).toHaveBeenCalledWith( + "Making HTTP request", + expect.objectContaining({ + url: "https://example.com/api?api%5Fkey=[REDACTED]", + }), + ); + }); + + it("should handle URL without query string", async () => { + const mockLogger = createMockLogger(); + mockSuccessResponse(); + + await fetcherImpl({ + url: "https://example.com/api", + method: "GET", + responseType: "json", + maxRetries: 0, + logging: { + level: "debug", + logger: mockLogger, + silent: false, + }, + }); + + expect(mockLogger.debug).toHaveBeenCalledWith( + "Making HTTP request", + expect.objectContaining({ + url: "https://example.com/api", + }), + ); + }); + + it("should handle empty query string", async () => { + const mockLogger = createMockLogger(); + mockSuccessResponse(); + + await fetcherImpl({ + url: "https://example.com/api?", + method: "GET", + responseType: "json", + maxRetries: 0, + logging: { + level: "debug", + logger: mockLogger, + silent: false, + }, + }); + + expect(mockLogger.debug).toHaveBeenCalledWith( + "Making HTTP request", + expect.objectContaining({ + url: "https://example.com/api?", + }), + ); + }); + + it("should redact multiple sensitive parameters in URL", async () => { + const mockLogger = createMockLogger(); + mockSuccessResponse(); + + await fetcherImpl({ + url: "https://example.com/api?api_key=secret1&token=secret2&page=1", + method: "GET", + responseType: "json", + maxRetries: 0, + logging: { + level: "debug", + logger: mockLogger, + silent: false, + }, + }); + + expect(mockLogger.debug).toHaveBeenCalledWith( + "Making HTTP request", + expect.objectContaining({ + url: "https://example.com/api?api_key=[REDACTED]&token=[REDACTED]&page=1", + }), + ); + }); + + it("should redact both credentials and query parameters", async () => { + const mockLogger = createMockLogger(); + mockSuccessResponse(); + + await fetcherImpl({ + url: "https://user:pass@example.com/api?token=secret", + method: "GET", + responseType: "json", + maxRetries: 0, + logging: { + level: "debug", + logger: mockLogger, + silent: false, + }, + }); + + expect(mockLogger.debug).toHaveBeenCalledWith( + "Making HTTP request", + expect.objectContaining({ + url: "https://[REDACTED]@example.com/api?token=[REDACTED]", + }), + ); + }); + + it("should use fast path for URLs without sensitive keywords", async () => { + const mockLogger = createMockLogger(); + mockSuccessResponse(); + + await fetcherImpl({ + url: "https://example.com/api?page=1&limit=10&sort=name&filter=value", + method: "GET", + responseType: "json", + maxRetries: 0, + logging: { + level: "debug", + logger: mockLogger, + silent: false, + }, + }); + + expect(mockLogger.debug).toHaveBeenCalledWith( + "Making HTTP request", + expect.objectContaining({ + url: "https://example.com/api?page=1&limit=10&sort=name&filter=value", + }), + ); + }); + + it("should handle query parameter without value", async () => { + const mockLogger = createMockLogger(); + mockSuccessResponse(); + + await fetcherImpl({ + url: "https://example.com/api?flag&token=secret", + method: "GET", + responseType: "json", + maxRetries: 0, + logging: { + level: "debug", + logger: mockLogger, + silent: false, + }, + }); + + expect(mockLogger.debug).toHaveBeenCalledWith( + "Making HTTP request", + expect.objectContaining({ + url: "https://example.com/api?flag&token=[REDACTED]", + }), + ); + }); + + it("should handle URL with multiple @ symbols in credentials", async () => { + const mockLogger = createMockLogger(); + mockSuccessResponse(); + + await fetcherImpl({ + url: "https://user@example.com:pass@host.com/api", + method: "GET", + responseType: "json", + maxRetries: 0, + logging: { + level: "debug", + logger: mockLogger, + silent: false, + }, + }); + + expect(mockLogger.debug).toHaveBeenCalledWith( + "Making HTTP request", + expect.objectContaining({ + url: "https://[REDACTED]@host.com/api", + }), + ); + }); + + it("should handle URL with @ in query parameter but not in credentials", async () => { + const mockLogger = createMockLogger(); + mockSuccessResponse(); + + await fetcherImpl({ + url: "https://example.com/api?email=user@example.com", + method: "GET", + responseType: "json", + maxRetries: 0, + logging: { + level: "debug", + logger: mockLogger, + silent: false, + }, + }); + + expect(mockLogger.debug).toHaveBeenCalledWith( + "Making HTTP request", + expect.objectContaining({ + url: "https://example.com/api?email=user@example.com", + }), + ); + }); + + it("should handle URL with both credentials and @ in path", async () => { + const mockLogger = createMockLogger(); + mockSuccessResponse(); + + await fetcherImpl({ + url: "https://user:pass@example.com/users/@username", + method: "GET", + responseType: "json", + maxRetries: 0, + logging: { + level: "debug", + logger: mockLogger, + silent: false, + }, + }); + + expect(mockLogger.debug).toHaveBeenCalledWith( + "Making HTTP request", + expect.objectContaining({ + url: "https://[REDACTED]@example.com/users/@username", + }), + ); + }); + }); +}); diff --git a/tests/unit/fetcher/requestWithRetries.test.ts b/tests/unit/fetcher/requestWithRetries.test.ts new file mode 100644 index 0000000..7c98c0a --- /dev/null +++ b/tests/unit/fetcher/requestWithRetries.test.ts @@ -0,0 +1,282 @@ +import type { Mock, MockInstance } from "vitest"; +import { requestWithRetries } from "../../../src/core/fetcher/requestWithRetries"; + +describe("requestWithRetries", () => { + let mockFetch: Mock; + let originalMathRandom: typeof Math.random; + let setTimeoutSpy: MockInstance; + + beforeEach(() => { + mockFetch = vi.fn(); + originalMathRandom = Math.random; + + Math.random = vi.fn(() => 0.5); + + vi.useFakeTimers({ + toFake: [ + "setTimeout", + "clearTimeout", + "setInterval", + "clearInterval", + "setImmediate", + "clearImmediate", + "Date", + "performance", + "requestAnimationFrame", + "cancelAnimationFrame", + "requestIdleCallback", + "cancelIdleCallback", + ], + }); + }); + + afterEach(() => { + Math.random = originalMathRandom; + vi.clearAllMocks(); + vi.clearAllTimers(); + }); + + it("should retry on retryable status codes (legacy mode)", async () => { + setTimeoutSpy = vi.spyOn(global, "setTimeout").mockImplementation((callback: (args: void) => void) => { + process.nextTick(callback); + return null as any; + }); + + const retryableStatuses = [408, 429, 500, 501, 502, 503, 504, 505]; + let callCount = 0; + + mockFetch.mockImplementation(async () => { + if (callCount < retryableStatuses.length) { + return new Response("", { status: retryableStatuses[callCount++] }); + } + return new Response("", { status: 200 }); + }); + + const responsePromise = requestWithRetries(() => mockFetch(), retryableStatuses.length); + await vi.runAllTimersAsync(); + const response = await responsePromise; + + expect(mockFetch).toHaveBeenCalledTimes(retryableStatuses.length + 1); + expect(response.status).toBe(200); + }); + + it("should retry on 500 Internal Server Error in legacy mode", async () => { + setTimeoutSpy = vi.spyOn(global, "setTimeout").mockImplementation((callback: (args: void) => void) => { + process.nextTick(callback); + return null as any; + }); + + mockFetch + .mockResolvedValueOnce(new Response("", { status: 500 })) + .mockResolvedValueOnce(new Response("", { status: 200 })); + + const responsePromise = requestWithRetries(() => mockFetch(), 3); + await vi.runAllTimersAsync(); + const response = await responsePromise; + + expect(mockFetch).toHaveBeenCalledTimes(2); + expect(response.status).toBe(200); + }); + + it("should respect maxRetries limit", async () => { + setTimeoutSpy = vi.spyOn(global, "setTimeout").mockImplementation((callback: (args: void) => void) => { + process.nextTick(callback); + return null as any; + }); + + const maxRetries = 2; + mockFetch.mockResolvedValue(new Response("", { status: 503 })); + + const responsePromise = requestWithRetries(() => mockFetch(), maxRetries); + await vi.runAllTimersAsync(); + const response = await responsePromise; + + expect(mockFetch).toHaveBeenCalledTimes(maxRetries + 1); + expect(response.status).toBe(503); + }); + + it("should retry on status 599 (upper boundary of retryable 5xx in legacy mode)", async () => { + setTimeoutSpy = vi.spyOn(global, "setTimeout").mockImplementation((callback: (args: void) => void) => { + process.nextTick(callback); + return null as any; + }); + + mockFetch + .mockResolvedValueOnce(new Response("", { status: 599 })) + .mockResolvedValueOnce(new Response("", { status: 200 })); + + const responsePromise = requestWithRetries(() => mockFetch(), 3); + await vi.runAllTimersAsync(); + const response = await responsePromise; + + expect(mockFetch).toHaveBeenCalledTimes(2); + expect(response.status).toBe(200); + }); + + it("should not retry on non-retryable client error (400)", async () => { + setTimeoutSpy = vi.spyOn(global, "setTimeout").mockImplementation((callback: (args: void) => void) => { + process.nextTick(callback); + return null as any; + }); + + mockFetch.mockResolvedValueOnce(new Response("", { status: 400 })); + + const responsePromise = requestWithRetries(() => mockFetch(), 3); + await vi.runAllTimersAsync(); + const response = await responsePromise; + + expect(mockFetch).toHaveBeenCalledTimes(1); + expect(response.status).toBe(400); + }); + + it("should not retry on success status codes", async () => { + setTimeoutSpy = vi.spyOn(global, "setTimeout").mockImplementation((callback: (args: void) => void) => { + process.nextTick(callback); + return null as any; + }); + + const successStatuses = [200, 201, 202]; + + for (const status of successStatuses) { + mockFetch.mockReset(); + setTimeoutSpy.mockClear(); + mockFetch.mockResolvedValueOnce(new Response("", { status })); + + const responsePromise = requestWithRetries(() => mockFetch(), 3); + await vi.runAllTimersAsync(); + await responsePromise; + + expect(mockFetch).toHaveBeenCalledTimes(1); + expect(setTimeoutSpy).not.toHaveBeenCalled(); + } + }); + + interface RetryHeaderTestCase { + description: string; + headerName: string; + headerValue: string | (() => string); + expectedDelayMin: number; + expectedDelayMax: number; + } + + const retryHeaderTests: RetryHeaderTestCase[] = [ + { + description: "should respect retry-after header with seconds value", + headerName: "retry-after", + headerValue: "5", + expectedDelayMin: 4000, + expectedDelayMax: 6000, + }, + { + description: "should respect retry-after header with HTTP date value", + headerName: "retry-after", + headerValue: () => new Date(Date.now() + 3000).toUTCString(), + expectedDelayMin: 2000, + expectedDelayMax: 4000, + }, + { + description: "should respect x-ratelimit-reset header", + headerName: "x-ratelimit-reset", + headerValue: () => Math.floor((Date.now() + 4000) / 1000).toString(), + expectedDelayMin: 3000, + expectedDelayMax: 6000, + }, + ]; + + retryHeaderTests.forEach(({ description, headerName, headerValue, expectedDelayMin, expectedDelayMax }) => { + it(description, async () => { + setTimeoutSpy = vi.spyOn(global, "setTimeout").mockImplementation((callback: (args: void) => void) => { + process.nextTick(callback); + return null as any; + }); + + const value = typeof headerValue === "function" ? headerValue() : headerValue; + mockFetch + .mockResolvedValueOnce( + new Response("", { + status: 429, + headers: new Headers({ [headerName]: value }), + }), + ) + .mockResolvedValueOnce(new Response("", { status: 200 })); + + const responsePromise = requestWithRetries(() => mockFetch(), 1); + await vi.runAllTimersAsync(); + const response = await responsePromise; + + expect(setTimeoutSpy).toHaveBeenCalledWith(expect.any(Function), expect.any(Number)); + const actualDelay = setTimeoutSpy.mock.calls[0][1]; + expect(actualDelay).toBeGreaterThan(expectedDelayMin); + expect(actualDelay).toBeLessThan(expectedDelayMax); + expect(response.status).toBe(200); + }); + }); + + it("should apply correct exponential backoff with jitter", async () => { + setTimeoutSpy = vi.spyOn(global, "setTimeout").mockImplementation((callback: (args: void) => void) => { + process.nextTick(callback); + return null as any; + }); + + mockFetch.mockResolvedValue(new Response("", { status: 502 })); + const maxRetries = 3; + const expectedDelays = [1000, 2000, 4000]; + + const responsePromise = requestWithRetries(() => mockFetch(), maxRetries); + await vi.runAllTimersAsync(); + await responsePromise; + + expect(setTimeoutSpy).toHaveBeenCalledTimes(expectedDelays.length); + + expectedDelays.forEach((delay, index) => { + expect(setTimeoutSpy).toHaveBeenNthCalledWith(index + 1, expect.any(Function), delay); + }); + + expect(mockFetch).toHaveBeenCalledTimes(maxRetries + 1); + }); + + it("should handle concurrent retries independently", async () => { + setTimeoutSpy = vi.spyOn(global, "setTimeout").mockImplementation((callback: (args: void) => void) => { + process.nextTick(callback); + return null as any; + }); + + mockFetch + .mockResolvedValueOnce(new Response("", { status: 502 })) + .mockResolvedValueOnce(new Response("", { status: 502 })) + .mockResolvedValueOnce(new Response("", { status: 200 })) + .mockResolvedValueOnce(new Response("", { status: 200 })); + + const promise1 = requestWithRetries(() => mockFetch(), 1); + const promise2 = requestWithRetries(() => mockFetch(), 1); + + await vi.runAllTimersAsync(); + const [response1, response2] = await Promise.all([promise1, promise2]); + + expect(response1.status).toBe(200); + expect(response2.status).toBe(200); + }); + + it("should cap delay at MAX_RETRY_DELAY for large header values", async () => { + setTimeoutSpy = vi.spyOn(global, "setTimeout").mockImplementation((callback: (args: void) => void) => { + process.nextTick(callback); + return null as any; + }); + + mockFetch + .mockResolvedValueOnce( + new Response("", { + status: 429, + headers: new Headers({ "retry-after": "120" }), // 120 seconds = 120000ms > MAX_RETRY_DELAY (60000ms) + }), + ) + .mockResolvedValueOnce(new Response("", { status: 200 })); + + const responsePromise = requestWithRetries(() => mockFetch(), 1); + await vi.runAllTimersAsync(); + const response = await responsePromise; + + expect(setTimeoutSpy).toHaveBeenCalledWith(expect.any(Function), 60000); + expect(response.status).toBe(200); + }); +}); diff --git a/tests/unit/fetcher/signals.test.ts b/tests/unit/fetcher/signals.test.ts new file mode 100644 index 0000000..c717617 --- /dev/null +++ b/tests/unit/fetcher/signals.test.ts @@ -0,0 +1,114 @@ +import { anySignal, getTimeoutSignal } from "../../../src/core/fetcher/signals"; + +describe("Test getTimeoutSignal", () => { + beforeEach(() => { + vi.useFakeTimers(); + }); + + afterEach(() => { + vi.useRealTimers(); + }); + + it("should return an object with signal and abortId", () => { + const { signal, abortId } = getTimeoutSignal(1000); + + expect(signal).toBeDefined(); + expect(abortId).toBeDefined(); + expect(signal).toBeInstanceOf(AbortSignal); + expect(signal.aborted).toBe(false); + }); + + it("should create a signal that aborts after the specified timeout", () => { + const timeoutMs = 5000; + const { signal } = getTimeoutSignal(timeoutMs); + + expect(signal.aborted).toBe(false); + + vi.advanceTimersByTime(timeoutMs - 1); + expect(signal.aborted).toBe(false); + + vi.advanceTimersByTime(1); + expect(signal.aborted).toBe(true); + }); +}); + +describe("Test anySignal", () => { + it("should return an AbortSignal", () => { + const signal = anySignal(new AbortController().signal); + expect(signal).toBeInstanceOf(AbortSignal); + }); + + it("should abort when any of the input signals is aborted", () => { + const controller1 = new AbortController(); + const controller2 = new AbortController(); + const signal = anySignal(controller1.signal, controller2.signal); + + expect(signal.aborted).toBe(false); + controller1.abort(); + expect(signal.aborted).toBe(true); + }); + + it("should handle an array of signals", () => { + const controller1 = new AbortController(); + const controller2 = new AbortController(); + const signal = anySignal([controller1.signal, controller2.signal]); + + expect(signal.aborted).toBe(false); + controller2.abort(); + expect(signal.aborted).toBe(true); + }); + + it("should abort immediately if one of the input signals is already aborted", () => { + const controller1 = new AbortController(); + const controller2 = new AbortController(); + controller1.abort(); + + const signal = anySignal(controller1.signal, controller2.signal); + expect(signal.aborted).toBe(true); + }); + + it("should detect a signal that aborts between the initial aborted check and the event listener registration", () => { + const ctrlA = new AbortController(); + const ctrlB = new AbortController(); + + const originalAddEventListener = ctrlA.signal.addEventListener.bind(ctrlA.signal); + const originalRemoveEventListener = ctrlA.signal.removeEventListener.bind(ctrlA.signal); + + let abortedAccessCount = 0; + const proxy = new Proxy(ctrlA.signal, { + get(target, prop, receiver) { + if (prop === "aborted") { + abortedAccessCount++; + if (abortedAccessCount === 1) return false; + return Reflect.get(target, prop, receiver); + } + if (prop === "addEventListener") { + return (...args: Parameters) => { + if (abortedAccessCount >= 1 && args[0] === "abort") { + ctrlA.abort("too-late"); + } + return originalAddEventListener(...args); + }; + } + if (prop === "removeEventListener") { + return originalRemoveEventListener; + } + return Reflect.get(target, prop, receiver); + }, + }); + + const combined = anySignal(proxy, ctrlB.signal); + + expect(combined.aborted).toBe(true); + expect(combined.reason).toBe("too-late"); + }); + + it("should forward the abort reason from a source signal", () => { + const controller = new AbortController(); + const combined = anySignal(controller.signal); + + controller.abort("test-reason"); + expect(combined.aborted).toBe(true); + expect(combined.reason).toBe("test-reason"); + }); +}); diff --git a/tests/unit/fetcher/test-file.txt b/tests/unit/fetcher/test-file.txt new file mode 100644 index 0000000..c66d471 --- /dev/null +++ b/tests/unit/fetcher/test-file.txt @@ -0,0 +1 @@ +This is a test file! diff --git a/tests/unit/file/file.test.ts b/tests/unit/file/file.test.ts new file mode 100644 index 0000000..54d7c29 --- /dev/null +++ b/tests/unit/file/file.test.ts @@ -0,0 +1,513 @@ +import fs from "fs"; +import { join } from "path"; +import { Readable } from "stream"; +import { toBinaryUploadRequest, type Uploadable } from "../../../src/core/file/index"; + +describe("toBinaryUploadRequest", () => { + const TEST_FILE_PATH = join(__dirname, "..", "test-file.txt"); + const TEST_FILE_SIZE = fs.statSync(TEST_FILE_PATH).size.toString(); + + beforeEach(() => { + vi.clearAllMocks(); + }); + + describe("Buffer input", () => { + it("should handle Buffer with all metadata", async () => { + const buffer = Buffer.from("test data"); + const input: Uploadable.WithMetadata = { + data: buffer, + filename: "test.txt", + contentType: "text/plain", + contentLength: 42, + }; + + const result = await toBinaryUploadRequest(input); + + expect(result.body).toBe(buffer); + expect(result.headers).toEqual({ + "Content-Disposition": 'attachment; filename="test.txt"', + "Content-Type": "text/plain", + "Content-Length": "42", + }); + }); + + it("should handle Buffer without metadata", async () => { + const buffer = Buffer.from("test data"); + const input: Uploadable.WithMetadata = { + data: buffer, + }; + + const result = await toBinaryUploadRequest(input); + + expect(result.body).toBe(buffer); + expect(result.headers).toEqual({ + "Content-Length": "9", // buffer.length + }); + }); + + it("should handle Buffer passed directly", async () => { + const buffer = Buffer.from("test data"); + + const result = await toBinaryUploadRequest(buffer); + + expect(result.body).toBe(buffer); + expect(result.headers).toEqual({ + "Content-Length": "9", // buffer.length + }); + }); + }); + + describe("ArrayBuffer input", () => { + it("should handle ArrayBuffer with metadata", async () => { + const arrayBuffer = new ArrayBuffer(10); + const input: Uploadable.WithMetadata = { + data: arrayBuffer, + filename: "data.bin", + contentType: "application/octet-stream", + }; + + const result = await toBinaryUploadRequest(input); + + expect(result.body).toBe(arrayBuffer); + expect(result.headers).toEqual({ + "Content-Disposition": 'attachment; filename="data.bin"', + "Content-Type": "application/octet-stream", + "Content-Length": "10", // arrayBuffer.byteLength + }); + }); + + it("should handle ArrayBuffer passed directly", async () => { + const arrayBuffer = new ArrayBuffer(10); + + const result = await toBinaryUploadRequest(arrayBuffer); + + expect(result.body).toBe(arrayBuffer); + expect(result.headers).toEqual({ + "Content-Length": "10", // arrayBuffer.byteLength + }); + }); + }); + + describe("Uint8Array input", () => { + it("should handle Uint8Array with metadata", async () => { + const uint8Array = new Uint8Array([1, 2, 3, 4, 5]); + const input: Uploadable.WithMetadata = { + data: uint8Array, + filename: "bytes.bin", + contentType: "application/octet-stream", + }; + + const result = await toBinaryUploadRequest(input); + + expect(result.body).toBe(uint8Array); + expect(result.headers).toEqual({ + "Content-Disposition": 'attachment; filename="bytes.bin"', + "Content-Type": "application/octet-stream", + "Content-Length": "5", // uint8Array.byteLength + }); + }); + + it("should handle Uint8Array passed directly", async () => { + const uint8Array = new Uint8Array([1, 2, 3, 4, 5]); + + const result = await toBinaryUploadRequest(uint8Array); + + expect(result.body).toBe(uint8Array); + expect(result.headers).toEqual({ + "Content-Length": "5", // uint8Array.byteLength + }); + }); + }); + + describe("Blob input", () => { + it("should handle Blob with metadata", async () => { + const blob = new Blob(["test content"], { type: "text/plain" }); + const input: Uploadable.WithMetadata = { + data: blob, + filename: "override.txt", + contentType: "text/html", // Override blob's type + }; + + const result = await toBinaryUploadRequest(input); + + expect(result.body).toBe(blob); + expect(result.headers).toEqual({ + "Content-Disposition": 'attachment; filename="override.txt"', + "Content-Type": "text/html", // Should use provided contentType + "Content-Length": "12", // blob.size + }); + }); + + it("should handle Blob with intrinsic type", async () => { + const blob = new Blob(["test content"], { type: "application/json" }); + const input: Uploadable.WithMetadata = { + data: blob, + filename: "data.json", + }; + + const result = await toBinaryUploadRequest(input); + + expect(result.body).toBe(blob); + expect(result.headers).toEqual({ + "Content-Disposition": 'attachment; filename="data.json"', + "Content-Type": "application/json", // Should use blob's type + "Content-Length": "12", // blob.size + }); + }); + + it("should handle Blob passed directly", async () => { + const blob = new Blob(["test content"], { type: "text/plain" }); + + const result = await toBinaryUploadRequest(blob); + + expect(result.body).toBe(blob); + expect(result.headers).toEqual({ + "Content-Type": "text/plain", // Should use blob's type + "Content-Length": "12", // blob.size + }); + }); + }); + + describe("File input", () => { + it("should handle File with metadata", async () => { + const file = new File(["file content"], "original.txt", { type: "text/plain" }); + const input: Uploadable.WithMetadata = { + data: file, + filename: "renamed.txt", + contentType: "text/html", // Override file's type + }; + + const result = await toBinaryUploadRequest(input); + + expect(result.body).toBe(file); + expect(result.headers).toEqual({ + "Content-Disposition": 'attachment; filename="renamed.txt"', + "Content-Type": "text/html", // Should use provided contentType + "Content-Length": "12", // file.size + }); + }); + + it("should handle File with intrinsic properties", async () => { + const file = new File(["file content"], "test.json", { type: "application/json" }); + const input: Uploadable.WithMetadata = { + data: file, + }; + + const result = await toBinaryUploadRequest(input); + + expect(result.body).toBe(file); + expect(result.headers).toEqual({ + "Content-Disposition": 'attachment; filename="test.json"', // Should use file's name + "Content-Type": "application/json", // Should use file's type + "Content-Length": "12", // file.size + }); + }); + + it("should handle File passed directly", async () => { + const file = new File(["file content"], "direct.txt", { type: "text/plain" }); + + const result = await toBinaryUploadRequest(file); + + expect(result.body).toBe(file); + expect(result.headers).toEqual({ + "Content-Disposition": 'attachment; filename="direct.txt"', + "Content-Type": "text/plain", + "Content-Length": "12", // file.size + }); + }); + }); + + describe("ReadableStream input", () => { + it("should handle ReadableStream with metadata", async () => { + const stream = new ReadableStream({ + start(controller) { + controller.enqueue(new TextEncoder().encode("stream data")); + controller.close(); + }, + }); + const input: Uploadable.WithMetadata = { + data: stream, + filename: "stream.txt", + contentType: "text/plain", + contentLength: 100, + }; + + const result = await toBinaryUploadRequest(input); + + expect(result.body).toBe(stream); + expect(result.headers).toEqual({ + "Content-Disposition": 'attachment; filename="stream.txt"', + "Content-Type": "text/plain", + "Content-Length": "100", // Should use provided contentLength + }); + }); + + it("should handle ReadableStream without size", async () => { + const stream = new ReadableStream({ + start(controller) { + controller.enqueue(new TextEncoder().encode("stream data")); + controller.close(); + }, + }); + const input: Uploadable.WithMetadata = { + data: stream, + filename: "stream.txt", + contentType: "text/plain", + }; + + const result = await toBinaryUploadRequest(input); + + expect(result.body).toBe(stream); + expect(result.headers).toEqual({ + "Content-Disposition": 'attachment; filename="stream.txt"', + "Content-Type": "text/plain", + // No Content-Length header since it cannot be determined from ReadableStream + }); + }); + + it("should handle ReadableStream passed directly", async () => { + const stream = new ReadableStream({ + start(controller) { + controller.enqueue(new TextEncoder().encode("stream data")); + controller.close(); + }, + }); + + const result = await toBinaryUploadRequest(stream); + + expect(result.body).toBe(stream); + expect(result.headers).toEqual({ + // No headers since no metadata provided and cannot be determined + }); + }); + }); + + describe("Node.js Readable stream input", () => { + it("should handle Readable stream with metadata", async () => { + const readable = new Readable({ + read() { + this.push("readable data"); + this.push(null); + }, + }); + const input: Uploadable.WithMetadata = { + data: readable, + filename: "readable.txt", + contentType: "text/plain", + contentLength: 50, + }; + + const result = await toBinaryUploadRequest(input); + + expect(result.body).toBe(readable); + expect(result.headers).toEqual({ + "Content-Disposition": 'attachment; filename="readable.txt"', + "Content-Type": "text/plain", + "Content-Length": "50", // Should use provided contentLength + }); + }); + + it("should handle Readable stream without size", async () => { + const readable = new Readable({ + read() { + this.push("readable data"); + this.push(null); + }, + }); + const input: Uploadable.WithMetadata = { + data: readable, + filename: "readable.txt", + contentType: "text/plain", + }; + + const result = await toBinaryUploadRequest(input); + + expect(result.body).toBe(readable); + expect(result.headers).toEqual({ + "Content-Disposition": 'attachment; filename="readable.txt"', + "Content-Type": "text/plain", + // No Content-Length header since it cannot be determined from Readable + }); + }); + + it("should handle Readable stream passed directly", async () => { + const readable = new Readable({ + read() { + this.push("readable data"); + this.push(null); + }, + }); + + const result = await toBinaryUploadRequest(readable); + + expect(result.body).toBe(readable); + expect(result.headers).toEqual({ + // No headers since no metadata provided and cannot be determined + }); + }); + }); + + describe("File path input (FromPath type)", () => { + it("should handle file path with all metadata", async () => { + const input: Uploadable.FromPath = { + path: TEST_FILE_PATH, + filename: "custom.txt", + contentType: "text/html", + contentLength: 42, + }; + + const result = await toBinaryUploadRequest(input); + + expect(result.body).toBeInstanceOf(fs.ReadStream); + expect(result.headers).toEqual({ + "Content-Disposition": 'attachment; filename="custom.txt"', + "Content-Type": "text/html", + "Content-Length": "42", // Should use provided contentLength + }); + }); + + it("should handle file path with minimal metadata", async () => { + const input: Uploadable.FromPath = { + path: TEST_FILE_PATH, + contentType: "text/plain", + }; + + const result = await toBinaryUploadRequest(input); + + expect(result.body).toBeInstanceOf(fs.ReadStream); + expect(result.headers).toEqual({ + "Content-Disposition": 'attachment; filename="test-file.txt"', // Should extract from path + "Content-Type": "text/plain", + "Content-Length": TEST_FILE_SIZE, // Should determine from file system (OS-agnostic) + }); + }); + + it("should handle file path with no metadata", async () => { + const input: Uploadable.FromPath = { + path: TEST_FILE_PATH, + }; + + const result = await toBinaryUploadRequest(input); + + expect(result.body).toBeInstanceOf(fs.ReadStream); + expect(result.headers).toEqual({ + "Content-Disposition": 'attachment; filename="test-file.txt"', // Should extract from path + "Content-Length": TEST_FILE_SIZE, // Should determine from file system (OS-agnostic) + }); + }); + }); + + describe("ArrayBufferView input", () => { + it("should handle ArrayBufferView with metadata", async () => { + const arrayBuffer = new ArrayBuffer(10); + const arrayBufferView = new Int8Array(arrayBuffer); + const input: Uploadable.WithMetadata = { + data: arrayBufferView, + filename: "view.bin", + contentType: "application/octet-stream", + }; + + const result = await toBinaryUploadRequest(input); + + expect(result.body).toBe(arrayBufferView); + expect(result.headers).toEqual({ + "Content-Disposition": 'attachment; filename="view.bin"', + "Content-Type": "application/octet-stream", + "Content-Length": "10", // arrayBufferView.byteLength + }); + }); + + it("should handle ArrayBufferView passed directly", async () => { + const arrayBuffer = new ArrayBuffer(10); + const arrayBufferView = new Int8Array(arrayBuffer); + + const result = await toBinaryUploadRequest(arrayBufferView); + + expect(result.body).toBe(arrayBufferView); + expect(result.headers).toEqual({ + "Content-Length": "10", // arrayBufferView.byteLength + }); + }); + }); + + describe("null and undefined input", () => { + it("should throw Error for undefined in binary upload", async () => { + await expect(toBinaryUploadRequest(undefined as unknown as Uploadable)).rejects.toThrow(Error); + await expect(toBinaryUploadRequest(undefined as unknown as Uploadable)).rejects.toThrow( + /but received undefined/, + ); + }); + + it("should throw Error for null in binary upload", async () => { + await expect(toBinaryUploadRequest(null as unknown as Uploadable)).rejects.toThrow(Error); + await expect(toBinaryUploadRequest(null as unknown as Uploadable)).rejects.toThrow(/but received null/); + }); + }); + + describe("Edge cases", () => { + it("should handle empty headers when no metadata is available", async () => { + const buffer = Buffer.from(""); + const input: Uploadable.WithMetadata = { + data: buffer, + }; + + const result = await toBinaryUploadRequest(input); + + expect(result.body).toBe(buffer); + expect(result.headers).toEqual({ + "Content-Length": "0", + }); + }); + + it("should handle zero contentLength", async () => { + const buffer = Buffer.from("test"); + const input: Uploadable.WithMetadata = { + data: buffer, + contentLength: 0, + }; + + const result = await toBinaryUploadRequest(input); + + expect(result.body).toBe(buffer); + expect(result.headers).toEqual({ + "Content-Length": "0", // Should use provided 0 + }); + }); + + it("should handle null filename", async () => { + const buffer = Buffer.from("test"); + const input: Uploadable.WithMetadata = { + data: buffer, + filename: undefined, + contentType: "text/plain", + }; + + const result = await toBinaryUploadRequest(input); + + expect(result.body).toBe(buffer); + expect(result.headers).toEqual({ + "Content-Type": "text/plain", + "Content-Length": "4", + // No Content-Disposition since filename is undefined + }); + }); + + it("should handle null contentType", async () => { + const buffer = Buffer.from("test"); + const input: Uploadable.WithMetadata = { + data: buffer, + filename: "test.txt", + contentType: undefined, + }; + + const result = await toBinaryUploadRequest(input); + + expect(result.body).toBe(buffer); + expect(result.headers).toEqual({ + "Content-Disposition": 'attachment; filename="test.txt"', + "Content-Length": "4", + // No Content-Type since contentType is undefined + }); + }); + }); +}); diff --git a/tests/unit/logging/logger.test.ts b/tests/unit/logging/logger.test.ts new file mode 100644 index 0000000..2e0b5fe --- /dev/null +++ b/tests/unit/logging/logger.test.ts @@ -0,0 +1,454 @@ +import { ConsoleLogger, createLogger, Logger, LogLevel } from "../../../src/core/logging/logger"; + +function createMockLogger() { + return { + debug: vi.fn(), + info: vi.fn(), + warn: vi.fn(), + error: vi.fn(), + }; +} + +describe("Logger", () => { + describe("LogLevel", () => { + it("should have correct log levels", () => { + expect(LogLevel.Debug).toBe("debug"); + expect(LogLevel.Info).toBe("info"); + expect(LogLevel.Warn).toBe("warn"); + expect(LogLevel.Error).toBe("error"); + }); + }); + + describe("ConsoleLogger", () => { + let consoleLogger: ConsoleLogger; + let consoleSpy: { + debug: ReturnType; + info: ReturnType; + warn: ReturnType; + error: ReturnType; + }; + + beforeEach(() => { + consoleLogger = new ConsoleLogger(); + consoleSpy = { + debug: vi.spyOn(console, "debug").mockImplementation(() => {}), + info: vi.spyOn(console, "info").mockImplementation(() => {}), + warn: vi.spyOn(console, "warn").mockImplementation(() => {}), + error: vi.spyOn(console, "error").mockImplementation(() => {}), + }; + }); + + afterEach(() => { + consoleSpy.debug.mockRestore(); + consoleSpy.info.mockRestore(); + consoleSpy.warn.mockRestore(); + consoleSpy.error.mockRestore(); + }); + + it("should log debug messages", () => { + consoleLogger.debug("debug message", { data: "test" }); + expect(consoleSpy.debug).toHaveBeenCalledWith("debug message", { data: "test" }); + }); + + it("should log info messages", () => { + consoleLogger.info("info message", { data: "test" }); + expect(consoleSpy.info).toHaveBeenCalledWith("info message", { data: "test" }); + }); + + it("should log warn messages", () => { + consoleLogger.warn("warn message", { data: "test" }); + expect(consoleSpy.warn).toHaveBeenCalledWith("warn message", { data: "test" }); + }); + + it("should log error messages", () => { + consoleLogger.error("error message", { data: "test" }); + expect(consoleSpy.error).toHaveBeenCalledWith("error message", { data: "test" }); + }); + + it("should handle multiple arguments", () => { + consoleLogger.debug("message", "arg1", "arg2", { key: "value" }); + expect(consoleSpy.debug).toHaveBeenCalledWith("message", "arg1", "arg2", { key: "value" }); + }); + }); + + describe("Logger with level filtering", () => { + let mockLogger: { + debug: ReturnType; + info: ReturnType; + warn: ReturnType; + error: ReturnType; + }; + + beforeEach(() => { + mockLogger = createMockLogger(); + }); + + describe("Debug level", () => { + it("should log all levels when set to debug", () => { + const logger = new Logger({ + level: LogLevel.Debug, + logger: mockLogger, + silent: false, + }); + + logger.debug("debug"); + logger.info("info"); + logger.warn("warn"); + logger.error("error"); + + expect(mockLogger.debug).toHaveBeenCalledWith("debug"); + expect(mockLogger.info).toHaveBeenCalledWith("info"); + expect(mockLogger.warn).toHaveBeenCalledWith("warn"); + expect(mockLogger.error).toHaveBeenCalledWith("error"); + }); + + it("should report correct level checks", () => { + const logger = new Logger({ + level: LogLevel.Debug, + logger: mockLogger, + silent: false, + }); + + expect(logger.isDebug()).toBe(true); + expect(logger.isInfo()).toBe(true); + expect(logger.isWarn()).toBe(true); + expect(logger.isError()).toBe(true); + }); + }); + + describe("Info level", () => { + it("should log info, warn, and error when set to info", () => { + const logger = new Logger({ + level: LogLevel.Info, + logger: mockLogger, + silent: false, + }); + + logger.debug("debug"); + logger.info("info"); + logger.warn("warn"); + logger.error("error"); + + expect(mockLogger.debug).not.toHaveBeenCalled(); + expect(mockLogger.info).toHaveBeenCalledWith("info"); + expect(mockLogger.warn).toHaveBeenCalledWith("warn"); + expect(mockLogger.error).toHaveBeenCalledWith("error"); + }); + + it("should report correct level checks", () => { + const logger = new Logger({ + level: LogLevel.Info, + logger: mockLogger, + silent: false, + }); + + expect(logger.isDebug()).toBe(false); + expect(logger.isInfo()).toBe(true); + expect(logger.isWarn()).toBe(true); + expect(logger.isError()).toBe(true); + }); + }); + + describe("Warn level", () => { + it("should log warn and error when set to warn", () => { + const logger = new Logger({ + level: LogLevel.Warn, + logger: mockLogger, + silent: false, + }); + + logger.debug("debug"); + logger.info("info"); + logger.warn("warn"); + logger.error("error"); + + expect(mockLogger.debug).not.toHaveBeenCalled(); + expect(mockLogger.info).not.toHaveBeenCalled(); + expect(mockLogger.warn).toHaveBeenCalledWith("warn"); + expect(mockLogger.error).toHaveBeenCalledWith("error"); + }); + + it("should report correct level checks", () => { + const logger = new Logger({ + level: LogLevel.Warn, + logger: mockLogger, + silent: false, + }); + + expect(logger.isDebug()).toBe(false); + expect(logger.isInfo()).toBe(false); + expect(logger.isWarn()).toBe(true); + expect(logger.isError()).toBe(true); + }); + }); + + describe("Error level", () => { + it("should only log error when set to error", () => { + const logger = new Logger({ + level: LogLevel.Error, + logger: mockLogger, + silent: false, + }); + + logger.debug("debug"); + logger.info("info"); + logger.warn("warn"); + logger.error("error"); + + expect(mockLogger.debug).not.toHaveBeenCalled(); + expect(mockLogger.info).not.toHaveBeenCalled(); + expect(mockLogger.warn).not.toHaveBeenCalled(); + expect(mockLogger.error).toHaveBeenCalledWith("error"); + }); + + it("should report correct level checks", () => { + const logger = new Logger({ + level: LogLevel.Error, + logger: mockLogger, + silent: false, + }); + + expect(logger.isDebug()).toBe(false); + expect(logger.isInfo()).toBe(false); + expect(logger.isWarn()).toBe(false); + expect(logger.isError()).toBe(true); + }); + }); + + describe("Silent mode", () => { + it("should not log anything when silent is true", () => { + const logger = new Logger({ + level: LogLevel.Debug, + logger: mockLogger, + silent: true, + }); + + logger.debug("debug"); + logger.info("info"); + logger.warn("warn"); + logger.error("error"); + + expect(mockLogger.debug).not.toHaveBeenCalled(); + expect(mockLogger.info).not.toHaveBeenCalled(); + expect(mockLogger.warn).not.toHaveBeenCalled(); + expect(mockLogger.error).not.toHaveBeenCalled(); + }); + + it("should report all level checks as false when silent", () => { + const logger = new Logger({ + level: LogLevel.Debug, + logger: mockLogger, + silent: true, + }); + + expect(logger.isDebug()).toBe(false); + expect(logger.isInfo()).toBe(false); + expect(logger.isWarn()).toBe(false); + expect(logger.isError()).toBe(false); + }); + }); + + describe("shouldLog", () => { + it("should correctly determine if level should be logged", () => { + const logger = new Logger({ + level: LogLevel.Info, + logger: mockLogger, + silent: false, + }); + + expect(logger.shouldLog(LogLevel.Debug)).toBe(false); + expect(logger.shouldLog(LogLevel.Info)).toBe(true); + expect(logger.shouldLog(LogLevel.Warn)).toBe(true); + expect(logger.shouldLog(LogLevel.Error)).toBe(true); + }); + + it("should return false for all levels when silent", () => { + const logger = new Logger({ + level: LogLevel.Debug, + logger: mockLogger, + silent: true, + }); + + expect(logger.shouldLog(LogLevel.Debug)).toBe(false); + expect(logger.shouldLog(LogLevel.Info)).toBe(false); + expect(logger.shouldLog(LogLevel.Warn)).toBe(false); + expect(logger.shouldLog(LogLevel.Error)).toBe(false); + }); + }); + + describe("Multiple arguments", () => { + it("should pass multiple arguments to logger", () => { + const logger = new Logger({ + level: LogLevel.Debug, + logger: mockLogger, + silent: false, + }); + + logger.debug("message", "arg1", { key: "value" }, 123); + expect(mockLogger.debug).toHaveBeenCalledWith("message", "arg1", { key: "value" }, 123); + }); + }); + }); + + describe("createLogger", () => { + it("should return default logger when no config provided", () => { + const logger = createLogger(); + expect(logger).toBeInstanceOf(Logger); + }); + + it("should return same logger instance when Logger is passed", () => { + const customLogger = new Logger({ + level: LogLevel.Debug, + logger: new ConsoleLogger(), + silent: false, + }); + + const result = createLogger(customLogger); + expect(result).toBe(customLogger); + }); + + it("should create logger with custom config", () => { + const mockLogger = createMockLogger(); + + const logger = createLogger({ + level: LogLevel.Warn, + logger: mockLogger, + silent: false, + }); + + expect(logger).toBeInstanceOf(Logger); + logger.warn("test"); + expect(mockLogger.warn).toHaveBeenCalledWith("test"); + }); + + it("should use default values for missing config", () => { + const logger = createLogger({}); + expect(logger).toBeInstanceOf(Logger); + }); + + it("should override default level", () => { + const mockLogger = createMockLogger(); + + const logger = createLogger({ + level: LogLevel.Debug, + logger: mockLogger, + silent: false, + }); + + logger.debug("test"); + expect(mockLogger.debug).toHaveBeenCalledWith("test"); + }); + + it("should override default silent mode", () => { + const mockLogger = createMockLogger(); + + const logger = createLogger({ + logger: mockLogger, + silent: false, + }); + + logger.info("test"); + expect(mockLogger.info).toHaveBeenCalledWith("test"); + }); + + it("should use provided logger implementation", () => { + const customLogger = createMockLogger(); + + const logger = createLogger({ + logger: customLogger, + level: LogLevel.Debug, + silent: false, + }); + + logger.debug("test"); + expect(customLogger.debug).toHaveBeenCalledWith("test"); + }); + + it("should default to silent: true", () => { + const mockLogger = createMockLogger(); + + const logger = createLogger({ + logger: mockLogger, + level: LogLevel.Debug, + }); + + logger.debug("test"); + expect(mockLogger.debug).not.toHaveBeenCalled(); + }); + }); + + describe("Default logger", () => { + it("should have silent: true by default", () => { + const logger = createLogger(); + expect(logger.shouldLog(LogLevel.Info)).toBe(false); + }); + + it("should not log when using default logger", () => { + const logger = createLogger(); + + logger.info("test"); + expect(logger.isInfo()).toBe(false); + }); + }); + + describe("Edge cases", () => { + it("should handle empty message", () => { + const mockLogger = createMockLogger(); + + const logger = new Logger({ + level: LogLevel.Debug, + logger: mockLogger, + silent: false, + }); + + logger.debug(""); + expect(mockLogger.debug).toHaveBeenCalledWith(""); + }); + + it("should handle no arguments", () => { + const mockLogger = createMockLogger(); + + const logger = new Logger({ + level: LogLevel.Debug, + logger: mockLogger, + silent: false, + }); + + logger.debug("message"); + expect(mockLogger.debug).toHaveBeenCalledWith("message"); + }); + + it("should handle complex objects", () => { + const mockLogger = createMockLogger(); + + const logger = new Logger({ + level: LogLevel.Debug, + logger: mockLogger, + silent: false, + }); + + const complexObject = { + nested: { key: "value" }, + array: [1, 2, 3], + fn: () => "test", + }; + + logger.debug("message", complexObject); + expect(mockLogger.debug).toHaveBeenCalledWith("message", complexObject); + }); + + it("should handle errors as arguments", () => { + const mockLogger = createMockLogger(); + + const logger = new Logger({ + level: LogLevel.Error, + logger: mockLogger, + silent: false, + }); + + const error = new Error("Test error"); + logger.error("Error occurred", error); + expect(mockLogger.error).toHaveBeenCalledWith("Error occurred", error); + }); + }); +}); diff --git a/tests/unit/test-file.txt b/tests/unit/test-file.txt new file mode 100644 index 0000000..c66d471 --- /dev/null +++ b/tests/unit/test-file.txt @@ -0,0 +1 @@ +This is a test file! diff --git a/tests/unit/url/QueryStringBuilder.test.ts b/tests/unit/url/QueryStringBuilder.test.ts new file mode 100644 index 0000000..1afa2d2 --- /dev/null +++ b/tests/unit/url/QueryStringBuilder.test.ts @@ -0,0 +1,236 @@ +import { queryBuilder } from "../../../src/core/url/QueryStringBuilder"; + +describe("QueryStringBuilder", () => { + describe("add() — default repeat format", () => { + it("adds a scalar string value", () => { + const qs = queryBuilder().add("key", "value").build(); + expect(qs).toBe("key=value"); + }); + + it("adds a scalar number value", () => { + const qs = queryBuilder().add("limit", 10).build(); + expect(qs).toBe("limit=10"); + }); + + it("adds a boolean value", () => { + const qs = queryBuilder().add("active", true).build(); + expect(qs).toBe("active=true"); + }); + + it("skips undefined values", () => { + const qs = queryBuilder().add("key", undefined).build(); + expect(qs).toBe(""); + }); + + it("skips null values", () => { + const qs = queryBuilder().add("key", null).build(); + expect(qs).toBe(""); + }); + + it("repeats array elements as separate key=value pairs", () => { + const qs = queryBuilder().add("color", ["red", "blue", "green"]).build(); + expect(qs).toBe("color=red&color=blue&color=green"); + }); + + it("skips undefined items within arrays", () => { + const qs = queryBuilder().add("color", ["red", undefined, "blue"]).build(); + expect(qs).toBe("color=red&color=blue"); + }); + + it("returns empty string for empty array", () => { + const qs = queryBuilder().add("color", []).build(); + expect(qs).toBe(""); + }); + + it("encodes special characters in keys and values", () => { + const qs = queryBuilder().add("my key", "hello world").build(); + expect(qs).toBe("my%20key=hello%20world"); + }); + + it("handles nested objects", () => { + const qs = queryBuilder().add("filter", { status: "active" }).build(); + expect(qs).toBe("filter%5Bstatus%5D=active"); + }); + }); + + describe("add() — comma style", () => { + it("joins array values with literal commas", () => { + const qs = queryBuilder().add("tags", ["a", "b", "c"], { style: "comma" }).build(); + expect(qs).toBe("tags=a,b,c"); + }); + + it("handles single-element array", () => { + const qs = queryBuilder().add("tags", ["only"], { style: "comma" }).build(); + expect(qs).toBe("tags=only"); + }); + + it("returns empty string for empty array", () => { + const qs = queryBuilder().add("tags", [], { style: "comma" }).build(); + expect(qs).toBe(""); + }); + + it("skips undefined values", () => { + const qs = queryBuilder().add("tags", undefined, { style: "comma" }).build(); + expect(qs).toBe(""); + }); + + it("skips null values", () => { + const qs = queryBuilder().add("tags", null, { style: "comma" }).build(); + expect(qs).toBe(""); + }); + + it("treats scalar values same as default add()", () => { + const qs = queryBuilder().add("tag", "single", { style: "comma" }).build(); + expect(qs).toBe("tag=single"); + }); + + it("encodes commas within individual values as %2C", () => { + const qs = queryBuilder().add("items", ["a,b", "c"], { style: "comma" }).build(); + expect(qs).toBe("items=a%2Cb,c"); + }); + + it("encodes special characters in values", () => { + const qs = queryBuilder().add("tags", ["hello world", "foo&bar"], { style: "comma" }).build(); + expect(qs).toBe("tags=hello%20world,foo%26bar"); + }); + }); + + describe("chaining", () => { + it("chains multiple add() calls", () => { + const qs = queryBuilder().add("limit", 10).add("offset", 20).build(); + expect(qs).toBe("limit=10&offset=20"); + }); + + it("chains add() with default and comma styles", () => { + const qs = queryBuilder() + .add("limit", 10) + .add("tags", ["ACCESS_GRANTED", "COPY", "DELETE"], { style: "comma" }) + .add("active", true) + .build(); + expect(qs).toBe("limit=10&tags=ACCESS_GRANTED,COPY,DELETE&active=true"); + }); + + it("skips undefined/null params in chain without breaking", () => { + const qs = queryBuilder() + .add("a", "1") + .add("b", undefined) + .add("c", null, { style: "comma" }) + .add("d", "4") + .build(); + expect(qs).toBe("a=1&d=4"); + }); + }); + + describe("addMany()", () => { + it("adds all params from a record", () => { + const qs = queryBuilder().addMany({ limit: 10, offset: 20, name: "test" }).build(); + expect(qs).toBe("limit=10&offset=20&name=test"); + }); + + it("skips null and undefined values", () => { + const qs = queryBuilder().addMany({ a: "1", b: null, c: undefined, d: "4" }).build(); + expect(qs).toBe("a=1&d=4"); + }); + + it("handles empty record", () => { + const qs = queryBuilder().addMany({}).build(); + expect(qs).toBe(""); + }); + + it("works with comma-style override after addMany", () => { + const params = { limit: 10, tags: ["a", "b"], active: true }; + const qs = queryBuilder().addMany(params).add("tags", params.tags, { style: "comma" }).build(); + expect(qs).toBe("limit=10&tags=a,b&active=true"); + }); + + it("handles array values with default repeat format", () => { + const qs = queryBuilder() + .addMany({ ids: [1, 2, 3] }) + .build(); + expect(qs).toBe("ids=1&ids=2&ids=3"); + }); + }); + + describe("mergeAdditional()", () => { + it("appends additional params", () => { + const qs = queryBuilder().add("limit", 10).mergeAdditional({ extra: "value" }).build(); + expect(qs).toBe("limit=10&extra=value"); + }); + + it("overrides existing keys (last-write-wins)", () => { + const qs = queryBuilder().add("limit", 10).mergeAdditional({ limit: 20 }).build(); + expect(qs).toBe("limit=20"); + }); + + it("handles undefined additional params", () => { + const qs = queryBuilder().add("limit", 10).mergeAdditional(undefined).build(); + expect(qs).toBe("limit=10"); + }); + + it("skips undefined values in additional params", () => { + const qs = queryBuilder().add("limit", 10).mergeAdditional({ extra: undefined }).build(); + expect(qs).toBe("limit=10"); + }); + + it("skips null values in additional params", () => { + const qs = queryBuilder().add("limit", 10).mergeAdditional({ extra: null }).build(); + expect(qs).toBe("limit=10"); + }); + + it("handles array values in additional params using repeat format", () => { + const qs = queryBuilder() + .mergeAdditional({ ids: [1, 2, 3] }) + .build(); + expect(qs).toBe("ids=1&ids=2&ids=3"); + }); + + it("overrides a comma-style param with repeat format", () => { + const qs = queryBuilder() + .add("tags", ["a", "b"], { style: "comma" }) + .mergeAdditional({ tags: ["x", "y"] }) + .build(); + expect(qs).toBe("tags=x&tags=y"); + }); + }); + + describe("build()", () => { + it("returns empty string when no params added", () => { + const qs = queryBuilder().build(); + expect(qs).toBe(""); + }); + + it("does not include leading ?", () => { + const qs = queryBuilder().add("key", "value").build(); + expect(qs).not.toContain("?"); + }); + }); + + describe("end-to-end scenarios", () => { + it("matches expected query-parameters-openapi output pattern", () => { + const params: Record = { + limit: 1, + id: "d5e9c84f-c2b2-4bf4-b4b0-7ffd7a9ffc32", + date: "2023-01-15", + deadline: "2024-01-15T09:30:00.000Z", + bytes: "SGVsbG8gd29ybGQh", + user: "user", + userList: ["user"], + optionalString: "optionalString", + nestedUser: "nestedUser", + excludeUser: "excludeUser", + filter: "filter", + tags: ["tags"], + optionalTags: undefined, + }; + const qs = queryBuilder() + .addMany(params) + .add("tags", params.tags, { style: "comma" }) + .add("optionalTags", params.optionalTags, { style: "comma" }) + .mergeAdditional(undefined) + .build(); + expect(qs).toContain("limit=1"); + expect(qs).toContain("tags=tags"); + expect(qs).not.toContain("optionalTags"); + }); + }); +}); diff --git a/tests/unit/url/join.test.ts b/tests/unit/url/join.test.ts new file mode 100644 index 0000000..123488f --- /dev/null +++ b/tests/unit/url/join.test.ts @@ -0,0 +1,284 @@ +import { join } from "../../../src/core/url/index"; + +describe("join", () => { + interface TestCase { + description: string; + base: string; + segments: string[]; + expected: string; + } + + describe("basic functionality", () => { + const basicTests: TestCase[] = [ + { description: "should return empty string for empty base", base: "", segments: [], expected: "" }, + { + description: "should return empty string for empty base with path", + base: "", + segments: ["path"], + expected: "", + }, + { + description: "should handle single segment", + base: "base", + segments: ["segment"], + expected: "base/segment", + }, + { + description: "should handle single segment with trailing slash on base", + base: "base/", + segments: ["segment"], + expected: "base/segment", + }, + { + description: "should handle single segment with leading slash", + base: "base", + segments: ["/segment"], + expected: "base/segment", + }, + { + description: "should handle single segment with both slashes", + base: "base/", + segments: ["/segment"], + expected: "base/segment", + }, + { + description: "should handle multiple segments", + base: "base", + segments: ["path1", "path2", "path3"], + expected: "base/path1/path2/path3", + }, + { + description: "should handle multiple segments with slashes", + base: "base/", + segments: ["/path1/", "/path2/", "/path3/"], + expected: "base/path1/path2/path3/", + }, + ]; + + basicTests.forEach(({ description, base, segments, expected }) => { + it(description, () => { + expect(join(base, ...segments)).toBe(expected); + }); + }); + }); + + describe("URL handling", () => { + const urlTests: TestCase[] = [ + { + description: "should handle absolute URLs", + base: "https://example.com", + segments: ["api", "v1"], + expected: "https://example.com/api/v1", + }, + { + description: "should handle absolute URLs with slashes", + base: "https://example.com/", + segments: ["/api/", "/v1/"], + expected: "https://example.com/api/v1/", + }, + { + description: "should handle absolute URLs with base path", + base: "https://example.com/base", + segments: ["api", "v1"], + expected: "https://example.com/base/api/v1", + }, + { + description: "should preserve URL query parameters", + base: "https://example.com?query=1", + segments: ["api"], + expected: "https://example.com/api?query=1", + }, + { + description: "should preserve URL fragments", + base: "https://example.com#fragment", + segments: ["api"], + expected: "https://example.com/api#fragment", + }, + { + description: "should preserve URL query and fragments", + base: "https://example.com?query=1#fragment", + segments: ["api"], + expected: "https://example.com/api?query=1#fragment", + }, + { + description: "should handle http protocol", + base: "http://example.com", + segments: ["api"], + expected: "http://example.com/api", + }, + { + description: "should handle ftp protocol", + base: "ftp://example.com", + segments: ["files"], + expected: "ftp://example.com/files", + }, + { + description: "should handle ws protocol", + base: "ws://example.com", + segments: ["socket"], + expected: "ws://example.com/socket", + }, + { + description: "should fallback to path joining for malformed URLs", + base: "not-a-url://", + segments: ["path"], + expected: "not-a-url:///path", + }, + ]; + + urlTests.forEach(({ description, base, segments, expected }) => { + it(description, () => { + expect(join(base, ...segments)).toBe(expected); + }); + }); + }); + + describe("edge cases", () => { + const edgeCaseTests: TestCase[] = [ + { + description: "should handle empty segments", + base: "base", + segments: ["", "path"], + expected: "base/path", + }, + { + description: "should handle null segments", + base: "base", + segments: [null as any, "path"], + expected: "base/path", + }, + { + description: "should handle undefined segments", + base: "base", + segments: [undefined as any, "path"], + expected: "base/path", + }, + { + description: "should handle segments with only single slash", + base: "base", + segments: ["/", "path"], + expected: "base/path", + }, + { + description: "should handle segments with only double slash", + base: "base", + segments: ["//", "path"], + expected: "base/path", + }, + { + description: "should handle base paths with trailing slashes", + base: "base/", + segments: ["path"], + expected: "base/path", + }, + { + description: "should handle complex nested paths", + base: "api/v1/", + segments: ["/users/", "/123/", "/profile"], + expected: "api/v1/users/123/profile", + }, + ]; + + edgeCaseTests.forEach(({ description, base, segments, expected }) => { + it(description, () => { + expect(join(base, ...segments)).toBe(expected); + }); + }); + }); + + describe("real-world scenarios", () => { + const realWorldTests: TestCase[] = [ + { + description: "should handle API endpoint construction", + base: "https://api.example.com/v1", + segments: ["users", "123", "posts"], + expected: "https://api.example.com/v1/users/123/posts", + }, + { + description: "should handle file path construction", + base: "/var/www", + segments: ["html", "assets", "images"], + expected: "/var/www/html/assets/images", + }, + { + description: "should handle relative path construction", + base: "../parent", + segments: ["child", "grandchild"], + expected: "../parent/child/grandchild", + }, + { + description: "should handle Windows-style paths", + base: "C:\\Users", + segments: ["Documents", "file.txt"], + expected: "C:\\Users/Documents/file.txt", + }, + ]; + + realWorldTests.forEach(({ description, base, segments, expected }) => { + it(description, () => { + expect(join(base, ...segments)).toBe(expected); + }); + }); + }); + + describe("performance scenarios", () => { + it("should handle many segments efficiently", () => { + const segments = Array(100).fill("segment"); + const result = join("base", ...segments); + expect(result).toBe(`base/${segments.join("/")}`); + }); + + it("should handle long URLs", () => { + const longPath = "a".repeat(1000); + expect(join("https://example.com", longPath)).toBe(`https://example.com/${longPath}`); + }); + }); + + describe("trailing slash preservation", () => { + const trailingSlashTests: TestCase[] = [ + { + description: + "should preserve trailing slash on final result when base has trailing slash and no segments", + base: "https://api.example.com/", + segments: [], + expected: "https://api.example.com/", + }, + { + description: "should preserve trailing slash on v1 path", + base: "https://api.example.com/v1/", + segments: [], + expected: "https://api.example.com/v1/", + }, + { + description: "should preserve trailing slash when last segment has trailing slash", + base: "https://api.example.com", + segments: ["users/"], + expected: "https://api.example.com/users/", + }, + { + description: "should preserve trailing slash with relative path", + base: "api/v1", + segments: ["users/"], + expected: "api/v1/users/", + }, + { + description: "should preserve trailing slash with multiple segments", + base: "https://api.example.com", + segments: ["v1", "collections/"], + expected: "https://api.example.com/v1/collections/", + }, + { + description: "should preserve trailing slash with base path", + base: "base", + segments: ["path1", "path2/"], + expected: "base/path1/path2/", + }, + ]; + + trailingSlashTests.forEach(({ description, base, segments, expected }) => { + it(description, () => { + expect(join(base, ...segments)).toBe(expected); + }); + }); + }); +}); diff --git a/tests/unit/url/qs.test.ts b/tests/unit/url/qs.test.ts new file mode 100644 index 0000000..54d2d9c --- /dev/null +++ b/tests/unit/url/qs.test.ts @@ -0,0 +1,374 @@ +import { toQueryString } from "../../../src/core/url/index"; + +describe("Test qs toQueryString", () => { + interface BasicTestCase { + description: string; + input: any; + expected: string; + } + + describe("Basic functionality", () => { + const basicTests: BasicTestCase[] = [ + { description: "should return empty string for null", input: null, expected: "" }, + { description: "should return empty string for undefined", input: undefined, expected: "" }, + { description: "should return empty string for string primitive", input: "hello", expected: "" }, + { description: "should return empty string for number primitive", input: 42, expected: "" }, + { description: "should return empty string for true boolean", input: true, expected: "" }, + { description: "should return empty string for false boolean", input: false, expected: "" }, + { description: "should handle empty objects", input: {}, expected: "" }, + { + description: "should handle simple key-value pairs", + input: { name: "John", age: 30 }, + expected: "name=John&age=30", + }, + ]; + + basicTests.forEach(({ description, input, expected }) => { + it(description, () => { + expect(toQueryString(input)).toBe(expected); + }); + }); + }); + + describe("Array handling", () => { + interface ArrayTestCase { + description: string; + input: any; + options?: { arrayFormat?: "repeat" | "indices" | "comma" }; + expected: string; + } + + const arrayTests: ArrayTestCase[] = [ + { + description: "should handle arrays with indices format (default)", + input: { items: ["a", "b", "c"] }, + expected: "items%5B0%5D=a&items%5B1%5D=b&items%5B2%5D=c", + }, + { + description: "should handle arrays with repeat format", + input: { items: ["a", "b", "c"] }, + options: { arrayFormat: "repeat" }, + expected: "items=a&items=b&items=c", + }, + { + description: "should handle empty arrays", + input: { items: [] }, + expected: "", + }, + { + description: "should handle arrays with mixed types", + input: { mixed: ["string", 42, true, false] }, + expected: "mixed%5B0%5D=string&mixed%5B1%5D=42&mixed%5B2%5D=true&mixed%5B3%5D=false", + }, + { + description: "should handle arrays with objects", + input: { users: [{ name: "John" }, { name: "Jane" }] }, + expected: "users%5B0%5D%5Bname%5D=John&users%5B1%5D%5Bname%5D=Jane", + }, + { + description: "should handle arrays with objects in repeat format", + input: { users: [{ name: "John" }, { name: "Jane" }] }, + options: { arrayFormat: "repeat" }, + expected: "users%5Bname%5D=John&users%5Bname%5D=Jane", + }, + ]; + + arrayTests.forEach(({ description, input, options, expected }) => { + it(description, () => { + expect(toQueryString(input, options)).toBe(expected); + }); + }); + }); + + describe("Nested objects", () => { + const nestedTests: BasicTestCase[] = [ + { + description: "should handle nested objects", + input: { user: { name: "John", age: 30 } }, + expected: "user%5Bname%5D=John&user%5Bage%5D=30", + }, + { + description: "should handle deeply nested objects", + input: { user: { profile: { name: "John", settings: { theme: "dark" } } } }, + expected: "user%5Bprofile%5D%5Bname%5D=John&user%5Bprofile%5D%5Bsettings%5D%5Btheme%5D=dark", + }, + { + description: "should handle empty nested objects", + input: { user: {} }, + expected: "", + }, + ]; + + nestedTests.forEach(({ description, input, expected }) => { + it(description, () => { + expect(toQueryString(input)).toBe(expected); + }); + }); + }); + + describe("Encoding", () => { + interface EncodingTestCase { + description: string; + input: any; + options?: { encode?: boolean }; + expected: string; + } + + const encodingTests: EncodingTestCase[] = [ + { + description: "should encode by default", + input: { name: "John Doe", email: "john@example.com" }, + expected: "name=John%20Doe&email=john%40example.com", + }, + { + description: "should not encode when encode is false", + input: { name: "John Doe", email: "john@example.com" }, + options: { encode: false }, + expected: "name=John Doe&email=john@example.com", + }, + { + description: "should encode special characters in keys", + input: { "user name": "John", "email[primary]": "john@example.com" }, + expected: "user%20name=John&email%5Bprimary%5D=john%40example.com", + }, + { + description: "should not encode special characters in keys when encode is false", + input: { "user name": "John", "email[primary]": "john@example.com" }, + options: { encode: false }, + expected: "user name=John&email[primary]=john@example.com", + }, + ]; + + encodingTests.forEach(({ description, input, options, expected }) => { + it(description, () => { + expect(toQueryString(input, options)).toBe(expected); + }); + }); + }); + + describe("Mixed scenarios", () => { + interface MixedTestCase { + description: string; + input: any; + options?: { arrayFormat?: "repeat" | "indices" | "comma" }; + expected: string; + } + + const mixedTests: MixedTestCase[] = [ + { + description: "should handle complex nested structures", + input: { + filters: { + status: ["active", "pending"], + category: { + type: "electronics", + subcategories: ["phones", "laptops"], + }, + }, + sort: { field: "name", direction: "asc" }, + }, + expected: + "filters%5Bstatus%5D%5B0%5D=active&filters%5Bstatus%5D%5B1%5D=pending&filters%5Bcategory%5D%5Btype%5D=electronics&filters%5Bcategory%5D%5Bsubcategories%5D%5B0%5D=phones&filters%5Bcategory%5D%5Bsubcategories%5D%5B1%5D=laptops&sort%5Bfield%5D=name&sort%5Bdirection%5D=asc", + }, + { + description: "should handle complex nested structures with repeat format", + input: { + filters: { + status: ["active", "pending"], + category: { + type: "electronics", + subcategories: ["phones", "laptops"], + }, + }, + sort: { field: "name", direction: "asc" }, + }, + options: { arrayFormat: "repeat" }, + expected: + "filters%5Bstatus%5D=active&filters%5Bstatus%5D=pending&filters%5Bcategory%5D%5Btype%5D=electronics&filters%5Bcategory%5D%5Bsubcategories%5D=phones&filters%5Bcategory%5D%5Bsubcategories%5D=laptops&sort%5Bfield%5D=name&sort%5Bdirection%5D=asc", + }, + { + description: "should handle arrays with null/undefined values", + input: { items: ["a", null, "c", undefined, "e"] }, + expected: "items%5B0%5D=a&items%5B2%5D=c&items%5B4%5D=e", + }, + { + description: "should handle objects with null/undefined values", + input: { name: "John", age: null, email: undefined, active: true }, + expected: "name=John&active=true", + }, + ]; + + mixedTests.forEach(({ description, input, options, expected }) => { + it(description, () => { + expect(toQueryString(input, options)).toBe(expected); + }); + }); + }); + + describe("Edge cases", () => { + const edgeCaseTests: BasicTestCase[] = [ + { + description: "should handle numeric keys", + input: { "0": "zero", "1": "one" }, + expected: "0=zero&1=one", + }, + { + description: "should handle boolean values in objects", + input: { enabled: true, disabled: false }, + expected: "enabled=true&disabled=false", + }, + { + description: "should handle empty strings", + input: { name: "", description: "test" }, + expected: "name=&description=test", + }, + { + description: "should handle zero values", + input: { count: 0, price: 0.0 }, + expected: "count=0&price=0", + }, + { + description: "should handle arrays with empty strings", + input: { items: ["a", "", "c"] }, + expected: "items%5B0%5D=a&items%5B1%5D=&items%5B2%5D=c", + }, + ]; + + edgeCaseTests.forEach(({ description, input, expected }) => { + it(description, () => { + expect(toQueryString(input)).toBe(expected); + }); + }); + }); + + describe("Comma array format", () => { + interface CommaTestCase { + description: string; + input: any; + options?: { arrayFormat?: "comma"; encode?: boolean }; + expected: string; + } + + const commaTests: CommaTestCase[] = [ + { + description: "should join array values with commas", + input: { event_type: ["ACCESS_GRANTED", "COPY", "DELETE"] }, + options: { arrayFormat: "comma" }, + expected: "event_type=ACCESS_GRANTED,COPY,DELETE", + }, + { + description: "should handle single-element array", + input: { event_type: ["ACCESS_GRANTED"] }, + options: { arrayFormat: "comma" }, + expected: "event_type=ACCESS_GRANTED", + }, + { + description: "should handle empty array", + input: { event_type: [] }, + options: { arrayFormat: "comma" }, + expected: "", + }, + { + description: "should not percent-encode commas", + input: { items: ["a", "b", "c"] }, + options: { arrayFormat: "comma" }, + expected: "items=a,b,c", + }, + { + description: "should encode values but not commas", + input: { items: ["a b", "c d"] }, + options: { arrayFormat: "comma" }, + expected: "items=a%20b,c%20d", + }, + { + description: "should not encode when encode is false", + input: { items: ["a b", "c d"] }, + options: { arrayFormat: "comma", encode: false }, + expected: "items=a b,c d", + }, + { + description: "should handle mixed parameters with comma and non-array values", + input: { event_type: ["ACCESS_GRANTED", "COPY", "DELETE"], limit: 10, offset: 0 }, + options: { arrayFormat: "comma" }, + expected: "event_type=ACCESS_GRANTED,COPY,DELETE&limit=10&offset=0", + }, + { + description: "should handle numeric array values", + input: { ids: [1, 2, 3] }, + options: { arrayFormat: "comma" }, + expected: "ids=1,2,3", + }, + { + description: "should handle boolean array values", + input: { flags: [true, false, true] }, + options: { arrayFormat: "comma" }, + expected: "flags=true,false,true", + }, + { + description: "should skip null values in comma format", + input: { items: ["a", null, "c"] }, + options: { arrayFormat: "comma" }, + expected: "items=a,c", + }, + { + description: "should skip undefined values in comma format", + input: { items: ["a", undefined, "c"] }, + options: { arrayFormat: "comma" }, + expected: "items=a,c", + }, + { + description: "should produce empty string for all-null array in comma format", + input: { items: [null, undefined] }, + options: { arrayFormat: "comma" }, + expected: "", + }, + { + description: "should encode commas within values while keeping separator commas literal", + input: { items: ["a,b", "c"] }, + options: { arrayFormat: "comma" }, + expected: "items=a%2Cb,c", + }, + ]; + + commaTests.forEach(({ description, input, options, expected }) => { + it(description, () => { + expect(toQueryString(input, options)).toBe(expected); + }); + }); + }); + + describe("Options combinations", () => { + interface OptionsTestCase { + description: string; + input: any; + options?: { arrayFormat?: "repeat" | "indices" | "comma"; encode?: boolean }; + expected: string; + } + + const optionsTests: OptionsTestCase[] = [ + { + description: "should respect both arrayFormat and encode options", + input: { items: ["a & b", "c & d"] }, + options: { arrayFormat: "repeat", encode: false }, + expected: "items=a & b&items=c & d", + }, + { + description: "should use default options when none provided", + input: { items: ["a", "b"] }, + expected: "items%5B0%5D=a&items%5B1%5D=b", + }, + { + description: "should merge provided options with defaults", + input: { items: ["a", "b"], name: "John Doe" }, + options: { encode: false }, + expected: "items[0]=a&items[1]=b&name=John Doe", + }, + ]; + + optionsTests.forEach(({ description, input, options, expected }) => { + it(description, () => { + expect(toQueryString(input, options)).toBe(expected); + }); + }); + }); +}); diff --git a/tests/wire/.gitkeep b/tests/wire/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/tests/wire/deployment.test.ts b/tests/wire/deployment.test.ts new file mode 100644 index 0000000..4ff599b --- /dev/null +++ b/tests/wire/deployment.test.ts @@ -0,0 +1,24 @@ +// This file was auto-generated by Fern from our API Definition. + +import { CloudpdfApiClient } from "../../src/Client"; +import { mockServerPool } from "../mock-server/MockServerPool"; + +describe("DeploymentClient", () => { + test("licenseStatus", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + + const rawResponseBody = { license: { key: "value" }, reporting: { key: "value" }, usage: { key: "value" } }; + + server + .mockEndpoint() + .get("/v1/deployment/license/status") + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.deployment.licenseStatus(); + expect(response).toEqual(rawResponseBody); + }); +}); diff --git a/tests/wire/doc.test.ts b/tests/wire/doc.test.ts new file mode 100644 index 0000000..675733d --- /dev/null +++ b/tests/wire/doc.test.ts @@ -0,0 +1,178 @@ +// This file was auto-generated by Fern from our API Definition. + +import * as CloudpdfApi from "../../src/api/index"; +import { CloudpdfApiClient } from "../../src/Client"; +import { mockServerPool } from "../mock-server/MockServerPool"; + +describe("DocClient", () => { + test("head (1)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + + const rawResponseBody = { + id: "id", + baseSha: "baseSha", + storageSizeBytes: 1, + docVersion: 1, + state: "pending", + encryption: { state: "unknown", requiresPassword: true }, + permissions: { + known: true, + bits: 1, + allAllowed: true, + openedAs: "none", + securityHandlerRevision: 1, + canUpgradeToOwner: true, + }, + access: { required: true, reasons: ["password"], endpoint: "endpoint" }, + }; + + server + .mockEndpoint() + .get("/v1/docs/docId/head") + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.doc.head({ + docId: "docId", + }); + expect(response).toEqual(rawResponseBody); + }); + + test("head (2)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + + server + .mockEndpoint() + .get("/v1/docs/docId/head") + .respondWith() + .statusCode(404) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.doc.head({ + docId: "docId", + }); + }).rejects.toThrow(CloudpdfApi.NotFoundError); + }); + + test("manifest (1)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + + const rawResponseBody = { + docVersion: 1, + layoutVersion: 1, + metadataVersion: 1, + actionsVersion: 1, + attachmentsVersion: 1, + auditHead: 1, + baseSha: "baseSha", + scopes: { + content: "base", + annotations: "base", + layout: "base", + attachments: "base", + metadata: "base", + actions: "base", + }, + pages: [ + { + state: { + pageObjectNumber: 1, + revision: { docSessionId: "docSessionId", pageObjectNumber: 1, generation: 1 }, + weakAnnotationState: { kind: "unknown" }, + }, + cache: { contentVersion: 1, annotationVersion: 1 }, + }, + ], + }; + + server + .mockEndpoint() + .get("/v1/docs/docId/layers/layerName/manifest") + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.doc.manifest({ + docId: "docId", + layerName: "layerName", + }); + expect(response).toEqual(rawResponseBody); + }); + + test("manifest (2)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + + server + .mockEndpoint() + .get("/v1/docs/docId/layers/layerName/manifest") + .respondWith() + .statusCode(404) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.doc.manifest({ + docId: "docId", + layerName: "layerName", + }); + }).rejects.toThrow(CloudpdfApi.NotFoundError); + }); + + test("text (1)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + + const rawResponseBody = { text: "text", charCount: 1 }; + + server + .mockEndpoint() + .get("/v1/docs/docId/layers/layerName/text/pages/1/data") + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.doc.text({ + docId: "docId", + layerName: "layerName", + pon: 1, + }); + expect(response).toEqual(rawResponseBody); + }); + + test("text (2)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + + server + .mockEndpoint() + .get("/v1/docs/docId/layers/layerName/text/pages/1/data") + .respondWith() + .statusCode(404) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.doc.text({ + docId: "docId", + layerName: "layerName", + pon: 1, + }); + }).rejects.toThrow(CloudpdfApi.NotFoundError); + }); +}); diff --git a/tests/wire/doc/annotations.test.ts b/tests/wire/doc/annotations.test.ts new file mode 100644 index 0000000..a842daa --- /dev/null +++ b/tests/wire/doc/annotations.test.ts @@ -0,0 +1,365 @@ +// This file was auto-generated by Fern from our API Definition. + +import * as CloudpdfApi from "../../../src/api/index"; +import { CloudpdfApiClient } from "../../../src/Client"; +import { mockServerPool } from "../../mock-server/MockServerPool"; + +describe("AnnotationsClient", () => { + test("list (1)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + + const rawResponseBody = { + pageState: { + pageObjectNumber: 1, + revision: { docSessionId: "docSessionId", pageObjectNumber: 1, generation: 1 }, + weakAnnotationState: { kind: "unknown" }, + }, + annotations: [ + { + subtype: "highlight", + ref: { kind: "objectNumber", pageObjectNumber: 1, annotObjectNumber: 1 }, + pageObjectNumber: 1, + index: 1, + identityQuality: "durable", + nm: "nm", + flags: { + invisible: true, + hidden: true, + print: true, + noZoom: true, + noRotate: true, + noView: true, + readOnly: true, + locked: true, + toggleNoView: true, + lockedContents: true, + }, + rect: { left: 1.1, bottom: 1.1, right: 1.1, top: 1.1 }, + contents: "contents", + author: "author", + created: "2024-01-15T09:30:00Z", + modified: "2024-01-15T09:30:00Z", + blendMode: "normal", + inReplyTo: { kind: "objectNumber", pageObjectNumber: 1, annotObjectNumber: 1 }, + replyType: "reply", + userId: "userId", + groupId: "groupId", + createdBy: "createdBy", + updatedBy: "updatedBy", + color: { r: 1, g: 1, b: 1 }, + opacity: 1.1, + quadPoints: [ + { + p1: { x: 1.1, y: 1.1 }, + p2: { x: 1.1, y: 1.1 }, + p3: { x: 1.1, y: 1.1 }, + p4: { x: 1.1, y: 1.1 }, + }, + ], + }, + ], + }; + + server + .mockEndpoint() + .get("/v1/docs/docId/layers/layerName/annotations/pages/1/items") + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.doc.annotations.list({ + docId: "docId", + layerName: "layerName", + pon: 1, + }); + expect(response).toEqual(rawResponseBody); + }); + + test("list (2)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + + server + .mockEndpoint() + .get("/v1/docs/docId/layers/layerName/annotations/pages/1/items") + .respondWith() + .statusCode(404) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.doc.annotations.list({ + docId: "docId", + layerName: "layerName", + pon: 1, + }); + }).rejects.toThrow(CloudpdfApi.NotFoundError); + }); + + test("create (1)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + const rawRequestBody = { key: "value" }; + const rawResponseBody = { + meta: { + affectedPages: [ + { + pageObjectNumber: 1, + revision: { docSessionId: "docSessionId", pageObjectNumber: 1, generation: 1 }, + weakAnnotationState: { kind: "unknown" }, + }, + ], + cacheDelta: { + previousDocVersion: 1, + docVersion: 1, + pages: [{ pageObjectNumber: 1, cache: { contentVersion: 1, annotationVersion: 1 } }], + }, + }, + }; + + server + .mockEndpoint() + .post("/v1/docs/docId/layers/layerName/annotations/pages/1/items") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.doc.annotations.create({ + docId: "docId", + layerName: "layerName", + pon: 1, + body: { + key: "value", + }, + }); + expect(response).toEqual(rawResponseBody); + }); + + test("create (2)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + const rawRequestBody = { string: { key: "value" } }; + const rawResponseBody = { key: "value" }; + + server + .mockEndpoint() + .post("/v1/docs/docId/layers/layerName/annotations/pages/1/items") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(400) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.doc.annotations.create({ + docId: "docId", + layerName: "layerName", + pon: 1, + body: { + string: { + key: "value", + }, + }, + }); + }).rejects.toThrow(CloudpdfApi.BadRequestError); + }); + + test("create (3)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + const rawRequestBody = { string: { key: "value" } }; + const rawResponseBody = { key: "value" }; + + server + .mockEndpoint() + .post("/v1/docs/docId/layers/layerName/annotations/pages/1/items") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(404) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.doc.annotations.create({ + docId: "docId", + layerName: "layerName", + pon: 1, + body: { + string: { + key: "value", + }, + }, + }); + }).rejects.toThrow(CloudpdfApi.NotFoundError); + }); + + test("delete (1)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + + const rawResponseBody = { + meta: { + affectedPages: [ + { + pageObjectNumber: 1, + revision: { docSessionId: "docSessionId", pageObjectNumber: 1, generation: 1 }, + weakAnnotationState: { kind: "unknown" }, + }, + ], + cacheDelta: { + previousDocVersion: 1, + docVersion: 1, + pages: [{ pageObjectNumber: 1, cache: { contentVersion: 1, annotationVersion: 1 } }], + }, + }, + }; + + server + .mockEndpoint() + .delete("/v1/docs/docId/layers/layerName/annotations/pages/1/items/annotKey") + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.doc.annotations.delete({ + docId: "docId", + layerName: "layerName", + pon: 1, + annotKey: "annotKey", + }); + expect(response).toEqual(rawResponseBody); + }); + + test("delete (2)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + + server + .mockEndpoint() + .delete("/v1/docs/docId/layers/layerName/annotations/pages/1/items/annotKey") + .respondWith() + .statusCode(404) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.doc.annotations.delete({ + docId: "docId", + layerName: "layerName", + pon: 1, + annotKey: "annotKey", + }); + }).rejects.toThrow(CloudpdfApi.NotFoundError); + }); + + test("update (1)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + const rawRequestBody = { key: "value" }; + const rawResponseBody = { + meta: { + affectedPages: [ + { + pageObjectNumber: 1, + revision: { docSessionId: "docSessionId", pageObjectNumber: 1, generation: 1 }, + weakAnnotationState: { kind: "unknown" }, + }, + ], + cacheDelta: { + previousDocVersion: 1, + docVersion: 1, + pages: [{ pageObjectNumber: 1, cache: { contentVersion: 1, annotationVersion: 1 } }], + }, + }, + }; + + server + .mockEndpoint() + .patch("/v1/docs/docId/layers/layerName/annotations/pages/1/items/annotKey") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.doc.annotations.update({ + docId: "docId", + layerName: "layerName", + pon: 1, + annotKey: "annotKey", + body: { + key: "value", + }, + }); + expect(response).toEqual(rawResponseBody); + }); + + test("update (2)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + const rawRequestBody = { string: { key: "value" } }; + const rawResponseBody = { key: "value" }; + + server + .mockEndpoint() + .patch("/v1/docs/docId/layers/layerName/annotations/pages/1/items/annotKey") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(400) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.doc.annotations.update({ + docId: "docId", + layerName: "layerName", + pon: 1, + annotKey: "annotKey", + body: { + string: { + key: "value", + }, + }, + }); + }).rejects.toThrow(CloudpdfApi.BadRequestError); + }); + + test("update (3)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + const rawRequestBody = { string: { key: "value" } }; + const rawResponseBody = { key: "value" }; + + server + .mockEndpoint() + .patch("/v1/docs/docId/layers/layerName/annotations/pages/1/items/annotKey") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(404) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.doc.annotations.update({ + docId: "docId", + layerName: "layerName", + pon: 1, + annotKey: "annotKey", + body: { + string: { + key: "value", + }, + }, + }); + }).rejects.toThrow(CloudpdfApi.NotFoundError); + }); +}); diff --git a/tests/wire/doc/forms.test.ts b/tests/wire/doc/forms.test.ts new file mode 100644 index 0000000..5a9eefc --- /dev/null +++ b/tests/wire/doc/forms.test.ts @@ -0,0 +1,330 @@ +// This file was auto-generated by Fern from our API Definition. + +import * as CloudpdfApi from "../../../src/api/index"; +import { CloudpdfApiClient } from "../../../src/Client"; +import { mockServerPool } from "../../mock-server/MockServerPool"; + +describe("FormsClient", () => { + test("get (1)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + + const rawResponseBody = { + formKind: "none", + needsAppearances: true, + fields: [ + { + family: "text", + ref: { kind: "objectNumber", fieldObjectNumber: 1 }, + fieldObjectNumber: 1, + name: "name", + origin: "acroform", + flags: { readOnly: true, required: true, noExport: true, raw: 1 }, + alternateName: "alternateName", + mappingName: "mappingName", + valueEntry: { kind: "none" }, + defaultValueEntry: { kind: "none" }, + widgets: [{ annotObjectNumber: 1, pageObjectNumber: 1 }], + value: "value", + defaultValue: "defaultValue", + maxLength: 1, + multiline: true, + password: true, + comb: true, + }, + ], + calculationOrder: [{ kind: "objectNumber", fieldObjectNumber: 1 }], + }; + + server + .mockEndpoint() + .get("/v1/docs/docId/layers/layerName/form") + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.doc.forms.get({ + docId: "docId", + layerName: "layerName", + }); + expect(response).toEqual(rawResponseBody); + }); + + test("get (2)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + + server + .mockEndpoint() + .get("/v1/docs/docId/layers/layerName/form") + .respondWith() + .statusCode(404) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.doc.forms.get({ + docId: "docId", + layerName: "layerName", + }); + }).rejects.toThrow(CloudpdfApi.NotFoundError); + }); + + test("importData (1)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + const rawRequestBody = { key: "value" }; + const rawResponseBody = { + meta: { + affectedPages: [ + { + pageObjectNumber: 1, + revision: { docSessionId: "docSessionId", pageObjectNumber: 1, generation: 1 }, + weakAnnotationState: { kind: "unknown" }, + }, + ], + cacheDelta: { + previousDocVersion: 1, + docVersion: 1, + pages: [{ pageObjectNumber: 1, cache: { contentVersion: 1, annotationVersion: 1 } }], + }, + }, + }; + + server + .mockEndpoint() + .post("/v1/docs/docId/layers/layerName/form/data") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.doc.forms.importData({ + docId: "docId", + layerName: "layerName", + body: { + key: "value", + }, + }); + expect(response).toEqual(rawResponseBody); + }); + + test("importData (2)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + const rawRequestBody = { string: { key: "value" } }; + const rawResponseBody = { key: "value" }; + + server + .mockEndpoint() + .post("/v1/docs/docId/layers/layerName/form/data") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(400) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.doc.forms.importData({ + docId: "docId", + layerName: "layerName", + body: { + string: { + key: "value", + }, + }, + }); + }).rejects.toThrow(CloudpdfApi.BadRequestError); + }); + + test("importData (3)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + const rawRequestBody = { string: { key: "value" } }; + const rawResponseBody = { key: "value" }; + + server + .mockEndpoint() + .post("/v1/docs/docId/layers/layerName/form/data") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(404) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.doc.forms.importData({ + docId: "docId", + layerName: "layerName", + body: { + string: { + key: "value", + }, + }, + }); + }).rejects.toThrow(CloudpdfApi.NotFoundError); + }); + + test("reset (1)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + + const rawResponseBody = { + meta: { + affectedPages: [ + { + pageObjectNumber: 1, + revision: { docSessionId: "docSessionId", pageObjectNumber: 1, generation: 1 }, + weakAnnotationState: { kind: "unknown" }, + }, + ], + cacheDelta: { + previousDocVersion: 1, + docVersion: 1, + pages: [{ pageObjectNumber: 1, cache: { contentVersion: 1, annotationVersion: 1 } }], + }, + }, + }; + + server + .mockEndpoint() + .post("/v1/docs/docId/layers/layerName/form/fields/fieldKey/reset") + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.doc.forms.reset({ + docId: "docId", + layerName: "layerName", + fieldKey: "fieldKey", + }); + expect(response).toEqual(rawResponseBody); + }); + + test("reset (2)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + + server + .mockEndpoint() + .post("/v1/docs/docId/layers/layerName/form/fields/fieldKey/reset") + .respondWith() + .statusCode(404) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.doc.forms.reset({ + docId: "docId", + layerName: "layerName", + fieldKey: "fieldKey", + }); + }).rejects.toThrow(CloudpdfApi.NotFoundError); + }); + + test("setValue (1)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + const rawRequestBody = { key: "value" }; + const rawResponseBody = { + meta: { + affectedPages: [ + { + pageObjectNumber: 1, + revision: { docSessionId: "docSessionId", pageObjectNumber: 1, generation: 1 }, + weakAnnotationState: { kind: "unknown" }, + }, + ], + cacheDelta: { + previousDocVersion: 1, + docVersion: 1, + pages: [{ pageObjectNumber: 1, cache: { contentVersion: 1, annotationVersion: 1 } }], + }, + }, + }; + + server + .mockEndpoint() + .post("/v1/docs/docId/layers/layerName/form/fields/fieldKey/value") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.doc.forms.setValue({ + docId: "docId", + layerName: "layerName", + fieldKey: "fieldKey", + body: { + key: "value", + }, + }); + expect(response).toEqual(rawResponseBody); + }); + + test("setValue (2)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + const rawRequestBody = { string: { key: "value" } }; + const rawResponseBody = { key: "value" }; + + server + .mockEndpoint() + .post("/v1/docs/docId/layers/layerName/form/fields/fieldKey/value") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(400) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.doc.forms.setValue({ + docId: "docId", + layerName: "layerName", + fieldKey: "fieldKey", + body: { + string: { + key: "value", + }, + }, + }); + }).rejects.toThrow(CloudpdfApi.BadRequestError); + }); + + test("setValue (3)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + const rawRequestBody = { string: { key: "value" } }; + const rawResponseBody = { key: "value" }; + + server + .mockEndpoint() + .post("/v1/docs/docId/layers/layerName/form/fields/fieldKey/value") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(404) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.doc.forms.setValue({ + docId: "docId", + layerName: "layerName", + fieldKey: "fieldKey", + body: { + string: { + key: "value", + }, + }, + }); + }).rejects.toThrow(CloudpdfApi.NotFoundError); + }); +}); diff --git a/tests/wire/doc/metadata.test.ts b/tests/wire/doc/metadata.test.ts new file mode 100644 index 0000000..b37947a --- /dev/null +++ b/tests/wire/doc/metadata.test.ts @@ -0,0 +1,61 @@ +// This file was auto-generated by Fern from our API Definition. + +import * as CloudpdfApi from "../../../src/api/index"; +import { CloudpdfApiClient } from "../../../src/Client"; +import { mockServerPool } from "../../mock-server/MockServerPool"; + +describe("MetadataClient", () => { + test("get (1)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + + const rawResponseBody = { + title: "title", + author: "author", + subject: "subject", + keywords: "keywords", + producer: "producer", + creator: "creator", + created: "2024-01-15T09:30:00Z", + modified: "2024-01-15T09:30:00Z", + trapped: "true", + custom: { key: "value" }, + }; + + server + .mockEndpoint() + .get("/v1/docs/docId/layers/layerName/metadata") + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.doc.metadata.get({ + docId: "docId", + layerName: "layerName", + }); + expect(response).toEqual(rawResponseBody); + }); + + test("get (2)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + + server + .mockEndpoint() + .get("/v1/docs/docId/layers/layerName/metadata") + .respondWith() + .statusCode(404) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.doc.metadata.get({ + docId: "docId", + layerName: "layerName", + }); + }).rejects.toThrow(CloudpdfApi.NotFoundError); + }); +}); diff --git a/tests/wire/doc/pages.test.ts b/tests/wire/doc/pages.test.ts new file mode 100644 index 0000000..e485fbe --- /dev/null +++ b/tests/wire/doc/pages.test.ts @@ -0,0 +1,391 @@ +// This file was auto-generated by Fern from our API Definition. + +import * as CloudpdfApi from "../../../src/api/index"; +import { CloudpdfApiClient } from "../../../src/Client"; +import { mockServerPool } from "../../mock-server/MockServerPool"; + +describe("PagesClient", () => { + test("delete (1)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + const rawRequestBody = { key: "value" }; + const rawResponseBody = { + meta: { + affectedPages: [ + { + pageObjectNumber: 1, + revision: { docSessionId: "docSessionId", pageObjectNumber: 1, generation: 1 }, + weakAnnotationState: { kind: "unknown" }, + }, + ], + cacheDelta: { + previousDocVersion: 1, + docVersion: 1, + pages: [{ pageObjectNumber: 1, cache: { contentVersion: 1, annotationVersion: 1 } }], + }, + }, + }; + + server + .mockEndpoint() + .post("/v1/docs/docId/layers/layerName/pages/delete") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.doc.pages.delete({ + docId: "docId", + layerName: "layerName", + body: { + key: "value", + }, + }); + expect(response).toEqual(rawResponseBody); + }); + + test("delete (2)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + const rawRequestBody = { string: { key: "value" } }; + const rawResponseBody = { key: "value" }; + + server + .mockEndpoint() + .post("/v1/docs/docId/layers/layerName/pages/delete") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(400) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.doc.pages.delete({ + docId: "docId", + layerName: "layerName", + body: { + string: { + key: "value", + }, + }, + }); + }).rejects.toThrow(CloudpdfApi.BadRequestError); + }); + + test("delete (3)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + const rawRequestBody = { string: { key: "value" } }; + const rawResponseBody = { key: "value" }; + + server + .mockEndpoint() + .post("/v1/docs/docId/layers/layerName/pages/delete") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(404) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.doc.pages.delete({ + docId: "docId", + layerName: "layerName", + body: { + string: { + key: "value", + }, + }, + }); + }).rejects.toThrow(CloudpdfApi.NotFoundError); + }); + + test("flatten (1)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + const rawRequestBody = { key: "value" }; + const rawResponseBody = { + meta: { + affectedPages: [ + { + pageObjectNumber: 1, + revision: { docSessionId: "docSessionId", pageObjectNumber: 1, generation: 1 }, + weakAnnotationState: { kind: "unknown" }, + }, + ], + cacheDelta: { + previousDocVersion: 1, + docVersion: 1, + pages: [{ pageObjectNumber: 1, cache: { contentVersion: 1, annotationVersion: 1 } }], + }, + }, + }; + + server + .mockEndpoint() + .post("/v1/docs/docId/layers/layerName/pages/flatten") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.doc.pages.flatten({ + docId: "docId", + layerName: "layerName", + body: { + key: "value", + }, + }); + expect(response).toEqual(rawResponseBody); + }); + + test("flatten (2)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + const rawRequestBody = { string: { key: "value" } }; + const rawResponseBody = { key: "value" }; + + server + .mockEndpoint() + .post("/v1/docs/docId/layers/layerName/pages/flatten") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(400) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.doc.pages.flatten({ + docId: "docId", + layerName: "layerName", + body: { + string: { + key: "value", + }, + }, + }); + }).rejects.toThrow(CloudpdfApi.BadRequestError); + }); + + test("flatten (3)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + const rawRequestBody = { string: { key: "value" } }; + const rawResponseBody = { key: "value" }; + + server + .mockEndpoint() + .post("/v1/docs/docId/layers/layerName/pages/flatten") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(404) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.doc.pages.flatten({ + docId: "docId", + layerName: "layerName", + body: { + string: { + key: "value", + }, + }, + }); + }).rejects.toThrow(CloudpdfApi.NotFoundError); + }); + + test("move (1)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + const rawRequestBody = { key: "value" }; + const rawResponseBody = { + meta: { + affectedPages: [ + { + pageObjectNumber: 1, + revision: { docSessionId: "docSessionId", pageObjectNumber: 1, generation: 1 }, + weakAnnotationState: { kind: "unknown" }, + }, + ], + cacheDelta: { + previousDocVersion: 1, + docVersion: 1, + pages: [{ pageObjectNumber: 1, cache: { contentVersion: 1, annotationVersion: 1 } }], + }, + }, + }; + + server + .mockEndpoint() + .post("/v1/docs/docId/layers/layerName/pages/move") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.doc.pages.move({ + docId: "docId", + layerName: "layerName", + body: { + key: "value", + }, + }); + expect(response).toEqual(rawResponseBody); + }); + + test("move (2)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + const rawRequestBody = { string: { key: "value" } }; + const rawResponseBody = { key: "value" }; + + server + .mockEndpoint() + .post("/v1/docs/docId/layers/layerName/pages/move") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(400) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.doc.pages.move({ + docId: "docId", + layerName: "layerName", + body: { + string: { + key: "value", + }, + }, + }); + }).rejects.toThrow(CloudpdfApi.BadRequestError); + }); + + test("move (3)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + const rawRequestBody = { string: { key: "value" } }; + const rawResponseBody = { key: "value" }; + + server + .mockEndpoint() + .post("/v1/docs/docId/layers/layerName/pages/move") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(404) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.doc.pages.move({ + docId: "docId", + layerName: "layerName", + body: { + string: { + key: "value", + }, + }, + }); + }).rejects.toThrow(CloudpdfApi.NotFoundError); + }); + + test("rotate (1)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + const rawRequestBody = { key: "value" }; + const rawResponseBody = { + meta: { + affectedPages: [ + { + pageObjectNumber: 1, + revision: { docSessionId: "docSessionId", pageObjectNumber: 1, generation: 1 }, + weakAnnotationState: { kind: "unknown" }, + }, + ], + cacheDelta: { + previousDocVersion: 1, + docVersion: 1, + pages: [{ pageObjectNumber: 1, cache: { contentVersion: 1, annotationVersion: 1 } }], + }, + }, + }; + + server + .mockEndpoint() + .post("/v1/docs/docId/layers/layerName/pages/rotate") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.doc.pages.rotate({ + docId: "docId", + layerName: "layerName", + body: { + key: "value", + }, + }); + expect(response).toEqual(rawResponseBody); + }); + + test("rotate (2)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + const rawRequestBody = { string: { key: "value" } }; + const rawResponseBody = { key: "value" }; + + server + .mockEndpoint() + .post("/v1/docs/docId/layers/layerName/pages/rotate") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(400) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.doc.pages.rotate({ + docId: "docId", + layerName: "layerName", + body: { + string: { + key: "value", + }, + }, + }); + }).rejects.toThrow(CloudpdfApi.BadRequestError); + }); + + test("rotate (3)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + const rawRequestBody = { string: { key: "value" } }; + const rawResponseBody = { key: "value" }; + + server + .mockEndpoint() + .post("/v1/docs/docId/layers/layerName/pages/rotate") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(404) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.doc.pages.rotate({ + docId: "docId", + layerName: "layerName", + body: { + string: { + key: "value", + }, + }, + }); + }).rejects.toThrow(CloudpdfApi.NotFoundError); + }); +}); diff --git a/tests/wire/doc/redactions.test.ts b/tests/wire/doc/redactions.test.ts new file mode 100644 index 0000000..f55832a --- /dev/null +++ b/tests/wire/doc/redactions.test.ts @@ -0,0 +1,103 @@ +// This file was auto-generated by Fern from our API Definition. + +import * as CloudpdfApi from "../../../src/api/index"; +import { CloudpdfApiClient } from "../../../src/Client"; +import { mockServerPool } from "../../mock-server/MockServerPool"; + +describe("RedactionsClient", () => { + test("apply (1)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + const rawRequestBody = { key: "value" }; + const rawResponseBody = { + meta: { + affectedPages: [ + { + pageObjectNumber: 1, + revision: { docSessionId: "docSessionId", pageObjectNumber: 1, generation: 1 }, + weakAnnotationState: { kind: "unknown" }, + }, + ], + cacheDelta: { + previousDocVersion: 1, + docVersion: 1, + pages: [{ pageObjectNumber: 1, cache: { contentVersion: 1, annotationVersion: 1 } }], + }, + }, + }; + + server + .mockEndpoint() + .post("/v1/docs/docId/layers/layerName/redactions/apply") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.doc.redactions.apply({ + docId: "docId", + layerName: "layerName", + body: { + key: "value", + }, + }); + expect(response).toEqual(rawResponseBody); + }); + + test("apply (2)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + const rawRequestBody = { string: { key: "value" } }; + const rawResponseBody = { key: "value" }; + + server + .mockEndpoint() + .post("/v1/docs/docId/layers/layerName/redactions/apply") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(400) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.doc.redactions.apply({ + docId: "docId", + layerName: "layerName", + body: { + string: { + key: "value", + }, + }, + }); + }).rejects.toThrow(CloudpdfApi.BadRequestError); + }); + + test("apply (3)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + const rawRequestBody = { string: { key: "value" } }; + const rawResponseBody = { key: "value" }; + + server + .mockEndpoint() + .post("/v1/docs/docId/layers/layerName/redactions/apply") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(404) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.doc.redactions.apply({ + docId: "docId", + layerName: "layerName", + body: { + string: { + key: "value", + }, + }, + }); + }).rejects.toThrow(CloudpdfApi.NotFoundError); + }); +}); diff --git a/tests/wire/documents.test.ts b/tests/wire/documents.test.ts new file mode 100644 index 0000000..d49ec16 --- /dev/null +++ b/tests/wire/documents.test.ts @@ -0,0 +1,361 @@ +// This file was auto-generated by Fern from our API Definition. + +import * as CloudpdfApi from "../../src/api/index"; +import { CloudpdfApiClient } from "../../src/Client"; +import { mockServerPool } from "../mock-server/MockServerPool"; + +describe("DocumentsClient", () => { + test("list (1)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + + const rawResponseBody = { + documents: [ + { + id: "id", + tenantId: "tenantId", + state: "pending", + baseSha: "baseSha", + storageSizeBytes: 1.1, + metadata: { key: "value" }, + idempotencyKey: "idempotencyKey", + failureReason: "failureReason", + thumbnailState: "pending", + thumbnailUrl: "thumbnailUrl", + createdAt: 1.1, + updatedAt: 1.1, + createdBy: "createdBy", + }, + ], + nextCursor: "nextCursor", + }; + + server + .mockEndpoint() + .get("/v1/tenants/tenantId/documents") + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.documents.list({ + tenantId: "tenantId", + }); + expect(response).toEqual(rawResponseBody); + }); + + test("list (2)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + + server + .mockEndpoint() + .get("/v1/tenants/tenantId/documents") + .respondWith() + .statusCode(400) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.documents.list({ + tenantId: "tenantId", + }); + }).rejects.toThrow(CloudpdfApi.BadRequestError); + }); + + test("get (1)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + + const rawResponseBody = { + document: { + id: "id", + tenantId: "tenantId", + state: "pending", + baseSha: "baseSha", + storageSizeBytes: 1.1, + metadata: { key: "value" }, + idempotencyKey: "idempotencyKey", + failureReason: "failureReason", + thumbnailState: "pending", + thumbnailUrl: "thumbnailUrl", + createdAt: 1.1, + updatedAt: 1.1, + createdBy: "createdBy", + }, + }; + + server + .mockEndpoint() + .get("/v1/tenants/tenantId/documents/id") + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.documents.get({ + tenantId: "tenantId", + id: "id", + }); + expect(response).toEqual(rawResponseBody); + }); + + test("get (2)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + + server + .mockEndpoint() + .get("/v1/tenants/tenantId/documents/id") + .respondWith() + .statusCode(403) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.documents.get({ + tenantId: "tenantId", + id: "id", + }); + }).rejects.toThrow(CloudpdfApi.ForbiddenError); + }); + + test("get (3)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + + server + .mockEndpoint() + .get("/v1/tenants/tenantId/documents/id") + .respondWith() + .statusCode(404) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.documents.get({ + tenantId: "tenantId", + id: "id", + }); + }).rejects.toThrow(CloudpdfApi.NotFoundError); + }); + + test("delete (1)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + + server.mockEndpoint().delete("/v1/tenants/tenantId/documents/id").respondWith().statusCode(200).build(); + + const response = await client.documents.delete({ + tenantId: "tenantId", + id: "id", + }); + expect(response).toEqual(undefined); + }); + + test("delete (2)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + + server + .mockEndpoint() + .delete("/v1/tenants/tenantId/documents/id") + .respondWith() + .statusCode(403) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.documents.delete({ + tenantId: "tenantId", + id: "id", + }); + }).rejects.toThrow(CloudpdfApi.ForbiddenError); + }); + + test("delete (3)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + + server + .mockEndpoint() + .delete("/v1/tenants/tenantId/documents/id") + .respondWith() + .statusCode(404) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.documents.delete({ + tenantId: "tenantId", + id: "id", + }); + }).rejects.toThrow(CloudpdfApi.NotFoundError); + }); + + test("commit (1)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + const rawRequestBody = { sha256: "sha256" }; + const rawResponseBody = { + document: { + id: "id", + tenantId: "tenantId", + state: "pending", + baseSha: "baseSha", + storageSizeBytes: 1.1, + metadata: { key: "value" }, + idempotencyKey: "idempotencyKey", + failureReason: "failureReason", + thumbnailState: "pending", + thumbnailUrl: "thumbnailUrl", + createdAt: 1.1, + updatedAt: 1.1, + createdBy: "createdBy", + }, + }; + + server + .mockEndpoint() + .post("/v1/tenants/tenantId/documents/id/commit") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.documents.commit({ + tenantId: "tenantId", + id: "id", + sha256: "sha256", + }); + expect(response).toEqual(rawResponseBody); + }); + + test("commit (2)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + const rawRequestBody = { sha256: "sha256" }; + const rawResponseBody = { key: "value" }; + + server + .mockEndpoint() + .post("/v1/tenants/tenantId/documents/id/commit") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(400) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.documents.commit({ + tenantId: "tenantId", + id: "id", + sha256: "sha256", + }); + }).rejects.toThrow(CloudpdfApi.BadRequestError); + }); + + test("commit (3)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + const rawRequestBody = { sha256: "sha256" }; + const rawResponseBody = { key: "value" }; + + server + .mockEndpoint() + .post("/v1/tenants/tenantId/documents/id/commit") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(404) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.documents.commit({ + tenantId: "tenantId", + id: "id", + sha256: "sha256", + }); + }).rejects.toThrow(CloudpdfApi.NotFoundError); + }); + + test("init (1)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + const rawRequestBody = { contentLength: 1.1, contentSha256: "contentSha256" }; + const rawResponseBody = { + tag: "created", + document: { + id: "id", + tenantId: "tenantId", + state: "pending", + baseSha: "baseSha", + storageSizeBytes: 1.1, + metadata: { key: "value" }, + idempotencyKey: "idempotencyKey", + failureReason: "failureReason", + thumbnailState: "pending", + thumbnailUrl: "thumbnailUrl", + createdAt: 1.1, + updatedAt: 1.1, + createdBy: "createdBy", + }, + upload: { + kind: "presigned", + presigned: { url: "url", headers: { key: "value" }, method: "PUT", expiresAt: 1.1 }, + key: "key", + }, + }; + + server + .mockEndpoint() + .post("/v1/tenants/tenantId/documents/init") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.documents.init({ + tenantId: "tenantId", + contentLength: 1.1, + contentSha256: "contentSha256", + }); + expect(response).toEqual(rawResponseBody); + }); + + test("init (2)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + const rawRequestBody = { contentLength: 1, contentSha256: "contentSha256" }; + const rawResponseBody = { key: "value" }; + + server + .mockEndpoint() + .post("/v1/tenants/tenantId/documents/init") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(400) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.documents.init({ + tenantId: "tenantId", + contentLength: 1, + contentSha256: "contentSha256", + }); + }).rejects.toThrow(CloudpdfApi.BadRequestError); + }); +}); diff --git a/tests/wire/tenants.test.ts b/tests/wire/tenants.test.ts new file mode 100644 index 0000000..468d6c2 --- /dev/null +++ b/tests/wire/tenants.test.ts @@ -0,0 +1,155 @@ +// This file was auto-generated by Fern from our API Definition. + +import * as CloudpdfApi from "../../src/api/index"; +import { CloudpdfApiClient } from "../../src/Client"; +import { mockServerPool } from "../mock-server/MockServerPool"; + +describe("TenantsClient", () => { + test("list (1)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + + const rawResponseBody = { + tenants: [{ id: "id", name: "name", autoProvisioned: true, createdAt: 1.1 }], + nextCursor: "nextCursor", + }; + + server.mockEndpoint().get("/v1/tenants").respondWith().statusCode(200).jsonBody(rawResponseBody).build(); + + const response = await client.tenants.list(); + expect(response).toEqual(rawResponseBody); + }); + + test("list (2)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + + server.mockEndpoint().get("/v1/tenants").respondWith().statusCode(400).jsonBody(rawResponseBody).build(); + + await expect(async () => { + return await client.tenants.list(); + }).rejects.toThrow(CloudpdfApi.BadRequestError); + }); + + test("create (1)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + const rawRequestBody = { id: "id" }; + const rawResponseBody = { + tenant: { id: "id", name: "name", autoProvisioned: true, createdAt: 1.1 }, + created: true, + }; + + server + .mockEndpoint() + .post("/v1/tenants") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.tenants.create({ + id: "id", + }); + expect(response).toEqual(rawResponseBody); + }); + + test("create (2)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + const rawRequestBody = { id: "id" }; + const rawResponseBody = { key: "value" }; + + server + .mockEndpoint() + .post("/v1/tenants") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(400) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.tenants.create({ + id: "id", + }); + }).rejects.toThrow(CloudpdfApi.BadRequestError); + }); + + test("get (1)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + + const rawResponseBody = { tenant: { id: "id", name: "name", autoProvisioned: true, createdAt: 1.1 } }; + + server + .mockEndpoint() + .get("/v1/tenants/tenantId") + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.tenants.get({ + tenantId: "tenantId", + }); + expect(response).toEqual(rawResponseBody); + }); + + test("get (2)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + + server + .mockEndpoint() + .get("/v1/tenants/tenantId") + .respondWith() + .statusCode(404) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.tenants.get({ + tenantId: "tenantId", + }); + }).rejects.toThrow(CloudpdfApi.NotFoundError); + }); + + test("delete (1)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + + server.mockEndpoint().delete("/v1/tenants/tenantId").respondWith().statusCode(200).build(); + + const response = await client.tenants.delete({ + tenantId: "tenantId", + }); + expect(response).toEqual(undefined); + }); + + test("delete (2)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + + const rawResponseBody = { key: "value" }; + + server + .mockEndpoint() + .delete("/v1/tenants/tenantId") + .respondWith() + .statusCode(404) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.tenants.delete({ + tenantId: "tenantId", + }); + }).rejects.toThrow(CloudpdfApi.NotFoundError); + }); +}); diff --git a/tests/wire/tokens.test.ts b/tests/wire/tokens.test.ts new file mode 100644 index 0000000..e918fb1 --- /dev/null +++ b/tests/wire/tokens.test.ts @@ -0,0 +1,165 @@ +// This file was auto-generated by Fern from our API Definition. + +import * as CloudpdfApi from "../../src/api/index"; +import { CloudpdfApiClient } from "../../src/Client"; +import { mockServerPool } from "../mock-server/MockServerPool"; + +describe("TokensClient", () => { + test("issue (1)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + const rawRequestBody = { kind: "doc", sub: "sub", docId: "docId", scope: ["scope"], expiresIn: 1 }; + const rawResponseBody = { token: "token", jti: "jti", expiresAt: 1.1 }; + + server + .mockEndpoint() + .post("/v1/tenants/tenantId/tokens") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(200) + .jsonBody(rawResponseBody) + .build(); + + const response = await client.tokens.issue({ + tenantId: "tenantId", + body: { + kind: "doc", + sub: "sub", + docId: "docId", + scope: ["scope"], + expiresIn: 1, + }, + }); + expect(response).toEqual(rawResponseBody); + }); + + test("issue (2)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + const rawRequestBody = { kind: "doc", sub: "x", docId: "docId", scope: ["scope", "scope"], expiresIn: 7776000 }; + const rawResponseBody = { key: "value" }; + + server + .mockEndpoint() + .post("/v1/tenants/tenantId/tokens") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(400) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.tokens.issue({ + tenantId: "tenantId", + body: { + kind: "doc", + sub: "x", + docId: "docId", + scope: ["scope", "scope"], + expiresIn: 7776000, + }, + }); + }).rejects.toThrow(CloudpdfApi.BadRequestError); + }); + + test("issue (3)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + const rawRequestBody = { kind: "doc", sub: "x", docId: "docId", scope: ["scope", "scope"], expiresIn: 7776000 }; + const rawResponseBody = { key: "value" }; + + server + .mockEndpoint() + .post("/v1/tenants/tenantId/tokens") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(403) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.tokens.issue({ + tenantId: "tenantId", + body: { + kind: "doc", + sub: "x", + docId: "docId", + scope: ["scope", "scope"], + expiresIn: 7776000, + }, + }); + }).rejects.toThrow(CloudpdfApi.ForbiddenError); + }); + + test("issue (4)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + const rawRequestBody = { kind: "doc", sub: "x", docId: "docId", scope: ["scope", "scope"], expiresIn: 7776000 }; + const rawResponseBody = { key: "value" }; + + server + .mockEndpoint() + .post("/v1/tenants/tenantId/tokens") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(404) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.tokens.issue({ + tenantId: "tenantId", + body: { + kind: "doc", + sub: "x", + docId: "docId", + scope: ["scope", "scope"], + expiresIn: 7776000, + }, + }); + }).rejects.toThrow(CloudpdfApi.NotFoundError); + }); + + test("revoke (1)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + const rawRequestBody = {}; + + server + .mockEndpoint() + .post("/v1/tenants/tenantId/tokens/jti/revoke") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(200) + .build(); + + const response = await client.tokens.revoke({ + tenantId: "tenantId", + jti: "jti", + }); + expect(response).toEqual(undefined); + }); + + test("revoke (2)", async () => { + const server = mockServerPool.createServer(); + const client = new CloudpdfApiClient({ maxRetries: 0, token: "test", environment: server.baseUrl }); + const rawRequestBody = {}; + const rawResponseBody = { key: "value" }; + + server + .mockEndpoint() + .post("/v1/tenants/tenantId/tokens/jti/revoke") + .jsonBody(rawRequestBody) + .respondWith() + .statusCode(400) + .jsonBody(rawResponseBody) + .build(); + + await expect(async () => { + return await client.tokens.revoke({ + tenantId: "tenantId", + jti: "jti", + }); + }).rejects.toThrow(CloudpdfApi.BadRequestError); + }); +}); diff --git a/tsconfig.base.json b/tsconfig.base.json new file mode 100644 index 0000000..93a92c0 --- /dev/null +++ b/tsconfig.base.json @@ -0,0 +1,17 @@ +{ + "compilerOptions": { + "extendedDiagnostics": true, + "strict": true, + "target": "ES6", + "moduleResolution": "node", + "esModuleInterop": true, + "skipLibCheck": true, + "declaration": true, + "outDir": "dist", + "rootDir": "src", + "isolatedModules": true, + "isolatedDeclarations": true + }, + "include": ["src"], + "exclude": [] +} diff --git a/tsconfig.cjs.json b/tsconfig.cjs.json new file mode 100644 index 0000000..5c11446 --- /dev/null +++ b/tsconfig.cjs.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.base.json", + "compilerOptions": { + "module": "CommonJS", + "outDir": "dist/cjs" + }, + "include": ["src"], + "exclude": [] +} diff --git a/tsconfig.esm.json b/tsconfig.esm.json new file mode 100644 index 0000000..021e74d --- /dev/null +++ b/tsconfig.esm.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.base.json", + "compilerOptions": { + "module": "esnext", + "moduleResolution": "bundler", + "outDir": "dist/esm", + "verbatimModuleSyntax": true + }, + "include": ["src"], + "exclude": [] +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..d77fdf0 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "./tsconfig.cjs.json" +} diff --git a/vitest.config.mts b/vitest.config.mts new file mode 100644 index 0000000..0dee5a7 --- /dev/null +++ b/vitest.config.mts @@ -0,0 +1,32 @@ +import { defineConfig } from "vitest/config"; +export default defineConfig({ + test: { + typecheck: { + enabled: true, + tsconfig: "./tests/tsconfig.json", + }, + projects: [ + { + test: { + globals: true, + name: "unit", + environment: "node", + root: "./tests", + include: ["**/*.test.{js,ts,jsx,tsx}"], + exclude: ["wire/**"], + setupFiles: ["./setup.ts"], + }, + }, + { + test: { + globals: true, + name: "wire", + environment: "node", + root: "./tests/wire", + setupFiles: ["../setup.ts", "../mock-server/setup.ts"], + }, + }, + ], + passWithNoTests: true, + }, +});