@andesine/sdk 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -0
- package/LICENSE +21 -0
- package/README.md +728 -0
- package/dist/answer-stream-7N_gLhVS.js +193 -0
- package/dist/answer-stream-7N_gLhVS.js.map +1 -0
- package/dist/index-DFEcYmbh.d.ts +23370 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1167 -0
- package/dist/index.js.map +1 -0
- package/dist/streaming.d.ts +41 -0
- package/dist/streaming.js +93 -0
- package/dist/streaming.js.map +1 -0
- package/openapi.json +27190 -0
- package/package.json +69 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/paginate.ts","../src/content-client.ts","../src/query.ts","../src/operation.ts","../src/generated/resources.ts","../src/retry.ts","../src/client.ts","../src/content-url.ts","../src/structured-content.ts"],"sourcesContent":["interface Page<T> {\n data: T[];\n pagination: { nextCursor: string | null; hasMore: boolean };\n}\ninterface PaginateOptions {\n /** Start after a saved cursor. The callback must retain its original scope and snapshot. */\n cursor?: string;\n}\n\n/**\n * Iterate cursor-paginated pages, retaining their metadata.\n *\n * @param getPage - Fetch one page for the supplied cursor. The first cursor is undefined unless supplied.\n * Keep filters stable. This generic helper does not bind snapshots; use content.paginateEntryPages()\n * or content.paginateCollectionPages() for automatic published snapshot handling.\n * @param options - Optional cursor from an earlier page to resume processing.\n * @returns A lazy iterator that requests the next page only after the previous page is consumed.\n * Save pagination.nextCursor after processing a page. Break the loop to stop further requests.\n * @throws Error for a missing or repeated next cursor. Callback failures pass through unchanged.\n */\nconst paginatePages = async function* <P extends Page<unknown>>(\n getPage: (cursor?: string) => Promise<P>,\n options: PaginateOptions = {}\n): AsyncGenerator<P> {\n const seen = new Set<string>(options.cursor ? [options.cursor] : []);\n\n let cursor = options.cursor;\n\n do {\n const page = await getPage(cursor);\n const next = page.pagination.nextCursor;\n\n if (page.pagination.hasMore && (!next || seen.has(next))) {\n throw new Error(\"Pagination returned a missing or repeated cursor\");\n }\n\n yield page;\n\n if (!page.pagination.hasMore) return;\n\n seen.add(next!);\n cursor = next!;\n } while (cursor);\n};\n\n/**\n * Iterate items across cursor-paginated pages without collecting them in memory.\n *\n * @param getPage - Fetch one page using the cursor. Keep scope and filters stable in this callback.\n * This generic helper does not bind snapshots; content.paginateEntries() and\n * content.paginateCollections() do that automatically for published content.\n * @param options - Optional starting cursor; retain its matching scope and snapshot yourself.\n * @returns Items in API order. Break the loop to prevent further page requests.\n * @throws Pagination errors from paginatePages(), or the original callback error.\n */\nconst paginate = async function* <T>(\n getPage: (cursor?: string) => Promise<Page<T>>,\n options: PaginateOptions = {}\n): AsyncGenerator<T> {\n for await (const page of paginatePages(getPage, options)) {\n yield* page.data;\n }\n};\n\nexport { paginate, paginatePages };\nexport type { Page, PaginateOptions };\n","import type { APIResources } from \"./generated/resources\";\nimport type { ContentListOutput } from \"./content-list\";\nimport type { OperationInput, OperationOutput, RequestOptions } from \"./operation\";\nimport { paginatePages, type Page } from \"./paginate\";\n\ninterface ContentClient extends ContentResources {\n /**\n * Iterate published entries, automatically keeping the first page's snapshot.\n *\n * @param input - List scope, filters, and page size. Set includeContent to true for full entries.\n * To resume, supply both cursor and snapshotID, or use a client from atSnapshot().\n * @param options - Options for each request. The timeout applies to each page separately.\n * @returns A lazy iterator in API order. Breaking the loop prevents further requests.\n * @throws API errors without switching to a newer snapshot, including expired snapshots.\n * @example\n * for await (const entry of client.content.paginateEntries({\n * collectionPath: \"/Tutorials\", includeContent: true\n * })) console.log(entry.properties);\n */\n paginateEntries<const Input extends EntryListInput = Record<string, never>>(\n input?: Input,\n options?: ContentPaginationOptions\n ): AsyncGenerator<ContentListOutput<Input>[\"data\"][number]>;\n /**\n * Iterate entry pages while retaining snapshot metadata and resume cursors.\n *\n * The first response selects the snapshot; later requests omit channel and reuse that snapshot.\n * Scope and filters are reused for every page. An existing atSnapshot() binding is respected.\n * @param input - List options. Resuming requires cursor and its snapshot, with the same filters.\n * @param options - Per-page request options, including cancellation and timeout.\n * @returns Lazy pages with includeContent-dependent item types and snapshot metadata.\n * @throws API errors or an error for a missing/repeated cursor or changed response snapshot.\n */\n paginateEntryPages<const Input extends EntryListInput = Record<string, never>>(\n input?: Input,\n options?: ContentPaginationOptions\n ): AsyncGenerator<ContentListOutput<Input>>;\n /**\n * Iterate published collections using the first page's snapshot for all later pages.\n *\n * @param input - Collection scope and page size. To resume, supply cursor and its snapshot.\n * @param options - Per-page request options. Break the loop to stop requesting pages.\n * @returns A lazy iterator of collection summaries in API order.\n * @throws API and pagination errors; unavailable snapshots are never replaced automatically.\n */\n paginateCollections(\n input?: OperationInput<\"content.listCollections\">,\n options?: ContentPaginationOptions\n ): AsyncGenerator<OperationOutput<\"content.listCollections\">[\"data\"][number]>;\n /**\n * Iterate collection pages with snapshot metadata and resume cursors.\n *\n * @param input - List options. Use the same scope and snapshot when resuming a cursor.\n * @param options - Options applied to each request, including cancellation and timeout.\n * @returns Lazy pages pinned to the first response's snapshot or the atSnapshot() binding.\n * @throws API errors or an error for a missing/repeated cursor or changed response snapshot.\n */\n paginateCollectionPages(\n input?: OperationInput<\"content.listCollections\">,\n options?: ContentPaginationOptions\n ): AsyncGenerator<OperationOutput<\"content.listCollections\">>;\n}\ninterface SnapshotListInput {\n channel?: string;\n snapshotID?: string;\n cursor?: string;\n}\ninterface SnapshotPage extends Page<unknown> {\n snapshotID: string;\n}\n\ntype ContentResources = APIResources[\"content\"];\ntype EntryListInput = OperationInput<\"content.listEntries\">;\ntype ContentPaginationOptions = RequestOptions & { response?: \"data\" };\n\nconst paginateSnapshotPages = async function* <\n Input extends SnapshotListInput,\n P extends SnapshotPage\n>(\n list: (input: Input, options: ContentPaginationOptions) => Promise<P>,\n input: Input,\n options: ContentPaginationOptions = {}\n): AsyncGenerator<P> {\n let query = { ...input };\n\n yield* paginatePages(\n async (cursor) => {\n const page = await list({ ...query, cursor }, { ...options, response: \"data\" });\n const snapshotChanged =\n query.snapshotID !== undefined && page.snapshotID !== query.snapshotID;\n\n if (snapshotChanged) throw new Error(\"Pagination returned a different snapshot\");\n\n query = { ...query, channel: undefined, snapshotID: page.snapshotID };\n\n return page;\n },\n { cursor: input.cursor }\n );\n};\n\nconst createContentClient = (content: ContentResources): ContentClient => {\n const paginateEntryPages = <const Input extends EntryListInput = Record<string, never>>(\n input: Input = {} as Input,\n options?: ContentPaginationOptions\n ) =>\n paginateSnapshotPages<Input, ContentListOutput<Input>>(\n (query, requestOptions) => content.listEntries(query, requestOptions),\n input,\n options\n );\n const paginateCollectionPages = (\n input: OperationInput<\"content.listCollections\"> = {},\n options?: ContentPaginationOptions\n ) =>\n paginateSnapshotPages(\n (query, requestOptions) => content.listCollections(query, requestOptions),\n input,\n options\n );\n\n return {\n ...content,\n paginateEntryPages,\n async *paginateEntries(input, options) {\n for await (const page of paginateEntryPages(input, options)) yield* page.data;\n },\n paginateCollectionPages,\n async *paginateCollections(input, options) {\n for await (const page of paginateCollectionPages(input, options)) yield* page.data;\n }\n };\n};\n\nexport { createContentClient };\nexport type { ContentClient, ContentPaginationOptions };\n","// oRPC represents nested query values with indexed bracket notation.\nconst serializeQuery = (query: Record<string, unknown>): string => {\n const parameters = new URLSearchParams();\n const escapeKey = (key: string) => key.replace(/[\\\\[\\]]/g, (character) => `\\\\${character}`);\n const append = (path: string, value: unknown): void => {\n if (value === undefined || value === null) return;\n\n if (Array.isArray(value)) {\n value.forEach((item, index) => append(`${path}[${index}]`, item));\n } else if (typeof value === \"object\") {\n for (const [key, item] of Object.entries(value)) append(`${path}[${escapeKey(key)}]`, item);\n } else {\n parameters.append(path, String(value));\n }\n };\n\n for (const [key, value] of Object.entries(query)) append(escapeKey(key), value);\n\n return parameters.toString();\n};\n\nexport { serializeQuery };\n","import type { ContentListOperation } from \"./content-list\";\nimport type { WithSelectors } from \"./selectors\";\nimport type { operations } from \"./generated/schema\";\n\ninterface RequestOptions {\n /** Cancel the request or stream, preserving the signal's abort reason. */\n signal?: AbortSignal;\n /** Override the client timeout in milliseconds; 0 disables it. Includes stream consumption. */\n timeout?: number;\n /** Override GET retry attempts. Defaults to the client setting; other methods never retry. */\n retries?: number;\n /** Headers merged over client headers. The configured API key supplies Authorization. */\n headers?: HeadersInit;\n /** Return data by default, or status/headers/data with \"full\". Required for possible 304s. */\n response?: \"data\" | \"full\";\n}\ninterface APIResponse<T> {\n status: number;\n headers: Headers;\n data: T;\n notModified: false;\n}\ninterface NotModifiedResponse {\n status: 304;\n headers: Headers;\n data: undefined;\n notModified: true;\n}\ninterface OperationDefinition {\n streaming?: boolean;\n method: string;\n path: string;\n pathParams: string[];\n queryParams: string[];\n body: boolean;\n multipart: boolean;\n binary: boolean;\n anonymous: boolean;\n}\ninterface Requester {\n (\n definition: OperationDefinition,\n input: Record<string, unknown>,\n options?: RequestOptions\n ): Promise<unknown>;\n}\ninterface StandardOperation<K extends keyof operations> {\n (\n input: OperationInput<K>,\n options: RequestOptions & { response: \"full\" }\n ): Promise<APIResponse<OperationOutput<K>> | NotModifiedResponse>;\n (\n ...args: Record<string, never> extends OperationInput<K>\n ? [input?: OperationInput<K>, options?: RequestOptions & { response?: \"data\" }]\n : [input: OperationInput<K>, options?: RequestOptions & { response?: \"data\" }]\n ): Promise<OperationOutput<K>>;\n}\n\ninterface StreamOperation<K extends keyof operations> {\n (\n input: OperationInput<K>,\n options: RequestOptions & { response: \"full\" }\n ): Promise<APIResponse<OperationOutput<K>>>;\n (\n input: OperationInput<K>,\n options?: RequestOptions & { response?: \"data\" }\n ): Promise<OperationOutput<K>>;\n}\n\ntype StreamContent<K extends keyof operations> = Responses<K>[Extract<\n keyof Responses<K>,\n 200\n>] extends { content: { \"text/event-stream\": infer Frames } }\n ? Frames\n : never;\ntype StreamEvent<K extends keyof operations> =\n Extract<StreamContent<K>, { event: \"message\" }> extends { data: infer Event } ? Event : never;\ntype Operation<K extends keyof operations> = [StreamContent<K>] extends [never]\n ? K extends \"content.listEntries\"\n ? ContentListOperation\n : StandardOperation<K>\n : StreamOperation<K>;\n\ntype Content<T> = T extends { content: infer C } ? C[keyof C] : never;\ntype Parameters<T, K extends string> = T extends { parameters: infer P }\n ? K extends keyof P\n ? [NonNullable<P[K]>] extends [never]\n ? unknown\n : NonNullable<P[K]>\n : unknown\n : unknown;\ntype Body<T> = T extends { requestBody?: infer B }\n ? [Content<NonNullable<B>>] extends [never]\n ? unknown\n : Content<NonNullable<B>>\n : unknown;\ntype OperationInput<K extends keyof operations> = WithSelectors<\n K,\n Parameters<operations[K], \"path\"> & Parameters<operations[K], \"query\"> & Body<operations[K]>\n>;\ntype Responses<K extends keyof operations> = operations[K][\"responses\"];\ntype SuccessContent<K extends keyof operations> = Content<\n Responses<K>[Extract<keyof Responses<K>, 200 | 201 | 202 | 203 | 206>]\n>;\ntype OperationError<K extends keyof operations> = K extends keyof operations\n ? Extract<Content<Responses<K>[keyof Responses<K>]>, { defined: true; code: string }>\n : never;\ntype APIErrorBody = OperationError<keyof operations>;\ntype APIErrorCode = APIErrorBody[\"code\"];\ntype APIErrorData<C extends APIErrorCode> = Extract<APIErrorBody, { code: C }>[\"data\"];\ntype OperationOutput<K extends keyof operations> = [StreamContent<K>] extends [never]\n ? [SuccessContent<K>] extends [never]\n ? void\n : SuccessContent<K>\n : AsyncIterableIterator<StreamEvent<K>>;\n\nconst operation = <K extends keyof operations>(\n request: Requester,\n definition: OperationDefinition\n): Operation<K> => {\n return ((input: Record<string, unknown>, options?: RequestOptions) => {\n return request(definition, input || {}, options);\n }) as Operation<K>;\n};\n\nexport { operation };\nexport type {\n APIResponse,\n APIErrorBody,\n APIErrorCode,\n APIErrorData,\n OperationError,\n NotModifiedResponse,\n Operation,\n OperationDefinition,\n OperationInput,\n OperationOutput,\n Requester,\n RequestOptions\n};\n","/* eslint-disable max-lines */\n// Generated from openapi.json. Do not edit.\nimport { operation, type Operation, type Requester } from \"../operation\";\n\ninterface APIResources {\n assets: {\n /**\n * Search assets\n *\n * Finds workspace images by text or SHA-256 checksum. Semantic search defaults to true. Returns up to 50 results.\n *\n * Required API key permissions: read:entries, read:collections. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.assets.search({\n * \"query\": \"mountains\",\n * \"limit\": 10\n * });\n */\n search: Operation<\"assets.search\">;\n /**\n * Import an image URL\n *\n * Downloads a remote image and starts processing it for the entry. With checkDuplicates, can return an existing image instead. Use assets.get to check processing status.\n *\n * Required API key permissions: entries. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.assets.importURL({\n * \"assetID\": \"ast_example\",\n * \"entryID\": \"ent_example\",\n * \"url\": \"https://example.com/image.png\",\n * \"checkDuplicates\": true\n * });\n */\n importURL: Operation<\"assets.importURL\">;\n /**\n * Attach an asset\n *\n * Attaches a ready image to an entry. This does not insert an image node into the document.\n *\n * Required API key permissions: entries. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.assets.attach({\n * \"assetID\": \"ast_example\",\n * \"entryID\": \"ent_example\"\n * });\n */\n attach: Operation<\"assets.attach\">;\n /**\n * Register an image upload\n *\n * Reserves an image upload for an entry. Supply the byte count and lowercase SHA-256 checksum of the file. Call assets.upload before expiresAt, then use assets.get to check processing status.\n *\n * Required API key permissions: entries. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.assets.register({\n * \"assetID\": \"ast_example\",\n * \"entryID\": \"ent_example\",\n * \"filename\": \"image.png\",\n * \"byteSize\": 1024,\n * \"checksum\": \"0000000000000000000000000000000000000000000000000000000000000000\"\n * });\n */\n register: Operation<\"assets.register\">;\n /**\n * Upload registered image bytes\n *\n * Uploads a file for a registered asset with multipart/form-data. The bytes must match the registered size and checksum. Processing continues after the upload; use assets.get to check status.\n *\n * Required API key permissions: entries. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.assets.upload({\n * \"assetID\": \"ast_example\",\n * \"file\": new Blob([imageBytes], { type: \"image/png\" })\n * });\n */\n upload: Operation<\"assets.upload\">;\n /**\n * Get asset status and details\n *\n * Returns image metadata, processing status, and available files. Supply entryID when checking access through an entry.\n *\n * @example\n * await client.assets.get({\n * \"assetID\": \"ast_example\",\n * \"entryID\": \"ent_example\"\n * });\n */\n get: Operation<\"assets.get\">;\n };\n instance: {\n /**\n * Get instance capabilities and limits\n *\n * Returns configured features and effective limits for the authenticated workspace. These values do not grant permissions or report live service health. No discovery request is made automatically by the SDK.\n *\n * @example\n * await client.instance.get({});\n */\n get: Operation<\"instance.get\">;\n };\n entries: {\n /**\n * Create an entry\n *\n * Creates an entry and its initial document. The name defaults to Untitled. Creation selects an available sibling name with a numeric suffix when needed. Names are trimmed, NFC-normalized, case-sensitive, and shared by sibling entries and collections. Names cannot contain a slash or equal a single dot or two dots. A collection schema can set the initial content.\n *\n * Required API key permissions: entries. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.entries.create({\n * \"name\": \"Getting started\",\n * \"collectionID\": \"coll_example\"\n * });\n */\n create: Operation<\"entries.create\">;\n /**\n * Delete entries\n *\n * Soft-deletes the selected entries and clears current-entry selections for affected members. An active schema migration can block this action.\n *\n * Required API key permissions: entries. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.entries.bulkDelete({\n * \"ids\": [\n * \"ent_example\"\n * ]\n * });\n */\n bulkDelete: Operation<\"entries.bulkDelete\">;\n /**\n * Delete an entry\n *\n * Soft-deletes the entry and clears current-entry selections for affected members. An active schema migration can block this action.\n *\n * Required API key permissions: entries. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.entries.delete({\n * \"id\": \"ent_example\"\n * });\n */\n delete: Operation<\"entries.delete\">;\n /**\n * Rename an entry\n *\n * Updates the entry name. Rejects names already used by a sibling entry or collection. An active schema migration can block this action.\n *\n * Required API key permissions: entries. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.entries.update({\n * \"id\": \"ent_example\",\n * \"name\": \"Installation\"\n * });\n */\n update: Operation<\"entries.update\">;\n /**\n * Get an entry\n *\n * Returns current entry details, fragments, properties, and recorded schema metadata. Validates content without changing it. expectedSchemaHash must match the recorded schema; schema-less content cannot match it. Use content.get to read published content.\n *\n * Required API key permissions: read:entries. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.entries.get({\n * \"id\": \"ent_example\"\n * });\n */\n get: Operation<\"entries.get\">;\n /**\n * List entries\n *\n * Lists entries in the selected collection, or all accessible entries when collectionID is omitted. Pass pagination.nextCursor to the next request while pagination.hasMore is true. The limit is 1 to 100 and defaults to 50.\n *\n * Required API key permissions: read:entries. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.entries.list({\n * \"collectionID\": \"coll_example\",\n * \"limit\": 20\n * });\n */\n list: Operation<\"entries.list\">;\n };\n collections: {\n /**\n * Create a collection\n *\n * Creates a child collection. Without parentID, uses the workspace root. The name defaults to Untitled. Creation selects an available sibling name with a numeric suffix when needed. Names are trimmed, NFC-normalized, case-sensitive, and shared by sibling entries and collections. Names cannot contain a slash or equal a single dot or two dots. Restricted collections require a session with restricted_collections permission and the Pro plan; API keys cannot create them.\n *\n * Required API key permissions: collections. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.collections.create({\n * \"name\": \"Documentation\",\n * \"parentID\": \"coll_example\"\n * });\n */\n create: Operation<\"collections.create\">;\n /**\n * Delete collection trees\n *\n * Soft-deletes the selected collections, their descendants, and their entries. The workspace root cannot be deleted. An active schema migration can block this action.\n *\n * Required API key permissions: collections. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.collections.bulkDelete({\n * \"ids\": [\n * \"coll_example\"\n * ]\n * });\n */\n bulkDelete: Operation<\"collections.bulkDelete\">;\n /**\n * Delete a collection tree\n *\n * Soft-deletes the collection, its descendants, and their entries. The workspace root cannot be deleted. An active schema migration can block this action.\n *\n * Required API key permissions: collections. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.collections.delete({\n * \"id\": \"coll_example\"\n * });\n */\n delete: Operation<\"collections.delete\">;\n /**\n * Rename a collection\n *\n * Updates the collection name. Rejects names already used by a sibling entry or collection. An active schema migration can block this action.\n *\n * Required API key permissions: collections. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.collections.update({\n * \"id\": \"coll_example\",\n * \"name\": \"Guides\"\n * });\n */\n update: Operation<\"collections.update\">;\n /**\n * List collections\n *\n * Lists collections under the selected ancestor. Pass pagination.nextCursor to the next request while pagination.hasMore is true. The limit is 1 to 100.\n *\n * Required API key permissions: read:collections. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.collections.list({\n * \"collectionID\": \"coll_example\",\n * \"limit\": 20\n * });\n */\n list: Operation<\"collections.list\">;\n };\n content: {\n /**\n * List published collections\n *\n * Returns a flat page of collections from a publication snapshot. The default channel is published. On later pages, pass the returned snapshotID and pagination.nextCursor, and omit channel. Optionally select direct children using collectionID or collectionPath. Results are ordered by ID, not display order.\n *\n * Required API key permissions: read:publishing. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.content.listCollections({\n * \"channel\": \"published\",\n * \"limit\": 20\n * });\n */\n listCollections: Operation<\"content.listCollections\">;\n /**\n * List published entries\n *\n * Returns a flat page of entries from a publication snapshot. The default channel is published. On later pages, pass the returned snapshotID and pagination.nextCursor, and omit channel. Select direct children using collectionID or collectionPath, or include nested entries with descendants: true. descendants requires a collection scope. All property filters must match the assigned version. includeContent: true returns validated full content, properties, fragments, assets, and recorded schema metadata. An invalid full item fails the page. Keep the same scope and filters across pages. Results are ordered by ID, not display order.\n *\n * Required API key permissions: read:publishing. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.content.listEntries({\n * \"channel\": \"published\",\n * \"limit\": 20\n * });\n */\n listEntries: Operation<\"content.listEntries\">;\n /**\n * Get a published entry schema\n *\n * Returns the exact recorded effective schema, or null for schema-less content. Uses the same publication access as content.get. Pass its snapshotID for a consistent read; use channel or snapshotID, not both.\n *\n * Required API key permissions: read:publishing. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.content.getSchema({\n * \"entryID\": \"ent_example\",\n * \"channel\": \"published\"\n * });\n */\n getSchema: Operation<\"content.getSchema\">;\n /**\n * Download a published asset\n *\n * Returns binary image data from a publication snapshot. No API key is required. The asset must belong to the entry in that available snapshot. Use the asset URLs returned with published content.\n *\n * @example\n * await client.content.getAsset({\n * \"workspaceID\": \"ws_example\",\n * \"snapshotID\": \"snp_example\",\n * \"entryID\": \"ent_example\",\n * \"assetID\": \"ast_example\",\n * \"variant\": \"display\"\n * });\n */\n getAsset: Operation<\"content.getAsset\">;\n /**\n * Get published entry content\n *\n * Returns content from a publishing channel or a specific available snapshot. Use channel or snapshotID, never both. The default channel is published. Validates saved content against its recorded schema and returns schema metadata. expectedSchemaHash must match that revision; schema-less content cannot match it. Validation and hash checks run before ETag handling. Supports ETag and If-None-Match; a match returns 304 without a body.\n *\n * Required API key permissions: read:publishing. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.content.get({\n * \"entryID\": \"ent_example\",\n * \"channel\": \"published\"\n * });\n */\n get: Operation<\"content.get\">;\n /**\n * Get a published collection tree\n *\n * Returns a published collection tree and its snapshot ID. Use channel or snapshotID, never both. The default channel is published. Reuse the snapshot ID for consistent content reads. Supports ETag and If-None-Match; a match returns 304 without a body.\n *\n * Required API key permissions: read:publishing. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.content.getTree({\n * \"collectionID\": \"coll_example\",\n * \"channel\": \"published\"\n * });\n */\n getTree: Operation<\"content.getTree\">;\n };\n roles: {\n /**\n * List roles\n *\n * Returns workspace roles and their permissions.\n *\n * Required API key permissions: read:roles. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.roles.list({});\n */\n list: Operation<\"roles.list\">;\n /**\n * Create a role\n *\n * Creates a workspace role. Names are unique without regard to case and must contain 1 to 50 characters after trimming. Requires the Pro plan and permission to delegate the selected permissions.\n *\n * Required API key permissions: roles. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.roles.create({\n * \"name\": \"Editor\",\n * \"permissions\": [\n * \"content\"\n * ]\n * });\n */\n create: Operation<\"roles.create\">;\n /**\n * Update a role\n *\n * Changes a role name or permissions. Names are unique without regard to case. Requires the Pro plan and permission to delegate the selected permissions. Built-in roles have additional restrictions.\n *\n * Required API key permissions: roles. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.roles.update({\n * \"id\": \"rl_example\",\n * \"name\": \"Content editor\"\n * });\n */\n update: Operation<\"roles.update\">;\n /**\n * Delete a role\n *\n * Deletes a custom role and updates its assignments. Built-in roles cannot be deleted. Requires the Pro plan.\n *\n * Required API key permissions: roles. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.roles.delete({\n * \"id\": \"rl_example\"\n * });\n */\n delete: Operation<\"roles.delete\">;\n };\n search: {\n /**\n * Search current content\n *\n * Searches current entry content by text and optional property filters. Up to 20 filters and 50 results are allowed. Semantic search is optional and has a separate rate limit.\n *\n * Required API key permissions: read:entries, read:collections. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.search.current({\n * \"query\": \"installation\",\n * \"limit\": 10\n * });\n */\n current: Operation<\"search.current\">;\n /**\n * Search published content\n *\n * Searches content published to the required channel. Up to 20 filters and 50 results are allowed. Semantic search is optional and has a separate rate limit.\n *\n * Required API key permissions: read:publishing. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.search.published({\n * \"query\": \"installation\",\n * \"channel\": \"published\",\n * \"limit\": 10\n * });\n */\n published: Operation<\"search.published\">;\n /**\n * Ask AI about current content\n *\n * Returns a complete answer with numbered sources. Requires explicit ai-answers permission in addition to content read permissions. Accepts up to 1,000 question characters, 10 history messages of up to 4,000 characters each, and 20 property filters. Uses the existing Ask AI rate limit. Keep API keys on your server.\n *\n * Required API key permissions: ai-answers, read:entries, read:collections. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.search.askCurrent({\n * \"question\": \"How do I install Andesine?\"\n * });\n */\n askCurrent: Operation<\"search.askCurrent\">;\n /**\n * Ask AI about published content\n *\n * Returns a complete answer with numbered sources. Requires explicit ai-answers permission in addition to content read permissions. Accepts up to 1,000 question characters, 10 history messages of up to 4,000 characters each, and 20 property filters. Uses the existing Ask AI rate limit. Keep API keys on your server.\n *\n * Required API key permissions: ai-answers, read:publishing. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.search.askPublished({\n * \"question\": \"How do I install Andesine?\",\n * \"channel\": \"published\"\n * });\n */\n askPublished: Operation<\"search.askPublished\">;\n /**\n * Stream an AI answer about current content\n *\n * Emits sources, textDelta, and completed events over SSE. Uses the same inputs, permissions, and rate limit as complete answers. Stream errors use SSE error frames. Never reconnect automatically.\n *\n * Required API key permissions: ai-answers, read:entries, read:collections. Write permissions also grant read access for the same resource.\n */\n askCurrentStream: Operation<\"search.askCurrentStream\">;\n /**\n * Stream an AI answer about published content\n *\n * Emits sources, textDelta, and completed events over SSE. Uses the same inputs, permissions, and rate limit as complete answers. Stream errors use SSE error frames. Never reconnect automatically.\n *\n * Required API key permissions: ai-answers, read:publishing. Write permissions also grant read access for the same resource.\n */\n askPublishedStream: Operation<\"search.askPublishedStream\">;\n };\n schemas: {\n /**\n * Create a local collection schema\n *\n * Creates a local schema draft for the collection. Use schemas.get to inspect local and effective schemas.\n *\n * Required API key permissions: collections. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.schemas.create({\n * \"collectionID\": \"coll_example\"\n * });\n */\n create: Operation<\"schemas.create\">;\n /**\n * Delete a local schema\n *\n * Removes the local schema and recalculates inherited schemas. This can start a content migration. Review possible content removal before setting confirmedDataLoss. Use schemaMigrations.get with a returned migrationID.\n *\n * Required API key permissions: collections. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.schemas.delete({\n * \"schemaID\": \"sch_example\",\n * \"confirmedDataLoss\": false\n * });\n */\n delete: Operation<\"schemas.delete\">;\n /**\n * Get an exact schema revision\n *\n * Returns the recorded effective definition, including inherited fields. Requires read access to the revision's collection. The definition is independent of the currently active schema.\n *\n * Required API key permissions: read:collections. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.schemas.getRevision({\n * \"revisionID\": \"schr_example\"\n * });\n */\n getRevision: Operation<\"schemas.getRevision\">;\n /**\n * Get collection schemas\n *\n * Returns local and effective schema details for the collection, including inheritance.\n *\n * Required API key permissions: read:collections. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.schemas.get({\n * \"collectionID\": \"coll_example\"\n * });\n */\n get: Operation<\"schemas.get\">;\n /**\n * Apply a schema draft\n *\n * Creates a schema version from the draft and starts any required migration of affected entry content. Review possible content removal before calling: confirmedDataLoss must be true. Use schemaMigrations.get to follow a returned migrationID.\n *\n * Required API key permissions: collections. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.schemas.apply({\n * \"schemaID\": \"sch_example\",\n * \"confirmedDataLoss\": true,\n * \"name\": \"Reviewed schema\"\n * });\n */\n apply: Operation<\"schemas.apply\">;\n };\n schemaMigrations: {\n /**\n * List entries with migration content loss\n *\n * Lists accessible, non-deleted entries that lost content in a completed migration. Returns an empty page until completion. Use pagination.nextCursor to continue.\n *\n * Required API key permissions: read:collections. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.schemaMigrations.listContentLossEntries({\n * \"id\": \"smg_example\",\n * \"limit\": 20\n * });\n */\n listContentLossEntries: Operation<\"schemaMigrations.listContentLossEntries\">;\n /**\n * Get the active schema migration\n *\n * Returns the active migration for a collection, or null when none is active.\n *\n * Required API key permissions: read:collections. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.schemaMigrations.getActive({\n * \"collectionID\": \"coll_example\"\n * });\n */\n getActive: Operation<\"schemaMigrations.getActive\">;\n /**\n * Get schema migration status\n *\n * Returns bounded migration progress and status. Use schemaMigrations.listContentLossEntries for per-entry content loss details. Check status before repeating an operation blocked by this migration.\n *\n * Required API key permissions: read:collections. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.schemaMigrations.get({\n * \"id\": \"smg_example\"\n * });\n */\n get: Operation<\"schemaMigrations.get\">;\n };\n schemaVersions: {\n /**\n * List schema versions\n *\n * Lists versions of a local collection schema. Pass pagination.nextCursor to the next request while pagination.hasMore is true. The limit is 1 to 100.\n *\n * Required API key permissions: read:collections. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.schemaVersions.list({\n * \"schemaID\": \"sch_example\",\n * \"limit\": 20\n * });\n */\n list: Operation<\"schemaVersions.list\">;\n /**\n * Get a schema version\n *\n * Returns a saved schema version and its definition.\n *\n * Required API key permissions: read:collections. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.schemaVersions.get({\n * \"id\": \"schv_example\"\n * });\n */\n get: Operation<\"schemaVersions.get\">;\n /**\n * Rename a schema version\n *\n * Changes the saved version name. Set name to null to remove the name.\n *\n * Required API key permissions: collections. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.schemaVersions.update({\n * \"id\": \"schv_example\",\n * \"name\": \"Reviewed schema\"\n * });\n */\n update: Operation<\"schemaVersions.update\">;\n /**\n * Restore a schema version\n *\n * Restores the selected definition and starts any required content migration. Review possible content removal before calling: confirmedDataLoss must be true. Use schemaMigrations.get to follow a returned migrationID.\n *\n * Required API key permissions: collections. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.schemaVersions.revert({\n * \"id\": \"schv_example\",\n * \"confirmedDataLoss\": true\n * });\n */\n revert: Operation<\"schemaVersions.revert\">;\n };\n memberships: {\n /**\n * List workspace members\n *\n * Lists workspace memberships with role and user details. Use pagination.nextCursor to continue with the same filters; concurrent changes can affect later pages.\n *\n * Required API key permissions: read:memberships. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.memberships.list({});\n */\n list: Operation<\"memberships.list\">;\n /**\n * Invite a workspace member\n *\n * Creates an invitation and attempts email delivery. Check emailDelivery in the result. Requires the Pro plan and permission to delegate the selected role. Existing membership or pending invitation returns a conflict.\n *\n * Required API key permissions: memberships. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.memberships.invite({\n * \"email\": \"editor@example.com\",\n * \"roleID\": \"rl_example\"\n * });\n */\n invite: Operation<\"memberships.invite\">;\n /**\n * Change a member role\n *\n * Assigns a new role to a member. Requires the Pro plan and permission to delegate that role. Administrator assignments have additional restrictions.\n *\n * Required API key permissions: memberships. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.memberships.update({\n * \"id\": \"ms_example\",\n * \"roleID\": \"rl_example\"\n * });\n */\n update: Operation<\"memberships.update\">;\n /**\n * Remove a workspace member\n *\n * Removes the membership and its workspace access. Administrator memberships have additional restrictions.\n *\n * Required API key permissions: memberships. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.memberships.remove({\n * \"id\": \"ms_example\"\n * });\n */\n remove: Operation<\"memberships.remove\">;\n /**\n * List invitations\n *\n * Lists pending, unexpired workspace invitations. Use pagination.nextCursor to continue. Requires the Pro plan.\n *\n * Required API key permissions: memberships. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.memberships.listInvites({});\n */\n listInvites: Operation<\"memberships.listInvites\">;\n /**\n * Resend an invitation\n *\n * Attempts email delivery again for a pending invitation. Check emailDelivery in the result. Requires the Pro plan.\n *\n * Required API key permissions: memberships. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.memberships.resendInvite({\n * \"id\": \"inv_example\"\n * });\n */\n resendInvite: Operation<\"memberships.resendInvite\">;\n /**\n * Revoke an invitation\n *\n * Revokes a pending invitation so it can no longer be accepted. Requires the Pro plan.\n *\n * Required API key permissions: memberships. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.memberships.revokeInvite({\n * \"id\": \"inv_example\"\n * });\n */\n revokeInvite: Operation<\"memberships.revokeInvite\">;\n };\n publishing: {\n /**\n * Configure collection publishing\n *\n * Enables publishing for a collection, or disables it and unpublishes its tree from all channels. When enabling, publish can also publish the latest entry versions.\n *\n * Required API key permissions: publishing. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.publishing.setCollection({\n * \"collectionID\": \"coll_example\",\n * \"enabled\": true,\n * \"publish\": false\n * });\n */\n setCollection: Operation<\"publishing.setCollection\">;\n /**\n * Publish a collection tree\n *\n * Publishes the latest entry versions in a publishing-enabled collection tree to the channel. The default channel is published. Supply expectedSnapshotID from a prior channel read to reject concurrent publication changes.\n *\n * Required API key permissions: publishing. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.publishing.publishCollection({\n * \"collectionID\": \"coll_example\",\n * \"channel\": \"published\"\n * });\n */\n publishCollection: Operation<\"publishing.publishCollection\">;\n /**\n * Unpublish a collection tree\n *\n * Removes publication assignments for a collection tree from the channel. The default channel is published. Supply expectedSnapshotID from a prior channel read to reject concurrent publication changes.\n *\n * Required API key permissions: publishing. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.publishing.unpublishCollection({\n * \"collectionID\": \"coll_example\",\n * \"channel\": \"published\"\n * });\n */\n unpublishCollection: Operation<\"publishing.unpublishCollection\">;\n /**\n * Configure publishing for collections\n *\n * Enables publishing for the selected collections, or disables it and unpublishes their trees from all channels. When enabling, publish can also publish the latest entry versions.\n *\n * Required API key permissions: publishing. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.publishing.bulkSetCollections({\n * \"ids\": [\n * \"coll_example\"\n * ],\n * \"enabled\": true,\n * \"publish\": false\n * });\n */\n bulkSetCollections: Operation<\"publishing.bulkSetCollections\">;\n /**\n * Publish collection trees\n *\n * Publishes the latest entry versions in the selected publishing-enabled collection trees. At least one ID is required. The default channel is published. Supply expectedSnapshotID from a prior channel read to reject concurrent publication changes.\n *\n * Required API key permissions: publishing. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.publishing.bulkPublishCollections({\n * \"ids\": [\n * \"coll_example\"\n * ],\n * \"channel\": \"published\"\n * });\n */\n bulkPublishCollections: Operation<\"publishing.bulkPublishCollections\">;\n /**\n * Unpublish collection trees\n *\n * Removes publication assignments for the selected collection trees from the channel. At least one ID is required. The default channel is published. Supply expectedSnapshotID from a prior channel read to reject concurrent publication changes.\n *\n * Required API key permissions: publishing. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.publishing.bulkUnpublishCollections({\n * \"ids\": [\n * \"coll_example\"\n * ],\n * \"channel\": \"published\"\n * });\n */\n bulkUnpublishCollections: Operation<\"publishing.bulkUnpublishCollections\">;\n /**\n * Publish an entry\n *\n * Publishes an existing version, or the latest entry content if versionID is omitted. The entry must be in a publishing-enabled collection. The default channel is published. Supply expectedSnapshotID from a prior channel read to reject concurrent publication changes.\n *\n * Required API key permissions: publishing. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.publishing.publishEntry({\n * \"entryID\": \"ent_example\",\n * \"channel\": \"published\"\n * });\n */\n publishEntry: Operation<\"publishing.publishEntry\">;\n /**\n * Unpublish an entry\n *\n * Removes the entry publication from the channel. Supply versionID to require that version to be assigned; a changed assignment returns a conflict. The default channel is published. Supply expectedSnapshotID from a prior channel read to reject concurrent publication changes.\n *\n * Required API key permissions: publishing. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.publishing.unpublishEntry({\n * \"entryID\": \"ent_example\",\n * \"channel\": \"published\",\n * \"versionID\": \"ver_example\"\n * });\n */\n unpublishEntry: Operation<\"publishing.unpublishEntry\">;\n /**\n * Publish entries\n *\n * Publishes the selected entries with optional version IDs. Entries must be in publishing-enabled collections. At least one entry is required. The default channel is published. Supply expectedSnapshotID from a prior channel read to reject concurrent publication changes.\n *\n * Required API key permissions: publishing. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.publishing.bulkPublishEntries({\n * \"entries\": [\n * {\n * \"entryID\": \"ent_example\"\n * }\n * ],\n * \"channel\": \"published\"\n * });\n */\n bulkPublishEntries: Operation<\"publishing.bulkPublishEntries\">;\n /**\n * Unpublish entries\n *\n * Removes publication assignments for the selected entries from the channel. At least one ID is required. The default channel is published. Supply expectedSnapshotID from a prior channel read to reject concurrent publication changes.\n *\n * Required API key permissions: publishing. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.publishing.bulkUnpublishEntries({\n * \"ids\": [\n * \"ent_example\"\n * ],\n * \"channel\": \"published\"\n * });\n */\n bulkUnpublishEntries: Operation<\"publishing.bulkUnpublishEntries\">;\n /**\n * Revert pending publishing changes\n *\n * Restores selected drafts to the reviewed publication snapshot. This can remove unpublished items and replace draft content. First review publishing.getChannelContent and pass its snapshotID. Use all: true or specific collectionIDs/entryIDs, never both. Requires write access to affected resources in addition to read:publishing.\n *\n * Required API key permissions: read:publishing. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.publishing.revertChanges({\n * \"collectionID\": \"coll_example\",\n * \"snapshotID\": \"snp_example\",\n * \"entryIDs\": [\n * \"ent_example\"\n * ],\n * \"channel\": \"published\"\n * });\n */\n revertChanges: Operation<\"publishing.revertChanges\">;\n /**\n * Get a published entry version\n *\n * Returns the entry version assigned to a channel, or to an explicit available snapshot, with its recorded schema metadata. Validates content against that revision. expectedSchemaHash must match it; schema-less content cannot match it. The default channel is published.\n *\n * Required API key permissions: read:publishing. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.publishing.getEntryVersion({\n * \"entryID\": \"ent_example\",\n * \"channel\": \"published\"\n * });\n */\n getEntryVersion: Operation<\"publishing.getEntryVersion\">;\n /**\n * List entry publications\n *\n * Returns the entry publication assignments across channels.\n *\n * Required API key permissions: read:publishing. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.publishing.listEntryPublications({\n * \"entryID\": \"ent_example\"\n * });\n */\n listEntryPublications: Operation<\"publishing.listEntryPublications\">;\n /**\n * List publishing channels\n *\n * Returns workspace publishing channels. Set includeAssignmentCount to include entry assignment counts.\n *\n * Required API key permissions: read:publishing. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.publishing.listChannels({\n * \"includeAssignmentCount\": true\n * });\n */\n listChannels: Operation<\"publishing.listChannels\">;\n /**\n * Create a publishing channel\n *\n * Creates a publishing channel from its display name and returns the generated channel code.\n *\n * Required API key permissions: publishing. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.publishing.createChannel({\n * \"name\": \"Preview\"\n * });\n */\n createChannel: Operation<\"publishing.createChannel\">;\n /**\n * Get channel content and pending changes\n *\n * Returns publication state and pending changes for a publishing root, with the snapshot ID needed to review and revert changes.\n *\n * Required API key permissions: read:publishing. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.publishing.getChannelContent({\n * \"channel\": \"published\",\n * \"collectionID\": \"coll_example\"\n * });\n */\n getChannelContent: Operation<\"publishing.getChannelContent\">;\n /**\n * Delete a publishing channel\n *\n * Deletes a custom channel and its publication assignments. The default published channel cannot be deleted.\n *\n * Required API key permissions: publishing. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.publishing.deleteChannel({\n * \"code\": \"preview\"\n * });\n */\n deleteChannel: Operation<\"publishing.deleteChannel\">;\n };\n versions: {\n /**\n * Create an entry version\n *\n * Saves a version of the current entry content. Optionally assigns a name.\n *\n * Required API key permissions: versions. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.versions.create({\n * \"entryID\": \"ent_example\",\n * \"name\": \"Before release\"\n * });\n */\n create: Operation<\"versions.create\">;\n /**\n * List entry versions\n *\n * Lists saved entry versions. Pass pagination.nextCursor to the next request while pagination.hasMore is true. The limit is 1 to 100.\n *\n * Required API key permissions: read:versions. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.versions.list({\n * \"entryID\": \"ent_example\",\n * \"limit\": 20\n * });\n */\n list: Operation<\"versions.list\">;\n /**\n * Get an entry version\n *\n * Returns the saved content and recorded schema metadata of an entry version. Validates against its recorded revision, including historical versions. expectedSchemaHash must match that revision; schema-less content cannot match it.\n *\n * Required API key permissions: read:versions. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.versions.get({\n * \"id\": \"ver_example\"\n * });\n */\n get: Operation<\"versions.get\">;\n /**\n * Rename an entry version\n *\n * Changes the saved version name. Set name to null to remove the name.\n *\n * Required API key permissions: versions. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.versions.update({\n * \"id\": \"ver_example\",\n * \"name\": \"Release candidate\"\n * });\n */\n update: Operation<\"versions.update\">;\n /**\n * Restore an entry version\n *\n * Restores saved content to the current entry and returns the resulting version. An active schema migration can block this action.\n *\n * Required API key permissions: versions. Write permissions also grant read access for the same resource.\n *\n * @example\n * await client.versions.revert({\n * \"id\": \"ver_example\"\n * });\n */\n revert: Operation<\"versions.revert\">;\n };\n}\n\nconst createResources = (request: Requester): APIResources => ({\n assets: {\n search: operation<\"assets.search\">(request, {\n method: \"get\",\n path: \"/assets/search\",\n pathParams: [],\n queryParams: [\"query\", \"checksum\", \"semantic\", \"limit\"],\n body: false,\n multipart: false,\n binary: false,\n anonymous: false\n }),\n importURL: operation<\"assets.importURL\">(request, {\n method: \"post\",\n path: \"/assets/imports\",\n pathParams: [],\n queryParams: [],\n body: true,\n multipart: false,\n binary: false,\n anonymous: false\n }),\n attach: operation<\"assets.attach\">(request, {\n method: \"post\",\n path: \"/assets/{assetID}/attachments\",\n pathParams: [\"assetID\"],\n queryParams: [],\n body: true,\n multipart: false,\n binary: false,\n anonymous: false\n }),\n register: operation<\"assets.register\">(request, {\n method: \"post\",\n path: \"/assets/uploads\",\n pathParams: [],\n queryParams: [],\n body: true,\n multipart: false,\n binary: false,\n anonymous: false\n }),\n upload: operation<\"assets.upload\">(request, {\n method: \"put\",\n path: \"/assets/{assetID}/upload\",\n pathParams: [\"assetID\"],\n queryParams: [],\n body: true,\n multipart: true,\n binary: false,\n anonymous: false\n }),\n get: operation<\"assets.get\">(request, {\n method: \"get\",\n path: \"/assets/{assetID}\",\n pathParams: [\"assetID\"],\n queryParams: [\"entryID\"],\n body: false,\n multipart: false,\n binary: false,\n anonymous: false\n })\n },\n instance: {\n get: operation<\"instance.get\">(request, {\n method: \"get\",\n path: \"/instance\",\n pathParams: [],\n queryParams: [],\n body: false,\n multipart: false,\n binary: false,\n anonymous: false\n })\n },\n entries: {\n create: operation<\"entries.create\">(request, {\n method: \"post\",\n path: \"/entries\",\n pathParams: [],\n queryParams: [],\n body: true,\n multipart: false,\n binary: false,\n anonymous: false\n }),\n bulkDelete: operation<\"entries.bulkDelete\">(request, {\n method: \"post\",\n path: \"/entries/bulk/delete\",\n pathParams: [],\n queryParams: [],\n body: true,\n multipart: false,\n binary: false,\n anonymous: false\n }),\n delete: operation<\"entries.delete\">(request, {\n method: \"delete\",\n path: \"/entries/{id}\",\n pathParams: [\"id\"],\n queryParams: [],\n body: false,\n multipart: false,\n binary: false,\n anonymous: false\n }),\n update: operation<\"entries.update\">(request, {\n method: \"put\",\n path: \"/entries/{id}\",\n pathParams: [\"id\"],\n queryParams: [],\n body: true,\n multipart: false,\n binary: false,\n anonymous: false\n }),\n get: operation<\"entries.get\">(request, {\n method: \"get\",\n path: \"/entries/get\",\n pathParams: [],\n queryParams: [\"id\", \"path\", \"expectedSchemaHash\"],\n body: false,\n multipart: false,\n binary: false,\n anonymous: false\n }),\n list: operation<\"entries.list\">(request, {\n method: \"get\",\n path: \"/entries/list\",\n pathParams: [],\n queryParams: [\"collectionID\", \"collectionPath\", \"cursor\", \"limit\"],\n body: false,\n multipart: false,\n binary: false,\n anonymous: false\n })\n },\n collections: {\n create: operation<\"collections.create\">(request, {\n method: \"post\",\n path: \"/collections\",\n pathParams: [],\n queryParams: [],\n body: true,\n multipart: false,\n binary: false,\n anonymous: false\n }),\n bulkDelete: operation<\"collections.bulkDelete\">(request, {\n method: \"post\",\n path: \"/collections/bulk/delete\",\n pathParams: [],\n queryParams: [],\n body: true,\n multipart: false,\n binary: false,\n anonymous: false\n }),\n delete: operation<\"collections.delete\">(request, {\n method: \"delete\",\n path: \"/collections/{id}\",\n pathParams: [\"id\"],\n queryParams: [],\n body: false,\n multipart: false,\n binary: false,\n anonymous: false\n }),\n update: operation<\"collections.update\">(request, {\n method: \"put\",\n path: \"/collections/{id}\",\n pathParams: [\"id\"],\n queryParams: [],\n body: true,\n multipart: false,\n binary: false,\n anonymous: false\n }),\n list: operation<\"collections.list\">(request, {\n method: \"get\",\n path: \"/collections/list\",\n pathParams: [],\n queryParams: [\"collectionID\", \"collectionPath\", \"cursor\", \"limit\"],\n body: false,\n multipart: false,\n binary: false,\n anonymous: false\n })\n },\n content: {\n listCollections: operation<\"content.listCollections\">(request, {\n method: \"get\",\n path: \"/content/collections\",\n pathParams: [],\n queryParams: [\"cursor\", \"limit\", \"collectionID\", \"collectionPath\", \"channel\", \"snapshotID\"],\n body: false,\n multipart: false,\n binary: false,\n anonymous: false\n }),\n listEntries: operation<\"content.listEntries\">(request, {\n method: \"get\",\n path: \"/content/entries\",\n pathParams: [],\n queryParams: [\n \"cursor\",\n \"limit\",\n \"collectionID\",\n \"collectionPath\",\n \"channel\",\n \"snapshotID\",\n \"descendants\",\n \"includeContent\",\n \"filters\"\n ],\n body: false,\n multipart: false,\n binary: false,\n anonymous: false\n }),\n getSchema: operation<\"content.getSchema\">(request, {\n method: \"get\",\n path: \"/content/entries/schema\",\n pathParams: [],\n queryParams: [\"entryID\", \"path\", \"channel\", \"snapshotID\"],\n body: false,\n multipart: false,\n binary: false,\n anonymous: false\n }),\n getAsset: operation<\"content.getAsset\">(request, {\n method: \"get\",\n path: \"/content/assets/{workspaceID}/{snapshotID}/{entryID}/{assetID}/{variant}\",\n pathParams: [\"workspaceID\", \"snapshotID\", \"entryID\", \"assetID\", \"variant\"],\n queryParams: [],\n body: false,\n multipart: false,\n binary: true,\n anonymous: true\n }),\n get: operation<\"content.get\">(request, {\n method: \"get\",\n path: \"/content/entries/get\",\n pathParams: [],\n queryParams: [\"entryID\", \"path\", \"expectedSchemaHash\", \"channel\", \"snapshotID\"],\n body: false,\n multipart: false,\n binary: false,\n anonymous: false\n }),\n getTree: operation<\"content.getTree\">(request, {\n method: \"get\",\n path: \"/content/tree\",\n pathParams: [],\n queryParams: [\"collectionID\", \"collectionPath\", \"channel\", \"snapshotID\"],\n body: false,\n multipart: false,\n binary: false,\n anonymous: false\n })\n },\n roles: {\n list: operation<\"roles.list\">(request, {\n method: \"get\",\n path: \"/roles\",\n pathParams: [],\n queryParams: [],\n body: false,\n multipart: false,\n binary: false,\n anonymous: false\n }),\n create: operation<\"roles.create\">(request, {\n method: \"post\",\n path: \"/roles\",\n pathParams: [],\n queryParams: [],\n body: true,\n multipart: false,\n binary: false,\n anonymous: false\n }),\n update: operation<\"roles.update\">(request, {\n method: \"put\",\n path: \"/roles/{id}\",\n pathParams: [\"id\"],\n queryParams: [],\n body: true,\n multipart: false,\n binary: false,\n anonymous: false\n }),\n delete: operation<\"roles.delete\">(request, {\n method: \"delete\",\n path: \"/roles/{id}\",\n pathParams: [\"id\"],\n queryParams: [],\n body: false,\n multipart: false,\n binary: false,\n anonymous: false\n })\n },\n search: {\n current: operation<\"search.current\">(request, {\n method: \"post\",\n path: \"/search/current\",\n pathParams: [],\n queryParams: [],\n body: true,\n multipart: false,\n binary: false,\n anonymous: false\n }),\n published: operation<\"search.published\">(request, {\n method: \"post\",\n path: \"/search/published\",\n pathParams: [],\n queryParams: [],\n body: true,\n multipart: false,\n binary: false,\n anonymous: false\n }),\n askCurrent: operation<\"search.askCurrent\">(request, {\n method: \"post\",\n path: \"/search/current/ask\",\n pathParams: [],\n queryParams: [],\n body: true,\n multipart: false,\n binary: false,\n anonymous: false\n }),\n askPublished: operation<\"search.askPublished\">(request, {\n method: \"post\",\n path: \"/search/published/ask\",\n pathParams: [],\n queryParams: [],\n body: true,\n multipart: false,\n binary: false,\n anonymous: false\n }),\n askCurrentStream: operation<\"search.askCurrentStream\">(request, {\n streaming: true,\n method: \"post\",\n path: \"/search/current/ask/stream\",\n pathParams: [],\n queryParams: [],\n body: true,\n multipart: false,\n binary: false,\n anonymous: false\n }),\n askPublishedStream: operation<\"search.askPublishedStream\">(request, {\n streaming: true,\n method: \"post\",\n path: \"/search/published/ask/stream\",\n pathParams: [],\n queryParams: [],\n body: true,\n multipart: false,\n binary: false,\n anonymous: false\n })\n },\n schemas: {\n create: operation<\"schemas.create\">(request, {\n method: \"post\",\n path: \"/collections/{collectionID}/schema\",\n pathParams: [\"collectionID\"],\n queryParams: [],\n body: false,\n multipart: false,\n binary: false,\n anonymous: false\n }),\n delete: operation<\"schemas.delete\">(request, {\n method: \"delete\",\n path: \"/schemas/{schemaID}\",\n pathParams: [\"schemaID\"],\n queryParams: [],\n body: true,\n multipart: false,\n binary: false,\n anonymous: false\n }),\n getRevision: operation<\"schemas.getRevision\">(request, {\n method: \"get\",\n path: \"/schema-revisions/{revisionID}\",\n pathParams: [\"revisionID\"],\n queryParams: [],\n body: false,\n multipart: false,\n binary: false,\n anonymous: false\n }),\n get: operation<\"schemas.get\">(request, {\n method: \"get\",\n path: \"/schemas/collection\",\n pathParams: [],\n queryParams: [\"collectionID\", \"collectionPath\"],\n body: false,\n multipart: false,\n binary: false,\n anonymous: false\n }),\n apply: operation<\"schemas.apply\">(request, {\n method: \"post\",\n path: \"/schemas/{schemaID}/apply\",\n pathParams: [\"schemaID\"],\n queryParams: [],\n body: true,\n multipart: false,\n binary: false,\n anonymous: false\n })\n },\n schemaMigrations: {\n listContentLossEntries: operation<\"schemaMigrations.listContentLossEntries\">(request, {\n method: \"get\",\n path: \"/schema-migrations/{id}/content-loss-entries\",\n pathParams: [\"id\"],\n queryParams: [\"cursor\", \"limit\"],\n body: false,\n multipart: false,\n binary: false,\n anonymous: false\n }),\n getActive: operation<\"schemaMigrations.getActive\">(request, {\n method: \"get\",\n path: \"/collections/{collectionID}/schema-migration\",\n pathParams: [\"collectionID\"],\n queryParams: [],\n body: false,\n multipart: false,\n binary: false,\n anonymous: false\n }),\n get: operation<\"schemaMigrations.get\">(request, {\n method: \"get\",\n path: \"/schema-migrations/{id}\",\n pathParams: [\"id\"],\n queryParams: [],\n body: false,\n multipart: false,\n binary: false,\n anonymous: false\n })\n },\n schemaVersions: {\n list: operation<\"schemaVersions.list\">(request, {\n method: \"get\",\n path: \"/schemas/{schemaID}/versions\",\n pathParams: [\"schemaID\"],\n queryParams: [\"cursor\", \"limit\"],\n body: false,\n multipart: false,\n binary: false,\n anonymous: false\n }),\n get: operation<\"schemaVersions.get\">(request, {\n method: \"get\",\n path: \"/schema-versions/{id}\",\n pathParams: [\"id\"],\n queryParams: [],\n body: false,\n multipart: false,\n binary: false,\n anonymous: false\n }),\n update: operation<\"schemaVersions.update\">(request, {\n method: \"patch\",\n path: \"/schema-versions/{id}\",\n pathParams: [\"id\"],\n queryParams: [],\n body: true,\n multipart: false,\n binary: false,\n anonymous: false\n }),\n revert: operation<\"schemaVersions.revert\">(request, {\n method: \"post\",\n path: \"/schema-versions/{id}/revert\",\n pathParams: [\"id\"],\n queryParams: [],\n body: true,\n multipart: false,\n binary: false,\n anonymous: false\n })\n },\n memberships: {\n list: operation<\"memberships.list\">(request, {\n method: \"get\",\n path: \"/memberships\",\n pathParams: [],\n queryParams: [\"cursor\", \"limit\"],\n body: false,\n multipart: false,\n binary: false,\n anonymous: false\n }),\n invite: operation<\"memberships.invite\">(request, {\n method: \"post\",\n path: \"/memberships\",\n pathParams: [],\n queryParams: [],\n body: true,\n multipart: false,\n binary: false,\n anonymous: false\n }),\n update: operation<\"memberships.update\">(request, {\n method: \"patch\",\n path: \"/memberships/{id}\",\n pathParams: [\"id\"],\n queryParams: [],\n body: true,\n multipart: false,\n binary: false,\n anonymous: false\n }),\n remove: operation<\"memberships.remove\">(request, {\n method: \"delete\",\n path: \"/memberships/{id}\",\n pathParams: [\"id\"],\n queryParams: [],\n body: false,\n multipart: false,\n binary: false,\n anonymous: false\n }),\n listInvites: operation<\"memberships.listInvites\">(request, {\n method: \"get\",\n path: \"/memberships/invites\",\n pathParams: [],\n queryParams: [\"cursor\", \"limit\"],\n body: false,\n multipart: false,\n binary: false,\n anonymous: false\n }),\n resendInvite: operation<\"memberships.resendInvite\">(request, {\n method: \"post\",\n path: \"/memberships/invites/{id}/resend\",\n pathParams: [\"id\"],\n queryParams: [],\n body: false,\n multipart: false,\n binary: false,\n anonymous: false\n }),\n revokeInvite: operation<\"memberships.revokeInvite\">(request, {\n method: \"delete\",\n path: \"/memberships/invites/{id}\",\n pathParams: [\"id\"],\n queryParams: [],\n body: false,\n multipart: false,\n binary: false,\n anonymous: false\n })\n },\n publishing: {\n setCollection: operation<\"publishing.setCollection\">(request, {\n method: \"put\",\n path: \"/publishing/collections/{collectionID}\",\n pathParams: [\"collectionID\"],\n queryParams: [],\n body: true,\n multipart: false,\n binary: false,\n anonymous: false\n }),\n publishCollection: operation<\"publishing.publishCollection\">(request, {\n method: \"post\",\n path: \"/publishing/collections/{collectionID}\",\n pathParams: [\"collectionID\"],\n queryParams: [],\n body: true,\n multipart: false,\n binary: false,\n anonymous: false\n }),\n unpublishCollection: operation<\"publishing.unpublishCollection\">(request, {\n method: \"delete\",\n path: \"/publishing/collections/{collectionID}\",\n pathParams: [\"collectionID\"],\n queryParams: [],\n body: true,\n multipart: false,\n binary: false,\n anonymous: false\n }),\n bulkSetCollections: operation<\"publishing.bulkSetCollections\">(request, {\n method: \"post\",\n path: \"/publishing/collections/bulk/set\",\n pathParams: [],\n queryParams: [],\n body: true,\n multipart: false,\n binary: false,\n anonymous: false\n }),\n bulkPublishCollections: operation<\"publishing.bulkPublishCollections\">(request, {\n method: \"post\",\n path: \"/publishing/collections/bulk/publish\",\n pathParams: [],\n queryParams: [],\n body: true,\n multipart: false,\n binary: false,\n anonymous: false\n }),\n bulkUnpublishCollections: operation<\"publishing.bulkUnpublishCollections\">(request, {\n method: \"post\",\n path: \"/publishing/collections/bulk/unpublish\",\n pathParams: [],\n queryParams: [],\n body: true,\n multipart: false,\n binary: false,\n anonymous: false\n }),\n publishEntry: operation<\"publishing.publishEntry\">(request, {\n method: \"post\",\n path: \"/publishing/entries/{entryID}\",\n pathParams: [\"entryID\"],\n queryParams: [],\n body: true,\n multipart: false,\n binary: false,\n anonymous: false\n }),\n unpublishEntry: operation<\"publishing.unpublishEntry\">(request, {\n method: \"delete\",\n path: \"/publishing/entries/{entryID}\",\n pathParams: [\"entryID\"],\n queryParams: [],\n body: true,\n multipart: false,\n binary: false,\n anonymous: false\n }),\n bulkPublishEntries: operation<\"publishing.bulkPublishEntries\">(request, {\n method: \"post\",\n path: \"/publishing/entries/bulk/publish\",\n pathParams: [],\n queryParams: [],\n body: true,\n multipart: false,\n binary: false,\n anonymous: false\n }),\n bulkUnpublishEntries: operation<\"publishing.bulkUnpublishEntries\">(request, {\n method: \"post\",\n path: \"/publishing/entries/bulk/unpublish\",\n pathParams: [],\n queryParams: [],\n body: true,\n multipart: false,\n binary: false,\n anonymous: false\n }),\n revertChanges: operation<\"publishing.revertChanges\">(request, {\n method: \"post\",\n path: \"/publishing/changes/revert\",\n pathParams: [],\n queryParams: [],\n body: true,\n multipart: false,\n binary: false,\n anonymous: false\n }),\n getEntryVersion: operation<\"publishing.getEntryVersion\">(request, {\n method: \"get\",\n path: \"/publishing/entries/{entryID}/version\",\n pathParams: [\"entryID\"],\n queryParams: [\"channel\", \"expectedSchemaHash\", \"snapshotID\"],\n body: false,\n multipart: false,\n binary: false,\n anonymous: false\n }),\n listEntryPublications: operation<\"publishing.listEntryPublications\">(request, {\n method: \"get\",\n path: \"/publishing/entries/{entryID}/publications\",\n pathParams: [\"entryID\"],\n queryParams: [],\n body: false,\n multipart: false,\n binary: false,\n anonymous: false\n }),\n listChannels: operation<\"publishing.listChannels\">(request, {\n method: \"get\",\n path: \"/publishing/channels\",\n pathParams: [],\n queryParams: [\"includeAssignmentCount\"],\n body: false,\n multipart: false,\n binary: false,\n anonymous: false\n }),\n createChannel: operation<\"publishing.createChannel\">(request, {\n method: \"post\",\n path: \"/publishing/channels\",\n pathParams: [],\n queryParams: [],\n body: true,\n multipart: false,\n binary: false,\n anonymous: false\n }),\n getChannelContent: operation<\"publishing.getChannelContent\">(request, {\n method: \"get\",\n path: \"/publishing/channels/{channel}/content\",\n pathParams: [\"channel\"],\n queryParams: [\"collectionID\"],\n body: false,\n multipart: false,\n binary: false,\n anonymous: false\n }),\n deleteChannel: operation<\"publishing.deleteChannel\">(request, {\n method: \"delete\",\n path: \"/publishing/channels/{code}\",\n pathParams: [\"code\"],\n queryParams: [],\n body: true,\n multipart: false,\n binary: false,\n anonymous: false\n })\n },\n versions: {\n create: operation<\"versions.create\">(request, {\n method: \"post\",\n path: \"/entries/{entryID}/versions\",\n pathParams: [\"entryID\"],\n queryParams: [],\n body: true,\n multipart: false,\n binary: false,\n anonymous: false\n }),\n list: operation<\"versions.list\">(request, {\n method: \"get\",\n path: \"/entries/{entryID}/versions\",\n pathParams: [\"entryID\"],\n queryParams: [\"cursor\", \"limit\"],\n body: false,\n multipart: false,\n binary: false,\n anonymous: false\n }),\n get: operation<\"versions.get\">(request, {\n method: \"get\",\n path: \"/versions/{id}\",\n pathParams: [\"id\"],\n queryParams: [\"expectedSchemaHash\"],\n body: false,\n multipart: false,\n binary: false,\n anonymous: false\n }),\n update: operation<\"versions.update\">(request, {\n method: \"patch\",\n path: \"/versions/{id}\",\n pathParams: [\"id\"],\n queryParams: [],\n body: true,\n multipart: false,\n binary: false,\n anonymous: false\n }),\n revert: operation<\"versions.revert\">(request, {\n method: \"post\",\n path: \"/versions/{id}/revert\",\n pathParams: [\"id\"],\n queryParams: [],\n body: false,\n multipart: false,\n binary: false,\n anonymous: false\n })\n }\n});\n\nexport { createResources };\nexport type { APIResources };\n","const wait = (delay: number, signal: AbortSignal): Promise<void> => {\n signal.throwIfAborted();\n\n return new Promise((resolve, reject) => {\n const abort = () => {\n clearTimeout(timer);\n reject(signal.reason);\n };\n const timer = setTimeout(() => {\n signal.removeEventListener(\"abort\", abort);\n resolve();\n }, delay);\n\n signal.addEventListener(\"abort\", abort, { once: true });\n });\n};\nconst retryDelay = (attempt: number, response?: Response): number => {\n const value = response?.headers.get(\"Retry-After\");\n const seconds = value === null || value === undefined ? NaN : Number(value);\n const date = value ? Date.parse(value) : NaN;\n\n if (Number.isFinite(seconds)) return Math.max(0, seconds * 1000);\n if (Number.isFinite(date)) return Math.max(0, date - Date.now());\n\n return Math.min(1000 * 2 ** attempt, 30_000) + Math.random() * 250;\n};\nconst fetchWithRetries = async (\n fetcher: typeof fetch,\n request: Request,\n retries: number\n): Promise<Response> => {\n const signal = request.signal;\n\n for (let attempt = 0; ; attempt += 1) {\n let response: Response;\n\n signal.throwIfAborted();\n\n try {\n response = await fetcher(request.clone());\n } catch (error) {\n if (signal.aborted || attempt >= retries || !(error instanceof TypeError)) {\n throw error;\n }\n\n await wait(retryDelay(attempt), signal);\n continue;\n }\n\n if (attempt >= retries || ![429, 500, 502, 503, 504].includes(response.status)) {\n return response;\n }\n\n const delay = retryDelay(attempt, response);\n\n await response.body?.cancel();\n await wait(delay, signal);\n }\n};\n\nexport { fetchWithRetries };\n","import { createAnswerStream } from \"./answer-stream\";\nimport { createContentClient, type ContentClient } from \"./content-client\";\nimport { serializeQuery } from \"./query\";\nimport createFetchClient from \"openapi-fetch\";\nimport { AndesineAPIError } from \"./error\";\nimport { createResources, type APIResources } from \"./generated/resources\";\nimport { fetchWithRetries } from \"./retry\";\nimport type { OperationDefinition, RequestOptions } from \"./operation\";\n\ninterface AndesineClient extends APIResources {\n content: ContentClient;\n /**\n * Bind published-content reads and pagination to an existing snapshot.\n * @param snapshotID - Snapshot ID returned by a published-content response.\n * @returns Content methods, including snapshot-aware entry and collection iterators.\n * No request is made until a method is called or an iterator is consumed.\n * @throws TypeError if a later request supplies a channel or a different snapshot ID.\n */\n atSnapshot(snapshotID: string): ContentClient;\n}\ninterface ClientOptions {\n /** HTTP(S) API root, including any deployment prefix. Defaults to https://api.andesine.app. */\n baseURL?: string;\n /**\n * Bearer API key. Defaults to process.env.ANDESINE_API_KEY when available, read at creation.\n * Pass an empty string to disable this fallback. Keep private keys on your server;\n * the key is omitted on anonymous operations.\n */\n apiKey?: string;\n /** Fetch implementation to use instead of globalThis.fetch. */\n fetch?: typeof fetch;\n /** Default headers. Request headers override these; apiKey supplies Authorization. */\n headers?: HeadersInit;\n /** Timeout in milliseconds, including stream consumption. Defaults to 30,000; 0 disables it. */\n timeout?: number;\n /** Extra attempts for eligible GET failures. Defaults to 0. Other methods are never retried. */\n retries?: number;\n}\ninterface RuntimeEnvironment {\n process?: { env?: { ANDESINE_API_KEY?: string } };\n}\ninterface RuntimeOperation {\n parameters: { path: Record<string, unknown>; query: Record<string, unknown> };\n requestBody?: { content: { \"application/json\": unknown } };\n responses: { 200: { content: { \"application/json\": unknown } } };\n}\n\ntype RuntimePaths = Record<\n string,\n Record<\"get\" | \"post\" | \"put\" | \"patch\" | \"delete\", RuntimeOperation>\n>;\n\n/**\n * Create a typed API client for a hosted or self-hosted Andesine instance.\n *\n * Methods return response data by default. Use response: \"full\" for status and headers,\n * including conditional reads that can return 304. Creation does not make a request.\n * @param config - Optional API root, credentials, transport, and request defaults.\n * Defaults to https://api.andesine.app and process.env.ANDESINE_API_KEY when available.\n * Runtimes without process.env use no default key. No environment files are loaded.\n * @returns API resources and helpers for published-content snapshots and pagination.\n * @throws TypeError if baseURL is not HTTP(S) or includes credentials, a query, or a fragment.\n * Request failures throw AndesineAPIError; abort and timeout reasons are preserved.\n * @example\n * const client = createClient();\n * const page = await client.content.get({ path: \"/Docs/Welcome\" });\n */\nconst createClient = (config: ClientOptions = {}): AndesineClient => {\n const baseURL = (config.baseURL ?? \"https://api.andesine.app\").replace(/\\/+$/, \"\");\n const apiKey = config.apiKey ?? (globalThis as RuntimeEnvironment).process?.env?.ANDESINE_API_KEY;\n const url = new URL(baseURL);\n const fetcher = config.fetch ?? globalThis.fetch;\n\n if (\n ![\"http:\", \"https:\"].includes(url.protocol) ||\n url.search ||\n url.hash ||\n url.username ||\n url.password\n ) {\n throw new TypeError(\"baseURL must be an HTTP(S) URL without credentials, query, or fragment\");\n }\n\n const request = async (\n definition: OperationDefinition,\n input: Record<string, unknown>,\n options: RequestOptions = {}\n ) => {\n const controller = new AbortController();\n const signal = options.signal\n ? AbortSignal.any([controller.signal, options.signal])\n : controller.signal;\n const timeout = options.timeout ?? config.timeout ?? 30_000;\n const retries = options.retries ?? config.retries ?? 0;\n const headers = new Headers(config.headers);\n const path = Object.fromEntries(definition.pathParams.map((key) => [key, input[key]]));\n const query = Object.fromEntries(definition.queryParams.map((key) => [key, input[key]]));\n const body = Object.fromEntries(\n Object.entries(input).filter(\n ([key]) => !definition.pathParams.includes(key) && !definition.queryParams.includes(key)\n )\n );\n const client = createFetchClient<RuntimePaths>({\n baseUrl: baseURL,\n querySerializer: serializeQuery\n });\n\n if (!Number.isFinite(timeout) || timeout < 0 || !Number.isInteger(retries) || retries < 0) {\n throw new TypeError(\"timeout and retries must be nonnegative; retries must be an integer\");\n }\n if (query.channel !== undefined && query.snapshotID !== undefined) {\n throw new TypeError(\"Use either channel or snapshotID, not both\");\n }\n\n for (const key of definition.pathParams) {\n if (input[key] === undefined || input[key] === null) {\n throw new TypeError(`Missing path parameter: ${key}`);\n }\n }\n\n new Headers(options.headers).forEach((value, key) => headers.set(key, value));\n\n if (definition.streaming && !headers.has(\"Accept\")) {\n headers.set(\"Accept\", \"text/event-stream\");\n }\n\n if (apiKey && !definition.anonymous) {\n headers.set(\"Authorization\", `Bearer ${apiKey}`);\n }\n\n const timer =\n timeout > 0\n ? setTimeout(\n () => controller.abort(new DOMException(\"Request timed out\", \"TimeoutError\")),\n timeout\n )\n : undefined;\n\n let streamOwnsRequest = false;\n\n try {\n const result = await client.request(\n definition.method as keyof RuntimePaths[string],\n definition.path,\n {\n params: { path, query },\n headers,\n signal,\n body: definition.body ? body : undefined,\n parseAs: \"stream\",\n bodySerializer: definition.multipart\n ? (value) => {\n const form = new FormData();\n\n for (const [key, item] of Object.entries(value as Record<string, unknown>)) {\n if (item instanceof Blob) {\n form.append(key, item);\n } else if (item !== undefined) {\n form.append(key, typeof item === \"string\" ? item : JSON.stringify(item));\n }\n }\n\n return form;\n }\n : undefined,\n fetch: (request) =>\n fetchWithRetries(fetcher, request, definition.method === \"get\" ? retries : 0)\n }\n );\n\n const response = result.response;\n\n if (response.status === 304) {\n if (options.response !== \"full\") {\n throw new TypeError(\"Use response: 'full' for conditional requests that can return 304\");\n }\n\n return { status: 304, headers: response.headers, data: undefined, notModified: true };\n }\n if (!response.ok) throw new AndesineAPIError(response, result.error);\n\n if (definition.streaming) {\n const data = createAnswerStream(response, {\n signal,\n cancel: () => controller.abort(),\n cleanup: () => {\n if (timer !== undefined) clearTimeout(timer);\n }\n });\n\n streamOwnsRequest = true;\n\n return options.response === \"full\"\n ? { status: response.status, headers: response.headers, data, notModified: false }\n : data;\n }\n\n const text = definition.binary || response.status === 204 ? undefined : await response.text();\n const data = definition.binary ? await response.blob() : text ? JSON.parse(text) : undefined;\n\n return options.response === \"full\"\n ? { status: response.status, headers: response.headers, data, notModified: false }\n : data;\n } finally {\n if (!streamOwnsRequest && timer !== undefined) clearTimeout(timer);\n }\n };\n const resources = createResources(request);\n\n return {\n ...resources,\n content: createContentClient(resources.content),\n atSnapshot(snapshotID: string) {\n return createContentClient(\n createResources((definition, input, options) => {\n const pinned =\n definition.path.startsWith(\"/content/\") &&\n definition.queryParams.includes(\"snapshotID\");\n\n if (\n pinned &&\n (input.channel !== undefined ||\n (input.snapshotID !== undefined && input.snapshotID !== snapshotID))\n ) {\n throw new TypeError(\"Cannot override a pinned snapshot\");\n }\n\n return request(definition, pinned ? { ...input, snapshotID } : input, options);\n }).content\n );\n }\n };\n};\n\nexport { createClient };\nexport type { AndesineClient, ClientOptions };\n","/** A decoded canonical path, optionally with a decoded heading anchor. */\ninterface ContentLocation {\n path: string;\n anchor?: string;\n}\ninterface ContentURLOptions {\n /** Decoded collection prefix to remove, matched on whole segments. Defaults to \"/\". */\n rootPath?: string;\n /**\n * Destination root: a root-relative URL such as \"/docs\", or an absolute HTTP(S) URL.\n * Its pathname is retained as a prefix. Queries, fragments, and credentials are not allowed.\n * Defaults to \"/\". Supply this as a URL; its pathname may already be percent-encoded.\n */\n baseURL?: string;\n}\n\n/**\n * Convert a canonical Andesine path or search/citation location to a website URL.\n *\n * Encodes each decoded path segment and anchor without changing case or deriving slugs.\n * This is a pure function: it does not resolve IDs, fetch content, or pin a snapshot.\n * @param source - An absolute decoded path (starting with /), or an object with path and anchor.\n * Collection-ID-relative selectors must first be resolved through the API to a canonical path.\n * @param options - Source collection root and destination URL prefix.\n * @returns A root-relative URL by default, or an absolute URL when baseURL is absolute.\n * The source root itself maps to the destination root without adding a trailing slash.\n * @throws TypeError for invalid paths, a source outside rootPath, or an invalid baseURL.\n * @example\n * toContentURL({ path: \"/Docs/Getting started\", anchor: \"install\" }, {\n * rootPath: \"/Docs\", baseURL: \"/docs\"\n * }); // \"/docs/Getting%20started#install\"\n */\nconst toContentURL = (\n source: string | ContentLocation,\n options: ContentURLOptions = {}\n): string => {\n const location = typeof source === \"string\" ? { path: source } : source;\n const segments = contentPathSegments(location.path);\n const root = contentPathSegments(options.rootPath ?? \"/\");\n const outsideRoot = root.some((segment, index) => segments[index] !== segment);\n const baseURL = options.baseURL ?? \"/\";\n const relative = baseURL.startsWith(\"/\") && !baseURL.startsWith(\"//\");\n const url = new URL(baseURL, relative ? \"https://andesine.invalid\" : undefined);\n const invalidBase =\n ![\"http:\", \"https:\"].includes(url.protocol) ||\n Boolean(url.search || url.hash || url.username || url.password) ||\n baseURL.includes(\"\\\\\");\n\n if (outsideRoot) throw new TypeError(\"Content path is outside rootPath\");\n if (invalidBase) {\n throw new TypeError(\n \"baseURL must be a root-relative or HTTP(S) URL without credentials, query, or fragment\"\n );\n }\n\n const suffix = segments.slice(root.length).map(encodeURIComponent).join(\"/\");\n const prefix = url.pathname.replace(/\\/+$/, \"\");\n\n url.pathname = (suffix ? `${prefix}/${suffix}` : prefix) || \"/\";\n url.hash = location.anchor ? encodeURIComponent(location.anchor) : \"\";\n\n return relative ? `${url.pathname}${url.hash}` : url.href;\n};\n\nconst contentPathSegments = (path: string): string[] => {\n const segments = path === \"/\" ? [] : path.slice(1).split(\"/\");\n const invalid =\n !path.startsWith(\"/\") ||\n segments.some((segment) => !segment || segment === \".\" || segment === \"..\");\n\n if (invalid) {\n throw new TypeError(\"Use an absolute decoded content path without empty or dot segments\");\n }\n\n return segments;\n};\n\nexport { toContentURL };\nexport type { ContentLocation, ContentURLOptions };\n","interface StructuredContentSource {\n properties: Readonly<Record<string, { readonly value: unknown }>>;\n fragments: Readonly<Record<string, { readonly content: unknown }>>;\n}\n\ntype StructuredContent<T extends StructuredContentSource> = Omit<T, \"properties\" | \"fragments\"> & {\n properties: { [Key in keyof T[\"properties\"]]: T[\"properties\"][Key][\"value\"] };\n fragments: { [Key in keyof T[\"fragments\"]]: T[\"fragments\"][Key][\"content\"] };\n};\n\n/**\n * Unwrap property values and fragment documents for use in application code.\n *\n * @param page - Full entry content with properties and fragments, including published list items.\n * @returns A new object with property.value and fragment.content exposed by key. Other fields,\n * including schema metadata and assets, are preserved. Nested content is shared, not cloned.\n * This helper does not validate content, convert formats, or infer collection-specific types.\n * @example\n * const tutorial = toStructuredContent(page);\n * const body = tutorial.fragments.body;\n * const enabled = tutorial.properties.enabled;\n */\nconst toStructuredContent = <T extends StructuredContentSource>(page: T): StructuredContent<T> =>\n ({\n ...page,\n properties: Object.fromEntries(\n Object.entries(page.properties).map(([key, property]) => [key, property.value])\n ),\n fragments: Object.fromEntries(\n Object.entries(page.fragments).map(([key, fragment]) => [key, fragment.content])\n )\n }) as StructuredContent<T>;\n\nexport { toStructuredContent };\nexport type { StructuredContent, StructuredContentSource };\n"],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { Vo as components, zi as AnswerEvent } from "./index-DFEcYmbh.js";
|
|
2
|
+
//#region src/streaming.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* Read typed answer events from an Andesine SSE response or a forwarded toAnswerResponse().
|
|
5
|
+
*
|
|
6
|
+
* @param response - An unconsumed Fetch response. Its body must use Andesine/oRPC SSE framing.
|
|
7
|
+
* @param options - Optional cancellation signal. Breaking iteration also closes the reader.
|
|
8
|
+
* @returns An iterator of sources, textDelta, and completed events; no automatic reconnection.
|
|
9
|
+
* Consume or close the iterator to release the response body.
|
|
10
|
+
* @throws AndesineAPIError for HTTP errors, AndesineStreamError for API error frames, or
|
|
11
|
+
* AndesineStreamProtocolError for invalid/incomplete streams. Abort reasons are preserved.
|
|
12
|
+
*/
|
|
13
|
+
declare const readAnswerStream: (response: Response, options?: {
|
|
14
|
+
signal?: AbortSignal;
|
|
15
|
+
}) => Promise<AsyncIterableIterator<{
|
|
16
|
+
type: "sources";
|
|
17
|
+
sources: components["schemas"]["AnswerSource"][];
|
|
18
|
+
} | {
|
|
19
|
+
type: "textDelta";
|
|
20
|
+
text: string;
|
|
21
|
+
} | {
|
|
22
|
+
answer: string;
|
|
23
|
+
sources: components["schemas"]["AnswerSource"][];
|
|
24
|
+
type: "completed";
|
|
25
|
+
}>>;
|
|
26
|
+
/**
|
|
27
|
+
* Forward answer events as a Fetch Response from your server to a browser.
|
|
28
|
+
*
|
|
29
|
+
* @param events - The iterator returned by an answer stream method, or equivalent typed events.
|
|
30
|
+
* @returns An SSE response with caching and proxy buffering disabled. It preserves backpressure
|
|
31
|
+
* and cancellation without copying upstream credentials or headers. API errors become typed
|
|
32
|
+
* error frames; other failures become generic error frames. A completed event is required.
|
|
33
|
+
* Handle errors that occur while opening the upstream stream in your route's error handler.
|
|
34
|
+
* @example
|
|
35
|
+
* const events = await client.search.askPublishedStream({ question });
|
|
36
|
+
* return toAnswerResponse(events);
|
|
37
|
+
*/
|
|
38
|
+
declare const toAnswerResponse: (events: AsyncIterable<AnswerEvent>) => Response;
|
|
39
|
+
//#endregion
|
|
40
|
+
export { readAnswerStream, toAnswerResponse };
|
|
41
|
+
//# sourceMappingURL=streaming.d.ts.map
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { n as AndesineAPIError, t as createAnswerStream } from "./answer-stream-7N_gLhVS.js";
|
|
2
|
+
import { encodeEventMessage } from "@orpc/standard-server";
|
|
3
|
+
//#region src/streaming.ts
|
|
4
|
+
/**
|
|
5
|
+
* Read typed answer events from an Andesine SSE response or a forwarded toAnswerResponse().
|
|
6
|
+
*
|
|
7
|
+
* @param response - An unconsumed Fetch response. Its body must use Andesine/oRPC SSE framing.
|
|
8
|
+
* @param options - Optional cancellation signal. Breaking iteration also closes the reader.
|
|
9
|
+
* @returns An iterator of sources, textDelta, and completed events; no automatic reconnection.
|
|
10
|
+
* Consume or close the iterator to release the response body.
|
|
11
|
+
* @throws AndesineAPIError for HTTP errors, AndesineStreamError for API error frames, or
|
|
12
|
+
* AndesineStreamProtocolError for invalid/incomplete streams. Abort reasons are preserved.
|
|
13
|
+
*/
|
|
14
|
+
const readAnswerStream = async (response, options = {}) => {
|
|
15
|
+
if (!response.ok) {
|
|
16
|
+
const text = await response.text();
|
|
17
|
+
let body = text;
|
|
18
|
+
try {
|
|
19
|
+
body = JSON.parse(text);
|
|
20
|
+
} catch {}
|
|
21
|
+
throw new AndesineAPIError(response, body);
|
|
22
|
+
}
|
|
23
|
+
return createAnswerStream(response, options);
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Forward answer events as a Fetch Response from your server to a browser.
|
|
27
|
+
*
|
|
28
|
+
* @param events - The iterator returned by an answer stream method, or equivalent typed events.
|
|
29
|
+
* @returns An SSE response with caching and proxy buffering disabled. It preserves backpressure
|
|
30
|
+
* and cancellation without copying upstream credentials or headers. API errors become typed
|
|
31
|
+
* error frames; other failures become generic error frames. A completed event is required.
|
|
32
|
+
* Handle errors that occur while opening the upstream stream in your route's error handler.
|
|
33
|
+
* @example
|
|
34
|
+
* const events = await client.search.askPublishedStream({ question });
|
|
35
|
+
* return toAnswerResponse(events);
|
|
36
|
+
*/
|
|
37
|
+
const toAnswerResponse = (events) => {
|
|
38
|
+
const iterator = events[Symbol.asyncIterator]();
|
|
39
|
+
const encoder = new TextEncoder();
|
|
40
|
+
let cancelled = false;
|
|
41
|
+
let completed = false;
|
|
42
|
+
const body = new ReadableStream({
|
|
43
|
+
async pull(controller) {
|
|
44
|
+
try {
|
|
45
|
+
const result = await iterator.next();
|
|
46
|
+
if (cancelled) return;
|
|
47
|
+
if (result.done) {
|
|
48
|
+
if (!completed) throw new Error("Incomplete answer stream");
|
|
49
|
+
controller.close();
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
if (result.value.type === "completed") completed = true;
|
|
53
|
+
controller.enqueue(encoder.encode(encodeEventMessage({
|
|
54
|
+
event: "message",
|
|
55
|
+
data: JSON.stringify(result.value)
|
|
56
|
+
})));
|
|
57
|
+
} catch (error) {
|
|
58
|
+
if (cancelled) return;
|
|
59
|
+
const data = error instanceof AndesineAPIError ? {
|
|
60
|
+
defined: error.defined,
|
|
61
|
+
code: error.code,
|
|
62
|
+
status: error.status,
|
|
63
|
+
message: error.message,
|
|
64
|
+
data: error.data
|
|
65
|
+
} : {
|
|
66
|
+
defined: false,
|
|
67
|
+
code: "INTERNAL_SERVER_ERROR",
|
|
68
|
+
status: 500,
|
|
69
|
+
message: "The answer stream could not be completed"
|
|
70
|
+
};
|
|
71
|
+
controller.enqueue(encoder.encode(encodeEventMessage({
|
|
72
|
+
event: "error",
|
|
73
|
+
data: JSON.stringify(data)
|
|
74
|
+
})));
|
|
75
|
+
controller.close();
|
|
76
|
+
await iterator.return?.();
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
async cancel() {
|
|
80
|
+
cancelled = true;
|
|
81
|
+
await iterator.return?.();
|
|
82
|
+
}
|
|
83
|
+
}, { highWaterMark: 0 });
|
|
84
|
+
return new Response(body, { headers: {
|
|
85
|
+
"Content-Type": "text/event-stream; charset=utf-8",
|
|
86
|
+
"Cache-Control": "private, no-store, no-transform",
|
|
87
|
+
"X-Accel-Buffering": "no"
|
|
88
|
+
} });
|
|
89
|
+
};
|
|
90
|
+
//#endregion
|
|
91
|
+
export { readAnswerStream, toAnswerResponse };
|
|
92
|
+
|
|
93
|
+
//# sourceMappingURL=streaming.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"streaming.js","names":[],"sources":["../src/streaming.ts"],"sourcesContent":["import { encodeEventMessage } from \"@orpc/standard-server\";\nimport type { AnswerEvent } from \"./generated/schema\";\nimport { AndesineAPIError } from \"./error\";\nimport { createAnswerStream } from \"./answer-stream\";\n\n/**\n * Read typed answer events from an Andesine SSE response or a forwarded toAnswerResponse().\n *\n * @param response - An unconsumed Fetch response. Its body must use Andesine/oRPC SSE framing.\n * @param options - Optional cancellation signal. Breaking iteration also closes the reader.\n * @returns An iterator of sources, textDelta, and completed events; no automatic reconnection.\n * Consume or close the iterator to release the response body.\n * @throws AndesineAPIError for HTTP errors, AndesineStreamError for API error frames, or\n * AndesineStreamProtocolError for invalid/incomplete streams. Abort reasons are preserved.\n */\nconst readAnswerStream = async (response: Response, options: { signal?: AbortSignal } = {}) => {\n if (!response.ok) {\n const text = await response.text();\n let body: unknown = text;\n try {\n body = JSON.parse(text);\n } catch {\n /* Keep non-JSON error responses. */\n }\n throw new AndesineAPIError(response, body);\n }\n return createAnswerStream(response, options);\n};\n\n/**\n * Forward answer events as a Fetch Response from your server to a browser.\n *\n * @param events - The iterator returned by an answer stream method, or equivalent typed events.\n * @returns An SSE response with caching and proxy buffering disabled. It preserves backpressure\n * and cancellation without copying upstream credentials or headers. API errors become typed\n * error frames; other failures become generic error frames. A completed event is required.\n * Handle errors that occur while opening the upstream stream in your route's error handler.\n * @example\n * const events = await client.search.askPublishedStream({ question });\n * return toAnswerResponse(events);\n */\nconst toAnswerResponse = (events: AsyncIterable<AnswerEvent>): Response => {\n const iterator = events[Symbol.asyncIterator]();\n const encoder = new TextEncoder();\n\n let cancelled = false;\n let completed = false;\n\n const body = new ReadableStream<Uint8Array>(\n {\n async pull(controller) {\n try {\n const result = await iterator.next();\n\n if (cancelled) return;\n if (result.done) {\n if (!completed) throw new Error(\"Incomplete answer stream\");\n\n controller.close();\n return;\n }\n\n if (result.value.type === \"completed\") {\n completed = true;\n }\n\n controller.enqueue(\n encoder.encode(\n encodeEventMessage({ event: \"message\", data: JSON.stringify(result.value) })\n )\n );\n } catch (error) {\n if (cancelled) return;\n\n const data =\n error instanceof AndesineAPIError\n ? {\n defined: error.defined,\n code: error.code,\n status: error.status,\n message: error.message,\n data: error.data\n }\n : {\n defined: false,\n code: \"INTERNAL_SERVER_ERROR\",\n status: 500,\n message: \"The answer stream could not be completed\"\n };\n\n controller.enqueue(\n encoder.encode(encodeEventMessage({ event: \"error\", data: JSON.stringify(data) }))\n );\n controller.close();\n\n await iterator.return?.();\n }\n },\n async cancel() {\n cancelled = true;\n\n await iterator.return?.();\n }\n },\n { highWaterMark: 0 }\n );\n\n return new Response(body, {\n headers: {\n \"Content-Type\": \"text/event-stream; charset=utf-8\",\n \"Cache-Control\": \"private, no-store, no-transform\",\n \"X-Accel-Buffering\": \"no\"\n }\n });\n};\n\nexport { toAnswerResponse, readAnswerStream };\n"],"mappings":";;;;;;;;;;;;;AAeA,MAAM,mBAAmB,OAAO,UAAoB,UAAoC,CAAC,MAAM;CAC7F,IAAI,CAAC,SAAS,IAAI;EAChB,MAAM,OAAO,MAAM,SAAS,KAAK;EACjC,IAAI,OAAgB;EACpB,IAAI;GACF,OAAO,KAAK,MAAM,IAAI;EACxB,QAAQ,CAER;EACA,MAAM,IAAI,iBAAiB,UAAU,IAAI;CAC3C;CACA,OAAO,mBAAmB,UAAU,OAAO;AAC7C;;;;;;;;;;;;;AAcA,MAAM,oBAAoB,WAAiD;CACzE,MAAM,WAAW,OAAO,OAAO,cAAc,CAAC;CAC9C,MAAM,UAAU,IAAI,YAAY;CAEhC,IAAI,YAAY;CAChB,IAAI,YAAY;CAEhB,MAAM,OAAO,IAAI,eACf;EACE,MAAM,KAAK,YAAY;GACrB,IAAI;IACF,MAAM,SAAS,MAAM,SAAS,KAAK;IAEnC,IAAI,WAAW;IACf,IAAI,OAAO,MAAM;KACf,IAAI,CAAC,WAAW,MAAM,IAAI,MAAM,0BAA0B;KAE1D,WAAW,MAAM;KACjB;IACF;IAEA,IAAI,OAAO,MAAM,SAAS,aACxB,YAAY;IAGd,WAAW,QACT,QAAQ,OACN,mBAAmB;KAAE,OAAO;KAAW,MAAM,KAAK,UAAU,OAAO,KAAK;IAAE,CAAC,CAC7E,CACF;GACF,SAAS,OAAO;IACd,IAAI,WAAW;IAEf,MAAM,OACJ,iBAAiB,mBACb;KACE,SAAS,MAAM;KACf,MAAM,MAAM;KACZ,QAAQ,MAAM;KACd,SAAS,MAAM;KACf,MAAM,MAAM;IACd,IACA;KACE,SAAS;KACT,MAAM;KACN,QAAQ;KACR,SAAS;IACX;IAEN,WAAW,QACT,QAAQ,OAAO,mBAAmB;KAAE,OAAO;KAAS,MAAM,KAAK,UAAU,IAAI;IAAE,CAAC,CAAC,CACnF;IACA,WAAW,MAAM;IAEjB,MAAM,SAAS,SAAS;GAC1B;EACF;EACA,MAAM,SAAS;GACb,YAAY;GAEZ,MAAM,SAAS,SAAS;EAC1B;CACF,GACA,EAAE,eAAe,EAAE,CACrB;CAEA,OAAO,IAAI,SAAS,MAAM,EACxB,SAAS;EACP,gBAAgB;EAChB,iBAAiB;EACjB,qBAAqB;CACvB,EACF,CAAC;AACH"}
|