@deadair/sdk 0.71.0 → 0.72.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/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/sdk-options.ts","../src/activity/types/activity.types.ts","../src/activity/activity.client.ts","../src/art/art.client.ts","../src/authentication/types/authentication.types.ts","../src/authentication/authentication.apikeys.client.ts","../src/authentication/types/registration.types.ts","../src/authentication/authentication.factor.client.ts","../src/authentication/authentication.sessions.client.ts","../src/authentication/authentication.client.ts","../src/catalog/types/catalog.types.ts","../src/catalog/catalog.client.ts","../src/charts/charts.client.ts","../src/director/types/rules.types.ts","../src/director/director.client.ts","../src/events/types/events.types.ts","../src/events/events.client.ts","../src/history/types/history.types.ts","../src/history/history.client.ts","../src/languages/types/languages.types.ts","../src/languages/languages.client.ts","../src/messaging/types/messaging.types.ts","../src/messaging/messaging.client.ts","../src/metrics/types/metrics.types.ts","../src/metrics/metrics.client.ts","../src/narrations/narrations.client.ts","../src/news/news.client.ts","../src/nowplaying/nowplaying.client.ts","../src/oauth/types/oauth.types.ts","../src/oauth/oauth.client.ts","../src/onboarding/onboarding.client.ts","../src/outputs/types/outputs.types.ts","../src/outputs/outputs.client.ts","../src/personas/personas.client.ts","../src/playlists/types/playlists.types.ts","../src/playlists/types/station.playlists.types.ts","../src/playlists/playlists.client.ts","../src/playout/playout.client.ts","../src/plugins/types/plugins.types.ts","../src/plugins/plugins.client.ts","../src/productions/types/productions.types.ts","../src/podcasts/types/podcasts.types.ts","../src/podcasts/podcasts.client.ts","../src/productions/productions.client.ts","../src/render/types/render.types.ts","../src/render/render.client.ts","../src/requests/types/requests.types.ts","../src/requests/requests.party.client.ts","../src/requests/requests.client.ts","../src/schedule/schedule.client.ts","../src/settings/settings.client.ts","../src/station/types/logs.types.ts","../src/station/types/station.types.ts","../src/station/types/traces.types.ts","../src/station/station.client.ts","../src/storage/types/storage.types.ts","../src/storage/storage.client.ts","../src/stream/stream.client.ts","../src/topics/topics.client.ts","../src/users/types/users.types.ts","../src/users/types/invitations.types.ts","../src/users/invitations.client.ts","../src/users/users.client.ts","../src/deadair.sdk.ts"],"sourcesContent":["export class SdkError<TBody = unknown> extends Error {\n constructor(\n public readonly status: number,\n public readonly statusText: string,\n public readonly body: TBody,\n public readonly headers: Headers,\n ) {\n super(`${status} ${statusText}`);\n this.name = 'SdkError';\n }\n}\n\nexport interface SdkRequestInit extends RequestInit {\n /**\n * Statuses this operation declares as values rather than errors — a 304 from\n * conditional-GET middleware, or an error status the service returns deliberately.\n * Anything else at or above 400 still throws SdkError.\n */\n expectStatuses?: number[];\n}\n\nexport type SdkFetch = (url: string, init: SdkRequestInit) => Promise<Response>;\n\nexport interface SdkOptions {\n baseUrl: string;\n headers?: Record<string, string> | (() => Record<string, string> | Promise<Record<string, string>>);\n fetch?: SdkFetch;\n /** Called once per request to produce a unique X-Request-ID header value */\n requestIdFactory?: () => string;\n}\n\nexport const bigIntReplacer = (_: string, value: any): any => {\n if (typeof value === 'bigint') {\n return value.toString() + 'n';\n }\n return value;\n};\n\nexport const bigIntReviver = (_: string, value: any): any => {\n if (typeof value === 'string' && /^-?\\d+n$/.test(value)) {\n return BigInt(value.slice(0, -1));\n }\n return value;\n};\n\nexport type JsonValue = string | number | boolean | null | JsonValue[] | { [key: string]: JsonValue };\n\nexport function readContentType(res: Response): string {\n return res.headers.get('content-type')?.split(';')[0]?.trim() ?? '';\n}\n\n/** A v4 UUID. `crypto.randomUUID` exists only in a secure context, so plain HTTP builds one by hand. */\nfunction randomRequestId(): string {\n if (typeof crypto.randomUUID === 'function') return crypto.randomUUID();\n const bytes = crypto.getRandomValues(new Uint8Array(16));\n bytes[6] = (bytes[6]! & 0x0f) | 0x40;\n bytes[8] = (bytes[8]! & 0x3f) | 0x80;\n const hex = Array.from(bytes, b => b.toString(16).padStart(2, '0')).join('');\n return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;\n}\n\nexport function createSdkFetch(options: SdkOptions): SdkFetch {\n const getRequestId = options.requestIdFactory ?? randomRequestId;\n return async (url: string, init: SdkRequestInit): Promise<Response> => {\n const baseHeaders = typeof options.headers === 'function' ? await options.headers() : (options.headers ?? {});\n const res = await fetch(`${options.baseUrl}${url}`, {\n ...init,\n headers: { ...baseHeaders, 'X-Request-ID': getRequestId(), ...(init.headers as Record<string, string>) },\n });\n if (!res.ok && !(init.expectStatuses ?? []).includes(res.status)) {\n const text = await res.text();\n let body: unknown;\n try {\n body = JSON.parse(text);\n } catch {\n body = text;\n }\n throw new SdkError(res.status, res.statusText, body, res.headers);\n }\n return res;\n };\n}\n\nexport function buildQueryString(query: object | undefined): string {\n const searchParams = new URLSearchParams();\n if (query) {\n for (const [k, v] of Object.entries(query)) {\n if (v === undefined || v === null) continue;\n if (Array.isArray(v)) {\n for (const item of v) searchParams.append(k, String(item));\n } else searchParams.set(k, String(v));\n }\n }\n const qs = searchParams.toString();\n return qs ? `?${qs}` : '';\n}\n\nexport function buildHeaders(headers: object | undefined): Record<string, string> {\n const out: Record<string, string> = {};\n if (headers) {\n for (const [k, v] of Object.entries(headers)) {\n if (v === undefined || v === null) continue;\n out[k] = Array.isArray(v) ? v.map(String).join(', ') : String(v);\n }\n }\n return out;\n}\n\nexport function parseBigIntHeader(name: string, value: string): bigint {\n if (/^-?\\d+n?$/.test(value)) return BigInt(value.replace(/n$/, ''));\n throw new Error(`Response header '${name}' is not a bigint: ${JSON.stringify(value)}`);\n}\n\n/** Per-call options for an operation that streams Server-Sent Events. */\nexport interface SseRequestOptions {\n /** Aborts the request. An iteration in progress rejects with the abort reason. */\n signal?: AbortSignal;\n /** Resume after this event id, sent as Last-Event-ID. Usually an earlier stream's lastEventId. */\n lastEventId?: string;\n}\n\n/**\n * The events of one Server-Sent Events response, parsed as they arrive. Iterate it once with\n * for await; leaving the loop early closes the connection.\n */\nexport interface SseEventStream<T> extends AsyncIterable<T> {\n /** The id of the most recent event that carried one, to resume from with SseRequestOptions.lastEventId. */\n readonly lastEventId: string | undefined;\n}\n\n/** The request headers a streaming call sends: Accept, plus Last-Event-ID when resuming. */\nexport function sseRequestHeaders(options: SseRequestOptions | undefined): Record<string, string> {\n const headers: Record<string, string> = { Accept: 'text/event-stream' };\n if (options?.lastEventId !== undefined) headers['Last-Event-ID'] = options.lastEventId;\n return headers;\n}\n\n/**\n * Parse a text/event-stream response into its events. Data lines are joined with newlines and\n * dispatched on a blank line; comments and other fields are skipped; an event cut off by the end\n * of the stream is dropped. Each event's data goes through parse, JSON.parse by default.\n */\nexport function parseSse<T>(res: Response, parse: (data: string) => T = data => JSON.parse(data) as T): SseEventStream<T> {\n let lastEventId: string | undefined;\n let iterated = false;\n async function* events(): AsyncGenerator<T> {\n if (!res.body) return;\n const reader = res.body.pipeThrough(new TextDecoderStream()).getReader();\n let buffer = '';\n let data: string[] = [];\n try {\n for (;;) {\n const chunk = await reader.read();\n if (!chunk.done) buffer += chunk.value;\n for (;;) {\n const end = buffer.search(/\\r\\n|\\r|\\n/);\n // A trailing CR may be the first half of a CRLF split across two reads, unless\n // this was the last read.\n if (end === -1 || (!chunk.done && end === buffer.length - 1 && buffer[end] === '\\r')) break;\n const line = buffer.slice(0, end);\n buffer = buffer.slice(buffer.startsWith('\\r\\n', end) ? end + 2 : end + 1);\n if (line === '') {\n if (data.length > 0) yield parse(data.join('\\n'));\n data = [];\n continue;\n }\n const colon = line.indexOf(':');\n const field = colon === -1 ? line : line.slice(0, colon);\n const value = colon === -1 ? '' : line.slice(line.startsWith(' ', colon + 1) ? colon + 2 : colon + 1);\n if (field === 'data') data.push(value);\n else if (field === 'id' && !value.includes('\\0')) lastEventId = value;\n }\n if (chunk.done) return;\n }\n } finally {\n await reader.cancel().catch(() => undefined);\n }\n }\n return {\n get lastEventId() {\n return lastEventId;\n },\n [Symbol.asyncIterator]() {\n if (iterated) throw new Error('An SseEventStream can be iterated only once');\n iterated = true;\n return events();\n },\n };\n}\n\n/**\n * Read a JSON response body.\n *\n * No reviver: `bigIntReviver` matches any string of the form `123n` anywhere in the\n * document, so a contract with no bigint field would still have a legitimate string like\n * \"123n\" silently turned into a BigInt. Clients whose contracts do use bigint import\n * `parseJsonWithBigInt` under this name instead.\n */\nexport async function parseJson<T>(res: Response): Promise<T> {\n return JSON.parse(await res.text()) as T;\n}\n\n/** `parseJson` for contracts that declare a bigint, applying the `123n` reviver. */\nexport async function parseJsonWithBigInt<T>(res: Response): Promise<T> {\n return JSON.parse(await res.text(), bigIntReviver) as T;\n}\n","import { DateTime } from 'luxon';\nconst __dt = (v: unknown, path: string): DateTime => {\n if (typeof v !== 'string') {\n throw new TypeError(`ContractKit: expected an ISO 8601 string at '${path}', received ${typeof v}.`);\n }\n const d = DateTime.fromISO(v);\n if (!d.isValid) throw new TypeError(`ContractKit: '${v}' at '${path}' is not a valid ISO 8601 datetime.`);\n return d;\n};\n\n/**\n * Which part of the station an entry came from, and the console's one filter axis\n * generated from [ActivityModule](../../../../../apps/api/data/contracts/activity/activity.types.ck)\n */\nexport type ActivityModule = 'playout' | 'director' | 'render' | 'catalog' | 'plugins' | 'storage' | 'events';\n\n/**\n * How an entry reads, not how bad it is. There is deliberately no `waiting`: a station idling for\n * want of a listener says so in its own words and stays `info`, for the same reason the transport\n * reports it as `ready` rather than as a mild fault\n * generated from [ActivitySeverity](../../../../../apps/api/data/contracts/activity/activity.types.ck)\n */\nexport type ActivitySeverity = 'info' | 'warn' | 'fault';\n\n/**\n * One thing that happened, from whichever of the feed's sources holds it\n * generated from [ActivityEntry](../../../../../apps/api/data/contracts/activity/activity.types.ck)\n */\nexport interface ActivityEntry {\n /** Unique across the whole feed, and half of the cursor below */\n id: string;\n /** When it happened, as the database recorded it */\n at: DateTime;\n module: ActivityModule;\n /** Dotted and stable: `silence.cause`, `air.on`, `segment.ready`, `track.aired`. What a console draws a line with, never something a decision is made on */\n kind: string;\n severity: ActivitySeverity;\n /** The sentence a person reads, phrased by whatever produced it */\n detail: string;\n /** The structured half, for a reader that wants to filter or chart rather than read */\n data?: Record<string, unknown>;\n /** The segment this is about, for an entry that came from one */\n segmentId?: string;\n /** The catalog track this is about, for an entry that came from one */\n trackId?: string;\n}\n\n/** Rehydrates every wire-encoded scalar in a ActivityEntry into its runtime type. Mutates and returns `raw`. */\nexport function reviveActivityEntry(raw: ActivityEntry): ActivityEntry {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['at'] = __dt(__o0['at'], 'ActivityEntry.at');\n return raw;\n}\n\n/**\n * One page of the feed, newest first\n * generated from [ActivityQuery](../../../../../apps/api/data/contracts/activity/activity.types.ck)\n */\nexport interface ActivityQuery {\n limit?: number;\n /** Where the previous page ended. Opaque, and a keyset rather than an offset because rows arrive at the head continuously: an offset would re-show a row on every page as the feed grew under it. Pass back whatever `nextBefore` said and nothing else */\n before?: string;\n module?: ActivityModule;\n /** The floor, not the exact match: `warn` answers with warnings and faults. Absent is everything */\n minSeverity?: ActivitySeverity;\n}\n\n/**\n * generated from [ActivityPage](../../../../../apps/api/data/contracts/activity/activity.types.ck)\n */\nexport interface ActivityPage {\n entries: ActivityEntry[];\n /** The cursor for the page after this one, absent once the feed has been read to its end */\n nextBefore?: string;\n}\n\n/** Rehydrates every wire-encoded scalar in a ActivityPage into its runtime type. Mutates and returns `raw`. */\nexport function reviveActivityPage(raw: ActivityPage): ActivityPage {\n const __o0 = raw as unknown as Record<string, unknown>;\n {\n const __a1 = __o0['entries'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveActivityEntry(__a1[__i2] as never);\n }\n }\n return raw;\n}\n","import type { SdkFetch } from '../sdk-options.js';\nimport { parseJson, buildQueryString } from '../sdk-options.js';\nimport type { ActivityPage, ActivityQuery } from './types/activity.types.js';\nimport { reviveActivityPage } from './types/activity.types.js';\n\nexport class ActivityClient {\n constructor(private fetch: SdkFetch) {}\n\n /**\n * @name Read activity\n * @description The feed, newest first, one page at a time\n */\n async readActivity(query?: ActivityQuery): Promise<ActivityPage> {\n const qs = buildQueryString(query);\n const result = await this.fetch(`/activity${qs}`, {\n method: 'GET',\n });\n return reviveActivityPage(await parseJson<ActivityPage>(result));\n }\n}\n","import type { SdkFetch } from '../sdk-options.js';\nimport { parseJson, readContentType } from '../sdk-options.js';\nimport type { BreakArtworkList, PersonaPortraitList } from './types/art.types.js';\n\nexport class ArtClient {\n constructor(private fetch: SdkFetch) {}\n\n /**\n * @name List break artwork\n * @description Every kind the station holds a picture for\n */\n async listBreakArtwork(): Promise<BreakArtworkList> {\n const result = await this.fetch(`/art/breaks`, { method: 'GET' });\n return await parseJson<BreakArtworkList>(result);\n }\n\n /**\n * @name Replace break artwork\n * @description Puts an operator's own picture behind a kind of break. The id does not change, so a URL already on the wire keeps working and the ETag is what says the picture moved\n */\n async replaceBreakArtwork(kind: string, body: FormData): Promise<BreakArtworkList> {\n const result = await this.fetch(`/art/breaks/${encodeURIComponent(kind)}`, {\n method: 'POST',\n body: body,\n });\n return await parseJson<BreakArtworkList>(result);\n }\n\n /**\n * @name Revert break artwork\n * @description Puts the picture this repository ships back. The shipped file is read at this moment rather than copied at install, so an upgrade that improved it is what comes back\n */\n async revertBreakArtwork(kind: string): Promise<BreakArtworkList> {\n const result = await this.fetch(`/art/breaks/${encodeURIComponent(kind)}`, { method: 'DELETE' });\n return await parseJson<BreakArtworkList>(result);\n }\n\n /**\n * @name Get source art\n * @description The bytes of a cover the station fetches on first ask, addressed by its sealed source\n */\n async getSourceArt(token: string): Promise<\n | {\n status: 200;\n contentType: 'image/jpeg' | 'image/png' | 'image/webp' | 'image/gif';\n data: Blob;\n headers: { cacheControl?: string; etag?: string };\n }\n | { status: 304 }\n > {\n const result = await this.fetch(`/art/source/${encodeURIComponent(token)}`, {\n method: 'GET',\n expectStatuses: [304],\n });\n switch (result.status) {\n case 304:\n return { status: 304 };\n default:\n return {\n status: 200,\n contentType: readContentType(result) as 'image/jpeg' | 'image/png' | 'image/webp' | 'image/gif',\n data: await result.blob(),\n headers: { cacheControl: result.headers.get('cache-control') ?? undefined, etag: result.headers.get('etag') ?? undefined },\n };\n }\n }\n\n /**\n * @name Get source art file\n * @description The bytes of a cover the station fetches on first ask, under any filename\n */\n async getSourceArtFile(\n token: string,\n filename: string,\n ): Promise<\n | {\n status: 200;\n contentType: 'image/jpeg' | 'image/png' | 'image/webp' | 'image/gif';\n data: Blob;\n headers: { cacheControl?: string; etag?: string };\n }\n | { status: 304 }\n > {\n const result = await this.fetch(`/art/source/${encodeURIComponent(token)}/${encodeURIComponent(filename)}`, {\n method: 'GET',\n expectStatuses: [304],\n });\n switch (result.status) {\n case 304:\n return { status: 304 };\n default:\n return {\n status: 200,\n contentType: readContentType(result) as 'image/jpeg' | 'image/png' | 'image/webp' | 'image/gif',\n data: await result.blob(),\n headers: { cacheControl: result.headers.get('cache-control') ?? undefined, etag: result.headers.get('etag') ?? undefined },\n };\n }\n }\n\n /**\n * @name Get art\n * @description The bytes of one cached image, addressed by its id alone\n */\n async getArt(id: string): Promise<\n | {\n status: 200;\n contentType: 'image/jpeg' | 'image/png' | 'image/webp' | 'image/gif';\n data: Blob;\n headers: { cacheControl?: string; etag?: string };\n }\n | { status: 304 }\n > {\n const result = await this.fetch(`/art/${encodeURIComponent(id)}`, {\n method: 'GET',\n expectStatuses: [304],\n });\n switch (result.status) {\n case 304:\n return { status: 304 };\n default:\n return {\n status: 200,\n contentType: readContentType(result) as 'image/jpeg' | 'image/png' | 'image/webp' | 'image/gif',\n data: await result.blob(),\n headers: { cacheControl: result.headers.get('cache-control') ?? undefined, etag: result.headers.get('etag') ?? undefined },\n };\n }\n }\n\n /**\n * @name Get art file\n * @description The bytes of one cached image, under any filename\n */\n async getArtFile(\n id: string,\n filename: string,\n ): Promise<\n | {\n status: 200;\n contentType: 'image/jpeg' | 'image/png' | 'image/webp' | 'image/gif';\n data: Blob;\n headers: { cacheControl?: string; etag?: string };\n }\n | { status: 304 }\n > {\n const result = await this.fetch(`/art/${encodeURIComponent(id)}/${encodeURIComponent(filename)}`, {\n method: 'GET',\n expectStatuses: [304],\n });\n switch (result.status) {\n case 304:\n return { status: 304 };\n default:\n return {\n status: 200,\n contentType: readContentType(result) as 'image/jpeg' | 'image/png' | 'image/webp' | 'image/gif',\n data: await result.blob(),\n headers: { cacheControl: result.headers.get('cache-control') ?? undefined, etag: result.headers.get('etag') ?? undefined },\n };\n }\n }\n\n /**\n * @name List persona portraits\n * @description Every persona that has a portrait\n */\n async listPersonaPortraits(): Promise<PersonaPortraitList> {\n const result = await this.fetch(`/art/personas`, { method: 'GET' });\n return await parseJson<PersonaPortraitList>(result);\n }\n\n /**\n * @name Replace persona portrait\n * @description Puts a picture on a persona. A persona that already had one keeps its URL, so a player holding it picks up the new picture\n */\n async replacePersonaPortrait(personaId: string, body: FormData): Promise<PersonaPortraitList> {\n const result = await this.fetch(`/art/personas/${encodeURIComponent(personaId)}`, {\n method: 'POST',\n body: body,\n });\n return await parseJson<PersonaPortraitList>(result);\n }\n\n /**\n * @name Remove persona portrait\n * @description Takes a persona's picture away. A player shows the record's cover instead\n */\n async removePersonaPortrait(personaId: string): Promise<PersonaPortraitList> {\n const result = await this.fetch(`/art/personas/${encodeURIComponent(personaId)}`, { method: 'DELETE' });\n return await parseJson<PersonaPortraitList>(result);\n }\n}\n","import { DateTime } from 'luxon';\nconst __dt = (v: unknown, path: string): DateTime => {\n if (typeof v !== 'string') {\n throw new TypeError(`ContractKit: expected an ISO 8601 string at '${path}', received ${typeof v}.`);\n }\n const d = DateTime.fromISO(v);\n if (!d.isValid) throw new TypeError(`ContractKit: '${v}' at '${path}' is not a valid ISO 8601 datetime.`);\n return d;\n};\n\n/**\n * Denotes the authorization flow to use\n * generated from [AuthenticationGrantType](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport type AuthenticationGrantType = 'client_credentials' | 'password' | 'refresh_token' | 'link' | 'code' | 'fido' | 'authenticator' | 'oidc';\n\n/**\n * Denotes the authorization flow to use\n * generated from [PasswordlessAuthenticationGrantType](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport type PasswordlessAuthenticationGrantType = 'link' | 'code' | 'fido' | 'oidc';\n\n/**\n * The type of the factor\n * generated from [AuthenticationFactorMethod](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport type AuthenticationFactorMethod = 'phone' | 'password' | 'email' | 'authenticator' | 'fido' | 'oidc';\n\n/**\n * The kind of the factor\n * generated from [AuthenticationFactorKind](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport type AuthenticationFactorKind = 'knowledge' | 'possession' | 'biometric';\n\n/**\n * The name of an identity provider the station offers, as the operator set it under Settings, Sign-in and security. `GET /auth/login/oidc/providers` lists them\n * generated from [OidcProvider](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport type OidcProvider = string;\n\n/**\n * Represents an authentication token\n * generated from [AuthenticationToken](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface AuthenticationToken {\n /** The access token string as issued by the authorization server */\n accessToken: string;\n /** A refresh token which applications can use to obtain another access token */\n refreshToken?: string;\n /** Unix timestamp (seconds) when the access token expires */\n expiresIn: number;\n /** The type of token this is, typically just the string *Bearer* */\n tokenType: string;\n /** Space-separated list of scopes granted to this token */\n scope: string;\n}\n\nexport interface AuthenticationTokenOutput {\n /** The access token string as issued by the authorization server */\n access_token: string;\n /** A refresh token which applications can use to obtain another access token */\n refresh_token?: string;\n /** Unix timestamp (seconds) when the access token expires */\n expires_in: number;\n /** The type of token this is, typically just the string *Bearer* */\n token_type: string;\n /** Space-separated list of scopes granted to this token */\n scope: string;\n}\n\n/**\n * Issued-token arm of /auth/token response\n * generated from [AuthenticationTokenIssued](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface AuthenticationTokenIssued {\n /** Discriminator */\n result: 'token';\n /** The access token string as issued by the authorization server */\n accessToken: string;\n /** A refresh token which applications can use to obtain another access token */\n refreshToken?: string;\n /** Unix timestamp (seconds) when the access token expires */\n expiresIn: number;\n /** The type of token this is, typically just the string *Bearer* */\n tokenType: string;\n /** Space-separated list of scopes granted to this token */\n scope: string;\n}\n\nexport interface AuthenticationTokenIssuedOutput {\n /** Discriminator */\n result: 'token';\n /** The access token string as issued by the authorization server */\n access_token: string;\n /** A refresh token which applications can use to obtain another access token */\n refresh_token?: string;\n /** Unix timestamp (seconds) when the access token expires */\n expires_in: number;\n /** The type of token this is, typically just the string *Bearer* */\n token_type: string;\n /** Space-separated list of scopes granted to this token */\n scope: string;\n}\n\n/**\n * Returned by /auth/step-up/start when no enrolled factor satisfies the requirement. The SPA should drive the user through enrollment and retry the gated action afterwards.\n * generated from [EnrollmentRequiredResponse](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface EnrollmentRequiredResponse {\n /** Discriminator */\n result: 'enrollment_required';\n}\n\nexport interface EnrollmentRequiredResponseOutput {\n /** Discriminator */\n result: 'enrollment_required';\n}\n\n/**\n * Represents a common shape of a `PublicKeyCredential` after the client serializes the `id` and `rawId` fields to base64 strings for transport\n * generated from [PublicKeyCredential](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface PublicKeyCredential {\n /** The base64url encoding of `rawId` */\n id: string;\n /** This enumeration defines the valid credential types. It is an extension point; values can be added to it in the future, as more credential types are defined. The values of this enumeration are used for versioning the Authentication Assertion and attestation structures according to the type of the authenticator. Currently one credential type is defined, namely `public-key`. */\n type: 'public-key';\n /** The credential identifier */\n rawId: string;\n /** The authenticator attachment */\n authenticatorAttachment?: 'cross-platform' | 'platform';\n}\n\n/**\n * Subset of the WebAuthn client extension results the service round-trips\n * generated from [SimpleClientExtensionResults](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface SimpleClientExtensionResults {\n /** Whether the client is an application */\n appid?: boolean;\n /** Whether the client is excluded from appid verification */\n appidExclude?: boolean;\n credProps?: { rk: boolean };\n}\n\n/**\n * generated from [FidoAuthenticatorAssertionResponse](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface FidoAuthenticatorAssertionResponse {\n /** The client data JSON */\n clientDataJSON: string;\n /** The authenticator data */\n authenticatorData: string;\n /** The signature */\n signature: string;\n /** The user handle */\n userHandle?: string;\n}\n\n/**\n * generated from [AuthenticationRegistration](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface AuthenticationRegistration {\n /** The registration identifier */\n registrationId: string;\n /** The registration expiration timestamp */\n expiresAt: DateTime;\n}\n\nexport interface AuthenticationRegistrationInput {\n /** User's email address */\n email: string;\n /** optionally set a password for the user */\n password?: string;\n}\n\n/** Rehydrates every wire-encoded scalar in a AuthenticationRegistration into its runtime type. Mutates and returns `raw`. */\nexport function reviveAuthenticationRegistration(raw: AuthenticationRegistration): AuthenticationRegistration {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['expiresAt'] = __dt(__o0['expiresAt'], 'AuthenticationRegistration.expiresAt');\n return raw;\n}\n\n/**\n * generated from [AuthenticationRegistrationVerification](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface AuthenticationRegistrationVerification {\n /** The registration identifier */\n registrationId: string;\n /** The verification code */\n code: string;\n}\n\n/**\n * A credential the relying party expects the user to be able to present\n * generated from [PublicKeyCredentialDescriptor](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface PublicKeyCredentialDescriptor {\n /** The credential type — currently always `public-key` */\n type: 'public-key';\n /** The base64url-encoded credential identifier */\n id: string;\n /** Transports the authenticator advertises */\n transports?: ('usb' | 'nfc' | 'ble' | 'internal' | 'hybrid')[];\n}\n\n/**\n * The transport used by the authenticator\n * generated from [FidoAuthenticatorTransport](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport type FidoAuthenticatorTransport = 'hybrid' | 'ble' | 'internal' | 'nfc' | 'usb';\n\n/**\n * Request to complete an OIDC sign-in flow\n * generated from [OidcLoginCallback](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface OidcLoginCallback {\n /** The issuer of the token */\n iss?: string;\n /** The scope of the token */\n scope?: string;\n /** The user ID */\n authuser?: string;\n /** The host domain */\n hd?: string;\n /** The prompt of the token */\n prompt?: string;\n /** The authorization code returned by the IdP (absent when the IdP rejected the request) */\n code?: string;\n /** The opaque state token bound to the original authorize request */\n state?: string;\n /** OAuth 2.0 error code per RFC 6749 §4.1.2.1 (e.g. access_denied) */\n error?: string;\n /** Human-readable explanation of `error` */\n error_description?: string;\n /** URL to a page describing `error` */\n error_uri?: string;\n}\n\n/**\n * Issue a phone SMS challenge during a pending MFA round\n * generated from [FactorChallengePhoneStart](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface FactorChallengePhoneStart {\n /** Discriminator */\n method: 'phone';\n /** Delivery channel — only `sms` is supported in this phase */\n transport: 'sms';\n /** The MFA challenge to which this factor challenge is bound */\n mfa_challenge_id: string;\n}\n\n/**\n * Issue a WebAuthn assertion challenge during a pending MFA round\n * generated from [FactorChallengeFidoStart](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface FactorChallengeFidoStart {\n /** Discriminator */\n method: 'fido';\n /** The MFA challenge to which this factor challenge is bound */\n mfa_challenge_id: string;\n}\n\n/**\n * Issue an email one-time-code challenge during a pending MFA round. Always a code: a magic link cannot complete an MFA round, since the `code` grant that redeems one takes `code(min=6, max=10)` and a link token is 43 characters\n * generated from [FactorChallengeEmailStart](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface FactorChallengeEmailStart {\n /** Discriminator */\n method: 'email';\n /** The MFA challenge to which this factor challenge is bound */\n mfa_challenge_id: string;\n}\n\n/**\n * Response for a phone SMS challenge\n * generated from [FactorChallengePhoneStartResponse](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface FactorChallengePhoneStartResponse {\n /** Discriminator */\n method: 'phone';\n /** Echo of the chosen delivery channel */\n transport: 'sms';\n /** The phone-factor challenge id — echo back on the `code` grant as `challenge_id` */\n phoneChallengeId: string;\n /** When the phone challenge expires */\n expiresAt: DateTime;\n}\n\nexport interface FactorChallengePhoneStartResponseOutput {\n /** Discriminator */\n method: 'phone';\n /** Echo of the chosen delivery channel */\n transport: 'sms';\n /** The phone-factor challenge id — echo back on the `code` grant as `challenge_id` */\n phone_challenge_id: string;\n /** When the phone challenge expires */\n expires_at: DateTime;\n}\n\n/** Rehydrates every wire-encoded scalar in a FactorChallengePhoneStartResponse into its runtime type. Mutates and returns `raw`. */\nexport function reviveFactorChallengePhoneStartResponse(raw: FactorChallengePhoneStartResponse): FactorChallengePhoneStartResponse {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['expiresAt'] = __dt(__o0['expiresAt'], 'FactorChallengePhoneStartResponse.expiresAt');\n return raw;\n}\n\n/** Rehydrates every wire-encoded scalar in a FactorChallengePhoneStartResponseOutput into its runtime type. Mutates and returns `raw`. */\nexport function reviveFactorChallengePhoneStartResponseOutput(raw: FactorChallengePhoneStartResponseOutput): FactorChallengePhoneStartResponseOutput {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['expires_at'] = __dt(__o0['expires_at'], 'FactorChallengePhoneStartResponse.expires_at');\n return raw;\n}\n\n/**\n * Response for an email one-time-code challenge\n * generated from [FactorChallengeEmailStartResponse](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface FactorChallengeEmailStartResponse {\n /** Discriminator */\n method: 'email';\n /** The email-factor challenge id — echo back on the `code` grant as `challenge_id` */\n emailChallengeId: string;\n /** When the email challenge expires */\n expiresAt: DateTime;\n}\n\nexport interface FactorChallengeEmailStartResponseOutput {\n /** Discriminator */\n method: 'email';\n /** The email-factor challenge id — echo back on the `code` grant as `challenge_id` */\n email_challenge_id: string;\n /** When the email challenge expires */\n expires_at: DateTime;\n}\n\n/** Rehydrates every wire-encoded scalar in a FactorChallengeEmailStartResponse into its runtime type. Mutates and returns `raw`. */\nexport function reviveFactorChallengeEmailStartResponse(raw: FactorChallengeEmailStartResponse): FactorChallengeEmailStartResponse {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['expiresAt'] = __dt(__o0['expiresAt'], 'FactorChallengeEmailStartResponse.expiresAt');\n return raw;\n}\n\n/** Rehydrates every wire-encoded scalar in a FactorChallengeEmailStartResponseOutput into its runtime type. Mutates and returns `raw`. */\nexport function reviveFactorChallengeEmailStartResponseOutput(raw: FactorChallengeEmailStartResponseOutput): FactorChallengeEmailStartResponseOutput {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['expires_at'] = __dt(__o0['expires_at'], 'FactorChallengeEmailStartResponse.expires_at');\n return raw;\n}\n\n/**\n * A factor satisfied by the session\n * generated from [SessionFactor](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface SessionFactor {\n /** The verification method */\n method: 'phone' | 'password' | 'authenticator' | 'email' | 'fido' | 'oidc';\n /** Stable identifier for the specific factor record */\n methodId: string;\n /** MFA category for the factor */\n kind: 'knowledge' | 'possession' | 'biometric';\n /** When this factor entry was first added to the session */\n issuedAt: DateTime;\n /** When the factor was most recently re-verified */\n authenticatedAt: DateTime;\n}\n\nexport interface SessionFactorInput {\n /** The verification method */\n method: 'phone' | 'password' | 'authenticator' | 'email' | 'fido' | 'oidc';\n /** Stable identifier for the specific factor record */\n methodId: string;\n /** MFA category for the factor */\n kind: 'knowledge' | 'possession' | 'biometric';\n}\n\n/** Rehydrates every wire-encoded scalar in a SessionFactor into its runtime type. Mutates and returns `raw`. */\nexport function reviveSessionFactor(raw: SessionFactor): SessionFactor {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['issuedAt'] = __dt(__o0['issuedAt'], 'SessionFactor.issuedAt');\n __o0['authenticatedAt'] = __dt(__o0['authenticatedAt'], 'SessionFactor.authenticatedAt');\n return raw;\n}\n\n/**\n * Optional metadata supplied to a revoke action\n * generated from [SessionRevoke](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface SessionRevoke {\n /** Free-form reason recorded with the revoke */\n reason?: string | null;\n}\n\n/**\n * A platform-wide role held on `platform:main`. `admin` grants every operation; `listener` grants the reads\n * generated from [PlatformRole](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport type PlatformRole = 'admin' | 'listener';\n\n/**\n * A successful authentication record\n * generated from [Login](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface Login {\n /** The login event identifier */\n id: bigint;\n /** The actor that authenticated */\n actorId: string;\n /** The factor that satisfied the primary authentication, or `apikey` for a request made with one of the account's API keys */\n factorType: 'phone' | 'password' | 'authenticator' | 'email' | 'fido' | 'oidc' | 'apikey';\n /** The specific factor record id, when available */\n factorId?: string | null;\n /** The session minted at this login, when available */\n sessionToken?: string | null;\n /** Whether MFA was required and satisfied at login */\n mfaSatisfied: boolean;\n /** IP address recorded at login */\n ip?: string | null;\n /** User agent recorded at login */\n userAgent?: string | null;\n /** When the login occurred */\n occurredAt: DateTime;\n}\n\nexport interface LoginInput {}\n\n/** Rehydrates every wire-encoded scalar in a Login into its runtime type. Mutates and returns `raw`. */\nexport function reviveLogin(raw: Login): Login {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['occurredAt'] = __dt(__o0['occurredAt'], 'Login.occurredAt');\n return raw;\n}\n\n/**\n * The current user's display preferences, auto-detected by the SPA from the browser (Intl timezone + navigator.language). Omitted fields are left unchanged (absent = never set).\n * generated from [ActorPreferences](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface ActorPreferences {\n /** RFC 5646 locale, e.g. \"en-US\" */\n locale?: string;\n /** Olson timezone, e.g. \"America/New_York\" */\n timezone?: string;\n}\n\n/**\n * What an API key may be granted. `view` covers every route a listener may read; `manage` covers the rest, and includes `view`\n * generated from [ApiKeyScope](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport type ApiKeyScope = 'view' | 'manage';\n\n/**\n * generated from [BaseAuthenticationRequest](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface BaseAuthenticationRequest {\n /** The grant type for the request */\n grant_type: AuthenticationGrantType;\n /** The scope of the request */\n scope?: string;\n /** The application's client identifier, if available */\n client_id?: string;\n}\n\n/**\n * generated from [BaseAuthenticationLoginStart](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface BaseAuthenticationLoginStart {\n /** The grant type for the request */\n grant_type: PasswordlessAuthenticationGrantType;\n /** The application's client identifier, if available */\n client_id?: string;\n}\n\n/**\n * generated from [BaseAuthenticationLoginStartResponse](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface BaseAuthenticationLoginStartResponse {\n /** The grant type for the response */\n grant_type: PasswordlessAuthenticationGrantType;\n /** The challenge identifier */\n challengeId: string;\n /** The challenge expiration timestamp */\n expiresAt: DateTime;\n}\n\n/** Rehydrates every wire-encoded scalar in a BaseAuthenticationLoginStartResponse into its runtime type. Mutates and returns `raw`. */\nexport function reviveBaseAuthenticationLoginStartResponse(raw: BaseAuthenticationLoginStartResponse): BaseAuthenticationLoginStartResponse {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['expiresAt'] = __dt(__o0['expiresAt'], 'BaseAuthenticationLoginStartResponse.expiresAt');\n return raw;\n}\n\n/**\n * A factor the SPA may use to satisfy the MFA challenge\n * generated from [MfaChallengeFactor](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface MfaChallengeFactor {\n /** The factor method */\n method: AuthenticationFactorMethod;\n /** The id of the enrolled factor (opaque to the SPA, must be echoed back in the proof for methods that don't bind another way) */\n methodId: string;\n /** The factor kind (knowledge, possession, biometric) — the SPA filters against step-up `acceptableKinds`/`excludeKinds` hints */\n kind: AuthenticationFactorKind;\n /** Optional human-readable label (e.g. provider name for OIDC, friendly name for FIDO) */\n label?: string;\n}\n\nexport interface MfaChallengeFactorOutput {\n /** The factor method */\n method: AuthenticationFactorMethod;\n /** The id of the enrolled factor (opaque to the SPA, must be echoed back in the proof for methods that don't bind another way) */\n method_id: string;\n /** The factor kind (knowledge, possession, biometric) — the SPA filters against step-up `acceptableKinds`/`excludeKinds` hints */\n kind: AuthenticationFactorKind;\n /** Optional human-readable label (e.g. provider name for OIDC, friendly name for FIDO) */\n label?: string;\n}\n\n/**\n * generated from [AuthenticationFactor](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface AuthenticationFactor {\n /** The method of the factor */\n method: AuthenticationFactorMethod;\n /** The kind of the factor */\n kind: AuthenticationFactorKind;\n /** The method identifier */\n methodId: string;\n /** The label for the factor */\n label?: string;\n}\n\n/**\n * Mint a fresh MFA challenge for the current session so the SPA can satisfy a `step_up_required` denial. Filters mirror `StepUpRequirement` from `@maroonedsoftware/policies`.\n * generated from [StepUpStartRequest](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface StepUpStartRequest {\n /** If set, only these factor methods are listed as eligible */\n acceptableMethods?: AuthenticationFactorMethod[];\n /** If set, only these factor kinds are listed as eligible */\n acceptableKinds?: AuthenticationFactorKind[];\n /** If set, factors with these methods are never listed */\n excludeMethods?: AuthenticationFactorMethod[];\n}\n\n/**\n * An identity provider the sign-in page can offer\n * generated from [OidcProviderSummary](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface OidcProviderSummary {\n /** What to start a sign-in with */\n name: OidcProvider;\n /** What its button says */\n label: string;\n}\n\n/**\n * generated from [PublicKeyCredentialWithAssertion](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface PublicKeyCredentialWithAssertion extends PublicKeyCredential {\n /** The client extension results */\n clientExtensionResults: SimpleClientExtensionResults;\n /** The authenticator assertion response */\n response: FidoAuthenticatorAssertionResponse;\n}\n\n/**\n * generated from [FidoPublicKeyCredentialRequestOptions](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface FidoPublicKeyCredentialRequestOptions {\n challenge: string;\n /** WebAuthn timeout hint in milliseconds */\n timeout?: number;\n rpId?: string;\n /** The attestation */\n attestation?: 'direct' | 'indirect' | 'none';\n /** Whether the authenticator must verify the user */\n userVerification?: 'required' | 'preferred' | 'discouraged';\n /** The raw challenge */\n rawChallenge?: Blob;\n extensions?: Record<string, unknown>;\n allowCredentials?: PublicKeyCredentialDescriptor[];\n}\n\n/**\n * Serialized form of `AuthenticatorAttestationResponse` — produced by the browser at registration; all binary fields are base64-encoded for transport\n * generated from [FidoAuthenticatorAttestationResponse](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface FidoAuthenticatorAttestationResponse {\n /** The client data JSON */\n clientDataJSON: string;\n /** The attestation object */\n attestationObject: string;\n /** The transports used by the authenticator */\n transports?: FidoAuthenticatorTransport[];\n}\n\n/**\n * generated from [FactorChallengeStartRequest](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport type FactorChallengeStartRequest = FactorChallengePhoneStart | FactorChallengeFidoStart | FactorChallengeEmailStart;\n\n/**\n * An active authentication session\n * generated from [Session](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface Session {\n /** Opaque session token used as the cache key and embedded in JWTs */\n sessionToken: string;\n /** The actor that owns this session */\n actorId: string;\n /** When the session was originally issued */\n issuedAt: DateTime;\n /** When the session expires */\n expiresAt: DateTime;\n /** When the session was last accessed */\n lastAccessedAt: DateTime;\n /** Factors that have been satisfied in this session */\n factors: SessionFactor[];\n /** IP address recorded when the session was created */\n ip?: string | null;\n /** User agent recorded when the session was created */\n userAgent?: string | null;\n /** True when this session matches the requesting session */\n isCurrent: boolean;\n}\n\nexport interface SessionInput {}\n\n/** Rehydrates every wire-encoded scalar in a Session into its runtime type. Mutates and returns `raw`. */\nexport function reviveSession(raw: Session): Session {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['issuedAt'] = __dt(__o0['issuedAt'], 'Session.issuedAt');\n __o0['expiresAt'] = __dt(__o0['expiresAt'], 'Session.expiresAt');\n __o0['lastAccessedAt'] = __dt(__o0['lastAccessedAt'], 'Session.lastAccessedAt');\n {\n const __a1 = __o0['factors'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveSessionFactor(__a1[__i2] as never);\n }\n }\n return raw;\n}\n\n/**\n * Who the caller is, as the station sees them\n * generated from [AuthSession](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface AuthSession {\n /** The actor the session belongs to */\n actorId: string;\n /** Every platform role the caller holds, sorted. Empty for an account nobody has granted one, which today is any account that did not come in through onboarding */\n roles: PlatformRole[];\n}\n\n/**\n * A personal API key, as its owner sees it in a list. The token itself is never returned after it is issued\n * generated from [ApiKey](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface ApiKey {\n /** The key's identifier, for rotating or revoking it */\n id: string;\n /** What the account called the key */\n name: string;\n /** The token's first characters, enough to recognise the key in a config file and far too few to use */\n hint: string;\n /** What the key was granted. A key never does more than the account that owns it */\n scopes: ApiKeyScope[];\n /** When the key was issued */\n createdAt: DateTime;\n /** When the key stops working. Absent means it never expires */\n expiresAt?: DateTime;\n /** When the key was last used, to within five minutes. Absent means it has not been used */\n lastUsedAt?: DateTime;\n /** When the key was revoked. Present means every request made with it is refused */\n revokedAt?: DateTime;\n}\n\n/** Rehydrates every wire-encoded scalar in a ApiKey into its runtime type. Mutates and returns `raw`. */\nexport function reviveApiKey(raw: ApiKey): ApiKey {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['createdAt'] = __dt(__o0['createdAt'], 'ApiKey.createdAt');\n if (__o0['expiresAt'] != null) {\n __o0['expiresAt'] = __dt(__o0['expiresAt'], 'ApiKey.expiresAt');\n }\n if (__o0['lastUsedAt'] != null) {\n __o0['lastUsedAt'] = __dt(__o0['lastUsedAt'], 'ApiKey.lastUsedAt');\n }\n if (__o0['revokedAt'] != null) {\n __o0['revokedAt'] = __dt(__o0['revokedAt'], 'ApiKey.revokedAt');\n }\n return raw;\n}\n\n/**\n * A new API key\n * generated from [ApiKeyCreate](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface ApiKeyCreate {\n /** What to call the key, so a list of several says which is which */\n name: string;\n /** What the key may do. At least one; `manage` includes `view` */\n scopes: ApiKeyScope[];\n /** When the key should stop working. Omit for a key that never expires */\n expiresAt?: DateTime;\n}\n\n/** Rehydrates every wire-encoded scalar in a ApiKeyCreate into its runtime type. Mutates and returns `raw`. */\nexport function reviveApiKeyCreate(raw: ApiKeyCreate): ApiKeyCreate {\n const __o0 = raw as unknown as Record<string, unknown>;\n if (__o0['expiresAt'] != null) {\n __o0['expiresAt'] = __dt(__o0['expiresAt'], 'ApiKeyCreate.expiresAt');\n }\n return raw;\n}\n\n/**\n * Represents an application authentication request\n * generated from [ClientCredentialsAuthenticationRequest](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface ClientCredentialsAuthenticationRequest extends Omit<BaseAuthenticationRequest, 'grant_type' | 'client_id'> {\n /** The grant type for the request */\n grant_type: 'client_credentials';\n /** The client identifier */\n client_id: string;\n /** The client secret */\n client_secret: string;\n}\n\n/**\n * Represents an authentication password request\n * generated from [PasswordAuthenticationRequest](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface PasswordAuthenticationRequest extends Omit<BaseAuthenticationRequest, 'grant_type'> {\n /** The grant type for the request */\n grant_type: 'password';\n /** User's identifier, usually an email address */\n username: string;\n /** User's password */\n password: string;\n}\n\n/**\n * Represents an authentication refresh request\n * generated from [RefreshTokenAuthenticationRequest](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface RefreshTokenAuthenticationRequest extends Omit<BaseAuthenticationRequest, 'grant_type'> {\n /** The grant type for the request */\n grant_type: 'refresh_token';\n /** The refresh token issued by the authorization server. Optional: browser clients omit it and present the httpOnly refresh cookie instead */\n refresh_token?: string;\n}\n\n/**\n * Represents an authentication magic link request\n * generated from [LinkAuthenticationRequest](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface LinkAuthenticationRequest extends Omit<BaseAuthenticationRequest, 'grant_type'> {\n /** The grant type for the request */\n grant_type: 'link';\n /** The email challenge id returned by `POST /auth/login/start` — binds the link to the issued challenge so cross-device clicks work */\n challenge_id: string;\n /** The magic link token */\n link: string;\n}\n\n/**\n * Represents an authentication one-time-code request\n * generated from [CodeAuthenticationRequest](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface CodeAuthenticationRequest extends Omit<BaseAuthenticationRequest, 'grant_type'> {\n /** The grant type for the request */\n grant_type: 'code';\n /** The one-time code */\n code: string;\n /** PKCE verifier — required for a primary code login; absent when mfa_challenge_id is set */\n code_verifier?: string;\n /** When set, completes a pending MFA challenge; replaces code_verifier as proof-of-origin */\n mfa_challenge_id?: string;\n /** The phone/email challenge id (returned by POST /auth/factors/start for phone-MFA). Required when mfa_challenge_id is set; ignored otherwise (resolved via PKCE) */\n challenge_id?: string;\n}\n\n/**\n * Submit a TOTP code as a second factor against a pending MFA challenge\n * generated from [AuthenticatorAuthenticationRequest](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface AuthenticatorAuthenticationRequest extends Omit<BaseAuthenticationRequest, 'grant_type'> {\n /** The grant type for the request */\n grant_type: 'authenticator';\n /** The TOTP code */\n code: string;\n /** The pending MFA challenge — required, TOTP has no other actor binding at initial login */\n mfa_challenge_id: string;\n /** The id of the enrolled authenticator factor to verify against (must be present in the MFA challenge's eligible list) */\n method_id: string;\n}\n\n/**\n * Redeem a completed OIDC authorization that the callback stashed under a one-time id\n * generated from [OidcAuthenticationRequest](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface OidcAuthenticationRequest extends Omit<BaseAuthenticationRequest, 'grant_type'> {\n /** The grant type for the request */\n grant_type: 'oidc';\n /** The one-time stash id from the OIDC callback redirect (the value after `?token=oidc:` on `/auth/callback`). Single-use — the API consumes it via `OidcFactorService.redeemAuthenticatedExchange`. */\n challenge_id: string;\n}\n\n/**\n * generated from [BaseAuthenticationLoginStartWithEmail](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface BaseAuthenticationLoginStartWithEmail extends BaseAuthenticationLoginStart {\n /** User's email address */\n email: string;\n}\n\n/**\n * Request to begin an OIDC sign-in flow\n * generated from [OidcAuthenticationLoginStart](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface OidcAuthenticationLoginStart extends Omit<BaseAuthenticationLoginStart, 'grant_type'> {\n /** The grant type for the request */\n grant_type: 'oidc';\n /** The IdP to authorize against */\n provider: OidcProvider;\n /** A path on the console to return to once signed in, such as `/settings/security`. Anything that is not a same-origin path is ignored and the console opens at its home page */\n redirect_after?: string;\n}\n\n/**\n * generated from [CodeAuthenticationLoginStartResponse](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface CodeAuthenticationLoginStartResponse extends Omit<BaseAuthenticationLoginStartResponse, 'grant_type'> {\n /** The grant type for the response */\n grant_type: 'code';\n}\n\n/** Rehydrates every wire-encoded scalar in a CodeAuthenticationLoginStartResponse into its runtime type. Mutates and returns `raw`. */\nexport function reviveCodeAuthenticationLoginStartResponse(raw: CodeAuthenticationLoginStartResponse): CodeAuthenticationLoginStartResponse {\n reviveBaseAuthenticationLoginStartResponse(raw as never);\n return raw;\n}\n\n/**\n * generated from [LinkAuthenticationLoginStartResponse](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface LinkAuthenticationLoginStartResponse extends Omit<BaseAuthenticationLoginStartResponse, 'grant_type'> {\n /** The grant type for the response */\n grant_type: 'link';\n}\n\n/** Rehydrates every wire-encoded scalar in a LinkAuthenticationLoginStartResponse into its runtime type. Mutates and returns `raw`. */\nexport function reviveLinkAuthenticationLoginStartResponse(raw: LinkAuthenticationLoginStartResponse): LinkAuthenticationLoginStartResponse {\n reviveBaseAuthenticationLoginStartResponse(raw as never);\n return raw;\n}\n\n/**\n * Response from `/auth/login/oidc/start` instructing the client to navigate to `authorize_url`\n * generated from [OidcAuthenticationLoginStartResponse](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface OidcAuthenticationLoginStartResponse extends Omit<BaseAuthenticationLoginStartResponse, 'grant_type'> {\n /** The grant type for the response */\n grant_type: 'oidc';\n /** Fully-formed authorize URL the user-agent should be redirected to */\n authorize_url: string;\n /** Opaque state token bound to this authorization round-trip */\n state: string;\n}\n\n/** Rehydrates every wire-encoded scalar in a OidcAuthenticationLoginStartResponse into its runtime type. Mutates and returns `raw`. */\nexport function reviveOidcAuthenticationLoginStartResponse(raw: OidcAuthenticationLoginStartResponse): OidcAuthenticationLoginStartResponse {\n reviveBaseAuthenticationLoginStartResponse(raw as never);\n return raw;\n}\n\n/**\n * MFA-required arm of /auth/token response\n * generated from [MfaRequiredResponse](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface MfaRequiredResponse {\n /** Discriminator */\n result: 'mfa_required';\n /** The MFA challenge identifier — pass back as `mfa_challenge_id` on the proof grant */\n challengeId: string;\n /** When the MFA challenge expires */\n expiresAt: DateTime;\n /** Eligible factors the SPA may use to complete the challenge */\n factors: MfaChallengeFactor[];\n}\n\nexport interface MfaRequiredResponseOutput {\n /** Discriminator */\n result: 'mfa_required';\n /** The MFA challenge identifier — pass back as `mfa_challenge_id` on the proof grant */\n challenge_id: string;\n /** When the MFA challenge expires */\n expires_at: DateTime;\n /** Eligible factors the SPA may use to complete the challenge */\n factors: MfaChallengeFactorOutput[];\n}\n\n/** Rehydrates every wire-encoded scalar in a MfaRequiredResponse into its runtime type. Mutates and returns `raw`. */\nexport function reviveMfaRequiredResponse(raw: MfaRequiredResponse): MfaRequiredResponse {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['expiresAt'] = __dt(__o0['expiresAt'], 'MfaRequiredResponse.expiresAt');\n return raw;\n}\n\n/** Rehydrates every wire-encoded scalar in a MfaRequiredResponseOutput into its runtime type. Mutates and returns `raw`. */\nexport function reviveMfaRequiredResponseOutput(raw: MfaRequiredResponseOutput): MfaRequiredResponseOutput {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['expires_at'] = __dt(__o0['expires_at'], 'MfaRequiredResponse.expires_at');\n return raw;\n}\n\n/**\n * Represents an authentication passkey request\n * generated from [FidoAuthenticationRequest](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface FidoAuthenticationRequest extends Omit<BaseAuthenticationRequest, 'grant_type'> {\n /** The grant type for the request */\n grant_type: 'fido';\n /** A passkey credential object */\n credential: PublicKeyCredentialWithAssertion;\n /** The FIDO assertion challenge id returned by `POST /auth/login/start` (primary) or `POST /auth/factors/start` (MFA second factor). Must be the per-challenge id, not the actor id. */\n challenge_id: string;\n /** When set, completes a pending MFA challenge instead of issuing a single-factor session */\n mfa_challenge_id?: string;\n}\n\n/**\n * WebAuthn assertion options for `navigator.credentials.get`\n * generated from [FidoAuthenticationLoginStartResponse](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface FidoAuthenticationLoginStartResponse extends Omit<BaseAuthenticationLoginStartResponse, 'grant_type'> {\n /** The grant type for the response */\n grant_type: 'fido';\n /** The WebAuthn assertion options */\n assertion: FidoPublicKeyCredentialRequestOptions;\n}\n\n/** Rehydrates every wire-encoded scalar in a FidoAuthenticationLoginStartResponse into its runtime type. Mutates and returns `raw`. */\nexport function reviveFidoAuthenticationLoginStartResponse(raw: FidoAuthenticationLoginStartResponse): FidoAuthenticationLoginStartResponse {\n reviveBaseAuthenticationLoginStartResponse(raw as never);\n return raw;\n}\n\n/**\n * Response for a FIDO assertion challenge\n * generated from [FactorChallengeFidoStartResponse](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface FactorChallengeFidoStartResponse {\n /** Discriminator */\n method: 'fido';\n /** The FIDO-factor challenge id — echo back on the `fido` grant as `challenge_id` */\n fidoChallengeId: string;\n /** WebAuthn assertion options for navigator.credentials.get */\n assertion: FidoPublicKeyCredentialRequestOptions;\n /** When the FIDO challenge expires */\n expiresAt: DateTime;\n}\n\nexport interface FactorChallengeFidoStartResponseOutput {\n /** Discriminator */\n method: 'fido';\n /** The FIDO-factor challenge id — echo back on the `fido` grant as `challenge_id` */\n fido_challenge_id: string;\n /** WebAuthn assertion options for navigator.credentials.get */\n assertion: FidoPublicKeyCredentialRequestOptions;\n /** When the FIDO challenge expires */\n expires_at: DateTime;\n}\n\n/** Rehydrates every wire-encoded scalar in a FactorChallengeFidoStartResponse into its runtime type. Mutates and returns `raw`. */\nexport function reviveFactorChallengeFidoStartResponse(raw: FactorChallengeFidoStartResponse): FactorChallengeFidoStartResponse {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['expiresAt'] = __dt(__o0['expiresAt'], 'FactorChallengeFidoStartResponse.expiresAt');\n return raw;\n}\n\n/** Rehydrates every wire-encoded scalar in a FactorChallengeFidoStartResponseOutput into its runtime type. Mutates and returns `raw`. */\nexport function reviveFactorChallengeFidoStartResponseOutput(raw: FactorChallengeFidoStartResponseOutput): FactorChallengeFidoStartResponseOutput {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['expires_at'] = __dt(__o0['expires_at'], 'FactorChallengeFidoStartResponse.expires_at');\n return raw;\n}\n\n/**\n * The credential the client posts back to complete registration\n * generated from [PublicKeyCredentialWithAttestation](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface PublicKeyCredentialWithAttestation extends PublicKeyCredential {\n /** The client extension results */\n clientExtensionResults: SimpleClientExtensionResults;\n /** The authenticator attestation response */\n response: FidoAuthenticatorAttestationResponse;\n}\n\n/**\n * Every API key the account holds, newest first, revoked and expired keys included\n * generated from [ApiKeyList](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface ApiKeyList {\n keys: ApiKey[];\n}\n\n/** Rehydrates every wire-encoded scalar in a ApiKeyList into its runtime type. Mutates and returns `raw`. */\nexport function reviveApiKeyList(raw: ApiKeyList): ApiKeyList {\n const __o0 = raw as unknown as Record<string, unknown>;\n {\n const __a1 = __o0['keys'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveApiKey(__a1[__i2] as never);\n }\n }\n return raw;\n}\n\n/**\n * A key and its token. The only time the token is ever returned: store it now, because nothing can show it again\n * generated from [ApiKeyIssued](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface ApiKeyIssued {\n /** The key as it will appear in the list */\n key: ApiKey;\n /** The bearer token, sent as `Authorization: Bearer <token>` */\n token: string;\n}\n\n/** Rehydrates every wire-encoded scalar in a ApiKeyIssued into its runtime type. Mutates and returns `raw`. */\nexport function reviveApiKeyIssued(raw: ApiKeyIssued): ApiKeyIssued {\n const __o0 = raw as unknown as Record<string, unknown>;\n reviveApiKey(__o0['key'] as never);\n return raw;\n}\n\n/**\n * generated from [LinkAuthenticationLoginStart](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface LinkAuthenticationLoginStart extends Omit<BaseAuthenticationLoginStartWithEmail, 'grant_type'> {\n /** The grant type for the request */\n grant_type: 'link';\n /** What the link is for. `reset` words the email as a password reset and lands the person on the password form once signed in; the link and what it proves are the same. Absent means `signin` */\n purpose?: 'signin' | 'reset';\n}\n\n/**\n * generated from [CodeAuthenticationLoginStart](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface CodeAuthenticationLoginStart extends Omit<BaseAuthenticationLoginStartWithEmail, 'grant_type'> {\n /** The grant type for the request */\n grant_type: 'code';\n /** A base64url encoded SHA256 hash of a one time secret used to validate that the request starts and ends on the same device */\n code_challenge: string;\n}\n\n/**\n * generated from [FidoAuthenticationLoginStart](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface FidoAuthenticationLoginStart extends Omit<BaseAuthenticationLoginStartWithEmail, 'grant_type'> {\n /** The grant type for the request */\n grant_type: 'fido';\n}\n\n/**\n * generated from [StepUpStartResponse](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport type StepUpStartResponse = MfaRequiredResponse | EnrollmentRequiredResponse;\nexport type StepUpStartResponseOutput = MfaRequiredResponseOutput | EnrollmentRequiredResponseOutput;\n\n/** Rehydrates every wire-encoded scalar in a StepUpStartResponse into its runtime type. Mutates and returns `raw`. */\nexport function reviveStepUpStartResponse(raw: StepUpStartResponse): StepUpStartResponse {\n const __v = [raw] as unknown[];\n {\n const __d0 = (__v[0] as Record<string, unknown>)['result'];\n if (__d0 === 'mfa_required') {\n reviveMfaRequiredResponse(__v[0] as never);\n }\n }\n return __v[0] as StepUpStartResponse;\n}\n\n/** Rehydrates every wire-encoded scalar in a StepUpStartResponseOutput into its runtime type. Mutates and returns `raw`. */\nexport function reviveStepUpStartResponseOutput(raw: StepUpStartResponseOutput): StepUpStartResponseOutput {\n const __v = [raw] as unknown[];\n {\n const __d0 = (__v[0] as Record<string, unknown>)['result'];\n if (__d0 === 'mfa_required') {\n reviveMfaRequiredResponseOutput(__v[0] as never);\n }\n }\n return __v[0] as StepUpStartResponseOutput;\n}\n\n/**\n * generated from [AuthenticationTokenResponse](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport type AuthenticationTokenResponse = AuthenticationTokenIssued | MfaRequiredResponse;\nexport type AuthenticationTokenResponseOutput = AuthenticationTokenIssuedOutput | MfaRequiredResponseOutput;\n\n/** Rehydrates every wire-encoded scalar in a AuthenticationTokenResponse into its runtime type. Mutates and returns `raw`. */\nexport function reviveAuthenticationTokenResponse(raw: AuthenticationTokenResponse): AuthenticationTokenResponse {\n const __v = [raw] as unknown[];\n {\n const __d0 = (__v[0] as Record<string, unknown>)['result'];\n if (__d0 === 'mfa_required') {\n reviveMfaRequiredResponse(__v[0] as never);\n }\n }\n return __v[0] as AuthenticationTokenResponse;\n}\n\n/** Rehydrates every wire-encoded scalar in a AuthenticationTokenResponseOutput into its runtime type. Mutates and returns `raw`. */\nexport function reviveAuthenticationTokenResponseOutput(raw: AuthenticationTokenResponseOutput): AuthenticationTokenResponseOutput {\n const __v = [raw] as unknown[];\n {\n const __d0 = (__v[0] as Record<string, unknown>)['result'];\n if (__d0 === 'mfa_required') {\n reviveMfaRequiredResponseOutput(__v[0] as never);\n }\n }\n return __v[0] as AuthenticationTokenResponseOutput;\n}\n\n/**\n * generated from [AuthenticationRequest](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport type AuthenticationRequest =\n | PasswordAuthenticationRequest\n | ClientCredentialsAuthenticationRequest\n | RefreshTokenAuthenticationRequest\n | LinkAuthenticationRequest\n | CodeAuthenticationRequest\n | FidoAuthenticationRequest\n | AuthenticatorAuthenticationRequest\n | OidcAuthenticationRequest;\n\n/**\n * generated from [AuthenticationLoginStartResponse](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport type AuthenticationLoginStartResponse =\n | CodeAuthenticationLoginStartResponse\n | LinkAuthenticationLoginStartResponse\n | FidoAuthenticationLoginStartResponse\n | OidcAuthenticationLoginStartResponse;\n\n/** Rehydrates every wire-encoded scalar in a AuthenticationLoginStartResponse into its runtime type. Mutates and returns `raw`. */\nexport function reviveAuthenticationLoginStartResponse(raw: AuthenticationLoginStartResponse): AuthenticationLoginStartResponse {\n const __v = [raw] as unknown[];\n {\n const __d0 = (__v[0] as Record<string, unknown>)['grant_type'];\n if (__d0 === 'code') {\n reviveCodeAuthenticationLoginStartResponse(__v[0] as never);\n }\n if (__d0 === 'link') {\n reviveLinkAuthenticationLoginStartResponse(__v[0] as never);\n }\n if (__d0 === 'fido') {\n reviveFidoAuthenticationLoginStartResponse(__v[0] as never);\n }\n if (__d0 === 'oidc') {\n reviveOidcAuthenticationLoginStartResponse(__v[0] as never);\n }\n }\n return __v[0] as AuthenticationLoginStartResponse;\n}\n\n/**\n * generated from [FactorChallengeStartResponse](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport type FactorChallengeStartResponse = FactorChallengePhoneStartResponse | FactorChallengeFidoStartResponse | FactorChallengeEmailStartResponse;\nexport type FactorChallengeStartResponseOutput =\n FactorChallengePhoneStartResponseOutput | FactorChallengeFidoStartResponseOutput | FactorChallengeEmailStartResponseOutput;\n\n/** Rehydrates every wire-encoded scalar in a FactorChallengeStartResponse into its runtime type. Mutates and returns `raw`. */\nexport function reviveFactorChallengeStartResponse(raw: FactorChallengeStartResponse): FactorChallengeStartResponse {\n const __v = [raw] as unknown[];\n {\n const __d0 = (__v[0] as Record<string, unknown>)['method'];\n if (__d0 === 'phone') {\n reviveFactorChallengePhoneStartResponse(__v[0] as never);\n }\n if (__d0 === 'fido') {\n reviveFactorChallengeFidoStartResponse(__v[0] as never);\n }\n if (__d0 === 'email') {\n reviveFactorChallengeEmailStartResponse(__v[0] as never);\n }\n }\n return __v[0] as FactorChallengeStartResponse;\n}\n\n/** Rehydrates every wire-encoded scalar in a FactorChallengeStartResponseOutput into its runtime type. Mutates and returns `raw`. */\nexport function reviveFactorChallengeStartResponseOutput(raw: FactorChallengeStartResponseOutput): FactorChallengeStartResponseOutput {\n const __v = [raw] as unknown[];\n {\n const __d0 = (__v[0] as Record<string, unknown>)['method'];\n if (__d0 === 'phone') {\n reviveFactorChallengePhoneStartResponseOutput(__v[0] as never);\n }\n if (__d0 === 'fido') {\n reviveFactorChallengeFidoStartResponseOutput(__v[0] as never);\n }\n if (__d0 === 'email') {\n reviveFactorChallengeEmailStartResponseOutput(__v[0] as never);\n }\n }\n return __v[0] as FactorChallengeStartResponseOutput;\n}\n\n/**\n * generated from [AuthenticationLoginStart](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport type AuthenticationLoginStart =\n LinkAuthenticationLoginStart | CodeAuthenticationLoginStart | FidoAuthenticationLoginStart | OidcAuthenticationLoginStart;\n","import type { ApiKeyCreate, ApiKeyIssued, ApiKeyList } from './types/authentication.types.js';\nimport { reviveApiKeyIssued, reviveApiKeyList } from './types/authentication.types.js';\nimport type { SdkFetch } from '../sdk-options.js';\nimport { bigIntReplacer, parseJson } from '../sdk-options.js';\n\n/**\n * generated from [authentication.apikeys.ck](../../../../apps/api/data/contracts/authentication/authentication.apikeys.ck)\n */\nexport class AuthenticationApikeysClient {\n constructor(private fetch: SdkFetch) {}\n\n /**\n * @name List API keys\n * @description The signed-in account's API keys, newest first, including revoked and expired ones so the list says what was withdrawn and when\n */\n async listAPIKeys(): Promise<ApiKeyList> {\n const result = await this.fetch(`/auth/apikeys`, { method: 'GET' });\n return reviveApiKeyList(await parseJson<ApiKeyList>(result));\n }\n\n /**\n * @name Create API key\n * @description Issue a new API key for the signed-in account. The token is in this response and nowhere else, ever. Once the account has a strong second factor, this needs one verified in the last five minutes\n */\n async createAPIKey(body: ApiKeyCreate): Promise<ApiKeyIssued> {\n const result = await this.fetch(`/auth/apikeys`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return reviveApiKeyIssued(await parseJson<ApiKeyIssued>(result));\n }\n\n /**\n * @name Rotate API key\n * @description Give a key a new token, so the old one stops working at once. The key keeps its name, scopes and expiry. Needs the same recent second factor as creating one\n */\n async rotateAPIKey(id: string): Promise<ApiKeyIssued> {\n const result = await this.fetch(`/auth/apikeys/${encodeURIComponent(id)}/rotate`, { method: 'POST' });\n return reviveApiKeyIssued(await parseJson<ApiKeyIssued>(result));\n }\n\n /**\n * @name Revoke API key\n * @description Revoke a key. Every request made with it is refused from the next one on. The key stays in the list, marked revoked\n */\n async revokeAPIKey(id: string): Promise<void> {\n await this.fetch(`/auth/apikeys/${encodeURIComponent(id)}`, { method: 'DELETE' });\n }\n}\n","import { DateTime } from 'luxon';\nimport type { OidcProvider } from './authentication.types.js';\nimport type { PublicKeyCredentialWithAttestation } from './authentication.types.js';\n\nconst __dt = (v: unknown, path: string): DateTime => {\n if (typeof v !== 'string') {\n throw new TypeError(`ContractKit: expected an ISO 8601 string at '${path}', received ${typeof v}.`);\n }\n const d = DateTime.fromISO(v);\n if (!d.isValid) throw new TypeError(`ContractKit: '${v}' at '${path}' is not a valid ISO 8601 datetime.`);\n return d;\n};\n\n/**\n * generated from [PhoneFactorRegistration](../../../../../apps/api/data/contracts/authentication/registration.types.ck)\n */\nexport interface PhoneFactorRegistration {\n /** The method of the factor */\n method: 'phone';\n /** The phone number in E.164 format (e.g. `+12025550123`) */\n value: string;\n /** A base64url encoded SHA256 hash of a one time secret used to validate that the request starts and ends on the same device */\n codeChallenge: string;\n}\n\n/**\n * generated from [PasswordFactorRegistration](../../../../../apps/api/data/contracts/authentication/registration.types.ck)\n */\nexport interface PasswordFactorRegistration {\n /** The method of the factor */\n method: 'password';\n /** The password */\n value: string;\n}\n\n/**\n * generated from [PasswordChange](../../../../../apps/api/data/contracts/authentication/registration.types.ck)\n */\nexport interface PasswordChange {\n /** The new password */\n password: string;\n /** The password it replaces. Needed when the account has one, unless a sign-in link was used in the last ten minutes */\n currentPassword?: string;\n}\n\n/**\n * generated from [EmailFactorRegistration](../../../../../apps/api/data/contracts/authentication/registration.types.ck)\n */\nexport interface EmailFactorRegistration {\n /** The method of the factor */\n method: 'email';\n /** The email address */\n value: string;\n /** A base64url encoded SHA256 hash of a one time secret used to validate that the request starts and ends on the same device */\n codeChallenge: string;\n}\n\n/**\n * generated from [AuthenticatorFactorRegistration](../../../../../apps/api/data/contracts/authentication/registration.types.ck)\n */\nexport interface AuthenticatorFactorRegistration {\n /** The method of the factor */\n method: 'authenticator';\n /** A base64url encoded SHA256 hash of a one time secret used to validate that the request starts and ends on the same device */\n codeChallenge: string;\n /** The label for the authenticator factor */\n label?: string;\n}\n\n/**\n * generated from [FidoFactorRegistration](../../../../../apps/api/data/contracts/authentication/registration.types.ck)\n */\nexport interface FidoFactorRegistration {\n /** The method of the factor */\n method: 'fido';\n /** The label for the FIDO factor */\n label?: string;\n}\n\n/**\n * Link an identity provider to the signed-in account. Answered with the provider's address; the browser goes there and comes back to Security\n * generated from [OidcFactorRegistration](../../../../../apps/api/data/contracts/authentication/registration.types.ck)\n */\nexport interface OidcFactorRegistration {\n /** The method of the factor */\n method: 'oidc';\n /** The provider to link, as `GET /auth/login/oidc/providers` names it */\n provider: OidcProvider;\n}\n\n/**\n * generated from [PhoneFactorRegistrationResponse](../../../../../apps/api/data/contracts/authentication/registration.types.ck)\n */\nexport interface PhoneFactorRegistrationResponse {\n /** The method of the factor */\n method: 'phone';\n /** The registration identifier */\n registrationId: string;\n /** The expiration timestamp */\n expiresAt: DateTime;\n /** The issuance timestamp */\n issuedAt: DateTime;\n}\n\n/** Rehydrates every wire-encoded scalar in a PhoneFactorRegistrationResponse into its runtime type. Mutates and returns `raw`. */\nexport function revivePhoneFactorRegistrationResponse(raw: PhoneFactorRegistrationResponse): PhoneFactorRegistrationResponse {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['expiresAt'] = __dt(__o0['expiresAt'], 'PhoneFactorRegistrationResponse.expiresAt');\n __o0['issuedAt'] = __dt(__o0['issuedAt'], 'PhoneFactorRegistrationResponse.issuedAt');\n return raw;\n}\n\n/**\n * generated from [PasswordFactorRegistrationResponse](../../../../../apps/api/data/contracts/authentication/registration.types.ck)\n */\nexport interface PasswordFactorRegistrationResponse {\n /** The method of the factor */\n method: 'password';\n /** Whether the password needs to be reset */\n needsReset: boolean;\n}\n\n/**\n * generated from [EmailFactorRegistrationResponse](../../../../../apps/api/data/contracts/authentication/registration.types.ck)\n */\nexport interface EmailFactorRegistrationResponse {\n /** The method of the factor */\n method: 'email';\n /** The registration identifier */\n registrationId: string;\n /** The expiration timestamp */\n expiresAt: DateTime;\n /** The issuance timestamp */\n issuedAt: DateTime;\n}\n\n/** Rehydrates every wire-encoded scalar in a EmailFactorRegistrationResponse into its runtime type. Mutates and returns `raw`. */\nexport function reviveEmailFactorRegistrationResponse(raw: EmailFactorRegistrationResponse): EmailFactorRegistrationResponse {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['expiresAt'] = __dt(__o0['expiresAt'], 'EmailFactorRegistrationResponse.expiresAt');\n __o0['issuedAt'] = __dt(__o0['issuedAt'], 'EmailFactorRegistrationResponse.issuedAt');\n return raw;\n}\n\n/**\n * generated from [AuthenticatorFactorRegistrationResponse](../../../../../apps/api/data/contracts/authentication/registration.types.ck)\n */\nexport interface AuthenticatorFactorRegistrationResponse {\n /** The method of the factor */\n method: 'authenticator';\n /** The registration identifier */\n registrationId: string;\n /** The secret for the authenticator */\n secret: string;\n /** The URI for the authenticator */\n uri: string;\n /** The QR code for the authenticator */\n qrCode: string;\n /** The expiration timestamp */\n expiresAt: DateTime;\n /** The issuance timestamp */\n issuedAt: DateTime;\n}\n\n/** Rehydrates every wire-encoded scalar in a AuthenticatorFactorRegistrationResponse into its runtime type. Mutates and returns `raw`. */\nexport function reviveAuthenticatorFactorRegistrationResponse(raw: AuthenticatorFactorRegistrationResponse): AuthenticatorFactorRegistrationResponse {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['expiresAt'] = __dt(__o0['expiresAt'], 'AuthenticatorFactorRegistrationResponse.expiresAt');\n __o0['issuedAt'] = __dt(__o0['issuedAt'], 'AuthenticatorFactorRegistrationResponse.issuedAt');\n return raw;\n}\n\n/**\n * The FIDO factor attestation information\n * generated from [FidoFactorAttestation](../../../../../apps/api/data/contracts/authentication/registration.types.ck)\n */\nexport interface FidoFactorAttestation {\n /** The relying party */\n rp: { name: string; id: string; icon?: string };\n user: { id: string; name: string; displayName: string };\n /** The challenge */\n challenge: string;\n /** The public key credential parameters */\n pubKeyCredParams: { type: 'public-key'; alg: number }[];\n /** The timeout */\n timeout?: number;\n /** The attestation */\n attestation: 'direct' | 'indirect' | 'none';\n}\n\n/**\n * generated from [OidcFactorRegistrationResponse](../../../../../apps/api/data/contracts/authentication/registration.types.ck)\n */\nexport interface OidcFactorRegistrationResponse {\n /** The method of the factor */\n method: 'oidc';\n /** Where to send the browser. The provider sends it back to Security, with `?linked=<provider>` on success */\n authorizeUrl: string;\n /** When the link attempt expires if the provider has not answered */\n expiresAt: DateTime;\n}\n\n/** Rehydrates every wire-encoded scalar in a OidcFactorRegistrationResponse into its runtime type. Mutates and returns `raw`. */\nexport function reviveOidcFactorRegistrationResponse(raw: OidcFactorRegistrationResponse): OidcFactorRegistrationResponse {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['expiresAt'] = __dt(__o0['expiresAt'], 'OidcFactorRegistrationResponse.expiresAt');\n return raw;\n}\n\n/**\n * generated from [PhoneFactorRegistrationVerification](../../../../../apps/api/data/contracts/authentication/registration.types.ck)\n */\nexport interface PhoneFactorRegistrationVerification {\n /** The method of the factor */\n method: 'phone';\n /** The registration identifier */\n registrationId: string;\n /** The verification code */\n code: string;\n /** A base64url encoded one time secret used to validate that the request starts and ends on the same device */\n codeVerifier: string;\n}\n\n/**\n * generated from [EmailFactorRegistrationVerification](../../../../../apps/api/data/contracts/authentication/registration.types.ck)\n */\nexport interface EmailFactorRegistrationVerification {\n /** The method of the factor */\n method: 'email';\n /** The registration identifier */\n registrationId: string;\n /** The verification code */\n code: string;\n /** A base64url encoded one time secret used to validate that the request starts and ends on the same device */\n codeVerifier: string;\n}\n\n/**\n * generated from [AuthenticatorFactorRegistrationVerification](../../../../../apps/api/data/contracts/authentication/registration.types.ck)\n */\nexport interface AuthenticatorFactorRegistrationVerification {\n /** The method of the factor */\n method: 'authenticator';\n /** The registration identifier */\n registrationId: string;\n /** The verification code */\n code: string;\n /** A base64url encoded one time secret used to validate that the request starts and ends on the same device */\n codeVerifier: string;\n}\n\n/**\n * generated from [FidoFactorRegistrationVerification](../../../../../apps/api/data/contracts/authentication/registration.types.ck)\n */\nexport interface FidoFactorRegistrationVerification {\n /** The method of the factor */\n method: 'fido';\n /** The registration identifier */\n registrationId: string;\n /** The credential the client posts back to complete registration */\n credential: PublicKeyCredentialWithAttestation;\n}\n\n/**\n * Begin enrolling a TOTP authenticator during a pending login MFA challenge (no session — authorized by the challenge)\n * generated from [MfaEnrollAuthenticatorStart](../../../../../apps/api/data/contracts/authentication/registration.types.ck)\n */\nexport interface MfaEnrollAuthenticatorStart {\n /** The pending MFA challenge from the `mfa_required` login response */\n mfa_challenge_id: string;\n /** Optional label for the new authenticator factor */\n label?: string;\n}\n\n/**\n * Verify the first TOTP code, persist the authenticator, and complete login\n * generated from [MfaEnrollAuthenticatorVerify](../../../../../apps/api/data/contracts/authentication/registration.types.ck)\n */\nexport interface MfaEnrollAuthenticatorVerify {\n /** The same pending MFA challenge */\n mfa_challenge_id: string;\n /** The registration id returned by the enroll-start response */\n registrationId: string;\n /** The first TOTP code from the user's authenticator app */\n code: string;\n}\n\n/**\n * A second-factor method a user may enroll\n * generated from [EnrollmentMethod](../../../../../apps/api/data/contracts/authentication/registration.types.ck)\n */\nexport type EnrollmentMethod = 'authenticator' | 'phone' | 'fido';\n\n/**\n * Begin enrolling an SMS phone factor during a pending login MFA challenge (no session — authorized by the challenge)\n * generated from [MfaEnrollPhoneStart](../../../../../apps/api/data/contracts/authentication/registration.types.ck)\n */\nexport interface MfaEnrollPhoneStart {\n /** The pending MFA challenge from the `mfa_required` login response */\n mfa_challenge_id: string;\n /** The phone number in E.164 format (e.g. `+12025550123`) */\n value: string;\n}\n\n/**\n * Acknowledges the phone registration and that an OTP was texted\n * generated from [MfaEnrollPhoneStartResponse](../../../../../apps/api/data/contracts/authentication/registration.types.ck)\n */\nexport interface MfaEnrollPhoneStartResponse {\n /** The method of the factor */\n method: 'phone';\n /** The registration id — echo back on the verify call */\n registrationId: string;\n /** When the registration expires */\n expiresAt: DateTime;\n /** When the registration was issued */\n issuedAt: DateTime;\n}\n\n/** Rehydrates every wire-encoded scalar in a MfaEnrollPhoneStartResponse into its runtime type. Mutates and returns `raw`. */\nexport function reviveMfaEnrollPhoneStartResponse(raw: MfaEnrollPhoneStartResponse): MfaEnrollPhoneStartResponse {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['expiresAt'] = __dt(__o0['expiresAt'], 'MfaEnrollPhoneStartResponse.expiresAt');\n __o0['issuedAt'] = __dt(__o0['issuedAt'], 'MfaEnrollPhoneStartResponse.issuedAt');\n return raw;\n}\n\n/**\n * Verify the texted OTP, persist the phone factor, and complete login\n * generated from [MfaEnrollPhoneVerify](../../../../../apps/api/data/contracts/authentication/registration.types.ck)\n */\nexport interface MfaEnrollPhoneVerify {\n /** The same pending MFA challenge */\n mfa_challenge_id: string;\n /** The registration id returned by the enroll-start response */\n registrationId: string;\n /** The one-time code texted to the phone */\n code: string;\n}\n\n/**\n * Begin enrolling a passkey during a pending login MFA challenge (no session — authorized by the challenge)\n * generated from [MfaEnrollFidoStart](../../../../../apps/api/data/contracts/authentication/registration.types.ck)\n */\nexport interface MfaEnrollFidoStart {\n /** The pending MFA challenge from the `mfa_required` login response */\n mfa_challenge_id: string;\n /** Optional label for the new passkey factor */\n label?: string;\n}\n\n/**\n * Post the new credential back, persist the passkey factor, and complete login\n * generated from [MfaEnrollFidoVerify](../../../../../apps/api/data/contracts/authentication/registration.types.ck)\n */\nexport interface MfaEnrollFidoVerify {\n /** The same pending MFA challenge */\n mfa_challenge_id: string;\n /** The registration id returned by the enroll-start response */\n registrationId: string;\n /** The credential produced by `navigator.credentials.create` */\n credential: PublicKeyCredentialWithAttestation;\n}\n\n/**\n * generated from [AuthenticationFactorRegistration](../../../../../apps/api/data/contracts/authentication/registration.types.ck)\n */\nexport type AuthenticationFactorRegistration =\n | PhoneFactorRegistration\n | PasswordFactorRegistration\n | EmailFactorRegistration\n | AuthenticatorFactorRegistration\n | FidoFactorRegistration\n | OidcFactorRegistration;\n\n/**\n * generated from [FidoFactorRegistrationResponse](../../../../../apps/api/data/contracts/authentication/registration.types.ck)\n */\nexport interface FidoFactorRegistrationResponse {\n /** The method of the factor */\n method: 'fido';\n /** The registration identifier */\n registrationId: string;\n /** The expiration timestamp */\n expiresAt: DateTime;\n /** The issuance timestamp */\n issuedAt: DateTime;\n /** The FIDO factor attestation information */\n attestation: FidoFactorAttestation;\n}\n\n/** Rehydrates every wire-encoded scalar in a FidoFactorRegistrationResponse into its runtime type. Mutates and returns `raw`. */\nexport function reviveFidoFactorRegistrationResponse(raw: FidoFactorRegistrationResponse): FidoFactorRegistrationResponse {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['expiresAt'] = __dt(__o0['expiresAt'], 'FidoFactorRegistrationResponse.expiresAt');\n __o0['issuedAt'] = __dt(__o0['issuedAt'], 'FidoFactorRegistrationResponse.issuedAt');\n return raw;\n}\n\n/**\n * WebAuthn attestation options for `navigator.credentials.create`\n * generated from [MfaEnrollFidoStartResponse](../../../../../apps/api/data/contracts/authentication/registration.types.ck)\n */\nexport interface MfaEnrollFidoStartResponse {\n /** The method of the factor */\n method: 'fido';\n /** The registration id — echo back on the verify call */\n registrationId: string;\n /** When the registration expires */\n expiresAt: DateTime;\n /** When the registration was issued */\n issuedAt: DateTime;\n /** The WebAuthn attestation (credential-creation) options */\n attestation: FidoFactorAttestation;\n}\n\n/** Rehydrates every wire-encoded scalar in a MfaEnrollFidoStartResponse into its runtime type. Mutates and returns `raw`. */\nexport function reviveMfaEnrollFidoStartResponse(raw: MfaEnrollFidoStartResponse): MfaEnrollFidoStartResponse {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['expiresAt'] = __dt(__o0['expiresAt'], 'MfaEnrollFidoStartResponse.expiresAt');\n __o0['issuedAt'] = __dt(__o0['issuedAt'], 'MfaEnrollFidoStartResponse.issuedAt');\n return raw;\n}\n\n/**\n * generated from [AuthenticationFactorRegistrationVerification](../../../../../apps/api/data/contracts/authentication/registration.types.ck)\n */\nexport type AuthenticationFactorRegistrationVerification =\n | PhoneFactorRegistrationVerification\n | EmailFactorRegistrationVerification\n | AuthenticatorFactorRegistrationVerification\n | FidoFactorRegistrationVerification;\n\n/**\n * Which second factors this instance permits enrolling. `phone` is present only when an SMS provider is configured (SMS_DELIVERY != noop); `authenticator` and `fido` are always available.\n * generated from [EnrollmentMethods](../../../../../apps/api/data/contracts/authentication/registration.types.ck)\n */\nexport interface EnrollmentMethods {\n /** The enrollable factor methods, in suggested display order */\n methods: EnrollmentMethod[];\n}\n\n/**\n * generated from [AuthenticationFactorRegistrationResponse](../../../../../apps/api/data/contracts/authentication/registration.types.ck)\n */\nexport type AuthenticationFactorRegistrationResponse =\n | PhoneFactorRegistrationResponse\n | PasswordFactorRegistrationResponse\n | EmailFactorRegistrationResponse\n | AuthenticatorFactorRegistrationResponse\n | FidoFactorRegistrationResponse\n | OidcFactorRegistrationResponse;\n\n/** Rehydrates every wire-encoded scalar in a AuthenticationFactorRegistrationResponse into its runtime type. Mutates and returns `raw`. */\nexport function reviveAuthenticationFactorRegistrationResponse(\n raw: AuthenticationFactorRegistrationResponse,\n): AuthenticationFactorRegistrationResponse {\n const __v = [raw] as unknown[];\n {\n const __d0 = (__v[0] as Record<string, unknown>)['method'];\n if (__d0 === 'phone') {\n revivePhoneFactorRegistrationResponse(__v[0] as never);\n }\n if (__d0 === 'email') {\n reviveEmailFactorRegistrationResponse(__v[0] as never);\n }\n if (__d0 === 'authenticator') {\n reviveAuthenticatorFactorRegistrationResponse(__v[0] as never);\n }\n if (__d0 === 'fido') {\n reviveFidoFactorRegistrationResponse(__v[0] as never);\n }\n if (__d0 === 'oidc') {\n reviveOidcFactorRegistrationResponse(__v[0] as never);\n }\n }\n return __v[0] as AuthenticationFactorRegistrationResponse;\n}\n","import type {\n AuthenticationFactor,\n AuthenticationFactorMethod,\n AuthenticationTokenOutput,\n FactorChallengeStartRequest,\n FactorChallengeStartResponseOutput,\n StepUpStartRequest,\n StepUpStartResponseOutput,\n} from './types/authentication.types.js';\nimport { reviveFactorChallengeStartResponseOutput, reviveStepUpStartResponseOutput } from './types/authentication.types.js';\nimport type {\n AuthenticationFactorRegistration,\n AuthenticationFactorRegistrationResponse,\n AuthenticationFactorRegistrationVerification,\n PasswordChange,\n} from './types/registration.types.js';\nimport { reviveAuthenticationFactorRegistrationResponse } from './types/registration.types.js';\nimport type { SdkFetch } from '../sdk-options.js';\nimport { bigIntReplacer, parseJson } from '../sdk-options.js';\n\n/**\n * generated from [authentication.factor.ck](../../../../apps/api/data/contracts/authentication/authentication.factor.ck)\n */\nexport class AuthenticationFactorsClient {\n constructor(private fetch: SdkFetch) {}\n\n /**\n * @name List factors\n * @description List authentication factors\n */\n async listFactors(): Promise<AuthenticationFactor[]> {\n const result = await this.fetch(`/auth/factors`, { method: 'GET' });\n return await parseJson<AuthenticationFactor[]>(result);\n }\n\n /**\n * @name Register factor\n * @description Register an authentication factor\n */\n async registerFactor(body: AuthenticationFactorRegistration): Promise<AuthenticationFactorRegistrationResponse> {\n const result = await this.fetch(`/auth/factors/register`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return reviveAuthenticationFactorRegistrationResponse(await parseJson<AuthenticationFactorRegistrationResponse>(result));\n }\n\n /**\n * @name Set password\n * @description Set or change the caller's own password. Needs the current one when there is one, unless a sign-in link was used in the last ten minutes, and a recent strong-factor verification once an authenticator or passkey is enrolled. Every other session of the account is signed out, and the account's email addresses are told.\n */\n async setPassword(body: PasswordChange): Promise<void> {\n await this.fetch(`/auth/password`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n }\n\n /**\n * @name Verify factor registration\n * @description Verify an authentication factor registration\n */\n async verifyFactorRegistration(body: AuthenticationFactorRegistrationVerification): Promise<AuthenticationTokenOutput> {\n const result = await this.fetch(`/auth/factors/verify`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<AuthenticationTokenOutput>(result);\n }\n\n /**\n * @name Start factor challenge\n * @description Issue a factor verification challenge for a pending MFA round. Authenticated via the short-lived `mfa_challenge_id` in the body, not by session — this is the only /auth/factors/* route that does not require an authenticated session.\n */\n async startFactorChallenge(body: FactorChallengeStartRequest): Promise<FactorChallengeStartResponseOutput> {\n const result = await this.fetch(`/auth/factors/start`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return reviveFactorChallengeStartResponseOutput(await parseJson<FactorChallengeStartResponseOutput>(result));\n }\n\n /**\n * @name Start MFA challenge\n * @description Mint a fresh MFA challenge for the *current* authenticated session so the SPA can satisfy a `step_up_required` denial. Optionally filters eligible factors against an inbound `StepUpRequirement` hint. Returns `enrollment_required` when no enrolled factor matches the requirement so the SPA can route the user into enrollment instead of getting stuck.\n */\n async startMFAChallenge(body: StepUpStartRequest): Promise<StepUpStartResponseOutput> {\n const result = await this.fetch(`/auth/mfa/start`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return reviveStepUpStartResponseOutput(await parseJson<StepUpStartResponseOutput>(result));\n }\n\n /**\n * @name Remove factor\n * @description Remove one of the caller's own factors. Answered for `authenticator` and `oidc`, and only after a recent strong-factor verification: the same gate enrolment sits behind once a strong factor exists, so a stolen session cannot quietly switch the second factor off. Removing the last authenticator turns the sign-in challenge off for that account. A linked identity provider that is the account's only way to sign in is refused with 409.\n */\n async removeFactor(method: AuthenticationFactorMethod, methodId: string): Promise<void> {\n await this.fetch(`/auth/factors/${encodeURIComponent(method)}/${encodeURIComponent(methodId)}`, { method: 'DELETE' });\n }\n}\n","import type { AuthSession } from './types/authentication.types.js';\nimport type { SdkFetch } from '../sdk-options.js';\nimport { parseJson } from '../sdk-options.js';\n\n/**\n * generated from [authentication.sessions.ck](../../../../apps/api/data/contracts/authentication/authentication.sessions.ck)\n */\nexport class AuthenticationSessionsClient {\n constructor(private fetch: SdkFetch) {}\n\n /**\n * @name Logout\n * @description revoke the caller's current session (self sign-out). Deliberately carries no policy gate: signing out must always clear the browser's httpOnly refresh cookie, including for a caller whose access token has already expired. A 401 here would leave a 30-day refresh cookie behind that silently signs the user back in on the next page load. SessionsService revokes the session only when the caller is actually authenticated; an anonymous caller still gets 204 and a cleared cookie.\n */\n async logout(): Promise<void> {\n await this.fetch(`/auth/logout`, { method: 'POST' });\n }\n\n /**\n * @name Read session\n * @description Who the caller is and which platform roles they hold\n */\n async readSession(): Promise<AuthSession> {\n const result = await this.fetch(`/auth/session`, { method: 'GET' });\n return await parseJson<AuthSession>(result);\n }\n}\n","import type { SdkFetch } from '../sdk-options.js';\nimport { bigIntReplacer, parseJson } from '../sdk-options.js';\nimport type {\n AuthenticationLoginStart,\n AuthenticationLoginStartResponse,\n AuthenticationRegistration,\n AuthenticationRegistrationInput,\n AuthenticationRegistrationVerification,\n AuthenticationRequest,\n AuthenticationTokenOutput,\n AuthenticationTokenResponseOutput,\n OidcProviderSummary,\n} from './types/authentication.types.js';\nimport {\n reviveAuthenticationLoginStartResponse,\n reviveAuthenticationRegistration,\n reviveAuthenticationTokenResponseOutput,\n} from './types/authentication.types.js';\nimport { AuthenticationApikeysClient } from './authentication.apikeys.client.js';\nimport { AuthenticationFactorsClient } from './authentication.factor.client.js';\nimport { AuthenticationSessionsClient } from './authentication.sessions.client.js';\n\nexport class AuthenticationClient {\n readonly apikeys: AuthenticationApikeysClient;\n readonly factors: AuthenticationFactorsClient;\n readonly sessions: AuthenticationSessionsClient;\n\n constructor(private fetch: SdkFetch) {\n this.apikeys = new AuthenticationApikeysClient(fetch);\n this.factors = new AuthenticationFactorsClient(fetch);\n this.sessions = new AuthenticationSessionsClient(fetch);\n }\n\n /**\n * @name Request token\n * @description Request authenticated token\n */\n async requestToken(\n body: AuthenticationRequest,\n options?: { contentType?: 'application/x-www-form-urlencoded' | 'application/json' },\n ): Promise<AuthenticationTokenResponseOutput> {\n const __contentType = options?.contentType ?? 'application/x-www-form-urlencoded';\n const __serialized =\n __contentType === 'application/x-www-form-urlencoded'\n ? new URLSearchParams(body as unknown as Record<string, string>).toString()\n : JSON.stringify(body, bigIntReplacer);\n const result = await this.fetch(`/auth/token`, {\n method: 'POST',\n headers: { 'Content-Type': __contentType },\n body: __serialized,\n });\n return reviveAuthenticationTokenResponseOutput(await parseJson<AuthenticationTokenResponseOutput>(result));\n }\n\n /**\n * @name Register login\n * @description Register a new login\n */\n async registerLogin(body: AuthenticationRegistrationInput): Promise<AuthenticationRegistration> {\n const result = await this.fetch(`/auth/login/register`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return reviveAuthenticationRegistration(await parseJson<AuthenticationRegistration>(result));\n }\n\n /**\n * @name Verify login registration\n * @description Verify a login registration\n */\n async verifyLoginRegistration(body: AuthenticationRegistrationVerification): Promise<AuthenticationTokenOutput> {\n const result = await this.fetch(`/auth/login/verify`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<AuthenticationTokenOutput>(result);\n }\n\n /**\n * @name Start login\n * @description Start a password-less login process\n */\n async startLogin(body: AuthenticationLoginStart): Promise<AuthenticationLoginStartResponse> {\n const result = await this.fetch(`/auth/login/start`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return reviveAuthenticationLoginStartResponse(await parseJson<AuthenticationLoginStartResponse>(result));\n }\n\n /**\n * @name List sign-in providers\n * @description The identity providers the sign-in page offers beside a password, in the order the operator listed them. Empty when none is set up\n */\n async listSignInProviders(): Promise<OidcProviderSummary[]> {\n const result = await this.fetch(`/auth/login/oidc/providers`, { method: 'GET' });\n return await parseJson<OidcProviderSummary[]>(result);\n }\n}\n","import { DateTime } from 'luxon';\nimport type { Pagination } from '../../shared/types/pagination.js';\nimport type { PaginationInput } from '../../shared/types/pagination.js';\n\nconst __dt = (v: unknown, path: string): DateTime => {\n if (typeof v !== 'string') {\n throw new TypeError(`ContractKit: expected an ISO 8601 string at '${path}', received ${typeof v}.`);\n }\n const d = DateTime.fromISO(v);\n if (!d.isValid) throw new TypeError(`ContractKit: '${v}' at '${path}' is not a valid ISO 8601 datetime.`);\n return d;\n};\n\n/**\n * What the station has been told about a record. `neutral` is the absence of an opinion rather than\n * a middling one, and it is what rating something back to nothing means.\n * generated from [Rating](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport type Rating = 'liked' | 'neutral' | 'disliked';\n\n/**\n * One provider's copy of a record, with whatever the station holds of it.\n *\n * PER BINDING and never per track, which is the rule the whole page is built on: one canonical\n * record may bind to several copies inside one provider, those copies are different files with\n * different loudness and different cue points, and the one that airs is the one that was resolved.\n * Collapsing them would make \"clear the audio\" ambiguous about which file it took.\n *\n * The failure columns are here rather than hidden because that is the question this page exists to\n * answer. A row with `attempts` and no `fetchedAt` is a remembered failure, and `lastError` with\n * `nextAttemptAt` is the whole of why a perfectly good-looking record will not play.\n * generated from [TrackBinding](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface TrackBinding {\n /** `track_sources.id`, which is also what the audio URL carries */\n sourceId: string;\n pluginId: string;\n externalId: string;\n /** False when the provider still knows the record but will not serve it here */\n playable: boolean;\n /** When the station gave up on this copy. Cleared by the next sync that sees it again */\n missingAt?: DateTime;\n /** `sync` if a playlist walk saw it, `discovered` if something looked it up */\n origin: string;\n bitrate?: number;\n format?: string;\n lastSeenAt?: DateTime;\n /** What the station holds of this copy, absent when nothing has ever fetched it. */\n byteSize?: number;\n fetchedAt?: DateTime;\n lastServedAt?: DateTime;\n /** CONSECUTIVE failures. Reset by a fetch that works */\n attempts: number;\n lastError?: string;\n nextAttemptAt?: DateTime;\n}\n\nexport interface TrackBindingInput {}\n\n/** Rehydrates every wire-encoded scalar in a TrackBinding into its runtime type. Mutates and returns `raw`. */\nexport function reviveTrackBinding(raw: TrackBinding): TrackBinding {\n const __o0 = raw as unknown as Record<string, unknown>;\n if (__o0['missingAt'] != null) {\n __o0['missingAt'] = __dt(__o0['missingAt'], 'TrackBinding.missingAt');\n }\n if (__o0['lastSeenAt'] != null) {\n __o0['lastSeenAt'] = __dt(__o0['lastSeenAt'], 'TrackBinding.lastSeenAt');\n }\n if (__o0['fetchedAt'] != null) {\n __o0['fetchedAt'] = __dt(__o0['fetchedAt'], 'TrackBinding.fetchedAt');\n }\n if (__o0['lastServedAt'] != null) {\n __o0['lastServedAt'] = __dt(__o0['lastServedAt'], 'TrackBinding.lastServedAt');\n }\n if (__o0['nextAttemptAt'] != null) {\n __o0['nextAttemptAt'] = __dt(__o0['nextAttemptAt'], 'TrackBinding.nextAttemptAt');\n }\n return raw;\n}\n\n/**\n * What the measurement sidecar made of a record.\n *\n * `complete` is NOT `analyzedAt`, and the two are separate fields for a reason `0005_music.sql`\n * argues at length: a measurement of a truncated download is confident and wrong, so every reader in\n * the app filters on `complete` and a page that showed only a date would be reporting a record as\n * measured that nothing will use the measurement of.\n * generated from [TrackAnalysis](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface TrackAnalysis {\n schemaVersion: number;\n complete: boolean;\n /** The measuring thing itself, which is not the plugin adapting it */\n analyzer?: string;\n analyzerPluginId?: string;\n analyzedAt?: DateTime;\n failedAt?: DateTime;\n failureReason?: string;\n}\n\nexport interface TrackAnalysisInput {}\n\n/** Rehydrates every wire-encoded scalar in a TrackAnalysis into its runtime type. Mutates and returns `raw`. */\nexport function reviveTrackAnalysis(raw: TrackAnalysis): TrackAnalysis {\n const __o0 = raw as unknown as Record<string, unknown>;\n if (__o0['analyzedAt'] != null) {\n __o0['analyzedAt'] = __dt(__o0['analyzedAt'], 'TrackAnalysis.analyzedAt');\n }\n if (__o0['failedAt'] != null) {\n __o0['failedAt'] = __dt(__o0['failedAt'], 'TrackAnalysis.failedAt');\n }\n return raw;\n}\n\n/**\n * One airing of a record, as this page needs it: when, and under which broadcast.\n * generated from [TrackPlay](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface TrackPlay {\n airedAt: DateTime;\n broadcastId?: string;\n /** What put it in the running order */\n source: string;\n}\n\nexport interface TrackPlayInput {}\n\n/** Rehydrates every wire-encoded scalar in a TrackPlay into its runtime type. Mutates and returns `raw`. */\nexport function reviveTrackPlay(raw: TrackPlay): TrackPlay {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['airedAt'] = __dt(__o0['airedAt'], 'TrackPlay.airedAt');\n return raw;\n}\n\n/**\n * What a clear actually did.\n *\n * A count rather than a bare 204, because the interesting answers are the small ones: clearing the\n * audio of a record with three copies and being told `1` is the station saying two of them were\n * never here — which is a fact about the record and not about the button.\n * generated from [TrackClearResult](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface TrackClearResult {\n trackId: string;\n /** Rows this affected. Zero is an ordinary answer, not a failure */\n cleared: number;\n /** What happened, in the words the console shows */\n detail: string;\n}\n\nexport interface TrackClearResultInput {}\n\n/**\n * Where the singing starts and stops on one record, and which answer that is. Times are milliseconds\n * from the start of the file, the timeline a lyric's timings use. Never the words themselves.\n * generated from [VocalMarkersDetail](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface VocalMarkersDetail {\n trackId: string;\n /** Nobody sings on it; where the singing is; or nothing to go on */\n kind: 'instrumental' | 'ranges' | 'unknown';\n /** Where the first sung word lands, when kind is ranges */\n onsetMs?: number;\n /** Where the singing stops, when it is known */\n endMs?: number;\n /** An operator's correction, the record's timed lyrics, or neither */\n source: 'override' | 'lyrics' | 'none';\n}\n\nexport interface VocalMarkersDetailInput {}\n\n/**\n * One timed piece of a lyric line: a word, or a syllable, and when it starts being sung. Milliseconds\n * from the start of the file, as the line's own start is.\n * generated from [LyricWordDetail](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface LyricWordDetail {\n /** Where this piece starts being sung */\n atMs: number;\n /** The piece, with any space after it, so a line's pieces joined are its text exactly */\n text: string;\n}\n\nexport interface LyricWordDetailInput {}\n\n/**\n * An operator's correction: either the record is instrumental, or the singing starts at `onsetMs`.\n * generated from [VocalMarkersInput](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface VocalMarkersInput {\n /** Nobody sings on this record, whatever its lyrics say */\n instrumental?: boolean;\n /** Where the first sung word lands, from the start of the file. Required unless instrumental */\n onsetMs?: number;\n /** Where the singing stops. Optional, and after the onset */\n endMs?: number;\n}\n\n/**\n * Narrow a clear to one provider's answer, for the case where one source is wrong and the rest are\n * not. Absent clears every provider's.\n * generated from [ClearEnrichmentQuery](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface ClearEnrichmentQuery {\n provider?: string;\n}\n\n/**\n * What an artist or album list is ordered BY, where `Pagination.sort` says only which direction.\n *\n * name the default, and the only key every row here has\n * albums how many records the station holds of them. Artists only\n * tracks how many songs. Artists only\n * year when the record came out. Albums only\n * rating the operator's own opinion\n *\n * One enum for both lists rather than two, because the alternative is a second near-identical\n * contract whose only content is which two keys it drops. A key the row cannot answer falls back to\n * name order rather than failing: an ordering nobody can serve is a page an operator cannot open.\n * generated from [CatalogSort](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport type CatalogSort = 'name' | 'albums' | 'tracks' | 'year' | 'rating';\n\n/**\n * Which records to show, by what the station has of them rather than by what they are.\n *\n * cached the audio is on this machine, so it can be committed to the running order now\n * uncached it is not, which for most of a library is ordinary rather than wrong\n * unmeasured no trustworthy measurement, so no cue points and no level decided before air\n * benched every copy written off, which is the one state that means it CANNOT air\n * failing a fetch has failed and is backing off. Not benched yet, and often the state before it\n * generated from [TrackState](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport type TrackState = 'cached' | 'uncached' | 'unmeasured' | 'benched' | 'failing';\n\n/**\n * What a track list is ordered BY. Its own enum for `TrackQuery`'s own reason: none of these keys\n * means anything about an artist, and `name` is spelled `title` on a song.\n *\n * `state` is deliberately absent. It is three independent booleans rather than one column, so there\n * is no ordering of it an operator would agree with: a benched record and an unmeasured one are not\n * more or less than each other.\n * generated from [TrackSort](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport type TrackSort = 'title' | 'artist' | 'album' | 'year' | 'duration' | 'rating';\n\n/**\n * How much of the library is in each state, over the whole filtered set rather than this page.\n *\n * The aggregate is what an operator reads first — \"13 of 581 measured\" is the sentence that made\n * [analysis-queue-ordering](https://github.com/robert-dean/deadair/discussions/5) necessary, and it was a psql query then. `total` is the\n * same number as `meta.total` when nothing is filtered, and is repeated here so the counts can be\n * read as N of M without reaching into the pager.\n * generated from [TrackStateCounts](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface TrackStateCounts {\n total: number;\n cached: number;\n measured: number;\n enriched: number;\n benched: number;\n failing: number;\n /** A lyrics source has the words of it. The words themselves are at `/catalog/tracks/{id}/lyrics` */\n lyrics: number;\n /** A lyrics source has the timing of its lines, which says when the singing starts */\n synced: number;\n /** A lyrics source says nobody sings on it */\n instrumental: number;\n /** A model has judged what mood it is in */\n moods: number;\n}\n\nexport interface TrackStateCountsInput {}\n\n/**\n * generated from [EnrichmentExternalId](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface EnrichmentExternalId {\n /** e.g. `musicbrainz`, `wikidata` */\n source: string;\n id: string;\n}\n\n/**\n * Narrowed to http(s) by the host before it is stored, since the console renders these as\n * something a human clicks.\n * generated from [EnrichmentLink](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface EnrichmentLink {\n label: string;\n url: string;\n}\n\n/**\n * One thing the station believes, and the words it read that say so. Extracted by the host out of\n * an article a plugin handed over, rather than said by any plugin: `sourceUrl` is where a person\n * checks it and `sourceQuote` is the span that supports it, and neither is ever absent.\n * generated from [FactClaim](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface FactClaim {\n id: string;\n /** One sentence, as the DJ would say it */\n claim: string;\n category: string;\n /** `lead` for the article's own opening, `model` for what a model found */\n source: string;\n sourceProvider: string;\n sourceUrl: string;\n sourceQuote: string;\n confidence?: number;\n model?: string;\n /** Absent means never said on air */\n lastUsedAt?: DateTime;\n}\n\nexport interface FactClaimInput {}\n\n/** Rehydrates every wire-encoded scalar in a FactClaim into its runtime type. Mutates and returns `raw`. */\nexport function reviveFactClaim(raw: FactClaim): FactClaim {\n const __o0 = raw as unknown as Record<string, unknown>;\n if (__o0['lastUsedAt'] != null) {\n __o0['lastUsedAt'] = __dt(__o0['lastUsedAt'], 'FactClaim.lastUsedAt');\n }\n return raw;\n}\n\n/**\n * Rate an artist, a record or a song. Ratings are absolute: a dislike anywhere above a track\n * excludes it, and nothing the station programmes may turn that off.\n * generated from [RateInput](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface RateInput {\n rating: Rating;\n}\n\n/**\n * The canonical work, not a binding to a provider. `deadair.artists` minus the columns that\n * only ingest cares about: `artist_key` is a match key, and a row with `merged_into_id` set is\n * never read out at all.\n *\n * `imageUrl` on both contracts below is always a path under the API root, never a provider's URL:\n * `art/<uuid>` for the station's cached copy, or `art/source/<token>` for one it has not cached\n * yet, which the station fetches on first ask and serves as its own. Resolve either against the\n * API base the client already configures (the API mounts at the root and does not know the `/api`\n * prefix the edge adds). The switch from the second to the first happens server-side.\n * generated from [Artist](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface Artist {\n id: string;\n name: string;\n /** MusicBrainz artist id, absent until enrichment resolves one */\n mbid?: string;\n /** An API-relative path: the cached copy, or the station's proxy for an uncached one */\n imageUrl?: string;\n rating?: Rating;\n /** Unmerged albums credited to this artist */\n albumCount: number;\n /** Unmerged tracks credited to this artist */\n trackCount: number;\n}\n\nexport interface ArtistInput {\n name: string;\n /** MusicBrainz artist id, absent until enrichment resolves one */\n mbid?: string;\n /** An API-relative path: the cached copy, or the station's proxy for an uncached one */\n imageUrl?: string;\n rating?: Rating;\n}\n\n/**\n * generated from [Album](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface Album {\n id: string;\n name: string;\n artistId: string;\n /** Joined, so a list renders without a second request per row */\n artistName: string;\n /** MusicBrainz release-group id, absent until enrichment resolves one */\n mbid?: string;\n year?: number;\n /** An API-relative path: the cached copy, or the station's proxy for an uncached one */\n imageUrl?: string;\n rating?: Rating;\n trackCount: number;\n}\n\nexport interface AlbumInput {\n name: string;\n /** MusicBrainz release-group id, absent until enrichment resolves one */\n mbid?: string;\n year?: number;\n /** An API-relative path: the cached copy, or the station's proxy for an uncached one */\n imageUrl?: string;\n rating?: Rating;\n}\n\n/**\n * generated from [Track](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface Track {\n id: string;\n title: string;\n artistId: string;\n artistName: string;\n /** Absent on a single ingested outside any release: `tracks.album_id` is nullable */\n albumId?: string;\n albumName?: string;\n /** The record's cover, as `Album.imageUrl` spells it. Nothing hangs art off a recording */\n albumImageUrl?: string;\n /** Display credit as written on the release (\"X feat. Y\"), not a join key */\n artists: string;\n genre?: string;\n year?: number;\n durationMs?: number;\n rating?: Rating;\n}\n\nexport interface TrackInput {\n title: string;\n /** Display credit as written on the release (\"X feat. Y\"), not a join key */\n artists: string;\n genre?: string;\n year?: number;\n durationMs?: number;\n rating?: Rating;\n}\n\n/**\n * One timed line of a record's lyrics. Times are milliseconds from the start of the file.\n * generated from [LyricLineDetail](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface LyricLineDetail {\n /** Where the line starts */\n atMs: number;\n /** Where the line ends, when the source published one. Absent rather than guessed */\n endMs?: number;\n /** The words of the line. Empty for a gap the source marked between lines */\n text: string;\n /** The line cut where its source timed each word, in order, when the source times words. Joined, the pieces are text */\n words?: LyricWordDetail[];\n}\n\nexport interface LyricLineDetailInput {}\n\n/**\n * Pagination plus a name filter. Every list operation here takes it, so the console's search box\n * narrows server-side rather than filtering one page client-side and lying about the total.\n * generated from [CatalogQuery](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface CatalogQuery extends Pagination {\n search?: string;\n sortBy?: CatalogSort;\n}\n\nexport interface CatalogQueryInput extends PaginationInput {\n search?: string;\n sortBy?: CatalogSort;\n}\n\n/**\n * `releaseDate` is a string and not `datetime` because it is a partial date: MusicBrainz answers\n * `1997`, `1997-06` or `1997-06-24` depending on what is actually known about the release, and the\n * SDK types it the same way. A `datetime` would reject the first two or invent a day and a time\n * for them, which is a precision the source never claimed.\n * generated from [TrackEnrichmentData](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface TrackEnrichmentData {\n artist?: string;\n title?: string;\n album?: string;\n year?: number;\n releaseDate?: string;\n genres?: string[];\n moods?: string[];\n biography?: string;\n /** Short lines, each independently speakable */\n facts?: string[];\n /** Not an integer: a tempo a source measured rather than declared is fractional */\n bpm?: number;\n musicalKey?: string;\n label?: string;\n isrc?: string;\n /** The provider's picture as the station serves it: `art/<id>` once cached, else the station's proxy `art/source/<token>`. Never the URL the plugin supplied */\n artworkUrl?: string;\n externalIds?: EnrichmentExternalId[];\n links?: EnrichmentLink[];\n /** What the plugin said that the SDK has no field for. Per provider only: the merged view drops it. Never holds a URL: any string with one is dropped when read, along with the key or array element that held it */\n extra?: Record<string, unknown>;\n}\n\n/**\n * generated from [ArtistEnrichmentData](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface ArtistEnrichmentData {\n name?: string;\n biography?: string;\n /** The provider's picture as the station serves it: `art/<id>` once cached, else the station's proxy `art/source/<token>`. Never the URL the plugin supplied */\n imageUrl?: string;\n genres?: string[];\n facts?: string[];\n externalIds?: EnrichmentExternalId[];\n links?: EnrichmentLink[];\n extra?: Record<string, unknown>;\n}\n\n/**\n * generated from [AlbumEnrichmentData](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface AlbumEnrichmentData {\n name?: string;\n /** The record's own credit, which is not always the track's */\n artist?: string;\n year?: number;\n /** Partial, exactly as on TrackEnrichmentData */\n releaseDate?: string;\n label?: string;\n genres?: string[];\n facts?: string[];\n /** The provider's picture as the station serves it: `art/<id>` once cached, else the station's proxy `art/source/<token>`. Never the URL the plugin supplied */\n artworkUrl?: string;\n externalIds?: EnrichmentExternalId[];\n links?: EnrichmentLink[];\n extra?: Record<string, unknown>;\n}\n\n/**\n * One page of artists, with the totals the request was counted against\n * generated from [ArtistPage](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface ArtistPage {\n meta: Pagination;\n data: Artist[];\n}\n\nexport interface ArtistPageInput {\n meta: PaginationInput;\n data: ArtistInput[];\n}\n\n/**\n * One page of albums\n * generated from [AlbumPage](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface AlbumPage {\n meta: Pagination;\n data: Album[];\n}\n\nexport interface AlbumPageInput {\n meta: PaginationInput;\n data: AlbumInput[];\n}\n\n/**\n * Everything one record has accumulated, in one read.\n *\n * The enrichment is deliberately NOT here. It has its own operation already, answering\n * `TrackEnrichmentDetail` with every provider's payload and the station's own sourced claims, and\n * the console draws it through the same panel the list uses. One enrichment shape rather than two.\n * generated from [TrackDetail](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface TrackDetail extends Track {\n bindings: TrackBinding[];\n /** Absent for a record the walk has not reached */\n analysis?: TrackAnalysis;\n /** The most recent airings, newest first */\n plays: TrackPlay[];\n /** How many times in all, which the list above is only the head of */\n playCount: number;\n}\n\nexport interface TrackDetailInput extends TrackInput {\n bindings: TrackBindingInput[];\n /** Absent for a record the walk has not reached */\n analysis?: TrackAnalysisInput;\n /** The most recent airings, newest first */\n plays: TrackPlayInput[];\n}\n\n/** Rehydrates every wire-encoded scalar in a TrackDetail into its runtime type. Mutates and returns `raw`. */\nexport function reviveTrackDetail(raw: TrackDetail): TrackDetail {\n const __o0 = raw as unknown as Record<string, unknown>;\n {\n const __a1 = __o0['bindings'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveTrackBinding(__a1[__i2] as never);\n }\n }\n if (__o0['analysis'] != null) {\n reviveTrackAnalysis(__o0['analysis'] as never);\n }\n {\n const __a3 = __o0['plays'] as unknown[];\n for (let __i4 = 0; __i4 < __a3.length; __i4++) {\n reviveTrackPlay(__a3[__i4] as never);\n }\n }\n return raw;\n}\n\n/**\n * A track as a LIST shows it: the record, plus three facts about what the station has of it.\n *\n * Three booleans and no more, deliberately. They are what a row can afford — one `exists` each, off\n * the query that was already running — and everything wider (which providers, how many bytes, why the\n * last fetch failed) is `TrackDetail`'s, one click away. A fourth would be the beginning of putting\n * the detail page in a table cell.\n * generated from [TrackRow](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface TrackRow extends Track {\n /** The bytes are on this machine */\n hasAudio: boolean;\n /** Measured, COMPLETE, and at a schema version the station still trusts */\n measured: boolean;\n /** At least one provider has answered about it */\n enriched: boolean;\n}\n\nexport interface TrackRowInput extends TrackInput {}\n\n/**\n * The station's answer for one record's lyrics: the words from the source it believes, or that nobody\n * sings on it, or nothing. Timings count from the start of the file, as the vocal markers' do, so a\n * player following along adds the record's cue-in to how long it has been on air.\n * generated from [TrackLyrics](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface TrackLyrics {\n trackId: string;\n /** The words are here; a source says nobody sings on it; or no source has an answer yet */\n kind: 'words' | 'instrumental' | 'none';\n /** The plugin whose answer this is, when kind is words or instrumental */\n provider?: string;\n /** The words without timings, when that source has them */\n plain?: string;\n /** The timed lines, when that source has them. Preferred over plain when choosing a source */\n synced?: LyricLineDetail[];\n /** A BCP 47 tag, when the source stated one */\n language?: string;\n}\n\nexport interface TrackLyricsInput {}\n\n/**\n * One lyrics source's answer for one record. A source that was asked and had nothing is not listed.\n * generated from [TrackLyricsSource](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface TrackLyricsSource {\n /** The plugin that answered */\n provider: string;\n /** The source's own id for what it matched */\n providerRef?: string;\n plain?: string;\n synced?: LyricLineDetail[];\n language?: string;\n /** The source says nobody sings on this record, so it holds no words */\n instrumental: boolean;\n fetchedAt: DateTime;\n}\n\nexport interface TrackLyricsSourceInput {}\n\n/** Rehydrates every wire-encoded scalar in a TrackLyricsSource into its runtime type. Mutates and returns `raw`. */\nexport function reviveTrackLyricsSource(raw: TrackLyricsSource): TrackLyricsSource {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['fetchedAt'] = __dt(__o0['fetchedAt'], 'TrackLyricsSource.fetchedAt');\n return raw;\n}\n\n/**\n * A track list, narrowed by what the station has of each record as well as by name.\n *\n * Its own contract rather than a field on `CatalogQuery`, because that one is shared with the artist\n * and album lists where none of these states means anything.\n * generated from [TrackQuery](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface TrackQuery extends Omit<CatalogQuery, 'sortBy'> {\n state?: TrackState;\n sortBy?: TrackSort;\n}\n\nexport interface TrackQueryInput extends Omit<CatalogQueryInput, 'sortBy'> {\n state?: TrackState;\n sortBy?: TrackSort;\n}\n\n/**\n * One provider's stored answer. `found: false` is a recorded miss, which is a fact rather than a\n * failure: the provider was asked, had nothing, and is not asked again until `expiresAt`. A provider\n * that could not be asked at all is `failed` instead, and the two never both hold.\n * generated from [TrackEnrichmentSource](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface TrackEnrichmentSource {\n provider: string;\n /** The id it was fetched under. Provenance, not identity */\n providerRef?: string;\n fetchedAt: DateTime;\n expiresAt?: DateTime;\n /** Past its TTL, so the next pass will ask again */\n stale: boolean;\n found: boolean;\n /** The last attempt errored, so `expiresAt` is a backoff rather than a TTL */\n failed: boolean;\n data: TrackEnrichmentData;\n}\n\nexport interface TrackEnrichmentSourceInput {\n data: TrackEnrichmentData;\n}\n\n/** Rehydrates every wire-encoded scalar in a TrackEnrichmentSource into its runtime type. Mutates and returns `raw`. */\nexport function reviveTrackEnrichmentSource(raw: TrackEnrichmentSource): TrackEnrichmentSource {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['fetchedAt'] = __dt(__o0['fetchedAt'], 'TrackEnrichmentSource.fetchedAt');\n if (__o0['expiresAt'] != null) {\n __o0['expiresAt'] = __dt(__o0['expiresAt'], 'TrackEnrichmentSource.expiresAt');\n }\n return raw;\n}\n\n/**\n * generated from [ArtistEnrichmentSource](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface ArtistEnrichmentSource {\n provider: string;\n providerRef?: string;\n fetchedAt: DateTime;\n expiresAt?: DateTime;\n stale: boolean;\n found: boolean;\n /** The last attempt errored, so `expiresAt` is a backoff rather than a TTL */\n failed: boolean;\n data: ArtistEnrichmentData;\n}\n\nexport interface ArtistEnrichmentSourceInput {\n data: ArtistEnrichmentData;\n}\n\n/** Rehydrates every wire-encoded scalar in a ArtistEnrichmentSource into its runtime type. Mutates and returns `raw`. */\nexport function reviveArtistEnrichmentSource(raw: ArtistEnrichmentSource): ArtistEnrichmentSource {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['fetchedAt'] = __dt(__o0['fetchedAt'], 'ArtistEnrichmentSource.fetchedAt');\n if (__o0['expiresAt'] != null) {\n __o0['expiresAt'] = __dt(__o0['expiresAt'], 'ArtistEnrichmentSource.expiresAt');\n }\n return raw;\n}\n\n/**\n * generated from [AlbumEnrichmentSource](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface AlbumEnrichmentSource {\n provider: string;\n providerRef?: string;\n fetchedAt: DateTime;\n expiresAt?: DateTime;\n stale: boolean;\n found: boolean;\n /** The last attempt errored, so `expiresAt` is a backoff rather than a TTL */\n failed: boolean;\n data: AlbumEnrichmentData;\n}\n\nexport interface AlbumEnrichmentSourceInput {\n data: AlbumEnrichmentData;\n}\n\n/** Rehydrates every wire-encoded scalar in a AlbumEnrichmentSource into its runtime type. Mutates and returns `raw`. */\nexport function reviveAlbumEnrichmentSource(raw: AlbumEnrichmentSource): AlbumEnrichmentSource {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['fetchedAt'] = __dt(__o0['fetchedAt'], 'AlbumEnrichmentSource.fetchedAt');\n if (__o0['expiresAt'] != null) {\n __o0['expiresAt'] = __dt(__o0['expiresAt'], 'AlbumEnrichmentSource.expiresAt');\n }\n return raw;\n}\n\n/**\n * One page of tracks, with what the station has of each and of the whole set\n * generated from [TrackPage](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface TrackPage {\n meta: Pagination;\n data: TrackRow[];\n states: TrackStateCounts;\n}\n\nexport interface TrackPageInput {\n meta: PaginationInput;\n data: TrackRowInput[];\n states: TrackStateCountsInput;\n}\n\n/**\n * Every lyrics source's answer for one record, in the order the station believes them.\n * generated from [TrackLyricsSources](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface TrackLyricsSources {\n trackId: string;\n sources: TrackLyricsSource[];\n}\n\nexport interface TrackLyricsSourcesInput {}\n\n/** Rehydrates every wire-encoded scalar in a TrackLyricsSources into its runtime type. Mutates and returns `raw`. */\nexport function reviveTrackLyricsSources(raw: TrackLyricsSources): TrackLyricsSources {\n const __o0 = raw as unknown as Record<string, unknown>;\n {\n const __a1 = __o0['sources'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveTrackLyricsSource(__a1[__i2] as never);\n }\n }\n return raw;\n}\n\n/**\n * Every provider's answer, plus the same merge the promotion step used, so the console and the\n * canonical columns cannot tell different stories. `sources` is empty on a row the walk has not\n * reached yet.\n *\n * `claims` sits beside them rather than inside `merged`, because a claim is the host's own and not\n * any provider's. The articles they were read out of are deliberately NOT here: raw source prose is\n * stored and never sent.\n * generated from [TrackEnrichmentDetail](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface TrackEnrichmentDetail {\n trackId: string;\n merged: TrackEnrichmentData;\n sources: TrackEnrichmentSource[];\n claims: FactClaim[];\n}\n\nexport interface TrackEnrichmentDetailInput {\n merged: TrackEnrichmentData;\n sources: TrackEnrichmentSourceInput[];\n claims: FactClaimInput[];\n}\n\n/** Rehydrates every wire-encoded scalar in a TrackEnrichmentDetail into its runtime type. Mutates and returns `raw`. */\nexport function reviveTrackEnrichmentDetail(raw: TrackEnrichmentDetail): TrackEnrichmentDetail {\n const __o0 = raw as unknown as Record<string, unknown>;\n {\n const __a1 = __o0['sources'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveTrackEnrichmentSource(__a1[__i2] as never);\n }\n }\n {\n const __a3 = __o0['claims'] as unknown[];\n for (let __i4 = 0; __i4 < __a3.length; __i4++) {\n reviveFactClaim(__a3[__i4] as never);\n }\n }\n return raw;\n}\n\n/**\n * generated from [ArtistEnrichmentDetail](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface ArtistEnrichmentDetail {\n artistId: string;\n merged: ArtistEnrichmentData;\n sources: ArtistEnrichmentSource[];\n claims: FactClaim[];\n}\n\nexport interface ArtistEnrichmentDetailInput {\n merged: ArtistEnrichmentData;\n sources: ArtistEnrichmentSourceInput[];\n claims: FactClaimInput[];\n}\n\n/** Rehydrates every wire-encoded scalar in a ArtistEnrichmentDetail into its runtime type. Mutates and returns `raw`. */\nexport function reviveArtistEnrichmentDetail(raw: ArtistEnrichmentDetail): ArtistEnrichmentDetail {\n const __o0 = raw as unknown as Record<string, unknown>;\n {\n const __a1 = __o0['sources'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveArtistEnrichmentSource(__a1[__i2] as never);\n }\n }\n {\n const __a3 = __o0['claims'] as unknown[];\n for (let __i4 = 0; __i4 < __a3.length; __i4++) {\n reviveFactClaim(__a3[__i4] as never);\n }\n }\n return raw;\n}\n\n/**\n * generated from [AlbumEnrichmentDetail](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface AlbumEnrichmentDetail {\n albumId: string;\n merged: AlbumEnrichmentData;\n sources: AlbumEnrichmentSource[];\n claims: FactClaim[];\n}\n\nexport interface AlbumEnrichmentDetailInput {\n merged: AlbumEnrichmentData;\n sources: AlbumEnrichmentSourceInput[];\n claims: FactClaimInput[];\n}\n\n/** Rehydrates every wire-encoded scalar in a AlbumEnrichmentDetail into its runtime type. Mutates and returns `raw`. */\nexport function reviveAlbumEnrichmentDetail(raw: AlbumEnrichmentDetail): AlbumEnrichmentDetail {\n const __o0 = raw as unknown as Record<string, unknown>;\n {\n const __a1 = __o0['sources'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveAlbumEnrichmentSource(__a1[__i2] as never);\n }\n }\n {\n const __a3 = __o0['claims'] as unknown[];\n for (let __i4 = 0; __i4 < __a3.length; __i4++) {\n reviveFactClaim(__a3[__i4] as never);\n }\n }\n return raw;\n}\n","import type { SdkFetch } from '../sdk-options.js';\nimport { bigIntReplacer, parseJson, buildQueryString } from '../sdk-options.js';\nimport type {\n Album,\n AlbumEnrichmentDetail,\n AlbumPage,\n Artist,\n ArtistEnrichmentDetail,\n ArtistPage,\n CatalogQueryInput,\n ClearEnrichmentQuery,\n RateInput,\n Track,\n TrackClearResult,\n TrackDetail,\n TrackEnrichmentDetail,\n TrackLyrics,\n TrackLyricsSources,\n TrackPage,\n TrackQueryInput,\n VocalMarkersDetail,\n VocalMarkersInput,\n} from './types/catalog.types.js';\nimport {\n reviveAlbumEnrichmentDetail,\n reviveArtistEnrichmentDetail,\n reviveTrackDetail,\n reviveTrackEnrichmentDetail,\n reviveTrackLyricsSources,\n} from './types/catalog.types.js';\n\nexport class CatalogClient {\n constructor(private fetch: SdkFetch) {}\n\n /**\n * @name List artists\n * @description Every artist the station has ingested, ordered by name\n */\n async listArtists(query?: CatalogQueryInput): Promise<ArtistPage> {\n const qs = buildQueryString(query);\n const result = await this.fetch(`/catalog/artists${qs}`, {\n method: 'GET',\n });\n return await parseJson<ArtistPage>(result);\n }\n\n /**\n * @name Get artist\n * @description One artist. 404s on an id that was merged away, since reads never return merged rows\n */\n async getArtist(id: string): Promise<Artist> {\n const result = await this.fetch(`/catalog/artists/${encodeURIComponent(id)}`, { method: 'GET' });\n return await parseJson<Artist>(result);\n }\n\n /**\n * @name Get artist enrichment\n * @description What every enrichment provider said about this artist, and when each of them said it\n */\n async getArtistEnrichment(id: string): Promise<ArtistEnrichmentDetail> {\n const result = await this.fetch(`/catalog/artists/${encodeURIComponent(id)}/enrichment`, { method: 'GET' });\n return reviveArtistEnrichmentDetail(await parseJson<ArtistEnrichmentDetail>(result));\n }\n\n /**\n * @name List artist albums\n * @description The albums credited to one artist\n */\n async listArtistAlbums(id: string, query?: CatalogQueryInput): Promise<AlbumPage> {\n const qs = buildQueryString(query);\n const result = await this.fetch(`/catalog/artists/${encodeURIComponent(id)}/albums${qs}`, {\n method: 'GET',\n });\n return await parseJson<AlbumPage>(result);\n }\n\n /**\n * @name Rate artist\n * @description What the station thinks of this artist. A dislike here excludes every record they are credited on\n */\n async rateArtist(id: string, body: RateInput): Promise<Artist> {\n const result = await this.fetch(`/catalog/artists/${encodeURIComponent(id)}/rating`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<Artist>(result);\n }\n\n /** @name List albums */\n async listAlbums(query?: CatalogQueryInput): Promise<AlbumPage> {\n const qs = buildQueryString(query);\n const result = await this.fetch(`/catalog/albums${qs}`, {\n method: 'GET',\n });\n return await parseJson<AlbumPage>(result);\n }\n\n /** @name Get album */\n async getAlbum(id: string): Promise<Album> {\n const result = await this.fetch(`/catalog/albums/${encodeURIComponent(id)}`, { method: 'GET' });\n return await parseJson<Album>(result);\n }\n\n /**\n * @name Get album enrichment\n * @description The record's own enrichment: the label, pressing and cover belong to the release, not to a track on it\n */\n async getAlbumEnrichment(id: string): Promise<AlbumEnrichmentDetail> {\n const result = await this.fetch(`/catalog/albums/${encodeURIComponent(id)}/enrichment`, { method: 'GET' });\n return reviveAlbumEnrichmentDetail(await parseJson<AlbumEnrichmentDetail>(result));\n }\n\n /**\n * @name List album tracks\n * @description One album's tracks\n */\n async listAlbumTracks(id: string, query?: TrackQueryInput): Promise<TrackPage> {\n const qs = buildQueryString(query);\n const result = await this.fetch(`/catalog/albums/${encodeURIComponent(id)}/tracks${qs}`, {\n method: 'GET',\n });\n return await parseJson<TrackPage>(result);\n }\n\n /**\n * @name Rate album\n * @description What the station thinks of this record. A dislike here excludes every track on it\n */\n async rateAlbum(id: string, body: RateInput): Promise<Album> {\n const result = await this.fetch(`/catalog/albums/${encodeURIComponent(id)}/rating`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<Album>(result);\n }\n\n /**\n * @name Get track\n * @description One record and everything it has accumulated: its copies, its bytes, its measurement, what it has aired\n */\n async getTrack(id: string): Promise<TrackDetail> {\n const result = await this.fetch(`/catalog/tracks/${encodeURIComponent(id)}`, { method: 'GET' });\n return reviveTrackDetail(await parseJson<TrackDetail>(result));\n }\n\n /**\n * @name Clear track audio\n * @description Drop the station's own copies of this record. The next play fetches them again\n */\n async clearTrackAudio(id: string): Promise<TrackClearResult> {\n const result = await this.fetch(`/catalog/tracks/${encodeURIComponent(id)}/audio`, { method: 'DELETE' });\n return await parseJson<TrackClearResult>(result);\n }\n\n /**\n * @name Clear track analysis\n * @description Forget the measurement, so the walk takes it again\n */\n async clearTrackAnalysis(id: string): Promise<TrackClearResult> {\n const result = await this.fetch(`/catalog/tracks/${encodeURIComponent(id)}/analysis`, { method: 'DELETE' });\n return await parseJson<TrackClearResult>(result);\n }\n\n /**\n * @name Get vocal markers\n * @description Where the singing starts and stops on one record, from an operator's correction or its timed lyrics\n */\n async getVocalMarkers(id: string): Promise<VocalMarkersDetail> {\n const result = await this.fetch(`/catalog/tracks/${encodeURIComponent(id)}/vocal-markers`, { method: 'GET' });\n return await parseJson<VocalMarkersDetail>(result);\n }\n\n /**\n * @name Set vocal markers\n * @description Correct where the singing starts and stops, over whatever the lyrics say\n */\n async setVocalMarkers(id: string, body: VocalMarkersInput): Promise<VocalMarkersDetail> {\n const result = await this.fetch(`/catalog/tracks/${encodeURIComponent(id)}/vocal-markers`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<VocalMarkersDetail>(result);\n }\n\n /**\n * @name Clear vocal markers\n * @description Drop the correction, so the record's timed lyrics decide again\n */\n async clearVocalMarkers(id: string): Promise<VocalMarkersDetail> {\n const result = await this.fetch(`/catalog/tracks/${encodeURIComponent(id)}/vocal-markers`, { method: 'DELETE' });\n return await parseJson<VocalMarkersDetail>(result);\n }\n\n /**\n * @name Get track lyrics\n * @description The words of one record, from the lyrics source the station believes, with the timing of each line when that source has it\n */\n async getTrackLyrics(id: string): Promise<TrackLyrics> {\n const result = await this.fetch(`/catalog/tracks/${encodeURIComponent(id)}/lyrics`, { method: 'GET' });\n return await parseJson<TrackLyrics>(result);\n }\n\n /**\n * @name List track lyrics sources\n * @description What every lyrics source answered for one record, in the order the station believes them\n */\n async listTrackLyricsSources(id: string): Promise<TrackLyricsSources> {\n const result = await this.fetch(`/catalog/tracks/${encodeURIComponent(id)}/lyrics/sources`, { method: 'GET' });\n return reviveTrackLyricsSources(await parseJson<TrackLyricsSources>(result));\n }\n\n /**\n * @name Retry track audio\n * @description Try this record's copies again now, rather than when the backoff says\n */\n async retryTrackAudio(id: string): Promise<TrackClearResult> {\n const result = await this.fetch(`/catalog/tracks/${encodeURIComponent(id)}/retry`, { method: 'POST' });\n return await parseJson<TrackClearResult>(result);\n }\n\n /**\n * @name Offer track copies again\n * @description Put copies a provider refused back on offer, and clear their backoff so they are tried now\n */\n async offerTrackCopiesAgain(id: string): Promise<TrackClearResult> {\n const result = await this.fetch(`/catalog/tracks/${encodeURIComponent(id)}/offer`, { method: 'POST' });\n return await parseJson<TrackClearResult>(result);\n }\n\n /**\n * @name Get track enrichment\n * @description What the providers said about one recording, including everything no canonical column holds\n */\n async getTrackEnrichment(id: string): Promise<TrackEnrichmentDetail> {\n const result = await this.fetch(`/catalog/tracks/${encodeURIComponent(id)}/enrichment`, { method: 'GET' });\n return reviveTrackEnrichmentDetail(await parseJson<TrackEnrichmentDetail>(result));\n }\n\n /**\n * @name Clear track enrichment\n * @description Forget what the providers said, so the enrichment pass asks again\n */\n async clearTrackEnrichment(id: string, query?: ClearEnrichmentQuery): Promise<TrackClearResult> {\n const qs = buildQueryString(query);\n const result = await this.fetch(`/catalog/tracks/${encodeURIComponent(id)}/enrichment${qs}`, {\n method: 'DELETE',\n });\n return await parseJson<TrackClearResult>(result);\n }\n\n /**\n * @name List tracks\n * @description Every track, flat. The only way to answer \"do we have this song?\" without knowing its artist\n */\n async listTracks(query?: TrackQueryInput): Promise<TrackPage> {\n const qs = buildQueryString(query);\n const result = await this.fetch(`/catalog/tracks${qs}`, {\n method: 'GET',\n });\n return await parseJson<TrackPage>(result);\n }\n\n /**\n * @name Rate track\n * @description What the station thinks of this song, which is the narrowest thing an opinion can be about\n */\n async rateTrack(id: string, body: RateInput): Promise<Track> {\n const result = await this.fetch(`/catalog/tracks/${encodeURIComponent(id)}/rating`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<Track>(result);\n }\n}\n","import type { SdkFetch } from '../sdk-options.js';\nimport { parseJson, buildQueryString } from '../sdk-options.js';\nimport type { ChartPage, ChartQuery, StationChartList } from './types/charts.types.js';\n\nexport class ChartsClient {\n constructor(private fetch: SdkFetch) {}\n\n /**\n * @name List charts\n * @description Every chart every installed chart plugin currently offers\n */\n async listCharts(): Promise<StationChartList> {\n const result = await this.fetch(`/charts`, { method: 'GET' });\n return await parseJson<StationChartList>(result);\n }\n\n /**\n * @name Read chart\n * @description One chart's records, ranked\n */\n async readChart(id: string, query?: ChartQuery): Promise<ChartPage> {\n const qs = buildQueryString(query);\n const result = await this.fetch(`/charts/${encodeURIComponent(id)}${qs}`, {\n method: 'GET',\n });\n return await parseJson<ChartPage>(result);\n }\n}\n","import { DateTime } from 'luxon';\nconst __dt = (v: unknown, path: string): DateTime => {\n if (typeof v !== 'string') {\n throw new TypeError(`ContractKit: expected an ISO 8601 string at '${path}', received ${typeof v}.`);\n }\n const d = DateTime.fromISO(v);\n if (!d.isValid) throw new TypeError(`ContractKit: '${v}' at '${path}' is not a valid ISO 8601 datetime.`);\n return d;\n};\n\n/**\n * A never-play rule: a KIND of record the station must not play. Absolute, like a dislike, and\n * exclude-only: there is no \"only these\" rule, because one could leave the station nothing to play.\n * Every scope is optional and an absent one means \"always\"\n * generated from [BlockRule](../../../../../apps/api/data/contracts/director/rules.types.ck)\n */\nexport interface BlockRule {\n id: string;\n /** `genre` refuses any record tagged with this genre or a kind of it (`Punk Rock` under `Punk`, never `Pop` under `Pop Punk`, never `Trap` under `Rap`). `tag` refuses a record carrying exactly this tag. `version` refuses a version of a record, read from the markers on its title and album: `live` refuses a live recording (\"War Pigs - Live\", anything from \"Live in Nottingham\"), and never a title that merely says the word (\"Live Wire\") */\n field: 'genre' | 'tag' | 'version';\n /** The genre or tag, as you would write it. For a `version` rule, the version: `live` is the only one */\n value: string;\n /** First day it holds, as `MM-DD`. With `seasonTo`; a season starting after it ends wraps the year end */\n seasonFrom?: string;\n /** Last day it holds, as `MM-DD` */\n seasonTo?: string;\n /** First hour of the station's day it holds. With `untilHour`; a window starting after it ends wraps midnight */\n fromHour?: number;\n /** The hour it stops holding, exclusive */\n untilHour?: number;\n /** Only while the station is in one of these modes. Absent or empty means every mode */\n modes?: ('rotation' | 'setlist' | 'feature')[];\n /** Only during these schedule blocks. Absent or empty means whatever is on */\n slotIds?: string[];\n /** When it stops holding. Absent means until it is removed */\n endsAt?: DateTime;\n /** Whether it holds right now, on the station's clock, for what is on air */\n inForce: boolean;\n}\n\nexport interface BlockRuleInput {\n /** `genre` refuses any record tagged with this genre or a kind of it (`Punk Rock` under `Punk`, never `Pop` under `Pop Punk`, never `Trap` under `Rap`). `tag` refuses a record carrying exactly this tag. `version` refuses a version of a record, read from the markers on its title and album: `live` refuses a live recording (\"War Pigs - Live\", anything from \"Live in Nottingham\"), and never a title that merely says the word (\"Live Wire\") */\n field: 'genre' | 'tag' | 'version';\n /** The genre or tag, as you would write it. For a `version` rule, the version: `live` is the only one */\n value: string;\n /** First day it holds, as `MM-DD`. With `seasonTo`; a season starting after it ends wraps the year end */\n seasonFrom?: string;\n /** Last day it holds, as `MM-DD` */\n seasonTo?: string;\n /** First hour of the station's day it holds. With `untilHour`; a window starting after it ends wraps midnight */\n fromHour?: number;\n /** The hour it stops holding, exclusive */\n untilHour?: number;\n /** Only while the station is in one of these modes. Absent or empty means every mode */\n modes?: ('rotation' | 'setlist' | 'feature')[];\n /** Only during these schedule blocks. Absent or empty means whatever is on */\n slotIds?: string[];\n /** When it stops holding. Absent means until it is removed */\n endsAt?: DateTime;\n}\n\n/** Rehydrates every wire-encoded scalar in a BlockRule into its runtime type. Mutates and returns `raw`. */\nexport function reviveBlockRule(raw: BlockRule): BlockRule {\n const __o0 = raw as unknown as Record<string, unknown>;\n if (__o0['endsAt'] != null) {\n __o0['endsAt'] = __dt(__o0['endsAt'], 'BlockRule.endsAt');\n }\n return raw;\n}\n\n/**\n * A lean toward some genres for a while. The opposite of a rule: the station favours them when it\n * chooses records, and still plays anything else rather than run dry\n * generated from [GenreSteer](../../../../../apps/api/data/contracts/director/rules.types.ck)\n */\nexport interface GenreSteer {\n /** What to favour, as genres. A record tagged with any of them, or a kind of one, is preferred */\n genres: string[];\n /** When the station goes back to choosing as it ordinarily does */\n endsAt: DateTime;\n}\n\n/** Rehydrates every wire-encoded scalar in a GenreSteer into its runtime type. Mutates and returns `raw`. */\nexport function reviveGenreSteer(raw: GenreSteer): GenreSteer {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['endsAt'] = __dt(__o0['endsAt'], 'GenreSteer.endsAt');\n return raw;\n}\n\n/**\n * Lean the station toward some genres for a number of hours\n * generated from [GenreSteerInput](../../../../../apps/api/data/contracts/director/rules.types.ck)\n */\nexport interface GenreSteerInput {\n genres: string[];\n /** How long it lasts, from now */\n hours: number;\n}\n\n/**\n * Every rule on the station, newest first\n * generated from [BlockRuleList](../../../../../apps/api/data/contracts/director/rules.types.ck)\n */\nexport interface BlockRuleList {\n rules: BlockRule[];\n}\n\nexport interface BlockRuleListInput {\n rules: BlockRuleInput[];\n}\n\n/** Rehydrates every wire-encoded scalar in a BlockRuleList into its runtime type. Mutates and returns `raw`. */\nexport function reviveBlockRuleList(raw: BlockRuleList): BlockRuleList {\n const __o0 = raw as unknown as Record<string, unknown>;\n {\n const __a1 = __o0['rules'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveBlockRule(__a1[__i2] as never);\n }\n }\n return raw;\n}\n\n/**\n * The lean in force, or none\n * generated from [GenreSteerReading](../../../../../apps/api/data/contracts/director/rules.types.ck)\n */\nexport interface GenreSteerReading {\n /** Absent when nothing is leaning the station, including once one has run out */\n steer?: GenreSteer;\n}\n\n/** Rehydrates every wire-encoded scalar in a GenreSteerReading into its runtime type. Mutates and returns `raw`. */\nexport function reviveGenreSteerReading(raw: GenreSteerReading): GenreSteerReading {\n const __o0 = raw as unknown as Record<string, unknown>;\n if (__o0['steer'] != null) {\n reviveGenreSteer(__o0['steer'] as never);\n }\n return raw;\n}\n","import type { SdkFetch } from '../sdk-options.js';\nimport { bigIntReplacer, parseJson } from '../sdk-options.js';\nimport type { ClockBandInput, ClockBandList } from './types/clock.types.js';\nimport type {\n AddStationSegmentInput,\n AddStationTrackInput,\n ArtistRoute,\n ExtendStationInput,\n HoldStationInput,\n MoveStationItemInput,\n PutOnAirInput,\n ReplanStationInput,\n RequestStationBreakInput,\n RoutePreviewInput,\n SetStationAirInput,\n SetStationHostInput,\n StationAir,\n StationBreakRequest,\n StationOrder,\n} from './types/director.types.js';\nimport type { BlockRuleInput, BlockRuleList, GenreSteerInput, GenreSteerReading } from './types/rules.types.js';\nimport { reviveBlockRuleList, reviveGenreSteerReading } from './types/rules.types.js';\n\nexport class DirectorClient {\n constructor(private fetch: SdkFetch) {}\n\n /**\n * @name List clock bands\n * @description Every band on this station's clock, including the ones switched off, in the operator's own order\n */\n async listClockBands(): Promise<ClockBandList> {\n const result = await this.fetch(`/clock/bands`, { method: 'GET' });\n return await parseJson<ClockBandList>(result);\n }\n\n /**\n * @name Create clock band\n * @description Adds a band. It claims its first boundary on the next commit pass\n */\n async createClockBand(body: ClockBandInput): Promise<ClockBandList> {\n const result = await this.fetch(`/clock/bands`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<ClockBandList>(result);\n }\n\n /**\n * @name Update clock band\n * @description Rewrites one band. Breaks it has already planted stay where they are: the running order is the memory\n */\n async updateClockBand(id: string, body: ClockBandInput): Promise<ClockBandList> {\n const result = await this.fetch(`/clock/bands/${encodeURIComponent(id)}`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<ClockBandList>(result);\n }\n\n /**\n * @name Delete clock band\n * @description Removes a band, which costs it the boundaries it had not claimed yet and nothing else\n */\n async deleteClockBand(id: string): Promise<ClockBandList> {\n const result = await this.fetch(`/clock/bands/${encodeURIComponent(id)}`, { method: 'DELETE' });\n return await parseJson<ClockBandList>(result);\n }\n\n /**\n * @name Get station air\n * @description What the station is airing, and whether it is driving at all\n */\n async getStationAir(): Promise<StationAir> {\n const result = await this.fetch(`/director/air`, { method: 'GET' });\n return await parseJson<StationAir>(result);\n }\n\n /**\n * @name Put the station on air\n * @description Puts the station on air, building the running order from a playlist read at this moment. What is playing finishes: changing the programming is not a reason to cut a listener off mid-track\n */\n async putTheStationOnAir(body: PutOnAirInput): Promise<StationAir> {\n const result = await this.fetch(`/director/air`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<StationAir>(result);\n }\n\n /**\n * @name Set the air mode\n * @description Changes what puts the station on air: only while somebody is listening, or whenever there is a programme. Takes effect at once rather than at the next boundary\n */\n async setTheAirMode(body: SetStationAirInput): Promise<StationAir> {\n const result = await this.fetch(`/director/air`, {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<StationAir>(result);\n }\n\n /**\n * @name Get the running order\n * @description The live running order, item by item, each saying where it has got to\n */\n async getTheRunningOrder(): Promise<StationOrder> {\n const result = await this.fetch(`/director/air/order`, { method: 'GET' });\n return await parseJson<StationOrder>(result);\n }\n\n /**\n * @name Recast the broadcast\n * @description Changes who is presenting this broadcast. Breaks already written for it in the outgoing character are written again in the new one\n */\n async recastTheBroadcast(body: SetStationHostInput): Promise<StationOrder> {\n const result = await this.fetch(`/director/air/persona`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<StationOrder>(result);\n }\n\n /**\n * @name Extend the running order\n * @description Queues a refill and returns at once. Generating a set walks the catalog, and an operator pressing a button should not be held open through it\n */\n async extendTheRunningOrder(body: ExtendStationInput): Promise<void> {\n await this.fetch(`/director/air/extend`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n }\n\n /**\n * @name Replan the running order\n * @description Queues a fresh set for everything the player is not already holding, and swaps it in once it exists. The old tail keeps playing until then, because emptying the running order first would take the station off air while the model was still choosing\n */\n async replanTheRunningOrder(body: ReplanStationInput): Promise<void> {\n await this.fetch(`/director/air/replan`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n }\n\n /**\n * @name Request a break\n * @description Asks the station to say something now rather than when the format clock next calls for it: the news, the weather, a word from the host. The director decides where it goes. A decline is answered rather than thrown, with the station's reason, because \"breaks are off\" and \"it was asked for a moment ago\" are things the person pressing the button needs to read\n */\n async requestABreak(body: RequestStationBreakInput): Promise<StationBreakRequest> {\n const result = await this.fetch(`/director/air/breaks`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<StationBreakRequest>(result);\n }\n\n /**\n * @name Preview an artist route\n * @description Finds a route from one artist to another through artists the library holds, and says how each stop connects to the one before. Nothing goes on air: this is what a route would be\n */\n async previewAnArtistRoute(body: RoutePreviewInput): Promise<ArtistRoute> {\n const result = await this.fetch(`/director/route/preview`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<ArtistRoute>(result);\n }\n\n /**\n * @name Hold the station against the schedule\n * @description Holds the running order against the schedule, so a block boundary does not take back what an operator put on. A takeover is otherwise stamped with whichever slot was in force and is replaced when that block ends, which is correct and gives nobody any warning\n */\n async holdTheStationAgainstTheSchedule(body: HoldStationInput): Promise<StationAir> {\n const result = await this.fetch(`/director/air/hold`, {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<StationAir>(result);\n }\n\n /**\n * @name Release the station to the schedule\n * @description Releases a hold, so the next block boundary changes the station over as it ordinarily would. A station with no hold is unchanged rather than refused\n */\n async releaseTheStationToTheSchedule(): Promise<StationAir> {\n const result = await this.fetch(`/director/air/hold`, { method: 'DELETE' });\n return await parseJson<StationAir>(result);\n }\n\n /**\n * @name Shuffle the running order\n * @description Shuffles the records not yet handed to the player, and plants the breaks again around the new sequence. The head is already in the player's hands and is left alone\n */\n async shuffleTheRunningOrder(): Promise<StationOrder> {\n const result = await this.fetch(`/director/air/shuffle`, { method: 'POST' });\n return await parseJson<StationOrder>(result);\n }\n\n /**\n * @name Add a segment to the running order\n * @description Puts something the station says into the running order. A segment with no audio yet is refused here rather than accepted and skipped when it comes round, so an operator is told why it cannot play\n */\n async addASegmentToTheRunningOrder(body: AddStationSegmentInput): Promise<StationOrder> {\n const result = await this.fetch(`/director/air/segments`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<StationOrder>(result);\n }\n\n /**\n * @name Add a record to the running order\n * @description Puts a catalog record into the running order. A record whose audio is not local yet is refused here rather than accepted and held or skipped when its slot comes round, so an operator asking for a specific one is told why it cannot play. What makes this worth having on its own is undo: dropping an item only ever marks a segment, but a track is spliced out of the order entirely, so nothing could put one back until this existed\n */\n async addARecordToTheRunningOrder(body: AddStationTrackInput): Promise<StationOrder> {\n const result = await this.fetch(`/director/air/tracks`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<StationOrder>(result);\n }\n\n /**\n * @name Move a running order item\n * @description Moves an item. A position already handed to the player is refused rather than clamped\n */\n async moveARunningOrderItem(itemId: string, body: MoveStationItemInput): Promise<StationOrder> {\n const result = await this.fetch(`/director/air/items/${encodeURIComponent(itemId)}`, {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<StationOrder>(result);\n }\n\n /**\n * @name Remove a running order item\n * @description Drops an item that has not been handed to the player yet\n */\n async removeARunningOrderItem(itemId: string): Promise<StationOrder> {\n const result = await this.fetch(`/director/air/items/${encodeURIComponent(itemId)}`, { method: 'DELETE' });\n return await parseJson<StationOrder>(result);\n }\n\n /**\n * @name Skip to a running order item\n * @description Makes a record further down the running order the next thing heard. Everything still to come in front of it is marked skipped, anything the player was already holding from in front of it is taken back, and the item on air is cut. Only a record can be skipped to, and only one still to come\n */\n async skipToARunningOrderItem(itemId: string): Promise<StationOrder> {\n const result = await this.fetch(`/director/air/items/${encodeURIComponent(itemId)}/skip-to`, { method: 'POST' });\n return await parseJson<StationOrder>(result);\n }\n\n /**\n * @name List never-play rules\n * @description Every never-play rule on this station, newest first, each saying whether it holds right now\n */\n async listNeverPlayRules(): Promise<BlockRuleList> {\n const result = await this.fetch(`/rules`, { method: 'GET' });\n return reviveBlockRuleList(await parseJson<BlockRuleList>(result));\n }\n\n /**\n * @name Add a never-play rule\n * @description Adds a rule. It holds from the next record the station chooses\n */\n async addANeverPlayRule(body: BlockRuleInput): Promise<BlockRuleList> {\n const result = await this.fetch(`/rules`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return reviveBlockRuleList(await parseJson<BlockRuleList>(result));\n }\n\n /**\n * @name Read the genre steer\n * @description The lean in force, if any\n */\n async readTheGenreSteer(): Promise<GenreSteerReading> {\n const result = await this.fetch(`/rules/steer`, { method: 'GET' });\n return reviveGenreSteerReading(await parseJson<GenreSteerReading>(result));\n }\n\n /**\n * @name Steer toward genres\n * @description Leans the station toward some genres for a number of hours, replacing any lean already in force\n */\n async steerTowardGenres(body: GenreSteerInput): Promise<GenreSteerReading> {\n const result = await this.fetch(`/rules/steer`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return reviveGenreSteerReading(await parseJson<GenreSteerReading>(result));\n }\n\n /**\n * @name Stop steering\n * @description Ends the lean now\n */\n async stopSteering(): Promise<GenreSteerReading> {\n const result = await this.fetch(`/rules/steer`, { method: 'DELETE' });\n return reviveGenreSteerReading(await parseJson<GenreSteerReading>(result));\n }\n\n /**\n * @name Change a never-play rule\n * @description Replaces a rule\n */\n async changeANeverPlayRule(id: string, body: BlockRuleInput): Promise<BlockRuleList> {\n const result = await this.fetch(`/rules/${encodeURIComponent(id)}`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return reviveBlockRuleList(await parseJson<BlockRuleList>(result));\n }\n\n /**\n * @name Remove a never-play rule\n * @description Removes a rule\n */\n async removeANeverPlayRule(id: string): Promise<BlockRuleList> {\n const result = await this.fetch(`/rules/${encodeURIComponent(id)}`, { method: 'DELETE' });\n return reviveBlockRuleList(await parseJson<BlockRuleList>(result));\n }\n}\n","import { DateTime } from 'luxon';\nconst __dt = (v: unknown, path: string): DateTime => {\n if (typeof v !== 'string') {\n throw new TypeError(`ContractKit: expected an ISO 8601 string at '${path}', received ${typeof v}.`);\n }\n const d = DateTime.fromISO(v);\n if (!d.isValid) throw new TypeError(`ContractKit: '${v}' at '${path}' is not a valid ISO 8601 datetime.`);\n return d;\n};\n\n/**\n * Somewhere the station sends what happens on it: an operator's own server, sent a signed POST per event\n * generated from [EventDestination](../../../../../apps/api/data/contracts/events/events.types.ck)\n */\nexport interface EventDestination {\n id: string;\n /** What the operator calls it */\n name: string;\n /** Where events are POSTed. http or https, and allowed to be on the station's own network. A redirect is never followed */\n url: string;\n /** Off sends nothing */\n enabled: boolean;\n /** The event types it is sent, from `/events/types`. Empty means every type, including any added later */\n events: string[];\n /** Deliveries in a row that did not arrive. Any delivery that arrives sets it back to nothing; at twenty the station turns the destination off */\n consecutiveFailures: number;\n /** Set when the station turned it off itself, because it kept failing. Turning it back on clears this and the count */\n disabledReason?: 'failing';\n lastDeliveredAt?: DateTime;\n lastFailedAt?: DateTime;\n /** What went wrong last time, in the station's words */\n lastFailure?: string;\n createdAt: DateTime;\n updatedAt: DateTime;\n}\n\nexport interface EventDestinationInput {\n /** What the operator calls it */\n name: string;\n /** Where events are POSTed. http or https, and allowed to be on the station's own network. A redirect is never followed */\n url: string;\n /** Off sends nothing */\n enabled: boolean;\n /** The event types it is sent, from `/events/types`. Empty means every type, including any added later */\n events: string[];\n}\n\n/** Rehydrates every wire-encoded scalar in a EventDestination into its runtime type. Mutates and returns `raw`. */\nexport function reviveEventDestination(raw: EventDestination): EventDestination {\n const __o0 = raw as unknown as Record<string, unknown>;\n if (__o0['lastDeliveredAt'] != null) {\n __o0['lastDeliveredAt'] = __dt(__o0['lastDeliveredAt'], 'EventDestination.lastDeliveredAt');\n }\n if (__o0['lastFailedAt'] != null) {\n __o0['lastFailedAt'] = __dt(__o0['lastFailedAt'], 'EventDestination.lastFailedAt');\n }\n __o0['createdAt'] = __dt(__o0['createdAt'], 'EventDestination.createdAt');\n __o0['updatedAt'] = __dt(__o0['updatedAt'], 'EventDestination.updatedAt');\n return raw;\n}\n\n/**\n * A new event destination\n * generated from [EventDestinationCreate](../../../../../apps/api/data/contracts/events/events.types.ck)\n */\nexport interface EventDestinationCreate {\n name: string;\n url: string;\n /** Defaults to on */\n enabled?: boolean;\n /** The event types to send it. Absent or empty means every type */\n events?: string[];\n}\n\n/**\n * Changes to an event destination. Only what is sent changes\n * generated from [EventDestinationUpdate](../../../../../apps/api/data/contracts/events/events.types.ck)\n */\nexport interface EventDestinationUpdate {\n name?: string;\n url?: string;\n /** Turning a destination back on also clears why the station turned it off, and its count of failures */\n enabled?: boolean;\n /** Empty means every type */\n events?: string[];\n}\n\n/**\n * The secret deliveries to a destination are signed with. Shown only when it is made, so keep it\n * generated from [EventDestinationSecret](../../../../../apps/api/data/contracts/events/events.types.ck)\n */\nexport interface EventDestinationSecret {\n /** Put this in the receiver. Each delivery carries `Deadair-Webhook-Signature: v1=<hex HMAC-SHA256 of \"<Deadair-Webhook-Timestamp>.<body>\">` */\n secret: string;\n}\n\n/**\n * One attempt at sending an event to a destination\n * generated from [EventDelivery](../../../../../apps/api/data/contracts/events/events.types.ck)\n */\nexport interface EventDelivery {\n id: string;\n /** The event's own id, which every attempt at it shares */\n eventId: string;\n eventType: string;\n attempt: number;\n /** `dropped` is an event no longer worth sending, such as a record that finished playing while its destination was down */\n outcome: 'delivered' | 'failed' | 'dropped';\n /** What the destination answered, when it answered at all */\n httpStatus?: number;\n durationMs: number;\n /** What went wrong, in the station's words. Never the destination's response body */\n error?: string;\n createdAt: DateTime;\n}\n\n/** Rehydrates every wire-encoded scalar in a EventDelivery into its runtime type. Mutates and returns `raw`. */\nexport function reviveEventDelivery(raw: EventDelivery): EventDelivery {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['createdAt'] = __dt(__o0['createdAt'], 'EventDelivery.createdAt');\n return raw;\n}\n\n/**\n * What a test delivery came to\n * generated from [EventTestResult](../../../../../apps/api/data/contracts/events/events.types.ck)\n */\nexport interface EventTestResult {\n delivered: boolean;\n /** What the destination answered, when it answered at all */\n httpStatus?: number;\n durationMs: number;\n /** Why it was not delivered, in the station's words */\n error?: string;\n}\n\n/**\n * Which station sent an event\n * generated from [EventStation](../../../../../apps/api/data/contracts/events/events.types.ck)\n */\nexport interface EventStation {\n key: string;\n name: string;\n}\n\n/**\n * `data` of `track.started`: a record began playing, as listeners heard it\n * generated from [TrackStartedData](../../../../../apps/api/data/contracts/events/events.types.ck)\n */\nexport interface TrackStartedData {\n /** The running order's id for this play */\n itemId: string;\n title: string;\n /** The credit as the release writes it */\n artists: string[];\n /** The credit as one line, for showing */\n artist: string;\n album?: string;\n year?: number;\n /** The station's catalog id, where the record is in the catalog */\n trackId?: string;\n durationMs?: number;\n /** When it should finish, as an ISO-8601 instant in UTC */\n endsAt?: string;\n /** The cover as the station serves it publicly, or the station's logo. Absent when the station has no public address */\n artworkUrl?: string;\n}\n\n/**\n * `data` of `talk.started`: the station began speaking, in a break or a bulletin\n * generated from [TalkStartedData](../../../../../apps/api/data/contracts/events/events.types.ck)\n */\nexport interface TalkStartedData {\n itemId: string;\n segmentId: string;\n /** What sort of break: `talkbreak`, `news`, `weather`, `welcome` and so on */\n kind: string;\n /** What a listener may be told it is, where the writer said */\n label?: string;\n durationMs?: number;\n /** When it should finish, as an ISO-8601 instant in UTC */\n endsAt?: string;\n}\n\n/**\n * `data` of `production.started`: a produced piece, such as a phone-in or a guest, began. Sent once per production\n * generated from [ProductionStartedData](../../../../../apps/api/data/contracts/events/events.types.ck)\n */\nexport interface ProductionStartedData {\n itemId: string;\n productionId: string;\n /** What sort of production: `callin`, `visit`, `banter` and so on */\n kind: string;\n title: string;\n durationMs?: number;\n /** When it should finish, as an ISO-8601 instant in UTC */\n endsAt?: string;\n}\n\n/**\n * `data` of `programme.started`: a programme the station carries began, a podcast episode or a reading\n * generated from [ProgrammeStartedData](../../../../../apps/api/data/contracts/events/events.types.ck)\n */\nexport interface ProgrammeStartedData {\n itemId: string;\n segmentId: string;\n /** A podcast episode as published, or something the station reads out itself */\n source: 'podcast' | 'narration';\n show?: string;\n episode: string;\n durationMs?: number;\n /** When it should finish, as an ISO-8601 instant in UTC */\n endsAt?: string;\n}\n\n/**\n * `data` of `station.onAir` and `station.offAir`: the station went on air, or came off it\n * generated from [StationAirData](../../../../../apps/api/data/contracts/events/events.types.ck)\n */\nexport interface StationAirData {\n /** A new running order, the stopped one started again, somebody stopping it, or the running order running out */\n reason: 'programme' | 'resumed' | 'stopped' | 'ranOut';\n /** The running order's name, when going on air with a new one that has one */\n programme?: string;\n}\n\n/**\n * Who a request is dedicated to, and what the listener wanted said. The listener's own words\n * generated from [RequestDedication](../../../../../apps/api/data/contracts/events/events.types.ck)\n */\nexport interface RequestDedication {\n to?: string;\n message?: string;\n}\n\n/**\n * Every event destination, oldest first\n * generated from [EventDestinationList](../../../../../apps/api/data/contracts/events/events.types.ck)\n */\nexport interface EventDestinationList {\n destinations: EventDestination[];\n}\n\nexport interface EventDestinationListInput {\n destinations: EventDestinationInput[];\n}\n\n/** Rehydrates every wire-encoded scalar in a EventDestinationList into its runtime type. Mutates and returns `raw`. */\nexport function reviveEventDestinationList(raw: EventDestinationList): EventDestinationList {\n const __o0 = raw as unknown as Record<string, unknown>;\n {\n const __a1 = __o0['destinations'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveEventDestination(__a1[__i2] as never);\n }\n }\n return raw;\n}\n\n/**\n * A destination just made, with its secret\n * generated from [EventDestinationCreated](../../../../../apps/api/data/contracts/events/events.types.ck)\n */\nexport type EventDestinationCreated = EventDestination & EventDestinationSecret;\nexport type EventDestinationCreatedInput = EventDestinationInput & EventDestinationSecret;\n\n/** Rehydrates every wire-encoded scalar in a EventDestinationCreated into its runtime type. Mutates and returns `raw`. */\nexport function reviveEventDestinationCreated(raw: EventDestinationCreated): EventDestinationCreated {\n const __v = [raw] as unknown[];\n reviveEventDestination(__v[0] as never);\n return __v[0] as EventDestinationCreated;\n}\n\n/**\n * A destination's latest delivery attempts, newest first. The station keeps the latest fifty\n * generated from [EventDeliveryList](../../../../../apps/api/data/contracts/events/events.types.ck)\n */\nexport interface EventDeliveryList {\n deliveries: EventDelivery[];\n}\n\n/** Rehydrates every wire-encoded scalar in a EventDeliveryList into its runtime type. Mutates and returns `raw`. */\nexport function reviveEventDeliveryList(raw: EventDeliveryList): EventDeliveryList {\n const __o0 = raw as unknown as Record<string, unknown>;\n {\n const __a1 = __o0['deliveries'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveEventDelivery(__a1[__i2] as never);\n }\n }\n return raw;\n}\n\n/**\n * One event, as a destination receives it. The same shape for every type: read `type`, then `data`\n * generated from [EventEnvelope](../../../../../apps/api/data/contracts/events/events.types.ck)\n */\nexport interface EventEnvelope {\n /** The event's own id. A redelivery of the same event carries the same one */\n id: string;\n /** What happened, such as `track.started` */\n type: string;\n /** When, as an ISO-8601 instant in UTC */\n occurredAt: string;\n station: EventStation;\n /** What the type says it holds. `/events/types` gives an example of each */\n data: Record<string, unknown>;\n}\n\n/**\n * `data` of `request.received`: a listener asked for a record, from an app, the console, a party pass or a chat\n * generated from [RequestReceivedData](../../../../../apps/api/data/contracts/events/events.types.ck)\n */\nexport interface RequestReceivedData {\n requestId: string;\n trackId: string;\n title: string;\n artist: string;\n /** What the listener is called, as the station names them */\n requesterName: string;\n /** Where they asked from. `app` covers the console, the listener apps and a party pass */\n via: 'app' | 'chat';\n /** How it stands now: waiting on an operator, waiting on its audio, in the running order, or declined */\n status: 'waiting' | 'pending' | 'queued' | 'aired' | 'declined' | 'expired';\n /** Why it was declined, as the listener is told */\n reason?: string;\n /** The listener asked for it again after the station turned it down for its own taste */\n insisted?: boolean;\n dedication?: RequestDedication;\n}\n\n/**\n * One kind of event the station sends\n * generated from [EventType](../../../../../apps/api/data/contracts/events/events.types.ck)\n */\nexport interface EventType {\n type: string;\n /** When it is sent, and what its `data` holds */\n description: string;\n /** False for the test event, which only a test delivery sends */\n subscribable: boolean;\n example: EventEnvelope;\n}\n\n/**\n * Every kind of event the station sends\n * generated from [EventTypeList](../../../../../apps/api/data/contracts/events/events.types.ck)\n */\nexport interface EventTypeList {\n types: EventType[];\n}\n","import type { SdkFetch } from '../sdk-options.js';\nimport { bigIntReplacer, parseJson } from '../sdk-options.js';\nimport type {\n EventDeliveryList,\n EventDestination,\n EventDestinationCreate,\n EventDestinationCreated,\n EventDestinationList,\n EventDestinationSecret,\n EventDestinationUpdate,\n EventTestResult,\n EventTypeList,\n} from './types/events.types.js';\nimport { reviveEventDeliveryList, reviveEventDestination, reviveEventDestinationCreated, reviveEventDestinationList } from './types/events.types.js';\n\nexport class EventsClient {\n constructor(private fetch: SdkFetch) {}\n\n /**\n * @name List event types\n * @description Every kind of event the station sends, each with an example of what a destination receives\n */\n async listEventTypes(): Promise<EventTypeList> {\n const result = await this.fetch(`/events/types`, { method: 'GET' });\n return await parseJson<EventTypeList>(result);\n }\n\n /**\n * @name List event destinations\n * @description Every event destination, oldest first\n */\n async listEventDestinations(): Promise<EventDestinationList> {\n const result = await this.fetch(`/events/destinations`, { method: 'GET' });\n return reviveEventDestinationList(await parseJson<EventDestinationList>(result));\n }\n\n /**\n * @name Create event destination\n * @description Add an event destination. The answer carries its signing secret, which is not shown again\n */\n async createEventDestination(body: EventDestinationCreate): Promise<EventDestinationCreated> {\n const result = await this.fetch(`/events/destinations`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return reviveEventDestinationCreated(await parseJson<EventDestinationCreated>(result));\n }\n\n /**\n * @name Update event destination\n * @description Change an event destination's name, address, or whether it is on\n */\n async updateEventDestination(id: string, body: EventDestinationUpdate): Promise<EventDestination> {\n const result = await this.fetch(`/events/destinations/${encodeURIComponent(id)}`, {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return reviveEventDestination(await parseJson<EventDestination>(result));\n }\n\n /**\n * @name Delete event destination\n * @description Remove an event destination and its delivery log\n */\n async deleteEventDestination(id: string): Promise<void> {\n await this.fetch(`/events/destinations/${encodeURIComponent(id)}`, { method: 'DELETE' });\n }\n\n /**\n * @name Rotate event destination secret\n * @description Make a new signing secret for a destination. The old one stops working at once\n */\n async rotateEventDestinationSecret(id: string): Promise<EventDestinationSecret> {\n const result = await this.fetch(`/events/destinations/${encodeURIComponent(id)}/secret`, { method: 'POST' });\n return await parseJson<EventDestinationSecret>(result);\n }\n\n /**\n * @name Test event destination\n * @description Send a destination a test event now, and say what it answered. Sent even when the destination is off\n */\n async testEventDestination(id: string): Promise<EventTestResult> {\n const result = await this.fetch(`/events/destinations/${encodeURIComponent(id)}/test`, { method: 'POST' });\n return await parseJson<EventTestResult>(result);\n }\n\n /**\n * @name List event deliveries\n * @description A destination's latest delivery attempts, newest first\n */\n async listEventDeliveries(id: string): Promise<EventDeliveryList> {\n const result = await this.fetch(`/events/destinations/${encodeURIComponent(id)}/deliveries`, { method: 'GET' });\n return reviveEventDeliveryList(await parseJson<EventDeliveryList>(result));\n }\n}\n","import { DateTime } from 'luxon';\nconst __dt = (v: unknown, path: string): DateTime => {\n if (typeof v !== 'string') {\n throw new TypeError(`ContractKit: expected an ISO 8601 string at '${path}', received ${typeof v}.`);\n }\n const d = DateTime.fromISO(v);\n if (!d.isValid) throw new TypeError(`ContractKit: '${v}' at '${path}' is not a valid ISO 8601 datetime.`);\n return d;\n};\n\n/**\n * One record the station actually played\n * generated from [HistoryEntry](../../../../../apps/api/data/contracts/history/history.types.ck)\n */\nexport interface HistoryEntry {\n /** Unique across the history, and half of the cursor below */\n id: string;\n /** When it started, written when it began rather than when it was handed to the player */\n airedAt: DateTime;\n title: string;\n /** The credit as written, whole: one line rather than a list, because that is the shape a release credits itself in and splitting it renames acts with a comma in their name */\n artists: string;\n /** Absent for anything aired straight from a provider, which the catalog holds no record for */\n album?: string;\n /** The station's own copy where it has one, as a path under the API root, and the upstream URL until then. Resolve it against the base the station is reached at */\n artworkUrl?: string;\n /** How long the recording runs, from the catalog rather than from the copy that played */\n durationMs?: number;\n /** The catalog track this was, for a client that wants to ask more about it. Absent for a record the catalog does not hold, and for one it has since forgotten */\n trackId?: string;\n}\n\n/** Rehydrates every wire-encoded scalar in a HistoryEntry into its runtime type. Mutates and returns `raw`. */\nexport function reviveHistoryEntry(raw: HistoryEntry): HistoryEntry {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['airedAt'] = __dt(__o0['airedAt'], 'HistoryEntry.airedAt');\n return raw;\n}\n\n/**\n * One page of the history, newest first\n * generated from [HistoryQuery](../../../../../apps/api/data/contracts/history/history.types.ck)\n */\nexport interface HistoryQuery {\n limit?: number;\n /** Where the previous page ended. Opaque, and a keyset rather than an offset because rows arrive at the head continuously: an offset would re-show a row on every page as the station kept playing under it. Pass back whatever `nextBefore` said and nothing else */\n before?: string;\n}\n\n/**\n * generated from [HistoryPage](../../../../../apps/api/data/contracts/history/history.types.ck)\n */\nexport interface HistoryPage {\n entries: HistoryEntry[];\n /** The cursor for the page after this one, absent once the history has been read to its end */\n nextBefore?: string;\n}\n\n/** Rehydrates every wire-encoded scalar in a HistoryPage into its runtime type. Mutates and returns `raw`. */\nexport function reviveHistoryPage(raw: HistoryPage): HistoryPage {\n const __o0 = raw as unknown as Record<string, unknown>;\n {\n const __a1 = __o0['entries'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveHistoryEntry(__a1[__i2] as never);\n }\n }\n return raw;\n}\n","import type { SdkFetch } from '../sdk-options.js';\nimport { parseJson, buildQueryString } from '../sdk-options.js';\nimport type { HistoryPage, HistoryQuery } from './types/history.types.js';\nimport { reviveHistoryPage } from './types/history.types.js';\n\nexport class HistoryClient {\n constructor(private fetch: SdkFetch) {}\n\n /**\n * @name Read history\n * @description What the station played, newest first, one page at a time\n */\n async readHistory(query?: HistoryQuery): Promise<HistoryPage> {\n const qs = buildQueryString(query);\n const result = await this.fetch(`/history${qs}`, {\n method: 'GET',\n });\n return reviveHistoryPage(await parseJson<HistoryPage>(result));\n }\n}\n","import { DateTime } from 'luxon';\nconst __dt = (v: unknown, path: string): DateTime => {\n if (typeof v !== 'string') {\n throw new TypeError(`ContractKit: expected an ISO 8601 string at '${path}', received ${typeof v}.`);\n }\n const d = DateTime.fromISO(v);\n if (!d.isValid) throw new TypeError(`ContractKit: '${v}' at '${path}' is not a valid ISO 8601 datetime.`);\n return d;\n};\n\n/**\n * A language pack: every word the console says, in one language, as the file a translator made. The same document is exported, imported and stored. The console's language only; what the station broadcasts in is the `stream.language` setting\n * generated from [ConsoleLanguagePack](../../../../../apps/api/data/contracts/languages/languages.types.ck)\n */\nexport interface ConsoleLanguagePack {\n /** Says the file is a console language pack */\n format: 'deadair.console-language';\n /** The version of the document's shape. This station reads version 1 */\n version: number;\n /** The language, as a BCP 47 tag such as `de` or `pt-BR`. Never English, which is built into the console */\n locale: string;\n /** The language's name in itself, as the console's picker shows it: `Deutsch`, not `German` */\n name: string;\n /** Which way its text runs */\n direction: 'ltr' | 'rtl';\n /** The console version the pack was translated against. Empty when the file did not say */\n madeFor: string;\n /** The strings, nested by namespace and then by key, in the English catalog's shape. Every value is text or a further level of nesting */\n catalog: Record<string, unknown>;\n}\n\n/**\n * A language the console can be shown in on this station, without its strings\n * generated from [ConsoleLanguage](../../../../../apps/api/data/contracts/languages/languages.types.ck)\n */\nexport interface ConsoleLanguage {\n locale: string;\n name: string;\n direction: 'ltr' | 'rtl';\n madeFor: string;\n /** When the pack now installed for it was imported */\n importedAt: DateTime;\n}\n\n/** Rehydrates every wire-encoded scalar in a ConsoleLanguage into its runtime type. Mutates and returns `raw`. */\nexport function reviveConsoleLanguage(raw: ConsoleLanguage): ConsoleLanguage {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['importedAt'] = __dt(__o0['importedAt'], 'ConsoleLanguage.importedAt');\n return raw;\n}\n\n/**\n * The language the signed-in operator chose for the console. Absent means none was chosen, and the console follows the browser's own preference among the languages it has\n * generated from [ConsoleLanguageChoice](../../../../../apps/api/data/contracts/languages/languages.types.ck)\n */\nexport interface ConsoleLanguageChoice {\n /** A language this station holds a pack for, or `en` for English whatever the browser prefers */\n locale?: string;\n}\n\n/**\n * generated from [ConsoleLanguageList](../../../../../apps/api/data/contracts/languages/languages.types.ck)\n */\nexport interface ConsoleLanguageList {\n /** In order of their tags. English is built in and is never listed */\n languages: ConsoleLanguage[];\n}\n\n/** Rehydrates every wire-encoded scalar in a ConsoleLanguageList into its runtime type. Mutates and returns `raw`. */\nexport function reviveConsoleLanguageList(raw: ConsoleLanguageList): ConsoleLanguageList {\n const __o0 = raw as unknown as Record<string, unknown>;\n {\n const __a1 = __o0['languages'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveConsoleLanguage(__a1[__i2] as never);\n }\n }\n return raw;\n}\n","import type { SdkFetch } from '../sdk-options.js';\nimport { bigIntReplacer, parseJson } from '../sdk-options.js';\nimport type { ConsoleLanguageChoice, ConsoleLanguageList, ConsoleLanguagePack } from './types/languages.types.js';\nimport { reviveConsoleLanguageList } from './types/languages.types.js';\n\nexport class LanguagesClient {\n constructor(private fetch: SdkFetch) {}\n\n /**\n * @name Get my console language\n * @description The language you chose for the console, if you chose one\n */\n async getMyConsoleLanguage(): Promise<ConsoleLanguageChoice> {\n const result = await this.fetch(`/console/language`, { method: 'GET' });\n return await parseJson<ConsoleLanguageChoice>(result);\n }\n\n /**\n * @name Choose my console language\n * @description Chooses the language your console is shown in, or, without one, goes back to following the browser\n */\n async chooseMyConsoleLanguage(body: ConsoleLanguageChoice): Promise<ConsoleLanguageChoice> {\n const result = await this.fetch(`/console/language`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<ConsoleLanguageChoice>(result);\n }\n\n /**\n * @name List console languages\n * @description Every language this station holds a pack for, without the strings\n */\n async listConsoleLanguages(): Promise<ConsoleLanguageList> {\n const result = await this.fetch(`/console/languages`, { method: 'GET' });\n return reviveConsoleLanguageList(await parseJson<ConsoleLanguageList>(result));\n }\n\n /**\n * @name Get console language\n * @description One language's pack, strings and all, as it was imported\n */\n async getConsoleLanguage(locale: string): Promise<ConsoleLanguagePack> {\n const result = await this.fetch(`/console/languages/${encodeURIComponent(locale)}`, { method: 'GET' });\n return await parseJson<ConsoleLanguagePack>(result);\n }\n\n /**\n * @name Import console language\n * @description Installs a language pack, replacing any pack already installed for the language. The tag in the path must be the pack's own\n */\n async importConsoleLanguage(locale: string, body: ConsoleLanguagePack): Promise<ConsoleLanguageList> {\n const result = await this.fetch(`/console/languages/${encodeURIComponent(locale)}`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return reviveConsoleLanguageList(await parseJson<ConsoleLanguageList>(result));\n }\n\n /**\n * @name Remove console language\n * @description Removes a language. Anybody who had chosen it sees English\n */\n async removeConsoleLanguage(locale: string): Promise<ConsoleLanguageList> {\n const result = await this.fetch(`/console/languages/${encodeURIComponent(locale)}`, { method: 'DELETE' });\n return reviveConsoleLanguageList(await parseJson<ConsoleLanguageList>(result));\n }\n}\n","import { DateTime } from 'luxon';\nconst __dt = (v: unknown, path: string): DateTime => {\n if (typeof v !== 'string') {\n throw new TypeError(`ContractKit: expected an ISO 8601 string at '${path}', received ${typeof v}.`);\n }\n const d = DateTime.fromISO(v);\n if (!d.isValid) throw new TypeError(`ContractKit: '${v}' at '${path}' is not a valid ISO 8601 datetime.`);\n return d;\n};\n\n/**\n * A one-time code that links a chat account to the signed-in station account. Shown once: send it to the station's bot as `/link CODE` in a direct message\n * generated from [MessagingLinkCode](../../../../../apps/api/data/contracts/messaging/messaging.types.ck)\n */\nexport interface MessagingLinkCode {\n /** The code itself. Case does not matter when it is sent */\n code: string;\n /** When the code stops working. A new code replaces any earlier one */\n expiresAt: DateTime;\n}\n\n/** Rehydrates every wire-encoded scalar in a MessagingLinkCode into its runtime type. Mutates and returns `raw`. */\nexport function reviveMessagingLinkCode(raw: MessagingLinkCode): MessagingLinkCode {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['expiresAt'] = __dt(__o0['expiresAt'], 'MessagingLinkCode.expiresAt');\n return raw;\n}\n\n/**\n * A chat account linked to the signed-in station account. Operator commands sent from it run with this account's permissions\n * generated from [MessagingLink](../../../../../apps/api/data/contracts/messaging/messaging.types.ck)\n */\nexport interface MessagingLink {\n /** Which messaging plugin the chat account is on, for example `deadair.telegram` */\n pluginId: string;\n /** The chat platform's own id for the person */\n platformUserId: string;\n /** What the chat platform called them when they linked */\n displayName: string;\n /** When the link was made */\n createdAt: DateTime;\n}\n\n/** Rehydrates every wire-encoded scalar in a MessagingLink into its runtime type. Mutates and returns `raw`. */\nexport function reviveMessagingLink(raw: MessagingLink): MessagingLink {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['createdAt'] = __dt(__o0['createdAt'], 'MessagingLink.createdAt');\n return raw;\n}\n\n/**\n * Every chat account linked to the signed-in station account, newest first\n * generated from [MessagingLinkList](../../../../../apps/api/data/contracts/messaging/messaging.types.ck)\n */\nexport interface MessagingLinkList {\n links: MessagingLink[];\n}\n\n/** Rehydrates every wire-encoded scalar in a MessagingLinkList into its runtime type. Mutates and returns `raw`. */\nexport function reviveMessagingLinkList(raw: MessagingLinkList): MessagingLinkList {\n const __o0 = raw as unknown as Record<string, unknown>;\n {\n const __a1 = __o0['links'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveMessagingLink(__a1[__i2] as never);\n }\n }\n return raw;\n}\n","import type { SdkFetch } from '../sdk-options.js';\nimport { parseJson } from '../sdk-options.js';\nimport type { MessagingLinkCode, MessagingLinkList } from './types/messaging.types.js';\nimport { reviveMessagingLinkCode, reviveMessagingLinkList } from './types/messaging.types.js';\n\nexport class MessagingClient {\n constructor(private fetch: SdkFetch) {}\n\n /**\n * @name List messaging links\n * @description The chat accounts linked to the signed-in account\n */\n async listMessagingLinks(): Promise<MessagingLinkList> {\n const result = await this.fetch(`/messaging/links`, { method: 'GET' });\n return reviveMessagingLinkList(await parseJson<MessagingLinkList>(result));\n }\n\n /**\n * @name Create messaging link code\n * @description A new one-time code for linking a chat account. It replaces any earlier code and stops working after ten minutes\n */\n async createMessagingLinkCode(): Promise<MessagingLinkCode> {\n const result = await this.fetch(`/messaging/links/code`, { method: 'POST' });\n return reviveMessagingLinkCode(await parseJson<MessagingLinkCode>(result));\n }\n\n /**\n * @name Remove messaging link\n * @description Unlink a chat account. Its operator commands are refused from the next one on\n */\n async removeMessagingLink(pluginId: string, platformUserId: string): Promise<void> {\n await this.fetch(`/messaging/links/${encodeURIComponent(pluginId)}/${encodeURIComponent(platformUserId)}`, { method: 'DELETE' });\n }\n}\n","import { DateTime } from 'luxon';\nconst __dt = (v: unknown, path: string): DateTime => {\n if (typeof v !== 'string') {\n throw new TypeError(`ContractKit: expected an ISO 8601 string at '${path}', received ${typeof v}.`);\n }\n const d = DateTime.fromISO(v);\n if (!d.isValid) throw new TypeError(`ContractKit: '${v}' at '${path}' is not a valid ISO 8601 datetime.`);\n return d;\n};\n\n/**\n * How wide one point is. Chosen by the station from the range asked for: minutes for two days or less, hours beyond\n * generated from [MetricResolution](../../../../../apps/api/data/contracts/metrics/metrics.types.ck)\n */\nexport type MetricResolution = 'minute' | 'hour';\n\n/**\n * The trends to read, over one range\n * generated from [MetricSeriesQuery](../../../../../apps/api/data/contracts/metrics/metrics.types.ck)\n */\nexport interface MetricSeriesQuery {\n /** Comma-separated metric names, at most twenty: `station.listeners,work.job.ms` */\n names: string;\n /** The start of the range, inclusive */\n from: DateTime;\n /** The end of the range, exclusive. At most four hundred days after `from` */\n to: DateTime;\n}\n\n/** Rehydrates every wire-encoded scalar in a MetricSeriesQuery into its runtime type. Mutates and returns `raw`. */\nexport function reviveMetricSeriesQuery(raw: MetricSeriesQuery): MetricSeriesQuery {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['from'] = __dt(__o0['from'], 'MetricSeriesQuery.from');\n __o0['to'] = __dt(__o0['to'], 'MetricSeriesQuery.to');\n return raw;\n}\n\n/**\n * One series over one minute or hour\n * generated from [MetricPoint](../../../../../apps/api/data/contracts/metrics/metrics.types.ck)\n */\nexport interface MetricPoint {\n /** The start of the minute or hour */\n at: DateTime;\n /** How many observations were folded in */\n count: number;\n /** Their total: a counter's value, or with `count` a duration's mean */\n sum: number;\n /** The smallest observation */\n min: number;\n /** The largest observation: a duration's worst */\n max: number;\n /** The latest observation: a gauge's value */\n last: number;\n}\n\n/** Rehydrates every wire-encoded scalar in a MetricPoint into its runtime type. Mutates and returns `raw`. */\nexport function reviveMetricPoint(raw: MetricPoint): MetricPoint {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['at'] = __dt(__o0['at'], 'MetricPoint.at');\n return raw;\n}\n\n/**\n * A metric the station holds, for a picker\n * generated from [MetricName](../../../../../apps/api/data/contracts/metrics/metrics.types.ck)\n */\nexport interface MetricName {\n name: string;\n source: string;\n /** Every label any of its series carries, sorted */\n labelKeys: string[];\n /** The newest point held for it, at either resolution */\n lastSeen: DateTime;\n}\n\n/** Rehydrates every wire-encoded scalar in a MetricName into its runtime type. Mutates and returns `raw`. */\nexport function reviveMetricName(raw: MetricName): MetricName {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['lastSeen'] = __dt(__o0['lastSeen'], 'MetricName.lastSeen');\n return raw;\n}\n\n/**\n * An OTLP/HTTP metrics export, sent as JSON. Only the top level is checked here; the station reads the rest itself and counts what it cannot use rather than refusing the whole request\n * generated from [OtlpMetricsExport](../../../../../apps/api/data/contracts/metrics/metrics.types.ck)\n */\nexport interface OtlpMetricsExport {\n resourceMetrics: Record<string, unknown>[];\n}\n\n/**\n * OTLP's answer when some points were not taken\n * generated from [OtlpPartialSuccess](../../../../../apps/api/data/contracts/metrics/metrics.types.ck)\n */\nexport interface OtlpPartialSuccess {\n /** How many, as OTLP writes a 64-bit count: a digit string */\n rejectedDataPoints: string;\n errorMessage: string;\n}\n\n/**\n * One metric and one set of labels, its points oldest first\n * generated from [MetricSeries](../../../../../apps/api/data/contracts/metrics/metrics.types.ck)\n */\nexport interface MetricSeries {\n name: string;\n /** What tells this series from the metric's others: `{ \"queue\": \"catalog.sync\" }`. Empty for a metric with one series */\n labels: Record<string, string>;\n /** `station` for what the station measured itself, `otlp` for what another service sent it */\n source: string;\n /** Only the buckets that hold something. A gap is a stretch nothing was measured, which a chart should draw as a gap */\n points: MetricPoint[];\n}\n\n/** Rehydrates every wire-encoded scalar in a MetricSeries into its runtime type. Mutates and returns `raw`. */\nexport function reviveMetricSeries(raw: MetricSeries): MetricSeries {\n const __o0 = raw as unknown as Record<string, unknown>;\n {\n const __a1 = __o0['points'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveMetricPoint(__a1[__i2] as never);\n }\n }\n return raw;\n}\n\n/**\n * generated from [MetricNames](../../../../../apps/api/data/contracts/metrics/metrics.types.ck)\n */\nexport interface MetricNames {\n /** Sorted by name */\n names: MetricName[];\n}\n\n/** Rehydrates every wire-encoded scalar in a MetricNames into its runtime type. Mutates and returns `raw`. */\nexport function reviveMetricNames(raw: MetricNames): MetricNames {\n const __o0 = raw as unknown as Record<string, unknown>;\n {\n const __a1 = __o0['names'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveMetricName(__a1[__i2] as never);\n }\n }\n return raw;\n}\n\n/**\n * OTLP's answer to an export. Empty when every point was taken\n * generated from [OtlpExportResponse](../../../../../apps/api/data/contracts/metrics/metrics.types.ck)\n */\nexport interface OtlpExportResponse {\n partialSuccess?: OtlpPartialSuccess;\n}\n\n/**\n * generated from [MetricSeriesPage](../../../../../apps/api/data/contracts/metrics/metrics.types.ck)\n */\nexport interface MetricSeriesPage {\n /** The width the points were read at */\n resolution: MetricResolution;\n from: DateTime;\n to: DateTime;\n /** Empty when nothing was measured in the range, which is not an error */\n series: MetricSeries[];\n}\n\n/** Rehydrates every wire-encoded scalar in a MetricSeriesPage into its runtime type. Mutates and returns `raw`. */\nexport function reviveMetricSeriesPage(raw: MetricSeriesPage): MetricSeriesPage {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['from'] = __dt(__o0['from'], 'MetricSeriesPage.from');\n __o0['to'] = __dt(__o0['to'], 'MetricSeriesPage.to');\n {\n const __a1 = __o0['series'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveMetricSeries(__a1[__i2] as never);\n }\n }\n return raw;\n}\n","import type { SdkFetch } from '../sdk-options.js';\nimport { parseJson, buildQueryString } from '../sdk-options.js';\nimport type { MetricNames, MetricSeriesPage, MetricSeriesQuery } from './types/metrics.types.js';\nimport { reviveMetricNames, reviveMetricSeriesPage } from './types/metrics.types.js';\n\nexport class MetricsClient {\n constructor(private fetch: SdkFetch) {}\n\n /**\n * @name Read metric series\n * @description Trends over a range, at minute resolution for two days or less and hourly beyond\n */\n async readMetricSeries(query?: MetricSeriesQuery): Promise<MetricSeriesPage> {\n const qs = buildQueryString(query);\n const result = await this.fetch(`/metrics/series${qs}`, {\n method: 'GET',\n });\n return reviveMetricSeriesPage(await parseJson<MetricSeriesPage>(result));\n }\n\n /**\n * @name Read metric names\n * @description Every metric the station holds, with its labels and when it was last measured\n */\n async readMetricNames(): Promise<MetricNames> {\n const result = await this.fetch(`/metrics/names`, { method: 'GET' });\n return reviveMetricNames(await parseJson<MetricNames>(result));\n }\n}\n","import type { SdkFetch } from '../sdk-options.js';\nimport { parseJson, buildQueryString } from '../sdk-options.js';\nimport type { StationPiece, StationPiecePage, StationPieceQuery, StationSeriesList } from './types/narrations.types.js';\n\nexport class NarrationsClient {\n constructor(private fetch: SdkFetch) {}\n\n /**\n * @name List series\n * @description Every series every installed narration plugin offers\n */\n async listSeries(): Promise<StationSeriesList> {\n const result = await this.fetch(`/narrations/series`, { method: 'GET' });\n return await parseJson<StationSeriesList>(result);\n }\n\n /**\n * @name List pieces\n * @description The pieces the station knows about, in their series' own order, with what it has done with each\n */\n async listPieces(query?: StationPieceQuery): Promise<StationPiecePage> {\n const qs = buildQueryString(query);\n const result = await this.fetch(`/narrations/pieces${qs}`, {\n method: 'GET',\n });\n return await parseJson<StationPiecePage>(result);\n }\n\n /**\n * @name Render piece\n * @description Has one piece spoken now, rather than waiting for its slot to come near\n */\n async renderPiece(id: string): Promise<StationPiece> {\n const result = await this.fetch(`/narrations/pieces/${encodeURIComponent(id)}/render`, { method: 'POST' });\n return await parseJson<StationPiece>(result);\n }\n\n /**\n * @name Refresh narrations\n * @description Reads every series again, in the background, rather than waiting for the next scheduled refresh\n */\n async refreshNarrations(): Promise<void> {\n await this.fetch(`/narrations/refresh`, { method: 'POST' });\n }\n}\n","import type { SdkFetch } from '../sdk-options.js';\nimport { parseJson, buildQueryString } from '../sdk-options.js';\nimport type { NewsPage, NewsQuery, StationFeedList } from './types/news.types.js';\n\nexport class NewsClient {\n constructor(private fetch: SdkFetch) {}\n\n /**\n * @name List feeds\n * @description Every feed every installed news plugin currently offers\n */\n async listFeeds(): Promise<StationFeedList> {\n const result = await this.fetch(`/news/feeds`, { method: 'GET' });\n return await parseJson<StationFeedList>(result);\n }\n\n /**\n * @name Read news\n * @description Published entries, newest first\n */\n async readNews(query?: NewsQuery): Promise<NewsPage> {\n const qs = buildQueryString(query);\n const result = await this.fetch(`/news${qs}`, {\n method: 'GET',\n });\n return await parseJson<NewsPage>(result);\n }\n}\n","import type { SdkFetch } from '../sdk-options.js';\nimport { parseJson } from '../sdk-options.js';\nimport type { NowPlaying, NowPlayingLyrics } from './types/nowplaying.types.js';\n\nexport class NowplayingClient {\n constructor(private fetch: SdkFetch) {}\n\n /**\n * @name Get now playing\n * @description What is on air right now. Answers 200 with `onAir: false` when the station is quiet, so a device polling this treats silence as an answer rather than an error\n */\n async getNowPlaying(): Promise<NowPlaying> {\n const result = await this.fetch(`/nowplaying`, { method: 'GET' });\n return await parseJson<NowPlaying>(result);\n }\n\n /**\n * @name Get now playing lyrics\n * @description The words of the record on air, with what a player needs to follow along line by line\n */\n async getNowPlayingLyrics(): Promise<NowPlayingLyrics> {\n const result = await this.fetch(`/nowplaying/lyrics`, { method: 'GET' });\n return await parseJson<NowPlayingLyrics>(result);\n }\n}\n","import { DateTime } from 'luxon';\nconst __dt = (v: unknown, path: string): DateTime => {\n if (typeof v !== 'string') {\n throw new TypeError(`ContractKit: expected an ISO 8601 string at '${path}', received ${typeof v}.`);\n }\n const d = DateTime.fromISO(v);\n if (!d.isValid) throw new TypeError(`ContractKit: '${v}' at '${path}' is not a valid ISO 8601 datetime.`);\n return d;\n};\n\n/**\n * An app's authorization request, as the consent page received it\n * generated from [OAuthAuthorizationQuery](../../../../../apps/api/data/contracts/oauth/oauth.types.ck)\n */\nexport interface OAuthAuthorizationQuery {\n /** The query string the app sent the browser to the consent page with, as `window.location.search` holds it */\n query: string;\n}\n\n/**\n * How the station knows an app: registered by an operator, registered by itself, or described by a document on its own website\n * generated from [OAuthClientKind](../../../../../apps/api/data/contracts/oauth/oauth.types.ck)\n */\nexport type OAuthClientKind = 'preregistered' | 'dynamic' | 'metadata_document';\n\n/**\n * A request with something wrong that the app should be told about: send the browser back to it\n * generated from [OAuthAuthorizationRedirect](../../../../../apps/api/data/contracts/oauth/oauth.types.ck)\n */\nexport interface OAuthAuthorizationRedirect {\n /** Discriminator */\n kind: 'redirect';\n /** Where to send the browser */\n redirectUrl: string;\n}\n\n/**\n * A request that names no app the station knows, or an address the app did not register. Never sent anywhere\n * generated from [OAuthAuthorizationRefusal](../../../../../apps/api/data/contracts/oauth/oauth.types.ck)\n */\nexport interface OAuthAuthorizationRefusal {\n /** Discriminator */\n kind: 'refuse';\n /** The OAuth error code */\n error: string;\n /** What was wrong, in words */\n description: string;\n}\n\n/**\n * Denying a stashed request\n * generated from [OAuthAuthorizationDecision](../../../../../apps/api/data/contracts/oauth/oauth.types.ck)\n */\nexport interface OAuthAuthorizationDecision {\n /** From the context */\n requestId: string;\n}\n\n/**\n * What a connected app may do on the station. `view` reads it; `manage` changes it and includes `view`. Never more than the person approving it may do\n * generated from [OAuthGrantScope](../../../../../apps/api/data/contracts/oauth/oauth.types.ck)\n */\nexport type OAuthGrantScope = 'view' | 'manage';\n\n/**\n * Where to send the browser now\n * generated from [OAuthAuthorizationOutcome](../../../../../apps/api/data/contracts/oauth/oauth.types.ck)\n */\nexport interface OAuthAuthorizationOutcome {\n /** The app's own address, carrying the code or the refusal */\n redirectUrl: string;\n}\n\n/**\n * How the app proves itself at the token endpoint. `none` is a public client, which is what apps on somebody's own device are\n * generated from [OAuthClientAuthMethod](../../../../../apps/api/data/contracts/oauth/oauth.types.ck)\n */\nexport type OAuthClientAuthMethod = 'none' | 'client_secret_post' | 'client_secret_basic';\n\n/**\n * An app the signed-in person has let act as them\n * generated from [OAuthGrant](../../../../../apps/api/data/contracts/oauth/oauth.types.ck)\n */\nexport interface OAuthGrant {\n /** For disconnecting it */\n id: string;\n /** The app's client id */\n clientId: string;\n /** What the app calls itself, when the station can still find out */\n clientName?: string;\n /** What it can reach */\n resource: string;\n /** What it was granted: `mcp`, and the station scopes it may use (`view`, `manage`) */\n scope: string[];\n /** When it was first approved */\n createdAt: DateTime;\n /** When it last obtained a token */\n lastUsedAt?: DateTime;\n}\n\n/** Rehydrates every wire-encoded scalar in a OAuthGrant into its runtime type. Mutates and returns `raw`. */\nexport function reviveOAuthGrant(raw: OAuthGrant): OAuthGrant {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['createdAt'] = __dt(__o0['createdAt'], 'OAuthGrant.createdAt');\n if (__o0['lastUsedAt'] != null) {\n __o0['lastUsedAt'] = __dt(__o0['lastUsedAt'], 'OAuthGrant.lastUsedAt');\n }\n return raw;\n}\n\n/**\n * A valid request, stashed for the signed-in person to approve or deny\n * generated from [OAuthAuthorizationContext](../../../../../apps/api/data/contracts/oauth/oauth.types.ck)\n */\nexport interface OAuthAuthorizationContext {\n /** Discriminator */\n kind: 'context';\n /** What approving or denying names. Good for a few minutes, and only for the person it was shown to */\n requestId: string;\n /** The app's client id */\n clientId: string;\n /** How the station knows the app */\n clientKind: OAuthClientKind;\n /** What the app calls itself */\n clientName?: string;\n /** The app's own website, when it gave one */\n clientUri?: string;\n /** The app's logo, when it gave one */\n logoUri?: string;\n /** The host the browser is sent back to, which is who actually receives the approval */\n redirectHost: string;\n /** Whether every address the app registered is this computer's own, which only an app running on it should use */\n loopbackOnly: boolean;\n /** What the app asked for. The person chooses what it gets when approving, whatever this says */\n scope: string[];\n /** What the app will be able to reach: the station's MCP endpoint */\n resource: string;\n}\n\n/**\n * Approving a stashed request, with what the app may do\n * generated from [OAuthAuthorizationApproval](../../../../../apps/api/data/contracts/oauth/oauth.types.ck)\n */\nexport interface OAuthAuthorizationApproval {\n /** From the context */\n requestId: string;\n /** What the person lets the app do. At least one; `manage` includes `view`. Replaces whatever the app asked for */\n scopes: OAuthGrantScope[];\n}\n\n/**\n * An app registered with the station\n * generated from [OAuthClientSummary](../../../../../apps/api/data/contracts/oauth/oauth.types.ck)\n */\nexport interface OAuthClientSummary {\n /** Its client id */\n clientId: string;\n /** Created by an operator, or registered by itself */\n kind: 'preregistered' | 'dynamic';\n /** What it is called */\n name?: string;\n /** Where it may be sent back to */\n redirectUris: string[];\n /** How it proves itself */\n tokenEndpointAuthMethod: OAuthClientAuthMethod;\n /** When it was registered */\n createdAt: DateTime;\n /** When it last obtained a token */\n lastUsedAt?: DateTime;\n /** When a self-registered app lapses unless used again */\n expiresAt?: DateTime;\n}\n\n/** Rehydrates every wire-encoded scalar in a OAuthClientSummary into its runtime type. Mutates and returns `raw`. */\nexport function reviveOAuthClientSummary(raw: OAuthClientSummary): OAuthClientSummary {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['createdAt'] = __dt(__o0['createdAt'], 'OAuthClientSummary.createdAt');\n if (__o0['lastUsedAt'] != null) {\n __o0['lastUsedAt'] = __dt(__o0['lastUsedAt'], 'OAuthClientSummary.lastUsedAt');\n }\n if (__o0['expiresAt'] != null) {\n __o0['expiresAt'] = __dt(__o0['expiresAt'], 'OAuthClientSummary.expiresAt');\n }\n return raw;\n}\n\n/**\n * An app an operator registers by hand, for a client that cannot register itself\n * generated from [OAuthClientCreate](../../../../../apps/api/data/contracts/oauth/oauth.types.ck)\n */\nexport interface OAuthClientCreate {\n /** What to call it */\n name: string;\n /** Where it may be sent back to. At least one; https, or this computer's own address */\n redirectUris: string[];\n /** `none` for an app on somebody's own device, otherwise a secret it keeps */\n tokenEndpointAuthMethod: OAuthClientAuthMethod;\n}\n\n/**\n * generated from [OAuthGrantList](../../../../../apps/api/data/contracts/oauth/oauth.types.ck)\n */\nexport interface OAuthGrantList {\n /** Most recent first */\n grants: OAuthGrant[];\n}\n\n/** Rehydrates every wire-encoded scalar in a OAuthGrantList into its runtime type. Mutates and returns `raw`. */\nexport function reviveOAuthGrantList(raw: OAuthGrantList): OAuthGrantList {\n const __o0 = raw as unknown as Record<string, unknown>;\n {\n const __a1 = __o0['grants'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveOAuthGrant(__a1[__i2] as never);\n }\n }\n return raw;\n}\n\n/**\n * generated from [OAuthAuthorizationContextResult](../../../../../apps/api/data/contracts/oauth/oauth.types.ck)\n */\nexport type OAuthAuthorizationContextResult = OAuthAuthorizationContext | OAuthAuthorizationRedirect | OAuthAuthorizationRefusal;\n\n/**\n * generated from [OAuthClientList](../../../../../apps/api/data/contracts/oauth/oauth.types.ck)\n */\nexport interface OAuthClientList {\n /** Newest first. Apps that describe themselves are not listed: nothing is stored for them */\n clients: OAuthClientSummary[];\n}\n\n/** Rehydrates every wire-encoded scalar in a OAuthClientList into its runtime type. Mutates and returns `raw`. */\nexport function reviveOAuthClientList(raw: OAuthClientList): OAuthClientList {\n const __o0 = raw as unknown as Record<string, unknown>;\n {\n const __a1 = __o0['clients'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveOAuthClientSummary(__a1[__i2] as never);\n }\n }\n return raw;\n}\n\n/**\n * A registered app, with its secret. The only time the secret is ever returned\n * generated from [OAuthClientIssued](../../../../../apps/api/data/contracts/oauth/oauth.types.ck)\n */\nexport interface OAuthClientIssued {\n /** The app as it will appear in the list */\n client: OAuthClientSummary;\n /** Present for an app that keeps a secret. Store it now: nothing can show it again */\n clientSecret?: string;\n}\n\n/** Rehydrates every wire-encoded scalar in a OAuthClientIssued into its runtime type. Mutates and returns `raw`. */\nexport function reviveOAuthClientIssued(raw: OAuthClientIssued): OAuthClientIssued {\n const __o0 = raw as unknown as Record<string, unknown>;\n reviveOAuthClientSummary(__o0['client'] as never);\n return raw;\n}\n","import type { SdkFetch } from '../sdk-options.js';\nimport { bigIntReplacer, parseJson } from '../sdk-options.js';\nimport type {\n OAuthAuthorizationApproval,\n OAuthAuthorizationContextResult,\n OAuthAuthorizationDecision,\n OAuthAuthorizationOutcome,\n OAuthAuthorizationQuery,\n OAuthClientCreate,\n OAuthClientIssued,\n OAuthClientList,\n OAuthGrantList,\n} from './types/oauth.types.js';\nimport { reviveOAuthClientIssued, reviveOAuthClientList, reviveOAuthGrantList } from './types/oauth.types.js';\n\nexport class OauthClient {\n constructor(private fetch: SdkFetch) {}\n\n /**\n * @name Describe authorization request\n * @description Validate an app's authorization request for the consent page, and stash it for the signed-in person. A POST because it stashes: what is approved is exactly what was validated here\n */\n async describeAuthorizationRequest(body: OAuthAuthorizationQuery): Promise<OAuthAuthorizationContextResult> {\n const result = await this.fetch(`/auth/oauth/authorize/context`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<OAuthAuthorizationContextResult>(result);\n }\n\n /**\n * @name Approve authorization request\n * @description Let the app act as the signed-in person, as far as the chosen scopes allow. Once the account has a strong second factor, this needs one verified in the last five minutes\n */\n async approveAuthorizationRequest(body: OAuthAuthorizationApproval): Promise<OAuthAuthorizationOutcome> {\n const result = await this.fetch(`/auth/oauth/authorize/approve`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<OAuthAuthorizationOutcome>(result);\n }\n\n /**\n * @name Deny authorization request\n * @description Turn the app away. It is told the person said no\n */\n async denyAuthorizationRequest(body: OAuthAuthorizationDecision): Promise<OAuthAuthorizationOutcome> {\n const result = await this.fetch(`/auth/oauth/authorize/deny`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<OAuthAuthorizationOutcome>(result);\n }\n\n /**\n * @name List OAuth clients\n * @description Every app registered with the station, by an operator or by itself\n */\n async listOAuthClients(): Promise<OAuthClientList> {\n const result = await this.fetch(`/auth/oauth/clients`, { method: 'GET' });\n return reviveOAuthClientList(await parseJson<OAuthClientList>(result));\n }\n\n /**\n * @name Create OAuth client\n * @description Register an app by hand. The secret, for an app that keeps one, is in this response and nowhere else\n */\n async createOAuthClient(body: OAuthClientCreate): Promise<OAuthClientIssued> {\n const result = await this.fetch(`/auth/oauth/clients`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return reviveOAuthClientIssued(await parseJson<OAuthClientIssued>(result));\n }\n\n /**\n * @name Revoke OAuth client\n * @description Withdraw an app. Every person's approval of it ends, and so does every token it holds\n */\n async revokeOAuthClient(clientId: string): Promise<void> {\n await this.fetch(`/auth/oauth/clients/${encodeURIComponent(clientId)}`, { method: 'DELETE' });\n }\n\n /**\n * @name List OAuth grants\n * @description The apps the signed-in person has let act as them\n */\n async listOAuthGrants(): Promise<OAuthGrantList> {\n const result = await this.fetch(`/auth/oauth/grants`, { method: 'GET' });\n return reviveOAuthGrantList(await parseJson<OAuthGrantList>(result));\n }\n\n /**\n * @name Revoke OAuth grant\n * @description Disconnect an app. Every token it holds for this person stops working at once\n */\n async revokeOAuthGrant(id: string): Promise<void> {\n await this.fetch(`/auth/oauth/grants/${encodeURIComponent(id)}`, { method: 'DELETE' });\n }\n}\n","import type { SdkFetch } from '../sdk-options.js';\nimport { bigIntReplacer, parseJson } from '../sdk-options.js';\nimport type { OnboardingRequirement, OnboardingRequirementInput } from './types/onboarding.types.js';\n\nexport class OnboardingClient {\n constructor(private fetch: SdkFetch) {}\n\n /** @name Get Onboarding Requirements */\n async getOnboardingRequirements(): Promise<OnboardingRequirement[]> {\n const result = await this.fetch(`/onboarding`, { method: 'GET' });\n return await parseJson<OnboardingRequirement[]>(result);\n }\n\n /** @name Submit Onboarding Requirement */\n async submitOnboardingRequirement(body: OnboardingRequirementInput): Promise<OnboardingRequirement[]> {\n const result = await this.fetch(`/onboarding`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<OnboardingRequirement[]>(result);\n }\n}\n","import { DateTime } from 'luxon';\nconst __dt = (v: unknown, path: string): DateTime => {\n if (typeof v !== 'string') {\n throw new TypeError(`ContractKit: expected an ISO 8601 string at '${path}', received ${typeof v}.`);\n }\n const d = DateTime.fromISO(v);\n if (!d.isValid) throw new TypeError(`ContractKit: '${v}' at '${path}' is not a valid ISO 8601 datetime.`);\n return d;\n};\n\n/**\n * One of the station's mounts a speaker can play\n * generated from [OutputMount](../../../../../apps/api/data/contracts/outputs/outputs.types.ck)\n */\nexport interface OutputMount {\n format: 'mp3' | 'opus' | 'aac' | 'flac' | 'hls';\n /** Same-origin path, leading slash included, as `/nowplaying` gives it */\n path: string;\n}\n\n/**\n * A plugin that could not list its speakers\n * generated from [OutputProblem](../../../../../apps/api/data/contracts/outputs/outputs.types.ck)\n */\nexport interface OutputProblem {\n pluginId: string;\n message: string;\n}\n\n/**\n * A speaker the station is meant to be playing on, and how it is doing\n * generated from [OutputCast](../../../../../apps/api/data/contracts/outputs/outputs.types.ck)\n */\nexport interface OutputCast {\n pluginId: string;\n deviceId: string;\n /** What the speaker was called when the cast started */\n deviceName: string;\n /** Which mount it plays */\n mountPath: string;\n startedAt: DateTime;\n /** As the speaker reports it now. `opening` and `buffering` are a stream starting, not a failure; `stopped` with the station's stream still loaded is played again on its own; `unreachable` is a speaker that did not answer, which the station waits out */\n phase: 'idle' | 'opening' | 'buffering' | 'playing' | 'stopped' | 'unreachable';\n /** A sentence about the phase when it needs one, such as why a speaker is unreachable */\n detail?: string;\n}\n\n/** Rehydrates every wire-encoded scalar in a OutputCast into its runtime type. Mutates and returns `raw`. */\nexport function reviveOutputCast(raw: OutputCast): OutputCast {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['startedAt'] = __dt(__o0['startedAt'], 'OutputCast.startedAt');\n return raw;\n}\n\n/**\n * Play the station on a speaker\n * generated from [OutputCastRequest](../../../../../apps/api/data/contracts/outputs/outputs.types.ck)\n */\nexport interface OutputCastRequest {\n pluginId: string;\n deviceId: string;\n /** Which mount, from the speaker's `mounts`. Absent means its first, which is MP3 wherever the speaker takes it */\n mountPath?: string;\n}\n\n/**\n * A speaker the station can play on, as an `output` plugin listed it\n * generated from [OutputDevice](../../../../../apps/api/data/contracts/outputs/outputs.types.ck)\n */\nexport interface OutputDevice {\n /** The plugin that drives it, for example `deadair.cast` */\n pluginId: string;\n /** The plugin's own id for the speaker. Stable across restarts */\n deviceId: string;\n /** What the operator calls it */\n name: string;\n /** The make or model, where the speaker says */\n model?: string;\n /** How the plugin reaches it, for recognising rather than dialling */\n address: string;\n /** How it is driven, for a plugin that speaks several: `chromecast`, `upnp`, `bluos` */\n protocol?: string;\n /** The station's mounts this speaker can play, MP3 first. Empty when it plays none of the ones switched on */\n mounts: OutputMount[];\n /** Whether the station is meant to be playing on it now. `/outputs/casts` says how that is going */\n casting: boolean;\n}\n\n/**\n * Every speaker the station is meant to be playing on\n * generated from [OutputCastList](../../../../../apps/api/data/contracts/outputs/outputs.types.ck)\n */\nexport interface OutputCastList {\n casts: OutputCast[];\n}\n\n/** Rehydrates every wire-encoded scalar in a OutputCastList into its runtime type. Mutates and returns `raw`. */\nexport function reviveOutputCastList(raw: OutputCastList): OutputCastList {\n const __o0 = raw as unknown as Record<string, unknown>;\n {\n const __a1 = __o0['casts'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveOutputCast(__a1[__i2] as never);\n }\n }\n return raw;\n}\n\n/**\n * Every speaker every `output` plugin can play the station on\n * generated from [OutputDeviceList](../../../../../apps/api/data/contracts/outputs/outputs.types.ck)\n */\nexport interface OutputDeviceList {\n devices: OutputDevice[];\n /** Plugins that did not answer. Their speakers are missing from `devices` rather than the whole list failing */\n problems: OutputProblem[];\n /** True when the station has looked for speakers on its network and never found one, which on a container usually means its network cannot carry multicast (a bridge network). Speakers added by address still work */\n discoverySeesNothing: boolean;\n}\n","import type { SdkFetch } from '../sdk-options.js';\nimport { bigIntReplacer, parseJson } from '../sdk-options.js';\nimport type { OutputCast, OutputCastList, OutputCastRequest, OutputDeviceList } from './types/outputs.types.js';\nimport { reviveOutputCast, reviveOutputCastList } from './types/outputs.types.js';\n\nexport class OutputsClient {\n constructor(private fetch: SdkFetch) {}\n\n /**\n * @name List output devices\n * @description Every speaker the station can play on, from every `output` plugin, with the mounts each can take\n */\n async listOutputDevices(): Promise<OutputDeviceList> {\n const result = await this.fetch(`/outputs/devices`, { method: 'GET' });\n return await parseJson<OutputDeviceList>(result);\n }\n\n /**\n * @name List casts\n * @description Every speaker the station is meant to be playing on, each asked how it is doing now\n */\n async listCasts(): Promise<OutputCastList> {\n const result = await this.fetch(`/outputs/casts`, { method: 'GET' });\n return reviveOutputCastList(await parseJson<OutputCastList>(result));\n }\n\n /**\n * @name Start cast\n * @description Play the station on a speaker, replacing whatever it was playing. The station keeps it playing, through a dropped stream or a restart, until it is stopped here or somebody plays something else on it\n */\n async startCast(body: OutputCastRequest): Promise<OutputCast> {\n const result = await this.fetch(`/outputs/casts`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return reviveOutputCast(await parseJson<OutputCast>(result));\n }\n\n /**\n * @name Stop cast\n * @description Stop the station on a speaker. Answers 204 when it was not playing too\n */\n async stopCast(pluginId: string, deviceId: string): Promise<void> {\n await this.fetch(`/outputs/casts/${encodeURIComponent(pluginId)}/${encodeURIComponent(deviceId)}`, { method: 'DELETE' });\n }\n}\n","import type { SdkFetch } from '../sdk-options.js';\nimport { bigIntReplacer, parseJson, buildQueryString } from '../sdk-options.js';\nimport type {\n GeneratedPersona,\n PersonaAudition,\n PersonaAuditionList,\n PersonaAuditionRequest,\n PersonaAuditionSummary,\n PersonaFile,\n PersonaImportPlan,\n PersonaImportResult,\n PersonaInput,\n PersonaList,\n PersonaMemory,\n PersonaMemoryChange,\n PersonaMemoryRollback,\n PersonaMemoryTimeline,\n PersonaNoteList,\n PersonaNoteState,\n PersonaNoteWrite,\n PersonaRehearsal,\n PersonaRequest,\n PersonaStoryBeatWrite,\n PersonaStoryDetailWrite,\n PersonaStoryList,\n PersonaStoryState,\n PersonaStoryWrite,\n} from './types/personas.types.js';\n\nexport class PersonasClient {\n constructor(private fetch: SdkFetch) {}\n\n /**\n * @name List persona auditions\n * @description Every audition of this character, newest first, without their breaks\n */\n async listPersonaAuditions(id: string): Promise<PersonaAuditionList> {\n const result = await this.fetch(`/personas/${encodeURIComponent(id)}/auditions`, { method: 'GET' });\n return await parseJson<PersonaAuditionList>(result);\n }\n\n /**\n * @name Start persona audition\n * @description Asks the station to put this character through a playlist or a chart. It is queued, not written\n */\n async startPersonaAudition(id: string, body: PersonaAuditionRequest): Promise<PersonaAudition> {\n const result = await this.fetch(`/personas/${encodeURIComponent(id)}/auditions`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<PersonaAudition>(result);\n }\n\n /**\n * @name Get persona audition\n * @description One audition with every break it has written so far, in order\n */\n async getPersonaAudition(id: string, auditionId: string): Promise<PersonaAudition> {\n const result = await this.fetch(`/personas/${encodeURIComponent(id)}/auditions/${encodeURIComponent(auditionId)}`, { method: 'GET' });\n return await parseJson<PersonaAudition>(result);\n }\n\n /**\n * @name Cancel persona audition\n * @description Stops an audition where it stands, keeping the breaks it has already written\n */\n async cancelPersonaAudition(id: string, auditionId: string): Promise<PersonaAuditionSummary> {\n const result = await this.fetch(`/personas/${encodeURIComponent(id)}/auditions/${encodeURIComponent(auditionId)}/cancel`, { method: 'POST' });\n return await parseJson<PersonaAuditionSummary>(result);\n }\n\n /**\n * @name List personas\n * @description Every persona this station has, oldest first\n */\n async listPersonas(): Promise<PersonaList> {\n const result = await this.fetch(`/personas`, { method: 'GET' });\n return await parseJson<PersonaList>(result);\n }\n\n /**\n * @name Create persona\n * @description Writes a new persona. It is not put on air by creating it\n */\n async createPersona(body: PersonaInput): Promise<PersonaList> {\n const result = await this.fetch(`/personas`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<PersonaList>(result);\n }\n\n /**\n * @name Generate persona\n * @description Turns a description of a character into a whole persona, checked against its own sample lines and handed back unsaved\n */\n async generatePersona(body: PersonaRequest): Promise<GeneratedPersona> {\n const result = await this.fetch(`/personas/generate`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<GeneratedPersona>(result);\n }\n\n /**\n * @name Restore station personas\n * @description Writes back whichever of the station's own personas this station is missing, touching nothing it already has and putting nothing on air\n */\n async restoreStationPersonas(): Promise<PersonaList> {\n const result = await this.fetch(`/personas/restore`, { method: 'POST' });\n return await parseJson<PersonaList>(result);\n }\n\n /**\n * @name Export personas\n * @description Every character this station holds, as one file\n */\n async exportPersonas(): Promise<{ data: PersonaFile; headers: { contentDisposition?: string } }> {\n const result = await this.fetch(`/personas/export`, { method: 'GET' });\n const data = await parseJson<PersonaFile>(result);\n return { data, headers: { contentDisposition: result.headers.get('Content-Disposition') ?? undefined } };\n }\n\n /**\n * @name Export persona\n * @description One character, its sheet and its stories, as a file\n */\n async exportPersona(id: string): Promise<{ data: PersonaFile; headers: { contentDisposition?: string } }> {\n const result = await this.fetch(`/personas/${encodeURIComponent(id)}/export`, { method: 'GET' });\n const data = await parseJson<PersonaFile>(result);\n return { data, headers: { contentDisposition: result.headers.get('Content-Disposition') ?? undefined } };\n }\n\n /**\n * @name Preview persona import\n * @description Reads a file and reports what importing it would create, rewrite and skip. Writes nothing\n */\n async previewPersonaImport(body: PersonaFile, query?: { replace?: string[] }): Promise<PersonaImportPlan> {\n const qs = buildQueryString(query);\n const result = await this.fetch(`/personas/import/preview${qs}`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<PersonaImportPlan>(result);\n }\n\n /**\n * @name Import personas\n * @description Writes a file into this station: creates what is new, rewrites only the characters named in `replace`, and answers with what it did\n */\n async importPersonas(body: PersonaFile, query?: { replace?: string[] }): Promise<PersonaImportResult> {\n const qs = buildQueryString(query);\n const result = await this.fetch(`/personas/import${qs}`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<PersonaImportResult>(result);\n }\n\n /**\n * @name Update persona\n * @description Rewrites one persona. An edit to the one on air is heard on the next break\n */\n async updatePersona(id: string, body: PersonaInput): Promise<PersonaList> {\n const result = await this.fetch(`/personas/${encodeURIComponent(id)}`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<PersonaList>(result);\n }\n\n /**\n * @name Delete persona\n * @description Removes a persona, including the one on air, which leaves the station with none\n */\n async deletePersona(id: string): Promise<PersonaList> {\n const result = await this.fetch(`/personas/${encodeURIComponent(id)}`, { method: 'DELETE' });\n return await parseJson<PersonaList>(result);\n }\n\n /**\n * @name Set the station host\n * @description Makes this persona the station's own host, and the previous one no longer is\n */\n async setTheStationHost(id: string): Promise<PersonaList> {\n const result = await this.fetch(`/personas/${encodeURIComponent(id)}/default-host`, { method: 'PUT' });\n return await parseJson<PersonaList>(result);\n }\n\n /**\n * @name List persona notes\n * @description Everything this character has accumulated, oldest first, in every state\n */\n async listPersonaNotes(id: string): Promise<PersonaNoteList> {\n const result = await this.fetch(`/personas/${encodeURIComponent(id)}/notes`, { method: 'GET' });\n return await parseJson<PersonaNoteList>(result);\n }\n\n /**\n * @name Write persona note\n * @description Writes a note by hand. An operator's own note is active from the moment it exists; only the distil pass proposes\n */\n async writePersonaNote(id: string, body: PersonaNoteWrite): Promise<PersonaNoteList> {\n const result = await this.fetch(`/personas/${encodeURIComponent(id)}/notes`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<PersonaNoteList>(result);\n }\n\n /**\n * @name Update persona note\n * @description Rewrites one note's words, whoever wrote it. Editing what the station proposed is most of the point of the panel\n */\n async updatePersonaNote(id: string, noteId: string, body: PersonaNoteWrite): Promise<PersonaNoteList> {\n const result = await this.fetch(`/personas/${encodeURIComponent(id)}/notes/${encodeURIComponent(noteId)}`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<PersonaNoteList>(result);\n }\n\n /**\n * @name Delete persona note\n * @description Removes a note outright. Turning down a PROPOSAL is a state rather than this, or the next pass writes it again\n */\n async deletePersonaNote(id: string, noteId: string): Promise<PersonaNoteList> {\n const result = await this.fetch(`/personas/${encodeURIComponent(id)}/notes/${encodeURIComponent(noteId)}`, { method: 'DELETE' });\n return await parseJson<PersonaNoteList>(result);\n }\n\n /**\n * @name Set persona note state\n * @description Accepts a proposal, turns one down, or rests an active note. Mirrors the lexicon's own state route\n */\n async setPersonaNoteState(id: string, noteId: string, body: PersonaNoteState): Promise<PersonaNoteList> {\n const result = await this.fetch(`/personas/${encodeURIComponent(id)}/notes/${encodeURIComponent(noteId)}/state`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<PersonaNoteList>(result);\n }\n\n /**\n * @name List persona stories\n * @description Every story this character holds, oldest first, in every state\n */\n async listPersonaStories(id: string): Promise<PersonaStoryList> {\n const result = await this.fetch(`/personas/${encodeURIComponent(id)}/stories`, { method: 'GET' });\n return await parseJson<PersonaStoryList>(result);\n }\n\n /**\n * @name Write persona story\n * @description Writes a story by hand. An operator's own is tellable from the moment it exists; only the enrichment pass proposes\n */\n async writePersonaStory(id: string, body: PersonaStoryWrite): Promise<PersonaStoryList> {\n const result = await this.fetch(`/personas/${encodeURIComponent(id)}/stories`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<PersonaStoryList>(result);\n }\n\n /**\n * @name Update persona story\n * @description Rewrites one story's handle and telling, whoever wrote it\n */\n async updatePersonaStory(id: string, storyId: string, body: PersonaStoryWrite): Promise<PersonaStoryList> {\n const result = await this.fetch(`/personas/${encodeURIComponent(id)}/stories/${encodeURIComponent(storyId)}`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<PersonaStoryList>(result);\n }\n\n /**\n * @name Delete persona story\n * @description Removes a story outright, details and all. Turning down a PROPOSAL is a state rather than this, or the next pass writes it again\n */\n async deletePersonaStory(id: string, storyId: string): Promise<PersonaStoryList> {\n const result = await this.fetch(`/personas/${encodeURIComponent(id)}/stories/${encodeURIComponent(storyId)}`, { method: 'DELETE' });\n return await parseJson<PersonaStoryList>(result);\n }\n\n /**\n * @name Set persona story state\n * @description Accepts a proposal, turns one down, or takes a story out of the rotation without losing it\n */\n async setPersonaStoryState(id: string, storyId: string, body: PersonaStoryState): Promise<PersonaStoryList> {\n const result = await this.fetch(`/personas/${encodeURIComponent(id)}/stories/${encodeURIComponent(storyId)}/state`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<PersonaStoryList>(result);\n }\n\n /**\n * @name Add persona story detail\n * @description Adds one thing to a story that already exists\n */\n async addPersonaStoryDetail(id: string, storyId: string, body: PersonaStoryDetailWrite): Promise<PersonaStoryList> {\n const result = await this.fetch(`/personas/${encodeURIComponent(id)}/stories/${encodeURIComponent(storyId)}/details`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<PersonaStoryList>(result);\n }\n\n /**\n * @name Update persona story detail\n * @description Rewrites one detail's words\n */\n async updatePersonaStoryDetail(id: string, storyId: string, detailId: string, body: PersonaStoryDetailWrite): Promise<PersonaStoryList> {\n const result = await this.fetch(\n `/personas/${encodeURIComponent(id)}/stories/${encodeURIComponent(storyId)}/details/${encodeURIComponent(detailId)}`,\n {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n },\n );\n return await parseJson<PersonaStoryList>(result);\n }\n\n /**\n * @name Delete persona story detail\n * @description Removes one detail, leaving the story it was hung on alone\n */\n async deletePersonaStoryDetail(id: string, storyId: string, detailId: string): Promise<PersonaStoryList> {\n const result = await this.fetch(\n `/personas/${encodeURIComponent(id)}/stories/${encodeURIComponent(storyId)}/details/${encodeURIComponent(detailId)}`,\n { method: 'DELETE' },\n );\n return await parseJson<PersonaStoryList>(result);\n }\n\n /**\n * @name Set persona story detail state\n * @description Accepts a proposed detail or turns it down, which has to outlive the pass that proposed it\n */\n async setPersonaStoryDetailState(id: string, storyId: string, detailId: string, body: PersonaStoryState): Promise<PersonaStoryList> {\n const result = await this.fetch(\n `/personas/${encodeURIComponent(id)}/stories/${encodeURIComponent(storyId)}/details/${encodeURIComponent(detailId)}/state`,\n {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n },\n );\n return await parseJson<PersonaStoryList>(result);\n }\n\n /**\n * @name Rehearse persona\n * @description Writes a talk break under this persona against two fixed invented records, and answers with every writer that was asked\n */\n async rehearsePersona(id: string): Promise<PersonaRehearsal> {\n const result = await this.fetch(`/personas/${encodeURIComponent(id)}/rehearse`, { method: 'POST' });\n return await parseJson<PersonaRehearsal>(result);\n }\n\n /**\n * @name Add persona story beat\n * @description Adds one part to an arc. A script rather than a summary: the floor speaks it as it stands\n */\n async addPersonaStoryBeat(id: string, storyId: string, body: PersonaStoryBeatWrite): Promise<PersonaStoryList> {\n const result = await this.fetch(`/personas/${encodeURIComponent(id)}/stories/${encodeURIComponent(storyId)}/beats`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<PersonaStoryList>(result);\n }\n\n /**\n * @name Update persona story beat\n * @description Rewrites one part's words, or moves it in the order\n */\n async updatePersonaStoryBeat(id: string, storyId: string, beatId: string, body: PersonaStoryBeatWrite): Promise<PersonaStoryList> {\n const result = await this.fetch(\n `/personas/${encodeURIComponent(id)}/stories/${encodeURIComponent(storyId)}/beats/${encodeURIComponent(beatId)}`,\n {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n },\n );\n return await parseJson<PersonaStoryList>(result);\n }\n\n /**\n * @name Delete persona story beat\n * @description Removes one part outright, leaving the arc standing. Turning down a PROPOSAL is a state instead\n */\n async deletePersonaStoryBeat(id: string, storyId: string, beatId: string): Promise<PersonaStoryList> {\n const result = await this.fetch(\n `/personas/${encodeURIComponent(id)}/stories/${encodeURIComponent(storyId)}/beats/${encodeURIComponent(beatId)}`,\n { method: 'DELETE' },\n );\n return await parseJson<PersonaStoryList>(result);\n }\n\n /**\n * @name Set persona story beat state\n * @description Accepts a proposed part, or turns it down without losing that it was turned down\n */\n async setPersonaStoryBeatState(id: string, storyId: string, beatId: string, body: PersonaStoryState): Promise<PersonaStoryList> {\n const result = await this.fetch(\n `/personas/${encodeURIComponent(id)}/stories/${encodeURIComponent(storyId)}/beats/${encodeURIComponent(beatId)}/state`,\n {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n },\n );\n return await parseJson<PersonaStoryList>(result);\n }\n\n /**\n * @name Read persona memory\n * @description What this character has told, newest first. The timeline a moment is picked from\n */\n async readPersonaMemory(id: string): Promise<PersonaMemoryTimeline> {\n const result = await this.fetch(`/personas/${encodeURIComponent(id)}/memory`, { method: 'GET' });\n return await parseJson<PersonaMemoryTimeline>(result);\n }\n\n /**\n * @name Preview persona memory rollback\n * @description What rolling back to a moment would undo, without undoing it\n */\n async previewPersonaMemoryRollback(id: string, query?: { to?: string }): Promise<PersonaMemoryChange> {\n const qs = buildQueryString(query);\n const result = await this.fetch(`/personas/${encodeURIComponent(id)}/memory/preview${qs}`, {\n method: 'GET',\n });\n return await parseJson<PersonaMemoryChange>(result);\n }\n\n /**\n * @name Roll back persona memory\n * @description Undo it. Everything the station accrued after that moment goes; everything an operator wrote stays\n */\n async rollBackPersonaMemory(id: string, body: PersonaMemoryRollback): Promise<PersonaMemory> {\n const result = await this.fetch(`/personas/${encodeURIComponent(id)}/memory/rollback`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<PersonaMemory>(result);\n }\n}\n","import { DateTime } from 'luxon';\nconst __dt = (v: unknown, path: string): DateTime => {\n if (typeof v !== 'string') {\n throw new TypeError(`ContractKit: expected an ISO 8601 string at '${path}', received ${typeof v}.`);\n }\n const d = DateTime.fromISO(v);\n if (!d.isValid) throw new TypeError(`ContractKit: '${v}' at '${path}' is not a valid ISO 8601 datetime.`);\n return d;\n};\n\n/**\n * An action a source will permit on one playlist's items. Item-scoped: neither value covers the playlist's own name or description\n * generated from [PlaylistPermission](../../../../../apps/api/data/contracts/playlists/playlists.types.ck)\n */\nexport type PlaylistPermission = 'read' | 'edit';\n\n/**\n * One record as its PROVIDER describes it, plus what the catalog can say about the same copy.\n *\n * The first half mirrors the plugin SDK's `ProviderTrack` and stays the provider's answer: this is a\n * listing of what a playlist holds, not of what the station has ingested. The three ids below are the\n * station's own and are absent for anything it has never seen, which on most playlists is plenty of\n * rows — a playlist is a provider's list and the library is what a sync has walked\n * generated from [CatalogTrack](../../../../../apps/api/data/contracts/playlists/playlists.types.ck)\n */\nexport interface CatalogTrack {\n /** The PROVIDER's id for this copy, which is what an import names it by. Never a `deadair.tracks` id */\n id: string;\n title: string;\n /** Ordered, primary artist first. Empty array if the provider genuinely has none */\n artists: string[];\n album?: string;\n durationMs?: number;\n isrc?: string;\n artworkUrl?: string;\n /** The canonical `deadair.tracks` row this copy is bound to, when the catalog holds one */\n trackId?: string;\n /** The canonical artist behind that row */\n artistId?: string;\n /** The release that row was ingested inside. Absent for a single ingested outside any */\n albumId?: string;\n}\n\n/**\n * One catalog-capable plugin that could not be listed\n * generated from [CatalogSourceError](../../../../../apps/api/data/contracts/playlists/playlists.types.ck)\n */\nexport interface CatalogSourceError {\n pluginId: string;\n pluginName: string;\n message: string;\n}\n\n/**\n * One music source whose playlists are in this answer, and how old its list is\n * generated from [CatalogPlaylistSource](../../../../../apps/api/data/contracts/playlists/playlists.types.ck)\n */\nexport interface CatalogPlaylistSource {\n pluginId: string;\n pluginName: string;\n /** When the station last read this source's whole list of playlists. The library sync reads it in the background, so this is usually minutes old; a source listed for the first time is read for this answer */\n listedAt: DateTime;\n}\n\n/** Rehydrates every wire-encoded scalar in a CatalogPlaylistSource into its runtime type. Mutates and returns `raw`. */\nexport function reviveCatalogPlaylistSource(raw: CatalogPlaylistSource): CatalogPlaylistSource {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['listedAt'] = __dt(__o0['listedAt'], 'CatalogPlaylistSource.listedAt');\n return raw;\n}\n\n/**\n * A playlist a catalog-capable plugin offers, tagged with the plugin it came from so an aggregated list is addressable\n * generated from [CatalogPlaylist](../../../../../apps/api/data/contracts/playlists/playlists.types.ck)\n */\nexport interface CatalogPlaylist {\n pluginId: string;\n pluginName: string;\n id: string;\n name: string;\n description?: string;\n trackCount?: number;\n artworkUrl?: string;\n /** What the SOURCE permits on this playlist's items, not what this actor may do. Empty means the source permits nothing; absent means it did not say */\n permissions?: PlaylistPermission[];\n /** The source made this playlist itself rather than a person: an editorial list, or one generated for the account like Discover Weekly. Absent when it did not say */\n madeByProvider?: boolean;\n /** An operator hid this playlist from this station, so pickers leave it out and the library sync does not read it. Absent when it is not hidden */\n hidden?: boolean;\n}\n\n/**\n * generated from [CatalogPlaylistTracks](../../../../../apps/api/data/contracts/playlists/playlists.types.ck)\n */\nexport interface CatalogPlaylistTracks {\n pluginId: string;\n playlistId: string;\n tracks: CatalogTrack[];\n}\n\n/**\n * generated from [CatalogPlaylistPage](../../../../../apps/api/data/contracts/playlists/playlists.types.ck)\n */\nexport interface CatalogPlaylistPage {\n playlists: CatalogPlaylist[];\n /** Every source whose playlists are listed, including one that also has an entry in `errors`: its list is then the last one the station read. Absent from a station that predates it, which asked every source live */\n sources?: CatalogPlaylistSource[];\n errors: CatalogSourceError[];\n}\n\n/** Rehydrates every wire-encoded scalar in a CatalogPlaylistPage into its runtime type. Mutates and returns `raw`. */\nexport function reviveCatalogPlaylistPage(raw: CatalogPlaylistPage): CatalogPlaylistPage {\n const __o0 = raw as unknown as Record<string, unknown>;\n if (__o0['sources'] != null) {\n {\n const __a1 = __o0['sources'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveCatalogPlaylistSource(__a1[__i2] as never);\n }\n }\n }\n return raw;\n}\n","import { DateTime } from 'luxon';\nconst __dt = (v: unknown, path: string): DateTime => {\n if (typeof v !== 'string') {\n throw new TypeError(`ContractKit: expected an ISO 8601 string at '${path}', received ${typeof v}.`);\n }\n const d = DateTime.fromISO(v);\n if (!d.isValid) throw new TypeError(`ContractKit: '${v}' at '${path}' is not a valid ISO 8601 datetime.`);\n return d;\n};\n\n/**\n * A playlist the station owns: records it holds in its own library, in an order somebody chose, cloned\n * from somewhere else and free to differ from it afterwards\n * generated from [StationPlaylist](../../../../../apps/api/data/contracts/playlists/station.playlists.types.ck)\n */\nexport interface StationPlaylist {\n id: string;\n name: string;\n /** What this playlist is for, in the operator's own words. Empty when nobody said */\n prompt: string;\n /** The plugin this was cloned from, for a badge and nothing else. Absent for one read from a file or made here */\n originPluginId?: string;\n /** Every row, placeholders included */\n trackCount: number;\n /** The rows that name a record in the library, which are the ones that can air */\n resolvedCount: number;\n createdAt: DateTime;\n updatedAt: DateTime;\n}\n\nexport interface StationPlaylistInput {\n name: string;\n /** What this playlist is for, in the operator's own words. Empty when nobody said */\n prompt: string;\n}\n\n/** Rehydrates every wire-encoded scalar in a StationPlaylist into its runtime type. Mutates and returns `raw`. */\nexport function reviveStationPlaylist(raw: StationPlaylist): StationPlaylist {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['createdAt'] = __dt(__o0['createdAt'], 'StationPlaylist.createdAt');\n __o0['updatedAt'] = __dt(__o0['updatedAt'], 'StationPlaylist.updatedAt');\n return raw;\n}\n\n/**\n * One row of a station playlist: a record in the library, or a placeholder for one it does not hold yet\n * generated from [StationPlaylistTrack](../../../../../apps/api/data/contracts/playlists/station.playlists.types.ck)\n */\nexport interface StationPlaylistTrack {\n /** The row's own id, not the record's */\n id: string;\n position: number;\n title: string;\n /** Ordered, primary artist first */\n artists: string[];\n album?: string;\n durationMs?: number;\n /** The library record this row plays. Absent on a placeholder */\n trackId?: string;\n artistId?: string;\n albumId?: string;\n /** On a placeholder, the plugin whose copy it was cloned from. Absent on one read from a file, which names a record and no copy of it */\n originPluginId?: string;\n}\n\n/**\n * What may change about a station playlist after it exists. Absent fields are left alone\n * generated from [StationPlaylistUpdate](../../../../../apps/api/data/contracts/playlists/station.playlists.types.ck)\n */\nexport interface StationPlaylistUpdate {\n name?: string;\n prompt?: string;\n}\n\n/**\n * Where a record in a file came from, when it came from a provider's copy. Carried so a record the\n * receiving library does not hold can still be matched by that copy later\n * generated from [PlaylistFileOrigin](../../../../../apps/api/data/contracts/playlists/station.playlists.types.ck)\n */\nexport interface PlaylistFileOrigin {\n pluginId: string;\n externalId: string;\n}\n\n/**\n * A playlist one of the station's music sources holds, named the way the playlists listing names it\n * generated from [PlaylistProviderRef](../../../../../apps/api/data/contracts/playlists/station.playlists.types.ck)\n */\nexport interface PlaylistProviderRef {\n pluginId: string;\n playlistId: string;\n}\n\n/**\n * What importing one record would do here\n * generated from [PlaylistImportEntry](../../../../../apps/api/data/contracts/playlists/station.playlists.types.ck)\n */\nexport interface PlaylistImportEntry {\n position: number;\n title: string;\n artists: string[];\n /** `matched`: the library holds it. `toAdd`: it names a provider's copy, which the station can add to its library. `toLookUp`: it names only a record, which the station has to search its providers for */\n outcome: 'matched' | 'toAdd' | 'toLookUp';\n /** The library record a `matched` row plays */\n trackId?: string;\n}\n\n/**\n * generated from [StationPlaylistList](../../../../../apps/api/data/contracts/playlists/station.playlists.types.ck)\n */\nexport interface StationPlaylistList {\n playlists: StationPlaylist[];\n}\n\nexport interface StationPlaylistListInput {\n playlists: StationPlaylistInput[];\n}\n\n/** Rehydrates every wire-encoded scalar in a StationPlaylistList into its runtime type. Mutates and returns `raw`. */\nexport function reviveStationPlaylistList(raw: StationPlaylistList): StationPlaylistList {\n const __o0 = raw as unknown as Record<string, unknown>;\n {\n const __a1 = __o0['playlists'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveStationPlaylist(__a1[__i2] as never);\n }\n }\n return raw;\n}\n\n/**\n * generated from [StationPlaylistDetail](../../../../../apps/api/data/contracts/playlists/station.playlists.types.ck)\n */\nexport interface StationPlaylistDetail extends StationPlaylist {\n tracks: StationPlaylistTrack[];\n}\n\nexport interface StationPlaylistDetailInput extends StationPlaylistInput {\n tracks: StationPlaylistTrack[];\n}\n\n/** Rehydrates every wire-encoded scalar in a StationPlaylistDetail into its runtime type. Mutates and returns `raw`. */\nexport function reviveStationPlaylistDetail(raw: StationPlaylistDetail): StationPlaylistDetail {\n reviveStationPlaylist(raw as never);\n return raw;\n}\n\n/**\n * One record as a playlist file names it. By its words and its ISRC, never by an id of this station's:\n * ids are minted afresh by every library, so a file keyed by them would restore onto nothing\n * generated from [PlaylistFileTrack](../../../../../apps/api/data/contracts/playlists/station.playlists.types.ck)\n */\nexport interface PlaylistFileTrack {\n title: string;\n /** Ordered, primary artist first */\n artists: string[];\n album?: string;\n durationMs?: number;\n isrc?: string;\n origin?: PlaylistFileOrigin;\n}\n\n/**\n * What an import WOULD do, written nowhere\n * generated from [PlaylistImportPlan](../../../../../apps/api/data/contracts/playlists/station.playlists.types.ck)\n */\nexport interface PlaylistImportPlan {\n name: string;\n matched: number;\n toAdd: number;\n toLookUp: number;\n /** Lines of the source that named no record the station could read */\n skipped: number;\n entries: PlaylistImportEntry[];\n /** Anything about the source as a whole an operator should know before importing it */\n notices: string[];\n}\n\n/**\n * A playlist as a file: everything somebody would need to rebuild it on another station\n * generated from [PlaylistFile](../../../../../apps/api/data/contracts/playlists/station.playlists.types.ck)\n */\nexport interface PlaylistFile {\n /** What shape this is, so a file from a later build says so rather than being read wrongly */\n format: string;\n /** When it was exported, ISO-8601 */\n takenAt: string;\n /** The station it was taken from. Provenance only */\n station?: string;\n name: string;\n prompt?: string;\n tracks: PlaylistFileTrack[];\n}\n\n/**\n * generated from [PlaylistImportResult](../../../../../apps/api/data/contracts/playlists/station.playlists.types.ck)\n */\nexport interface PlaylistImportResult {\n plan: PlaylistImportPlan;\n playlist: StationPlaylist;\n}\n\nexport interface PlaylistImportResultInput {\n plan: PlaylistImportPlan;\n playlist: StationPlaylistInput;\n}\n\n/** Rehydrates every wire-encoded scalar in a PlaylistImportResult into its runtime type. Mutates and returns `raw`. */\nexport function revivePlaylistImportResult(raw: PlaylistImportResult): PlaylistImportResult {\n const __o0 = raw as unknown as Record<string, unknown>;\n reviveStationPlaylist(__o0['playlist'] as never);\n return raw;\n}\n\n/**\n * Something to import a playlist from. Exactly one source\n * generated from [PlaylistImportInput](../../../../../apps/api/data/contracts/playlists/station.playlists.types.ck)\n */\nexport interface PlaylistImportInput {\n /** A playlist exported from a deadair station */\n file?: PlaylistFile;\n /** A playlist another program wrote, as its text: an M3U, a CSV with a header row, or one `Artist - Title` per line */\n text?: string;\n /** Which of those `text` is. Absent works it out from the text */\n format?: 'm3u' | 'csv' | 'text';\n /** The name of the file `text` came from, which names the playlist when the text does not */\n fileName?: string;\n /** A link to a playlist at one of the station's music sources, as a browser or an app shows it */\n url?: string;\n /** A playlist a music source lists here, by its plugin and its id */\n providerPlaylist?: PlaylistProviderRef;\n /** What to call the new playlist. Absent keeps the name the source gives it */\n name?: string;\n}\n","import type { SdkFetch } from '../sdk-options.js';\nimport { bigIntReplacer, parseJson } from '../sdk-options.js';\nimport type { CatalogPlaylistPage, CatalogPlaylistTracks } from './types/playlists.types.js';\nimport { reviveCatalogPlaylistPage } from './types/playlists.types.js';\nimport type {\n PlaylistFile,\n PlaylistImportInput,\n PlaylistImportPlan,\n PlaylistImportResult,\n StationPlaylist,\n StationPlaylistDetail,\n StationPlaylistList,\n StationPlaylistUpdate,\n} from './types/station.playlists.types.js';\nimport {\n revivePlaylistImportResult,\n reviveStationPlaylist,\n reviveStationPlaylistDetail,\n reviveStationPlaylistList,\n} from './types/station.playlists.types.js';\n\nexport class PlaylistsClient {\n constructor(private fetch: SdkFetch) {}\n\n /**\n * @name List importable playlists\n * @description Every playlist the installed `catalog` plugins offer, as the library sync last read each one's list. A source with no list kept yet is asked while the request waits\n */\n async listImportablePlaylists(): Promise<CatalogPlaylistPage> {\n const result = await this.fetch(`/playlists`, { method: 'GET' });\n return reviveCatalogPlaylistPage(await parseJson<CatalogPlaylistPage>(result));\n }\n\n /**\n * @name Get playlist tracks\n * @description One playlist's tracks from one plugin\n */\n async getPlaylistTracks(pluginId: string, playlistId: string): Promise<CatalogPlaylistTracks> {\n const result = await this.fetch(`/playlists/${encodeURIComponent(pluginId)}/${encodeURIComponent(playlistId)}/tracks`, { method: 'GET' });\n return await parseJson<CatalogPlaylistTracks>(result);\n }\n\n /**\n * @name Hide playlist\n * @description Hides one playlist from this station: the listing marks it hidden, the pickers stop offering it and the library sync stops reading it. Hiding one already hidden changes nothing\n */\n async hidePlaylist(pluginId: string, playlistId: string): Promise<void> {\n await this.fetch(`/playlists/${encodeURIComponent(pluginId)}/${encodeURIComponent(playlistId)}/hidden`, { method: 'PUT' });\n }\n\n /**\n * @name Show playlist\n * @description Shows a hidden playlist again. Showing one that is not hidden changes nothing\n */\n async showPlaylist(pluginId: string, playlistId: string): Promise<void> {\n await this.fetch(`/playlists/${encodeURIComponent(pluginId)}/${encodeURIComponent(playlistId)}/hidden`, { method: 'DELETE' });\n }\n\n /**\n * @name Refresh playlists\n * @description Reads every playlist on every music source again, in the background, rather than waiting for the next scheduled read. New records reach the library; records gone from every playlist are retired\n */\n async refreshPlaylists(): Promise<void> {\n await this.fetch(`/playlists/refresh`, { method: 'POST' });\n }\n\n /**\n * @name Refresh playlist\n * @description Reads one playlist again, in the background. New records reach the library; a record taken out of it stays until the next full read judges it\n */\n async refreshPlaylist(pluginId: string, playlistId: string): Promise<void> {\n await this.fetch(`/playlists/${encodeURIComponent(pluginId)}/${encodeURIComponent(playlistId)}/refresh`, { method: 'POST' });\n }\n\n /**\n * @name List station playlists\n * @description Every playlist the station owns, newest first\n */\n async listStationPlaylists(): Promise<StationPlaylistList> {\n const result = await this.fetch(`/station-playlists`, { method: 'GET' });\n return reviveStationPlaylistList(await parseJson<StationPlaylistList>(result));\n }\n\n /**\n * @name Get station playlist\n * @description One station playlist with its records in order, placeholders included\n */\n async getStationPlaylist(id: string): Promise<StationPlaylistDetail> {\n const result = await this.fetch(`/station-playlists/${encodeURIComponent(id)}`, { method: 'GET' });\n return reviveStationPlaylistDetail(await parseJson<StationPlaylistDetail>(result));\n }\n\n /**\n * @name Update station playlist\n * @description Renames a station playlist, or rewrites what it is for\n */\n async updateStationPlaylist(id: string, body: StationPlaylistUpdate): Promise<StationPlaylist> {\n const result = await this.fetch(`/station-playlists/${encodeURIComponent(id)}`, {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return reviveStationPlaylist(await parseJson<StationPlaylist>(result));\n }\n\n /**\n * @name Delete station playlist\n * @description Deletes a station playlist. The records it named stay in the library\n */\n async deleteStationPlaylist(id: string): Promise<void> {\n await this.fetch(`/station-playlists/${encodeURIComponent(id)}`, { method: 'DELETE' });\n }\n\n /**\n * @name Fill station playlist\n * @description Looks up the records this playlist names and the library does not hold, in the background, and adds the ones a provider has. The activity feed says how it went\n */\n async fillStationPlaylist(id: string): Promise<void> {\n await this.fetch(`/station-playlists/${encodeURIComponent(id)}/fill`, { method: 'POST' });\n }\n\n /**\n * @name Export station playlist\n * @description One station playlist as a file another station can import\n */\n async exportStationPlaylist(id: string): Promise<{ data: PlaylistFile; headers: { contentDisposition?: string } }> {\n const result = await this.fetch(`/station-playlists/${encodeURIComponent(id)}/export`, { method: 'GET' });\n const data = await parseJson<PlaylistFile>(result);\n return { data, headers: { contentDisposition: result.headers.get('Content-Disposition') ?? undefined } };\n }\n\n /**\n * @name Preview playlist import\n * @description Reads a source and reports which of its records the library holds and which it would have to find. Writes nothing\n */\n async previewPlaylistImport(body: PlaylistImportInput): Promise<PlaylistImportPlan> {\n const result = await this.fetch(`/station-playlists/import/preview`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<PlaylistImportPlan>(result);\n }\n\n /**\n * @name Import playlist\n * @description Makes a new station playlist from a source and answers with what it did\n */\n async importPlaylist(body: PlaylistImportInput): Promise<PlaylistImportResult> {\n const result = await this.fetch(`/station-playlists/import`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return revivePlaylistImportResult(await parseJson<PlaylistImportResult>(result));\n }\n}\n","import type { SdkFetch } from '../sdk-options.js';\nimport { bigIntReplacer, parseJson } from '../sdk-options.js';\nimport type {\n PlayoutAlbumInput,\n PlayoutChartInput,\n PlayoutPlaylistInput,\n PlayoutStationPlaylistInput,\n PlayoutStatus,\n} from './types/playout.types.js';\n\nexport class PlayoutClient {\n constructor(private fetch: SdkFetch) {}\n\n /**\n * @name Get playout status\n * @description What the station is playing and what is queued behind it. The console polls this\n */\n async getPlayoutStatus(): Promise<PlayoutStatus> {\n const result = await this.fetch(`/playout/status`, { method: 'GET' });\n return await parseJson<PlayoutStatus>(result);\n }\n\n /**\n * @name Play a playlist\n * @description Loads a plugin playlist into the running order and starts handing it to the player. Replaces whatever was queued; what is on air finishes rather than being cut off\n */\n async playAPlaylist(body: PlayoutPlaylistInput): Promise<PlayoutStatus> {\n const result = await this.fetch(`/playout/playlist`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<PlayoutStatus>(result);\n }\n\n /**\n * @name Play a station playlist\n * @description Loads a playlist the station owns into the running order and starts handing it to the player. The same replacement a plugin playlist makes, from records the library already holds\n */\n async playAStationPlaylist(body: PlayoutStationPlaylistInput): Promise<PlayoutStatus> {\n const result = await this.fetch(`/playout/station-playlist`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<PlayoutStatus>(result);\n }\n\n /**\n * @name Play an album\n * @description Plays an album the library holds, whole and in the order it was made: by disc, then by track. A feature, so no breaks and no blends between its records, and what is on air finishes rather than being cut off. It stops at the end of the album, or when the schedule's next block starts\n */\n async playAnAlbum(body: PlayoutAlbumInput): Promise<PlayoutStatus> {\n const result = await this.fetch(`/playout/album`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<PlayoutStatus>(result);\n }\n\n /**\n * @name Play a chart\n * @description Builds the running order from a published chart and starts handing it to the player. The same replacement a playlist makes, from a document somebody else ranked\n */\n async playAChart(body: PlayoutChartInput): Promise<PlayoutStatus> {\n const result = await this.fetch(`/playout/chart`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<PlayoutStatus>(result);\n }\n\n /**\n * @name Skip the current item\n * @description Ends the item on air so the next one starts immediately. The station owns the decoder, so this lands at once rather than waiting out audio already committed to a player\n */\n async skipTheCurrentItem(): Promise<PlayoutStatus> {\n const result = await this.fetch(`/playout/skip`, { method: 'POST' });\n return await parseJson<PlayoutStatus>(result);\n }\n\n /**\n * @name Start playout\n * @description Puts the station back on air with the running order it already has, picking it up where Stop left it. Distinct from putting a playlist on air, which builds a new broadcast and throws away what was there. Refused when there is nothing left to resume\n */\n async startPlayout(): Promise<PlayoutStatus> {\n const result = await this.fetch(`/playout/start`, { method: 'POST' });\n return await parseJson<PlayoutStatus>(result);\n }\n\n /**\n * @name Stop playout\n * @description Stands the station down: stops what is on air at once and hands the mount back. The running order is LEFT as it is, so `/playout/start` can pick it up where this stopped it. deadair holds the mount on a lease it renews while it has something to play, so stopping goes quiet rather than falling through to a bed nobody programmed\n */\n async stopPlayout(): Promise<PlayoutStatus> {\n const result = await this.fetch(`/playout/stop`, { method: 'POST' });\n return await parseJson<PlayoutStatus>(result);\n }\n}\n","import { DateTime } from 'luxon';\nconst __dt = (v: unknown, path: string): DateTime => {\n if (typeof v !== 'string') {\n throw new TypeError(`ContractKit: expected an ISO 8601 string at '${path}', received ${typeof v}.`);\n }\n const d = DateTime.fromISO(v);\n if (!d.isValid) throw new TypeError(`ContractKit: '${v}' at '${path}' is not a valid ISO 8601 datetime.`);\n return d;\n};\n\n/**\n * Lifecycle state of a plugin the host knows about\n * generated from [PluginStatus](../../../../../apps/api/data/contracts/plugins/plugins.types.ck)\n */\nexport type PluginStatus = 'discovered' | 'disabled' | 'misconfigured' | 'active' | 'failed';\n\n/**\n * Where the station found a plugin: shipped inside the image, or installed by the operator into the plugins\n * directory on the data volume. Says nothing about trust; both kinds run inside the station with its privileges\n * generated from [PluginOrigin](../../../../../apps/api/data/contracts/plugins/plugins.types.ck)\n */\nexport type PluginOrigin = 'bundled' | 'installed';\n\n/**\n * generated from [ConfigFieldType](../../../../../apps/api/data/contracts/plugins/plugins.types.ck)\n */\nexport type ConfigFieldType = 'string' | 'text' | 'url' | 'secret' | 'number' | 'boolean' | 'select' | 'multiselect' | 'list' | 'note';\n\n/**\n * What a `number` field's value is measured in. The stored value is always in this unit; only the\n * control the operator touches changes, so a byte count stays a byte count everywhere it is read and\n * a `fraction` stays the share between 0 and 1 that the code multiplying by it wants\n * generated from [ConfigFieldUnit](../../../../../apps/api/data/contracts/plugins/plugins.types.ck)\n */\nexport type ConfigFieldUnit = 'bytes' | 'fraction';\n\n/**\n * The control a field asks to be drawn with, where the ordinary one for its type reads badly. Opt-in\n * per field rather than inferred, because a slider is right for a value you feel for and wrong for\n * one you have to hit exactly, and `tags` is right for a comma-separated line that is really a SET\n * and wrong for one that is prose. Nothing about the stored value changes either way\n * generated from [ConfigFieldControl](../../../../../apps/api/data/contracts/plugins/plugins.types.ck)\n */\nexport type ConfigFieldControl = 'slider' | 'tags';\n\n/**\n * One choice of a `select` config field\n * generated from [ConfigFieldOption](../../../../../apps/api/data/contracts/plugins/plugins.types.ck)\n */\nexport interface ConfigFieldOption {\n value: string;\n label: string;\n}\n\n/**\n * Where a field's or a column's choices come from when only the console can enumerate them: the\n * station's own tables, the platform's zone list, the enabled plugins that can do one of five jobs,\n * or the models the selected model plugin currently offers. Resolved by the console either way\n * generated from [ConfigFieldOptionSource](../../../../../apps/api/data/contracts/plugins/plugins.types.ck)\n */\nexport type ConfigFieldOptionSource =\n | 'station.newsCategories'\n | 'station.newsFeeds'\n | 'station.podcastShows'\n | 'station.narrationSeries'\n | 'intl.timeZones'\n | 'plugins.speech'\n | 'plugins.llm'\n | 'plugins.mixer'\n | 'plugins.analysis'\n | 'plugins.similarity'\n | 'llm.models';\n\n/**\n * A row a `list` field offers to start from instead of an empty one. Adding a row from it fills the cells it names, by column key, and nothing records which preset a row came from\n * generated from [ConfigFieldPreset](../../../../../apps/api/data/contracts/plugins/plugins.types.ck)\n */\nexport interface ConfigFieldPreset {\n /** What the operator picks it by */\n label: string;\n /** Cell values by column key. A key with no column, or a `secret` column's, is ignored */\n cells: Record<string, string>;\n}\n\n/**\n * Whether a capability has ONE answer or is asked of everything in turn. `one` stores a plugin id\n * and `ordered` stores a list of them; see `plugins/plugin.providers.ts`, which both this and the\n * station read the pairing from\n * generated from [ProviderMode](../../../../../apps/api/data/contracts/plugins/plugins.types.ck)\n */\nexport type ProviderMode = 'one' | 'ordered';\n\n/**\n * A plugin handed over from the browser. The generated client types the body as `FormData`, so\n * nothing checks this shape. It says what to send\n * generated from [PluginImport](../../../../../apps/api/data/contracts/plugins/plugins.types.ck)\n */\nexport interface PluginImport {\n /** The gzip tarball npm pack writes: every entry under package/, holding package.json and the built code, at most 64 MB */\n file: Blob;\n}\n\n/**\n * generated from [PluginLogLevel](../../../../../apps/api/data/contracts/plugins/plugins.types.ck)\n */\nexport type PluginLogLevel = 'debug' | 'info' | 'warn' | 'error';\n\n/**\n * A submitted settings form. Secret values arrive in here and are never echoed back\n * generated from [PluginConfigInput](../../../../../apps/api/data/contracts/plugins/plugins.types.ck)\n */\nexport interface PluginConfigInput {\n config: Record<string, unknown>;\n}\n\n/**\n * What a plugin may do with a capability it asked for. Denied is the default and needs no row: a\n * capability is refused until somebody allows it, so \"never answered\" and \"refused\" are one state\n * generated from [GrantDecision](../../../../../apps/api/data/contracts/plugins/plugins.types.ck)\n */\nexport type GrantDecision = 'allowed' | 'denied';\n\n/**\n * Outcome of the plugin's own `testConnection()`\n * generated from [PluginTestResult](../../../../../apps/api/data/contracts/plugins/plugins.types.ck)\n */\nexport interface PluginTestResult {\n ok: boolean;\n message?: string;\n}\n\n/**\n * Where the console should send the browser to obtain the operator's consent. Reported rather than\n * redirected to: the route is behind the Bearer floor, so a browser cannot follow a redirect from it\n * generated from [PluginOAuthStart](../../../../../apps/api/data/contracts/plugins/plugins.types.ck)\n */\nexport interface PluginOAuthStart {\n url: string;\n}\n\n/**\n * Outcome of an OAuth callback\n * generated from [PluginOAuthResult](../../../../../apps/api/data/contracts/plugins/plugins.types.ck)\n */\nexport interface PluginOAuthResult {\n pluginId: string;\n ok: boolean;\n message?: string;\n}\n\n/**\n * generated from [PluginOAuthCallbackQuery](../../../../../apps/api/data/contracts/plugins/plugins.types.ck)\n */\nexport interface PluginOAuthCallbackQuery {\n code?: string;\n state?: string;\n error?: string;\n ubi?: string;\n /**\n * What a desktop-style flow returns instead of `code`: the provider mints a token before the\n * consent screen and hands the same one back, which the plugin exchanges for a session. Last.fm's\n * auth works this way. Listed here because the route parses this query strictly, so an\n * undeclared parameter is a 400 before any plugin code runs\n */\n token?: string;\n}\n\n/**\n * One plugin's standing for one capability, as the Providers section draws it\n * generated from [ProviderCandidate](../../../../../apps/api/data/contracts/plugins/plugins.types.ck)\n */\nexport interface ProviderCandidate {\n pluginId: string;\n /** The plugin's own name, which is what an operator knows it by. The id is what is stored */\n name: string;\n enabled: boolean;\n status: PluginStatus;\n /** Where in the asking order this plugin sits, counting from 1. Absent when it cannot currently answer, which is every status but `active` */\n position?: number;\n /** Whether the operator named this plugin, as opposed to it being here because it is installed. False everywhere when nothing is set */\n listed: boolean;\n /** Whether the station reaches this plugin for this capability. Every active candidate for an `ordered` capability, and only the chosen one for a `one` */\n inUse: boolean;\n /** `enrichment` only: the number the plugin's AUTHOR gave it, which orders whatever the operator did not. Lower wins a conflicting fact */\n declaredPriority?: number;\n}\n\n/**\n * Live choices for a plugin's config fields, keyed by field key, out of the plugin's own\n * `suggestConfigOptions()`. What `ConfigFieldDescriptor.options` cannot be: fixed when the manifest\n * was written, where these are whatever the operator's own server currently says\n * generated from [PluginFieldSuggestions](../../../../../apps/api/data/contracts/plugins/plugins.types.ck)\n */\nexport interface PluginFieldSuggestions {\n /** Keys the plugin had nothing to say about are simply absent, rather than present and empty */\n fields: Record<string, ConfigFieldOption[]>;\n /**\n * False when the plugin does not implement suggestions at all, so a console can tell \"nothing to\n * suggest\" from \"asked and got nothing\", and draw a refresh control only where one would do something\n */\n supported: boolean;\n}\n\n/**\n * One column of a `list` field. Every ordinary cell is stored as a string in the row, so this describes the\n * control rather than the value; a `secret` cell is encrypted on its own and is never in the row at all\n * generated from [ConfigFieldColumn](../../../../../apps/api/data/contracts/plugins/plugins.types.ck)\n */\nexport interface ConfigFieldColumn {\n key: string;\n label: string;\n type: 'string' | 'url' | 'select' | 'secret';\n required?: boolean;\n placeholder?: string;\n options?: ConfigFieldOption[];\n optionsFrom?: ConfigFieldOptionSource;\n /** Key of another column in the same list. This cell applies only to a row whose cell there holds one of `dependsOnValues`. Stronger than a field's `dependsOn`, which only hides a control: a cell that does not apply is neither sent by the console nor read by the host, so a `url` column that does not apply to a row contributes no hostname to the plugin's allowlist. A target this list does not declare, or a target cell still empty, shows the cell */\n dependsOn?: string;\n /** The values of the `dependsOn` cell this one applies to. Omitted means any non-empty value; ignored without a target */\n dependsOnValues?: string[];\n /** `secret` only: key of the address column in the same list this credential is sent to. A save that keeps the stored credential while that row's address moves to another origin is refused */\n sentTo?: string;\n}\n\n/**\n * generated from [PluginLogEntry](../../../../../apps/api/data/contracts/plugins/plugins.types.ck)\n */\nexport interface PluginLogEntry {\n ts: string;\n level: PluginLogLevel;\n /** Must match MAX_LINE_BYTES_CEILING in apps/api/src/logging/rotating.log.store.ts. Change both together */\n text: string;\n}\n\n/**\n * generated from [PluginLogQuery](../../../../../apps/api/data/contracts/plugins/plugins.types.ck)\n */\nexport interface PluginLogQuery {\n limit?: number;\n level?: PluginLogLevel;\n}\n\n/**\n * generated from [PluginLogLevelInput](../../../../../apps/api/data/contracts/plugins/plugins.types.ck)\n */\nexport interface PluginLogLevelInput {\n level: PluginLogLevel;\n}\n\n/**\n * One capability a plugin asked for, with the station's answer. The ask is the plugin's manifest and\n * the answer is a row, so a plugin that stops asking stops appearing here whatever was stored\n * generated from [PluginGrant](../../../../../apps/api/data/contracts/plugins/plugins.types.ck)\n */\nexport interface PluginGrant {\n pluginId: string;\n pluginName: string;\n /** The host's own id for it, e.g. `network.open` */\n capability: string;\n /** What the host calls the capability */\n label: string;\n /** What allowing it opens up, in the station's words */\n describes: string;\n /** Why this plugin says it needs it, in the plugin's words */\n reason: string;\n decision: GrantDecision;\n}\n\n/**\n * generated from [PluginGrantInput](../../../../../apps/api/data/contracts/plugins/plugins.types.ck)\n */\nexport interface PluginGrantInput {\n capability: string;\n decision: GrantDecision;\n}\n\n/**\n * One capability, who can answer it, and what the operator has said about the order\n * generated from [ProviderCapabilityState](../../../../../apps/api/data/contracts/plugins/plugins.types.ck)\n */\nexport interface ProviderCapabilityState {\n /** The manifest capability, which is also the console's anchor for this block */\n capability: string;\n mode: ProviderMode;\n /** The `deadair.settings` key the console writes. Its descriptor carries the wording */\n settingKey: string;\n /** The raw stored value, so the console can tell a default order from one somebody set. Empty when nothing is stored */\n configured: string;\n /** Active plugins first, in the order the station asks them, then the ones that cannot answer */\n candidates: ProviderCandidate[];\n /** Ids named in the setting that no active plugin answers to. Ordering never gates, so these cost nothing but say nothing either until they are shown */\n stale: string[];\n /** `one` only: a plugin is named and is not an active candidate, so the station has NO provider for this. The dangerous state, because naming one is an instruction and never falls back */\n unanswered: boolean;\n}\n\n/**\n * Mirrors the plugin SDK's `ConfigField`: enough for a console to render the settings form with no per-plugin code\n * generated from [ConfigFieldDescriptor](../../../../../apps/api/data/contracts/plugins/plugins.types.ck)\n */\nexport interface ConfigFieldDescriptor {\n key: string;\n label: string;\n type: ConfigFieldType;\n required?: boolean;\n default?: string | number | boolean;\n /** `number` only, and ignored elsewhere */\n unit?: ConfigFieldUnit;\n /** `slider` for a `number` with both `min` and `max`, `tags` for a `string` holding a comma-separated set */\n control?: ConfigFieldControl;\n /** How coarsely a `control` moves, in the field's own unit. Ignored without one, and defaults to 1 */\n step?: number;\n /** `number` only: the smallest value that will be accepted, inclusive */\n min?: number;\n /** `number` only: the largest value that will be accepted, inclusive */\n max?: number;\n placeholder?: string;\n help?: string;\n options?: ConfigFieldOption[];\n /** Choices only the console can enumerate. Merged where a plugin's own suggestions are, and outranked by them */\n optionsFrom?: ConfigFieldOptionSource;\n /** `list` only, and ignored elsewhere */\n columns?: ConfigFieldColumn[];\n /** `list` only: rows the Add button offers to start from, beside an empty one */\n presets?: ConfigFieldPreset[];\n /** Key of the field this one is only relevant to */\n dependsOn?: string;\n /** Key of the `number` field that is the upper end of the range this one opens, declared on the lower end only. Still two settings, each validated by name; the console draws them as one control whose handles cannot cross */\n rangeWith?: string;\n /** `secret` only: key of the address field this credential is sent to. A save that keeps the stored credential while that address moves to another origin is refused */\n sentTo?: string;\n}\n\n/**\n * generated from [PluginLogPage](../../../../../apps/api/data/contracts/plugins/plugins.types.ck)\n */\nexport interface PluginLogPage {\n pluginId: string;\n level: PluginLogLevel;\n /** Newest first, as the activity feed and the script history send. The download is the file as written, oldest first */\n entries: PluginLogEntry[];\n}\n\n/**\n * generated from [PluginGrantList](../../../../../apps/api/data/contracts/plugins/plugins.types.ck)\n */\nexport interface PluginGrantList {\n /** Every capability every installed plugin is asking for, refused ones included */\n grants: PluginGrant[];\n}\n\n/**\n * Every capability an operator chooses between. Capabilities that fan out and merge without\n * ranking are deliberately absent: order changes nothing about a union\n * generated from [ProviderCatalogue](../../../../../apps/api/data/contracts/plugins/plugins.types.ck)\n */\nexport interface ProviderCatalogue {\n capabilities: ProviderCapabilityState[];\n}\n\n/**\n * A plugin as the settings list sees it. Carries no configured VALUES, only which secrets are set\n * generated from [PluginSummary](../../../../../apps/api/data/contracts/plugins/plugins.types.ck)\n */\nexport interface PluginSummary {\n id: string;\n name: string;\n version: string;\n capabilities: string[];\n /** Whether the manifest declares the `trackFetcher` permission, so its records reach air through the station's own track fetcher and that fetcher needs its own authorization. Not the same as the `stream` capability, which a plugin that mints its own stream URLs declares too. Absent means it does not */\n usesTrackFetcher?: boolean;\n status: PluginStatus;\n origin: PluginOrigin;\n enabled: boolean;\n description?: string;\n icon?: string;\n configFields: ConfigFieldDescriptor[];\n /** Whether a value is currently stored, per `secret` field under its own key and per `secret` cell under `field/rowId/column`. Never the value itself */\n secretsConfigured: Record<string, boolean>;\n /** When this plugin was first ever enabled. Absent means it never has been, so the console asks before it is */\n firstEnabledAt?: DateTime;\n /** The last recorded failure. Absent means it is not currently unhappy */\n lastError?: string;\n /** When the breaker will probe this plugin again on its own. Absent means no probe is pending */\n nextProbeAt?: DateTime;\n}\n\nexport interface PluginSummaryInput {\n id: string;\n name: string;\n version: string;\n capabilities: string[];\n /** Whether the manifest declares the `trackFetcher` permission, so its records reach air through the station's own track fetcher and that fetcher needs its own authorization. Not the same as the `stream` capability, which a plugin that mints its own stream URLs declares too. Absent means it does not */\n usesTrackFetcher?: boolean;\n status: PluginStatus;\n origin: PluginOrigin;\n enabled: boolean;\n description?: string;\n icon?: string;\n configFields: ConfigFieldDescriptor[];\n /** Whether a value is currently stored, per `secret` field under its own key and per `secret` cell under `field/rowId/column`. Never the value itself */\n secretsConfigured: Record<string, boolean>;\n /** The last recorded failure. Absent means it is not currently unhappy */\n lastError?: string;\n}\n\n/** Rehydrates every wire-encoded scalar in a PluginSummary into its runtime type. Mutates and returns `raw`. */\nexport function revivePluginSummary(raw: PluginSummary): PluginSummary {\n const __o0 = raw as unknown as Record<string, unknown>;\n if (__o0['firstEnabledAt'] != null) {\n __o0['firstEnabledAt'] = __dt(__o0['firstEnabledAt'], 'PluginSummary.firstEnabledAt');\n }\n if (__o0['nextProbeAt'] != null) {\n __o0['nextProbeAt'] = __dt(__o0['nextProbeAt'], 'PluginSummary.nextProbeAt');\n }\n return raw;\n}\n\n/**\n * What an import did\n * generated from [PluginImportResult](../../../../../apps/api/data/contracts/plugins/plugins.types.ck)\n */\nexport interface PluginImportResult {\n /** The id the imported plugin claimed */\n pluginId: string;\n /** The same version was already loaded, so the station runs the build it had until it restarts. False for a new plugin and for a new version */\n restartRequired: boolean;\n /** Every plugin, as the catalogue now stands. An import can take an older version away as well as add one */\n plugins: PluginSummary[];\n}\n\nexport interface PluginImportResultInput {\n /** The id the imported plugin claimed */\n pluginId: string;\n /** The same version was already loaded, so the station runs the build it had until it restarts. False for a new plugin and for a new version */\n restartRequired: boolean;\n /** Every plugin, as the catalogue now stands. An import can take an older version away as well as add one */\n plugins: PluginSummaryInput[];\n}\n\n/** Rehydrates every wire-encoded scalar in a PluginImportResult into its runtime type. Mutates and returns `raw`. */\nexport function revivePluginImportResult(raw: PluginImportResult): PluginImportResult {\n const __o0 = raw as unknown as Record<string, unknown>;\n {\n const __a1 = __o0['plugins'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n revivePluginSummary(__a1[__i2] as never);\n }\n }\n return raw;\n}\n\n/**\n * A summary plus the stored NON-SECRET configuration\n * generated from [PluginDetail](../../../../../apps/api/data/contracts/plugins/plugins.types.ck)\n */\nexport interface PluginDetail extends PluginSummary {\n /** Absolute path of the plugin's directory on the station */\n dir: string;\n config: Record<string, unknown>;\n oauthConnected?: boolean;\n logLevel: PluginLogLevel;\n}\n\nexport interface PluginDetailInput extends PluginSummaryInput {\n /** Absolute path of the plugin's directory on the station */\n dir: string;\n config: Record<string, unknown>;\n oauthConnected?: boolean;\n logLevel: PluginLogLevel;\n}\n\n/** Rehydrates every wire-encoded scalar in a PluginDetail into its runtime type. Mutates and returns `raw`. */\nexport function revivePluginDetail(raw: PluginDetail): PluginDetail {\n revivePluginSummary(raw as never);\n return raw;\n}\n","import type { SdkFetch } from '../sdk-options.js';\nimport { bigIntReplacer, parseJson, buildQueryString } from '../sdk-options.js';\nimport type {\n PluginConfigInput,\n PluginDetail,\n PluginFieldSuggestions,\n PluginGrantInput,\n PluginGrantList,\n PluginImportResult,\n PluginLogLevelInput,\n PluginLogPage,\n PluginLogQuery,\n PluginOAuthCallbackQuery,\n PluginOAuthResult,\n PluginOAuthStart,\n PluginSummary,\n PluginTestResult,\n ProviderCatalogue,\n} from './types/plugins.types.js';\nimport { revivePluginDetail, revivePluginImportResult, revivePluginSummary } from './types/plugins.types.js';\n\nexport class PluginsClient {\n constructor(private fetch: SdkFetch) {}\n\n /**\n * @name List plugins\n * @description Lists every plugin the host knows about\n */\n async listPlugins(): Promise<PluginSummary[]> {\n const result = await this.fetch(`/plugins`, { method: 'GET' });\n return (await parseJson<PluginSummary[]>(result)).map(revivePluginSummary);\n }\n\n /**\n * @name List plugin grants\n * @description Every capability an installed plugin is asking the operator for, with the answer so far\n */\n async listPluginGrants(): Promise<PluginGrantList> {\n const result = await this.fetch(`/plugins/grants`, { method: 'GET' });\n return await parseJson<PluginGrantList>(result);\n }\n\n /**\n * @name List capability providers\n * @description Every capability more than one plugin could answer, who can answer it, and in what order the station asks them\n */\n async listCapabilityProviders(): Promise<ProviderCatalogue> {\n const result = await this.fetch(`/plugins/providers`, { method: 'GET' });\n return await parseJson<ProviderCatalogue>(result);\n }\n\n /**\n * @name Rescan plugins\n * @description Rescans the mounted plugin directory: registers new plugins, unloads removed ones\n */\n async rescanPlugins(): Promise<PluginSummary[]> {\n const result = await this.fetch(`/plugins/rescan`, { method: 'POST' });\n return (await parseJson<PluginSummary[]>(result)).map(revivePluginSummary);\n }\n\n /**\n * @name Import plugin\n * @description Takes a plugin in from the browser as the tarball npm pack writes and puts it in the plugins directory. Importing runs the plugin's code: the station loads it to read its manifest, inside the server and with the server's privileges. It lands disabled, which only means the station does not use it until it is enabled. A newer version of an installed plugin replaces the older one\n */\n async importPlugin(body: FormData): Promise<PluginImportResult> {\n const result = await this.fetch(`/plugins/import`, {\n method: 'POST',\n body: body,\n });\n return revivePluginImportResult(await parseJson<PluginImportResult>(result));\n }\n\n /**\n * @name Get plugin\n * @description One plugin, including its stored non-secret configuration and last error\n */\n async getPlugin(id: string): Promise<PluginDetail> {\n const result = await this.fetch(`/plugins/${encodeURIComponent(id)}`, { method: 'GET' });\n return revivePluginDetail(await parseJson<PluginDetail>(result));\n }\n\n /**\n * @name Remove plugin\n * @description Removes a plugin the operator installed: stops it and deletes its folder. Its settings are kept, so importing it again brings them back. A bundled plugin is refused, unless an installed copy of it is left over from before the station shipped it: that copy never loads, and it is what gets removed\n */\n async removePlugin(id: string): Promise<PluginSummary[]> {\n const result = await this.fetch(`/plugins/${encodeURIComponent(id)}`, { method: 'DELETE' });\n return (await parseJson<PluginSummary[]>(result)).map(revivePluginSummary);\n }\n\n /**\n * @name Update plugin configuration\n * @description Validates against the plugin's own config schema, encrypts secrets, persists, and reinitializes\n */\n async updatePluginConfiguration(id: string, body: PluginConfigInput): Promise<PluginDetail> {\n const result = await this.fetch(`/plugins/${encodeURIComponent(id)}/config`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return revivePluginDetail(await parseJson<PluginDetail>(result));\n }\n\n /**\n * @name Enable plugin\n * @description Enables a plugin without resubmitting its configuration\n */\n async enablePlugin(id: string): Promise<PluginDetail> {\n const result = await this.fetch(`/plugins/${encodeURIComponent(id)}/enable`, { method: 'POST' });\n return revivePluginDetail(await parseJson<PluginDetail>(result));\n }\n\n /**\n * @name Disable plugin\n * @description Disables a plugin and tears its instance down, keeping its configuration\n */\n async disablePlugin(id: string): Promise<PluginDetail> {\n const result = await this.fetch(`/plugins/${encodeURIComponent(id)}/disable`, { method: 'POST' });\n return revivePluginDetail(await parseJson<PluginDetail>(result));\n }\n\n /**\n * @name Decide plugin grant\n * @description Answers one capability this plugin asked for. Takes effect on the next fetch, with no reload\n */\n async decidePluginGrant(id: string, body: PluginGrantInput): Promise<PluginGrantList> {\n const result = await this.fetch(`/plugins/${encodeURIComponent(id)}/grants`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<PluginGrantList>(result);\n }\n\n /**\n * @name Reload plugin\n * @description Reapplies the plugin's stored configuration: disposes the running instance and initializes it again\n */\n async reloadPlugin(id: string): Promise<PluginDetail> {\n const result = await this.fetch(`/plugins/${encodeURIComponent(id)}/reload`, { method: 'POST' });\n return revivePluginDetail(await parseJson<PluginDetail>(result));\n }\n\n /**\n * @name Test plugin connection\n * @description Runs the plugin's own `testConnection()` through the invoker\n */\n async testPluginConnection(id: string): Promise<PluginTestResult> {\n const result = await this.fetch(`/plugins/${encodeURIComponent(id)}/test`, { method: 'POST' });\n return await parseJson<PluginTestResult>(result);\n }\n\n /**\n * @name Suggest plugin config options\n * @description Asks the plugin what to offer for its config fields right now, through the invoker\n */\n async suggestPluginConfigOptions(id: string): Promise<PluginFieldSuggestions> {\n const result = await this.fetch(`/plugins/${encodeURIComponent(id)}/config/suggestions`, { method: 'POST' });\n return await parseJson<PluginFieldSuggestions>(result);\n }\n\n /**\n * @name Get plugin logs\n * @description Returns the plugin's buffered log lines at or above the current log level\n */\n async getPluginLogs(id: string, query?: PluginLogQuery): Promise<PluginLogPage> {\n const qs = buildQueryString(query);\n const result = await this.fetch(`/plugins/${encodeURIComponent(id)}/logs${qs}`, {\n method: 'GET',\n });\n return await parseJson<PluginLogPage>(result);\n }\n\n /**\n * @name Download plugin logs\n * @description Streams the plugin's full retained log as a plain-text attachment\n */\n async downloadPluginLogs(id: string): Promise<{ data: string; headers: { contentDisposition?: string } }> {\n const result = await this.fetch(`/plugins/${encodeURIComponent(id)}/logs/download`, { method: 'GET' });\n const data = await result.text();\n return { data, headers: { contentDisposition: result.headers.get('Content-Disposition') ?? undefined } };\n }\n\n /**\n * @name Set plugin log level\n * @description Sets the minimum severity the plugin's log store retains going forward\n */\n async setPluginLogLevel(id: string, body: PluginLogLevelInput): Promise<PluginDetail> {\n const result = await this.fetch(`/plugins/${encodeURIComponent(id)}/logs/level`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return revivePluginDetail(await parseJson<PluginDetail>(result));\n }\n\n /**\n * @name Start plugin OAuth authorization\n * @description Reports where to send the operator for the provider's consent screen\n */\n async startPluginOAuthAuthorization(id: string): Promise<PluginOAuthStart> {\n const result = await this.fetch(`/plugins/${encodeURIComponent(id)}/oauth/authorize`, { method: 'GET' });\n return await parseJson<PluginOAuthStart>(result);\n }\n\n /**\n * @name Disconnect plugin OAuth\n * @description Forgets the plugin's stored OAuth tokens and reinitializes it\n */\n async disconnectPluginOAuth(id: string): Promise<PluginDetail> {\n const result = await this.fetch(`/plugins/${encodeURIComponent(id)}/oauth`, { method: 'DELETE' });\n return revivePluginDetail(await parseJson<PluginDetail>(result));\n }\n\n /**\n * @name Complete plugin OAuth authorization\n * @description Completes the flow. Anonymous: the provider redirects the browser here with no session of ours\n */\n async completePluginOAuthAuthorization(id: string, query?: PluginOAuthCallbackQuery): Promise<PluginOAuthResult> {\n const qs = buildQueryString(query);\n const result = await this.fetch(`/plugins/${encodeURIComponent(id)}/oauth/callback${qs}`, {\n method: 'GET',\n });\n return await parseJson<PluginOAuthResult>(result);\n }\n}\n","import { DateTime } from 'luxon';\nconst __dt = (v: unknown, path: string): DateTime => {\n if (typeof v !== 'string') {\n throw new TypeError(`ContractKit: expected an ISO 8601 string at '${path}', received ${typeof v}.`);\n }\n const d = DateTime.fromISO(v);\n if (!d.isValid) throw new TypeError(`ContractKit: '${v}' at '${path}' is not a valid ISO 8601 datetime.`);\n return d;\n};\n\n/**\n * One person in a production: the presenter, or somebody cast to phone in. A snapshot rather than a\n * reference, because the persona it names may be edited or deleted while the programme is still being\n * made and what the turns were written as has to be what an operator reads back\n * generated from [ProductionCastMember](../../../../../apps/api/data/contracts/productions/productions.types.ck)\n */\nexport interface ProductionCastMember {\n role: 'host' | 'caller' | 'guest' | 'cohost';\n /** What they are called on air */\n name?: string;\n /** The persona key, for a link back to the character */\n persona?: string;\n}\n\n/**\n * Something a production was handed to read. The research pass takes the notes it states as fact out of these, keeping only claims whose words really are in the text\n * generated from [ProductionSource](../../../../../apps/api/data/contracts/productions/productions.types.ck)\n */\nexport interface ProductionSource {\n /** What the source is called, for the console and for the research pass's sense of what it is reading */\n title: string;\n /** Where it came from, when it came from somewhere */\n url?: string;\n /** What it says. Absent for a source given only by its address, which the research pass reads through whichever installed plugin can open a page */\n text?: string;\n}\n\n/**\n * Something the station makes rather than something it says: several beats of speech, written in several passes, that airs as one block\n * generated from [Production](../../../../../apps/api/data/contracts/productions/productions.types.ck)\n */\nexport interface Production {\n id: string;\n /** What sort of production: podcast, bulletin, feature. Free text, so a station that wants a documentary strand needs no migration */\n kind: string;\n title: string;\n /** What was asked for, in the operator's own words. Distinct from the title, which is only a label */\n brief?: string;\n /** What it may state as fact, one short note each. The outline divides them between the beats, and nothing else it says is offered as fact */\n notes?: string[];\n /** What it was handed to read. Its notes are taken from these by the research pass when nobody gave it any */\n sources?: ProductionSource[];\n /** Whether it was asked to find its own sources on the operator's trusted sites */\n research?: boolean;\n /** Who presents it. Absent falls back to the station's active persona when a pass runs */\n personaId?: string;\n /** How many passes to spend on it */\n writingMode: 'quick' | 'outlined' | 'polished';\n /** How long it should run. What the beat count and the per-beat word budgets are computed from */\n targetMs: number;\n /** `researching` is its sources being read for notes. `stitching` is the beats being joined into one piece of audio, and it leads to `ready` whether that worked or not */\n state: 'planned' | 'researching' | 'outlining' | 'drafting' | 'checking' | 'rendering' | 'stitching' | 'ready' | 'aired' | 'failed' | 'cancelled';\n /** Why making it did not work */\n error?: string;\n /** When it should air. Absent means as soon as it is made */\n scheduledFor?: DateTime;\n cancelledAt?: DateTime;\n /** How many beats exist so far, which is how far along the drafting is */\n beats: number;\n /** The station's own show this is an episode of, when it is one */\n showId?: string;\n /** Who is on it, decided by the first pass that ran. Empty for one nobody has started, and for a programme the presenter reads alone */\n cast: ProductionCastMember[];\n createdAt: DateTime;\n}\n\nexport interface ProductionInput {\n /** What sort of production: podcast, bulletin, feature. Free text, so a station that wants a documentary strand needs no migration */\n kind: string;\n title: string;\n /** What was asked for, in the operator's own words. Distinct from the title, which is only a label */\n brief?: string;\n /** What it may state as fact, one short note each. The outline divides them between the beats, and nothing else it says is offered as fact */\n notes?: string[];\n /** What it was handed to read. Its notes are taken from these by the research pass when nobody gave it any */\n sources?: ProductionSource[];\n /** Who presents it. Absent falls back to the station's active persona when a pass runs */\n personaId?: string;\n /** How many passes to spend on it */\n writingMode: 'quick' | 'outlined' | 'polished';\n /** How long it should run. What the beat count and the per-beat word budgets are computed from */\n targetMs: number;\n /** When it should air. Absent means as soon as it is made */\n scheduledFor?: DateTime;\n}\n\n/** Rehydrates every wire-encoded scalar in a Production into its runtime type. Mutates and returns `raw`. */\nexport function reviveProduction(raw: Production): Production {\n const __o0 = raw as unknown as Record<string, unknown>;\n if (__o0['scheduledFor'] != null) {\n __o0['scheduledFor'] = __dt(__o0['scheduledFor'], 'Production.scheduledFor');\n }\n if (__o0['cancelledAt'] != null) {\n __o0['cancelledAt'] = __dt(__o0['cancelledAt'], 'Production.cancelledAt');\n }\n __o0['createdAt'] = __dt(__o0['createdAt'], 'Production.createdAt');\n return raw;\n}\n\n/**\n * What an operator asks for. Everything else about a production is decided by the passes that make it\n * generated from [ProductionRequest](../../../../../apps/api/data/contracts/productions/productions.types.ck)\n */\nexport interface ProductionRequest {\n kind?: string;\n /** Absent is named after its kind and the moment it was asked for, which is what somebody taking a call now wants rather than a box to fill in */\n title?: string;\n brief?: string;\n /** What it may state as fact, one short note each. Absent leaves it to general knowledge, said vaguely */\n notes?: string[];\n /** What to read before writing it. Given sources and no notes, a research pass takes the notes out of these first */\n sources?: ProductionSource[];\n /** Given nothing to read, search the operator's trusted sites for its subject and read what comes back. Needs an enrichment plugin that can, such as the web search one with trusted sites */\n research?: boolean;\n personaId?: string;\n /** Absent takes the station's `render.productionWritingMode` */\n writingMode?: 'quick' | 'outlined' | 'polished';\n targetMs?: number;\n scheduledFor?: DateTime;\n}\n\n/** Rehydrates every wire-encoded scalar in a ProductionRequest into its runtime type. Mutates and returns `raw`. */\nexport function reviveProductionRequest(raw: ProductionRequest): ProductionRequest {\n const __o0 = raw as unknown as Record<string, unknown>;\n if (__o0['scheduledFor'] != null) {\n __o0['scheduledFor'] = __dt(__o0['scheduledFor'], 'ProductionRequest.scheduledFor');\n }\n return raw;\n}\n\n/**\n * generated from [ProductionList](../../../../../apps/api/data/contracts/productions/productions.types.ck)\n */\nexport interface ProductionList {\n productions: Production[];\n}\n\nexport interface ProductionListInput {\n productions: ProductionInput[];\n}\n\n/** Rehydrates every wire-encoded scalar in a ProductionList into its runtime type. Mutates and returns `raw`. */\nexport function reviveProductionList(raw: ProductionList): ProductionList {\n const __o0 = raw as unknown as Record<string, unknown>;\n {\n const __a1 = __o0['productions'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveProduction(__a1[__i2] as never);\n }\n }\n return raw;\n}\n","import { DateTime } from 'luxon';\nconst __dt = (v: unknown, path: string): DateTime => {\n if (typeof v !== 'string') {\n throw new TypeError(`ContractKit: expected an ISO 8601 string at '${path}', received ${typeof v}.`);\n }\n const d = DateTime.fromISO(v);\n if (!d.isValid) throw new TypeError(`ContractKit: '${v}' at '${path}' is not a valid ISO 8601 datetime.`);\n return d;\n};\n\n/**\n * A programme the station carries, as one installed plugin describes it\n * generated from [StationShow](../../../../../apps/api/data/contracts/podcasts/podcasts.types.ck)\n */\nexport interface StationShow {\n /** Unique across the station: the plugin's own id for the show, qualified with the plugin that offered it */\n id: string;\n pluginId: string;\n /** What the show is called, which is what a presenter says out loud */\n title: string;\n author?: string;\n /** What the show says about itself, as plain text */\n description?: string;\n artworkUrl?: string;\n homeUrl?: string;\n /** Where its feed is, when the plugin reads one */\n feedUrl?: string;\n language?: string;\n categories?: string[];\n /** Whether the publisher marked the whole show explicit. Absent means the publisher did not say, which is not the same as clean */\n explicit?: boolean;\n}\n\n/**\n * One episode of a programme the station carries, and what the station has done with it\n * generated from [StationEpisode](../../../../../apps/api/data/contracts/podcasts/podcasts.types.ck)\n */\nexport interface StationEpisode {\n /** The station's own id for this episode */\n id: string;\n /** Qualified, matching `StationShow.id` */\n showId: string;\n /** The plugin's own id for the episode, stable across refreshes */\n episodeId: string;\n showTitle: string;\n title: string;\n /** What the publisher says it is about, as plain text */\n summary?: string;\n /** The episode's page, for a person */\n url?: string;\n /** ISO-8601 */\n publishedAt?: string;\n /** How long the publisher says it runs, in milliseconds */\n durationMs?: number;\n artworkUrl?: string;\n explicit?: boolean;\n /** ISO-8601: when a refresh last saw it in its feed */\n seenAt: string;\n /** Whether the station holds its own copy of the audio, ready to air */\n fetched: boolean;\n /** ISO-8601: when the station last asked for the audio */\n fetchRequestedAt?: string;\n /** Why the last attempt to fetch the audio failed, when it did */\n fetchError?: string;\n /** ISO-8601: the slot the audio was fetched for */\n scheduledFor?: string;\n /** ISO-8601: when a listener could first have heard it. An episode airs once */\n airedAt?: string;\n}\n\n/**\n * A show a podcast plugin's directory knows about, which the station may or may not carry\n * generated from [StationDirectoryEntry](../../../../../apps/api/data/contracts/podcasts/podcasts.types.ck)\n */\nexport interface StationDirectoryEntry {\n /** The directory's own id for the show. A key in a list, and nothing more */\n id: string;\n /** The plugin whose directory answered, which is the plugin a subscription would go to */\n pluginId: string;\n title: string;\n /** Where the show's feed is, which is what subscribing needs */\n feedUrl: string;\n author?: string;\n description?: string;\n artworkUrl?: string;\n homeUrl?: string;\n categories?: string[];\n explicit?: boolean;\n}\n\n/**\n * generated from [StationDirectoryQuery](../../../../../apps/api/data/contracts/podcasts/podcasts.types.ck)\n */\nexport interface StationDirectoryQuery {\n /** Words to look a show up by: its name, its publisher, its subject */\n query: string;\n limit?: number;\n}\n\n/**\n * generated from [StationEpisodeQuery](../../../../../apps/api/data/contracts/podcasts/podcasts.types.ck)\n */\nexport interface StationEpisodeQuery {\n /** One show's episodes, or absent for every show's, newest first */\n showId?: string;\n limit?: number;\n}\n\n/**\n * A show the station makes for itself: a saved recipe for a podcast, whose every episode is a production\n * generated from [OwnShow](../../../../../apps/api/data/contracts/podcasts/podcasts.types.ck)\n */\nexport interface OwnShow {\n id: string;\n /** What the show is called. Each episode's title starts with it */\n title: string;\n /** What the show is, for the console. Never read out */\n description?: string;\n /** What an episode is about when it is asked for with no subject of its own */\n subject?: string;\n /** Who presents it. Absent is whoever is presenting when it is made */\n personaId?: string;\n /** How long an episode runs. Absent is the station's production length */\n targetMs?: number;\n /** How much of the model an episode is worth. Absent is the station's default */\n writingMode?: 'quick' | 'outlined' | 'polished';\n /** The station's news feeds an episode reads, by their qualified ids. Absent or empty is a show that does not read the news */\n newsFeedIds?: string[];\n /** How many hours of news an episode reads. Absent is a day */\n newsHours?: number;\n /** Whether an episode given nothing to read finds its own sources on the operator's trusted sites */\n research?: boolean;\n createdAt: DateTime;\n}\n\nexport interface OwnShowInput {\n /** What the show is called. Each episode's title starts with it */\n title: string;\n /** What the show is, for the console. Never read out */\n description?: string;\n /** What an episode is about when it is asked for with no subject of its own */\n subject?: string;\n /** Who presents it. Absent is whoever is presenting when it is made */\n personaId?: string;\n /** How long an episode runs. Absent is the station's production length */\n targetMs?: number;\n /** How much of the model an episode is worth. Absent is the station's default */\n writingMode?: 'quick' | 'outlined' | 'polished';\n /** The station's news feeds an episode reads, by their qualified ids. Absent or empty is a show that does not read the news */\n newsFeedIds?: string[];\n /** How many hours of news an episode reads. Absent is a day */\n newsHours?: number;\n /** Whether an episode given nothing to read finds its own sources on the operator's trusted sites */\n research?: boolean;\n}\n\n/** Rehydrates every wire-encoded scalar in a OwnShow into its runtime type. Mutates and returns `raw`. */\nexport function reviveOwnShow(raw: OwnShow): OwnShow {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['createdAt'] = __dt(__o0['createdAt'], 'OwnShow.createdAt');\n return raw;\n}\n\n/**\n * Asks one of the station's own shows for an episode. Everything is optional: a show with a standing subject needs nothing\n * generated from [OwnEpisodeRequest](../../../../../apps/api/data/contracts/podcasts/podcasts.types.ck)\n */\nexport interface OwnEpisodeRequest {\n /** What this episode is about. Absent is the show's own subject */\n topic?: string;\n /** A page for it to read first, by its address. The episode states only what it can find there */\n url?: string;\n /** What the pasted text is called */\n sourceTitle?: string;\n /** Something for it to read first. The episode states only what it can find in this. Given text, a show that reads the news reads this instead */\n text?: string;\n /** When it should air. Absent is as soon as it is made */\n airAt?: DateTime;\n}\n\n/** Rehydrates every wire-encoded scalar in a OwnEpisodeRequest into its runtime type. Mutates and returns `raw`. */\nexport function reviveOwnEpisodeRequest(raw: OwnEpisodeRequest): OwnEpisodeRequest {\n const __o0 = raw as unknown as Record<string, unknown>;\n if (__o0['airAt'] != null) {\n __o0['airAt'] = __dt(__o0['airAt'], 'OwnEpisodeRequest.airAt');\n }\n return raw;\n}\n\n/**\n * generated from [StationShowList](../../../../../apps/api/data/contracts/podcasts/podcasts.types.ck)\n */\nexport interface StationShowList {\n shows: StationShow[];\n}\n\n/**\n * generated from [StationEpisodePage](../../../../../apps/api/data/contracts/podcasts/podcasts.types.ck)\n */\nexport interface StationEpisodePage {\n /** Newest first. Empty when the station knows of none, which is not an error */\n episodes: StationEpisode[];\n}\n\n/**\n * generated from [StationDirectoryPage](../../../../../apps/api/data/contracts/podcasts/podcasts.types.ck)\n */\nexport interface StationDirectoryPage {\n /** Empty when nothing matched or no directory could be asked, which is not an error */\n results: StationDirectoryEntry[];\n}\n\n/**\n * generated from [OwnShowList](../../../../../apps/api/data/contracts/podcasts/podcasts.types.ck)\n */\nexport interface OwnShowList {\n shows: OwnShow[];\n}\n\nexport interface OwnShowListInput {\n shows: OwnShowInput[];\n}\n\n/** Rehydrates every wire-encoded scalar in a OwnShowList into its runtime type. Mutates and returns `raw`. */\nexport function reviveOwnShowList(raw: OwnShowList): OwnShowList {\n const __o0 = raw as unknown as Record<string, unknown>;\n {\n const __a1 = __o0['shows'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveOwnShow(__a1[__i2] as never);\n }\n }\n return raw;\n}\n","import type { SdkFetch } from '../sdk-options.js';\nimport { bigIntReplacer, parseJson, buildQueryString } from '../sdk-options.js';\nimport type { Production, ProductionList } from '../productions/types/productions.types.js';\nimport { reviveProduction, reviveProductionList } from '../productions/types/productions.types.js';\nimport type {\n OwnEpisodeRequest,\n OwnShow,\n OwnShowInput,\n OwnShowList,\n StationDirectoryPage,\n StationDirectoryQuery,\n StationEpisode,\n StationEpisodePage,\n StationEpisodeQuery,\n StationShowList,\n} from './types/podcasts.types.js';\nimport { reviveOwnShow, reviveOwnShowList } from './types/podcasts.types.js';\n\nexport class PodcastsClient {\n constructor(private fetch: SdkFetch) {}\n\n /**\n * @name List shows\n * @description Every programme every installed podcast plugin carries\n */\n async listShows(): Promise<StationShowList> {\n const result = await this.fetch(`/podcasts/shows`, { method: 'GET' });\n return await parseJson<StationShowList>(result);\n }\n\n /**\n * @name Search podcast directory\n * @description Looks a show up in the directories the installed podcast plugins can search\n */\n async searchPodcastDirectory(query?: StationDirectoryQuery): Promise<StationDirectoryPage> {\n const qs = buildQueryString(query);\n const result = await this.fetch(`/podcasts/search${qs}`, {\n method: 'GET',\n });\n return await parseJson<StationDirectoryPage>(result);\n }\n\n /**\n * @name List episodes\n * @description The episodes the station knows about, newest first, with what it has done with each\n */\n async listEpisodes(query?: StationEpisodeQuery): Promise<StationEpisodePage> {\n const qs = buildQueryString(query);\n const result = await this.fetch(`/podcasts/episodes${qs}`, {\n method: 'GET',\n });\n return await parseJson<StationEpisodePage>(result);\n }\n\n /**\n * @name Fetch episode\n * @description Fetches one episode's audio into the station's store now, rather than waiting for its slot to come near\n */\n async fetchEpisode(id: string): Promise<StationEpisode> {\n const result = await this.fetch(`/podcasts/episodes/${encodeURIComponent(id)}/fetch`, { method: 'POST' });\n return await parseJson<StationEpisode>(result);\n }\n\n /**\n * @name Refresh podcasts\n * @description Reads every show's feed again, in the background, rather than waiting for the next scheduled refresh\n */\n async refreshPodcasts(): Promise<void> {\n await this.fetch(`/podcasts/refresh`, { method: 'POST' });\n }\n\n /**\n * @name List own shows\n * @description The shows the station makes for itself\n */\n async listOwnShows(): Promise<OwnShowList> {\n const result = await this.fetch(`/podcasts/own`, { method: 'GET' });\n return reviveOwnShowList(await parseJson<OwnShowList>(result));\n }\n\n /**\n * @name Create own show\n * @description Makes a new show. Nothing is made until an episode is asked for\n */\n async createOwnShow(body: OwnShowInput): Promise<OwnShow> {\n const result = await this.fetch(`/podcasts/own`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return reviveOwnShow(await parseJson<OwnShow>(result));\n }\n\n /**\n * @name Update own show\n * @description Rewrites a show. Episodes already asked for keep what they were asked with\n */\n async updateOwnShow(id: string, body: OwnShowInput): Promise<OwnShow> {\n const result = await this.fetch(`/podcasts/own/${encodeURIComponent(id)}`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return reviveOwnShow(await parseJson<OwnShow>(result));\n }\n\n /**\n * @name Delete own show\n * @description Removes a show. Its episodes stay on the Productions page, no longer filed under it\n */\n async deleteOwnShow(id: string): Promise<void> {\n await this.fetch(`/podcasts/own/${encodeURIComponent(id)}`, { method: 'DELETE' });\n }\n\n /**\n * @name List own show episodes\n * @description A show's episodes, newest first, with how far along each is\n */\n async listOwnShowEpisodes(id: string): Promise<ProductionList> {\n const result = await this.fetch(`/podcasts/own/${encodeURIComponent(id)}/episodes`, { method: 'GET' });\n return reviveProductionList(await parseJson<ProductionList>(result));\n }\n\n /**\n * @name Request own show episode\n * @description Asks the show for an episode. It is queued, not started, and airs when it is made or at the time given\n */\n async requestOwnShowEpisode(id: string, body: OwnEpisodeRequest): Promise<Production> {\n const result = await this.fetch(`/podcasts/own/${encodeURIComponent(id)}/episodes`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return reviveProduction(await parseJson<Production>(result));\n }\n}\n","import type { SdkFetch } from '../sdk-options.js';\nimport { bigIntReplacer, parseJson } from '../sdk-options.js';\nimport type { Production, ProductionList, ProductionRequest } from './types/productions.types.js';\nimport { reviveProduction, reviveProductionList } from './types/productions.types.js';\n\nexport class ProductionsClient {\n constructor(private fetch: SdkFetch) {}\n\n /**\n * @name List productions\n * @description Everything the station has made or is making, newest first\n */\n async listProductions(): Promise<ProductionList> {\n const result = await this.fetch(`/productions`, { method: 'GET' });\n return reviveProductionList(await parseJson<ProductionList>(result));\n }\n\n /**\n * @name Request production\n * @description Asks the station to make one. It is queued, not started\n */\n async requestProduction(body: ProductionRequest): Promise<Production> {\n const result = await this.fetch(`/productions`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return reviveProduction(await parseJson<Production>(result));\n }\n\n /**\n * @name Cancel production\n * @description Stops a production being made, for good\n */\n async cancelProduction(id: string): Promise<Production> {\n const result = await this.fetch(`/productions/${encodeURIComponent(id)}/cancel`, { method: 'POST' });\n return reviveProduction(await parseJson<Production>(result));\n }\n}\n","import { DateTime } from 'luxon';\nconst __dt = (v: unknown, path: string): DateTime => {\n if (typeof v !== 'string') {\n throw new TypeError(`ContractKit: expected an ISO 8601 string at '${path}', received ${typeof v}.`);\n }\n const d = DateTime.fromISO(v);\n if (!d.isValid) throw new TypeError(`ContractKit: '${v}' at '${path}' is not a valid ISO 8601 datetime.`);\n return d;\n};\n\n/**\n * One thing the station can play that is not a record\n * generated from [Segment](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface Segment {\n id: string;\n /** What sort of element it is: `ident`, `stinger`, `talkbreak`, `news` */\n kind: string;\n /** One state per stage of making it. Only `ready` can go on air; the station skips anything else rather than waiting for it */\n state: 'planned' | 'writing' | 'written' | 'rendering' | 'ready' | 'failed';\n /** What the console calls it, and what the mount is labelled with while it airs */\n label: string;\n /** Who made it: `library` for a file dropped into the inbox */\n source: string;\n /** Whether there is audio behind it yet */\n playable: boolean;\n /** The words, for anything that speaks. Absent for an imported recording */\n script?: string;\n /** The words as the speech engine was handed them: symbols said, years read as a person reads them, the station's pronunciation list applied. Absent until something has spoken it */\n spokenScript?: string;\n /** The file in the inbox this came from. The bytes were copied, so emptying the inbox does not take it off the air */\n sourcePath?: string;\n /** How long it runs. A display value: the player measures the audio itself */\n durationMs?: number;\n /** Why it is `failed` */\n error?: string;\n /** The station's own name for the voice this is said in, e.g. `host`. Absent means the speech plugin's default */\n voice?: string;\n /** How the words are read: `hushed` or `frantic`. Absent is the voice's own ordinary reading, which is nearly every segment */\n delivery?: string;\n}\n\n/**\n * Something for the station to say, before anything has said it\n * generated from [SegmentCreate](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface SegmentCreate {\n /** What the console calls it, and what the mount is labelled with while it airs */\n label: string;\n /** The words to say */\n script: string;\n /** What sort of element it is. Defaults to `talkbreak` */\n kind?: string;\n /** A station voice name the speech plugin knows how to map. Absent uses its default */\n voice?: string;\n /** How to read the words: `hushed` or `frantic`, and refused otherwise. Absent is the voice's own ordinary reading. Dropped at render time by an engine that cannot perform it */\n delivery?: string;\n}\n\n/**\n * A recording arriving from the browser, as multipart form parts.\n *\n * Documentation rather than validation: a multipart body reaches the service as the raw parser and\n * the generated client types the body as `FormData`, so nothing checks this shape. It says what to\n * send\n * generated from [SegmentUpload](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface SegmentUpload {\n /** The audio itself. mp3, wav, ogg, flac or m4a, and at most 50 MB */\n file: Blob;\n /** What sort of element it is, which is also the directory it is filed under. A kind nothing else uses becomes a bookable band on the format clock */\n kind: string;\n /** What the console calls it, and what the mount is labelled with while it airs. Derived from the filename when absent */\n label?: string;\n}\n\n/**\n * A voice the station can be asked to speak in\n * generated from [Voice](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface Voice {\n /** What to pass as a segment's `voice`. Empty means the plugin's own default */\n id: string;\n /** What the console calls it */\n label: string;\n /** What it sounds like, or what it maps to on the engine */\n description?: string;\n}\n\n/**\n * Whether there are words, and if not, which way it went wrong\n * generated from [ScriptOutcome](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport type ScriptOutcome = 'written' | 'declined' | 'failed';\n\n/**\n * A record a writer was told about, kept as it was told\n * generated from [ScriptNeighbour](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface ScriptNeighbour {\n title: string;\n artist: string;\n /** What it was shown about the record. A break that said nothing interesting and one that was TOLD nothing interesting read the same from the script alone */\n facts?: string[];\n}\n\n/**\n * What the provider said the attempt cost, when it said anything\n * generated from [ScriptUsage](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface ScriptUsage {\n inputTokens?: number;\n outputTokens?: number;\n totalTokens?: number;\n}\n\n/**\n * One turn of the conversation a writer sent\n * generated from [ScriptPromptMessage](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface ScriptPromptMessage {\n role: string;\n content: string;\n}\n\n/**\n * What an operator thought of something the station said.\n *\n * The catalog's three spellings exactly, and deliberately not a second vocabulary: an opinion is an\n * opinion whether it is about a record or about a sentence, and `catalog/rating.ts` is the one place\n * the words and the column's numbers meet.\n *\n * `neutral` is a real answer rather than an absence. Rating something back to nothing is a thing an\n * operator does, and it has to be distinguishable from never having listened, which is the field\n * being absent on the attempt.\n * generated from [ScriptRating](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport type ScriptRating = 'liked' | 'neutral' | 'disliked';\n\n/**\n * Words to hear before anything has aired them\n * generated from [SpeechPreviewRequest](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface SpeechPreviewRequest {\n /** What to say. Far under a segment's 20000 because this is one break heard once, and the cap is what bounds a cache keyed on the words themselves */\n text: string;\n /** A station voice name, as a segment's `voice`. Absent uses the plugin's own default */\n voice?: string;\n /** How to read it, as a segment's `delivery`: `hushed` or `frantic`, and refused otherwise. Absent is the voice's own ordinary reading */\n delivery?: string;\n /** The board a `[sfx:name]` in the text is played from, as a character's `soundboard`. Absent, or a hit the board does not hold, and the hit is left out and only the words are spoken */\n soundboard?: string;\n}\n\n/**\n * The window the counts cover\n * generated from [ScriptHistorySummaryQuery](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface ScriptHistorySummaryQuery {\n /** How far back to count. Defaults to 24, and a week at most, because past that the nightly sweep may already have taken the rows and the count would quietly be of what survived rather than of what happened */\n hours?: number;\n}\n\n/**\n * One presenter's attempts in the window\n * generated from [ScriptHistorySummaryRow](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface ScriptHistorySummaryRow {\n /** Absent means nobody was presenting, which is an ordinary state rather than a gap in the data */\n personaKey?: string;\n written: number;\n /** A decline is the writer registry working: the model had nothing to say and the floor covered for it */\n declined: number;\n failed: number;\n}\n\n/**\n * What one pass over the inbox did\n * generated from [SegmentScanResult](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface SegmentScanResult {\n /** Audio files seen, whether or not they were already known */\n scanned: number;\n /** Segments the station did not have before this pass */\n imported: number;\n /** Files passed over: not audio it can serve, or unreadable */\n skipped: number;\n}\n\n/**\n * One name the station says differently from how it is written\n * generated from [Pronunciation](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface Pronunciation {\n id: string;\n /** What appears in a script. Matched case-insensitively, and whole words only */\n written: string;\n /** What the engine is handed instead, untouched. EMPTY is meaningful: it drops the words, which is the honest reading for a marker that got into a title and is not a word */\n spoken: string;\n /** `active` is said. `suggested` is proposed and says nothing yet. `rejected` outlives the pass that proposed it, or the same article proposes it again forever */\n state: 'active' | 'suggested' | 'rejected';\n /** Who says so. `gloss` is a pronunciation key an encyclopaedia article printed for itself */\n origin: 'operator' | 'gloss';\n /** The article. Present on anything an operator did not type */\n sourceUrl?: string;\n /** The sentence that says so, as it stands in the article, which is what the decision is actually made on */\n sourceQuote?: string;\n /** What the article was about */\n subjectKind?: 'track' | 'album' | 'artist';\n subjectId?: string;\n createdAt: string;\n}\n\n/**\n * A name and how to say it\n * generated from [PronunciationWrite](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface PronunciationWrite {\n written: string;\n /** Empty drops the words rather than saying them */\n spoken: string;\n}\n\n/**\n * Accepting a proposal, turning one down, or taking an entry out of use without losing it\n * generated from [PronunciationStateWrite](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface PronunciationStateWrite {\n state: 'active' | 'suggested' | 'rejected';\n}\n\n/**\n * Which part of the lexicon to read\n * generated from [PronunciationQuery](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface PronunciationQuery {\n /** Absent is all of it */\n state?: 'active' | 'suggested' | 'rejected';\n}\n\n/**\n * Where in a break a sound may fall. `start` is before the first word, `end` after the last, and\n * `middle` anywhere between two words\n * generated from [PadPlacement](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport type PadPlacement = 'start' | 'middle' | 'end';\n\n/**\n * A sound arriving from the browser, as multipart form parts.\n *\n * Documentation rather than validation: a multipart body reaches the service as the raw parser and\n * the generated client types the body as `FormData`, so nothing checks this shape. It says what to\n * send\n * generated from [PadUpload](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface PadUpload {\n /** The audio itself. mp3, wav, ogg, flac or m4a, and at most 25 MB */\n file: Blob;\n /** The directory it is filed under, which is also the set it joins. A new name makes both */\n board: string;\n /** What a script will write. Derived from the filename when absent, and the FILE is named after this either way */\n name?: string;\n /** What the console calls it. Derived from the filename when absent */\n label?: string;\n}\n\n/**\n * A sound the station is being told to go and get.\n *\n * The operator names the address, so this is them choosing a file exactly as dropping one in the\n * library is. Nothing inspects what comes back and nothing records a claim about its licence -- see\n * `docs/internals/render.md` under \"Pads\", whose line is redistribution rather than use\n * generated from [PadFetch](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface PadFetch {\n /** Where the audio is. Followed once, bounded, and refused unless what comes back is a format the station serves */\n url: string;\n /** The directory it is filed under, which is also the set it joins */\n board: string;\n /** What a script will write. Derived from the address when absent */\n name?: string;\n label?: string;\n}\n\n/**\n * A named collection of pads: what a presenter is actually handed.\n *\n * One library, cut as many ways as an operator likes. `personas.soundboard` holds the `key`, so\n * renaming a set unpoints every persona naming it — which is why `personas` says who those are\n * generated from [PadSet](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface PadSet {\n id: string;\n /** The slug a persona names. A directory in the pad library makes one of these */\n key: string;\n label: string;\n position: number;\n /** How many sounds are on it. Zero is ordinary: it is what a set looks like before anybody drops a file */\n pads: number;\n /** Who is pointed at it, so a rename or a delete can say what it is about to unpoint */\n personas: string[];\n}\n\nexport interface PadSetInput {\n /** The slug a persona names. A directory in the pad library makes one of these */\n key: string;\n label: string;\n position: number;\n}\n\n/**\n * A set an operator is naming, or renaming\n * generated from [PadSetWrite](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface PadSetWrite {\n key: string;\n label: string;\n position?: number;\n}\n\n/**\n * Which pad, and whether it is on the set\n * generated from [PadSetMembership](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface PadSetMembership {\n padId: string;\n on: boolean;\n}\n\n/**\n * Turning a pad down, or putting one back\n * generated from [PadState](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface PadState {\n state: 'active' | 'rejected';\n}\n\n/**\n * What one pass over the pad library did\n * generated from [PadScanResult](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface PadScanResult {\n /** Audio files seen, whether or not anything changed */\n scanned: number;\n /** Sounds the station did not have before */\n imported: number;\n /** Slots whose file changed under them, which every script naming them now plays */\n replaced: number;\n /** Sounds that reached the library but not their set, because it already answered to their name. In the library and unreachable until somebody says where they go */\n contested: number;\n /** Files passed over: not audio, unreadable, or named something no script could write */\n skipped: number;\n}\n\n/**\n * Which copy of a segment's audio. `original` is what the station airs. `share` is a small copy made for a listener to send on, AAC in an .m4a, never aired\n * generated from [SegmentAudioRendition](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport type SegmentAudioRendition = 'original' | 'share';\n\n/**\n * Everything the station can play that is not a record\n * generated from [SegmentList](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface SegmentList {\n segments: Segment[];\n}\n\n/**\n * The voices the station's current speech plugin offers\n * generated from [VoiceList](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface VoiceList {\n voices: Voice[];\n /** Which plugin answered. Absent when nothing can speak */\n pluginId?: string;\n /** Why there are no voices, when there are none */\n reason?: string;\n /** Which readings that plugin can perform right now, out of `hushed` and `frantic`. Absent or empty means none, which is most engines and is not a fault */\n deliveries?: string[];\n}\n\n/**\n * One page of what the station has written, newest first\n * generated from [ScriptHistoryQuery](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface ScriptHistoryQuery {\n limit?: number;\n /** Where the previous page ended. Opaque, and a keyset rather than an offset because rows arrive at the head continuously. Pass back whatever `nextBefore` said and nothing else */\n before?: string;\n kind?: string;\n writer?: string;\n outcome?: ScriptOutcome;\n /** Everything ONE character has said. Absent is every character and none */\n personaKey?: string;\n /** Every attempt made for ONE break, which is how a console reaches the words behind an item of the running order. Absent is the whole history */\n segmentId?: string;\n}\n\n/**\n * One attempt to write something the station would say, including the ones that came to nothing\n * generated from [ScriptAttempt](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface ScriptAttempt {\n id: string;\n at: DateTime;\n /** What sort of break it was for: `talkbreak`, `welcome`, `news` */\n kind: string;\n /** The binding that produced or declined it */\n writer: string;\n outcome: ScriptOutcome;\n /** Who was presenting, as the persona's own key. Absent means nobody was, which is an ordinary state. Stamped on every attempt including the declined ones, so a character whose model breaks are all being refused is visible rather than hidden behind the floor */\n personaKey?: string;\n label?: string;\n /** The words. Absent for an attempt that produced none */\n script?: string;\n /** How the writer chose to have the words read, `hushed` or `frantic`. Absent for an ordinary reading */\n delivery?: string;\n /** The model that said it, for a writer that used one */\n model?: string;\n /** What the line was rendered from, for a writer working from something an operator can edit */\n source?: string;\n /** Why, for anything that is not `written` */\n reason?: string;\n /** The segment this was for, while it is still known. The row outlives it */\n segmentId?: string;\n previous?: ScriptNeighbour;\n next?: ScriptNeighbour;\n /** How long the attempt took */\n durationMs?: number;\n usage?: ScriptUsage;\n /** The answer before anything read it. Only while `llm.captureWrites` is on */\n raw?: string;\n /** What the writer sent. Only while `llm.captureWrites` is on */\n prompt?: ScriptPromptMessage[];\n /** What the operator thought of it. ABSENT means nobody has said, which `neutral` does not */\n rating?: ScriptRating;\n}\n\nexport interface ScriptAttemptInput {\n id: string;\n at: DateTime;\n /** What sort of break it was for: `talkbreak`, `welcome`, `news` */\n kind: string;\n /** The binding that produced or declined it */\n writer: string;\n outcome: ScriptOutcome;\n /** Who was presenting, as the persona's own key. Absent means nobody was, which is an ordinary state. Stamped on every attempt including the declined ones, so a character whose model breaks are all being refused is visible rather than hidden behind the floor */\n personaKey?: string;\n label?: string;\n /** The words. Absent for an attempt that produced none */\n script?: string;\n /** How the writer chose to have the words read, `hushed` or `frantic`. Absent for an ordinary reading */\n delivery?: string;\n /** The model that said it, for a writer that used one */\n model?: string;\n /** What the line was rendered from, for a writer working from something an operator can edit */\n source?: string;\n /** Why, for anything that is not `written` */\n reason?: string;\n /** The segment this was for, while it is still known. The row outlives it */\n segmentId?: string;\n previous?: ScriptNeighbour;\n next?: ScriptNeighbour;\n /** How long the attempt took */\n durationMs?: number;\n usage?: ScriptUsage;\n /** The answer before anything read it. Only while `llm.captureWrites` is on */\n raw?: string;\n /** What the writer sent. Only while `llm.captureWrites` is on */\n prompt?: ScriptPromptMessage[];\n}\n\n/** Rehydrates every wire-encoded scalar in a ScriptAttempt into its runtime type. Mutates and returns `raw`. */\nexport function reviveScriptAttempt(raw: ScriptAttempt): ScriptAttempt {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['at'] = __dt(__o0['at'], 'ScriptAttempt.at');\n return raw;\n}\n\n/**\n * generated from [ScriptRatingInput](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface ScriptRatingInput {\n rating: ScriptRating;\n}\n\n/**\n * What each presenter has written lately, and over how long\n * generated from [ScriptHistorySummary](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface ScriptHistorySummary {\n /** The window actually counted, echoed so a console can label the numbers it draws */\n hours: number;\n rows: ScriptHistorySummaryRow[];\n}\n\n/**\n * The station's lexicon, oldest first\n * generated from [PronunciationList](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface PronunciationList {\n pronunciations: Pronunciation[];\n}\n\n/**\n * One sound on a soundboard, as the console draws it.\n *\n * `name` is what a script writes to hit it and `label` is what a person reads: two columns rather\n * than one, because a token for a model and prose for an operator are different things and the\n * filename produces both\n * generated from [Pad](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface Pad {\n id: string;\n /** Which directory it arrived in. Provenance: what reaches it is a set */\n board: string;\n /** The keys of the sets it is on. Empty means it is in the library and nothing can hit it */\n sets: string[];\n /** What a script writes: `[sfx:airhorn]` */\n name: string;\n label: string;\n durationMs?: number;\n /** How loud it came out, once something measured it. Absent on a station with no analyzer, which is ordinary */\n loudnessLufs?: number;\n /** Who put the file there: `library` for one the operator dropped in, `upload` or `url` for one the console wrote. It decides whether the console may delete it */\n source: string;\n /** The file in the library directory it was imported from, so the console can say where it came from */\n sourcePath?: string;\n /** When it was last hit. Absent for one nothing has reached for yet */\n lastUsedAt?: DateTime;\n state: 'active' | 'rejected';\n /** Where in a break it may land: before the first word, between two, or after the last. Every pad starts with all three */\n placements: PadPlacement[];\n /** When to reach for it, in the operator's words (\"right after a punchline\"). Shown to the presenter beside the sound; the station's own writers leave a cued pad alone */\n cue?: string;\n}\n\nexport interface PadInput {\n /** Which directory it arrived in. Provenance: what reaches it is a set */\n board: string;\n /** What a script writes: `[sfx:airhorn]` */\n name: string;\n label: string;\n durationMs?: number;\n /** How loud it came out, once something measured it. Absent on a station with no analyzer, which is ordinary */\n loudnessLufs?: number;\n /** The file in the library directory it was imported from, so the console can say where it came from */\n sourcePath?: string;\n /** When it was last hit. Absent for one nothing has reached for yet */\n lastUsedAt?: DateTime;\n state: 'active' | 'rejected';\n /** Where in a break it may land: before the first word, between two, or after the last. Every pad starts with all three */\n placements: PadPlacement[];\n /** When to reach for it, in the operator's words (\"right after a punchline\"). Shown to the presenter beside the sound; the station's own writers leave a cued pad alone */\n cue?: string;\n}\n\n/** Rehydrates every wire-encoded scalar in a Pad into its runtime type. Mutates and returns `raw`. */\nexport function revivePad(raw: Pad): Pad {\n const __o0 = raw as unknown as Record<string, unknown>;\n if (__o0['lastUsedAt'] != null) {\n __o0['lastUsedAt'] = __dt(__o0['lastUsedAt'], 'Pad.lastUsedAt');\n }\n return raw;\n}\n\n/**\n * Where and when a pad may be hit, written together because the console edits them together\n * generated from [PadUse](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface PadUse {\n /** At least one: a sound that may go nowhere is a sound turned down, which is what `PadState` is for */\n placements: PadPlacement[];\n /** Absent clears it, so the pad is fair game wherever its placements allow */\n cue?: string;\n}\n\n/**\n * generated from [SegmentAudioQuery](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface SegmentAudioQuery {\n /** A purpose the station interprets rather than a format the caller picks, so what `share` means can change without any caller changing */\n rendition?: SegmentAudioRendition;\n}\n\n/**\n * generated from [ScriptHistoryPage](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface ScriptHistoryPage {\n attempts: ScriptAttempt[];\n /** The cursor for the page after this one, absent once the history has been read to its end */\n nextBefore?: string;\n}\n\nexport interface ScriptHistoryPageInput {\n attempts: ScriptAttemptInput[];\n /** The cursor for the page after this one, absent once the history has been read to its end */\n nextBefore?: string;\n}\n\n/** Rehydrates every wire-encoded scalar in a ScriptHistoryPage into its runtime type. Mutates and returns `raw`. */\nexport function reviveScriptHistoryPage(raw: ScriptHistoryPage): ScriptHistoryPage {\n const __o0 = raw as unknown as Record<string, unknown>;\n {\n const __a1 = __o0['attempts'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveScriptAttempt(__a1[__i2] as never);\n }\n }\n return raw;\n}\n\n/**\n * Every sound the station holds, and the sets over it\n * generated from [PadList](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface PadList {\n pads: Pad[];\n sets: PadSet[];\n}\n\nexport interface PadListInput {\n pads: PadInput[];\n sets: PadSetInput[];\n}\n\n/** Rehydrates every wire-encoded scalar in a PadList into its runtime type. Mutates and returns `raw`. */\nexport function revivePadList(raw: PadList): PadList {\n const __o0 = raw as unknown as Record<string, unknown>;\n {\n const __a1 = __o0['pads'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n revivePad(__a1[__i2] as never);\n }\n }\n return raw;\n}\n","import type { SdkFetch } from '../sdk-options.js';\nimport { bigIntReplacer, parseJson, buildQueryString, readContentType } from '../sdk-options.js';\nimport type {\n PadFetch,\n PadList,\n PadScanResult,\n PadSetMembership,\n PadSetWrite,\n PadState,\n PadUse,\n PronunciationList,\n PronunciationQuery,\n PronunciationStateWrite,\n PronunciationWrite,\n ScriptAttempt,\n ScriptHistoryPage,\n ScriptHistoryQuery,\n ScriptHistorySummary,\n ScriptHistorySummaryQuery,\n ScriptRatingInput,\n Segment,\n SegmentAudioQuery,\n SegmentCreate,\n SegmentList,\n SegmentScanResult,\n SpeechPreviewRequest,\n VoiceList,\n} from './types/render.types.js';\nimport { revivePadList, reviveScriptAttempt, reviveScriptHistoryPage } from './types/render.types.js';\n\nexport class RenderClient {\n constructor(private fetch: SdkFetch) {}\n\n /**\n * @name List segments\n * @description Everything the station can play that is not a record\n */\n async listSegments(): Promise<SegmentList> {\n const result = await this.fetch(`/segments`, { method: 'GET' });\n return await parseJson<SegmentList>(result);\n }\n\n /**\n * @name Create segment\n * @description Plans something for the station to say, and starts rendering it\n */\n async createSegment(body: SegmentCreate): Promise<Segment> {\n const result = await this.fetch(`/segments`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<Segment>(result);\n }\n\n /**\n * @name Upload segment\n * @description Takes a recording in from the browser and puts it in the library, ready to air\n */\n async uploadSegment(body: FormData): Promise<Segment> {\n const result = await this.fetch(`/segments/upload`, {\n method: 'POST',\n body: body,\n });\n return await parseJson<Segment>(result);\n }\n\n /**\n * @name Scan the segment inbox\n * @description Takes whatever audio is sitting in the inbox directory into the library. Safe to repeat: a segment is identified by its audio, so the same recording arriving twice is one segment\n */\n async scanTheSegmentInbox(): Promise<SegmentScanResult> {\n const result = await this.fetch(`/segments/scan`, { method: 'POST' });\n return await parseJson<SegmentScanResult>(result);\n }\n\n /**\n * @name Read script history\n * @description What the station has written lately, newest first, one page at a time\n */\n async readScriptHistory(query?: ScriptHistoryQuery): Promise<ScriptHistoryPage> {\n const qs = buildQueryString(query);\n const result = await this.fetch(`/scripts${qs}`, {\n method: 'GET',\n });\n return reviveScriptHistoryPage(await parseJson<ScriptHistoryPage>(result));\n }\n\n /**\n * @name Rate script\n * @description What the operator thought of this attempt. Nothing acts on it automatically\n */\n async rateScript(id: string, body: ScriptRatingInput): Promise<ScriptAttempt> {\n const result = await this.fetch(`/scripts/${encodeURIComponent(id)}/rating`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return reviveScriptAttempt(await parseJson<ScriptAttempt>(result));\n }\n\n /**\n * @name Read script summary\n * @description Write attempts by outcome, per presenter, over a recent window\n */\n async readScriptSummary(query?: ScriptHistorySummaryQuery): Promise<ScriptHistorySummary> {\n const qs = buildQueryString(query);\n const result = await this.fetch(`/scripts/summary${qs}`, {\n method: 'GET',\n });\n return await parseJson<ScriptHistorySummary>(result);\n }\n\n /**\n * @name List voices\n * @description The voices the station can be asked to speak in\n */\n async listVoices(): Promise<VoiceList> {\n const result = await this.fetch(`/voices`, { method: 'GET' });\n return await parseJson<VoiceList>(result);\n }\n\n /**\n * @name Get default voice sample\n * @description A short line spoken in whichever voice the plugin falls back to\n */\n async getDefaultVoiceSample(): Promise<\n | {\n status: 200;\n contentType: 'audio/mpeg' | 'audio/wav' | 'audio/ogg' | 'audio/flac' | 'audio/mp4';\n data: Blob;\n headers: { cacheControl?: string; etag?: string };\n }\n | { status: 304 }\n > {\n const result = await this.fetch(`/voices/sample`, {\n method: 'GET',\n expectStatuses: [304],\n });\n switch (result.status) {\n case 304:\n return { status: 304 };\n default:\n return {\n status: 200,\n contentType: readContentType(result) as 'audio/mpeg' | 'audio/wav' | 'audio/ogg' | 'audio/flac' | 'audio/mp4',\n data: await result.blob(),\n headers: { cacheControl: result.headers.get('cache-control') ?? undefined, etag: result.headers.get('etag') ?? undefined },\n };\n }\n }\n\n /**\n * @name Get voice sample\n * @description A short line spoken in one voice, so an operator can hear it before choosing it\n */\n async getVoiceSample(voiceId: string): Promise<\n | {\n status: 200;\n contentType: 'audio/mpeg' | 'audio/wav' | 'audio/ogg' | 'audio/flac' | 'audio/mp4';\n data: Blob;\n headers: { cacheControl?: string; etag?: string };\n }\n | { status: 304 }\n > {\n const result = await this.fetch(`/voices/${encodeURIComponent(voiceId)}/sample`, {\n method: 'GET',\n expectStatuses: [304],\n });\n switch (result.status) {\n case 304:\n return { status: 304 };\n default:\n return {\n status: 200,\n contentType: readContentType(result) as 'audio/mpeg' | 'audio/wav' | 'audio/ogg' | 'audio/flac' | 'audio/mp4',\n data: await result.blob(),\n headers: { cacheControl: result.headers.get('cache-control') ?? undefined, etag: result.headers.get('etag') ?? undefined },\n };\n }\n }\n\n /**\n * @name Preview speech\n * @description Speaks the caller's words in one voice, so a break can be heard before it is written for air\n */\n async previewSpeech(\n body: SpeechPreviewRequest,\n ): Promise<{ contentType: 'audio/mpeg' | 'audio/wav' | 'audio/ogg' | 'audio/flac' | 'audio/mp4'; data: Blob }> {\n const result = await this.fetch(`/voices/preview`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return {\n contentType: readContentType(result) as 'audio/mpeg' | 'audio/wav' | 'audio/ogg' | 'audio/flac' | 'audio/mp4',\n data: await result.blob(),\n };\n }\n\n /**\n * @name Delete segment\n * @description Removes a recording and the inbox file behind it, so the next scan does not read it back in\n */\n async deleteSegment(id: string): Promise<SegmentList> {\n const result = await this.fetch(`/segments/${encodeURIComponent(id)}`, { method: 'DELETE' });\n return await parseJson<SegmentList>(result);\n }\n\n /**\n * @name Get segment audio\n * @description The audio of one segment\n */\n async getSegmentAudio(\n id: string,\n query?: SegmentAudioQuery,\n ): Promise<\n | {\n status: 200;\n contentType: 'audio/mpeg' | 'audio/wav' | 'audio/ogg' | 'audio/flac' | 'audio/mp4';\n data: Blob;\n headers: { cacheControl?: string; etag?: string; contentDisposition?: string };\n }\n | { status: 304 }\n > {\n const qs = buildQueryString(query);\n const result = await this.fetch(`/segments/${encodeURIComponent(id)}/audio${qs}`, {\n method: 'GET',\n expectStatuses: [304],\n });\n switch (result.status) {\n case 304:\n return { status: 304 };\n default:\n return {\n status: 200,\n contentType: readContentType(result) as 'audio/mpeg' | 'audio/wav' | 'audio/ogg' | 'audio/flac' | 'audio/mp4',\n data: await result.blob(),\n headers: {\n cacheControl: result.headers.get('cache-control') ?? undefined,\n etag: result.headers.get('etag') ?? undefined,\n contentDisposition: result.headers.get('content-disposition') ?? undefined,\n },\n };\n }\n }\n\n /**\n * @name Get stored audio\n * @description Audio out of the segment store, addressed by content rather than by row\n */\n async getStoredAudio(\n checksum: string,\n ext: string,\n ): Promise<\n | {\n status: 200;\n contentType: 'audio/mpeg' | 'audio/wav' | 'audio/ogg' | 'audio/flac' | 'audio/mp4';\n data: Blob;\n headers: { cacheControl?: string; etag?: string };\n }\n | { status: 304 }\n > {\n const result = await this.fetch(`/audio/${encodeURIComponent(checksum)}/${encodeURIComponent(ext)}`, {\n method: 'GET',\n expectStatuses: [304],\n });\n switch (result.status) {\n case 304:\n return { status: 304 };\n default:\n return {\n status: 200,\n contentType: readContentType(result) as 'audio/mpeg' | 'audio/wav' | 'audio/ogg' | 'audio/flac' | 'audio/mp4',\n data: await result.blob(),\n headers: { cacheControl: result.headers.get('cache-control') ?? undefined, etag: result.headers.get('etag') ?? undefined },\n };\n }\n }\n\n /**\n * @name List pronunciations\n * @description The station's lexicon: what it says, what has been proposed to it, and what it has turned down\n */\n async listPronunciations(query?: PronunciationQuery): Promise<PronunciationList> {\n const qs = buildQueryString(query);\n const result = await this.fetch(`/pronunciations${qs}`, {\n method: 'GET',\n });\n return await parseJson<PronunciationList>(result);\n }\n\n /**\n * @name Create pronunciation\n * @description Adds one the operator typed. It is said from the next render on\n */\n async createPronunciation(body: PronunciationWrite): Promise<PronunciationList> {\n const result = await this.fetch(`/pronunciations`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<PronunciationList>(result);\n }\n\n /**\n * @name Update pronunciation\n * @description Rewrites one entry's words, whoever proposed it\n */\n async updatePronunciation(id: string, body: PronunciationWrite): Promise<PronunciationList> {\n const result = await this.fetch(`/pronunciations/${encodeURIComponent(id)}`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<PronunciationList>(result);\n }\n\n /**\n * @name Delete pronunciation\n * @description Removes an entry outright. Turning a PROPOSAL down is a state rather than a deletion, because a deleted one comes back on the next pass\n */\n async deletePronunciation(id: string): Promise<PronunciationList> {\n const result = await this.fetch(`/pronunciations/${encodeURIComponent(id)}`, { method: 'DELETE' });\n return await parseJson<PronunciationList>(result);\n }\n\n /**\n * @name Set pronunciation state\n * @description Accepts a proposal, turns one down, or takes an entry out of use without losing what it said\n */\n async setPronunciationState(id: string, body: PronunciationStateWrite): Promise<PronunciationList> {\n const result = await this.fetch(`/pronunciations/${encodeURIComponent(id)}/state`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<PronunciationList>(result);\n }\n\n /**\n * @name List pads\n * @description Every sound the station holds, board by board\n */\n async listPads(): Promise<PadList> {\n const result = await this.fetch(`/pads`, { method: 'GET' });\n return revivePadList(await parseJson<PadList>(result));\n }\n\n /**\n * @name Upload pad\n * @description Takes a sound in from the browser and puts it on a board. The file lands in the pad library on disk, so it survives a rebuild and an archive carries it\n */\n async uploadPad(body: FormData): Promise<PadList> {\n const result = await this.fetch(`/pads`, {\n method: 'POST',\n body: body,\n });\n return revivePadList(await parseJson<PadList>(result));\n }\n\n /**\n * @name Scan the pad library\n * @description Takes whatever audio is sitting in the pad library directory onto its board. Safe to repeat: a file nobody has touched is seen and left alone\n */\n async scanThePadLibrary(): Promise<PadScanResult> {\n const result = await this.fetch(`/pads/scan`, { method: 'POST' });\n return await parseJson<PadScanResult>(result);\n }\n\n /**\n * @name Fetch pad\n * @description Fetches a sound from an address and puts it on a board. The operator names the address, so this is them choosing a file exactly as dropping one in the library is\n */\n async fetchPad(body: PadFetch): Promise<PadList> {\n const result = await this.fetch(`/pads/fetch`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return revivePadList(await parseJson<PadList>(result));\n }\n\n /**\n * @name Delete pad\n * @description Removes a sound the console put there, and the file it wrote for it\n */\n async deletePad(id: string): Promise<PadList> {\n const result = await this.fetch(`/pads/${encodeURIComponent(id)}`, { method: 'DELETE' });\n return revivePadList(await parseJson<PadList>(result));\n }\n\n /**\n * @name Set pad state\n * @description Turns a sound down, or puts one back. Answers the whole rack, since one pad changing state is one row moving between two sections of the same page\n */\n async setPadState(id: string, body: PadState): Promise<PadList> {\n const result = await this.fetch(`/pads/${encodeURIComponent(id)}/state`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return revivePadList(await parseJson<PadList>(result));\n }\n\n /**\n * @name Set pad use\n * @description Says where in a break a sound may land and when to reach for it. Answers the whole rack\n */\n async setPadUse(id: string, body: PadUse): Promise<PadList> {\n const result = await this.fetch(`/pads/${encodeURIComponent(id)}/use`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return revivePadList(await parseJson<PadList>(result));\n }\n\n /**\n * @name Get pad audio\n * @description The sound itself, so an operator can hear what they dropped in\n */\n async getPadAudio(id: string): Promise<\n | {\n status: 200;\n contentType: 'audio/mpeg' | 'audio/wav' | 'audio/ogg' | 'audio/flac' | 'audio/mp4';\n data: Blob;\n headers: { cacheControl?: string; etag?: string };\n }\n | { status: 304 }\n > {\n const result = await this.fetch(`/pads/${encodeURIComponent(id)}/audio`, {\n method: 'GET',\n expectStatuses: [304],\n });\n switch (result.status) {\n case 304:\n return { status: 304 };\n default:\n return {\n status: 200,\n contentType: readContentType(result) as 'audio/mpeg' | 'audio/wav' | 'audio/ogg' | 'audio/flac' | 'audio/mp4',\n data: await result.blob(),\n headers: { cacheControl: result.headers.get('cache-control') ?? undefined, etag: result.headers.get('etag') ?? undefined },\n };\n }\n }\n\n /**\n * @name Create pad set\n * @description Names a new set, or answers the one already under that key\n */\n async createPadSet(body: PadSetWrite): Promise<PadList> {\n const result = await this.fetch(`/pads/sets`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return revivePadList(await parseJson<PadList>(result));\n }\n\n /**\n * @name Update pad set\n * @description Renames a set. The KEY moves with it, so every persona naming the old one stops finding it\n */\n async updatePadSet(id: string, body: PadSetWrite): Promise<PadList> {\n const result = await this.fetch(`/pads/sets/${encodeURIComponent(id)}`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return revivePadList(await parseJson<PadList>(result));\n }\n\n /**\n * @name Delete pad set\n * @description Removes a set and its memberships, and no pads at all\n */\n async deletePadSet(id: string): Promise<PadList> {\n const result = await this.fetch(`/pads/sets/${encodeURIComponent(id)}`, { method: 'DELETE' });\n return revivePadList(await parseJson<PadList>(result));\n }\n\n /**\n * @name Set pad membership\n * @description Puts a pad on a set or takes it off. Refused where the set already answers to that name, because a script writes a name\n */\n async setPadMembership(id: string, body: PadSetMembership): Promise<PadList> {\n const result = await this.fetch(`/pads/sets/${encodeURIComponent(id)}/pads`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return revivePadList(await parseJson<PadList>(result));\n }\n}\n","import { DateTime } from 'luxon';\nconst __dt = (v: unknown, path: string): DateTime => {\n if (typeof v !== 'string') {\n throw new TypeError(`ContractKit: expected an ISO 8601 string at '${path}', received ${typeof v}.`);\n }\n const d = DateTime.fromISO(v);\n if (!d.isValid) throw new TypeError(`ContractKit: '${v}' at '${path}' is not a valid ISO 8601 datetime.`);\n return d;\n};\n\n/**\n * A music provider's copy of a record the station has not taken in yet\n * generated from [RequestableSource](../../../../../apps/api/data/contracts/requests/requests.types.ck)\n */\nexport interface RequestableSource {\n /** The plugin that carries it */\n pluginId: string;\n /** That plugin's own id for the record */\n externalId: string;\n}\n\n/**\n * generated from [RequestStatus](../../../../../apps/api/data/contracts/requests/requests.types.ck)\n */\nexport type RequestStatus = 'waiting' | 'pending' | 'queued' | 'aired' | 'declined' | 'expired';\n\n/**\n * generated from [RequestSource](../../../../../apps/api/data/contracts/requests/requests.types.ck)\n */\nexport type RequestSource = 'app' | 'chat';\n\n/**\n * Turn a request down\n * generated from [ListenerRequestDecline](../../../../../apps/api/data/contracts/requests/requests.types.ck)\n */\nexport interface ListenerRequestDecline {\n /** What to tell the listener. Omit for a plain no */\n reason?: string;\n}\n\n/**\n * A party: the pass guests join with by scanning its QR code, for as long as it lasts\n * generated from [PartyPass](../../../../../apps/api/data/contracts/requests/requests.types.ck)\n */\nexport interface PartyPass {\n /** The pass itself. Put it after `#` on the station's `/party` page, as `/party#<token>`, and that address is what the QR code holds. Anyone holding it can join until the party ends, so show it only to the room */\n token: string;\n /** When the party started */\n createdAt: DateTime;\n /** When the pass stops letting guests in, and turns away every guest who joined with it */\n expiresAt: DateTime;\n /** How many guests have joined with it */\n guests: number;\n}\n\n/** Rehydrates every wire-encoded scalar in a PartyPass into its runtime type. Mutates and returns `raw`. */\nexport function revivePartyPass(raw: PartyPass): PartyPass {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['createdAt'] = __dt(__o0['createdAt'], 'PartyPass.createdAt');\n __o0['expiresAt'] = __dt(__o0['expiresAt'], 'PartyPass.expiresAt');\n return raw;\n}\n\n/**\n * Start a party\n * generated from [PartyStart](../../../../../apps/api/data/contracts/requests/requests.types.ck)\n */\nexport interface PartyStart {\n /** How long the pass lasts. Six when omitted */\n hours?: number;\n}\n\n/**\n * Join a party as a guest, with the pass from its QR code\n * generated from [PartyJoin](../../../../../apps/api/data/contracts/requests/requests.types.ck)\n */\nexport interface PartyJoin {\n /** The pass, as it appears after `#` in the party page's address */\n token: string;\n}\n\n/**\n * A guest's way in: send it as a bearer token on the request routes\n * generated from [PartyGuestSession](../../../../../apps/api/data/contracts/requests/requests.types.ck)\n */\nexport interface PartyGuestSession {\n /** The bearer token. It lets a guest search for records, ask for one and see their own requests, and nothing else */\n accessToken: string;\n /** When it stops working, which is when the party's pass does */\n expiresAt: DateTime;\n}\n\n/** Rehydrates every wire-encoded scalar in a PartyGuestSession into its runtime type. Mutates and returns `raw`. */\nexport function revivePartyGuestSession(raw: PartyGuestSession): PartyGuestSession {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['expiresAt'] = __dt(__o0['expiresAt'], 'PartyGuestSession.expiresAt');\n return raw;\n}\n\n/**\n * A record the station could be asked for: one it holds, or one a music provider carries\n * generated from [RequestableTrack](../../../../../apps/api/data/contracts/requests/requests.types.ck)\n */\nexport interface RequestableTrack {\n /** What to send as `trackId` to make the request. Absent for a record from a provider, which is asked for by `source` instead */\n trackId?: string;\n /** Where a record the station does not hold yet comes from. Send it as `source` to ask for it */\n source?: RequestableSource;\n /** The provider, as the station names it, for a record from one */\n sourceName?: string;\n title: string;\n /** The lead artist */\n artist: string;\n album?: string;\n year?: number;\n}\n\n/**\n * Ask the station to play a record\n * generated from [ListenerRequestCreate](../../../../../apps/api/data/contracts/requests/requests.types.ck)\n */\nexport interface ListenerRequestCreate {\n /** A record from the request search that the station holds. Send this or `source`, never both */\n trackId?: string;\n /** A record from the request search that a provider carries. The station takes it in, then decides on the request as usual */\n source?: RequestableSource;\n /** What the station should call you. Omitted, you are \"a listener\": your account's email address is never shown or read out */\n name?: string;\n /** Dedicate it to somebody. The station may say this name on air */\n dedicateTo?: string;\n /** A few words to go with it. The presenter may put them in their own words on air, and leaves out anything unfit to broadcast; the words themselves are never read out */\n message?: string;\n}\n\n/**\n * A record somebody asked the station to play, and what became of it\n * generated from [ListenerRequest](../../../../../apps/api/data/contracts/requests/requests.types.ck)\n */\nexport interface ListenerRequest {\n id: string;\n /** `waiting` for an operator to approve it, `pending` while its audio is fetched or a place is found for it, `queued` in the running order, `aired` once heard, `declined` or `expired` when it never will be */\n status: RequestStatus;\n /** The record, as it was called when it was asked for */\n title: string;\n artist: string;\n /** Who asked, by the name their account or chat platform gave */\n requesterName: string;\n /** Whether it came from an app or a chat platform */\n source: RequestSource;\n /** When it was asked for */\n createdAt: DateTime;\n /** Why it was declined or expired, in the station's words or an operator's */\n reason?: string;\n /** When it aired */\n airedAt?: DateTime;\n /** Who the listener dedicated it to */\n dedicateTo?: string;\n /** What the listener asked to have said with it, in their own words */\n message?: string;\n /** True when a guest at a party asked for it, through the party pass. Absent otherwise */\n fromParty?: boolean;\n /** True on a declined request whoever asked may still insist on, with `POST /requests/{id}/insist`: the station turned it down for its own taste (aired lately, a cooldown, a dislike, the period, a length) rather than a rule nobody overrules. Absent otherwise, and once it has been insisted on */\n overrulable?: boolean;\n /** True when whoever asked insisted on it after the station turned it down, so the station's own taste was overruled. Absent otherwise */\n insisted?: boolean;\n}\n\n/** Rehydrates every wire-encoded scalar in a ListenerRequest into its runtime type. Mutates and returns `raw`. */\nexport function reviveListenerRequest(raw: ListenerRequest): ListenerRequest {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['createdAt'] = __dt(__o0['createdAt'], 'ListenerRequest.createdAt');\n if (__o0['airedAt'] != null) {\n __o0['airedAt'] = __dt(__o0['airedAt'], 'ListenerRequest.airedAt');\n }\n return raw;\n}\n\n/**\n * The party, if one is on\n * generated from [PartyState](../../../../../apps/api/data/contracts/requests/requests.types.ck)\n */\nexport interface PartyState {\n /** Absent when no party is on */\n party?: PartyPass;\n}\n\n/** Rehydrates every wire-encoded scalar in a PartyState into its runtime type. Mutates and returns `raw`. */\nexport function revivePartyState(raw: PartyState): PartyState {\n const __o0 = raw as unknown as Record<string, unknown>;\n if (__o0['party'] != null) {\n revivePartyPass(__o0['party'] as never);\n }\n return raw;\n}\n\n/**\n * Records matching a search, best matches first, the station's own before any a provider carries\n * generated from [RequestableTrackList](../../../../../apps/api/data/contracts/requests/requests.types.ck)\n */\nexport interface RequestableTrackList {\n tracks: RequestableTrack[];\n}\n\n/**\n * Requests, newest first\n * generated from [ListenerRequestList](../../../../../apps/api/data/contracts/requests/requests.types.ck)\n */\nexport interface ListenerRequestList {\n requests: ListenerRequest[];\n}\n\n/** Rehydrates every wire-encoded scalar in a ListenerRequestList into its runtime type. Mutates and returns `raw`. */\nexport function reviveListenerRequestList(raw: ListenerRequestList): ListenerRequestList {\n const __o0 = raw as unknown as Record<string, unknown>;\n {\n const __a1 = __o0['requests'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveListenerRequest(__a1[__i2] as never);\n }\n }\n return raw;\n}\n","import type { PartyGuestSession, PartyJoin, PartyPass, PartyStart, PartyState } from './types/requests.types.js';\nimport { revivePartyGuestSession, revivePartyPass, revivePartyState } from './types/requests.types.js';\nimport type { SdkFetch } from '../sdk-options.js';\nimport { bigIntReplacer, parseJson } from '../sdk-options.js';\n\n/**\n * generated from [requests.party.ck](../../../../apps/api/data/contracts/requests/requests.party.ck)\n */\nexport class RequestsPartyClient {\n constructor(private fetch: SdkFetch) {}\n\n /**\n * @name Get party\n * @description The party that is on, with its pass, so the console can show the QR code again\n */\n async getParty(): Promise<PartyState> {\n const result = await this.fetch(`/party`, { method: 'GET' });\n return revivePartyState(await parseJson<PartyState>(result));\n }\n\n /**\n * @name Start party\n * @description Start a party. A party already on is ended first, which turns its guests away, so there is only ever one pass to scan\n */\n async startParty(body: PartyStart): Promise<PartyPass> {\n const result = await this.fetch(`/party`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return revivePartyPass(await parseJson<PartyPass>(result));\n }\n\n /**\n * @name End party\n * @description End the party. Its pass stops working and every guest who joined with it is turned away on their next request\n */\n async endParty(): Promise<void> {\n await this.fetch(`/party`, { method: 'DELETE' });\n }\n\n /**\n * @name Join party\n * @description Join the party as a guest. Answers 404 for a pass that is unknown, ended or run out, without saying which\n */\n async joinParty(body: PartyJoin): Promise<PartyGuestSession> {\n const result = await this.fetch(`/party/join`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return revivePartyGuestSession(await parseJson<PartyGuestSession>(result));\n }\n}\n","import type { SdkFetch } from '../sdk-options.js';\nimport { bigIntReplacer, parseJson, buildQueryString } from '../sdk-options.js';\nimport type {\n ListenerRequest,\n ListenerRequestCreate,\n ListenerRequestDecline,\n ListenerRequestList,\n RequestStatus,\n RequestableTrackList,\n} from './types/requests.types.js';\nimport { reviveListenerRequest, reviveListenerRequestList } from './types/requests.types.js';\nimport { RequestsPartyClient } from './requests.party.client.js';\n\nexport class RequestsClient {\n readonly party: RequestsPartyClient;\n\n constructor(private fetch: SdkFetch) {\n this.party = new RequestsPartyClient(fetch);\n }\n\n /**\n * @name Search requestable records\n * @description Records the station could be asked to play, matching a title or an artist, then what the music providers carry in the room left\n */\n async searchRequestableRecords(query: { q: string; limit?: number }): Promise<RequestableTrackList> {\n const qs = buildQueryString(query);\n const result = await this.fetch(`/requests/search${qs}`, {\n method: 'GET',\n });\n return await parseJson<RequestableTrackList>(result);\n }\n\n /**\n * @name List requests\n * @description Every recent request, for the operator deciding on them\n */\n async listRequests(query?: { status?: RequestStatus }): Promise<ListenerRequestList> {\n const qs = buildQueryString(query);\n const result = await this.fetch(`/requests${qs}`, {\n method: 'GET',\n });\n return reviveListenerRequestList(await parseJson<ListenerRequestList>(result));\n }\n\n /**\n * @name Create request\n * @description Ask the station to play a record. Answers with the request whatever became of it, so a refusal says why in `reason`\n */\n async createRequest(body: ListenerRequestCreate): Promise<ListenerRequest> {\n const result = await this.fetch(`/requests`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return reviveListenerRequest(await parseJson<ListenerRequest>(result));\n }\n\n /**\n * @name List my requests\n * @description The signed-in account's own recent requests\n */\n async listMyRequests(): Promise<ListenerRequestList> {\n const result = await this.fetch(`/requests/mine`, { method: 'GET' });\n return reviveListenerRequestList(await parseJson<ListenerRequestList>(result));\n }\n\n /**\n * @name Insist on request\n * @description Ask again for a record the station turned down for its own taste, overruling it. Only your own request, only one marked `overrulable`, and only once. Answers with the NEW request this makes, decided like any other: it can still wait for an operator, or be refused for who is asking or how full the line is\n */\n async insistOnRequest(id: string): Promise<ListenerRequest> {\n const result = await this.fetch(`/requests/${encodeURIComponent(id)}/insist`, { method: 'POST' });\n return reviveListenerRequest(await parseJson<ListenerRequest>(result));\n }\n\n /**\n * @name Grant request\n * @description Let a waiting request through. It goes into the running order once its audio is here\n */\n async grantRequest(id: string): Promise<ListenerRequest> {\n const result = await this.fetch(`/requests/${encodeURIComponent(id)}/grant`, { method: 'POST' });\n return reviveListenerRequest(await parseJson<ListenerRequest>(result));\n }\n\n /**\n * @name Decline request\n * @description Turn a request down. One already in the running order is left there; take it out of the order instead\n */\n async declineRequest(id: string, body: ListenerRequestDecline): Promise<ListenerRequest> {\n const result = await this.fetch(`/requests/${encodeURIComponent(id)}/decline`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return reviveListenerRequest(await parseJson<ListenerRequest>(result));\n }\n}\n","import type { SdkFetch } from '../sdk-options.js';\nimport { bigIntReplacer, parseJson, buildQueryString } from '../sdk-options.js';\nimport type {\n ScheduleNow,\n ScheduleSlotInput,\n ScheduleSlotList,\n ScheduleTimetable,\n ScheduleTimetableQuery,\n SlotPlaylistPosition,\n} from './types/schedule.types.js';\n\nexport class ScheduleClient {\n constructor(private fetch: SdkFetch) {}\n\n /**\n * @name List schedule\n * @description Every slot in this station's schedule, earliest in the day first\n */\n async listSchedule(): Promise<ScheduleSlotList> {\n const result = await this.fetch(`/schedule`, { method: 'GET' });\n return await parseJson<ScheduleSlotList>(result);\n }\n\n /**\n * @name Create schedule slot\n * @description Adds a slot. The station does not change over until its start time comes round\n */\n async createScheduleSlot(body: ScheduleSlotInput): Promise<ScheduleSlotList> {\n const result = await this.fetch(`/schedule`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<ScheduleSlotList>(result);\n }\n\n /**\n * @name Read current slot\n * @description Which slot the clock says should be on, and which one the station is actually airing\n */\n async readCurrentSlot(): Promise<ScheduleNow> {\n const result = await this.fetch(`/schedule/current`, { method: 'GET' });\n return await parseJson<ScheduleNow>(result);\n }\n\n /**\n * @name Read timetable\n * @description The station's day as blocks, contiguous and gapless, for drawing\n */\n async readTimetable(query?: ScheduleTimetableQuery): Promise<ScheduleTimetable> {\n const qs = buildQueryString(query);\n const result = await this.fetch(`/schedule/timetable${qs}`, {\n method: 'GET',\n });\n return await parseJson<ScheduleTimetable>(result);\n }\n\n /**\n * @name Update schedule slot\n * @description Rewrites a slot. Takes effect at its next boundary rather than immediately\n */\n async updateScheduleSlot(id: string, body: ScheduleSlotInput): Promise<ScheduleSlotList> {\n const result = await this.fetch(`/schedule/${encodeURIComponent(id)}`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<ScheduleSlotList>(result);\n }\n\n /**\n * @name Delete schedule slot\n * @description Removes a slot. Whatever is on air stays on until the next slot begins\n */\n async deleteScheduleSlot(id: string): Promise<ScheduleSlotList> {\n const result = await this.fetch(`/schedule/${encodeURIComponent(id)}`, { method: 'DELETE' });\n return await parseJson<ScheduleSlotList>(result);\n }\n\n /**\n * @name Read slot playlist position\n * @description The record a slot that resumes its playlist will open on next time, or nothing when it would start from the top\n */\n async readSlotPlaylistPosition(id: string): Promise<SlotPlaylistPosition> {\n const result = await this.fetch(`/schedule/${encodeURIComponent(id)}/playlist-position`, { method: 'GET' });\n return await parseJson<SlotPlaylistPosition>(result);\n }\n\n /**\n * @name Restart slot playlist\n * @description Forgets where a slot got to in its playlist, so it starts from the top the next time it opens\n */\n async restartSlotPlaylist(id: string): Promise<void> {\n await this.fetch(`/schedule/${encodeURIComponent(id)}/playlist-position`, { method: 'DELETE' });\n }\n}\n","import type { SdkFetch } from '../sdk-options.js';\nimport { bigIntReplacer, parseJson, buildQueryString } from '../sdk-options.js';\nimport type {\n InvitationPreview,\n InvitationPreviewQuery,\n SigninProvidersCheck,\n StationSettings,\n StationSettingsInput,\n} from './types/settings.types.js';\n\nexport class SettingsClient {\n constructor(private fetch: SdkFetch) {}\n\n /**\n * @name Get settings\n * @description Every station setting, its descriptor and its current value\n */\n async getSettings(): Promise<StationSettings> {\n const result = await this.fetch(`/settings`, { method: 'GET' });\n return await parseJson<StationSettings>(result);\n }\n\n /**\n * @name Update settings\n * @description Applies a submitted settings form and answers with the settings as they now stand\n */\n async updateSettings(body: StationSettingsInput): Promise<StationSettings> {\n const result = await this.fetch(`/settings`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<StationSettings>(result);\n }\n\n /**\n * @name Check sign-in providers\n * @description Asks each identity provider in the sign-in settings for its discovery document, the way a sign-in would, and says which answered\n */\n async checkSignInProviders(): Promise<SigninProvidersCheck> {\n const result = await this.fetch(`/settings/signin/check`, { method: 'GET' });\n return await parseJson<SigninProvidersCheck>(result);\n }\n\n /**\n * @name Preview invitation\n * @description Renders the invitation email as it would be sent now, in the station's saved wording, with sample values in place of a real link, inviter and date\n */\n async previewInvitation(query?: InvitationPreviewQuery): Promise<InvitationPreview> {\n const qs = buildQueryString(query);\n const result = await this.fetch(`/settings/mail/invitation/preview${qs}`, {\n method: 'GET',\n });\n return await parseJson<InvitationPreview>(result);\n }\n}\n","import { DateTime } from 'luxon';\nconst __dt = (v: unknown, path: string): DateTime => {\n if (typeof v !== 'string') {\n throw new TypeError(`ContractKit: expected an ISO 8601 string at '${path}', received ${typeof v}.`);\n }\n const d = DateTime.fromISO(v);\n if (!d.isValid) throw new TypeError(`ContractKit: '${v}' at '${path}' is not a valid ISO 8601 datetime.`);\n return d;\n};\n\n/**\n * Five values, where `PluginLogLevel` next door has four. The plugin enum is the narrower one on\n * purpose — that is the vocabulary a plugin's own `PluginLogger` offers — while `api.log` is written\n * by `DeadairLogger`, which tees every level the app-wide `Logger` has, `trace` included. Narrowing\n * here would make a `trace` line unrepresentable in the type of the surface that reads the file it\n * is in.\n * generated from [LogLevel](../../../../../apps/api/data/contracts/station/logs.types.ck)\n */\nexport type LogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error';\n\n/**\n * One log file this install has, whether or not anything has been written to it\n * generated from [LogSource](../../../../../apps/api/data/contracts/station/logs.types.ck)\n */\nexport interface LogSource {\n /** A closed set the API owns: `api`, `liquidsoap`, `shim`. Never a path */\n id: string;\n label: string;\n /** What writes it, in a sentence, because \"shim\" means nothing to somebody who has not read the tree */\n description: string;\n /** Whether the file is there at all. A station that never ran the stream has no stream logs, which is a state rather than a fault */\n present: boolean;\n /** Whether its lines carry a level, so the console knows whether to offer the filter */\n levels: boolean;\n /** Retained size across every segment. Zero when absent */\n bytes: number;\n /** Absent when nothing has ever been written */\n lastWriteAt?: DateTime;\n}\n\n/** Rehydrates every wire-encoded scalar in a LogSource into its runtime type. Mutates and returns `raw`. */\nexport function reviveLogSource(raw: LogSource): LogSource {\n const __o0 = raw as unknown as Record<string, unknown>;\n if (__o0['lastWriteAt'] != null) {\n __o0['lastWriteAt'] = __dt(__o0['lastWriteAt'], 'LogSource.lastWriteAt');\n }\n return raw;\n}\n\n/**\n * One line, as far as it could be read back\n * generated from [LogLine](../../../../../apps/api/data/contracts/station/logs.types.ck)\n */\nexport interface LogLine {\n /** Absent on a line this API did not write, and on one of its own that did not parse */\n ts?: string;\n /** Absent for the same two reasons */\n level?: LogLevel;\n /** Must match MAX_LINE_BYTES_CEILING in apps/api/src/logging/rotating.log.store.ts. Change both together */\n text: string;\n}\n\n/**\n * generated from [LogQuery](../../../../../apps/api/data/contracts/station/logs.types.ck)\n */\nexport interface LogQuery {\n limit?: number;\n /** Ignored by a source whose lines carry no level */\n level?: LogLevel;\n}\n\n/**\n * generated from [LogSourceList](../../../../../apps/api/data/contracts/station/logs.types.ck)\n */\nexport interface LogSourceList {\n /** Every source, in a fixed order, including the ones that are not present */\n sources: LogSource[];\n}\n\n/** Rehydrates every wire-encoded scalar in a LogSourceList into its runtime type. Mutates and returns `raw`. */\nexport function reviveLogSourceList(raw: LogSourceList): LogSourceList {\n const __o0 = raw as unknown as Record<string, unknown>;\n {\n const __a1 = __o0['sources'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveLogSource(__a1[__i2] as never);\n }\n }\n return raw;\n}\n\n/**\n * generated from [LogPage](../../../../../apps/api/data/contracts/station/logs.types.ck)\n */\nexport interface LogPage {\n sourceId: string;\n /** The minimum severity that was applied. Absent when the source carries no levels, so a filter that did nothing cannot look as though it worked */\n level?: LogLevel;\n /** Whether the read hit its byte budget, so the oldest line here is not the file's first */\n truncated: boolean;\n /** Newest first, as the plugin log page, the activity feed and the script history all send */\n lines: LogLine[];\n}\n","import { DateTime } from 'luxon';\nconst __dt = (v: unknown, path: string): DateTime => {\n if (typeof v !== 'string') {\n throw new TypeError(`ContractKit: expected an ISO 8601 string at '${path}', received ${typeof v}.`);\n }\n const d = DateTime.fromISO(v);\n if (!d.isValid) throw new TypeError(`ContractKit: '${v}' at '${path}' is not a valid ISO 8601 datetime.`);\n return d;\n};\nconst __dtf = (v: unknown, path: string, fmt: string): DateTime => {\n if (typeof v !== 'string') {\n throw new TypeError(`ContractKit: expected a string at '${path}' in format ${fmt}, received ${typeof v}.`);\n }\n const d = DateTime.fromFormat(v, fmt);\n if (!d.isValid) throw new TypeError(`ContractKit: '${v}' at '${path}' does not match format ${fmt}.`);\n return d;\n};\n\n/**\n * One concrete thing an attention row is about, so the reason does not live a page away.\n *\n * The row above it counts and categorises; this names. \"4 records have no copy left that will play\"\n * is a category an operator can do nothing with until they know WHICH four and WHY each one, and\n * every one of those facts was already stored — the fetch error on `track_audio.last_error`, the\n * provider's refusal on `track_sources.playable` — and reachable only by finding the record and\n * hovering a cell on its page. This is that fact travelling with the row that counted it.\n * generated from [AttentionEvidence](../../../../../apps/api/data/contracts/station/station.types.ck)\n */\nexport interface AttentionEvidence {\n /** The thing itself, as an operator would name it: a record's title and who made it */\n label: string;\n /** Why THIS one, in the station's own sentence. The row's `detail` says what the category means; this says what happened here */\n reason: string;\n /** The page holding the whole of it. Absent where there is no page for it, which the running order can hold: a record the catalog never ingested has none */\n route?: string;\n}\n\n/**\n * One loop the station runs, and when it last came round.\n *\n * Two timestamps and no verdict, because the loop cannot supply one: a five-second reconcile and a\n * nightly sweep are both healthy and no single threshold describes both. `Heartbeat` itself takes\n * this position — it answers how long it has been and lets the reader decide — and a `stalled`\n * boolean here would be this module inventing the threshold that file deliberately refuses to.\n *\n * `lastBeat` is absent until a loop finishes its first pass, which is why `startedAt` is there: from\n * the two of them a reader can tell a loop that has never completed anything from one that stopped.\n * generated from [StationHeartbeat](../../../../../apps/api/data/contracts/station/station.types.ck)\n */\nexport interface StationHeartbeat {\n name: string;\n /** When the loop registered, which is when it was last (re)started */\n startedAt: DateTime;\n /** When it last completed a pass. Absent until it completes its first */\n lastBeat?: DateTime;\n}\n\nexport interface StationHeartbeatInput {}\n\n/** Rehydrates every wire-encoded scalar in a StationHeartbeat into its runtime type. Mutates and returns `raw`. */\nexport function reviveStationHeartbeat(raw: StationHeartbeat): StationHeartbeat {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['startedAt'] = __dt(__o0['startedAt'], 'StationHeartbeat.startedAt');\n if (__o0['lastBeat'] != null) {\n __o0['lastBeat'] = __dt(__o0['lastBeat'], 'StationHeartbeat.lastBeat');\n }\n return raw;\n}\n\n/**\n * How much of the library the station has actually looked at.\n *\n * The counts `/catalog/tracks` already answers with, lifted out of a page of rows: a check-up wants\n * the sentence \"13 of 581 measured\" without asking for thirteen tracks to get it.\n * generated from [StationBacklog](../../../../../apps/api/data/contracts/station/station.types.ck)\n */\nexport interface StationBacklog {\n total: number;\n cached: number;\n measured: number;\n}\n\nexport interface StationBacklogInput {}\n\n/**\n * Who has the station's one model slot, and how many are waiting for it.\n *\n * The model is shared by every break, every programme refill and every production, one generation at\n * a time, so a slot held for far longer than any generation takes is the station's ability to speak\n * stuck behind one answer. Nothing else exposes it.\n * generated from [StationModelHolder](../../../../../apps/api/data/contracts/station/station.types.ck)\n */\nexport interface StationModelHolder {\n /** Whose work it is: `breaking` and `air` have a deadline, `background` (a refill, a production) does not, `preview` is an operator trying something */\n priority: 'breaking' | 'air' | 'background' | 'preview';\n /** When it took the slot. Every generation is bounded at ten minutes, so a holder older than that is a stream that stopped arriving */\n heldSince: DateTime;\n /** The model plugin answering it */\n plugin?: string;\n}\n\nexport interface StationModelHolderInput {}\n\n/** Rehydrates every wire-encoded scalar in a StationModelHolder into its runtime type. Mutates and returns `raw`. */\nexport function reviveStationModelHolder(raw: StationModelHolder): StationModelHolder {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['heldSince'] = __dt(__o0['heldSince'], 'StationModelHolder.heldSince');\n return raw;\n}\n\n/**\n * One release of the station, in the words its changelog entry used\n * generated from [StationRelease](../../../../../apps/api/data/contracts/station/station.types.ck)\n */\nexport interface StationRelease {\n /** The release, as its tag names it without the leading `v` */\n version: string;\n /** The day it went out. Absent where the entry named none */\n date?: DateTime;\n /** What changed, as the Markdown of its changelog entry. Empty for a release that recorded nothing */\n notes: string;\n /** The release's page on GitHub. Present on a release this station does not contain yet, which is where its notes came from */\n url?: string;\n}\n\nexport interface StationReleaseInput {}\n\n/** Rehydrates every wire-encoded scalar in a StationRelease into its runtime type. Mutates and returns `raw`. */\nexport function reviveStationRelease(raw: StationRelease): StationRelease {\n const __o0 = raw as unknown as Record<string, unknown>;\n if (__o0['date'] != null) {\n __o0['date'] = __dtf(__o0['date'], 'StationRelease.date', 'yyyy-MM-dd');\n }\n return raw;\n}\n\n/**\n * One thing that wants the operator's attention, or the fact that nothing does\n * generated from [AttentionItem](../../../../../apps/api/data/contracts/station/station.types.ck)\n */\nexport interface AttentionItem {\n /** What this is, as a stable key: `silence`, `benchedCopies`, `noPersona`. The console groups and counts on it rather than on the sentence */\n code: string;\n /** `failure` is the station not doing its job, `warning` is something failing beside a station that is working, and `notice` is a thing nobody has set up yet. A notice is not a fault and must not be drawn as one */\n severity: 'failure' | 'warning' | 'notice';\n /** The line an operator reads first */\n title: string;\n /** The whole of it, in a sentence. Where the station already has words for a fact, these are those words rather than a second phrasing of them */\n detail: string;\n /** The console page that can do something about it */\n route: string;\n /** How many things this is about, where that is a number rather than a state */\n count?: number;\n /** The operator may accept this row as it stands, through `POST /station/attention/{code}/dismiss`. It comes back by itself when something new joins it. Absent on a row that only goes away when its cause does */\n dismissible?: boolean;\n /** A HANDFUL of the things this row is about, never all of them: this answer is polled and a row about four hundred records must not be four hundred sentences. `count` stays the true figure, and a console showing fewer than it says so */\n evidence?: AttentionEvidence[];\n}\n\n/**\n * The model slot and its queue\n * generated from [StationModel](../../../../../apps/api/data/contracts/station/station.types.ck)\n */\nexport interface StationModel {\n /** Callers queued behind whoever holds the slot */\n waiting: number;\n /** Absent while the model is free */\n holder?: StationModelHolder;\n}\n\nexport interface StationModelInput {}\n\n/** Rehydrates every wire-encoded scalar in a StationModel into its runtime type. Mutates and returns `raw`. */\nexport function reviveStationModel(raw: StationModel): StationModel {\n const __o0 = raw as unknown as Record<string, unknown>;\n if (__o0['holder'] != null) {\n reviveStationModelHolder(__o0['holder'] as never);\n }\n return raw;\n}\n\n/**\n * What this build is, and what changed in it\n * generated from [StationReleases](../../../../../apps/api/data/contracts/station/station.types.ck)\n */\nexport interface StationReleases {\n /** The newest release this build contains, read off the changelog it was built with. Present on a build that follows `main` too, where `version` on the check-up is absent: every build carries the entry of the last release merged before it. Absent only when the build carries no changelog to read */\n current?: string;\n /** Every release this build contains, newest first */\n notes: StationRelease[];\n /** Whether the station asks GitHub for newer releases, which the operator switches under Settings, Station */\n checks: boolean;\n /** When GitHub last answered. Absent until it has, and while the check is switched off */\n checkedAt?: DateTime;\n /** Releases newer than this build, newest first, each with its notes and its page. Empty when there are none, while the check is off, and until GitHub has answered */\n available: StationRelease[];\n}\n\nexport interface StationReleasesInput {}\n\n/** Rehydrates every wire-encoded scalar in a StationReleases into its runtime type. Mutates and returns `raw`. */\nexport function reviveStationReleases(raw: StationReleases): StationReleases {\n const __o0 = raw as unknown as Record<string, unknown>;\n {\n const __a1 = __o0['notes'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveStationRelease(__a1[__i2] as never);\n }\n }\n if (__o0['checkedAt'] != null) {\n __o0['checkedAt'] = __dt(__o0['checkedAt'], 'StationReleases.checkedAt');\n }\n {\n const __a3 = __o0['available'] as unknown[];\n for (let __i4 = 0; __i4 < __a3.length; __i4++) {\n reviveStationRelease(__a3[__i4] as never);\n }\n }\n return raw;\n}\n\n/**\n * Everything wrong or waiting, worst first\n * generated from [StationAttention](../../../../../apps/api/data/contracts/station/station.types.ck)\n */\nexport interface StationAttention {\n items: AttentionItem[];\n}\n\n/**\n * One reading of the machinery, for a page that assembles the station's health.\n *\n * It carries ONLY the signals nothing else exposes. Everything else a check-up shows — the\n * silence verdict, the listener count, what needs somebody, the plugin statuses, the disk — is\n * already on a contract the console reads, and composing them again here would be a second answer\n * that can disagree with the first. `/playout/status` in particular is polled every two seconds for\n * the transport strip, so asking for it a second way would be a second reading of the same fact.\n *\n * Each section is OPTIONAL and absent means that reader failed. A page saying what is wrong is the\n * worst place for one broken reader to take the whole answer down, which is the rule\n * `StationAttentionService` already works to. `revision` is the one exception and says so on its\n * own line: it cannot fail, so absent there means something else.\n *\n * The revision is on THIS contract rather than composed from `/health`, which also reports it, and\n * that is not the second-answer problem the paragraph above describes. Both read one string from one\n * place at boot, so they cannot disagree. What they differ in is who can reach them: `/health` is\n * `operation(internal)`, deliberately, so it generates no SDK method and the console cannot call it\n * — which would leave \"which build is this\" answerable only from a shell, the one thing carrying it\n * here exists to fix.\n * generated from [StationCheckup](../../../../../apps/api/data/contracts/station/station.types.ck)\n */\nexport interface StationCheckup {\n /** When this reading was taken, so a stale page cannot pass itself off as now */\n readAt: DateTime;\n /** The commit this station was built from, as the image's `org.opencontainers.image.revision` label says it. Unlike the sections below, absent is not a failed reader: it means nothing stamped this build, which is what a development tree and a hand-built image both are */\n revision?: string;\n /** The release this station is, as the image's `org.opencontainers.image.version` label says it. Absent on the same terms as `revision` and for a second reason: only a tagged build carries one, so a station following `latest` reports a commit and no version */\n version?: string;\n heartbeats?: StationHeartbeat[];\n backlog?: StationBacklog;\n model?: StationModel;\n}\n\nexport interface StationCheckupInput {}\n\n/** Rehydrates every wire-encoded scalar in a StationCheckup into its runtime type. Mutates and returns `raw`. */\nexport function reviveStationCheckup(raw: StationCheckup): StationCheckup {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['readAt'] = __dt(__o0['readAt'], 'StationCheckup.readAt');\n if (__o0['heartbeats'] != null) {\n {\n const __a1 = __o0['heartbeats'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveStationHeartbeat(__a1[__i2] as never);\n }\n }\n }\n if (__o0['model'] != null) {\n reviveStationModel(__o0['model'] as never);\n }\n return raw;\n}\n","import { DateTime } from 'luxon';\nconst __dt = (v: unknown, path: string): DateTime => {\n if (typeof v !== 'string') {\n throw new TypeError(`ContractKit: expected an ISO 8601 string at '${path}', received ${typeof v}.`);\n }\n const d = DateTime.fromISO(v);\n if (!d.isValid) throw new TypeError(`ContractKit: '${v}' at '${path}' is not a valid ISO 8601 datetime.`);\n return d;\n};\n\n/**\n * Whether a call produced what it was asked for. Two values on purpose: every finer distinction —\n * timed out, was preempted, came back empty — is a fact the caller knew and the recorder did not, so\n * it lives in `detail` where it can be named\n * generated from [TraceOutcome](../../../../../apps/api/data/contracts/station/traces.types.ck)\n */\nexport type TraceOutcome = 'ok' | 'failed';\n\n/**\n * One decision, folded: a job execution or a request\n * generated from [TraceDecision](../../../../../apps/api/data/contracts/station/traces.types.ck)\n */\nexport interface TraceDecision {\n /** The job id or the request id. Already the station's correlation id, never generated for this */\n id: string;\n /** A queue name, or a method and path */\n kind: string;\n /** The decision that enqueued this one. Absent on a request, a cron job and anything at boot */\n parent?: string;\n /** When its first recorded call ended */\n at: DateTime;\n /** Wall clock, off the `job.run` span. Zero for a decision recorded before that span existed */\n ms: number;\n /** Everything it did, not counting the `job.run` that contains them */\n calls: number;\n /** How many of those did not produce what they were asked for */\n failed: number;\n}\n\n/** Rehydrates every wire-encoded scalar in a TraceDecision into its runtime type. Mutates and returns `raw`. */\nexport function reviveTraceDecision(raw: TraceDecision): TraceDecision {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['at'] = __dt(__o0['at'], 'TraceDecision.at');\n return raw;\n}\n\n/**\n * Which slice of the kept window to read\n * generated from [TracesQuery](../../../../../apps/api/data/contracts/station/traces.types.ck)\n */\nexport interface TracesQuery {\n limit?: number;\n /** An exact queue name or route, for reading one kind of decision on its own */\n kind?: string;\n /** Only decisions carrying at least one failed call */\n failedOnly?: boolean;\n}\n\n/**\n * One call inside a decision, and what it cost\n * generated from [TraceSpan](../../../../../apps/api/data/contracts/station/traces.types.ck)\n */\nexport interface TraceSpan {\n /** When the call ended, which is when its cost was known */\n at: DateTime;\n /** Dotted and stable: `job.run`, `plugin.invoke`, `llm.generate` */\n op: string;\n /** Which one: a plugin and its method, or a model */\n target?: string;\n /** How long it held, measured around the call rather than reported by it */\n ms: number;\n outcome: TraceOutcome;\n /** The failure, summarized to a shape rather than a stack */\n error?: string;\n /** Whatever this `op` is worth reading back: tokens, a finish reason, the bound it was given */\n detail?: Record<string, unknown>;\n}\n\n/** Rehydrates every wire-encoded scalar in a TraceSpan into its runtime type. Mutates and returns `raw`. */\nexport function reviveTraceSpan(raw: TraceSpan): TraceSpan {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['at'] = __dt(__o0['at'], 'TraceSpan.at');\n return raw;\n}\n\n/**\n * generated from [TracesPage](../../../../../apps/api/data/contracts/station/traces.types.ck)\n */\nexport interface TracesPage {\n /** Newest first */\n decisions: TraceDecision[];\n /** How many the window holds before `limit`, so a page can say it is showing a slice */\n total: number;\n /** How many calls were read to answer, which is the honest cost of this page */\n spans: number;\n}\n\n/** Rehydrates every wire-encoded scalar in a TracesPage into its runtime type. Mutates and returns `raw`. */\nexport function reviveTracesPage(raw: TracesPage): TracesPage {\n const __o0 = raw as unknown as Record<string, unknown>;\n {\n const __a1 = __o0['decisions'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveTraceDecision(__a1[__i2] as never);\n }\n }\n return raw;\n}\n\n/**\n * One decision, its calls, and the decisions on either side of it\n * generated from [TraceDetail](../../../../../apps/api/data/contracts/station/traces.types.ck)\n */\nexport interface TraceDetail {\n decision: TraceDecision;\n /** In the order they happened */\n spans: TraceSpan[];\n /** What enqueued this, when that decision is still inside the kept window */\n parent?: TraceDecision;\n /** What this one went on to enqueue */\n caused: TraceDecision[];\n}\n\n/** Rehydrates every wire-encoded scalar in a TraceDetail into its runtime type. Mutates and returns `raw`. */\nexport function reviveTraceDetail(raw: TraceDetail): TraceDetail {\n const __o0 = raw as unknown as Record<string, unknown>;\n reviveTraceDecision(__o0['decision'] as never);\n {\n const __a1 = __o0['spans'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveTraceSpan(__a1[__i2] as never);\n }\n }\n if (__o0['parent'] != null) {\n reviveTraceDecision(__o0['parent'] as never);\n }\n {\n const __a3 = __o0['caused'] as unknown[];\n for (let __i4 = 0; __i4 < __a3.length; __i4++) {\n reviveTraceDecision(__a3[__i4] as never);\n }\n }\n return raw;\n}\n","import type { SdkFetch } from '../sdk-options.js';\nimport { parseJson, buildQueryString } from '../sdk-options.js';\nimport type { LogPage, LogQuery, LogSourceList } from './types/logs.types.js';\nimport { reviveLogSourceList } from './types/logs.types.js';\nimport type { StationAttention, StationCheckup, StationReleases } from './types/station.types.js';\nimport { reviveStationCheckup, reviveStationReleases } from './types/station.types.js';\nimport type { TraceDetail, TracesPage, TracesQuery } from './types/traces.types.js';\nimport { reviveTraceDetail, reviveTracesPage } from './types/traces.types.js';\n\nexport class StationClient {\n constructor(private fetch: SdkFetch) {}\n\n /**\n * @name List logs\n * @description Every log this install has, present or not, with its size and when it was last written\n */\n async listLogs(): Promise<LogSourceList> {\n const result = await this.fetch(`/logs`, { method: 'GET' });\n return reviveLogSourceList(await parseJson<LogSourceList>(result));\n }\n\n /**\n * @name Read log\n * @description A tail of one log, newest first\n */\n async readLog(id: string, query?: LogQuery): Promise<LogPage> {\n const qs = buildQueryString(query);\n const result = await this.fetch(`/logs/${encodeURIComponent(id)}${qs}`, {\n method: 'GET',\n });\n return await parseJson<LogPage>(result);\n }\n\n /**\n * @name Download log\n * @description The retained log as a plain-text attachment, oldest first, as the file is written\n */\n async downloadLog(id: string): Promise<{ data: string; headers: { contentDisposition?: string } }> {\n const result = await this.fetch(`/logs/${encodeURIComponent(id)}/download`, { method: 'GET' });\n const data = await result.text();\n return { data, headers: { contentDisposition: result.headers.get('Content-Disposition') ?? undefined } };\n }\n\n /**\n * @name Read station attention\n * @description Everything wrong or waiting, worst first, each with the console page that can act on it\n */\n async readStationAttention(): Promise<StationAttention> {\n const result = await this.fetch(`/station/attention`, { method: 'GET' });\n return await parseJson<StationAttention>(result);\n }\n\n /**\n * @name Dismiss station attention\n * @description Accept an attention row as it stands, until something new joins it\n */\n async dismissStationAttention(code: string): Promise<void> {\n await this.fetch(`/station/attention/${encodeURIComponent(code)}/dismiss`, { method: 'POST' });\n }\n\n /**\n * @name Read station checkup\n * @description The loops the station runs and how much of the library it has looked at\n */\n async readStationCheckup(): Promise<StationCheckup> {\n const result = await this.fetch(`/station/checkup`, { method: 'GET' });\n return reviveStationCheckup(await parseJson<StationCheckup>(result));\n }\n\n /**\n * @name Read station releases\n * @description The releases this build contains and what each one changed, newest first\n */\n async readStationReleases(): Promise<StationReleases> {\n const result = await this.fetch(`/station/releases`, { method: 'GET' });\n return reviveStationReleases(await parseJson<StationReleases>(result));\n }\n\n /**\n * @name Check station releases\n * @description Asks GitHub for newer releases now, and answers with what the station then knows\n */\n async checkStationReleases(): Promise<StationReleases> {\n const result = await this.fetch(`/station/releases/check`, { method: 'POST' });\n return reviveStationReleases(await parseJson<StationReleases>(result));\n }\n\n /**\n * @name Read traces\n * @description Recent decisions, newest first, folded to one row each\n */\n async readTraces(query?: TracesQuery): Promise<TracesPage> {\n const qs = buildQueryString(query);\n const result = await this.fetch(`/traces${qs}`, {\n method: 'GET',\n });\n return reviveTracesPage(await parseJson<TracesPage>(result));\n }\n\n /**\n * @name Read trace\n * @description One decision: every call it made, and the decisions on either side of it\n */\n async readTrace(id: string): Promise<TraceDetail> {\n const result = await this.fetch(`/traces/${encodeURIComponent(id)}`, { method: 'GET' });\n return reviveTraceDetail(await parseJson<TraceDetail>(result));\n }\n}\n","import { DateTime } from 'luxon';\nconst __dt = (v: unknown, path: string): DateTime => {\n if (typeof v !== 'string') {\n throw new TypeError(`ContractKit: expected an ISO 8601 string at '${path}', received ${typeof v}.`);\n }\n const d = DateTime.fromISO(v);\n if (!d.isValid) throw new TypeError(`ContractKit: '${v}' at '${path}' is not a valid ISO 8601 datetime.`);\n return d;\n};\n\n/**\n * Which store, as a stable id the console can key off rather than a name it renders.\n * generated from [StorageStoreId](../../../../../apps/api/data/contracts/storage/storage.types.ck)\n */\nexport type StorageStoreId = 'tracks' | 'art' | 'segments' | 'voices';\n\n/**\n * One content store: what is on disk, and what the database says should be.\n *\n * The two halves are deliberately separate numbers rather than one reconciled figure. They disagree\n * in two directions and each direction means something different — a file nothing claims is what a\n * crash between writing bytes and writing a row leaves behind, and a row whose file is gone is what\n * an operator emptying a directory leaves. Reporting one number would hide both.\n * generated from [StorageStore](../../../../../apps/api/data/contracts/storage/storage.types.ck)\n */\nexport interface StorageStore {\n id: StorageStoreId;\n /** What to call it on a page */\n label: string;\n /** Where it is, so `du` and this can be compared */\n path: string;\n /** Files actually there */\n files: number;\n /** What they weigh */\n bytes: number;\n /** Rows pointing at a file. Absent when no table backs this store */\n rows?: number;\n /** What those rows say those files weigh. Absent where the table does not record a size */\n accountedBytes?: number;\n /** The limit an operator set, where the store has one. Absent means no limit */\n capBytes?: number;\n /** Files no row claims. Reported and never cleaned up automatically */\n orphanFiles: number;\n orphanBytes: number;\n /** Claims whose file is not there. The station re-fetches or re-renders these */\n rowsWithNoFile: number;\n}\n\nexport interface StorageStoreInput {}\n\n/**\n * Every store, plus the number an operator actually wants first.\n *\n * `readAt` is not decoration: the figures come from walking directories, which is real I/O on a\n * station holding tens of thousands of files, so the answer is cached for a short while and this is\n * what stops a page mistaking it for live.\n * generated from [StorageReport](../../../../../apps/api/data/contracts/storage/storage.types.ck)\n */\nexport interface StorageReport {\n readAt: DateTime;\n totalFiles: number;\n totalBytes: number;\n stores: StorageStore[];\n}\n\nexport interface StorageReportInput {\n stores: StorageStoreInput[];\n}\n\n/** Rehydrates every wire-encoded scalar in a StorageReport into its runtime type. Mutates and returns `raw`. */\nexport function reviveStorageReport(raw: StorageReport): StorageReport {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['readAt'] = __dt(__o0['readAt'], 'StorageReport.readAt');\n return raw;\n}\n","import type { SdkFetch } from '../sdk-options.js';\nimport { parseJson } from '../sdk-options.js';\nimport type { StorageReport } from './types/storage.types.js';\nimport { reviveStorageReport } from './types/storage.types.js';\n\nexport class StorageClient {\n constructor(private fetch: SdkFetch) {}\n\n /**\n * @name Read storage\n * @description What is on disk, per store, against what the database says should be\n */\n async readStorage(): Promise<StorageReport> {\n const result = await this.fetch(`/storage`, { method: 'GET' });\n return reviveStorageReport(await parseJson<StorageReport>(result));\n }\n}\n","import type { SdkFetch } from '../sdk-options.js';\nimport { bigIntReplacer, parseJson } from '../sdk-options.js';\nimport type {\n FetcherAuthorization,\n FetcherAuthorizationFinished,\n FetcherAuthorizationInput,\n FetcherAuthorizationStart,\n} from './types/stream.types.js';\n\nexport class StreamClient {\n constructor(private fetch: SdkFetch) {}\n\n /**\n * @name Get HLS playlist\n * @description One HLS playlist, and the tick that says somebody is still listening to it\n */\n async getHLSPlaylist(name: string): Promise<{ data: Blob; headers: { cacheControl?: string } }> {\n const result = await this.fetch(`/hls/${encodeURIComponent(name)}`, { method: 'GET' });\n const data = await result.blob();\n return { data, headers: { cacheControl: result.headers.get('cache-control') ?? undefined } };\n }\n\n /**\n * @name Get tune-in pls\n * @description The station's streams as a PLS playlist, MP3 first, for a player that takes a playlist file rather than a stream address\n */\n async getTuneInPls(): Promise<Blob> {\n const result = await this.fetch(`/listen.pls`, { method: 'GET' });\n return await result.blob();\n }\n\n /**\n * @name Get tune-in m3u\n * @description The station's streams as an M3U playlist, MP3 first, for a player that takes a playlist file rather than a stream address\n */\n async getTuneInM3u(): Promise<Blob> {\n const result = await this.fetch(`/listen.m3u`, { method: 'GET' });\n return await result.blob();\n }\n\n /**\n * @name Read fetcher authorization\n * @description What the track fetcher holds by way of a Spotify login, and whether an authorization is already waiting to be finished\n */\n async readFetcherAuthorization(): Promise<FetcherAuthorization> {\n const result = await this.fetch(`/stream/authorization`, { method: 'GET' });\n return await parseJson<FetcherAuthorization>(result);\n }\n\n /**\n * @name Start fetcher authorization\n * @description Starts the fetcher's one-time authorization and answers with the URL to open. Starting another replaces whichever was pending\n */\n async startFetcherAuthorization(): Promise<FetcherAuthorizationStart> {\n const result = await this.fetch(`/stream/authorization`, { method: 'POST' });\n return await parseJson<FetcherAuthorizationStart>(result);\n }\n\n /**\n * @name Finish fetcher authorization\n * @description Finishes an authorization from the address the operator's browser ended up at\n */\n async finishFetcherAuthorization(body: FetcherAuthorizationInput): Promise<FetcherAuthorizationFinished> {\n const result = await this.fetch(`/stream/authorization/complete`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<FetcherAuthorizationFinished>(result);\n }\n}\n","import type { SdkFetch } from '../sdk-options.js';\nimport { bigIntReplacer, parseJson, buildQueryString } from '../sdk-options.js';\nimport type { TopicInput, TopicKindList, TopicList, TopicQuery } from './types/topics.types.js';\n\nexport class TopicsClient {\n constructor(private fetch: SdkFetch) {}\n\n /**\n * @name List topics\n * @description Every subject this station has named, for one sort of break or for all of them\n */\n async listTopics(query?: TopicQuery): Promise<TopicList> {\n const qs = buildQueryString(query);\n const result = await this.fetch(`/topics${qs}`, {\n method: 'GET',\n });\n return await parseJson<TopicList>(result);\n }\n\n /**\n * @name Create topic\n * @description Names a new subject. Nothing uses it until something points at it\n */\n async createTopic(body: TopicInput): Promise<TopicList> {\n const result = await this.fetch(`/topics`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<TopicList>(result);\n }\n\n /**\n * @name List topic kinds\n * @description Which sorts of break have subjects, and the form each one's settings are edited with\n */\n async listTopicKinds(): Promise<TopicKindList> {\n const result = await this.fetch(`/topics/kinds`, { method: 'GET' });\n return await parseJson<TopicKindList>(result);\n }\n\n /**\n * @name Update topic\n * @description Rewrites one subject. A break already written keeps the words it was given\n */\n async updateTopic(id: string, body: TopicInput): Promise<TopicList> {\n const result = await this.fetch(`/topics/${encodeURIComponent(id)}`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<TopicList>(result);\n }\n\n /**\n * @name Delete topic\n * @description Removes a subject, and any band on the format clock that asked for it\n */\n async deleteTopic(id: string): Promise<TopicList> {\n const result = await this.fetch(`/topics/${encodeURIComponent(id)}`, { method: 'DELETE' });\n return await parseJson<TopicList>(result);\n }\n}\n","import { DateTime } from 'luxon';\nimport type { Pagination } from '../../shared/types/pagination.js';\nimport type { PaginationInput } from '../../shared/types/pagination.js';\nimport type { PaginationWithActive } from '../../shared/types/pagination.js';\nimport type { PaginationWithActiveInput } from '../../shared/types/pagination.js';\nimport type { PlatformRole } from '../../authentication/types/authentication.types.js';\nimport type { Session } from '../../authentication/types/authentication.types.js';\nimport { reviveSession } from '../../authentication/types/authentication.types.js';\nimport type { SessionInput } from '../../authentication/types/authentication.types.js';\n\nconst __dt = (v: unknown, path: string): DateTime => {\n if (typeof v !== 'string') {\n throw new TypeError(`ContractKit: expected an ISO 8601 string at '${path}', received ${typeof v}.`);\n }\n const d = DateTime.fromISO(v);\n if (!d.isValid) throw new TypeError(`ContractKit: '${v}' at '${path}' is not a valid ISO 8601 datetime.`);\n return d;\n};\n\n/**\n * Which people to list\n * generated from [UserQuery](../../../../../apps/api/data/contracts/users/users.types.ck)\n */\nexport interface UserQuery extends PaginationWithActive {\n /** Part of an email address */\n search?: string;\n /** Only people holding this role */\n role?: PlatformRole;\n}\n\nexport interface UserQueryInput extends PaginationWithActiveInput {\n /** Part of an email address */\n search?: string;\n /** Only people holding this role */\n role?: PlatformRole;\n}\n\n/**\n * A person with an account on the station\n * generated from [UserSummary](../../../../../apps/api/data/contracts/users/users.types.ck)\n */\nexport interface UserSummary {\n /** The person's account id */\n id: string;\n /** The address they sign in with. Absent for an account that has none, such as one made through a provider that shared no address */\n email?: string;\n /** The one role they hold. Absent for an account nobody has granted one */\n role?: PlatformRole;\n /** False once the account has been switched off. A switched-off person cannot sign in, and every session they held has ended */\n active: boolean;\n /** When the account was made */\n createdAt: DateTime;\n /** When they last signed in. Absent if they never have */\n lastSignInAt?: DateTime;\n /** Whether they have an authenticator app or a passkey, which the phone apps need to sign in with */\n hasStrongFactor: boolean;\n}\n\n/** Rehydrates every wire-encoded scalar in a UserSummary into its runtime type. Mutates and returns `raw`. */\nexport function reviveUserSummary(raw: UserSummary): UserSummary {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['createdAt'] = __dt(__o0['createdAt'], 'UserSummary.createdAt');\n if (__o0['lastSignInAt'] != null) {\n __o0['lastSignInAt'] = __dt(__o0['lastSignInAt'], 'UserSummary.lastSignInAt');\n }\n return raw;\n}\n\n/**\n * One way a person signs in. Never the secret itself\n * generated from [UserFactor](../../../../../apps/api/data/contracts/users/users.types.ck)\n */\nexport interface UserFactor {\n /** What kind of factor it is */\n method: 'email' | 'password' | 'authenticator' | 'fido' | 'oidc' | 'phone';\n /** Which factor of that kind */\n methodId: string;\n /** What it proves */\n kind: 'knowledge' | 'possession' | 'biometric';\n /** How it is shown, such as a masked address or the authenticator's name */\n label?: string;\n}\n\n/**\n * One time a person signed in\n * generated from [UserSignIn](../../../../../apps/api/data/contracts/users/users.types.ck)\n */\nexport interface UserSignIn {\n /** When */\n occurredAt: DateTime;\n /** The factor they signed in with */\n method: string;\n /** Whether a second factor was proved */\n mfaSatisfied: boolean;\n /** The address the request came from */\n ip?: string;\n /** The app or browser that asked */\n userAgent?: string;\n}\n\n/** Rehydrates every wire-encoded scalar in a UserSignIn into its runtime type. Mutates and returns `raw`. */\nexport function reviveUserSignIn(raw: UserSignIn): UserSignIn {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['occurredAt'] = __dt(__o0['occurredAt'], 'UserSignIn.occurredAt');\n return raw;\n}\n\n/**\n * The role a person should hold\n * generated from [UserRoleChange](../../../../../apps/api/data/contracts/users/users.types.ck)\n */\nexport interface UserRoleChange {\n /** Replaces whatever role they held */\n role: PlatformRole;\n}\n\n/**\n * One page of people\n * generated from [UserPage](../../../../../apps/api/data/contracts/users/users.types.ck)\n */\nexport interface UserPage {\n meta: Pagination;\n data: UserSummary[];\n}\n\nexport interface UserPageInput {\n meta: PaginationInput;\n data: UserSummary[];\n}\n\n/** Rehydrates every wire-encoded scalar in a UserPage into its runtime type. Mutates and returns `raw`. */\nexport function reviveUserPage(raw: UserPage): UserPage {\n const __o0 = raw as unknown as Record<string, unknown>;\n {\n const __a1 = __o0['data'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveUserSummary(__a1[__i2] as never);\n }\n }\n return raw;\n}\n\n/**\n * A person, with how they sign in and where they are signed in\n * generated from [UserDetail](../../../../../apps/api/data/contracts/users/users.types.ck)\n */\nexport interface UserDetail extends UserSummary {\n /** Every way they can sign in */\n factors: UserFactor[];\n /** Where they are signed in now */\n sessions: Session[];\n /** Their most recent sign-ins, newest first */\n signIns: UserSignIn[];\n}\n\nexport interface UserDetailInput extends UserSummary {\n /** Every way they can sign in */\n factors: UserFactor[];\n /** Where they are signed in now */\n sessions: SessionInput[];\n /** Their most recent sign-ins, newest first */\n signIns: UserSignIn[];\n}\n\n/** Rehydrates every wire-encoded scalar in a UserDetail into its runtime type. Mutates and returns `raw`. */\nexport function reviveUserDetail(raw: UserDetail): UserDetail {\n const __o0 = raw as unknown as Record<string, unknown>;\n reviveUserSummary(raw as never);\n {\n const __a1 = __o0['sessions'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveSession(__a1[__i2] as never);\n }\n }\n {\n const __a3 = __o0['signIns'] as unknown[];\n for (let __i4 = 0; __i4 < __a3.length; __i4++) {\n reviveUserSignIn(__a3[__i4] as never);\n }\n }\n return raw;\n}\n","import { DateTime } from 'luxon';\nimport type { FidoFactorAttestation } from '../../authentication/types/registration.types.js';\nimport type { PlatformRole } from '../../authentication/types/authentication.types.js';\nimport type { PublicKeyCredentialWithAttestation } from '../../authentication/types/authentication.types.js';\n\nconst __dt = (v: unknown, path: string): DateTime => {\n if (typeof v !== 'string') {\n throw new TypeError(`ContractKit: expected an ISO 8601 string at '${path}', received ${typeof v}.`);\n }\n const d = DateTime.fromISO(v);\n if (!d.isValid) throw new TypeError(`ContractKit: '${v}' at '${path}' is not a valid ISO 8601 datetime.`);\n return d;\n};\n\n/**\n * Where an invitation stands. `expired` is a pending invitation whose time ran out\n * generated from [InvitationState](../../../../../apps/api/data/contracts/users/invitations.types.ck)\n */\nexport type InvitationState = 'pending' | 'accepted' | 'revoked' | 'expired';\n\n/**\n * Invite somebody by their address\n * generated from [InvitationCreate](../../../../../apps/api/data/contracts/users/invitations.types.ck)\n */\nexport interface InvitationCreate {\n /** The address the account will have */\n email: string;\n /** The role the account will hold */\n role: PlatformRole;\n /** Email the link to the address too. Refused with a 503, and nothing made, when the station has no mail server */\n send?: boolean;\n}\n\n/**\n * An invitation's link token, as it appears after `#` on the invite page\n * generated from [InvitationToken](../../../../../apps/api/data/contracts/users/invitations.types.ck)\n */\nexport interface InvitationToken {\n /** The token */\n token: string;\n}\n\n/**\n * What an open invitation is for, shown to the person before they accept\n * generated from [InvitationDetails](../../../../../apps/api/data/contracts/users/invitations.types.ck)\n */\nexport interface InvitationDetails {\n /** The address the account will have */\n email: string;\n /** The role it will hold */\n role: PlatformRole;\n /** What the station calls itself */\n stationName: string;\n /** When the link stops working */\n expiresAt: DateTime;\n}\n\n/** Rehydrates every wire-encoded scalar in a InvitationDetails into its runtime type. Mutates and returns `raw`. */\nexport function reviveInvitationDetails(raw: InvitationDetails): InvitationDetails {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['expiresAt'] = __dt(__o0['expiresAt'], 'InvitationDetails.expiresAt');\n return raw;\n}\n\n/**\n * How the person will prove it is them after their password: an authenticator app, or a passkey\n * generated from [InvitationSecondStep](../../../../../apps/api/data/contracts/users/invitations.types.ck)\n */\nexport type InvitationSecondStep = 'authenticator' | 'fido';\n\n/**\n * An authenticator app to scan, for an invitation being accepted\n * generated from [InvitationAuthenticatorSetup](../../../../../apps/api/data/contracts/users/invitations.types.ck)\n */\nexport interface InvitationAuthenticatorSetup {\n /** Discriminator */\n method: 'authenticator';\n /** Send this back with the first code */\n registrationId: string;\n /** The key, for an app that cannot scan */\n secret: string;\n /** The `otpauth://` address the QR code holds */\n uri: string;\n /** The QR code, as a data URL */\n qrCode: string;\n}\n\n/**\n * A passkey to make, for an invitation being accepted\n * generated from [InvitationPasskeySetup](../../../../../apps/api/data/contracts/users/invitations.types.ck)\n */\nexport interface InvitationPasskeySetup {\n /** Discriminator */\n method: 'fido';\n /** Send this back with the credential */\n registrationId: string;\n /** What to hand `navigator.credentials.create` */\n attestation: FidoFactorAttestation;\n}\n\n/**\n * Accept with the first code from the authenticator app\n * generated from [InvitationAcceptWithAuthenticator](../../../../../apps/api/data/contracts/users/invitations.types.ck)\n */\nexport interface InvitationAcceptWithAuthenticator {\n /** Discriminator */\n method: 'authenticator';\n /** The invitation's token */\n token: string;\n /** The same password as at the start */\n password: string;\n /** From the start */\n registrationId: string;\n /** The first code the app shows */\n code: string;\n}\n\n/**\n * Accept with the passkey the browser just made\n * generated from [InvitationAcceptWithPasskey](../../../../../apps/api/data/contracts/users/invitations.types.ck)\n */\nexport interface InvitationAcceptWithPasskey {\n /** Discriminator */\n method: 'fido';\n /** The invitation's token */\n token: string;\n /** The same password as at the start */\n password: string;\n /** From the start */\n registrationId: string;\n /** What `navigator.credentials.create` answered */\n credential: PublicKeyCredentialWithAttestation;\n}\n\n/**\n * The account made from an invitation. Sign in with it as usual\n * generated from [InvitationAccepted](../../../../../apps/api/data/contracts/users/invitations.types.ck)\n */\nexport interface InvitationAccepted {\n /** The address to sign in with */\n email: string;\n /** The role it holds */\n role: PlatformRole;\n}\n\n/**\n * An invitation for somebody to take an account on the station\n * generated from [Invitation](../../../../../apps/api/data/contracts/users/invitations.types.ck)\n */\nexport interface Invitation {\n /** The invitation's id */\n id: string;\n /** The address the account will have. The person cannot change it while accepting */\n email: string;\n /** The role the account will hold */\n role: PlatformRole;\n /** Where it stands */\n state: InvitationState;\n /** When it was made */\n createdAt: DateTime;\n /** When the link stops working, if nobody has used it */\n expiresAt: DateTime;\n /** The address of the admin who made it. Absent once their account is gone */\n invitedBy?: string;\n /** When somebody accepted it */\n acceptedAt?: DateTime;\n /** When it was withdrawn, by an admin or by a newer invitation to the same address */\n revokedAt?: DateTime;\n /** The invitation itself, only while it is pending. Put it after `#` on the station's `/invite` page, as `/invite#<token>`. Anyone holding it can claim the account, so show it only to the person invited */\n token?: string;\n}\n\n/** Rehydrates every wire-encoded scalar in a Invitation into its runtime type. Mutates and returns `raw`. */\nexport function reviveInvitation(raw: Invitation): Invitation {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['createdAt'] = __dt(__o0['createdAt'], 'Invitation.createdAt');\n __o0['expiresAt'] = __dt(__o0['expiresAt'], 'Invitation.expiresAt');\n if (__o0['acceptedAt'] != null) {\n __o0['acceptedAt'] = __dt(__o0['acceptedAt'], 'Invitation.acceptedAt');\n }\n if (__o0['revokedAt'] != null) {\n __o0['revokedAt'] = __dt(__o0['revokedAt'], 'Invitation.revokedAt');\n }\n return raw;\n}\n\n/**\n * Choose a password and a second step. Nothing is saved yet\n * generated from [InvitationAcceptStart](../../../../../apps/api/data/contracts/users/invitations.types.ck)\n */\nexport interface InvitationAcceptStart {\n /** The invitation's token */\n token: string;\n /** The password the account will have. Refused here if it is too weak, so the person learns before setting anything else up */\n password: string;\n /** The second step to set up */\n method: InvitationSecondStep;\n}\n\n/**\n * generated from [InvitationAcceptStartResponse](../../../../../apps/api/data/contracts/users/invitations.types.ck)\n */\nexport type InvitationAcceptStartResponse = InvitationAuthenticatorSetup | InvitationPasskeySetup;\n\n/**\n * generated from [InvitationAccept](../../../../../apps/api/data/contracts/users/invitations.types.ck)\n */\nexport type InvitationAccept = InvitationAcceptWithAuthenticator | InvitationAcceptWithPasskey;\n\n/**\n * The station's invitations, newest first\n * generated from [InvitationList](../../../../../apps/api/data/contracts/users/invitations.types.ck)\n */\nexport interface InvitationList {\n data: Invitation[];\n}\n\n/** Rehydrates every wire-encoded scalar in a InvitationList into its runtime type. Mutates and returns `raw`. */\nexport function reviveInvitationList(raw: InvitationList): InvitationList {\n const __o0 = raw as unknown as Record<string, unknown>;\n {\n const __a1 = __o0['data'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveInvitation(__a1[__i2] as never);\n }\n }\n return raw;\n}\n","import type {\n Invitation,\n InvitationAccept,\n InvitationAcceptStart,\n InvitationAcceptStartResponse,\n InvitationAccepted,\n InvitationCreate,\n InvitationDetails,\n InvitationList,\n InvitationToken,\n} from './types/invitations.types.js';\nimport { reviveInvitation, reviveInvitationDetails, reviveInvitationList } from './types/invitations.types.js';\nimport type { SdkFetch } from '../sdk-options.js';\nimport { bigIntReplacer, parseJson } from '../sdk-options.js';\n\n/**\n * generated from [invitations.ck](../../../../apps/api/data/contracts/users/invitations.ck)\n */\nexport class UsersInvitationsClient {\n constructor(private fetch: SdkFetch) {}\n\n /**\n * @name List invitations\n * @description Every invitation, newest first, with the link of each one still open\n */\n async listInvitations(): Promise<InvitationList> {\n const result = await this.fetch(`/invitations`, { method: 'GET' });\n return reviveInvitationList(await parseJson<InvitationList>(result));\n }\n\n /**\n * @name Create invitation\n * @description Invite somebody into a role. An open invitation to the same address is withdrawn first, so this is also how one is sent again. Refused for an address that already has an account\n */\n async createInvitation(body: InvitationCreate): Promise<Invitation> {\n const result = await this.fetch(`/invitations`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return reviveInvitation(await parseJson<Invitation>(result));\n }\n\n /**\n * @name Revoke invitation\n * @description Withdraw an invitation. Its link stops working at once. Nothing is deleted: it stays in the list as withdrawn\n */\n async revokeInvitation(id: string): Promise<Invitation> {\n const result = await this.fetch(`/invitations/${encodeURIComponent(id)}`, { method: 'DELETE' });\n return reviveInvitation(await parseJson<Invitation>(result));\n }\n\n /**\n * @name Read invitation\n * @description What an open invitation is for: the address, the role and the station. Changes nothing\n */\n async readInvitation(body: InvitationToken): Promise<InvitationDetails> {\n const result = await this.fetch(`/invitations/accept/details`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return reviveInvitationDetails(await parseJson<InvitationDetails>(result));\n }\n\n /**\n * @name Start accepting invitation\n * @description Check the password and start setting up the second step. Nothing is saved, and starting again replaces the setup\n */\n async startAcceptingInvitation(body: InvitationAcceptStart): Promise<InvitationAcceptStartResponse> {\n const result = await this.fetch(`/invitations/accept/start`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<InvitationAcceptStartResponse>(result);\n }\n\n /**\n * @name Accept invitation\n * @description Accept: make the account with its password, its second step and its role, all at once, and spend the invitation\n */\n async acceptInvitation(body: InvitationAccept): Promise<InvitationAccepted> {\n const result = await this.fetch(`/invitations/accept`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<InvitationAccepted>(result);\n }\n}\n","import type { SdkFetch } from '../sdk-options.js';\nimport { bigIntReplacer, parseJson, buildQueryString } from '../sdk-options.js';\nimport type { UserDetail, UserPage, UserQueryInput, UserRoleChange, UserSummary } from './types/users.types.js';\nimport { reviveUserDetail, reviveUserPage, reviveUserSummary } from './types/users.types.js';\nimport { UsersInvitationsClient } from './invitations.client.js';\n\nexport class UsersClient {\n readonly invitations: UsersInvitationsClient;\n\n constructor(private fetch: SdkFetch) {\n this.invitations = new UsersInvitationsClient(fetch);\n }\n\n /**\n * @name List users\n * @description The station's people, one page at a time, ordered by when their account was made\n */\n async listUsers(query?: UserQueryInput): Promise<UserPage> {\n const qs = buildQueryString(query);\n const result = await this.fetch(`/users${qs}`, {\n method: 'GET',\n });\n return reviveUserPage(await parseJson<UserPage>(result));\n }\n\n /**\n * @name Get user\n * @description One person, with every way they sign in, where they are signed in and their recent sign-ins\n */\n async getUser(id: string): Promise<UserDetail> {\n const result = await this.fetch(`/users/${encodeURIComponent(id)}`, { method: 'GET' });\n return reviveUserDetail(await parseJson<UserDetail>(result));\n }\n\n /**\n * @name Change user role\n * @description Give a person a different role. They hold exactly one, so the role they had is taken away. Refused for your own account, and for the last admin\n */\n async changeUserRole(id: string, body: UserRoleChange): Promise<UserSummary> {\n const result = await this.fetch(`/users/${encodeURIComponent(id)}/role`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return reviveUserSummary(await parseJson<UserSummary>(result));\n }\n\n /**\n * @name Deactivate user\n * @description Switch a person off. They are signed out everywhere and cannot sign in, and their API keys, connected apps and chat links stop working, until they are switched back on. Nothing is deleted. Refused for your own account, and for the last admin\n */\n async deactivateUser(id: string): Promise<UserSummary> {\n const result = await this.fetch(`/users/${encodeURIComponent(id)}/deactivate`, { method: 'POST' });\n return reviveUserSummary(await parseJson<UserSummary>(result));\n }\n\n /**\n * @name Reactivate user\n * @description Switch a person back on. They sign in as they did before, and their API keys, connected apps and chat links work again\n */\n async reactivateUser(id: string): Promise<UserSummary> {\n const result = await this.fetch(`/users/${encodeURIComponent(id)}/reactivate`, { method: 'POST' });\n return reviveUserSummary(await parseJson<UserSummary>(result));\n }\n\n /**\n * @name Sign out user\n * @description Sign a person out everywhere. They can sign straight back in\n */\n async signOutUser(id: string): Promise<void> {\n await this.fetch(`/users/${encodeURIComponent(id)}/sign-out`, { method: 'POST' });\n }\n\n /**\n * @name Reset user MFA\n * @description Remove a person's authenticator apps and passkeys and sign them out everywhere, for when they have lost the device. They sign in with their password and set a new one up\n */\n async resetUserMFA(id: string): Promise<void> {\n await this.fetch(`/users/${encodeURIComponent(id)}/mfa/reset`, { method: 'POST' });\n }\n}\n","import type { SdkOptions } from './sdk-options.js';\nimport { createSdkFetch } from './sdk-options.js';\nimport { ActivityClient } from './activity/activity.client.js';\nimport { ArtClient } from './art/art.client.js';\nimport { AuthenticationClient } from './authentication/authentication.client.js';\nimport { CatalogClient } from './catalog/catalog.client.js';\nimport { ChartsClient } from './charts/charts.client.js';\nimport { DirectorClient } from './director/director.client.js';\nimport { EventsClient } from './events/events.client.js';\nimport { HistoryClient } from './history/history.client.js';\nimport { LanguagesClient } from './languages/languages.client.js';\nimport { MessagingClient } from './messaging/messaging.client.js';\nimport { MetricsClient } from './metrics/metrics.client.js';\nimport { NarrationsClient } from './narrations/narrations.client.js';\nimport { NewsClient } from './news/news.client.js';\nimport { NowplayingClient } from './nowplaying/nowplaying.client.js';\nimport { OauthClient } from './oauth/oauth.client.js';\nimport { OnboardingClient } from './onboarding/onboarding.client.js';\nimport { OutputsClient } from './outputs/outputs.client.js';\nimport { PersonasClient } from './personas/personas.client.js';\nimport { PlaylistsClient } from './playlists/playlists.client.js';\nimport { PlayoutClient } from './playout/playout.client.js';\nimport { PluginsClient } from './plugins/plugins.client.js';\nimport { PodcastsClient } from './podcasts/podcasts.client.js';\nimport { ProductionsClient } from './productions/productions.client.js';\nimport { RenderClient } from './render/render.client.js';\nimport { RequestsClient } from './requests/requests.client.js';\nimport { ScheduleClient } from './schedule/schedule.client.js';\nimport { SettingsClient } from './settings/settings.client.js';\nimport { StationClient } from './station/station.client.js';\nimport { StorageClient } from './storage/storage.client.js';\nimport { StreamClient } from './stream/stream.client.js';\nimport { TopicsClient } from './topics/topics.client.js';\nimport { UsersClient } from './users/users.client.js';\n\nexport class DeadairSdk {\n readonly activity: ActivityClient;\n readonly art: ArtClient;\n readonly authentication: AuthenticationClient;\n readonly catalog: CatalogClient;\n readonly charts: ChartsClient;\n readonly director: DirectorClient;\n readonly events: EventsClient;\n readonly history: HistoryClient;\n readonly languages: LanguagesClient;\n readonly messaging: MessagingClient;\n readonly metrics: MetricsClient;\n readonly narrations: NarrationsClient;\n readonly news: NewsClient;\n readonly nowplaying: NowplayingClient;\n readonly oauth: OauthClient;\n readonly onboarding: OnboardingClient;\n readonly outputs: OutputsClient;\n readonly personas: PersonasClient;\n readonly playlists: PlaylistsClient;\n readonly playout: PlayoutClient;\n readonly plugins: PluginsClient;\n readonly podcasts: PodcastsClient;\n readonly productions: ProductionsClient;\n readonly render: RenderClient;\n readonly requests: RequestsClient;\n readonly schedule: ScheduleClient;\n readonly settings: SettingsClient;\n readonly station: StationClient;\n readonly storage: StorageClient;\n readonly stream: StreamClient;\n readonly topics: TopicsClient;\n readonly users: UsersClient;\n\n constructor(options: SdkOptions) {\n const sdkFetch = options.fetch ?? createSdkFetch(options);\n this.activity = new ActivityClient(sdkFetch);\n this.art = new ArtClient(sdkFetch);\n this.authentication = new AuthenticationClient(sdkFetch);\n this.catalog = new CatalogClient(sdkFetch);\n this.charts = new ChartsClient(sdkFetch);\n this.director = new DirectorClient(sdkFetch);\n this.events = new EventsClient(sdkFetch);\n this.history = new HistoryClient(sdkFetch);\n this.languages = new LanguagesClient(sdkFetch);\n this.messaging = new MessagingClient(sdkFetch);\n this.metrics = new MetricsClient(sdkFetch);\n this.narrations = new NarrationsClient(sdkFetch);\n this.news = new NewsClient(sdkFetch);\n this.nowplaying = new NowplayingClient(sdkFetch);\n this.oauth = new OauthClient(sdkFetch);\n this.onboarding = new OnboardingClient(sdkFetch);\n this.outputs = new OutputsClient(sdkFetch);\n this.personas = new PersonasClient(sdkFetch);\n this.playlists = new PlaylistsClient(sdkFetch);\n this.playout = new PlayoutClient(sdkFetch);\n this.plugins = new PluginsClient(sdkFetch);\n this.podcasts = new PodcastsClient(sdkFetch);\n this.productions = new ProductionsClient(sdkFetch);\n this.render = new RenderClient(sdkFetch);\n this.requests = new RequestsClient(sdkFetch);\n this.schedule = new ScheduleClient(sdkFetch);\n this.settings = new SettingsClient(sdkFetch);\n this.station = new StationClient(sdkFetch);\n this.storage = new StorageClient(sdkFetch);\n this.stream = new StreamClient(sdkFetch);\n this.topics = new TopicsClient(sdkFetch);\n this.users = new UsersClient(sdkFetch);\n }\n}\n"],"mappings":"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","names":["SdkError","Error","status","statusText","body","headers","name","bigIntReplacer","_","value","toString","bigIntReviver","test","BigInt","slice","readContentType","res","get","split","trim","randomRequestId","crypto","randomUUID","bytes","getRandomValues","Uint8Array","hex","Array","from","b","padStart","join","createSdkFetch","options","getRequestId","requestIdFactory","url","init","baseHeaders","fetch","baseUrl","ok","expectStatuses","includes","text","JSON","parse","buildQueryString","query","searchParams","URLSearchParams","k","v","Object","entries","undefined","isArray","item","append","String","set","qs","buildHeaders","out","map","parseBigIntHeader","replace","stringify","sseRequestHeaders","Accept","lastEventId","parseSse","data","iterated","events","reader","pipeThrough","TextDecoderStream","getReader","buffer","chunk","read","done","end","search","length","line","startsWith","colon","indexOf","field","push","cancel","catch","Symbol","asyncIterator","parseJson","parseJsonWithBigInt","DateTime","__dt","v","path","TypeError","d","DateTime","fromISO","isValid","reviveActivityEntry","raw","__o0","reviveActivityPage","__a1","__i2","length","ActivityClient","fetch","readActivity","query","qs","buildQueryString","result","method","reviveActivityPage","parseJson","ArtClient","fetch","listBreakArtwork","result","method","parseJson","replaceBreakArtwork","kind","body","encodeURIComponent","revertBreakArtwork","getSourceArt","token","expectStatuses","status","contentType","readContentType","data","blob","headers","cacheControl","get","undefined","etag","getSourceArtFile","filename","getArt","id","getArtFile","listPersonaPortraits","replacePersonaPortrait","personaId","removePersonaPortrait","DateTime","__dt","v","path","TypeError","d","DateTime","fromISO","isValid","reviveAuthenticationRegistration","raw","__o0","reviveFactorChallengePhoneStartResponse","reviveFactorChallengePhoneStartResponseOutput","reviveFactorChallengeEmailStartResponse","reviveFactorChallengeEmailStartResponseOutput","reviveSessionFactor","reviveLogin","reviveBaseAuthenticationLoginStartResponse","reviveSession","__a1","__i2","length","reviveApiKey","reviveApiKeyCreate","reviveCodeAuthenticationLoginStartResponse","reviveLinkAuthenticationLoginStartResponse","reviveOidcAuthenticationLoginStartResponse","reviveMfaRequiredResponse","reviveMfaRequiredResponseOutput","reviveFidoAuthenticationLoginStartResponse","reviveFactorChallengeFidoStartResponse","reviveFactorChallengeFidoStartResponseOutput","reviveApiKeyList","reviveApiKeyIssued","reviveStepUpStartResponse","__v","__d0","reviveStepUpStartResponseOutput","reviveAuthenticationTokenResponse","reviveAuthenticationTokenResponseOutput","reviveAuthenticationLoginStartResponse","reviveFactorChallengeStartResponse","reviveFactorChallengeStartResponseOutput","AuthenticationApikeysClient","fetch","listAPIKeys","result","method","reviveApiKeyList","parseJson","createAPIKey","body","headers","JSON","stringify","bigIntReplacer","reviveApiKeyIssued","rotateAPIKey","id","encodeURIComponent","revokeAPIKey","DateTime","__dt","v","path","TypeError","d","DateTime","fromISO","isValid","revivePhoneFactorRegistrationResponse","raw","__o0","reviveEmailFactorRegistrationResponse","reviveAuthenticatorFactorRegistrationResponse","reviveOidcFactorRegistrationResponse","reviveMfaEnrollPhoneStartResponse","reviveFidoFactorRegistrationResponse","reviveMfaEnrollFidoStartResponse","reviveAuthenticationFactorRegistrationResponse","__v","__d0","AuthenticationFactorsClient","fetch","listFactors","result","method","parseJson","registerFactor","body","headers","JSON","stringify","bigIntReplacer","reviveAuthenticationFactorRegistrationResponse","setPassword","verifyFactorRegistration","startFactorChallenge","reviveFactorChallengeStartResponseOutput","startMFAChallenge","reviveStepUpStartResponseOutput","removeFactor","methodId","encodeURIComponent","AuthenticationSessionsClient","fetch","logout","method","readSession","result","parseJson","AuthenticationClient","apikeys","factors","sessions","fetch","AuthenticationApikeysClient","AuthenticationFactorsClient","AuthenticationSessionsClient","requestToken","body","options","__contentType","contentType","__serialized","URLSearchParams","toString","JSON","stringify","bigIntReplacer","result","method","headers","reviveAuthenticationTokenResponseOutput","parseJson","registerLogin","reviveAuthenticationRegistration","verifyLoginRegistration","startLogin","reviveAuthenticationLoginStartResponse","listSignInProviders","DateTime","__dt","v","path","TypeError","d","DateTime","fromISO","isValid","reviveTrackBinding","raw","__o0","reviveTrackAnalysis","reviveTrackPlay","reviveFactClaim","reviveTrackDetail","__a1","__i2","length","__a3","__i4","reviveTrackLyricsSource","reviveTrackEnrichmentSource","reviveArtistEnrichmentSource","reviveAlbumEnrichmentSource","reviveTrackLyricsSources","reviveTrackEnrichmentDetail","reviveArtistEnrichmentDetail","reviveAlbumEnrichmentDetail","CatalogClient","fetch","listArtists","query","qs","buildQueryString","result","method","parseJson","getArtist","id","encodeURIComponent","getArtistEnrichment","reviveArtistEnrichmentDetail","listArtistAlbums","rateArtist","body","headers","JSON","stringify","bigIntReplacer","listAlbums","getAlbum","getAlbumEnrichment","reviveAlbumEnrichmentDetail","listAlbumTracks","rateAlbum","getTrack","reviveTrackDetail","clearTrackAudio","clearTrackAnalysis","getVocalMarkers","setVocalMarkers","clearVocalMarkers","getTrackLyrics","listTrackLyricsSources","reviveTrackLyricsSources","retryTrackAudio","offerTrackCopiesAgain","getTrackEnrichment","reviveTrackEnrichmentDetail","clearTrackEnrichment","listTracks","rateTrack","ChartsClient","fetch","listCharts","result","method","parseJson","readChart","id","query","qs","buildQueryString","encodeURIComponent","DateTime","__dt","v","path","TypeError","d","DateTime","fromISO","isValid","reviveBlockRule","raw","__o0","reviveGenreSteer","reviveBlockRuleList","__a1","__i2","length","reviveGenreSteerReading","DirectorClient","fetch","listClockBands","result","method","parseJson","createClockBand","body","headers","JSON","stringify","bigIntReplacer","updateClockBand","id","encodeURIComponent","deleteClockBand","getStationAir","putTheStationOnAir","setTheAirMode","getTheRunningOrder","recastTheBroadcast","extendTheRunningOrder","replanTheRunningOrder","requestABreak","previewAnArtistRoute","holdTheStationAgainstTheSchedule","releaseTheStationToTheSchedule","shuffleTheRunningOrder","addASegmentToTheRunningOrder","addARecordToTheRunningOrder","moveARunningOrderItem","itemId","removeARunningOrderItem","skipToARunningOrderItem","listNeverPlayRules","reviveBlockRuleList","addANeverPlayRule","readTheGenreSteer","reviveGenreSteerReading","steerTowardGenres","stopSteering","changeANeverPlayRule","removeANeverPlayRule","DateTime","__dt","v","path","TypeError","d","DateTime","fromISO","isValid","reviveEventDestination","raw","__o0","reviveEventDelivery","reviveEventDestinationList","__a1","__i2","length","reviveEventDestinationCreated","__v","reviveEventDeliveryList","EventsClient","fetch","listEventTypes","result","method","parseJson","listEventDestinations","reviveEventDestinationList","createEventDestination","body","headers","JSON","stringify","bigIntReplacer","reviveEventDestinationCreated","updateEventDestination","id","encodeURIComponent","reviveEventDestination","deleteEventDestination","rotateEventDestinationSecret","testEventDestination","listEventDeliveries","reviveEventDeliveryList","DateTime","__dt","v","path","TypeError","d","DateTime","fromISO","isValid","reviveHistoryEntry","raw","__o0","reviveHistoryPage","__a1","__i2","length","HistoryClient","fetch","readHistory","query","qs","buildQueryString","result","method","reviveHistoryPage","parseJson","DateTime","__dt","v","path","TypeError","d","DateTime","fromISO","isValid","reviveConsoleLanguage","raw","__o0","reviveConsoleLanguageList","__a1","__i2","length","LanguagesClient","fetch","getMyConsoleLanguage","result","method","parseJson","chooseMyConsoleLanguage","body","headers","JSON","stringify","bigIntReplacer","listConsoleLanguages","reviveConsoleLanguageList","getConsoleLanguage","locale","encodeURIComponent","importConsoleLanguage","removeConsoleLanguage","DateTime","__dt","v","path","TypeError","d","DateTime","fromISO","isValid","reviveMessagingLinkCode","raw","__o0","reviveMessagingLink","reviveMessagingLinkList","__a1","__i2","length","MessagingClient","fetch","listMessagingLinks","result","method","reviveMessagingLinkList","parseJson","createMessagingLinkCode","reviveMessagingLinkCode","removeMessagingLink","pluginId","platformUserId","encodeURIComponent","DateTime","__dt","v","path","TypeError","d","DateTime","fromISO","isValid","reviveMetricSeriesQuery","raw","__o0","reviveMetricPoint","reviveMetricName","reviveMetricSeries","__a1","__i2","length","reviveMetricNames","reviveMetricSeriesPage","MetricsClient","fetch","readMetricSeries","query","qs","buildQueryString","result","method","reviveMetricSeriesPage","parseJson","readMetricNames","reviveMetricNames","NarrationsClient","fetch","listSeries","result","method","parseJson","listPieces","query","qs","buildQueryString","renderPiece","id","encodeURIComponent","refreshNarrations","NewsClient","fetch","listFeeds","result","method","parseJson","readNews","query","qs","buildQueryString","NowplayingClient","fetch","getNowPlaying","result","method","parseJson","getNowPlayingLyrics","DateTime","__dt","v","path","TypeError","d","DateTime","fromISO","isValid","reviveOAuthGrant","raw","__o0","reviveOAuthClientSummary","reviveOAuthGrantList","__a1","__i2","length","reviveOAuthClientList","reviveOAuthClientIssued","OauthClient","fetch","describeAuthorizationRequest","body","result","method","headers","JSON","stringify","bigIntReplacer","parseJson","approveAuthorizationRequest","denyAuthorizationRequest","listOAuthClients","reviveOAuthClientList","createOAuthClient","reviveOAuthClientIssued","revokeOAuthClient","clientId","encodeURIComponent","listOAuthGrants","reviveOAuthGrantList","revokeOAuthGrant","id","OnboardingClient","fetch","getOnboardingRequirements","result","method","parseJson","submitOnboardingRequirement","body","headers","JSON","stringify","bigIntReplacer","DateTime","__dt","v","path","TypeError","d","DateTime","fromISO","isValid","reviveOutputCast","raw","__o0","reviveOutputCastList","__a1","__i2","length","OutputsClient","fetch","listOutputDevices","result","method","parseJson","listCasts","reviveOutputCastList","startCast","body","headers","JSON","stringify","bigIntReplacer","reviveOutputCast","stopCast","pluginId","deviceId","encodeURIComponent","PersonasClient","fetch","listPersonaAuditions","id","result","encodeURIComponent","method","parseJson","startPersonaAudition","body","headers","JSON","stringify","bigIntReplacer","getPersonaAudition","auditionId","cancelPersonaAudition","listPersonas","createPersona","generatePersona","restoreStationPersonas","exportPersonas","data","contentDisposition","get","undefined","exportPersona","previewPersonaImport","query","qs","buildQueryString","importPersonas","updatePersona","deletePersona","setTheStationHost","listPersonaNotes","writePersonaNote","updatePersonaNote","noteId","deletePersonaNote","setPersonaNoteState","listPersonaStories","writePersonaStory","updatePersonaStory","storyId","deletePersonaStory","setPersonaStoryState","addPersonaStoryDetail","updatePersonaStoryDetail","detailId","deletePersonaStoryDetail","setPersonaStoryDetailState","rehearsePersona","addPersonaStoryBeat","updatePersonaStoryBeat","beatId","deletePersonaStoryBeat","setPersonaStoryBeatState","readPersonaMemory","previewPersonaMemoryRollback","rollBackPersonaMemory","DateTime","__dt","v","path","TypeError","d","DateTime","fromISO","isValid","reviveCatalogPlaylistSource","raw","__o0","reviveCatalogPlaylistPage","__a1","__i2","length","DateTime","__dt","v","path","TypeError","d","DateTime","fromISO","isValid","reviveStationPlaylist","raw","__o0","reviveStationPlaylistList","__a1","__i2","length","reviveStationPlaylistDetail","revivePlaylistImportResult","PlaylistsClient","fetch","listImportablePlaylists","result","method","reviveCatalogPlaylistPage","parseJson","getPlaylistTracks","pluginId","playlistId","encodeURIComponent","hidePlaylist","showPlaylist","refreshPlaylists","refreshPlaylist","listStationPlaylists","reviveStationPlaylistList","getStationPlaylist","id","reviveStationPlaylistDetail","updateStationPlaylist","body","headers","JSON","stringify","bigIntReplacer","reviveStationPlaylist","deleteStationPlaylist","fillStationPlaylist","exportStationPlaylist","data","contentDisposition","get","undefined","previewPlaylistImport","importPlaylist","revivePlaylistImportResult","PlayoutClient","fetch","getPlayoutStatus","result","method","parseJson","playAPlaylist","body","headers","JSON","stringify","bigIntReplacer","playAStationPlaylist","playAnAlbum","playAChart","skipTheCurrentItem","startPlayout","stopPlayout","DateTime","__dt","v","path","TypeError","d","DateTime","fromISO","isValid","revivePluginSummary","raw","__o0","revivePluginImportResult","__a1","__i2","length","revivePluginDetail","PluginsClient","fetch","listPlugins","result","method","parseJson","map","revivePluginSummary","listPluginGrants","listCapabilityProviders","rescanPlugins","importPlugin","body","revivePluginImportResult","getPlugin","id","encodeURIComponent","revivePluginDetail","removePlugin","updatePluginConfiguration","headers","JSON","stringify","bigIntReplacer","enablePlugin","disablePlugin","decidePluginGrant","reloadPlugin","testPluginConnection","suggestPluginConfigOptions","getPluginLogs","query","qs","buildQueryString","downloadPluginLogs","data","text","contentDisposition","get","undefined","setPluginLogLevel","startPluginOAuthAuthorization","disconnectPluginOAuth","completePluginOAuthAuthorization","DateTime","__dt","v","path","TypeError","d","DateTime","fromISO","isValid","reviveProduction","raw","__o0","reviveProductionRequest","reviveProductionList","__a1","__i2","length","DateTime","__dt","v","path","TypeError","d","DateTime","fromISO","isValid","reviveOwnShow","raw","__o0","reviveOwnEpisodeRequest","reviveOwnShowList","__a1","__i2","length","PodcastsClient","fetch","listShows","result","method","parseJson","searchPodcastDirectory","query","qs","buildQueryString","listEpisodes","fetchEpisode","id","encodeURIComponent","refreshPodcasts","listOwnShows","reviveOwnShowList","createOwnShow","body","headers","JSON","stringify","bigIntReplacer","reviveOwnShow","updateOwnShow","deleteOwnShow","listOwnShowEpisodes","reviveProductionList","requestOwnShowEpisode","reviveProduction","ProductionsClient","fetch","listProductions","result","method","reviveProductionList","parseJson","requestProduction","body","headers","JSON","stringify","bigIntReplacer","reviveProduction","cancelProduction","id","encodeURIComponent","DateTime","__dt","v","path","TypeError","d","DateTime","fromISO","isValid","reviveScriptAttempt","raw","__o0","revivePad","reviveScriptHistoryPage","__a1","__i2","length","revivePadList","RenderClient","fetch","listSegments","result","method","parseJson","createSegment","body","headers","JSON","stringify","bigIntReplacer","uploadSegment","scanTheSegmentInbox","readScriptHistory","query","qs","buildQueryString","reviveScriptHistoryPage","rateScript","id","encodeURIComponent","reviveScriptAttempt","readScriptSummary","listVoices","getDefaultVoiceSample","expectStatuses","status","contentType","readContentType","data","blob","cacheControl","get","undefined","etag","getVoiceSample","voiceId","previewSpeech","deleteSegment","getSegmentAudio","contentDisposition","getStoredAudio","checksum","ext","listPronunciations","createPronunciation","updatePronunciation","deletePronunciation","setPronunciationState","listPads","revivePadList","uploadPad","scanThePadLibrary","fetchPad","deletePad","setPadState","setPadUse","getPadAudio","createPadSet","updatePadSet","deletePadSet","setPadMembership","DateTime","__dt","v","path","TypeError","d","DateTime","fromISO","isValid","revivePartyPass","raw","__o0","revivePartyGuestSession","reviveListenerRequest","revivePartyState","reviveListenerRequestList","__a1","__i2","length","RequestsPartyClient","fetch","getParty","result","method","revivePartyState","parseJson","startParty","body","headers","JSON","stringify","bigIntReplacer","revivePartyPass","endParty","joinParty","revivePartyGuestSession","RequestsClient","party","fetch","RequestsPartyClient","searchRequestableRecords","query","qs","buildQueryString","result","method","parseJson","listRequests","reviveListenerRequestList","createRequest","body","headers","JSON","stringify","bigIntReplacer","reviveListenerRequest","listMyRequests","insistOnRequest","id","encodeURIComponent","grantRequest","declineRequest","ScheduleClient","fetch","listSchedule","result","method","parseJson","createScheduleSlot","body","headers","JSON","stringify","bigIntReplacer","readCurrentSlot","readTimetable","query","qs","buildQueryString","updateScheduleSlot","id","encodeURIComponent","deleteScheduleSlot","readSlotPlaylistPosition","restartSlotPlaylist","SettingsClient","fetch","getSettings","result","method","parseJson","updateSettings","body","headers","JSON","stringify","bigIntReplacer","checkSignInProviders","previewInvitation","query","qs","buildQueryString","DateTime","__dt","v","path","TypeError","d","DateTime","fromISO","isValid","reviveLogSource","raw","__o0","reviveLogSourceList","__a1","__i2","length","DateTime","__dt","v","path","TypeError","d","DateTime","fromISO","isValid","__dtf","fmt","fromFormat","reviveStationHeartbeat","raw","__o0","reviveStationModelHolder","reviveStationRelease","reviveStationModel","reviveStationReleases","__a1","__i2","length","__a3","__i4","reviveStationCheckup","DateTime","__dt","v","path","TypeError","d","DateTime","fromISO","isValid","reviveTraceDecision","raw","__o0","reviveTraceSpan","reviveTracesPage","__a1","__i2","length","reviveTraceDetail","__a3","__i4","StationClient","fetch","listLogs","result","method","reviveLogSourceList","parseJson","readLog","id","query","qs","buildQueryString","encodeURIComponent","downloadLog","data","text","headers","contentDisposition","get","undefined","readStationAttention","dismissStationAttention","code","readStationCheckup","reviveStationCheckup","readStationReleases","reviveStationReleases","checkStationReleases","readTraces","reviveTracesPage","readTrace","reviveTraceDetail","DateTime","__dt","v","path","TypeError","d","DateTime","fromISO","isValid","reviveStorageReport","raw","__o0","StorageClient","fetch","readStorage","result","method","reviveStorageReport","parseJson","StreamClient","fetch","getHLSPlaylist","name","result","encodeURIComponent","method","data","blob","headers","cacheControl","get","undefined","getTuneInPls","getTuneInM3u","readFetcherAuthorization","parseJson","startFetcherAuthorization","finishFetcherAuthorization","body","JSON","stringify","bigIntReplacer","TopicsClient","fetch","listTopics","query","qs","buildQueryString","result","method","parseJson","createTopic","body","headers","JSON","stringify","bigIntReplacer","listTopicKinds","updateTopic","id","encodeURIComponent","deleteTopic","DateTime","__dt","v","path","TypeError","d","DateTime","fromISO","isValid","reviveUserSummary","raw","__o0","reviveUserSignIn","reviveUserPage","__a1","__i2","length","reviveUserDetail","reviveSession","__a3","__i4","DateTime","__dt","v","path","TypeError","d","DateTime","fromISO","isValid","reviveInvitationDetails","raw","__o0","reviveInvitation","reviveInvitationList","__a1","__i2","length","UsersInvitationsClient","fetch","listInvitations","result","method","reviveInvitationList","parseJson","createInvitation","body","headers","JSON","stringify","bigIntReplacer","reviveInvitation","revokeInvitation","id","encodeURIComponent","readInvitation","reviveInvitationDetails","startAcceptingInvitation","acceptInvitation","UsersClient","invitations","fetch","UsersInvitationsClient","listUsers","query","qs","buildQueryString","result","method","reviveUserPage","parseJson","getUser","id","encodeURIComponent","reviveUserDetail","changeUserRole","body","headers","JSON","stringify","bigIntReplacer","reviveUserSummary","deactivateUser","reactivateUser","signOutUser","resetUserMFA","DeadairSdk","activity","art","authentication","catalog","charts","director","events","history","languages","messaging","metrics","narrations","news","nowplaying","oauth","onboarding","outputs","personas","playlists","playout","plugins","podcasts","productions","render","requests","schedule","settings","station","storage","stream","topics","users","options","sdkFetch","fetch","createSdkFetch","ActivityClient","ArtClient","AuthenticationClient","CatalogClient","ChartsClient","DirectorClient","EventsClient","HistoryClient","LanguagesClient","MessagingClient","MetricsClient","NarrationsClient","NewsClient","NowplayingClient","OauthClient","OnboardingClient","OutputsClient","PersonasClient","PlaylistsClient","PlayoutClient","PluginsClient","PodcastsClient","ProductionsClient","RenderClient","RequestsClient","ScheduleClient","SettingsClient","StationClient","StorageClient","StreamClient","TopicsClient","UsersClient"]}
|
|
1
|
+
{"version":3,"sources":["../src/sdk-options.ts","../src/activity/types/activity.types.ts","../src/activity/activity.client.ts","../src/art/art.client.ts","../src/authentication/types/authentication.types.ts","../src/authentication/authentication.apikeys.client.ts","../src/authentication/types/registration.types.ts","../src/authentication/authentication.factor.client.ts","../src/authentication/authentication.sessions.client.ts","../src/authentication/authentication.client.ts","../src/catalog/types/catalog.types.ts","../src/catalog/catalog.client.ts","../src/charts/charts.client.ts","../src/director/types/rules.types.ts","../src/director/director.client.ts","../src/events/types/events.types.ts","../src/events/events.client.ts","../src/history/types/history.types.ts","../src/history/history.client.ts","../src/languages/types/languages.types.ts","../src/languages/languages.client.ts","../src/messaging/types/messaging.types.ts","../src/messaging/messaging.client.ts","../src/metrics/types/metrics.types.ts","../src/metrics/metrics.client.ts","../src/narrations/narrations.client.ts","../src/news/news.client.ts","../src/nowplaying/nowplaying.client.ts","../src/oauth/types/oauth.types.ts","../src/oauth/oauth.client.ts","../src/onboarding/onboarding.client.ts","../src/outputs/types/outputs.types.ts","../src/outputs/outputs.client.ts","../src/personas/personas.client.ts","../src/playlists/types/playlists.types.ts","../src/playlists/types/station.playlists.types.ts","../src/playlists/playlists.client.ts","../src/playout/playout.client.ts","../src/plugins/types/plugins.types.ts","../src/plugins/plugins.client.ts","../src/productions/types/productions.types.ts","../src/podcasts/types/podcasts.types.ts","../src/podcasts/podcasts.client.ts","../src/productions/productions.client.ts","../src/render/types/render.types.ts","../src/render/render.client.ts","../src/requests/types/requests.types.ts","../src/requests/requests.party.client.ts","../src/requests/requests.client.ts","../src/schedule/schedule.client.ts","../src/settings/settings.client.ts","../src/station/types/logs.types.ts","../src/station/types/station.types.ts","../src/station/types/traces.types.ts","../src/station/station.client.ts","../src/storage/types/storage.types.ts","../src/storage/storage.client.ts","../src/stream/stream.client.ts","../src/topics/topics.client.ts","../src/users/types/users.types.ts","../src/users/types/invitations.types.ts","../src/users/invitations.client.ts","../src/users/users.client.ts","../src/deadair.sdk.ts"],"sourcesContent":["export class SdkError<TBody = unknown> extends Error {\n constructor(\n public readonly status: number,\n public readonly statusText: string,\n public readonly body: TBody,\n public readonly headers: Headers,\n ) {\n super(`${status} ${statusText}`);\n this.name = 'SdkError';\n }\n}\n\nexport interface SdkRequestInit extends RequestInit {\n /**\n * Statuses this operation declares as values rather than errors — a 304 from\n * conditional-GET middleware, or an error status the service returns deliberately.\n * Anything else at or above 400 still throws SdkError.\n */\n expectStatuses?: number[];\n}\n\nexport type SdkFetch = (url: string, init: SdkRequestInit) => Promise<Response>;\n\nexport interface SdkOptions {\n baseUrl: string;\n headers?: Record<string, string> | (() => Record<string, string> | Promise<Record<string, string>>);\n fetch?: SdkFetch;\n /** Called once per request to produce a unique X-Request-ID header value */\n requestIdFactory?: () => string;\n}\n\nexport const bigIntReplacer = (_: string, value: any): any => {\n if (typeof value === 'bigint') {\n return value.toString() + 'n';\n }\n return value;\n};\n\nexport const bigIntReviver = (_: string, value: any): any => {\n if (typeof value === 'string' && /^-?\\d+n$/.test(value)) {\n return BigInt(value.slice(0, -1));\n }\n return value;\n};\n\nexport type JsonValue = string | number | boolean | null | JsonValue[] | { [key: string]: JsonValue };\n\nexport function readContentType(res: Response): string {\n return res.headers.get('content-type')?.split(';')[0]?.trim() ?? '';\n}\n\n/** A v4 UUID. `crypto.randomUUID` exists only in a secure context, so plain HTTP builds one by hand. */\nfunction randomRequestId(): string {\n if (typeof crypto.randomUUID === 'function') return crypto.randomUUID();\n const bytes = crypto.getRandomValues(new Uint8Array(16));\n bytes[6] = (bytes[6]! & 0x0f) | 0x40;\n bytes[8] = (bytes[8]! & 0x3f) | 0x80;\n const hex = Array.from(bytes, b => b.toString(16).padStart(2, '0')).join('');\n return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;\n}\n\nexport function createSdkFetch(options: SdkOptions): SdkFetch {\n const getRequestId = options.requestIdFactory ?? randomRequestId;\n return async (url: string, init: SdkRequestInit): Promise<Response> => {\n const baseHeaders = typeof options.headers === 'function' ? await options.headers() : (options.headers ?? {});\n const res = await fetch(`${options.baseUrl}${url}`, {\n ...init,\n headers: { ...baseHeaders, 'X-Request-ID': getRequestId(), ...(init.headers as Record<string, string>) },\n });\n if (!res.ok && !(init.expectStatuses ?? []).includes(res.status)) {\n const text = await res.text();\n let body: unknown;\n try {\n body = JSON.parse(text);\n } catch {\n body = text;\n }\n throw new SdkError(res.status, res.statusText, body, res.headers);\n }\n return res;\n };\n}\n\nexport function buildQueryString(query: object | undefined): string {\n const searchParams = new URLSearchParams();\n if (query) {\n for (const [k, v] of Object.entries(query)) {\n if (v === undefined || v === null) continue;\n if (Array.isArray(v)) {\n for (const item of v) searchParams.append(k, String(item));\n } else searchParams.set(k, String(v));\n }\n }\n const qs = searchParams.toString();\n return qs ? `?${qs}` : '';\n}\n\nexport function buildHeaders(headers: object | undefined): Record<string, string> {\n const out: Record<string, string> = {};\n if (headers) {\n for (const [k, v] of Object.entries(headers)) {\n if (v === undefined || v === null) continue;\n out[k] = Array.isArray(v) ? v.map(String).join(', ') : String(v);\n }\n }\n return out;\n}\n\nexport function parseBigIntHeader(name: string, value: string): bigint {\n if (/^-?\\d+n?$/.test(value)) return BigInt(value.replace(/n$/, ''));\n throw new Error(`Response header '${name}' is not a bigint: ${JSON.stringify(value)}`);\n}\n\n/** Per-call options for an operation that streams Server-Sent Events. */\nexport interface SseRequestOptions {\n /** Aborts the request. An iteration in progress rejects with the abort reason. */\n signal?: AbortSignal;\n /** Resume after this event id, sent as Last-Event-ID. Usually an earlier stream's lastEventId. */\n lastEventId?: string;\n}\n\n/**\n * The events of one Server-Sent Events response, parsed as they arrive. Iterate it once with\n * for await; leaving the loop early closes the connection.\n */\nexport interface SseEventStream<T> extends AsyncIterable<T> {\n /** The id of the most recent event that carried one, to resume from with SseRequestOptions.lastEventId. */\n readonly lastEventId: string | undefined;\n}\n\n/** The request headers a streaming call sends: Accept, plus Last-Event-ID when resuming. */\nexport function sseRequestHeaders(options: SseRequestOptions | undefined): Record<string, string> {\n const headers: Record<string, string> = { Accept: 'text/event-stream' };\n if (options?.lastEventId !== undefined) headers['Last-Event-ID'] = options.lastEventId;\n return headers;\n}\n\n/**\n * Parse a text/event-stream response into its events. Data lines are joined with newlines and\n * dispatched on a blank line; comments and other fields are skipped; an event cut off by the end\n * of the stream is dropped. Each event's data goes through parse, JSON.parse by default.\n */\nexport function parseSse<T>(res: Response, parse: (data: string) => T = data => JSON.parse(data) as T): SseEventStream<T> {\n let lastEventId: string | undefined;\n let iterated = false;\n async function* events(): AsyncGenerator<T> {\n if (!res.body) return;\n const reader = res.body.pipeThrough(new TextDecoderStream()).getReader();\n let buffer = '';\n let data: string[] = [];\n try {\n for (;;) {\n const chunk = await reader.read();\n if (!chunk.done) buffer += chunk.value;\n for (;;) {\n const end = buffer.search(/\\r\\n|\\r|\\n/);\n // A trailing CR may be the first half of a CRLF split across two reads, unless\n // this was the last read.\n if (end === -1 || (!chunk.done && end === buffer.length - 1 && buffer[end] === '\\r')) break;\n const line = buffer.slice(0, end);\n buffer = buffer.slice(buffer.startsWith('\\r\\n', end) ? end + 2 : end + 1);\n if (line === '') {\n if (data.length > 0) yield parse(data.join('\\n'));\n data = [];\n continue;\n }\n const colon = line.indexOf(':');\n const field = colon === -1 ? line : line.slice(0, colon);\n const value = colon === -1 ? '' : line.slice(line.startsWith(' ', colon + 1) ? colon + 2 : colon + 1);\n if (field === 'data') data.push(value);\n else if (field === 'id' && !value.includes('\\0')) lastEventId = value;\n }\n if (chunk.done) return;\n }\n } finally {\n await reader.cancel().catch(() => undefined);\n }\n }\n return {\n get lastEventId() {\n return lastEventId;\n },\n [Symbol.asyncIterator]() {\n if (iterated) throw new Error('An SseEventStream can be iterated only once');\n iterated = true;\n return events();\n },\n };\n}\n\n/**\n * Read a JSON response body.\n *\n * No reviver: `bigIntReviver` matches any string of the form `123n` anywhere in the\n * document, so a contract with no bigint field would still have a legitimate string like\n * \"123n\" silently turned into a BigInt. Clients whose contracts do use bigint import\n * `parseJsonWithBigInt` under this name instead.\n */\nexport async function parseJson<T>(res: Response): Promise<T> {\n return JSON.parse(await res.text()) as T;\n}\n\n/** `parseJson` for contracts that declare a bigint, applying the `123n` reviver. */\nexport async function parseJsonWithBigInt<T>(res: Response): Promise<T> {\n return JSON.parse(await res.text(), bigIntReviver) as T;\n}\n","import { DateTime } from 'luxon';\nconst __dt = (v: unknown, path: string): DateTime => {\n if (typeof v !== 'string') {\n throw new TypeError(`ContractKit: expected an ISO 8601 string at '${path}', received ${typeof v}.`);\n }\n const d = DateTime.fromISO(v);\n if (!d.isValid) throw new TypeError(`ContractKit: '${v}' at '${path}' is not a valid ISO 8601 datetime.`);\n return d;\n};\n\n/**\n * Which part of the station an entry came from, and the console's one filter axis\n * generated from [ActivityModule](../../../../../apps/api/data/contracts/activity/activity.types.ck)\n */\nexport type ActivityModule = 'playout' | 'director' | 'render' | 'catalog' | 'plugins' | 'storage' | 'events';\n\n/**\n * How an entry reads, not how bad it is. There is deliberately no `waiting`: a station idling for\n * want of a listener says so in its own words and stays `info`, for the same reason the transport\n * reports it as `ready` rather than as a mild fault\n * generated from [ActivitySeverity](../../../../../apps/api/data/contracts/activity/activity.types.ck)\n */\nexport type ActivitySeverity = 'info' | 'warn' | 'fault';\n\n/**\n * One thing that happened, from whichever of the feed's sources holds it\n * generated from [ActivityEntry](../../../../../apps/api/data/contracts/activity/activity.types.ck)\n */\nexport interface ActivityEntry {\n /** Unique across the whole feed, and half of the cursor below */\n id: string;\n /** When it happened, as the database recorded it */\n at: DateTime;\n module: ActivityModule;\n /** Dotted and stable: `silence.cause`, `air.on`, `segment.ready`, `track.aired`. What a console draws a line with, never something a decision is made on */\n kind: string;\n severity: ActivitySeverity;\n /** The sentence a person reads, phrased by whatever produced it */\n detail: string;\n /** The structured half, for a reader that wants to filter or chart rather than read */\n data?: Record<string, unknown>;\n /** The segment this is about, for an entry that came from one */\n segmentId?: string;\n /** The catalog track this is about, for an entry that came from one */\n trackId?: string;\n}\n\n/** Rehydrates every wire-encoded scalar in a ActivityEntry into its runtime type. Mutates and returns `raw`. */\nexport function reviveActivityEntry(raw: ActivityEntry): ActivityEntry {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['at'] = __dt(__o0['at'], 'ActivityEntry.at');\n return raw;\n}\n\n/**\n * One page of the feed, newest first\n * generated from [ActivityQuery](../../../../../apps/api/data/contracts/activity/activity.types.ck)\n */\nexport interface ActivityQuery {\n limit?: number;\n /** Where the previous page ended. Opaque, and a keyset rather than an offset because rows arrive at the head continuously: an offset would re-show a row on every page as the feed grew under it. Pass back whatever `nextBefore` said and nothing else */\n before?: string;\n module?: ActivityModule;\n /** The floor, not the exact match: `warn` answers with warnings and faults. Absent is everything */\n minSeverity?: ActivitySeverity;\n}\n\n/**\n * generated from [ActivityPage](../../../../../apps/api/data/contracts/activity/activity.types.ck)\n */\nexport interface ActivityPage {\n entries: ActivityEntry[];\n /** The cursor for the page after this one, absent once the feed has been read to its end */\n nextBefore?: string;\n}\n\n/** Rehydrates every wire-encoded scalar in a ActivityPage into its runtime type. Mutates and returns `raw`. */\nexport function reviveActivityPage(raw: ActivityPage): ActivityPage {\n const __o0 = raw as unknown as Record<string, unknown>;\n {\n const __a1 = __o0['entries'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveActivityEntry(__a1[__i2] as never);\n }\n }\n return raw;\n}\n","import type { SdkFetch } from '../sdk-options.js';\nimport { parseJson, buildQueryString } from '../sdk-options.js';\nimport type { ActivityPage, ActivityQuery } from './types/activity.types.js';\nimport { reviveActivityPage } from './types/activity.types.js';\n\nexport class ActivityClient {\n constructor(private fetch: SdkFetch) {}\n\n /**\n * @name Read activity\n * @description The feed, newest first, one page at a time\n */\n async readActivity(query?: ActivityQuery): Promise<ActivityPage> {\n const qs = buildQueryString(query);\n const result = await this.fetch(`/activity${qs}`, {\n method: 'GET',\n });\n return reviveActivityPage(await parseJson<ActivityPage>(result));\n }\n}\n","import type { SdkFetch } from '../sdk-options.js';\nimport { parseJson, readContentType } from '../sdk-options.js';\nimport type { BreakArtworkList, PersonaPortraitList } from './types/art.types.js';\n\nexport class ArtClient {\n constructor(private fetch: SdkFetch) {}\n\n /**\n * @name List break artwork\n * @description Every kind the station holds a picture for\n */\n async listBreakArtwork(): Promise<BreakArtworkList> {\n const result = await this.fetch(`/art/breaks`, { method: 'GET' });\n return await parseJson<BreakArtworkList>(result);\n }\n\n /**\n * @name Replace break artwork\n * @description Puts an operator's own picture behind a kind of break. The id does not change, so a URL already on the wire keeps working and the ETag is what says the picture moved\n */\n async replaceBreakArtwork(kind: string, body: FormData): Promise<BreakArtworkList> {\n const result = await this.fetch(`/art/breaks/${encodeURIComponent(kind)}`, {\n method: 'POST',\n body: body,\n });\n return await parseJson<BreakArtworkList>(result);\n }\n\n /**\n * @name Revert break artwork\n * @description Puts the picture this repository ships back. The shipped file is read at this moment rather than copied at install, so an upgrade that improved it is what comes back\n */\n async revertBreakArtwork(kind: string): Promise<BreakArtworkList> {\n const result = await this.fetch(`/art/breaks/${encodeURIComponent(kind)}`, { method: 'DELETE' });\n return await parseJson<BreakArtworkList>(result);\n }\n\n /**\n * @name Get source art\n * @description The bytes of a cover the station fetches on first ask, addressed by its sealed source\n */\n async getSourceArt(token: string): Promise<\n | {\n status: 200;\n contentType: 'image/jpeg' | 'image/png' | 'image/webp' | 'image/gif';\n data: Blob;\n headers: { cacheControl?: string; etag?: string };\n }\n | { status: 304 }\n > {\n const result = await this.fetch(`/art/source/${encodeURIComponent(token)}`, {\n method: 'GET',\n expectStatuses: [304],\n });\n switch (result.status) {\n case 304:\n return { status: 304 };\n default:\n return {\n status: 200,\n contentType: readContentType(result) as 'image/jpeg' | 'image/png' | 'image/webp' | 'image/gif',\n data: await result.blob(),\n headers: { cacheControl: result.headers.get('cache-control') ?? undefined, etag: result.headers.get('etag') ?? undefined },\n };\n }\n }\n\n /**\n * @name Get source art file\n * @description The bytes of a cover the station fetches on first ask, under any filename\n */\n async getSourceArtFile(\n token: string,\n filename: string,\n ): Promise<\n | {\n status: 200;\n contentType: 'image/jpeg' | 'image/png' | 'image/webp' | 'image/gif';\n data: Blob;\n headers: { cacheControl?: string; etag?: string };\n }\n | { status: 304 }\n > {\n const result = await this.fetch(`/art/source/${encodeURIComponent(token)}/${encodeURIComponent(filename)}`, {\n method: 'GET',\n expectStatuses: [304],\n });\n switch (result.status) {\n case 304:\n return { status: 304 };\n default:\n return {\n status: 200,\n contentType: readContentType(result) as 'image/jpeg' | 'image/png' | 'image/webp' | 'image/gif',\n data: await result.blob(),\n headers: { cacheControl: result.headers.get('cache-control') ?? undefined, etag: result.headers.get('etag') ?? undefined },\n };\n }\n }\n\n /**\n * @name Get art\n * @description The bytes of one cached image, addressed by its id alone\n */\n async getArt(id: string): Promise<\n | {\n status: 200;\n contentType: 'image/jpeg' | 'image/png' | 'image/webp' | 'image/gif';\n data: Blob;\n headers: { cacheControl?: string; etag?: string };\n }\n | { status: 304 }\n > {\n const result = await this.fetch(`/art/${encodeURIComponent(id)}`, {\n method: 'GET',\n expectStatuses: [304],\n });\n switch (result.status) {\n case 304:\n return { status: 304 };\n default:\n return {\n status: 200,\n contentType: readContentType(result) as 'image/jpeg' | 'image/png' | 'image/webp' | 'image/gif',\n data: await result.blob(),\n headers: { cacheControl: result.headers.get('cache-control') ?? undefined, etag: result.headers.get('etag') ?? undefined },\n };\n }\n }\n\n /**\n * @name Get art file\n * @description The bytes of one cached image, under any filename\n */\n async getArtFile(\n id: string,\n filename: string,\n ): Promise<\n | {\n status: 200;\n contentType: 'image/jpeg' | 'image/png' | 'image/webp' | 'image/gif';\n data: Blob;\n headers: { cacheControl?: string; etag?: string };\n }\n | { status: 304 }\n > {\n const result = await this.fetch(`/art/${encodeURIComponent(id)}/${encodeURIComponent(filename)}`, {\n method: 'GET',\n expectStatuses: [304],\n });\n switch (result.status) {\n case 304:\n return { status: 304 };\n default:\n return {\n status: 200,\n contentType: readContentType(result) as 'image/jpeg' | 'image/png' | 'image/webp' | 'image/gif',\n data: await result.blob(),\n headers: { cacheControl: result.headers.get('cache-control') ?? undefined, etag: result.headers.get('etag') ?? undefined },\n };\n }\n }\n\n /**\n * @name List persona portraits\n * @description Every persona that has a portrait\n */\n async listPersonaPortraits(): Promise<PersonaPortraitList> {\n const result = await this.fetch(`/art/personas`, { method: 'GET' });\n return await parseJson<PersonaPortraitList>(result);\n }\n\n /**\n * @name Replace persona portrait\n * @description Puts a picture on a persona. A persona that already had one keeps its URL, so a player holding it picks up the new picture\n */\n async replacePersonaPortrait(personaId: string, body: FormData): Promise<PersonaPortraitList> {\n const result = await this.fetch(`/art/personas/${encodeURIComponent(personaId)}`, {\n method: 'POST',\n body: body,\n });\n return await parseJson<PersonaPortraitList>(result);\n }\n\n /**\n * @name Remove persona portrait\n * @description Takes a persona's picture away. A player shows the record's cover instead\n */\n async removePersonaPortrait(personaId: string): Promise<PersonaPortraitList> {\n const result = await this.fetch(`/art/personas/${encodeURIComponent(personaId)}`, { method: 'DELETE' });\n return await parseJson<PersonaPortraitList>(result);\n }\n}\n","import { DateTime } from 'luxon';\nconst __dt = (v: unknown, path: string): DateTime => {\n if (typeof v !== 'string') {\n throw new TypeError(`ContractKit: expected an ISO 8601 string at '${path}', received ${typeof v}.`);\n }\n const d = DateTime.fromISO(v);\n if (!d.isValid) throw new TypeError(`ContractKit: '${v}' at '${path}' is not a valid ISO 8601 datetime.`);\n return d;\n};\n\n/**\n * Denotes the authorization flow to use\n * generated from [AuthenticationGrantType](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport type AuthenticationGrantType = 'client_credentials' | 'password' | 'refresh_token' | 'link' | 'code' | 'fido' | 'authenticator' | 'oidc';\n\n/**\n * Denotes the authorization flow to use\n * generated from [PasswordlessAuthenticationGrantType](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport type PasswordlessAuthenticationGrantType = 'link' | 'code' | 'fido' | 'oidc';\n\n/**\n * The type of the factor\n * generated from [AuthenticationFactorMethod](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport type AuthenticationFactorMethod = 'phone' | 'password' | 'email' | 'authenticator' | 'fido' | 'oidc';\n\n/**\n * The kind of the factor\n * generated from [AuthenticationFactorKind](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport type AuthenticationFactorKind = 'knowledge' | 'possession' | 'biometric';\n\n/**\n * The name of an identity provider the station offers, as the operator set it under Settings, Sign-in and security. `GET /auth/login/oidc/providers` lists them\n * generated from [OidcProvider](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport type OidcProvider = string;\n\n/**\n * Represents an authentication token\n * generated from [AuthenticationToken](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface AuthenticationToken {\n /** The access token string as issued by the authorization server */\n accessToken: string;\n /** A refresh token which applications can use to obtain another access token */\n refreshToken?: string;\n /** Unix timestamp (seconds) when the access token expires */\n expiresIn: number;\n /** The type of token this is, typically just the string *Bearer* */\n tokenType: string;\n /** Space-separated list of scopes granted to this token */\n scope: string;\n}\n\nexport interface AuthenticationTokenOutput {\n /** The access token string as issued by the authorization server */\n access_token: string;\n /** A refresh token which applications can use to obtain another access token */\n refresh_token?: string;\n /** Unix timestamp (seconds) when the access token expires */\n expires_in: number;\n /** The type of token this is, typically just the string *Bearer* */\n token_type: string;\n /** Space-separated list of scopes granted to this token */\n scope: string;\n}\n\n/**\n * Issued-token arm of /auth/token response\n * generated from [AuthenticationTokenIssued](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface AuthenticationTokenIssued {\n /** Discriminator */\n result: 'token';\n /** The access token string as issued by the authorization server */\n accessToken: string;\n /** A refresh token which applications can use to obtain another access token */\n refreshToken?: string;\n /** Unix timestamp (seconds) when the access token expires */\n expiresIn: number;\n /** The type of token this is, typically just the string *Bearer* */\n tokenType: string;\n /** Space-separated list of scopes granted to this token */\n scope: string;\n}\n\nexport interface AuthenticationTokenIssuedOutput {\n /** Discriminator */\n result: 'token';\n /** The access token string as issued by the authorization server */\n access_token: string;\n /** A refresh token which applications can use to obtain another access token */\n refresh_token?: string;\n /** Unix timestamp (seconds) when the access token expires */\n expires_in: number;\n /** The type of token this is, typically just the string *Bearer* */\n token_type: string;\n /** Space-separated list of scopes granted to this token */\n scope: string;\n}\n\n/**\n * Returned by /auth/step-up/start when no enrolled factor satisfies the requirement. The SPA should drive the user through enrollment and retry the gated action afterwards.\n * generated from [EnrollmentRequiredResponse](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface EnrollmentRequiredResponse {\n /** Discriminator */\n result: 'enrollment_required';\n}\n\nexport interface EnrollmentRequiredResponseOutput {\n /** Discriminator */\n result: 'enrollment_required';\n}\n\n/**\n * Represents a common shape of a `PublicKeyCredential` after the client serializes the `id` and `rawId` fields to base64 strings for transport\n * generated from [PublicKeyCredential](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface PublicKeyCredential {\n /** The base64url encoding of `rawId` */\n id: string;\n /** This enumeration defines the valid credential types. It is an extension point; values can be added to it in the future, as more credential types are defined. The values of this enumeration are used for versioning the Authentication Assertion and attestation structures according to the type of the authenticator. Currently one credential type is defined, namely `public-key`. */\n type: 'public-key';\n /** The credential identifier */\n rawId: string;\n /** The authenticator attachment */\n authenticatorAttachment?: 'cross-platform' | 'platform';\n}\n\n/**\n * Subset of the WebAuthn client extension results the service round-trips\n * generated from [SimpleClientExtensionResults](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface SimpleClientExtensionResults {\n /** Whether the client is an application */\n appid?: boolean;\n /** Whether the client is excluded from appid verification */\n appidExclude?: boolean;\n credProps?: { rk: boolean };\n}\n\n/**\n * generated from [FidoAuthenticatorAssertionResponse](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface FidoAuthenticatorAssertionResponse {\n /** The client data JSON */\n clientDataJSON: string;\n /** The authenticator data */\n authenticatorData: string;\n /** The signature */\n signature: string;\n /** The user handle */\n userHandle?: string;\n}\n\n/**\n * generated from [AuthenticationRegistration](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface AuthenticationRegistration {\n /** The registration identifier */\n registrationId: string;\n /** The registration expiration timestamp */\n expiresAt: DateTime;\n}\n\nexport interface AuthenticationRegistrationInput {\n /** User's email address */\n email: string;\n /** optionally set a password for the user */\n password?: string;\n}\n\n/** Rehydrates every wire-encoded scalar in a AuthenticationRegistration into its runtime type. Mutates and returns `raw`. */\nexport function reviveAuthenticationRegistration(raw: AuthenticationRegistration): AuthenticationRegistration {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['expiresAt'] = __dt(__o0['expiresAt'], 'AuthenticationRegistration.expiresAt');\n return raw;\n}\n\n/**\n * generated from [AuthenticationRegistrationVerification](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface AuthenticationRegistrationVerification {\n /** The registration identifier */\n registrationId: string;\n /** The verification code */\n code: string;\n}\n\n/**\n * A credential the relying party expects the user to be able to present\n * generated from [PublicKeyCredentialDescriptor](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface PublicKeyCredentialDescriptor {\n /** The credential type — currently always `public-key` */\n type: 'public-key';\n /** The base64url-encoded credential identifier */\n id: string;\n /** Transports the authenticator advertises */\n transports?: ('usb' | 'nfc' | 'ble' | 'internal' | 'hybrid')[];\n}\n\n/**\n * The transport used by the authenticator\n * generated from [FidoAuthenticatorTransport](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport type FidoAuthenticatorTransport = 'hybrid' | 'ble' | 'internal' | 'nfc' | 'usb';\n\n/**\n * Request to complete an OIDC sign-in flow\n * generated from [OidcLoginCallback](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface OidcLoginCallback {\n /** The issuer of the token */\n iss?: string;\n /** The scope of the token */\n scope?: string;\n /** The user ID */\n authuser?: string;\n /** The host domain */\n hd?: string;\n /** The prompt of the token */\n prompt?: string;\n /** The authorization code returned by the IdP (absent when the IdP rejected the request) */\n code?: string;\n /** The opaque state token bound to the original authorize request */\n state?: string;\n /** OAuth 2.0 error code per RFC 6749 §4.1.2.1 (e.g. access_denied) */\n error?: string;\n /** Human-readable explanation of `error` */\n error_description?: string;\n /** URL to a page describing `error` */\n error_uri?: string;\n}\n\n/**\n * Issue a phone SMS challenge during a pending MFA round\n * generated from [FactorChallengePhoneStart](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface FactorChallengePhoneStart {\n /** Discriminator */\n method: 'phone';\n /** Delivery channel — only `sms` is supported in this phase */\n transport: 'sms';\n /** The MFA challenge to which this factor challenge is bound */\n mfa_challenge_id: string;\n}\n\n/**\n * Issue a WebAuthn assertion challenge during a pending MFA round\n * generated from [FactorChallengeFidoStart](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface FactorChallengeFidoStart {\n /** Discriminator */\n method: 'fido';\n /** The MFA challenge to which this factor challenge is bound */\n mfa_challenge_id: string;\n}\n\n/**\n * Issue an email one-time-code challenge during a pending MFA round. Always a code: a magic link cannot complete an MFA round, since the `code` grant that redeems one takes `code(min=6, max=10)` and a link token is 43 characters\n * generated from [FactorChallengeEmailStart](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface FactorChallengeEmailStart {\n /** Discriminator */\n method: 'email';\n /** The MFA challenge to which this factor challenge is bound */\n mfa_challenge_id: string;\n}\n\n/**\n * Response for a phone SMS challenge\n * generated from [FactorChallengePhoneStartResponse](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface FactorChallengePhoneStartResponse {\n /** Discriminator */\n method: 'phone';\n /** Echo of the chosen delivery channel */\n transport: 'sms';\n /** The phone-factor challenge id — echo back on the `code` grant as `challenge_id` */\n phoneChallengeId: string;\n /** When the phone challenge expires */\n expiresAt: DateTime;\n}\n\nexport interface FactorChallengePhoneStartResponseOutput {\n /** Discriminator */\n method: 'phone';\n /** Echo of the chosen delivery channel */\n transport: 'sms';\n /** The phone-factor challenge id — echo back on the `code` grant as `challenge_id` */\n phone_challenge_id: string;\n /** When the phone challenge expires */\n expires_at: DateTime;\n}\n\n/** Rehydrates every wire-encoded scalar in a FactorChallengePhoneStartResponse into its runtime type. Mutates and returns `raw`. */\nexport function reviveFactorChallengePhoneStartResponse(raw: FactorChallengePhoneStartResponse): FactorChallengePhoneStartResponse {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['expiresAt'] = __dt(__o0['expiresAt'], 'FactorChallengePhoneStartResponse.expiresAt');\n return raw;\n}\n\n/** Rehydrates every wire-encoded scalar in a FactorChallengePhoneStartResponseOutput into its runtime type. Mutates and returns `raw`. */\nexport function reviveFactorChallengePhoneStartResponseOutput(raw: FactorChallengePhoneStartResponseOutput): FactorChallengePhoneStartResponseOutput {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['expires_at'] = __dt(__o0['expires_at'], 'FactorChallengePhoneStartResponse.expires_at');\n return raw;\n}\n\n/**\n * Response for an email one-time-code challenge\n * generated from [FactorChallengeEmailStartResponse](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface FactorChallengeEmailStartResponse {\n /** Discriminator */\n method: 'email';\n /** The email-factor challenge id — echo back on the `code` grant as `challenge_id` */\n emailChallengeId: string;\n /** When the email challenge expires */\n expiresAt: DateTime;\n}\n\nexport interface FactorChallengeEmailStartResponseOutput {\n /** Discriminator */\n method: 'email';\n /** The email-factor challenge id — echo back on the `code` grant as `challenge_id` */\n email_challenge_id: string;\n /** When the email challenge expires */\n expires_at: DateTime;\n}\n\n/** Rehydrates every wire-encoded scalar in a FactorChallengeEmailStartResponse into its runtime type. Mutates and returns `raw`. */\nexport function reviveFactorChallengeEmailStartResponse(raw: FactorChallengeEmailStartResponse): FactorChallengeEmailStartResponse {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['expiresAt'] = __dt(__o0['expiresAt'], 'FactorChallengeEmailStartResponse.expiresAt');\n return raw;\n}\n\n/** Rehydrates every wire-encoded scalar in a FactorChallengeEmailStartResponseOutput into its runtime type. Mutates and returns `raw`. */\nexport function reviveFactorChallengeEmailStartResponseOutput(raw: FactorChallengeEmailStartResponseOutput): FactorChallengeEmailStartResponseOutput {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['expires_at'] = __dt(__o0['expires_at'], 'FactorChallengeEmailStartResponse.expires_at');\n return raw;\n}\n\n/**\n * A factor satisfied by the session\n * generated from [SessionFactor](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface SessionFactor {\n /** The verification method */\n method: 'phone' | 'password' | 'authenticator' | 'email' | 'fido' | 'oidc';\n /** Stable identifier for the specific factor record */\n methodId: string;\n /** MFA category for the factor */\n kind: 'knowledge' | 'possession' | 'biometric';\n /** When this factor entry was first added to the session */\n issuedAt: DateTime;\n /** When the factor was most recently re-verified */\n authenticatedAt: DateTime;\n}\n\nexport interface SessionFactorInput {\n /** The verification method */\n method: 'phone' | 'password' | 'authenticator' | 'email' | 'fido' | 'oidc';\n /** Stable identifier for the specific factor record */\n methodId: string;\n /** MFA category for the factor */\n kind: 'knowledge' | 'possession' | 'biometric';\n}\n\n/** Rehydrates every wire-encoded scalar in a SessionFactor into its runtime type. Mutates and returns `raw`. */\nexport function reviveSessionFactor(raw: SessionFactor): SessionFactor {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['issuedAt'] = __dt(__o0['issuedAt'], 'SessionFactor.issuedAt');\n __o0['authenticatedAt'] = __dt(__o0['authenticatedAt'], 'SessionFactor.authenticatedAt');\n return raw;\n}\n\n/**\n * Optional metadata supplied to a revoke action\n * generated from [SessionRevoke](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface SessionRevoke {\n /** Free-form reason recorded with the revoke */\n reason?: string | null;\n}\n\n/**\n * A platform-wide role held on `platform:main`. `admin` grants every operation; `listener` grants the reads\n * generated from [PlatformRole](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport type PlatformRole = 'admin' | 'listener';\n\n/**\n * A successful authentication record\n * generated from [Login](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface Login {\n /** The login event identifier */\n id: bigint;\n /** The actor that authenticated */\n actorId: string;\n /** The factor that satisfied the primary authentication, or `apikey` for a request made with one of the account's API keys */\n factorType: 'phone' | 'password' | 'authenticator' | 'email' | 'fido' | 'oidc' | 'apikey';\n /** The specific factor record id, when available */\n factorId?: string | null;\n /** The session minted at this login, when available */\n sessionToken?: string | null;\n /** Whether MFA was required and satisfied at login */\n mfaSatisfied: boolean;\n /** IP address recorded at login */\n ip?: string | null;\n /** User agent recorded at login */\n userAgent?: string | null;\n /** When the login occurred */\n occurredAt: DateTime;\n}\n\nexport interface LoginInput {}\n\n/** Rehydrates every wire-encoded scalar in a Login into its runtime type. Mutates and returns `raw`. */\nexport function reviveLogin(raw: Login): Login {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['occurredAt'] = __dt(__o0['occurredAt'], 'Login.occurredAt');\n return raw;\n}\n\n/**\n * The current user's display preferences, auto-detected by the SPA from the browser (Intl timezone + navigator.language). Omitted fields are left unchanged (absent = never set).\n * generated from [ActorPreferences](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface ActorPreferences {\n /** RFC 5646 locale, e.g. \"en-US\" */\n locale?: string;\n /** Olson timezone, e.g. \"America/New_York\" */\n timezone?: string;\n}\n\n/**\n * What an API key may be granted. `view` covers every route a listener may read; `manage` covers the rest, and includes `view`\n * generated from [ApiKeyScope](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport type ApiKeyScope = 'view' | 'manage';\n\n/**\n * generated from [BaseAuthenticationRequest](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface BaseAuthenticationRequest {\n /** The grant type for the request */\n grant_type: AuthenticationGrantType;\n /** The scope of the request */\n scope?: string;\n /** The application's client identifier, if available */\n client_id?: string;\n}\n\n/**\n * generated from [BaseAuthenticationLoginStart](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface BaseAuthenticationLoginStart {\n /** The grant type for the request */\n grant_type: PasswordlessAuthenticationGrantType;\n /** The application's client identifier, if available */\n client_id?: string;\n}\n\n/**\n * generated from [BaseAuthenticationLoginStartResponse](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface BaseAuthenticationLoginStartResponse {\n /** The grant type for the response */\n grant_type: PasswordlessAuthenticationGrantType;\n /** The challenge identifier */\n challengeId: string;\n /** The challenge expiration timestamp */\n expiresAt: DateTime;\n}\n\n/** Rehydrates every wire-encoded scalar in a BaseAuthenticationLoginStartResponse into its runtime type. Mutates and returns `raw`. */\nexport function reviveBaseAuthenticationLoginStartResponse(raw: BaseAuthenticationLoginStartResponse): BaseAuthenticationLoginStartResponse {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['expiresAt'] = __dt(__o0['expiresAt'], 'BaseAuthenticationLoginStartResponse.expiresAt');\n return raw;\n}\n\n/**\n * A factor the SPA may use to satisfy the MFA challenge\n * generated from [MfaChallengeFactor](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface MfaChallengeFactor {\n /** The factor method */\n method: AuthenticationFactorMethod;\n /** The id of the enrolled factor (opaque to the SPA, must be echoed back in the proof for methods that don't bind another way) */\n methodId: string;\n /** The factor kind (knowledge, possession, biometric) — the SPA filters against step-up `acceptableKinds`/`excludeKinds` hints */\n kind: AuthenticationFactorKind;\n /** Optional human-readable label (e.g. provider name for OIDC, friendly name for FIDO) */\n label?: string;\n}\n\nexport interface MfaChallengeFactorOutput {\n /** The factor method */\n method: AuthenticationFactorMethod;\n /** The id of the enrolled factor (opaque to the SPA, must be echoed back in the proof for methods that don't bind another way) */\n method_id: string;\n /** The factor kind (knowledge, possession, biometric) — the SPA filters against step-up `acceptableKinds`/`excludeKinds` hints */\n kind: AuthenticationFactorKind;\n /** Optional human-readable label (e.g. provider name for OIDC, friendly name for FIDO) */\n label?: string;\n}\n\n/**\n * generated from [AuthenticationFactor](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface AuthenticationFactor {\n /** The method of the factor */\n method: AuthenticationFactorMethod;\n /** The kind of the factor */\n kind: AuthenticationFactorKind;\n /** The method identifier */\n methodId: string;\n /** The label for the factor */\n label?: string;\n}\n\n/**\n * Mint a fresh MFA challenge for the current session so the SPA can satisfy a `step_up_required` denial. Filters mirror `StepUpRequirement` from `@maroonedsoftware/policies`.\n * generated from [StepUpStartRequest](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface StepUpStartRequest {\n /** If set, only these factor methods are listed as eligible */\n acceptableMethods?: AuthenticationFactorMethod[];\n /** If set, only these factor kinds are listed as eligible */\n acceptableKinds?: AuthenticationFactorKind[];\n /** If set, factors with these methods are never listed */\n excludeMethods?: AuthenticationFactorMethod[];\n}\n\n/**\n * An identity provider the sign-in page can offer\n * generated from [OidcProviderSummary](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface OidcProviderSummary {\n /** What to start a sign-in with */\n name: OidcProvider;\n /** What its button says */\n label: string;\n}\n\n/**\n * generated from [PublicKeyCredentialWithAssertion](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface PublicKeyCredentialWithAssertion extends PublicKeyCredential {\n /** The client extension results */\n clientExtensionResults: SimpleClientExtensionResults;\n /** The authenticator assertion response */\n response: FidoAuthenticatorAssertionResponse;\n}\n\n/**\n * generated from [FidoPublicKeyCredentialRequestOptions](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface FidoPublicKeyCredentialRequestOptions {\n challenge: string;\n /** WebAuthn timeout hint in milliseconds */\n timeout?: number;\n rpId?: string;\n /** The attestation */\n attestation?: 'direct' | 'indirect' | 'none';\n /** Whether the authenticator must verify the user */\n userVerification?: 'required' | 'preferred' | 'discouraged';\n /** The raw challenge */\n rawChallenge?: Blob;\n extensions?: Record<string, unknown>;\n allowCredentials?: PublicKeyCredentialDescriptor[];\n}\n\n/**\n * Serialized form of `AuthenticatorAttestationResponse` — produced by the browser at registration; all binary fields are base64-encoded for transport\n * generated from [FidoAuthenticatorAttestationResponse](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface FidoAuthenticatorAttestationResponse {\n /** The client data JSON */\n clientDataJSON: string;\n /** The attestation object */\n attestationObject: string;\n /** The transports used by the authenticator */\n transports?: FidoAuthenticatorTransport[];\n}\n\n/**\n * generated from [FactorChallengeStartRequest](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport type FactorChallengeStartRequest = FactorChallengePhoneStart | FactorChallengeFidoStart | FactorChallengeEmailStart;\n\n/**\n * An active authentication session\n * generated from [Session](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface Session {\n /** Opaque session token used as the cache key and embedded in JWTs */\n sessionToken: string;\n /** The actor that owns this session */\n actorId: string;\n /** When the session was originally issued */\n issuedAt: DateTime;\n /** When the session expires */\n expiresAt: DateTime;\n /** When the session was last accessed */\n lastAccessedAt: DateTime;\n /** Factors that have been satisfied in this session */\n factors: SessionFactor[];\n /** IP address recorded when the session was created */\n ip?: string | null;\n /** User agent recorded when the session was created */\n userAgent?: string | null;\n /** True when this session matches the requesting session */\n isCurrent: boolean;\n}\n\nexport interface SessionInput {}\n\n/** Rehydrates every wire-encoded scalar in a Session into its runtime type. Mutates and returns `raw`. */\nexport function reviveSession(raw: Session): Session {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['issuedAt'] = __dt(__o0['issuedAt'], 'Session.issuedAt');\n __o0['expiresAt'] = __dt(__o0['expiresAt'], 'Session.expiresAt');\n __o0['lastAccessedAt'] = __dt(__o0['lastAccessedAt'], 'Session.lastAccessedAt');\n {\n const __a1 = __o0['factors'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveSessionFactor(__a1[__i2] as never);\n }\n }\n return raw;\n}\n\n/**\n * Who the caller is, as the station sees them\n * generated from [AuthSession](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface AuthSession {\n /** The actor the session belongs to */\n actorId: string;\n /** Every platform role the caller holds, sorted. Empty for an account nobody has granted one, which today is any account that did not come in through onboarding */\n roles: PlatformRole[];\n}\n\n/**\n * A personal API key, as its owner sees it in a list. The token itself is never returned after it is issued\n * generated from [ApiKey](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface ApiKey {\n /** The key's identifier, for rotating or revoking it */\n id: string;\n /** What the account called the key */\n name: string;\n /** The token's first characters, enough to recognise the key in a config file and far too few to use */\n hint: string;\n /** What the key was granted. A key never does more than the account that owns it */\n scopes: ApiKeyScope[];\n /** When the key was issued */\n createdAt: DateTime;\n /** When the key stops working. Absent means it never expires */\n expiresAt?: DateTime;\n /** When the key was last used, to within five minutes. Absent means it has not been used */\n lastUsedAt?: DateTime;\n /** When the key was revoked. Present means every request made with it is refused */\n revokedAt?: DateTime;\n}\n\n/** Rehydrates every wire-encoded scalar in a ApiKey into its runtime type. Mutates and returns `raw`. */\nexport function reviveApiKey(raw: ApiKey): ApiKey {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['createdAt'] = __dt(__o0['createdAt'], 'ApiKey.createdAt');\n if (__o0['expiresAt'] != null) {\n __o0['expiresAt'] = __dt(__o0['expiresAt'], 'ApiKey.expiresAt');\n }\n if (__o0['lastUsedAt'] != null) {\n __o0['lastUsedAt'] = __dt(__o0['lastUsedAt'], 'ApiKey.lastUsedAt');\n }\n if (__o0['revokedAt'] != null) {\n __o0['revokedAt'] = __dt(__o0['revokedAt'], 'ApiKey.revokedAt');\n }\n return raw;\n}\n\n/**\n * A new API key\n * generated from [ApiKeyCreate](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface ApiKeyCreate {\n /** What to call the key, so a list of several says which is which */\n name: string;\n /** What the key may do. At least one; `manage` includes `view` */\n scopes: ApiKeyScope[];\n /** When the key should stop working. Omit for a key that never expires */\n expiresAt?: DateTime;\n}\n\n/** Rehydrates every wire-encoded scalar in a ApiKeyCreate into its runtime type. Mutates and returns `raw`. */\nexport function reviveApiKeyCreate(raw: ApiKeyCreate): ApiKeyCreate {\n const __o0 = raw as unknown as Record<string, unknown>;\n if (__o0['expiresAt'] != null) {\n __o0['expiresAt'] = __dt(__o0['expiresAt'], 'ApiKeyCreate.expiresAt');\n }\n return raw;\n}\n\n/**\n * Represents an application authentication request\n * generated from [ClientCredentialsAuthenticationRequest](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface ClientCredentialsAuthenticationRequest extends Omit<BaseAuthenticationRequest, 'grant_type' | 'client_id'> {\n /** The grant type for the request */\n grant_type: 'client_credentials';\n /** The client identifier */\n client_id: string;\n /** The client secret */\n client_secret: string;\n}\n\n/**\n * Represents an authentication password request\n * generated from [PasswordAuthenticationRequest](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface PasswordAuthenticationRequest extends Omit<BaseAuthenticationRequest, 'grant_type'> {\n /** The grant type for the request */\n grant_type: 'password';\n /** User's identifier, usually an email address */\n username: string;\n /** User's password */\n password: string;\n}\n\n/**\n * Represents an authentication refresh request\n * generated from [RefreshTokenAuthenticationRequest](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface RefreshTokenAuthenticationRequest extends Omit<BaseAuthenticationRequest, 'grant_type'> {\n /** The grant type for the request */\n grant_type: 'refresh_token';\n /** The refresh token issued by the authorization server. Optional: browser clients omit it and present the httpOnly refresh cookie instead */\n refresh_token?: string;\n}\n\n/**\n * Represents an authentication magic link request\n * generated from [LinkAuthenticationRequest](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface LinkAuthenticationRequest extends Omit<BaseAuthenticationRequest, 'grant_type'> {\n /** The grant type for the request */\n grant_type: 'link';\n /** The email challenge id returned by `POST /auth/login/start` — binds the link to the issued challenge so cross-device clicks work */\n challenge_id: string;\n /** The magic link token */\n link: string;\n}\n\n/**\n * Represents an authentication one-time-code request\n * generated from [CodeAuthenticationRequest](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface CodeAuthenticationRequest extends Omit<BaseAuthenticationRequest, 'grant_type'> {\n /** The grant type for the request */\n grant_type: 'code';\n /** The one-time code */\n code: string;\n /** PKCE verifier — required for a primary code login; absent when mfa_challenge_id is set */\n code_verifier?: string;\n /** When set, completes a pending MFA challenge; replaces code_verifier as proof-of-origin */\n mfa_challenge_id?: string;\n /** The phone/email challenge id (returned by POST /auth/factors/start for phone-MFA). Required when mfa_challenge_id is set; ignored otherwise (resolved via PKCE) */\n challenge_id?: string;\n}\n\n/**\n * Submit a TOTP code as a second factor against a pending MFA challenge\n * generated from [AuthenticatorAuthenticationRequest](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface AuthenticatorAuthenticationRequest extends Omit<BaseAuthenticationRequest, 'grant_type'> {\n /** The grant type for the request */\n grant_type: 'authenticator';\n /** The TOTP code */\n code: string;\n /** The pending MFA challenge — required, TOTP has no other actor binding at initial login */\n mfa_challenge_id: string;\n /** The id of the enrolled authenticator factor to verify against (must be present in the MFA challenge's eligible list) */\n method_id: string;\n}\n\n/**\n * Redeem a completed OIDC authorization that the callback stashed under a one-time id\n * generated from [OidcAuthenticationRequest](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface OidcAuthenticationRequest extends Omit<BaseAuthenticationRequest, 'grant_type'> {\n /** The grant type for the request */\n grant_type: 'oidc';\n /** The one-time stash id from the OIDC callback redirect (the value after `?token=oidc:` on `/auth/callback`). Single-use — the API consumes it via `OidcFactorService.redeemAuthenticatedExchange`. */\n challenge_id: string;\n}\n\n/**\n * generated from [BaseAuthenticationLoginStartWithEmail](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface BaseAuthenticationLoginStartWithEmail extends BaseAuthenticationLoginStart {\n /** User's email address */\n email: string;\n}\n\n/**\n * Request to begin an OIDC sign-in flow\n * generated from [OidcAuthenticationLoginStart](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface OidcAuthenticationLoginStart extends Omit<BaseAuthenticationLoginStart, 'grant_type'> {\n /** The grant type for the request */\n grant_type: 'oidc';\n /** The IdP to authorize against */\n provider: OidcProvider;\n /** A path on the console to return to once signed in, such as `/settings/security`. Anything that is not a same-origin path is ignored and the console opens at its home page */\n redirect_after?: string;\n}\n\n/**\n * generated from [CodeAuthenticationLoginStartResponse](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface CodeAuthenticationLoginStartResponse extends Omit<BaseAuthenticationLoginStartResponse, 'grant_type'> {\n /** The grant type for the response */\n grant_type: 'code';\n}\n\n/** Rehydrates every wire-encoded scalar in a CodeAuthenticationLoginStartResponse into its runtime type. Mutates and returns `raw`. */\nexport function reviveCodeAuthenticationLoginStartResponse(raw: CodeAuthenticationLoginStartResponse): CodeAuthenticationLoginStartResponse {\n reviveBaseAuthenticationLoginStartResponse(raw as never);\n return raw;\n}\n\n/**\n * generated from [LinkAuthenticationLoginStartResponse](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface LinkAuthenticationLoginStartResponse extends Omit<BaseAuthenticationLoginStartResponse, 'grant_type'> {\n /** The grant type for the response */\n grant_type: 'link';\n}\n\n/** Rehydrates every wire-encoded scalar in a LinkAuthenticationLoginStartResponse into its runtime type. Mutates and returns `raw`. */\nexport function reviveLinkAuthenticationLoginStartResponse(raw: LinkAuthenticationLoginStartResponse): LinkAuthenticationLoginStartResponse {\n reviveBaseAuthenticationLoginStartResponse(raw as never);\n return raw;\n}\n\n/**\n * Response from `/auth/login/oidc/start` instructing the client to navigate to `authorize_url`\n * generated from [OidcAuthenticationLoginStartResponse](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface OidcAuthenticationLoginStartResponse extends Omit<BaseAuthenticationLoginStartResponse, 'grant_type'> {\n /** The grant type for the response */\n grant_type: 'oidc';\n /** Fully-formed authorize URL the user-agent should be redirected to */\n authorize_url: string;\n /** Opaque state token bound to this authorization round-trip */\n state: string;\n}\n\n/** Rehydrates every wire-encoded scalar in a OidcAuthenticationLoginStartResponse into its runtime type. Mutates and returns `raw`. */\nexport function reviveOidcAuthenticationLoginStartResponse(raw: OidcAuthenticationLoginStartResponse): OidcAuthenticationLoginStartResponse {\n reviveBaseAuthenticationLoginStartResponse(raw as never);\n return raw;\n}\n\n/**\n * MFA-required arm of /auth/token response\n * generated from [MfaRequiredResponse](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface MfaRequiredResponse {\n /** Discriminator */\n result: 'mfa_required';\n /** The MFA challenge identifier — pass back as `mfa_challenge_id` on the proof grant */\n challengeId: string;\n /** When the MFA challenge expires */\n expiresAt: DateTime;\n /** Eligible factors the SPA may use to complete the challenge */\n factors: MfaChallengeFactor[];\n}\n\nexport interface MfaRequiredResponseOutput {\n /** Discriminator */\n result: 'mfa_required';\n /** The MFA challenge identifier — pass back as `mfa_challenge_id` on the proof grant */\n challenge_id: string;\n /** When the MFA challenge expires */\n expires_at: DateTime;\n /** Eligible factors the SPA may use to complete the challenge */\n factors: MfaChallengeFactorOutput[];\n}\n\n/** Rehydrates every wire-encoded scalar in a MfaRequiredResponse into its runtime type. Mutates and returns `raw`. */\nexport function reviveMfaRequiredResponse(raw: MfaRequiredResponse): MfaRequiredResponse {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['expiresAt'] = __dt(__o0['expiresAt'], 'MfaRequiredResponse.expiresAt');\n return raw;\n}\n\n/** Rehydrates every wire-encoded scalar in a MfaRequiredResponseOutput into its runtime type. Mutates and returns `raw`. */\nexport function reviveMfaRequiredResponseOutput(raw: MfaRequiredResponseOutput): MfaRequiredResponseOutput {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['expires_at'] = __dt(__o0['expires_at'], 'MfaRequiredResponse.expires_at');\n return raw;\n}\n\n/**\n * Represents an authentication passkey request\n * generated from [FidoAuthenticationRequest](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface FidoAuthenticationRequest extends Omit<BaseAuthenticationRequest, 'grant_type'> {\n /** The grant type for the request */\n grant_type: 'fido';\n /** A passkey credential object */\n credential: PublicKeyCredentialWithAssertion;\n /** The FIDO assertion challenge id returned by `POST /auth/login/start` (primary) or `POST /auth/factors/start` (MFA second factor). Must be the per-challenge id, not the actor id. */\n challenge_id: string;\n /** When set, completes a pending MFA challenge instead of issuing a single-factor session */\n mfa_challenge_id?: string;\n}\n\n/**\n * WebAuthn assertion options for `navigator.credentials.get`\n * generated from [FidoAuthenticationLoginStartResponse](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface FidoAuthenticationLoginStartResponse extends Omit<BaseAuthenticationLoginStartResponse, 'grant_type'> {\n /** The grant type for the response */\n grant_type: 'fido';\n /** The WebAuthn assertion options */\n assertion: FidoPublicKeyCredentialRequestOptions;\n}\n\n/** Rehydrates every wire-encoded scalar in a FidoAuthenticationLoginStartResponse into its runtime type. Mutates and returns `raw`. */\nexport function reviveFidoAuthenticationLoginStartResponse(raw: FidoAuthenticationLoginStartResponse): FidoAuthenticationLoginStartResponse {\n reviveBaseAuthenticationLoginStartResponse(raw as never);\n return raw;\n}\n\n/**\n * Response for a FIDO assertion challenge\n * generated from [FactorChallengeFidoStartResponse](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface FactorChallengeFidoStartResponse {\n /** Discriminator */\n method: 'fido';\n /** The FIDO-factor challenge id — echo back on the `fido` grant as `challenge_id` */\n fidoChallengeId: string;\n /** WebAuthn assertion options for navigator.credentials.get */\n assertion: FidoPublicKeyCredentialRequestOptions;\n /** When the FIDO challenge expires */\n expiresAt: DateTime;\n}\n\nexport interface FactorChallengeFidoStartResponseOutput {\n /** Discriminator */\n method: 'fido';\n /** The FIDO-factor challenge id — echo back on the `fido` grant as `challenge_id` */\n fido_challenge_id: string;\n /** WebAuthn assertion options for navigator.credentials.get */\n assertion: FidoPublicKeyCredentialRequestOptions;\n /** When the FIDO challenge expires */\n expires_at: DateTime;\n}\n\n/** Rehydrates every wire-encoded scalar in a FactorChallengeFidoStartResponse into its runtime type. Mutates and returns `raw`. */\nexport function reviveFactorChallengeFidoStartResponse(raw: FactorChallengeFidoStartResponse): FactorChallengeFidoStartResponse {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['expiresAt'] = __dt(__o0['expiresAt'], 'FactorChallengeFidoStartResponse.expiresAt');\n return raw;\n}\n\n/** Rehydrates every wire-encoded scalar in a FactorChallengeFidoStartResponseOutput into its runtime type. Mutates and returns `raw`. */\nexport function reviveFactorChallengeFidoStartResponseOutput(raw: FactorChallengeFidoStartResponseOutput): FactorChallengeFidoStartResponseOutput {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['expires_at'] = __dt(__o0['expires_at'], 'FactorChallengeFidoStartResponse.expires_at');\n return raw;\n}\n\n/**\n * The credential the client posts back to complete registration\n * generated from [PublicKeyCredentialWithAttestation](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface PublicKeyCredentialWithAttestation extends PublicKeyCredential {\n /** The client extension results */\n clientExtensionResults: SimpleClientExtensionResults;\n /** The authenticator attestation response */\n response: FidoAuthenticatorAttestationResponse;\n}\n\n/**\n * Every API key the account holds, newest first, revoked and expired keys included\n * generated from [ApiKeyList](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface ApiKeyList {\n keys: ApiKey[];\n}\n\n/** Rehydrates every wire-encoded scalar in a ApiKeyList into its runtime type. Mutates and returns `raw`. */\nexport function reviveApiKeyList(raw: ApiKeyList): ApiKeyList {\n const __o0 = raw as unknown as Record<string, unknown>;\n {\n const __a1 = __o0['keys'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveApiKey(__a1[__i2] as never);\n }\n }\n return raw;\n}\n\n/**\n * A key and its token. The only time the token is ever returned: store it now, because nothing can show it again\n * generated from [ApiKeyIssued](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface ApiKeyIssued {\n /** The key as it will appear in the list */\n key: ApiKey;\n /** The bearer token, sent as `Authorization: Bearer <token>` */\n token: string;\n}\n\n/** Rehydrates every wire-encoded scalar in a ApiKeyIssued into its runtime type. Mutates and returns `raw`. */\nexport function reviveApiKeyIssued(raw: ApiKeyIssued): ApiKeyIssued {\n const __o0 = raw as unknown as Record<string, unknown>;\n reviveApiKey(__o0['key'] as never);\n return raw;\n}\n\n/**\n * generated from [LinkAuthenticationLoginStart](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface LinkAuthenticationLoginStart extends Omit<BaseAuthenticationLoginStartWithEmail, 'grant_type'> {\n /** The grant type for the request */\n grant_type: 'link';\n /** What the link is for. `reset` words the email as a password reset and lands the person on the password form once signed in; the link and what it proves are the same. Absent means `signin` */\n purpose?: 'signin' | 'reset';\n}\n\n/**\n * generated from [CodeAuthenticationLoginStart](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface CodeAuthenticationLoginStart extends Omit<BaseAuthenticationLoginStartWithEmail, 'grant_type'> {\n /** The grant type for the request */\n grant_type: 'code';\n /** A base64url encoded SHA256 hash of a one time secret used to validate that the request starts and ends on the same device */\n code_challenge: string;\n}\n\n/**\n * generated from [FidoAuthenticationLoginStart](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport interface FidoAuthenticationLoginStart extends Omit<BaseAuthenticationLoginStartWithEmail, 'grant_type'> {\n /** The grant type for the request */\n grant_type: 'fido';\n}\n\n/**\n * generated from [StepUpStartResponse](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport type StepUpStartResponse = MfaRequiredResponse | EnrollmentRequiredResponse;\nexport type StepUpStartResponseOutput = MfaRequiredResponseOutput | EnrollmentRequiredResponseOutput;\n\n/** Rehydrates every wire-encoded scalar in a StepUpStartResponse into its runtime type. Mutates and returns `raw`. */\nexport function reviveStepUpStartResponse(raw: StepUpStartResponse): StepUpStartResponse {\n const __v = [raw] as unknown[];\n {\n const __d0 = (__v[0] as Record<string, unknown>)['result'];\n if (__d0 === 'mfa_required') {\n reviveMfaRequiredResponse(__v[0] as never);\n }\n }\n return __v[0] as StepUpStartResponse;\n}\n\n/** Rehydrates every wire-encoded scalar in a StepUpStartResponseOutput into its runtime type. Mutates and returns `raw`. */\nexport function reviveStepUpStartResponseOutput(raw: StepUpStartResponseOutput): StepUpStartResponseOutput {\n const __v = [raw] as unknown[];\n {\n const __d0 = (__v[0] as Record<string, unknown>)['result'];\n if (__d0 === 'mfa_required') {\n reviveMfaRequiredResponseOutput(__v[0] as never);\n }\n }\n return __v[0] as StepUpStartResponseOutput;\n}\n\n/**\n * generated from [AuthenticationTokenResponse](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport type AuthenticationTokenResponse = AuthenticationTokenIssued | MfaRequiredResponse;\nexport type AuthenticationTokenResponseOutput = AuthenticationTokenIssuedOutput | MfaRequiredResponseOutput;\n\n/** Rehydrates every wire-encoded scalar in a AuthenticationTokenResponse into its runtime type. Mutates and returns `raw`. */\nexport function reviveAuthenticationTokenResponse(raw: AuthenticationTokenResponse): AuthenticationTokenResponse {\n const __v = [raw] as unknown[];\n {\n const __d0 = (__v[0] as Record<string, unknown>)['result'];\n if (__d0 === 'mfa_required') {\n reviveMfaRequiredResponse(__v[0] as never);\n }\n }\n return __v[0] as AuthenticationTokenResponse;\n}\n\n/** Rehydrates every wire-encoded scalar in a AuthenticationTokenResponseOutput into its runtime type. Mutates and returns `raw`. */\nexport function reviveAuthenticationTokenResponseOutput(raw: AuthenticationTokenResponseOutput): AuthenticationTokenResponseOutput {\n const __v = [raw] as unknown[];\n {\n const __d0 = (__v[0] as Record<string, unknown>)['result'];\n if (__d0 === 'mfa_required') {\n reviveMfaRequiredResponseOutput(__v[0] as never);\n }\n }\n return __v[0] as AuthenticationTokenResponseOutput;\n}\n\n/**\n * generated from [AuthenticationRequest](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport type AuthenticationRequest =\n | PasswordAuthenticationRequest\n | ClientCredentialsAuthenticationRequest\n | RefreshTokenAuthenticationRequest\n | LinkAuthenticationRequest\n | CodeAuthenticationRequest\n | FidoAuthenticationRequest\n | AuthenticatorAuthenticationRequest\n | OidcAuthenticationRequest;\n\n/**\n * generated from [AuthenticationLoginStartResponse](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport type AuthenticationLoginStartResponse =\n | CodeAuthenticationLoginStartResponse\n | LinkAuthenticationLoginStartResponse\n | FidoAuthenticationLoginStartResponse\n | OidcAuthenticationLoginStartResponse;\n\n/** Rehydrates every wire-encoded scalar in a AuthenticationLoginStartResponse into its runtime type. Mutates and returns `raw`. */\nexport function reviveAuthenticationLoginStartResponse(raw: AuthenticationLoginStartResponse): AuthenticationLoginStartResponse {\n const __v = [raw] as unknown[];\n {\n const __d0 = (__v[0] as Record<string, unknown>)['grant_type'];\n if (__d0 === 'code') {\n reviveCodeAuthenticationLoginStartResponse(__v[0] as never);\n }\n if (__d0 === 'link') {\n reviveLinkAuthenticationLoginStartResponse(__v[0] as never);\n }\n if (__d0 === 'fido') {\n reviveFidoAuthenticationLoginStartResponse(__v[0] as never);\n }\n if (__d0 === 'oidc') {\n reviveOidcAuthenticationLoginStartResponse(__v[0] as never);\n }\n }\n return __v[0] as AuthenticationLoginStartResponse;\n}\n\n/**\n * generated from [FactorChallengeStartResponse](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport type FactorChallengeStartResponse = FactorChallengePhoneStartResponse | FactorChallengeFidoStartResponse | FactorChallengeEmailStartResponse;\nexport type FactorChallengeStartResponseOutput =\n FactorChallengePhoneStartResponseOutput | FactorChallengeFidoStartResponseOutput | FactorChallengeEmailStartResponseOutput;\n\n/** Rehydrates every wire-encoded scalar in a FactorChallengeStartResponse into its runtime type. Mutates and returns `raw`. */\nexport function reviveFactorChallengeStartResponse(raw: FactorChallengeStartResponse): FactorChallengeStartResponse {\n const __v = [raw] as unknown[];\n {\n const __d0 = (__v[0] as Record<string, unknown>)['method'];\n if (__d0 === 'phone') {\n reviveFactorChallengePhoneStartResponse(__v[0] as never);\n }\n if (__d0 === 'fido') {\n reviveFactorChallengeFidoStartResponse(__v[0] as never);\n }\n if (__d0 === 'email') {\n reviveFactorChallengeEmailStartResponse(__v[0] as never);\n }\n }\n return __v[0] as FactorChallengeStartResponse;\n}\n\n/** Rehydrates every wire-encoded scalar in a FactorChallengeStartResponseOutput into its runtime type. Mutates and returns `raw`. */\nexport function reviveFactorChallengeStartResponseOutput(raw: FactorChallengeStartResponseOutput): FactorChallengeStartResponseOutput {\n const __v = [raw] as unknown[];\n {\n const __d0 = (__v[0] as Record<string, unknown>)['method'];\n if (__d0 === 'phone') {\n reviveFactorChallengePhoneStartResponseOutput(__v[0] as never);\n }\n if (__d0 === 'fido') {\n reviveFactorChallengeFidoStartResponseOutput(__v[0] as never);\n }\n if (__d0 === 'email') {\n reviveFactorChallengeEmailStartResponseOutput(__v[0] as never);\n }\n }\n return __v[0] as FactorChallengeStartResponseOutput;\n}\n\n/**\n * generated from [AuthenticationLoginStart](../../../../../apps/api/data/contracts/authentication/authentication.types.ck)\n */\nexport type AuthenticationLoginStart =\n LinkAuthenticationLoginStart | CodeAuthenticationLoginStart | FidoAuthenticationLoginStart | OidcAuthenticationLoginStart;\n","import type { ApiKeyCreate, ApiKeyIssued, ApiKeyList } from './types/authentication.types.js';\nimport { reviveApiKeyIssued, reviveApiKeyList } from './types/authentication.types.js';\nimport type { SdkFetch } from '../sdk-options.js';\nimport { bigIntReplacer, parseJson } from '../sdk-options.js';\n\n/**\n * generated from [authentication.apikeys.ck](../../../../apps/api/data/contracts/authentication/authentication.apikeys.ck)\n */\nexport class AuthenticationApikeysClient {\n constructor(private fetch: SdkFetch) {}\n\n /**\n * @name List API keys\n * @description The signed-in account's API keys, newest first, including revoked and expired ones so the list says what was withdrawn and when\n */\n async listAPIKeys(): Promise<ApiKeyList> {\n const result = await this.fetch(`/auth/apikeys`, { method: 'GET' });\n return reviveApiKeyList(await parseJson<ApiKeyList>(result));\n }\n\n /**\n * @name Create API key\n * @description Issue a new API key for the signed-in account. The token is in this response and nowhere else, ever. Once the account has a strong second factor, this needs one verified in the last five minutes\n */\n async createAPIKey(body: ApiKeyCreate): Promise<ApiKeyIssued> {\n const result = await this.fetch(`/auth/apikeys`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return reviveApiKeyIssued(await parseJson<ApiKeyIssued>(result));\n }\n\n /**\n * @name Rotate API key\n * @description Give a key a new token, so the old one stops working at once. The key keeps its name, scopes and expiry. Needs the same recent second factor as creating one\n */\n async rotateAPIKey(id: string): Promise<ApiKeyIssued> {\n const result = await this.fetch(`/auth/apikeys/${encodeURIComponent(id)}/rotate`, { method: 'POST' });\n return reviveApiKeyIssued(await parseJson<ApiKeyIssued>(result));\n }\n\n /**\n * @name Revoke API key\n * @description Revoke a key. Every request made with it is refused from the next one on. The key stays in the list, marked revoked\n */\n async revokeAPIKey(id: string): Promise<void> {\n await this.fetch(`/auth/apikeys/${encodeURIComponent(id)}`, { method: 'DELETE' });\n }\n}\n","import { DateTime } from 'luxon';\nimport type { OidcProvider } from './authentication.types.js';\nimport type { PublicKeyCredentialWithAttestation } from './authentication.types.js';\n\nconst __dt = (v: unknown, path: string): DateTime => {\n if (typeof v !== 'string') {\n throw new TypeError(`ContractKit: expected an ISO 8601 string at '${path}', received ${typeof v}.`);\n }\n const d = DateTime.fromISO(v);\n if (!d.isValid) throw new TypeError(`ContractKit: '${v}' at '${path}' is not a valid ISO 8601 datetime.`);\n return d;\n};\n\n/**\n * generated from [PhoneFactorRegistration](../../../../../apps/api/data/contracts/authentication/registration.types.ck)\n */\nexport interface PhoneFactorRegistration {\n /** The method of the factor */\n method: 'phone';\n /** The phone number in E.164 format (e.g. `+12025550123`) */\n value: string;\n /** A base64url encoded SHA256 hash of a one time secret used to validate that the request starts and ends on the same device */\n codeChallenge: string;\n}\n\n/**\n * generated from [PasswordFactorRegistration](../../../../../apps/api/data/contracts/authentication/registration.types.ck)\n */\nexport interface PasswordFactorRegistration {\n /** The method of the factor */\n method: 'password';\n /** The password */\n value: string;\n}\n\n/**\n * generated from [PasswordChange](../../../../../apps/api/data/contracts/authentication/registration.types.ck)\n */\nexport interface PasswordChange {\n /** The new password */\n password: string;\n /** The password it replaces. Needed when the account has one, unless a sign-in link was used in the last ten minutes */\n currentPassword?: string;\n}\n\n/**\n * generated from [EmailFactorRegistration](../../../../../apps/api/data/contracts/authentication/registration.types.ck)\n */\nexport interface EmailFactorRegistration {\n /** The method of the factor */\n method: 'email';\n /** The email address */\n value: string;\n /** A base64url encoded SHA256 hash of a one time secret used to validate that the request starts and ends on the same device */\n codeChallenge: string;\n}\n\n/**\n * generated from [AuthenticatorFactorRegistration](../../../../../apps/api/data/contracts/authentication/registration.types.ck)\n */\nexport interface AuthenticatorFactorRegistration {\n /** The method of the factor */\n method: 'authenticator';\n /** A base64url encoded SHA256 hash of a one time secret used to validate that the request starts and ends on the same device */\n codeChallenge: string;\n /** The label for the authenticator factor */\n label?: string;\n}\n\n/**\n * generated from [FidoFactorRegistration](../../../../../apps/api/data/contracts/authentication/registration.types.ck)\n */\nexport interface FidoFactorRegistration {\n /** The method of the factor */\n method: 'fido';\n /** The label for the FIDO factor */\n label?: string;\n}\n\n/**\n * Link an identity provider to the signed-in account. Answered with the provider's address; the browser goes there and comes back to Security\n * generated from [OidcFactorRegistration](../../../../../apps/api/data/contracts/authentication/registration.types.ck)\n */\nexport interface OidcFactorRegistration {\n /** The method of the factor */\n method: 'oidc';\n /** The provider to link, as `GET /auth/login/oidc/providers` names it */\n provider: OidcProvider;\n}\n\n/**\n * generated from [PhoneFactorRegistrationResponse](../../../../../apps/api/data/contracts/authentication/registration.types.ck)\n */\nexport interface PhoneFactorRegistrationResponse {\n /** The method of the factor */\n method: 'phone';\n /** The registration identifier */\n registrationId: string;\n /** The expiration timestamp */\n expiresAt: DateTime;\n /** The issuance timestamp */\n issuedAt: DateTime;\n}\n\n/** Rehydrates every wire-encoded scalar in a PhoneFactorRegistrationResponse into its runtime type. Mutates and returns `raw`. */\nexport function revivePhoneFactorRegistrationResponse(raw: PhoneFactorRegistrationResponse): PhoneFactorRegistrationResponse {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['expiresAt'] = __dt(__o0['expiresAt'], 'PhoneFactorRegistrationResponse.expiresAt');\n __o0['issuedAt'] = __dt(__o0['issuedAt'], 'PhoneFactorRegistrationResponse.issuedAt');\n return raw;\n}\n\n/**\n * generated from [PasswordFactorRegistrationResponse](../../../../../apps/api/data/contracts/authentication/registration.types.ck)\n */\nexport interface PasswordFactorRegistrationResponse {\n /** The method of the factor */\n method: 'password';\n /** Whether the password needs to be reset */\n needsReset: boolean;\n}\n\n/**\n * generated from [EmailFactorRegistrationResponse](../../../../../apps/api/data/contracts/authentication/registration.types.ck)\n */\nexport interface EmailFactorRegistrationResponse {\n /** The method of the factor */\n method: 'email';\n /** The registration identifier */\n registrationId: string;\n /** The expiration timestamp */\n expiresAt: DateTime;\n /** The issuance timestamp */\n issuedAt: DateTime;\n}\n\n/** Rehydrates every wire-encoded scalar in a EmailFactorRegistrationResponse into its runtime type. Mutates and returns `raw`. */\nexport function reviveEmailFactorRegistrationResponse(raw: EmailFactorRegistrationResponse): EmailFactorRegistrationResponse {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['expiresAt'] = __dt(__o0['expiresAt'], 'EmailFactorRegistrationResponse.expiresAt');\n __o0['issuedAt'] = __dt(__o0['issuedAt'], 'EmailFactorRegistrationResponse.issuedAt');\n return raw;\n}\n\n/**\n * generated from [AuthenticatorFactorRegistrationResponse](../../../../../apps/api/data/contracts/authentication/registration.types.ck)\n */\nexport interface AuthenticatorFactorRegistrationResponse {\n /** The method of the factor */\n method: 'authenticator';\n /** The registration identifier */\n registrationId: string;\n /** The secret for the authenticator */\n secret: string;\n /** The URI for the authenticator */\n uri: string;\n /** The QR code for the authenticator */\n qrCode: string;\n /** The expiration timestamp */\n expiresAt: DateTime;\n /** The issuance timestamp */\n issuedAt: DateTime;\n}\n\n/** Rehydrates every wire-encoded scalar in a AuthenticatorFactorRegistrationResponse into its runtime type. Mutates and returns `raw`. */\nexport function reviveAuthenticatorFactorRegistrationResponse(raw: AuthenticatorFactorRegistrationResponse): AuthenticatorFactorRegistrationResponse {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['expiresAt'] = __dt(__o0['expiresAt'], 'AuthenticatorFactorRegistrationResponse.expiresAt');\n __o0['issuedAt'] = __dt(__o0['issuedAt'], 'AuthenticatorFactorRegistrationResponse.issuedAt');\n return raw;\n}\n\n/**\n * The FIDO factor attestation information\n * generated from [FidoFactorAttestation](../../../../../apps/api/data/contracts/authentication/registration.types.ck)\n */\nexport interface FidoFactorAttestation {\n /** The relying party */\n rp: { name: string; id: string; icon?: string };\n user: { id: string; name: string; displayName: string };\n /** The challenge */\n challenge: string;\n /** The public key credential parameters */\n pubKeyCredParams: { type: 'public-key'; alg: number }[];\n /** The timeout */\n timeout?: number;\n /** The attestation */\n attestation: 'direct' | 'indirect' | 'none';\n}\n\n/**\n * generated from [OidcFactorRegistrationResponse](../../../../../apps/api/data/contracts/authentication/registration.types.ck)\n */\nexport interface OidcFactorRegistrationResponse {\n /** The method of the factor */\n method: 'oidc';\n /** Where to send the browser. The provider sends it back to Security, with `?linked=<provider>` on success */\n authorizeUrl: string;\n /** When the link attempt expires if the provider has not answered */\n expiresAt: DateTime;\n}\n\n/** Rehydrates every wire-encoded scalar in a OidcFactorRegistrationResponse into its runtime type. Mutates and returns `raw`. */\nexport function reviveOidcFactorRegistrationResponse(raw: OidcFactorRegistrationResponse): OidcFactorRegistrationResponse {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['expiresAt'] = __dt(__o0['expiresAt'], 'OidcFactorRegistrationResponse.expiresAt');\n return raw;\n}\n\n/**\n * generated from [PhoneFactorRegistrationVerification](../../../../../apps/api/data/contracts/authentication/registration.types.ck)\n */\nexport interface PhoneFactorRegistrationVerification {\n /** The method of the factor */\n method: 'phone';\n /** The registration identifier */\n registrationId: string;\n /** The verification code */\n code: string;\n /** A base64url encoded one time secret used to validate that the request starts and ends on the same device */\n codeVerifier: string;\n}\n\n/**\n * generated from [EmailFactorRegistrationVerification](../../../../../apps/api/data/contracts/authentication/registration.types.ck)\n */\nexport interface EmailFactorRegistrationVerification {\n /** The method of the factor */\n method: 'email';\n /** The registration identifier */\n registrationId: string;\n /** The verification code */\n code: string;\n /** A base64url encoded one time secret used to validate that the request starts and ends on the same device */\n codeVerifier: string;\n}\n\n/**\n * generated from [AuthenticatorFactorRegistrationVerification](../../../../../apps/api/data/contracts/authentication/registration.types.ck)\n */\nexport interface AuthenticatorFactorRegistrationVerification {\n /** The method of the factor */\n method: 'authenticator';\n /** The registration identifier */\n registrationId: string;\n /** The verification code */\n code: string;\n /** A base64url encoded one time secret used to validate that the request starts and ends on the same device */\n codeVerifier: string;\n}\n\n/**\n * generated from [FidoFactorRegistrationVerification](../../../../../apps/api/data/contracts/authentication/registration.types.ck)\n */\nexport interface FidoFactorRegistrationVerification {\n /** The method of the factor */\n method: 'fido';\n /** The registration identifier */\n registrationId: string;\n /** The credential the client posts back to complete registration */\n credential: PublicKeyCredentialWithAttestation;\n}\n\n/**\n * Begin enrolling a TOTP authenticator during a pending login MFA challenge (no session — authorized by the challenge)\n * generated from [MfaEnrollAuthenticatorStart](../../../../../apps/api/data/contracts/authentication/registration.types.ck)\n */\nexport interface MfaEnrollAuthenticatorStart {\n /** The pending MFA challenge from the `mfa_required` login response */\n mfa_challenge_id: string;\n /** Optional label for the new authenticator factor */\n label?: string;\n}\n\n/**\n * Verify the first TOTP code, persist the authenticator, and complete login\n * generated from [MfaEnrollAuthenticatorVerify](../../../../../apps/api/data/contracts/authentication/registration.types.ck)\n */\nexport interface MfaEnrollAuthenticatorVerify {\n /** The same pending MFA challenge */\n mfa_challenge_id: string;\n /** The registration id returned by the enroll-start response */\n registrationId: string;\n /** The first TOTP code from the user's authenticator app */\n code: string;\n}\n\n/**\n * A second-factor method a user may enroll\n * generated from [EnrollmentMethod](../../../../../apps/api/data/contracts/authentication/registration.types.ck)\n */\nexport type EnrollmentMethod = 'authenticator' | 'phone' | 'fido';\n\n/**\n * Begin enrolling an SMS phone factor during a pending login MFA challenge (no session — authorized by the challenge)\n * generated from [MfaEnrollPhoneStart](../../../../../apps/api/data/contracts/authentication/registration.types.ck)\n */\nexport interface MfaEnrollPhoneStart {\n /** The pending MFA challenge from the `mfa_required` login response */\n mfa_challenge_id: string;\n /** The phone number in E.164 format (e.g. `+12025550123`) */\n value: string;\n}\n\n/**\n * Acknowledges the phone registration and that an OTP was texted\n * generated from [MfaEnrollPhoneStartResponse](../../../../../apps/api/data/contracts/authentication/registration.types.ck)\n */\nexport interface MfaEnrollPhoneStartResponse {\n /** The method of the factor */\n method: 'phone';\n /** The registration id — echo back on the verify call */\n registrationId: string;\n /** When the registration expires */\n expiresAt: DateTime;\n /** When the registration was issued */\n issuedAt: DateTime;\n}\n\n/** Rehydrates every wire-encoded scalar in a MfaEnrollPhoneStartResponse into its runtime type. Mutates and returns `raw`. */\nexport function reviveMfaEnrollPhoneStartResponse(raw: MfaEnrollPhoneStartResponse): MfaEnrollPhoneStartResponse {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['expiresAt'] = __dt(__o0['expiresAt'], 'MfaEnrollPhoneStartResponse.expiresAt');\n __o0['issuedAt'] = __dt(__o0['issuedAt'], 'MfaEnrollPhoneStartResponse.issuedAt');\n return raw;\n}\n\n/**\n * Verify the texted OTP, persist the phone factor, and complete login\n * generated from [MfaEnrollPhoneVerify](../../../../../apps/api/data/contracts/authentication/registration.types.ck)\n */\nexport interface MfaEnrollPhoneVerify {\n /** The same pending MFA challenge */\n mfa_challenge_id: string;\n /** The registration id returned by the enroll-start response */\n registrationId: string;\n /** The one-time code texted to the phone */\n code: string;\n}\n\n/**\n * Begin enrolling a passkey during a pending login MFA challenge (no session — authorized by the challenge)\n * generated from [MfaEnrollFidoStart](../../../../../apps/api/data/contracts/authentication/registration.types.ck)\n */\nexport interface MfaEnrollFidoStart {\n /** The pending MFA challenge from the `mfa_required` login response */\n mfa_challenge_id: string;\n /** Optional label for the new passkey factor */\n label?: string;\n}\n\n/**\n * Post the new credential back, persist the passkey factor, and complete login\n * generated from [MfaEnrollFidoVerify](../../../../../apps/api/data/contracts/authentication/registration.types.ck)\n */\nexport interface MfaEnrollFidoVerify {\n /** The same pending MFA challenge */\n mfa_challenge_id: string;\n /** The registration id returned by the enroll-start response */\n registrationId: string;\n /** The credential produced by `navigator.credentials.create` */\n credential: PublicKeyCredentialWithAttestation;\n}\n\n/**\n * generated from [AuthenticationFactorRegistration](../../../../../apps/api/data/contracts/authentication/registration.types.ck)\n */\nexport type AuthenticationFactorRegistration =\n | PhoneFactorRegistration\n | PasswordFactorRegistration\n | EmailFactorRegistration\n | AuthenticatorFactorRegistration\n | FidoFactorRegistration\n | OidcFactorRegistration;\n\n/**\n * generated from [FidoFactorRegistrationResponse](../../../../../apps/api/data/contracts/authentication/registration.types.ck)\n */\nexport interface FidoFactorRegistrationResponse {\n /** The method of the factor */\n method: 'fido';\n /** The registration identifier */\n registrationId: string;\n /** The expiration timestamp */\n expiresAt: DateTime;\n /** The issuance timestamp */\n issuedAt: DateTime;\n /** The FIDO factor attestation information */\n attestation: FidoFactorAttestation;\n}\n\n/** Rehydrates every wire-encoded scalar in a FidoFactorRegistrationResponse into its runtime type. Mutates and returns `raw`. */\nexport function reviveFidoFactorRegistrationResponse(raw: FidoFactorRegistrationResponse): FidoFactorRegistrationResponse {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['expiresAt'] = __dt(__o0['expiresAt'], 'FidoFactorRegistrationResponse.expiresAt');\n __o0['issuedAt'] = __dt(__o0['issuedAt'], 'FidoFactorRegistrationResponse.issuedAt');\n return raw;\n}\n\n/**\n * WebAuthn attestation options for `navigator.credentials.create`\n * generated from [MfaEnrollFidoStartResponse](../../../../../apps/api/data/contracts/authentication/registration.types.ck)\n */\nexport interface MfaEnrollFidoStartResponse {\n /** The method of the factor */\n method: 'fido';\n /** The registration id — echo back on the verify call */\n registrationId: string;\n /** When the registration expires */\n expiresAt: DateTime;\n /** When the registration was issued */\n issuedAt: DateTime;\n /** The WebAuthn attestation (credential-creation) options */\n attestation: FidoFactorAttestation;\n}\n\n/** Rehydrates every wire-encoded scalar in a MfaEnrollFidoStartResponse into its runtime type. Mutates and returns `raw`. */\nexport function reviveMfaEnrollFidoStartResponse(raw: MfaEnrollFidoStartResponse): MfaEnrollFidoStartResponse {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['expiresAt'] = __dt(__o0['expiresAt'], 'MfaEnrollFidoStartResponse.expiresAt');\n __o0['issuedAt'] = __dt(__o0['issuedAt'], 'MfaEnrollFidoStartResponse.issuedAt');\n return raw;\n}\n\n/**\n * generated from [AuthenticationFactorRegistrationVerification](../../../../../apps/api/data/contracts/authentication/registration.types.ck)\n */\nexport type AuthenticationFactorRegistrationVerification =\n | PhoneFactorRegistrationVerification\n | EmailFactorRegistrationVerification\n | AuthenticatorFactorRegistrationVerification\n | FidoFactorRegistrationVerification;\n\n/**\n * Which second factors this instance permits enrolling. `phone` is present only when an SMS provider is configured (SMS_DELIVERY != noop); `authenticator` and `fido` are always available.\n * generated from [EnrollmentMethods](../../../../../apps/api/data/contracts/authentication/registration.types.ck)\n */\nexport interface EnrollmentMethods {\n /** The enrollable factor methods, in suggested display order */\n methods: EnrollmentMethod[];\n}\n\n/**\n * generated from [AuthenticationFactorRegistrationResponse](../../../../../apps/api/data/contracts/authentication/registration.types.ck)\n */\nexport type AuthenticationFactorRegistrationResponse =\n | PhoneFactorRegistrationResponse\n | PasswordFactorRegistrationResponse\n | EmailFactorRegistrationResponse\n | AuthenticatorFactorRegistrationResponse\n | FidoFactorRegistrationResponse\n | OidcFactorRegistrationResponse;\n\n/** Rehydrates every wire-encoded scalar in a AuthenticationFactorRegistrationResponse into its runtime type. Mutates and returns `raw`. */\nexport function reviveAuthenticationFactorRegistrationResponse(\n raw: AuthenticationFactorRegistrationResponse,\n): AuthenticationFactorRegistrationResponse {\n const __v = [raw] as unknown[];\n {\n const __d0 = (__v[0] as Record<string, unknown>)['method'];\n if (__d0 === 'phone') {\n revivePhoneFactorRegistrationResponse(__v[0] as never);\n }\n if (__d0 === 'email') {\n reviveEmailFactorRegistrationResponse(__v[0] as never);\n }\n if (__d0 === 'authenticator') {\n reviveAuthenticatorFactorRegistrationResponse(__v[0] as never);\n }\n if (__d0 === 'fido') {\n reviveFidoFactorRegistrationResponse(__v[0] as never);\n }\n if (__d0 === 'oidc') {\n reviveOidcFactorRegistrationResponse(__v[0] as never);\n }\n }\n return __v[0] as AuthenticationFactorRegistrationResponse;\n}\n","import type {\n AuthenticationFactor,\n AuthenticationFactorMethod,\n AuthenticationTokenOutput,\n FactorChallengeStartRequest,\n FactorChallengeStartResponseOutput,\n StepUpStartRequest,\n StepUpStartResponseOutput,\n} from './types/authentication.types.js';\nimport { reviveFactorChallengeStartResponseOutput, reviveStepUpStartResponseOutput } from './types/authentication.types.js';\nimport type {\n AuthenticationFactorRegistration,\n AuthenticationFactorRegistrationResponse,\n AuthenticationFactorRegistrationVerification,\n PasswordChange,\n} from './types/registration.types.js';\nimport { reviveAuthenticationFactorRegistrationResponse } from './types/registration.types.js';\nimport type { SdkFetch } from '../sdk-options.js';\nimport { bigIntReplacer, parseJson } from '../sdk-options.js';\n\n/**\n * generated from [authentication.factor.ck](../../../../apps/api/data/contracts/authentication/authentication.factor.ck)\n */\nexport class AuthenticationFactorsClient {\n constructor(private fetch: SdkFetch) {}\n\n /**\n * @name List factors\n * @description List authentication factors\n */\n async listFactors(): Promise<AuthenticationFactor[]> {\n const result = await this.fetch(`/auth/factors`, { method: 'GET' });\n return await parseJson<AuthenticationFactor[]>(result);\n }\n\n /**\n * @name Register factor\n * @description Register an authentication factor\n */\n async registerFactor(body: AuthenticationFactorRegistration): Promise<AuthenticationFactorRegistrationResponse> {\n const result = await this.fetch(`/auth/factors/register`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return reviveAuthenticationFactorRegistrationResponse(await parseJson<AuthenticationFactorRegistrationResponse>(result));\n }\n\n /**\n * @name Set password\n * @description Set or change the caller's own password. Needs the current one when there is one, unless a sign-in link was used in the last ten minutes, and a recent strong-factor verification once an authenticator or passkey is enrolled. Every other session of the account is signed out, and the account's email addresses are told.\n */\n async setPassword(body: PasswordChange): Promise<void> {\n await this.fetch(`/auth/password`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n }\n\n /**\n * @name Verify factor registration\n * @description Verify an authentication factor registration\n */\n async verifyFactorRegistration(body: AuthenticationFactorRegistrationVerification): Promise<AuthenticationTokenOutput> {\n const result = await this.fetch(`/auth/factors/verify`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<AuthenticationTokenOutput>(result);\n }\n\n /**\n * @name Start factor challenge\n * @description Issue a factor verification challenge for a pending MFA round. Authenticated via the short-lived `mfa_challenge_id` in the body, not by session — this is the only /auth/factors/* route that does not require an authenticated session.\n */\n async startFactorChallenge(body: FactorChallengeStartRequest): Promise<FactorChallengeStartResponseOutput> {\n const result = await this.fetch(`/auth/factors/start`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return reviveFactorChallengeStartResponseOutput(await parseJson<FactorChallengeStartResponseOutput>(result));\n }\n\n /**\n * @name Start MFA challenge\n * @description Mint a fresh MFA challenge for the *current* authenticated session so the SPA can satisfy a `step_up_required` denial. Optionally filters eligible factors against an inbound `StepUpRequirement` hint. Returns `enrollment_required` when no enrolled factor matches the requirement so the SPA can route the user into enrollment instead of getting stuck.\n */\n async startMFAChallenge(body: StepUpStartRequest): Promise<StepUpStartResponseOutput> {\n const result = await this.fetch(`/auth/mfa/start`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return reviveStepUpStartResponseOutput(await parseJson<StepUpStartResponseOutput>(result));\n }\n\n /**\n * @name Remove factor\n * @description Remove one of the caller's own factors. Answered for `authenticator` and `oidc`, and only after a recent strong-factor verification: the same gate enrolment sits behind once a strong factor exists, so a stolen session cannot quietly switch the second factor off. Removing the last authenticator turns the sign-in challenge off for that account. A linked identity provider that is the account's only way to sign in is refused with 409.\n */\n async removeFactor(method: AuthenticationFactorMethod, methodId: string): Promise<void> {\n await this.fetch(`/auth/factors/${encodeURIComponent(method)}/${encodeURIComponent(methodId)}`, { method: 'DELETE' });\n }\n}\n","import type { AuthSession } from './types/authentication.types.js';\nimport type { SdkFetch } from '../sdk-options.js';\nimport { parseJson } from '../sdk-options.js';\n\n/**\n * generated from [authentication.sessions.ck](../../../../apps/api/data/contracts/authentication/authentication.sessions.ck)\n */\nexport class AuthenticationSessionsClient {\n constructor(private fetch: SdkFetch) {}\n\n /**\n * @name Logout\n * @description revoke the caller's current session (self sign-out). Deliberately carries no policy gate: signing out must always clear the browser's httpOnly refresh cookie, including for a caller whose access token has already expired. A 401 here would leave a 30-day refresh cookie behind that silently signs the user back in on the next page load. SessionsService revokes the session only when the caller is actually authenticated; an anonymous caller still gets 204 and a cleared cookie.\n */\n async logout(): Promise<void> {\n await this.fetch(`/auth/logout`, { method: 'POST' });\n }\n\n /**\n * @name Read session\n * @description Who the caller is and which platform roles they hold\n */\n async readSession(): Promise<AuthSession> {\n const result = await this.fetch(`/auth/session`, { method: 'GET' });\n return await parseJson<AuthSession>(result);\n }\n}\n","import type { SdkFetch } from '../sdk-options.js';\nimport { bigIntReplacer, parseJson } from '../sdk-options.js';\nimport type {\n AuthenticationLoginStart,\n AuthenticationLoginStartResponse,\n AuthenticationRegistration,\n AuthenticationRegistrationInput,\n AuthenticationRegistrationVerification,\n AuthenticationRequest,\n AuthenticationTokenOutput,\n AuthenticationTokenResponseOutput,\n OidcProviderSummary,\n} from './types/authentication.types.js';\nimport {\n reviveAuthenticationLoginStartResponse,\n reviveAuthenticationRegistration,\n reviveAuthenticationTokenResponseOutput,\n} from './types/authentication.types.js';\nimport { AuthenticationApikeysClient } from './authentication.apikeys.client.js';\nimport { AuthenticationFactorsClient } from './authentication.factor.client.js';\nimport { AuthenticationSessionsClient } from './authentication.sessions.client.js';\n\nexport class AuthenticationClient {\n readonly apikeys: AuthenticationApikeysClient;\n readonly factors: AuthenticationFactorsClient;\n readonly sessions: AuthenticationSessionsClient;\n\n constructor(private fetch: SdkFetch) {\n this.apikeys = new AuthenticationApikeysClient(fetch);\n this.factors = new AuthenticationFactorsClient(fetch);\n this.sessions = new AuthenticationSessionsClient(fetch);\n }\n\n /**\n * @name Request token\n * @description Request authenticated token\n */\n async requestToken(\n body: AuthenticationRequest,\n options?: { contentType?: 'application/x-www-form-urlencoded' | 'application/json' },\n ): Promise<AuthenticationTokenResponseOutput> {\n const __contentType = options?.contentType ?? 'application/x-www-form-urlencoded';\n const __serialized =\n __contentType === 'application/x-www-form-urlencoded'\n ? new URLSearchParams(body as unknown as Record<string, string>).toString()\n : JSON.stringify(body, bigIntReplacer);\n const result = await this.fetch(`/auth/token`, {\n method: 'POST',\n headers: { 'Content-Type': __contentType },\n body: __serialized,\n });\n return reviveAuthenticationTokenResponseOutput(await parseJson<AuthenticationTokenResponseOutput>(result));\n }\n\n /**\n * @name Register login\n * @description Register a new login\n */\n async registerLogin(body: AuthenticationRegistrationInput): Promise<AuthenticationRegistration> {\n const result = await this.fetch(`/auth/login/register`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return reviveAuthenticationRegistration(await parseJson<AuthenticationRegistration>(result));\n }\n\n /**\n * @name Verify login registration\n * @description Verify a login registration\n */\n async verifyLoginRegistration(body: AuthenticationRegistrationVerification): Promise<AuthenticationTokenOutput> {\n const result = await this.fetch(`/auth/login/verify`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<AuthenticationTokenOutput>(result);\n }\n\n /**\n * @name Start login\n * @description Start a password-less login process\n */\n async startLogin(body: AuthenticationLoginStart): Promise<AuthenticationLoginStartResponse> {\n const result = await this.fetch(`/auth/login/start`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return reviveAuthenticationLoginStartResponse(await parseJson<AuthenticationLoginStartResponse>(result));\n }\n\n /**\n * @name List sign-in providers\n * @description The identity providers the sign-in page offers beside a password, in the order the operator listed them. Empty when none is set up\n */\n async listSignInProviders(): Promise<OidcProviderSummary[]> {\n const result = await this.fetch(`/auth/login/oidc/providers`, { method: 'GET' });\n return await parseJson<OidcProviderSummary[]>(result);\n }\n}\n","import { DateTime } from 'luxon';\nimport type { Pagination } from '../../shared/types/pagination.js';\nimport type { PaginationInput } from '../../shared/types/pagination.js';\n\nconst __dt = (v: unknown, path: string): DateTime => {\n if (typeof v !== 'string') {\n throw new TypeError(`ContractKit: expected an ISO 8601 string at '${path}', received ${typeof v}.`);\n }\n const d = DateTime.fromISO(v);\n if (!d.isValid) throw new TypeError(`ContractKit: '${v}' at '${path}' is not a valid ISO 8601 datetime.`);\n return d;\n};\n\n/**\n * What the station has been told about a record. `neutral` is the absence of an opinion rather than\n * a middling one, and it is what rating something back to nothing means.\n * generated from [Rating](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport type Rating = 'liked' | 'neutral' | 'disliked';\n\n/**\n * One provider's copy of a record, with whatever the station holds of it.\n *\n * PER BINDING and never per track, which is the rule the whole page is built on: one canonical\n * record may bind to several copies inside one provider, those copies are different files with\n * different loudness and different cue points, and the one that airs is the one that was resolved.\n * Collapsing them would make \"clear the audio\" ambiguous about which file it took.\n *\n * The failure columns are here rather than hidden because that is the question this page exists to\n * answer. A row with `attempts` and no `fetchedAt` is a remembered failure, and `lastError` with\n * `nextAttemptAt` is the whole of why a perfectly good-looking record will not play.\n * generated from [TrackBinding](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface TrackBinding {\n /** `track_sources.id`, which is also what the audio URL carries */\n sourceId: string;\n pluginId: string;\n externalId: string;\n /** False when the provider still knows the record but will not serve it here */\n playable: boolean;\n /** When the station gave up on this copy. Cleared by the next sync that sees it again */\n missingAt?: DateTime;\n /** `sync` if a playlist walk saw it, `discovered` if something looked it up */\n origin: string;\n bitrate?: number;\n format?: string;\n lastSeenAt?: DateTime;\n /** What the station holds of this copy, absent when nothing has ever fetched it. */\n byteSize?: number;\n fetchedAt?: DateTime;\n lastServedAt?: DateTime;\n /** CONSECUTIVE failures. Reset by a fetch that works */\n attempts: number;\n lastError?: string;\n nextAttemptAt?: DateTime;\n}\n\nexport interface TrackBindingInput {}\n\n/** Rehydrates every wire-encoded scalar in a TrackBinding into its runtime type. Mutates and returns `raw`. */\nexport function reviveTrackBinding(raw: TrackBinding): TrackBinding {\n const __o0 = raw as unknown as Record<string, unknown>;\n if (__o0['missingAt'] != null) {\n __o0['missingAt'] = __dt(__o0['missingAt'], 'TrackBinding.missingAt');\n }\n if (__o0['lastSeenAt'] != null) {\n __o0['lastSeenAt'] = __dt(__o0['lastSeenAt'], 'TrackBinding.lastSeenAt');\n }\n if (__o0['fetchedAt'] != null) {\n __o0['fetchedAt'] = __dt(__o0['fetchedAt'], 'TrackBinding.fetchedAt');\n }\n if (__o0['lastServedAt'] != null) {\n __o0['lastServedAt'] = __dt(__o0['lastServedAt'], 'TrackBinding.lastServedAt');\n }\n if (__o0['nextAttemptAt'] != null) {\n __o0['nextAttemptAt'] = __dt(__o0['nextAttemptAt'], 'TrackBinding.nextAttemptAt');\n }\n return raw;\n}\n\n/**\n * What the measurement sidecar made of a record.\n *\n * `complete` is NOT `analyzedAt`, and the two are separate fields for a reason `0005_music.sql`\n * argues at length: a measurement of a truncated download is confident and wrong, so every reader in\n * the app filters on `complete` and a page that showed only a date would be reporting a record as\n * measured that nothing will use the measurement of.\n * generated from [TrackAnalysis](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface TrackAnalysis {\n schemaVersion: number;\n complete: boolean;\n /** The measuring thing itself, which is not the plugin adapting it */\n analyzer?: string;\n analyzerPluginId?: string;\n analyzedAt?: DateTime;\n failedAt?: DateTime;\n failureReason?: string;\n}\n\nexport interface TrackAnalysisInput {}\n\n/** Rehydrates every wire-encoded scalar in a TrackAnalysis into its runtime type. Mutates and returns `raw`. */\nexport function reviveTrackAnalysis(raw: TrackAnalysis): TrackAnalysis {\n const __o0 = raw as unknown as Record<string, unknown>;\n if (__o0['analyzedAt'] != null) {\n __o0['analyzedAt'] = __dt(__o0['analyzedAt'], 'TrackAnalysis.analyzedAt');\n }\n if (__o0['failedAt'] != null) {\n __o0['failedAt'] = __dt(__o0['failedAt'], 'TrackAnalysis.failedAt');\n }\n return raw;\n}\n\n/**\n * One airing of a record, as this page needs it: when, and under which broadcast.\n * generated from [TrackPlay](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface TrackPlay {\n airedAt: DateTime;\n broadcastId?: string;\n /** What put it in the running order */\n source: string;\n}\n\nexport interface TrackPlayInput {}\n\n/** Rehydrates every wire-encoded scalar in a TrackPlay into its runtime type. Mutates and returns `raw`. */\nexport function reviveTrackPlay(raw: TrackPlay): TrackPlay {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['airedAt'] = __dt(__o0['airedAt'], 'TrackPlay.airedAt');\n return raw;\n}\n\n/**\n * What a clear actually did.\n *\n * A count rather than a bare 204, because the interesting answers are the small ones: clearing the\n * audio of a record with three copies and being told `1` is the station saying two of them were\n * never here — which is a fact about the record and not about the button.\n * generated from [TrackClearResult](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface TrackClearResult {\n trackId: string;\n /** Rows this affected. Zero is an ordinary answer, not a failure */\n cleared: number;\n /** What happened, in the words the console shows */\n detail: string;\n}\n\nexport interface TrackClearResultInput {}\n\n/**\n * Where the singing starts and stops on one record, and which answer that is. Times are milliseconds\n * from the start of the file, the timeline a lyric's timings use. Never the words themselves.\n * generated from [VocalMarkersDetail](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface VocalMarkersDetail {\n trackId: string;\n /** Nobody sings on it; where the singing is; or nothing to go on */\n kind: 'instrumental' | 'ranges' | 'unknown';\n /** Where the first sung word lands, when kind is ranges */\n onsetMs?: number;\n /** Where the singing stops, when it is known */\n endMs?: number;\n /** An operator's correction, the record's timed lyrics, or neither */\n source: 'override' | 'lyrics' | 'none';\n}\n\nexport interface VocalMarkersDetailInput {}\n\n/**\n * One timed piece of a lyric line: a word, or a syllable, and when it starts being sung. Milliseconds\n * from the start of the file, as the line's own start is.\n * generated from [LyricWordDetail](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface LyricWordDetail {\n /** Where this piece starts being sung */\n atMs: number;\n /** The piece, with any space after it, so a line's pieces joined are its text exactly */\n text: string;\n}\n\nexport interface LyricWordDetailInput {}\n\n/**\n * An operator's correction: either the record is instrumental, or the singing starts at `onsetMs`.\n * generated from [VocalMarkersInput](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface VocalMarkersInput {\n /** Nobody sings on this record, whatever its lyrics say */\n instrumental?: boolean;\n /** Where the first sung word lands, from the start of the file. Required unless instrumental */\n onsetMs?: number;\n /** Where the singing stops. Optional, and after the onset */\n endMs?: number;\n}\n\n/**\n * Narrow a clear to one provider's answer, for the case where one source is wrong and the rest are\n * not. Absent clears every provider's.\n * generated from [ClearEnrichmentQuery](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface ClearEnrichmentQuery {\n provider?: string;\n}\n\n/**\n * What an artist or album list is ordered BY, where `Pagination.sort` says only which direction.\n *\n * name the default, and the only key every row here has\n * albums how many records the station holds of them. Artists only\n * tracks how many songs. Artists only\n * year when the record came out. Albums only\n * rating the operator's own opinion\n *\n * One enum for both lists rather than two, because the alternative is a second near-identical\n * contract whose only content is which two keys it drops. A key the row cannot answer falls back to\n * name order rather than failing: an ordering nobody can serve is a page an operator cannot open.\n * generated from [CatalogSort](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport type CatalogSort = 'name' | 'albums' | 'tracks' | 'year' | 'rating';\n\n/**\n * Which records to show, by what the station has of them rather than by what they are.\n *\n * cached the audio is on this machine, so it can be committed to the running order now\n * uncached it is not, which for most of a library is ordinary rather than wrong\n * unmeasured no trustworthy measurement, so no cue points and no level decided before air\n * benched every copy written off, which is the one state that means it CANNOT air\n * failing a fetch has failed and is backing off. Not benched yet, and often the state before it\n * generated from [TrackState](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport type TrackState = 'cached' | 'uncached' | 'unmeasured' | 'benched' | 'failing';\n\n/**\n * What a track list is ordered BY. Its own enum for `TrackQuery`'s own reason: none of these keys\n * means anything about an artist, and `name` is spelled `title` on a song.\n *\n * `state` is deliberately absent. It is three independent booleans rather than one column, so there\n * is no ordering of it an operator would agree with: a benched record and an unmeasured one are not\n * more or less than each other.\n * generated from [TrackSort](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport type TrackSort = 'title' | 'artist' | 'album' | 'year' | 'duration' | 'rating';\n\n/**\n * How much of the library is in each state, over the whole filtered set rather than this page.\n *\n * The aggregate is what an operator reads first — \"13 of 581 measured\" is the sentence that made\n * [analysis-queue-ordering](https://github.com/robert-dean/deadair/discussions/5) necessary, and it was a psql query then. `total` is the\n * same number as `meta.total` when nothing is filtered, and is repeated here so the counts can be\n * read as N of M without reaching into the pager.\n * generated from [TrackStateCounts](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface TrackStateCounts {\n total: number;\n cached: number;\n measured: number;\n enriched: number;\n benched: number;\n failing: number;\n /** A lyrics source has the words of it. The words themselves are at `/catalog/tracks/{id}/lyrics` */\n lyrics: number;\n /** A lyrics source has the timing of its lines, which says when the singing starts */\n synced: number;\n /** A lyrics source says nobody sings on it */\n instrumental: number;\n /** A model has judged what mood it is in */\n moods: number;\n}\n\nexport interface TrackStateCountsInput {}\n\n/**\n * generated from [EnrichmentExternalId](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface EnrichmentExternalId {\n /** e.g. `musicbrainz`, `wikidata` */\n source: string;\n id: string;\n}\n\n/**\n * Narrowed to http(s) by the host before it is stored, since the console renders these as\n * something a human clicks.\n * generated from [EnrichmentLink](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface EnrichmentLink {\n label: string;\n url: string;\n}\n\n/**\n * One thing the station believes, and the words it read that say so. Extracted by the host out of\n * an article a plugin handed over, rather than said by any plugin: `sourceUrl` is where a person\n * checks it and `sourceQuote` is the span that supports it, and neither is ever absent.\n * generated from [FactClaim](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface FactClaim {\n id: string;\n /** One sentence, as the DJ would say it */\n claim: string;\n category: string;\n /** `lead` for the article's own opening, `model` for what a model found */\n source: string;\n sourceProvider: string;\n sourceUrl: string;\n sourceQuote: string;\n confidence?: number;\n model?: string;\n /** Absent means never said on air */\n lastUsedAt?: DateTime;\n}\n\nexport interface FactClaimInput {}\n\n/** Rehydrates every wire-encoded scalar in a FactClaim into its runtime type. Mutates and returns `raw`. */\nexport function reviveFactClaim(raw: FactClaim): FactClaim {\n const __o0 = raw as unknown as Record<string, unknown>;\n if (__o0['lastUsedAt'] != null) {\n __o0['lastUsedAt'] = __dt(__o0['lastUsedAt'], 'FactClaim.lastUsedAt');\n }\n return raw;\n}\n\n/**\n * Rate an artist, a record or a song. Ratings are absolute: a dislike anywhere above a track\n * excludes it, and nothing the station programmes may turn that off.\n * generated from [RateInput](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface RateInput {\n rating: Rating;\n}\n\n/**\n * The canonical work, not a binding to a provider. `deadair.artists` minus the columns that\n * only ingest cares about: `artist_key` is a match key, and a row with `merged_into_id` set is\n * never read out at all.\n *\n * `imageUrl` on both contracts below is always a path under the API root, never a provider's URL:\n * `art/<uuid>` for the station's cached copy, or `art/source/<token>` for one it has not cached\n * yet, which the station fetches on first ask and serves as its own. Resolve either against the\n * API base the client already configures (the API mounts at the root and does not know the `/api`\n * prefix the edge adds). The switch from the second to the first happens server-side.\n * generated from [Artist](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface Artist {\n id: string;\n name: string;\n /** MusicBrainz artist id, absent until enrichment resolves one */\n mbid?: string;\n /** An API-relative path: the cached copy, or the station's proxy for an uncached one */\n imageUrl?: string;\n rating?: Rating;\n /** Unmerged albums credited to this artist */\n albumCount: number;\n /** Unmerged tracks credited to this artist */\n trackCount: number;\n}\n\nexport interface ArtistInput {\n name: string;\n /** MusicBrainz artist id, absent until enrichment resolves one */\n mbid?: string;\n /** An API-relative path: the cached copy, or the station's proxy for an uncached one */\n imageUrl?: string;\n rating?: Rating;\n}\n\n/**\n * generated from [Album](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface Album {\n id: string;\n name: string;\n artistId: string;\n /** Joined, so a list renders without a second request per row */\n artistName: string;\n /** MusicBrainz release-group id, absent until enrichment resolves one */\n mbid?: string;\n year?: number;\n /** An API-relative path: the cached copy, or the station's proxy for an uncached one */\n imageUrl?: string;\n rating?: Rating;\n trackCount: number;\n}\n\nexport interface AlbumInput {\n name: string;\n /** MusicBrainz release-group id, absent until enrichment resolves one */\n mbid?: string;\n year?: number;\n /** An API-relative path: the cached copy, or the station's proxy for an uncached one */\n imageUrl?: string;\n rating?: Rating;\n}\n\n/**\n * generated from [Track](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface Track {\n id: string;\n title: string;\n artistId: string;\n artistName: string;\n /** Absent on a single ingested outside any release: `tracks.album_id` is nullable */\n albumId?: string;\n albumName?: string;\n /** The record's cover, as `Album.imageUrl` spells it. Nothing hangs art off a recording */\n albumImageUrl?: string;\n /** Display credit as written on the release (\"X feat. Y\"), not a join key */\n artists: string;\n genre?: string;\n year?: number;\n durationMs?: number;\n rating?: Rating;\n}\n\nexport interface TrackInput {\n title: string;\n /** Display credit as written on the release (\"X feat. Y\"), not a join key */\n artists: string;\n genre?: string;\n year?: number;\n durationMs?: number;\n rating?: Rating;\n}\n\n/**\n * One timed line of a record's lyrics. Times are milliseconds from the start of the file.\n * generated from [LyricLineDetail](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface LyricLineDetail {\n /** Where the line starts */\n atMs: number;\n /** Where the line ends, when the source published one. Absent rather than guessed */\n endMs?: number;\n /** The words of the line. Empty for a gap the source marked between lines */\n text: string;\n /** The line cut where its source timed each word, in order, when the source times words. Joined, the pieces are text */\n words?: LyricWordDetail[];\n}\n\nexport interface LyricLineDetailInput {}\n\n/**\n * Pagination plus a name filter. Every list operation here takes it, so the console's search box\n * narrows server-side rather than filtering one page client-side and lying about the total.\n * generated from [CatalogQuery](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface CatalogQuery extends Pagination {\n search?: string;\n sortBy?: CatalogSort;\n}\n\nexport interface CatalogQueryInput extends PaginationInput {\n search?: string;\n sortBy?: CatalogSort;\n}\n\n/**\n * `releaseDate` is a string and not `datetime` because it is a partial date: MusicBrainz answers\n * `1997`, `1997-06` or `1997-06-24` depending on what is actually known about the release, and the\n * SDK types it the same way. A `datetime` would reject the first two or invent a day and a time\n * for them, which is a precision the source never claimed.\n * generated from [TrackEnrichmentData](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface TrackEnrichmentData {\n artist?: string;\n title?: string;\n album?: string;\n year?: number;\n releaseDate?: string;\n genres?: string[];\n moods?: string[];\n biography?: string;\n /** Short lines, each independently speakable */\n facts?: string[];\n /** Not an integer: a tempo a source measured rather than declared is fractional */\n bpm?: number;\n musicalKey?: string;\n label?: string;\n isrc?: string;\n /** The provider's picture as the station serves it: `art/<id>` once cached, else the station's proxy `art/source/<token>`. Never the URL the plugin supplied */\n artworkUrl?: string;\n externalIds?: EnrichmentExternalId[];\n links?: EnrichmentLink[];\n /** What the plugin said that the SDK has no field for. Per provider only: the merged view drops it. Never holds a URL: any string with one is dropped when read, along with the key or array element that held it */\n extra?: Record<string, unknown>;\n}\n\n/**\n * generated from [ArtistEnrichmentData](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface ArtistEnrichmentData {\n name?: string;\n biography?: string;\n /** The provider's picture as the station serves it: `art/<id>` once cached, else the station's proxy `art/source/<token>`. Never the URL the plugin supplied */\n imageUrl?: string;\n genres?: string[];\n facts?: string[];\n externalIds?: EnrichmentExternalId[];\n links?: EnrichmentLink[];\n extra?: Record<string, unknown>;\n}\n\n/**\n * generated from [AlbumEnrichmentData](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface AlbumEnrichmentData {\n name?: string;\n /** The record's own credit, which is not always the track's */\n artist?: string;\n year?: number;\n /** Partial, exactly as on TrackEnrichmentData */\n releaseDate?: string;\n label?: string;\n genres?: string[];\n facts?: string[];\n /** The provider's picture as the station serves it: `art/<id>` once cached, else the station's proxy `art/source/<token>`. Never the URL the plugin supplied */\n artworkUrl?: string;\n externalIds?: EnrichmentExternalId[];\n links?: EnrichmentLink[];\n extra?: Record<string, unknown>;\n}\n\n/**\n * One page of artists, with the totals the request was counted against\n * generated from [ArtistPage](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface ArtistPage {\n meta: Pagination;\n data: Artist[];\n}\n\nexport interface ArtistPageInput {\n meta: PaginationInput;\n data: ArtistInput[];\n}\n\n/**\n * One page of albums\n * generated from [AlbumPage](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface AlbumPage {\n meta: Pagination;\n data: Album[];\n}\n\nexport interface AlbumPageInput {\n meta: PaginationInput;\n data: AlbumInput[];\n}\n\n/**\n * Everything one record has accumulated, in one read.\n *\n * The enrichment is deliberately NOT here. It has its own operation already, answering\n * `TrackEnrichmentDetail` with every provider's payload and the station's own sourced claims, and\n * the console draws it through the same panel the list uses. One enrichment shape rather than two.\n * generated from [TrackDetail](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface TrackDetail extends Track {\n bindings: TrackBinding[];\n /** Absent for a record the walk has not reached */\n analysis?: TrackAnalysis;\n /** The most recent airings, newest first */\n plays: TrackPlay[];\n /** How many times in all, which the list above is only the head of */\n playCount: number;\n}\n\nexport interface TrackDetailInput extends TrackInput {\n bindings: TrackBindingInput[];\n /** Absent for a record the walk has not reached */\n analysis?: TrackAnalysisInput;\n /** The most recent airings, newest first */\n plays: TrackPlayInput[];\n}\n\n/** Rehydrates every wire-encoded scalar in a TrackDetail into its runtime type. Mutates and returns `raw`. */\nexport function reviveTrackDetail(raw: TrackDetail): TrackDetail {\n const __o0 = raw as unknown as Record<string, unknown>;\n {\n const __a1 = __o0['bindings'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveTrackBinding(__a1[__i2] as never);\n }\n }\n if (__o0['analysis'] != null) {\n reviveTrackAnalysis(__o0['analysis'] as never);\n }\n {\n const __a3 = __o0['plays'] as unknown[];\n for (let __i4 = 0; __i4 < __a3.length; __i4++) {\n reviveTrackPlay(__a3[__i4] as never);\n }\n }\n return raw;\n}\n\n/**\n * A track as a LIST shows it: the record, plus three facts about what the station has of it.\n *\n * Three booleans and no more, deliberately. They are what a row can afford — one `exists` each, off\n * the query that was already running — and everything wider (which providers, how many bytes, why the\n * last fetch failed) is `TrackDetail`'s, one click away. A fourth would be the beginning of putting\n * the detail page in a table cell.\n * generated from [TrackRow](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface TrackRow extends Track {\n /** The bytes are on this machine */\n hasAudio: boolean;\n /** Measured, COMPLETE, and at a schema version the station still trusts */\n measured: boolean;\n /** At least one provider has answered about it */\n enriched: boolean;\n}\n\nexport interface TrackRowInput extends TrackInput {}\n\n/**\n * The station's answer for one record's lyrics: the words from the source it believes, or that nobody\n * sings on it, or nothing. Timings count from the start of the file, as the vocal markers' do, so a\n * player following along adds the record's cue-in to how long it has been on air.\n * generated from [TrackLyrics](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface TrackLyrics {\n trackId: string;\n /** The words are here; a source says nobody sings on it; or no source has an answer yet */\n kind: 'words' | 'instrumental' | 'none';\n /** The plugin whose answer this is, when kind is words or instrumental */\n provider?: string;\n /** The words without timings, when that source has them */\n plain?: string;\n /** The timed lines, when that source has them. Preferred over plain when choosing a source */\n synced?: LyricLineDetail[];\n /** A BCP 47 tag, when the source stated one */\n language?: string;\n}\n\nexport interface TrackLyricsInput {}\n\n/**\n * One lyrics source's answer for one record. A source that was asked and had nothing is not listed.\n * generated from [TrackLyricsSource](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface TrackLyricsSource {\n /** The plugin that answered */\n provider: string;\n /** The source's own id for what it matched */\n providerRef?: string;\n plain?: string;\n synced?: LyricLineDetail[];\n language?: string;\n /** The source says nobody sings on this record, so it holds no words */\n instrumental: boolean;\n fetchedAt: DateTime;\n}\n\nexport interface TrackLyricsSourceInput {}\n\n/** Rehydrates every wire-encoded scalar in a TrackLyricsSource into its runtime type. Mutates and returns `raw`. */\nexport function reviveTrackLyricsSource(raw: TrackLyricsSource): TrackLyricsSource {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['fetchedAt'] = __dt(__o0['fetchedAt'], 'TrackLyricsSource.fetchedAt');\n return raw;\n}\n\n/**\n * A track list, narrowed by what the station has of each record as well as by name.\n *\n * Its own contract rather than a field on `CatalogQuery`, because that one is shared with the artist\n * and album lists where none of these states means anything.\n * generated from [TrackQuery](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface TrackQuery extends Omit<CatalogQuery, 'sortBy'> {\n state?: TrackState;\n sortBy?: TrackSort;\n}\n\nexport interface TrackQueryInput extends Omit<CatalogQueryInput, 'sortBy'> {\n state?: TrackState;\n sortBy?: TrackSort;\n}\n\n/**\n * One provider's stored answer. `found: false` is a recorded miss, which is a fact rather than a\n * failure: the provider was asked, had nothing, and is not asked again until `expiresAt`. A provider\n * that could not be asked at all is `failed` instead, and the two never both hold.\n * generated from [TrackEnrichmentSource](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface TrackEnrichmentSource {\n provider: string;\n /** The id it was fetched under. Provenance, not identity */\n providerRef?: string;\n fetchedAt: DateTime;\n expiresAt?: DateTime;\n /** Past its TTL, so the next pass will ask again */\n stale: boolean;\n found: boolean;\n /** The last attempt errored, so `expiresAt` is a backoff rather than a TTL */\n failed: boolean;\n data: TrackEnrichmentData;\n}\n\nexport interface TrackEnrichmentSourceInput {\n data: TrackEnrichmentData;\n}\n\n/** Rehydrates every wire-encoded scalar in a TrackEnrichmentSource into its runtime type. Mutates and returns `raw`. */\nexport function reviveTrackEnrichmentSource(raw: TrackEnrichmentSource): TrackEnrichmentSource {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['fetchedAt'] = __dt(__o0['fetchedAt'], 'TrackEnrichmentSource.fetchedAt');\n if (__o0['expiresAt'] != null) {\n __o0['expiresAt'] = __dt(__o0['expiresAt'], 'TrackEnrichmentSource.expiresAt');\n }\n return raw;\n}\n\n/**\n * generated from [ArtistEnrichmentSource](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface ArtistEnrichmentSource {\n provider: string;\n providerRef?: string;\n fetchedAt: DateTime;\n expiresAt?: DateTime;\n stale: boolean;\n found: boolean;\n /** The last attempt errored, so `expiresAt` is a backoff rather than a TTL */\n failed: boolean;\n data: ArtistEnrichmentData;\n}\n\nexport interface ArtistEnrichmentSourceInput {\n data: ArtistEnrichmentData;\n}\n\n/** Rehydrates every wire-encoded scalar in a ArtistEnrichmentSource into its runtime type. Mutates and returns `raw`. */\nexport function reviveArtistEnrichmentSource(raw: ArtistEnrichmentSource): ArtistEnrichmentSource {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['fetchedAt'] = __dt(__o0['fetchedAt'], 'ArtistEnrichmentSource.fetchedAt');\n if (__o0['expiresAt'] != null) {\n __o0['expiresAt'] = __dt(__o0['expiresAt'], 'ArtistEnrichmentSource.expiresAt');\n }\n return raw;\n}\n\n/**\n * generated from [AlbumEnrichmentSource](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface AlbumEnrichmentSource {\n provider: string;\n providerRef?: string;\n fetchedAt: DateTime;\n expiresAt?: DateTime;\n stale: boolean;\n found: boolean;\n /** The last attempt errored, so `expiresAt` is a backoff rather than a TTL */\n failed: boolean;\n data: AlbumEnrichmentData;\n}\n\nexport interface AlbumEnrichmentSourceInput {\n data: AlbumEnrichmentData;\n}\n\n/** Rehydrates every wire-encoded scalar in a AlbumEnrichmentSource into its runtime type. Mutates and returns `raw`. */\nexport function reviveAlbumEnrichmentSource(raw: AlbumEnrichmentSource): AlbumEnrichmentSource {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['fetchedAt'] = __dt(__o0['fetchedAt'], 'AlbumEnrichmentSource.fetchedAt');\n if (__o0['expiresAt'] != null) {\n __o0['expiresAt'] = __dt(__o0['expiresAt'], 'AlbumEnrichmentSource.expiresAt');\n }\n return raw;\n}\n\n/**\n * One page of tracks, with what the station has of each and of the whole set\n * generated from [TrackPage](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface TrackPage {\n meta: Pagination;\n data: TrackRow[];\n states: TrackStateCounts;\n}\n\nexport interface TrackPageInput {\n meta: PaginationInput;\n data: TrackRowInput[];\n states: TrackStateCountsInput;\n}\n\n/**\n * Every lyrics source's answer for one record, in the order the station believes them.\n * generated from [TrackLyricsSources](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface TrackLyricsSources {\n trackId: string;\n sources: TrackLyricsSource[];\n}\n\nexport interface TrackLyricsSourcesInput {}\n\n/** Rehydrates every wire-encoded scalar in a TrackLyricsSources into its runtime type. Mutates and returns `raw`. */\nexport function reviveTrackLyricsSources(raw: TrackLyricsSources): TrackLyricsSources {\n const __o0 = raw as unknown as Record<string, unknown>;\n {\n const __a1 = __o0['sources'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveTrackLyricsSource(__a1[__i2] as never);\n }\n }\n return raw;\n}\n\n/**\n * Every provider's answer, plus the same merge the promotion step used, so the console and the\n * canonical columns cannot tell different stories. `sources` is empty on a row the walk has not\n * reached yet.\n *\n * `claims` sits beside them rather than inside `merged`, because a claim is the host's own and not\n * any provider's. The articles they were read out of are deliberately NOT here: raw source prose is\n * stored and never sent.\n * generated from [TrackEnrichmentDetail](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface TrackEnrichmentDetail {\n trackId: string;\n merged: TrackEnrichmentData;\n sources: TrackEnrichmentSource[];\n claims: FactClaim[];\n}\n\nexport interface TrackEnrichmentDetailInput {\n merged: TrackEnrichmentData;\n sources: TrackEnrichmentSourceInput[];\n claims: FactClaimInput[];\n}\n\n/** Rehydrates every wire-encoded scalar in a TrackEnrichmentDetail into its runtime type. Mutates and returns `raw`. */\nexport function reviveTrackEnrichmentDetail(raw: TrackEnrichmentDetail): TrackEnrichmentDetail {\n const __o0 = raw as unknown as Record<string, unknown>;\n {\n const __a1 = __o0['sources'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveTrackEnrichmentSource(__a1[__i2] as never);\n }\n }\n {\n const __a3 = __o0['claims'] as unknown[];\n for (let __i4 = 0; __i4 < __a3.length; __i4++) {\n reviveFactClaim(__a3[__i4] as never);\n }\n }\n return raw;\n}\n\n/**\n * generated from [ArtistEnrichmentDetail](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface ArtistEnrichmentDetail {\n artistId: string;\n merged: ArtistEnrichmentData;\n sources: ArtistEnrichmentSource[];\n claims: FactClaim[];\n}\n\nexport interface ArtistEnrichmentDetailInput {\n merged: ArtistEnrichmentData;\n sources: ArtistEnrichmentSourceInput[];\n claims: FactClaimInput[];\n}\n\n/** Rehydrates every wire-encoded scalar in a ArtistEnrichmentDetail into its runtime type. Mutates and returns `raw`. */\nexport function reviveArtistEnrichmentDetail(raw: ArtistEnrichmentDetail): ArtistEnrichmentDetail {\n const __o0 = raw as unknown as Record<string, unknown>;\n {\n const __a1 = __o0['sources'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveArtistEnrichmentSource(__a1[__i2] as never);\n }\n }\n {\n const __a3 = __o0['claims'] as unknown[];\n for (let __i4 = 0; __i4 < __a3.length; __i4++) {\n reviveFactClaim(__a3[__i4] as never);\n }\n }\n return raw;\n}\n\n/**\n * generated from [AlbumEnrichmentDetail](../../../../../apps/api/data/contracts/catalog/catalog.types.ck)\n */\nexport interface AlbumEnrichmentDetail {\n albumId: string;\n merged: AlbumEnrichmentData;\n sources: AlbumEnrichmentSource[];\n claims: FactClaim[];\n}\n\nexport interface AlbumEnrichmentDetailInput {\n merged: AlbumEnrichmentData;\n sources: AlbumEnrichmentSourceInput[];\n claims: FactClaimInput[];\n}\n\n/** Rehydrates every wire-encoded scalar in a AlbumEnrichmentDetail into its runtime type. Mutates and returns `raw`. */\nexport function reviveAlbumEnrichmentDetail(raw: AlbumEnrichmentDetail): AlbumEnrichmentDetail {\n const __o0 = raw as unknown as Record<string, unknown>;\n {\n const __a1 = __o0['sources'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveAlbumEnrichmentSource(__a1[__i2] as never);\n }\n }\n {\n const __a3 = __o0['claims'] as unknown[];\n for (let __i4 = 0; __i4 < __a3.length; __i4++) {\n reviveFactClaim(__a3[__i4] as never);\n }\n }\n return raw;\n}\n","import type { SdkFetch } from '../sdk-options.js';\nimport { bigIntReplacer, parseJson, buildQueryString } from '../sdk-options.js';\nimport type {\n Album,\n AlbumEnrichmentDetail,\n AlbumPage,\n Artist,\n ArtistEnrichmentDetail,\n ArtistPage,\n CatalogQueryInput,\n ClearEnrichmentQuery,\n RateInput,\n Track,\n TrackClearResult,\n TrackDetail,\n TrackEnrichmentDetail,\n TrackLyrics,\n TrackLyricsSources,\n TrackPage,\n TrackQueryInput,\n VocalMarkersDetail,\n VocalMarkersInput,\n} from './types/catalog.types.js';\nimport {\n reviveAlbumEnrichmentDetail,\n reviveArtistEnrichmentDetail,\n reviveTrackDetail,\n reviveTrackEnrichmentDetail,\n reviveTrackLyricsSources,\n} from './types/catalog.types.js';\n\nexport class CatalogClient {\n constructor(private fetch: SdkFetch) {}\n\n /**\n * @name List artists\n * @description Every artist the station has ingested, ordered by name\n */\n async listArtists(query?: CatalogQueryInput): Promise<ArtistPage> {\n const qs = buildQueryString(query);\n const result = await this.fetch(`/catalog/artists${qs}`, {\n method: 'GET',\n });\n return await parseJson<ArtistPage>(result);\n }\n\n /**\n * @name Get artist\n * @description One artist. 404s on an id that was merged away, since reads never return merged rows\n */\n async getArtist(id: string): Promise<Artist> {\n const result = await this.fetch(`/catalog/artists/${encodeURIComponent(id)}`, { method: 'GET' });\n return await parseJson<Artist>(result);\n }\n\n /**\n * @name Get artist enrichment\n * @description What every enrichment provider said about this artist, and when each of them said it\n */\n async getArtistEnrichment(id: string): Promise<ArtistEnrichmentDetail> {\n const result = await this.fetch(`/catalog/artists/${encodeURIComponent(id)}/enrichment`, { method: 'GET' });\n return reviveArtistEnrichmentDetail(await parseJson<ArtistEnrichmentDetail>(result));\n }\n\n /**\n * @name List artist albums\n * @description The albums credited to one artist\n */\n async listArtistAlbums(id: string, query?: CatalogQueryInput): Promise<AlbumPage> {\n const qs = buildQueryString(query);\n const result = await this.fetch(`/catalog/artists/${encodeURIComponent(id)}/albums${qs}`, {\n method: 'GET',\n });\n return await parseJson<AlbumPage>(result);\n }\n\n /**\n * @name Rate artist\n * @description What the station thinks of this artist. A dislike here excludes every record they are credited on\n */\n async rateArtist(id: string, body: RateInput): Promise<Artist> {\n const result = await this.fetch(`/catalog/artists/${encodeURIComponent(id)}/rating`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<Artist>(result);\n }\n\n /** @name List albums */\n async listAlbums(query?: CatalogQueryInput): Promise<AlbumPage> {\n const qs = buildQueryString(query);\n const result = await this.fetch(`/catalog/albums${qs}`, {\n method: 'GET',\n });\n return await parseJson<AlbumPage>(result);\n }\n\n /** @name Get album */\n async getAlbum(id: string): Promise<Album> {\n const result = await this.fetch(`/catalog/albums/${encodeURIComponent(id)}`, { method: 'GET' });\n return await parseJson<Album>(result);\n }\n\n /**\n * @name Get album enrichment\n * @description The record's own enrichment: the label, pressing and cover belong to the release, not to a track on it\n */\n async getAlbumEnrichment(id: string): Promise<AlbumEnrichmentDetail> {\n const result = await this.fetch(`/catalog/albums/${encodeURIComponent(id)}/enrichment`, { method: 'GET' });\n return reviveAlbumEnrichmentDetail(await parseJson<AlbumEnrichmentDetail>(result));\n }\n\n /**\n * @name List album tracks\n * @description One album's tracks\n */\n async listAlbumTracks(id: string, query?: TrackQueryInput): Promise<TrackPage> {\n const qs = buildQueryString(query);\n const result = await this.fetch(`/catalog/albums/${encodeURIComponent(id)}/tracks${qs}`, {\n method: 'GET',\n });\n return await parseJson<TrackPage>(result);\n }\n\n /**\n * @name Rate album\n * @description What the station thinks of this record. A dislike here excludes every track on it\n */\n async rateAlbum(id: string, body: RateInput): Promise<Album> {\n const result = await this.fetch(`/catalog/albums/${encodeURIComponent(id)}/rating`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<Album>(result);\n }\n\n /**\n * @name Get track\n * @description One record and everything it has accumulated: its copies, its bytes, its measurement, what it has aired\n */\n async getTrack(id: string): Promise<TrackDetail> {\n const result = await this.fetch(`/catalog/tracks/${encodeURIComponent(id)}`, { method: 'GET' });\n return reviveTrackDetail(await parseJson<TrackDetail>(result));\n }\n\n /**\n * @name Clear track audio\n * @description Drop the station's own copies of this record. The next play fetches them again\n */\n async clearTrackAudio(id: string): Promise<TrackClearResult> {\n const result = await this.fetch(`/catalog/tracks/${encodeURIComponent(id)}/audio`, { method: 'DELETE' });\n return await parseJson<TrackClearResult>(result);\n }\n\n /**\n * @name Clear track analysis\n * @description Forget the measurement, so the walk takes it again\n */\n async clearTrackAnalysis(id: string): Promise<TrackClearResult> {\n const result = await this.fetch(`/catalog/tracks/${encodeURIComponent(id)}/analysis`, { method: 'DELETE' });\n return await parseJson<TrackClearResult>(result);\n }\n\n /**\n * @name Get vocal markers\n * @description Where the singing starts and stops on one record, from an operator's correction or its timed lyrics\n */\n async getVocalMarkers(id: string): Promise<VocalMarkersDetail> {\n const result = await this.fetch(`/catalog/tracks/${encodeURIComponent(id)}/vocal-markers`, { method: 'GET' });\n return await parseJson<VocalMarkersDetail>(result);\n }\n\n /**\n * @name Set vocal markers\n * @description Correct where the singing starts and stops, over whatever the lyrics say\n */\n async setVocalMarkers(id: string, body: VocalMarkersInput): Promise<VocalMarkersDetail> {\n const result = await this.fetch(`/catalog/tracks/${encodeURIComponent(id)}/vocal-markers`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<VocalMarkersDetail>(result);\n }\n\n /**\n * @name Clear vocal markers\n * @description Drop the correction, so the record's timed lyrics decide again\n */\n async clearVocalMarkers(id: string): Promise<VocalMarkersDetail> {\n const result = await this.fetch(`/catalog/tracks/${encodeURIComponent(id)}/vocal-markers`, { method: 'DELETE' });\n return await parseJson<VocalMarkersDetail>(result);\n }\n\n /**\n * @name Get track lyrics\n * @description The words of one record, from the lyrics source the station believes, with the timing of each line when that source has it\n */\n async getTrackLyrics(id: string): Promise<TrackLyrics> {\n const result = await this.fetch(`/catalog/tracks/${encodeURIComponent(id)}/lyrics`, { method: 'GET' });\n return await parseJson<TrackLyrics>(result);\n }\n\n /**\n * @name List track lyrics sources\n * @description What every lyrics source answered for one record, in the order the station believes them\n */\n async listTrackLyricsSources(id: string): Promise<TrackLyricsSources> {\n const result = await this.fetch(`/catalog/tracks/${encodeURIComponent(id)}/lyrics/sources`, { method: 'GET' });\n return reviveTrackLyricsSources(await parseJson<TrackLyricsSources>(result));\n }\n\n /**\n * @name Retry track audio\n * @description Try this record's copies again now, rather than when the backoff says\n */\n async retryTrackAudio(id: string): Promise<TrackClearResult> {\n const result = await this.fetch(`/catalog/tracks/${encodeURIComponent(id)}/retry`, { method: 'POST' });\n return await parseJson<TrackClearResult>(result);\n }\n\n /**\n * @name Offer track copies again\n * @description Put copies a provider refused back on offer, and clear their backoff so they are tried now\n */\n async offerTrackCopiesAgain(id: string): Promise<TrackClearResult> {\n const result = await this.fetch(`/catalog/tracks/${encodeURIComponent(id)}/offer`, { method: 'POST' });\n return await parseJson<TrackClearResult>(result);\n }\n\n /**\n * @name Get track enrichment\n * @description What the providers said about one recording, including everything no canonical column holds\n */\n async getTrackEnrichment(id: string): Promise<TrackEnrichmentDetail> {\n const result = await this.fetch(`/catalog/tracks/${encodeURIComponent(id)}/enrichment`, { method: 'GET' });\n return reviveTrackEnrichmentDetail(await parseJson<TrackEnrichmentDetail>(result));\n }\n\n /**\n * @name Clear track enrichment\n * @description Forget what the providers said, so the enrichment pass asks again\n */\n async clearTrackEnrichment(id: string, query?: ClearEnrichmentQuery): Promise<TrackClearResult> {\n const qs = buildQueryString(query);\n const result = await this.fetch(`/catalog/tracks/${encodeURIComponent(id)}/enrichment${qs}`, {\n method: 'DELETE',\n });\n return await parseJson<TrackClearResult>(result);\n }\n\n /**\n * @name List tracks\n * @description Every track, flat. The only way to answer \"do we have this song?\" without knowing its artist\n */\n async listTracks(query?: TrackQueryInput): Promise<TrackPage> {\n const qs = buildQueryString(query);\n const result = await this.fetch(`/catalog/tracks${qs}`, {\n method: 'GET',\n });\n return await parseJson<TrackPage>(result);\n }\n\n /**\n * @name Rate track\n * @description What the station thinks of this song, which is the narrowest thing an opinion can be about\n */\n async rateTrack(id: string, body: RateInput): Promise<Track> {\n const result = await this.fetch(`/catalog/tracks/${encodeURIComponent(id)}/rating`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<Track>(result);\n }\n}\n","import type { SdkFetch } from '../sdk-options.js';\nimport { parseJson, buildQueryString } from '../sdk-options.js';\nimport type { ChartPage, ChartQuery, StationChartList } from './types/charts.types.js';\n\nexport class ChartsClient {\n constructor(private fetch: SdkFetch) {}\n\n /**\n * @name List charts\n * @description Every chart every installed chart plugin currently offers\n */\n async listCharts(): Promise<StationChartList> {\n const result = await this.fetch(`/charts`, { method: 'GET' });\n return await parseJson<StationChartList>(result);\n }\n\n /**\n * @name Read chart\n * @description One chart's records, ranked\n */\n async readChart(id: string, query?: ChartQuery): Promise<ChartPage> {\n const qs = buildQueryString(query);\n const result = await this.fetch(`/charts/${encodeURIComponent(id)}${qs}`, {\n method: 'GET',\n });\n return await parseJson<ChartPage>(result);\n }\n}\n","import { DateTime } from 'luxon';\nconst __dt = (v: unknown, path: string): DateTime => {\n if (typeof v !== 'string') {\n throw new TypeError(`ContractKit: expected an ISO 8601 string at '${path}', received ${typeof v}.`);\n }\n const d = DateTime.fromISO(v);\n if (!d.isValid) throw new TypeError(`ContractKit: '${v}' at '${path}' is not a valid ISO 8601 datetime.`);\n return d;\n};\n\n/**\n * A never-play rule: a KIND of record the station must not play. Absolute, like a dislike, and\n * exclude-only: there is no \"only these\" rule, because one could leave the station nothing to play.\n * Every scope is optional and an absent one means \"always\"\n * generated from [BlockRule](../../../../../apps/api/data/contracts/director/rules.types.ck)\n */\nexport interface BlockRule {\n id: string;\n /** `genre` refuses any record tagged with this genre or a kind of it (`Punk Rock` under `Punk`, never `Pop` under `Pop Punk`, never `Trap` under `Rap`). `tag` refuses a record carrying exactly this tag. `version` refuses a version of a record, read from the markers on its title and album: `live` refuses a live recording (\"War Pigs - Live\", anything from \"Live in Nottingham\"), and never a title that merely says the word (\"Live Wire\") */\n field: 'genre' | 'tag' | 'version';\n /** The genre or tag, as you would write it. For a `version` rule, the version: `live` is the only one */\n value: string;\n /** First day it holds, as `MM-DD`. With `seasonTo`; a season starting after it ends wraps the year end */\n seasonFrom?: string;\n /** Last day it holds, as `MM-DD` */\n seasonTo?: string;\n /** First hour of the station's day it holds. With `untilHour`; a window starting after it ends wraps midnight */\n fromHour?: number;\n /** The hour it stops holding, exclusive */\n untilHour?: number;\n /** Only while the station is in one of these modes. Absent or empty means every mode */\n modes?: ('rotation' | 'setlist' | 'feature')[];\n /** Only during these schedule blocks. Absent or empty means whatever is on */\n slotIds?: string[];\n /** When it stops holding. Absent means until it is removed */\n endsAt?: DateTime;\n /** Whether it holds right now, on the station's clock, for what is on air */\n inForce: boolean;\n}\n\nexport interface BlockRuleInput {\n /** `genre` refuses any record tagged with this genre or a kind of it (`Punk Rock` under `Punk`, never `Pop` under `Pop Punk`, never `Trap` under `Rap`). `tag` refuses a record carrying exactly this tag. `version` refuses a version of a record, read from the markers on its title and album: `live` refuses a live recording (\"War Pigs - Live\", anything from \"Live in Nottingham\"), and never a title that merely says the word (\"Live Wire\") */\n field: 'genre' | 'tag' | 'version';\n /** The genre or tag, as you would write it. For a `version` rule, the version: `live` is the only one */\n value: string;\n /** First day it holds, as `MM-DD`. With `seasonTo`; a season starting after it ends wraps the year end */\n seasonFrom?: string;\n /** Last day it holds, as `MM-DD` */\n seasonTo?: string;\n /** First hour of the station's day it holds. With `untilHour`; a window starting after it ends wraps midnight */\n fromHour?: number;\n /** The hour it stops holding, exclusive */\n untilHour?: number;\n /** Only while the station is in one of these modes. Absent or empty means every mode */\n modes?: ('rotation' | 'setlist' | 'feature')[];\n /** Only during these schedule blocks. Absent or empty means whatever is on */\n slotIds?: string[];\n /** When it stops holding. Absent means until it is removed */\n endsAt?: DateTime;\n}\n\n/** Rehydrates every wire-encoded scalar in a BlockRule into its runtime type. Mutates and returns `raw`. */\nexport function reviveBlockRule(raw: BlockRule): BlockRule {\n const __o0 = raw as unknown as Record<string, unknown>;\n if (__o0['endsAt'] != null) {\n __o0['endsAt'] = __dt(__o0['endsAt'], 'BlockRule.endsAt');\n }\n return raw;\n}\n\n/**\n * A lean toward some genres for a while. The opposite of a rule: the station favours them when it\n * chooses records, and still plays anything else rather than run dry\n * generated from [GenreSteer](../../../../../apps/api/data/contracts/director/rules.types.ck)\n */\nexport interface GenreSteer {\n /** What to favour, as genres. A record tagged with any of them, or a kind of one, is preferred */\n genres: string[];\n /** When the station goes back to choosing as it ordinarily does */\n endsAt: DateTime;\n}\n\n/** Rehydrates every wire-encoded scalar in a GenreSteer into its runtime type. Mutates and returns `raw`. */\nexport function reviveGenreSteer(raw: GenreSteer): GenreSteer {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['endsAt'] = __dt(__o0['endsAt'], 'GenreSteer.endsAt');\n return raw;\n}\n\n/**\n * Lean the station toward some genres for a number of hours\n * generated from [GenreSteerInput](../../../../../apps/api/data/contracts/director/rules.types.ck)\n */\nexport interface GenreSteerInput {\n genres: string[];\n /** How long it lasts, from now */\n hours: number;\n}\n\n/**\n * Every rule on the station, newest first\n * generated from [BlockRuleList](../../../../../apps/api/data/contracts/director/rules.types.ck)\n */\nexport interface BlockRuleList {\n rules: BlockRule[];\n}\n\nexport interface BlockRuleListInput {\n rules: BlockRuleInput[];\n}\n\n/** Rehydrates every wire-encoded scalar in a BlockRuleList into its runtime type. Mutates and returns `raw`. */\nexport function reviveBlockRuleList(raw: BlockRuleList): BlockRuleList {\n const __o0 = raw as unknown as Record<string, unknown>;\n {\n const __a1 = __o0['rules'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveBlockRule(__a1[__i2] as never);\n }\n }\n return raw;\n}\n\n/**\n * The lean in force, or none\n * generated from [GenreSteerReading](../../../../../apps/api/data/contracts/director/rules.types.ck)\n */\nexport interface GenreSteerReading {\n /** Absent when nothing is leaning the station, including once one has run out */\n steer?: GenreSteer;\n}\n\n/** Rehydrates every wire-encoded scalar in a GenreSteerReading into its runtime type. Mutates and returns `raw`. */\nexport function reviveGenreSteerReading(raw: GenreSteerReading): GenreSteerReading {\n const __o0 = raw as unknown as Record<string, unknown>;\n if (__o0['steer'] != null) {\n reviveGenreSteer(__o0['steer'] as never);\n }\n return raw;\n}\n","import type { SdkFetch } from '../sdk-options.js';\nimport { bigIntReplacer, parseJson } from '../sdk-options.js';\nimport type { ClockBandInput, ClockBandList } from './types/clock.types.js';\nimport type {\n AddStationSegmentInput,\n AddStationTrackInput,\n ArtistRoute,\n ExtendStationInput,\n HoldStationInput,\n MoveStationItemInput,\n PutOnAirInput,\n ReplanStationInput,\n RequestStationBreakInput,\n RoutePreviewInput,\n SetStationAirInput,\n SetStationHostInput,\n StationAir,\n StationBreakRequest,\n StationOrder,\n} from './types/director.types.js';\nimport type { BlockRuleInput, BlockRuleList, GenreSteerInput, GenreSteerReading } from './types/rules.types.js';\nimport { reviveBlockRuleList, reviveGenreSteerReading } from './types/rules.types.js';\n\nexport class DirectorClient {\n constructor(private fetch: SdkFetch) {}\n\n /**\n * @name List clock bands\n * @description Every band on this station's clock, including the ones switched off, in the operator's own order\n */\n async listClockBands(): Promise<ClockBandList> {\n const result = await this.fetch(`/clock/bands`, { method: 'GET' });\n return await parseJson<ClockBandList>(result);\n }\n\n /**\n * @name Create clock band\n * @description Adds a band. It claims its first boundary on the next commit pass\n */\n async createClockBand(body: ClockBandInput): Promise<ClockBandList> {\n const result = await this.fetch(`/clock/bands`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<ClockBandList>(result);\n }\n\n /**\n * @name Update clock band\n * @description Rewrites one band. Breaks it has already planted stay where they are: the running order is the memory\n */\n async updateClockBand(id: string, body: ClockBandInput): Promise<ClockBandList> {\n const result = await this.fetch(`/clock/bands/${encodeURIComponent(id)}`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<ClockBandList>(result);\n }\n\n /**\n * @name Delete clock band\n * @description Removes a band, which costs it the boundaries it had not claimed yet and nothing else\n */\n async deleteClockBand(id: string): Promise<ClockBandList> {\n const result = await this.fetch(`/clock/bands/${encodeURIComponent(id)}`, { method: 'DELETE' });\n return await parseJson<ClockBandList>(result);\n }\n\n /**\n * @name Get station air\n * @description What the station is airing, and whether it is driving at all\n */\n async getStationAir(): Promise<StationAir> {\n const result = await this.fetch(`/director/air`, { method: 'GET' });\n return await parseJson<StationAir>(result);\n }\n\n /**\n * @name Put the station on air\n * @description Puts the station on air, building the running order from a playlist read at this moment. What is playing finishes: changing the programming is not a reason to cut a listener off mid-track\n */\n async putTheStationOnAir(body: PutOnAirInput): Promise<StationAir> {\n const result = await this.fetch(`/director/air`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<StationAir>(result);\n }\n\n /**\n * @name Set the air mode\n * @description Changes what puts the station on air: only while somebody is listening, or whenever there is a programme. Takes effect at once rather than at the next boundary\n */\n async setTheAirMode(body: SetStationAirInput): Promise<StationAir> {\n const result = await this.fetch(`/director/air`, {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<StationAir>(result);\n }\n\n /**\n * @name Get the running order\n * @description The live running order, item by item, each saying where it has got to\n */\n async getTheRunningOrder(): Promise<StationOrder> {\n const result = await this.fetch(`/director/air/order`, { method: 'GET' });\n return await parseJson<StationOrder>(result);\n }\n\n /**\n * @name Recast the broadcast\n * @description Changes who is presenting this broadcast. Breaks already written for it in the outgoing character are written again in the new one\n */\n async recastTheBroadcast(body: SetStationHostInput): Promise<StationOrder> {\n const result = await this.fetch(`/director/air/persona`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<StationOrder>(result);\n }\n\n /**\n * @name Extend the running order\n * @description Queues a refill and returns at once. Generating a set walks the catalog, and an operator pressing a button should not be held open through it\n */\n async extendTheRunningOrder(body: ExtendStationInput): Promise<void> {\n await this.fetch(`/director/air/extend`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n }\n\n /**\n * @name Replan the running order\n * @description Queues a fresh set for everything the player is not already holding, and swaps it in once it exists. The old tail keeps playing until then, because emptying the running order first would take the station off air while the model was still choosing\n */\n async replanTheRunningOrder(body: ReplanStationInput): Promise<void> {\n await this.fetch(`/director/air/replan`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n }\n\n /**\n * @name Request a break\n * @description Asks the station to say something now rather than when the format clock next calls for it: the news, the weather, a word from the host. The director decides where it goes. A decline is answered rather than thrown, with the station's reason, because \"breaks are off\" and \"it was asked for a moment ago\" are things the person pressing the button needs to read\n */\n async requestABreak(body: RequestStationBreakInput): Promise<StationBreakRequest> {\n const result = await this.fetch(`/director/air/breaks`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<StationBreakRequest>(result);\n }\n\n /**\n * @name Preview an artist route\n * @description Finds a route from one artist to another through artists the library holds, and says how each stop connects to the one before. Nothing goes on air: this is what a route would be\n */\n async previewAnArtistRoute(body: RoutePreviewInput): Promise<ArtistRoute> {\n const result = await this.fetch(`/director/route/preview`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<ArtistRoute>(result);\n }\n\n /**\n * @name Hold the station against the schedule\n * @description Holds the running order against the schedule, so a block boundary does not take back what an operator put on. A takeover is otherwise stamped with whichever slot was in force and is replaced when that block ends, which is correct and gives nobody any warning\n */\n async holdTheStationAgainstTheSchedule(body: HoldStationInput): Promise<StationAir> {\n const result = await this.fetch(`/director/air/hold`, {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<StationAir>(result);\n }\n\n /**\n * @name Release the station to the schedule\n * @description Releases a hold, so the next block boundary changes the station over as it ordinarily would. A station with no hold is unchanged rather than refused\n */\n async releaseTheStationToTheSchedule(): Promise<StationAir> {\n const result = await this.fetch(`/director/air/hold`, { method: 'DELETE' });\n return await parseJson<StationAir>(result);\n }\n\n /**\n * @name Shuffle the running order\n * @description Shuffles the records not yet handed to the player, and plants the breaks again around the new sequence. The head is already in the player's hands and is left alone\n */\n async shuffleTheRunningOrder(): Promise<StationOrder> {\n const result = await this.fetch(`/director/air/shuffle`, { method: 'POST' });\n return await parseJson<StationOrder>(result);\n }\n\n /**\n * @name Add a segment to the running order\n * @description Puts something the station says into the running order. A segment with no audio yet is refused here rather than accepted and skipped when it comes round, so an operator is told why it cannot play\n */\n async addASegmentToTheRunningOrder(body: AddStationSegmentInput): Promise<StationOrder> {\n const result = await this.fetch(`/director/air/segments`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<StationOrder>(result);\n }\n\n /**\n * @name Add a record to the running order\n * @description Puts a catalog record into the running order. A record whose audio is not local yet is refused here rather than accepted and held or skipped when its slot comes round, so an operator asking for a specific one is told why it cannot play. What makes this worth having on its own is undo: dropping an item only ever marks a segment, but a track is spliced out of the order entirely, so nothing could put one back until this existed\n */\n async addARecordToTheRunningOrder(body: AddStationTrackInput): Promise<StationOrder> {\n const result = await this.fetch(`/director/air/tracks`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<StationOrder>(result);\n }\n\n /**\n * @name Move a running order item\n * @description Moves an item. A position already handed to the player is refused rather than clamped\n */\n async moveARunningOrderItem(itemId: string, body: MoveStationItemInput): Promise<StationOrder> {\n const result = await this.fetch(`/director/air/items/${encodeURIComponent(itemId)}`, {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<StationOrder>(result);\n }\n\n /**\n * @name Remove a running order item\n * @description Drops an item that has not been handed to the player yet\n */\n async removeARunningOrderItem(itemId: string): Promise<StationOrder> {\n const result = await this.fetch(`/director/air/items/${encodeURIComponent(itemId)}`, { method: 'DELETE' });\n return await parseJson<StationOrder>(result);\n }\n\n /**\n * @name Skip to a running order item\n * @description Makes a record further down the running order the next thing heard. Everything still to come in front of it is marked skipped, anything the player was already holding from in front of it is taken back, and the item on air is cut. Only a record can be skipped to, and only one still to come\n */\n async skipToARunningOrderItem(itemId: string): Promise<StationOrder> {\n const result = await this.fetch(`/director/air/items/${encodeURIComponent(itemId)}/skip-to`, { method: 'POST' });\n return await parseJson<StationOrder>(result);\n }\n\n /**\n * @name List never-play rules\n * @description Every never-play rule on this station, newest first, each saying whether it holds right now\n */\n async listNeverPlayRules(): Promise<BlockRuleList> {\n const result = await this.fetch(`/rules`, { method: 'GET' });\n return reviveBlockRuleList(await parseJson<BlockRuleList>(result));\n }\n\n /**\n * @name Add a never-play rule\n * @description Adds a rule. It holds from the next record the station chooses\n */\n async addANeverPlayRule(body: BlockRuleInput): Promise<BlockRuleList> {\n const result = await this.fetch(`/rules`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return reviveBlockRuleList(await parseJson<BlockRuleList>(result));\n }\n\n /**\n * @name Read the genre steer\n * @description The lean in force, if any\n */\n async readTheGenreSteer(): Promise<GenreSteerReading> {\n const result = await this.fetch(`/rules/steer`, { method: 'GET' });\n return reviveGenreSteerReading(await parseJson<GenreSteerReading>(result));\n }\n\n /**\n * @name Steer toward genres\n * @description Leans the station toward some genres for a number of hours, replacing any lean already in force\n */\n async steerTowardGenres(body: GenreSteerInput): Promise<GenreSteerReading> {\n const result = await this.fetch(`/rules/steer`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return reviveGenreSteerReading(await parseJson<GenreSteerReading>(result));\n }\n\n /**\n * @name Stop steering\n * @description Ends the lean now\n */\n async stopSteering(): Promise<GenreSteerReading> {\n const result = await this.fetch(`/rules/steer`, { method: 'DELETE' });\n return reviveGenreSteerReading(await parseJson<GenreSteerReading>(result));\n }\n\n /**\n * @name Change a never-play rule\n * @description Replaces a rule\n */\n async changeANeverPlayRule(id: string, body: BlockRuleInput): Promise<BlockRuleList> {\n const result = await this.fetch(`/rules/${encodeURIComponent(id)}`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return reviveBlockRuleList(await parseJson<BlockRuleList>(result));\n }\n\n /**\n * @name Remove a never-play rule\n * @description Removes a rule\n */\n async removeANeverPlayRule(id: string): Promise<BlockRuleList> {\n const result = await this.fetch(`/rules/${encodeURIComponent(id)}`, { method: 'DELETE' });\n return reviveBlockRuleList(await parseJson<BlockRuleList>(result));\n }\n}\n","import { DateTime } from 'luxon';\nconst __dt = (v: unknown, path: string): DateTime => {\n if (typeof v !== 'string') {\n throw new TypeError(`ContractKit: expected an ISO 8601 string at '${path}', received ${typeof v}.`);\n }\n const d = DateTime.fromISO(v);\n if (!d.isValid) throw new TypeError(`ContractKit: '${v}' at '${path}' is not a valid ISO 8601 datetime.`);\n return d;\n};\n\n/**\n * Somewhere the station sends what happens on it: an operator's own server, sent a signed POST per event\n * generated from [EventDestination](../../../../../apps/api/data/contracts/events/events.types.ck)\n */\nexport interface EventDestination {\n id: string;\n /** What the operator calls it */\n name: string;\n /** Where events are POSTed. http or https, and allowed to be on the station's own network. A redirect is never followed */\n url: string;\n /** Off sends nothing */\n enabled: boolean;\n /** The event types it is sent, from `/events/types`. Empty means every type, including any added later */\n events: string[];\n /** Deliveries in a row that did not arrive. Any delivery that arrives sets it back to nothing; at twenty the station turns the destination off */\n consecutiveFailures: number;\n /** Set when the station turned it off itself, because it kept failing. Turning it back on clears this and the count */\n disabledReason?: 'failing';\n lastDeliveredAt?: DateTime;\n lastFailedAt?: DateTime;\n /** What went wrong last time, in the station's words */\n lastFailure?: string;\n createdAt: DateTime;\n updatedAt: DateTime;\n}\n\nexport interface EventDestinationInput {\n /** What the operator calls it */\n name: string;\n /** Where events are POSTed. http or https, and allowed to be on the station's own network. A redirect is never followed */\n url: string;\n /** Off sends nothing */\n enabled: boolean;\n /** The event types it is sent, from `/events/types`. Empty means every type, including any added later */\n events: string[];\n}\n\n/** Rehydrates every wire-encoded scalar in a EventDestination into its runtime type. Mutates and returns `raw`. */\nexport function reviveEventDestination(raw: EventDestination): EventDestination {\n const __o0 = raw as unknown as Record<string, unknown>;\n if (__o0['lastDeliveredAt'] != null) {\n __o0['lastDeliveredAt'] = __dt(__o0['lastDeliveredAt'], 'EventDestination.lastDeliveredAt');\n }\n if (__o0['lastFailedAt'] != null) {\n __o0['lastFailedAt'] = __dt(__o0['lastFailedAt'], 'EventDestination.lastFailedAt');\n }\n __o0['createdAt'] = __dt(__o0['createdAt'], 'EventDestination.createdAt');\n __o0['updatedAt'] = __dt(__o0['updatedAt'], 'EventDestination.updatedAt');\n return raw;\n}\n\n/**\n * A new event destination\n * generated from [EventDestinationCreate](../../../../../apps/api/data/contracts/events/events.types.ck)\n */\nexport interface EventDestinationCreate {\n name: string;\n url: string;\n /** Defaults to on */\n enabled?: boolean;\n /** The event types to send it. Absent or empty means every type */\n events?: string[];\n}\n\n/**\n * Changes to an event destination. Only what is sent changes\n * generated from [EventDestinationUpdate](../../../../../apps/api/data/contracts/events/events.types.ck)\n */\nexport interface EventDestinationUpdate {\n name?: string;\n url?: string;\n /** Turning a destination back on also clears why the station turned it off, and its count of failures */\n enabled?: boolean;\n /** Empty means every type */\n events?: string[];\n}\n\n/**\n * The secret deliveries to a destination are signed with. Shown only when it is made, so keep it\n * generated from [EventDestinationSecret](../../../../../apps/api/data/contracts/events/events.types.ck)\n */\nexport interface EventDestinationSecret {\n /** Put this in the receiver. Each delivery carries `Deadair-Webhook-Signature: v1=<hex HMAC-SHA256 of \"<Deadair-Webhook-Timestamp>.<body>\">` */\n secret: string;\n}\n\n/**\n * One attempt at sending an event to a destination\n * generated from [EventDelivery](../../../../../apps/api/data/contracts/events/events.types.ck)\n */\nexport interface EventDelivery {\n id: string;\n /** The event's own id, which every attempt at it shares */\n eventId: string;\n eventType: string;\n attempt: number;\n /** `dropped` is an event no longer worth sending, such as a record that finished playing while its destination was down */\n outcome: 'delivered' | 'failed' | 'dropped';\n /** What the destination answered, when it answered at all */\n httpStatus?: number;\n durationMs: number;\n /** What went wrong, in the station's words. Never the destination's response body */\n error?: string;\n createdAt: DateTime;\n}\n\n/** Rehydrates every wire-encoded scalar in a EventDelivery into its runtime type. Mutates and returns `raw`. */\nexport function reviveEventDelivery(raw: EventDelivery): EventDelivery {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['createdAt'] = __dt(__o0['createdAt'], 'EventDelivery.createdAt');\n return raw;\n}\n\n/**\n * What a test delivery came to\n * generated from [EventTestResult](../../../../../apps/api/data/contracts/events/events.types.ck)\n */\nexport interface EventTestResult {\n delivered: boolean;\n /** What the destination answered, when it answered at all */\n httpStatus?: number;\n durationMs: number;\n /** Why it was not delivered, in the station's words */\n error?: string;\n}\n\n/**\n * Which station sent an event\n * generated from [EventStation](../../../../../apps/api/data/contracts/events/events.types.ck)\n */\nexport interface EventStation {\n key: string;\n name: string;\n}\n\n/**\n * `data` of `track.started`: a record began playing, as listeners heard it\n * generated from [TrackStartedData](../../../../../apps/api/data/contracts/events/events.types.ck)\n */\nexport interface TrackStartedData {\n /** The running order's id for this play */\n itemId: string;\n title: string;\n /** The credit as the release writes it */\n artists: string[];\n /** The credit as one line, for showing */\n artist: string;\n album?: string;\n year?: number;\n /** The station's catalog id, where the record is in the catalog */\n trackId?: string;\n durationMs?: number;\n /** When it should finish, as an ISO-8601 instant in UTC */\n endsAt?: string;\n /** The cover as the station serves it publicly, or the station's logo. Absent when the station has no public address */\n artworkUrl?: string;\n}\n\n/**\n * `data` of `talk.started`: the station began speaking, in a break or a bulletin\n * generated from [TalkStartedData](../../../../../apps/api/data/contracts/events/events.types.ck)\n */\nexport interface TalkStartedData {\n itemId: string;\n segmentId: string;\n /** What sort of break: `talkbreak`, `news`, `weather`, `welcome` and so on */\n kind: string;\n /** What a listener may be told it is, where the writer said */\n label?: string;\n durationMs?: number;\n /** When it should finish, as an ISO-8601 instant in UTC */\n endsAt?: string;\n}\n\n/**\n * `data` of `production.started`: a produced piece, such as a phone-in or a guest, began. Sent once per production\n * generated from [ProductionStartedData](../../../../../apps/api/data/contracts/events/events.types.ck)\n */\nexport interface ProductionStartedData {\n itemId: string;\n productionId: string;\n /** What sort of production: `callin`, `visit`, `banter` and so on */\n kind: string;\n title: string;\n durationMs?: number;\n /** When it should finish, as an ISO-8601 instant in UTC */\n endsAt?: string;\n}\n\n/**\n * `data` of `programme.started`: a programme the station carries began, a podcast episode or a reading\n * generated from [ProgrammeStartedData](../../../../../apps/api/data/contracts/events/events.types.ck)\n */\nexport interface ProgrammeStartedData {\n itemId: string;\n segmentId: string;\n /** A podcast episode as published, or something the station reads out itself */\n source: 'podcast' | 'narration';\n show?: string;\n episode: string;\n durationMs?: number;\n /** When it should finish, as an ISO-8601 instant in UTC */\n endsAt?: string;\n}\n\n/**\n * `data` of `station.onAir` and `station.offAir`: the station went on air, or came off it\n * generated from [StationAirData](../../../../../apps/api/data/contracts/events/events.types.ck)\n */\nexport interface StationAirData {\n /** A new running order, the stopped one started again, somebody stopping it, or the running order running out */\n reason: 'programme' | 'resumed' | 'stopped' | 'ranOut';\n /** The running order's name, when going on air with a new one that has one */\n programme?: string;\n}\n\n/**\n * Who a request is dedicated to, and what the listener wanted said. The listener's own words\n * generated from [RequestDedication](../../../../../apps/api/data/contracts/events/events.types.ck)\n */\nexport interface RequestDedication {\n to?: string;\n message?: string;\n}\n\n/**\n * Every event destination, oldest first\n * generated from [EventDestinationList](../../../../../apps/api/data/contracts/events/events.types.ck)\n */\nexport interface EventDestinationList {\n destinations: EventDestination[];\n}\n\nexport interface EventDestinationListInput {\n destinations: EventDestinationInput[];\n}\n\n/** Rehydrates every wire-encoded scalar in a EventDestinationList into its runtime type. Mutates and returns `raw`. */\nexport function reviveEventDestinationList(raw: EventDestinationList): EventDestinationList {\n const __o0 = raw as unknown as Record<string, unknown>;\n {\n const __a1 = __o0['destinations'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveEventDestination(__a1[__i2] as never);\n }\n }\n return raw;\n}\n\n/**\n * A destination just made, with its secret\n * generated from [EventDestinationCreated](../../../../../apps/api/data/contracts/events/events.types.ck)\n */\nexport type EventDestinationCreated = EventDestination & EventDestinationSecret;\nexport type EventDestinationCreatedInput = EventDestinationInput & EventDestinationSecret;\n\n/** Rehydrates every wire-encoded scalar in a EventDestinationCreated into its runtime type. Mutates and returns `raw`. */\nexport function reviveEventDestinationCreated(raw: EventDestinationCreated): EventDestinationCreated {\n const __v = [raw] as unknown[];\n reviveEventDestination(__v[0] as never);\n return __v[0] as EventDestinationCreated;\n}\n\n/**\n * A destination's latest delivery attempts, newest first. The station keeps the latest fifty\n * generated from [EventDeliveryList](../../../../../apps/api/data/contracts/events/events.types.ck)\n */\nexport interface EventDeliveryList {\n deliveries: EventDelivery[];\n}\n\n/** Rehydrates every wire-encoded scalar in a EventDeliveryList into its runtime type. Mutates and returns `raw`. */\nexport function reviveEventDeliveryList(raw: EventDeliveryList): EventDeliveryList {\n const __o0 = raw as unknown as Record<string, unknown>;\n {\n const __a1 = __o0['deliveries'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveEventDelivery(__a1[__i2] as never);\n }\n }\n return raw;\n}\n\n/**\n * One event, as a destination receives it. The same shape for every type: read `type`, then `data`\n * generated from [EventEnvelope](../../../../../apps/api/data/contracts/events/events.types.ck)\n */\nexport interface EventEnvelope {\n /** The event's own id. A redelivery of the same event carries the same one */\n id: string;\n /** What happened, such as `track.started` */\n type: string;\n /** When, as an ISO-8601 instant in UTC */\n occurredAt: string;\n station: EventStation;\n /** What the type says it holds. `/events/types` gives an example of each */\n data: Record<string, unknown>;\n}\n\n/**\n * `data` of `request.received`: a listener asked for a record, from an app, the console, a party pass or a chat\n * generated from [RequestReceivedData](../../../../../apps/api/data/contracts/events/events.types.ck)\n */\nexport interface RequestReceivedData {\n requestId: string;\n trackId: string;\n title: string;\n artist: string;\n /** What the listener is called, as the station names them */\n requesterName: string;\n /** Where they asked from. `app` covers the console, the listener apps and a party pass */\n via: 'app' | 'chat';\n /** How it stands now: waiting on an operator, waiting on its audio, in the running order, or declined */\n status: 'waiting' | 'pending' | 'queued' | 'aired' | 'declined' | 'expired';\n /** Why it was declined, as the listener is told */\n reason?: string;\n /** The listener asked for it again after the station turned it down for its own taste */\n insisted?: boolean;\n dedication?: RequestDedication;\n}\n\n/**\n * One kind of event the station sends\n * generated from [EventType](../../../../../apps/api/data/contracts/events/events.types.ck)\n */\nexport interface EventType {\n type: string;\n /** When it is sent, and what its `data` holds */\n description: string;\n /** False for the test event, which only a test delivery sends */\n subscribable: boolean;\n example: EventEnvelope;\n}\n\n/**\n * Every kind of event the station sends\n * generated from [EventTypeList](../../../../../apps/api/data/contracts/events/events.types.ck)\n */\nexport interface EventTypeList {\n types: EventType[];\n}\n","import type { SdkFetch } from '../sdk-options.js';\nimport { bigIntReplacer, parseJson } from '../sdk-options.js';\nimport type {\n EventDeliveryList,\n EventDestination,\n EventDestinationCreate,\n EventDestinationCreated,\n EventDestinationList,\n EventDestinationSecret,\n EventDestinationUpdate,\n EventTestResult,\n EventTypeList,\n} from './types/events.types.js';\nimport { reviveEventDeliveryList, reviveEventDestination, reviveEventDestinationCreated, reviveEventDestinationList } from './types/events.types.js';\n\nexport class EventsClient {\n constructor(private fetch: SdkFetch) {}\n\n /**\n * @name List event types\n * @description Every kind of event the station sends, each with an example of what a destination receives\n */\n async listEventTypes(): Promise<EventTypeList> {\n const result = await this.fetch(`/events/types`, { method: 'GET' });\n return await parseJson<EventTypeList>(result);\n }\n\n /**\n * @name List event destinations\n * @description Every event destination, oldest first\n */\n async listEventDestinations(): Promise<EventDestinationList> {\n const result = await this.fetch(`/events/destinations`, { method: 'GET' });\n return reviveEventDestinationList(await parseJson<EventDestinationList>(result));\n }\n\n /**\n * @name Create event destination\n * @description Add an event destination. The answer carries its signing secret, which is not shown again\n */\n async createEventDestination(body: EventDestinationCreate): Promise<EventDestinationCreated> {\n const result = await this.fetch(`/events/destinations`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return reviveEventDestinationCreated(await parseJson<EventDestinationCreated>(result));\n }\n\n /**\n * @name Update event destination\n * @description Change an event destination's name, address, or whether it is on\n */\n async updateEventDestination(id: string, body: EventDestinationUpdate): Promise<EventDestination> {\n const result = await this.fetch(`/events/destinations/${encodeURIComponent(id)}`, {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return reviveEventDestination(await parseJson<EventDestination>(result));\n }\n\n /**\n * @name Delete event destination\n * @description Remove an event destination and its delivery log\n */\n async deleteEventDestination(id: string): Promise<void> {\n await this.fetch(`/events/destinations/${encodeURIComponent(id)}`, { method: 'DELETE' });\n }\n\n /**\n * @name Rotate event destination secret\n * @description Make a new signing secret for a destination. The old one stops working at once\n */\n async rotateEventDestinationSecret(id: string): Promise<EventDestinationSecret> {\n const result = await this.fetch(`/events/destinations/${encodeURIComponent(id)}/secret`, { method: 'POST' });\n return await parseJson<EventDestinationSecret>(result);\n }\n\n /**\n * @name Test event destination\n * @description Send a destination a test event now, and say what it answered. Sent even when the destination is off\n */\n async testEventDestination(id: string): Promise<EventTestResult> {\n const result = await this.fetch(`/events/destinations/${encodeURIComponent(id)}/test`, { method: 'POST' });\n return await parseJson<EventTestResult>(result);\n }\n\n /**\n * @name List event deliveries\n * @description A destination's latest delivery attempts, newest first\n */\n async listEventDeliveries(id: string): Promise<EventDeliveryList> {\n const result = await this.fetch(`/events/destinations/${encodeURIComponent(id)}/deliveries`, { method: 'GET' });\n return reviveEventDeliveryList(await parseJson<EventDeliveryList>(result));\n }\n}\n","import { DateTime } from 'luxon';\nconst __dt = (v: unknown, path: string): DateTime => {\n if (typeof v !== 'string') {\n throw new TypeError(`ContractKit: expected an ISO 8601 string at '${path}', received ${typeof v}.`);\n }\n const d = DateTime.fromISO(v);\n if (!d.isValid) throw new TypeError(`ContractKit: '${v}' at '${path}' is not a valid ISO 8601 datetime.`);\n return d;\n};\n\n/**\n * One record the station actually played\n * generated from [HistoryEntry](../../../../../apps/api/data/contracts/history/history.types.ck)\n */\nexport interface HistoryEntry {\n /** Unique across the history, and half of the cursor below */\n id: string;\n /** When it started, written when it began rather than when it was handed to the player */\n airedAt: DateTime;\n title: string;\n /** The credit as written, whole: one line rather than a list, because that is the shape a release credits itself in and splitting it renames acts with a comma in their name */\n artists: string;\n /** Absent for anything aired straight from a provider, which the catalog holds no record for */\n album?: string;\n /** The station's own copy where it has one, as a path under the API root, and the upstream URL until then. Resolve it against the base the station is reached at */\n artworkUrl?: string;\n /** How long the recording runs, from the catalog rather than from the copy that played */\n durationMs?: number;\n /** The catalog track this was, for a client that wants to ask more about it. Absent for a record the catalog does not hold, and for one it has since forgotten */\n trackId?: string;\n}\n\n/** Rehydrates every wire-encoded scalar in a HistoryEntry into its runtime type. Mutates and returns `raw`. */\nexport function reviveHistoryEntry(raw: HistoryEntry): HistoryEntry {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['airedAt'] = __dt(__o0['airedAt'], 'HistoryEntry.airedAt');\n return raw;\n}\n\n/**\n * One page of the history, newest first\n * generated from [HistoryQuery](../../../../../apps/api/data/contracts/history/history.types.ck)\n */\nexport interface HistoryQuery {\n limit?: number;\n /** Where the previous page ended. Opaque, and a keyset rather than an offset because rows arrive at the head continuously: an offset would re-show a row on every page as the station kept playing under it. Pass back whatever `nextBefore` said and nothing else */\n before?: string;\n}\n\n/**\n * generated from [HistoryPage](../../../../../apps/api/data/contracts/history/history.types.ck)\n */\nexport interface HistoryPage {\n entries: HistoryEntry[];\n /** The cursor for the page after this one, absent once the history has been read to its end */\n nextBefore?: string;\n}\n\n/** Rehydrates every wire-encoded scalar in a HistoryPage into its runtime type. Mutates and returns `raw`. */\nexport function reviveHistoryPage(raw: HistoryPage): HistoryPage {\n const __o0 = raw as unknown as Record<string, unknown>;\n {\n const __a1 = __o0['entries'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveHistoryEntry(__a1[__i2] as never);\n }\n }\n return raw;\n}\n","import type { SdkFetch } from '../sdk-options.js';\nimport { parseJson, buildQueryString } from '../sdk-options.js';\nimport type { HistoryPage, HistoryQuery } from './types/history.types.js';\nimport { reviveHistoryPage } from './types/history.types.js';\n\nexport class HistoryClient {\n constructor(private fetch: SdkFetch) {}\n\n /**\n * @name Read history\n * @description What the station played, newest first, one page at a time\n */\n async readHistory(query?: HistoryQuery): Promise<HistoryPage> {\n const qs = buildQueryString(query);\n const result = await this.fetch(`/history${qs}`, {\n method: 'GET',\n });\n return reviveHistoryPage(await parseJson<HistoryPage>(result));\n }\n}\n","import { DateTime } from 'luxon';\nconst __dt = (v: unknown, path: string): DateTime => {\n if (typeof v !== 'string') {\n throw new TypeError(`ContractKit: expected an ISO 8601 string at '${path}', received ${typeof v}.`);\n }\n const d = DateTime.fromISO(v);\n if (!d.isValid) throw new TypeError(`ContractKit: '${v}' at '${path}' is not a valid ISO 8601 datetime.`);\n return d;\n};\n\n/**\n * A language pack: every word the console says, in one language, as the file a translator made. The same document is exported, imported and stored. The console's language only; what the station broadcasts in is the `stream.language` setting\n * generated from [ConsoleLanguagePack](../../../../../apps/api/data/contracts/languages/languages.types.ck)\n */\nexport interface ConsoleLanguagePack {\n /** Says the file is a console language pack */\n format: 'deadair.console-language';\n /** The version of the document's shape. This station reads version 1 */\n version: number;\n /** The language, as a BCP 47 tag such as `de` or `pt-BR`. Never English, which is built into the console */\n locale: string;\n /** The language's name in itself, as the console's picker shows it: `Deutsch`, not `German` */\n name: string;\n /** Which way its text runs */\n direction: 'ltr' | 'rtl';\n /** The console version the pack was translated against. Empty when the file did not say */\n madeFor: string;\n /** The strings, nested by namespace and then by key, in the English catalog's shape. Every value is text or a further level of nesting */\n catalog: Record<string, unknown>;\n}\n\n/**\n * A language the console can be shown in on this station, without its strings\n * generated from [ConsoleLanguage](../../../../../apps/api/data/contracts/languages/languages.types.ck)\n */\nexport interface ConsoleLanguage {\n locale: string;\n name: string;\n direction: 'ltr' | 'rtl';\n madeFor: string;\n /** When the pack now installed for it was imported */\n importedAt: DateTime;\n}\n\n/** Rehydrates every wire-encoded scalar in a ConsoleLanguage into its runtime type. Mutates and returns `raw`. */\nexport function reviveConsoleLanguage(raw: ConsoleLanguage): ConsoleLanguage {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['importedAt'] = __dt(__o0['importedAt'], 'ConsoleLanguage.importedAt');\n return raw;\n}\n\n/**\n * The language the signed-in operator chose for the console. Absent means none was chosen, and the console follows the browser's own preference among the languages it has\n * generated from [ConsoleLanguageChoice](../../../../../apps/api/data/contracts/languages/languages.types.ck)\n */\nexport interface ConsoleLanguageChoice {\n /** A language this station holds a pack for, or `en` for English whatever the browser prefers */\n locale?: string;\n}\n\n/**\n * generated from [ConsoleLanguageList](../../../../../apps/api/data/contracts/languages/languages.types.ck)\n */\nexport interface ConsoleLanguageList {\n /** In order of their tags. English is built in and is never listed */\n languages: ConsoleLanguage[];\n}\n\n/** Rehydrates every wire-encoded scalar in a ConsoleLanguageList into its runtime type. Mutates and returns `raw`. */\nexport function reviveConsoleLanguageList(raw: ConsoleLanguageList): ConsoleLanguageList {\n const __o0 = raw as unknown as Record<string, unknown>;\n {\n const __a1 = __o0['languages'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveConsoleLanguage(__a1[__i2] as never);\n }\n }\n return raw;\n}\n","import type { SdkFetch } from '../sdk-options.js';\nimport { bigIntReplacer, parseJson } from '../sdk-options.js';\nimport type { ConsoleLanguageChoice, ConsoleLanguageList, ConsoleLanguagePack } from './types/languages.types.js';\nimport { reviveConsoleLanguageList } from './types/languages.types.js';\n\nexport class LanguagesClient {\n constructor(private fetch: SdkFetch) {}\n\n /**\n * @name Get my console language\n * @description The language you chose for the console, if you chose one\n */\n async getMyConsoleLanguage(): Promise<ConsoleLanguageChoice> {\n const result = await this.fetch(`/console/language`, { method: 'GET' });\n return await parseJson<ConsoleLanguageChoice>(result);\n }\n\n /**\n * @name Choose my console language\n * @description Chooses the language your console is shown in, or, without one, goes back to following the browser\n */\n async chooseMyConsoleLanguage(body: ConsoleLanguageChoice): Promise<ConsoleLanguageChoice> {\n const result = await this.fetch(`/console/language`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<ConsoleLanguageChoice>(result);\n }\n\n /**\n * @name List console languages\n * @description Every language this station holds a pack for, without the strings\n */\n async listConsoleLanguages(): Promise<ConsoleLanguageList> {\n const result = await this.fetch(`/console/languages`, { method: 'GET' });\n return reviveConsoleLanguageList(await parseJson<ConsoleLanguageList>(result));\n }\n\n /**\n * @name Get console language\n * @description One language's pack, strings and all, as it was imported\n */\n async getConsoleLanguage(locale: string): Promise<ConsoleLanguagePack> {\n const result = await this.fetch(`/console/languages/${encodeURIComponent(locale)}`, { method: 'GET' });\n return await parseJson<ConsoleLanguagePack>(result);\n }\n\n /**\n * @name Import console language\n * @description Installs a language pack, replacing any pack already installed for the language. The tag in the path must be the pack's own\n */\n async importConsoleLanguage(locale: string, body: ConsoleLanguagePack): Promise<ConsoleLanguageList> {\n const result = await this.fetch(`/console/languages/${encodeURIComponent(locale)}`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return reviveConsoleLanguageList(await parseJson<ConsoleLanguageList>(result));\n }\n\n /**\n * @name Remove console language\n * @description Removes a language. Anybody who had chosen it sees English\n */\n async removeConsoleLanguage(locale: string): Promise<ConsoleLanguageList> {\n const result = await this.fetch(`/console/languages/${encodeURIComponent(locale)}`, { method: 'DELETE' });\n return reviveConsoleLanguageList(await parseJson<ConsoleLanguageList>(result));\n }\n}\n","import { DateTime } from 'luxon';\nconst __dt = (v: unknown, path: string): DateTime => {\n if (typeof v !== 'string') {\n throw new TypeError(`ContractKit: expected an ISO 8601 string at '${path}', received ${typeof v}.`);\n }\n const d = DateTime.fromISO(v);\n if (!d.isValid) throw new TypeError(`ContractKit: '${v}' at '${path}' is not a valid ISO 8601 datetime.`);\n return d;\n};\n\n/**\n * A one-time code that links a chat account to the signed-in station account. Shown once: send it to the station's bot as `/link CODE` in a direct message\n * generated from [MessagingLinkCode](../../../../../apps/api/data/contracts/messaging/messaging.types.ck)\n */\nexport interface MessagingLinkCode {\n /** The code itself. Case does not matter when it is sent */\n code: string;\n /** When the code stops working. A new code replaces any earlier one */\n expiresAt: DateTime;\n}\n\n/** Rehydrates every wire-encoded scalar in a MessagingLinkCode into its runtime type. Mutates and returns `raw`. */\nexport function reviveMessagingLinkCode(raw: MessagingLinkCode): MessagingLinkCode {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['expiresAt'] = __dt(__o0['expiresAt'], 'MessagingLinkCode.expiresAt');\n return raw;\n}\n\n/**\n * A chat account linked to the signed-in station account. Operator commands sent from it run with this account's permissions\n * generated from [MessagingLink](../../../../../apps/api/data/contracts/messaging/messaging.types.ck)\n */\nexport interface MessagingLink {\n /** Which messaging plugin the chat account is on, for example `deadair.telegram` */\n pluginId: string;\n /** The chat platform's own id for the person */\n platformUserId: string;\n /** What the chat platform called them when they linked */\n displayName: string;\n /** When the link was made */\n createdAt: DateTime;\n}\n\n/** Rehydrates every wire-encoded scalar in a MessagingLink into its runtime type. Mutates and returns `raw`. */\nexport function reviveMessagingLink(raw: MessagingLink): MessagingLink {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['createdAt'] = __dt(__o0['createdAt'], 'MessagingLink.createdAt');\n return raw;\n}\n\n/**\n * Every chat account linked to the signed-in station account, newest first\n * generated from [MessagingLinkList](../../../../../apps/api/data/contracts/messaging/messaging.types.ck)\n */\nexport interface MessagingLinkList {\n links: MessagingLink[];\n}\n\n/** Rehydrates every wire-encoded scalar in a MessagingLinkList into its runtime type. Mutates and returns `raw`. */\nexport function reviveMessagingLinkList(raw: MessagingLinkList): MessagingLinkList {\n const __o0 = raw as unknown as Record<string, unknown>;\n {\n const __a1 = __o0['links'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveMessagingLink(__a1[__i2] as never);\n }\n }\n return raw;\n}\n","import type { SdkFetch } from '../sdk-options.js';\nimport { parseJson } from '../sdk-options.js';\nimport type { MessagingLinkCode, MessagingLinkList } from './types/messaging.types.js';\nimport { reviveMessagingLinkCode, reviveMessagingLinkList } from './types/messaging.types.js';\n\nexport class MessagingClient {\n constructor(private fetch: SdkFetch) {}\n\n /**\n * @name List messaging links\n * @description The chat accounts linked to the signed-in account\n */\n async listMessagingLinks(): Promise<MessagingLinkList> {\n const result = await this.fetch(`/messaging/links`, { method: 'GET' });\n return reviveMessagingLinkList(await parseJson<MessagingLinkList>(result));\n }\n\n /**\n * @name Create messaging link code\n * @description A new one-time code for linking a chat account. It replaces any earlier code and stops working after ten minutes\n */\n async createMessagingLinkCode(): Promise<MessagingLinkCode> {\n const result = await this.fetch(`/messaging/links/code`, { method: 'POST' });\n return reviveMessagingLinkCode(await parseJson<MessagingLinkCode>(result));\n }\n\n /**\n * @name Remove messaging link\n * @description Unlink a chat account. Its operator commands are refused from the next one on\n */\n async removeMessagingLink(pluginId: string, platformUserId: string): Promise<void> {\n await this.fetch(`/messaging/links/${encodeURIComponent(pluginId)}/${encodeURIComponent(platformUserId)}`, { method: 'DELETE' });\n }\n}\n","import { DateTime } from 'luxon';\nconst __dt = (v: unknown, path: string): DateTime => {\n if (typeof v !== 'string') {\n throw new TypeError(`ContractKit: expected an ISO 8601 string at '${path}', received ${typeof v}.`);\n }\n const d = DateTime.fromISO(v);\n if (!d.isValid) throw new TypeError(`ContractKit: '${v}' at '${path}' is not a valid ISO 8601 datetime.`);\n return d;\n};\n\n/**\n * How wide one point is. Chosen by the station from the range asked for: minutes for two days or less, hours beyond\n * generated from [MetricResolution](../../../../../apps/api/data/contracts/metrics/metrics.types.ck)\n */\nexport type MetricResolution = 'minute' | 'hour';\n\n/**\n * The trends to read, over one range\n * generated from [MetricSeriesQuery](../../../../../apps/api/data/contracts/metrics/metrics.types.ck)\n */\nexport interface MetricSeriesQuery {\n /** Comma-separated metric names, at most twenty: `station.listeners,work.job.ms` */\n names: string;\n /** The start of the range, inclusive */\n from: DateTime;\n /** The end of the range, exclusive. At most four hundred days after `from` */\n to: DateTime;\n}\n\n/** Rehydrates every wire-encoded scalar in a MetricSeriesQuery into its runtime type. Mutates and returns `raw`. */\nexport function reviveMetricSeriesQuery(raw: MetricSeriesQuery): MetricSeriesQuery {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['from'] = __dt(__o0['from'], 'MetricSeriesQuery.from');\n __o0['to'] = __dt(__o0['to'], 'MetricSeriesQuery.to');\n return raw;\n}\n\n/**\n * One series over one minute or hour\n * generated from [MetricPoint](../../../../../apps/api/data/contracts/metrics/metrics.types.ck)\n */\nexport interface MetricPoint {\n /** The start of the minute or hour */\n at: DateTime;\n /** How many observations were folded in */\n count: number;\n /** Their total: a counter's value, or with `count` a duration's mean */\n sum: number;\n /** The smallest observation */\n min: number;\n /** The largest observation: a duration's worst */\n max: number;\n /** The latest observation: a gauge's value */\n last: number;\n}\n\n/** Rehydrates every wire-encoded scalar in a MetricPoint into its runtime type. Mutates and returns `raw`. */\nexport function reviveMetricPoint(raw: MetricPoint): MetricPoint {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['at'] = __dt(__o0['at'], 'MetricPoint.at');\n return raw;\n}\n\n/**\n * A metric the station holds, for a picker\n * generated from [MetricName](../../../../../apps/api/data/contracts/metrics/metrics.types.ck)\n */\nexport interface MetricName {\n name: string;\n source: string;\n /** Every label any of its series carries, sorted */\n labelKeys: string[];\n /** The newest point held for it, at either resolution */\n lastSeen: DateTime;\n}\n\n/** Rehydrates every wire-encoded scalar in a MetricName into its runtime type. Mutates and returns `raw`. */\nexport function reviveMetricName(raw: MetricName): MetricName {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['lastSeen'] = __dt(__o0['lastSeen'], 'MetricName.lastSeen');\n return raw;\n}\n\n/**\n * An OTLP/HTTP metrics export, sent as JSON. Only the top level is checked here; the station reads the rest itself and counts what it cannot use rather than refusing the whole request\n * generated from [OtlpMetricsExport](../../../../../apps/api/data/contracts/metrics/metrics.types.ck)\n */\nexport interface OtlpMetricsExport {\n resourceMetrics: Record<string, unknown>[];\n}\n\n/**\n * OTLP's answer when some points were not taken\n * generated from [OtlpPartialSuccess](../../../../../apps/api/data/contracts/metrics/metrics.types.ck)\n */\nexport interface OtlpPartialSuccess {\n /** How many, as OTLP writes a 64-bit count: a digit string */\n rejectedDataPoints: string;\n errorMessage: string;\n}\n\n/**\n * One metric and one set of labels, its points oldest first\n * generated from [MetricSeries](../../../../../apps/api/data/contracts/metrics/metrics.types.ck)\n */\nexport interface MetricSeries {\n name: string;\n /** What tells this series from the metric's others: `{ \"queue\": \"catalog.sync\" }`. Empty for a metric with one series */\n labels: Record<string, string>;\n /** `station` for what the station measured itself, `otlp` for what another service sent it */\n source: string;\n /** Only the buckets that hold something. A gap is a stretch nothing was measured, which a chart should draw as a gap */\n points: MetricPoint[];\n}\n\n/** Rehydrates every wire-encoded scalar in a MetricSeries into its runtime type. Mutates and returns `raw`. */\nexport function reviveMetricSeries(raw: MetricSeries): MetricSeries {\n const __o0 = raw as unknown as Record<string, unknown>;\n {\n const __a1 = __o0['points'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveMetricPoint(__a1[__i2] as never);\n }\n }\n return raw;\n}\n\n/**\n * generated from [MetricNames](../../../../../apps/api/data/contracts/metrics/metrics.types.ck)\n */\nexport interface MetricNames {\n /** Sorted by name */\n names: MetricName[];\n}\n\n/** Rehydrates every wire-encoded scalar in a MetricNames into its runtime type. Mutates and returns `raw`. */\nexport function reviveMetricNames(raw: MetricNames): MetricNames {\n const __o0 = raw as unknown as Record<string, unknown>;\n {\n const __a1 = __o0['names'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveMetricName(__a1[__i2] as never);\n }\n }\n return raw;\n}\n\n/**\n * OTLP's answer to an export. Empty when every point was taken\n * generated from [OtlpExportResponse](../../../../../apps/api/data/contracts/metrics/metrics.types.ck)\n */\nexport interface OtlpExportResponse {\n partialSuccess?: OtlpPartialSuccess;\n}\n\n/**\n * generated from [MetricSeriesPage](../../../../../apps/api/data/contracts/metrics/metrics.types.ck)\n */\nexport interface MetricSeriesPage {\n /** The width the points were read at */\n resolution: MetricResolution;\n from: DateTime;\n to: DateTime;\n /** Empty when nothing was measured in the range, which is not an error */\n series: MetricSeries[];\n}\n\n/** Rehydrates every wire-encoded scalar in a MetricSeriesPage into its runtime type. Mutates and returns `raw`. */\nexport function reviveMetricSeriesPage(raw: MetricSeriesPage): MetricSeriesPage {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['from'] = __dt(__o0['from'], 'MetricSeriesPage.from');\n __o0['to'] = __dt(__o0['to'], 'MetricSeriesPage.to');\n {\n const __a1 = __o0['series'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveMetricSeries(__a1[__i2] as never);\n }\n }\n return raw;\n}\n","import type { SdkFetch } from '../sdk-options.js';\nimport { parseJson, buildQueryString } from '../sdk-options.js';\nimport type { MetricNames, MetricSeriesPage, MetricSeriesQuery } from './types/metrics.types.js';\nimport { reviveMetricNames, reviveMetricSeriesPage } from './types/metrics.types.js';\n\nexport class MetricsClient {\n constructor(private fetch: SdkFetch) {}\n\n /**\n * @name Read metric series\n * @description Trends over a range, at minute resolution for two days or less and hourly beyond\n */\n async readMetricSeries(query?: MetricSeriesQuery): Promise<MetricSeriesPage> {\n const qs = buildQueryString(query);\n const result = await this.fetch(`/metrics/series${qs}`, {\n method: 'GET',\n });\n return reviveMetricSeriesPage(await parseJson<MetricSeriesPage>(result));\n }\n\n /**\n * @name Read metric names\n * @description Every metric the station holds, with its labels and when it was last measured\n */\n async readMetricNames(): Promise<MetricNames> {\n const result = await this.fetch(`/metrics/names`, { method: 'GET' });\n return reviveMetricNames(await parseJson<MetricNames>(result));\n }\n}\n","import type { SdkFetch } from '../sdk-options.js';\nimport { parseJson, buildQueryString } from '../sdk-options.js';\nimport type { StationPiece, StationPiecePage, StationPieceQuery, StationSeriesList } from './types/narrations.types.js';\n\nexport class NarrationsClient {\n constructor(private fetch: SdkFetch) {}\n\n /**\n * @name List series\n * @description Every series every installed narration plugin offers\n */\n async listSeries(): Promise<StationSeriesList> {\n const result = await this.fetch(`/narrations/series`, { method: 'GET' });\n return await parseJson<StationSeriesList>(result);\n }\n\n /**\n * @name List pieces\n * @description The pieces the station knows about, in their series' own order, with what it has done with each\n */\n async listPieces(query?: StationPieceQuery): Promise<StationPiecePage> {\n const qs = buildQueryString(query);\n const result = await this.fetch(`/narrations/pieces${qs}`, {\n method: 'GET',\n });\n return await parseJson<StationPiecePage>(result);\n }\n\n /**\n * @name Render piece\n * @description Has one piece spoken now, rather than waiting for its slot to come near\n */\n async renderPiece(id: string): Promise<StationPiece> {\n const result = await this.fetch(`/narrations/pieces/${encodeURIComponent(id)}/render`, { method: 'POST' });\n return await parseJson<StationPiece>(result);\n }\n\n /**\n * @name Refresh narrations\n * @description Reads every series again, in the background, rather than waiting for the next scheduled refresh\n */\n async refreshNarrations(): Promise<void> {\n await this.fetch(`/narrations/refresh`, { method: 'POST' });\n }\n}\n","import type { SdkFetch } from '../sdk-options.js';\nimport { parseJson, buildQueryString } from '../sdk-options.js';\nimport type { NewsPage, NewsQuery, StationFeedList } from './types/news.types.js';\n\nexport class NewsClient {\n constructor(private fetch: SdkFetch) {}\n\n /**\n * @name List feeds\n * @description Every feed every installed news plugin currently offers\n */\n async listFeeds(): Promise<StationFeedList> {\n const result = await this.fetch(`/news/feeds`, { method: 'GET' });\n return await parseJson<StationFeedList>(result);\n }\n\n /**\n * @name Read news\n * @description Published entries, newest first\n */\n async readNews(query?: NewsQuery): Promise<NewsPage> {\n const qs = buildQueryString(query);\n const result = await this.fetch(`/news${qs}`, {\n method: 'GET',\n });\n return await parseJson<NewsPage>(result);\n }\n}\n","import type { SdkFetch } from '../sdk-options.js';\nimport { parseJson } from '../sdk-options.js';\nimport type { NowPlaying, NowPlayingLyrics } from './types/nowplaying.types.js';\n\nexport class NowplayingClient {\n constructor(private fetch: SdkFetch) {}\n\n /**\n * @name Get now playing\n * @description What is on air right now. Answers 200 with `onAir: false` when the station is quiet, so a device polling this treats silence as an answer rather than an error\n */\n async getNowPlaying(): Promise<NowPlaying> {\n const result = await this.fetch(`/nowplaying`, { method: 'GET' });\n return await parseJson<NowPlaying>(result);\n }\n\n /**\n * @name Get now playing lyrics\n * @description The words of the record on air, with what a player needs to follow along line by line\n */\n async getNowPlayingLyrics(): Promise<NowPlayingLyrics> {\n const result = await this.fetch(`/nowplaying/lyrics`, { method: 'GET' });\n return await parseJson<NowPlayingLyrics>(result);\n }\n}\n","import { DateTime } from 'luxon';\nconst __dt = (v: unknown, path: string): DateTime => {\n if (typeof v !== 'string') {\n throw new TypeError(`ContractKit: expected an ISO 8601 string at '${path}', received ${typeof v}.`);\n }\n const d = DateTime.fromISO(v);\n if (!d.isValid) throw new TypeError(`ContractKit: '${v}' at '${path}' is not a valid ISO 8601 datetime.`);\n return d;\n};\n\n/**\n * An app's authorization request, as the consent page received it\n * generated from [OAuthAuthorizationQuery](../../../../../apps/api/data/contracts/oauth/oauth.types.ck)\n */\nexport interface OAuthAuthorizationQuery {\n /** The query string the app sent the browser to the consent page with, as `window.location.search` holds it */\n query: string;\n}\n\n/**\n * How the station knows an app: registered by an operator, registered by itself, or described by a document on its own website\n * generated from [OAuthClientKind](../../../../../apps/api/data/contracts/oauth/oauth.types.ck)\n */\nexport type OAuthClientKind = 'preregistered' | 'dynamic' | 'metadata_document';\n\n/**\n * A request with something wrong that the app should be told about: send the browser back to it\n * generated from [OAuthAuthorizationRedirect](../../../../../apps/api/data/contracts/oauth/oauth.types.ck)\n */\nexport interface OAuthAuthorizationRedirect {\n /** Discriminator */\n kind: 'redirect';\n /** Where to send the browser */\n redirectUrl: string;\n}\n\n/**\n * A request that names no app the station knows, or an address the app did not register. Never sent anywhere\n * generated from [OAuthAuthorizationRefusal](../../../../../apps/api/data/contracts/oauth/oauth.types.ck)\n */\nexport interface OAuthAuthorizationRefusal {\n /** Discriminator */\n kind: 'refuse';\n /** The OAuth error code */\n error: string;\n /** What was wrong, in words */\n description: string;\n}\n\n/**\n * Denying a stashed request\n * generated from [OAuthAuthorizationDecision](../../../../../apps/api/data/contracts/oauth/oauth.types.ck)\n */\nexport interface OAuthAuthorizationDecision {\n /** From the context */\n requestId: string;\n}\n\n/**\n * What a connected app may do on the station. `view` reads it; `manage` changes it and includes `view`. Never more than the person approving it may do\n * generated from [OAuthGrantScope](../../../../../apps/api/data/contracts/oauth/oauth.types.ck)\n */\nexport type OAuthGrantScope = 'view' | 'manage';\n\n/**\n * Where to send the browser now\n * generated from [OAuthAuthorizationOutcome](../../../../../apps/api/data/contracts/oauth/oauth.types.ck)\n */\nexport interface OAuthAuthorizationOutcome {\n /** The app's own address, carrying the code or the refusal */\n redirectUrl: string;\n}\n\n/**\n * How the app proves itself at the token endpoint. `none` is a public client, which is what apps on somebody's own device are\n * generated from [OAuthClientAuthMethod](../../../../../apps/api/data/contracts/oauth/oauth.types.ck)\n */\nexport type OAuthClientAuthMethod = 'none' | 'client_secret_post' | 'client_secret_basic';\n\n/**\n * An app the signed-in person has let act as them\n * generated from [OAuthGrant](../../../../../apps/api/data/contracts/oauth/oauth.types.ck)\n */\nexport interface OAuthGrant {\n /** For disconnecting it */\n id: string;\n /** The app's client id */\n clientId: string;\n /** What the app calls itself, when the station can still find out */\n clientName?: string;\n /** What it can reach */\n resource: string;\n /** What it was granted: `mcp`, and the station scopes it may use (`view`, `manage`) */\n scope: string[];\n /** When it was first approved */\n createdAt: DateTime;\n /** When it last obtained a token */\n lastUsedAt?: DateTime;\n}\n\n/** Rehydrates every wire-encoded scalar in a OAuthGrant into its runtime type. Mutates and returns `raw`. */\nexport function reviveOAuthGrant(raw: OAuthGrant): OAuthGrant {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['createdAt'] = __dt(__o0['createdAt'], 'OAuthGrant.createdAt');\n if (__o0['lastUsedAt'] != null) {\n __o0['lastUsedAt'] = __dt(__o0['lastUsedAt'], 'OAuthGrant.lastUsedAt');\n }\n return raw;\n}\n\n/**\n * A valid request, stashed for the signed-in person to approve or deny\n * generated from [OAuthAuthorizationContext](../../../../../apps/api/data/contracts/oauth/oauth.types.ck)\n */\nexport interface OAuthAuthorizationContext {\n /** Discriminator */\n kind: 'context';\n /** What approving or denying names. Good for a few minutes, and only for the person it was shown to */\n requestId: string;\n /** The app's client id */\n clientId: string;\n /** How the station knows the app */\n clientKind: OAuthClientKind;\n /** What the app calls itself */\n clientName?: string;\n /** The app's own website, when it gave one */\n clientUri?: string;\n /** The app's logo, when it gave one */\n logoUri?: string;\n /** The host the browser is sent back to, which is who actually receives the approval */\n redirectHost: string;\n /** Whether every address the app registered is this computer's own, which only an app running on it should use */\n loopbackOnly: boolean;\n /** What the app asked for. The person chooses what it gets when approving, whatever this says */\n scope: string[];\n /** What the app will be able to reach: the station's MCP endpoint */\n resource: string;\n}\n\n/**\n * Approving a stashed request, with what the app may do\n * generated from [OAuthAuthorizationApproval](../../../../../apps/api/data/contracts/oauth/oauth.types.ck)\n */\nexport interface OAuthAuthorizationApproval {\n /** From the context */\n requestId: string;\n /** What the person lets the app do. At least one; `manage` includes `view`. Replaces whatever the app asked for */\n scopes: OAuthGrantScope[];\n}\n\n/**\n * An app registered with the station\n * generated from [OAuthClientSummary](../../../../../apps/api/data/contracts/oauth/oauth.types.ck)\n */\nexport interface OAuthClientSummary {\n /** Its client id */\n clientId: string;\n /** Created by an operator, or registered by itself */\n kind: 'preregistered' | 'dynamic';\n /** What it is called */\n name?: string;\n /** Where it may be sent back to */\n redirectUris: string[];\n /** How it proves itself */\n tokenEndpointAuthMethod: OAuthClientAuthMethod;\n /** When it was registered */\n createdAt: DateTime;\n /** When it last obtained a token */\n lastUsedAt?: DateTime;\n /** When a self-registered app lapses unless used again */\n expiresAt?: DateTime;\n}\n\n/** Rehydrates every wire-encoded scalar in a OAuthClientSummary into its runtime type. Mutates and returns `raw`. */\nexport function reviveOAuthClientSummary(raw: OAuthClientSummary): OAuthClientSummary {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['createdAt'] = __dt(__o0['createdAt'], 'OAuthClientSummary.createdAt');\n if (__o0['lastUsedAt'] != null) {\n __o0['lastUsedAt'] = __dt(__o0['lastUsedAt'], 'OAuthClientSummary.lastUsedAt');\n }\n if (__o0['expiresAt'] != null) {\n __o0['expiresAt'] = __dt(__o0['expiresAt'], 'OAuthClientSummary.expiresAt');\n }\n return raw;\n}\n\n/**\n * An app an operator registers by hand, for a client that cannot register itself\n * generated from [OAuthClientCreate](../../../../../apps/api/data/contracts/oauth/oauth.types.ck)\n */\nexport interface OAuthClientCreate {\n /** What to call it */\n name: string;\n /** Where it may be sent back to. At least one; https, or this computer's own address */\n redirectUris: string[];\n /** `none` for an app on somebody's own device, otherwise a secret it keeps */\n tokenEndpointAuthMethod: OAuthClientAuthMethod;\n}\n\n/**\n * generated from [OAuthGrantList](../../../../../apps/api/data/contracts/oauth/oauth.types.ck)\n */\nexport interface OAuthGrantList {\n /** Most recent first */\n grants: OAuthGrant[];\n}\n\n/** Rehydrates every wire-encoded scalar in a OAuthGrantList into its runtime type. Mutates and returns `raw`. */\nexport function reviveOAuthGrantList(raw: OAuthGrantList): OAuthGrantList {\n const __o0 = raw as unknown as Record<string, unknown>;\n {\n const __a1 = __o0['grants'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveOAuthGrant(__a1[__i2] as never);\n }\n }\n return raw;\n}\n\n/**\n * generated from [OAuthAuthorizationContextResult](../../../../../apps/api/data/contracts/oauth/oauth.types.ck)\n */\nexport type OAuthAuthorizationContextResult = OAuthAuthorizationContext | OAuthAuthorizationRedirect | OAuthAuthorizationRefusal;\n\n/**\n * generated from [OAuthClientList](../../../../../apps/api/data/contracts/oauth/oauth.types.ck)\n */\nexport interface OAuthClientList {\n /** Newest first. Apps that describe themselves are not listed: nothing is stored for them */\n clients: OAuthClientSummary[];\n}\n\n/** Rehydrates every wire-encoded scalar in a OAuthClientList into its runtime type. Mutates and returns `raw`. */\nexport function reviveOAuthClientList(raw: OAuthClientList): OAuthClientList {\n const __o0 = raw as unknown as Record<string, unknown>;\n {\n const __a1 = __o0['clients'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveOAuthClientSummary(__a1[__i2] as never);\n }\n }\n return raw;\n}\n\n/**\n * A registered app, with its secret. The only time the secret is ever returned\n * generated from [OAuthClientIssued](../../../../../apps/api/data/contracts/oauth/oauth.types.ck)\n */\nexport interface OAuthClientIssued {\n /** The app as it will appear in the list */\n client: OAuthClientSummary;\n /** Present for an app that keeps a secret. Store it now: nothing can show it again */\n clientSecret?: string;\n}\n\n/** Rehydrates every wire-encoded scalar in a OAuthClientIssued into its runtime type. Mutates and returns `raw`. */\nexport function reviveOAuthClientIssued(raw: OAuthClientIssued): OAuthClientIssued {\n const __o0 = raw as unknown as Record<string, unknown>;\n reviveOAuthClientSummary(__o0['client'] as never);\n return raw;\n}\n","import type { SdkFetch } from '../sdk-options.js';\nimport { bigIntReplacer, parseJson } from '../sdk-options.js';\nimport type {\n OAuthAuthorizationApproval,\n OAuthAuthorizationContextResult,\n OAuthAuthorizationDecision,\n OAuthAuthorizationOutcome,\n OAuthAuthorizationQuery,\n OAuthClientCreate,\n OAuthClientIssued,\n OAuthClientList,\n OAuthGrantList,\n} from './types/oauth.types.js';\nimport { reviveOAuthClientIssued, reviveOAuthClientList, reviveOAuthGrantList } from './types/oauth.types.js';\n\nexport class OauthClient {\n constructor(private fetch: SdkFetch) {}\n\n /**\n * @name Describe authorization request\n * @description Validate an app's authorization request for the consent page, and stash it for the signed-in person. A POST because it stashes: what is approved is exactly what was validated here\n */\n async describeAuthorizationRequest(body: OAuthAuthorizationQuery): Promise<OAuthAuthorizationContextResult> {\n const result = await this.fetch(`/auth/oauth/authorize/context`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<OAuthAuthorizationContextResult>(result);\n }\n\n /**\n * @name Approve authorization request\n * @description Let the app act as the signed-in person, as far as the chosen scopes allow. Once the account has a strong second factor, this needs one verified in the last five minutes\n */\n async approveAuthorizationRequest(body: OAuthAuthorizationApproval): Promise<OAuthAuthorizationOutcome> {\n const result = await this.fetch(`/auth/oauth/authorize/approve`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<OAuthAuthorizationOutcome>(result);\n }\n\n /**\n * @name Deny authorization request\n * @description Turn the app away. It is told the person said no\n */\n async denyAuthorizationRequest(body: OAuthAuthorizationDecision): Promise<OAuthAuthorizationOutcome> {\n const result = await this.fetch(`/auth/oauth/authorize/deny`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<OAuthAuthorizationOutcome>(result);\n }\n\n /**\n * @name List OAuth clients\n * @description Every app registered with the station, by an operator or by itself\n */\n async listOAuthClients(): Promise<OAuthClientList> {\n const result = await this.fetch(`/auth/oauth/clients`, { method: 'GET' });\n return reviveOAuthClientList(await parseJson<OAuthClientList>(result));\n }\n\n /**\n * @name Create OAuth client\n * @description Register an app by hand. The secret, for an app that keeps one, is in this response and nowhere else\n */\n async createOAuthClient(body: OAuthClientCreate): Promise<OAuthClientIssued> {\n const result = await this.fetch(`/auth/oauth/clients`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return reviveOAuthClientIssued(await parseJson<OAuthClientIssued>(result));\n }\n\n /**\n * @name Revoke OAuth client\n * @description Withdraw an app. Every person's approval of it ends, and so does every token it holds\n */\n async revokeOAuthClient(clientId: string): Promise<void> {\n await this.fetch(`/auth/oauth/clients/${encodeURIComponent(clientId)}`, { method: 'DELETE' });\n }\n\n /**\n * @name List OAuth grants\n * @description The apps the signed-in person has let act as them\n */\n async listOAuthGrants(): Promise<OAuthGrantList> {\n const result = await this.fetch(`/auth/oauth/grants`, { method: 'GET' });\n return reviveOAuthGrantList(await parseJson<OAuthGrantList>(result));\n }\n\n /**\n * @name Revoke OAuth grant\n * @description Disconnect an app. Every token it holds for this person stops working at once\n */\n async revokeOAuthGrant(id: string): Promise<void> {\n await this.fetch(`/auth/oauth/grants/${encodeURIComponent(id)}`, { method: 'DELETE' });\n }\n}\n","import type { SdkFetch } from '../sdk-options.js';\nimport { bigIntReplacer, parseJson } from '../sdk-options.js';\nimport type { OnboardingRequirement, OnboardingRequirementInput } from './types/onboarding.types.js';\n\nexport class OnboardingClient {\n constructor(private fetch: SdkFetch) {}\n\n /** @name Get Onboarding Requirements */\n async getOnboardingRequirements(): Promise<OnboardingRequirement[]> {\n const result = await this.fetch(`/onboarding`, { method: 'GET' });\n return await parseJson<OnboardingRequirement[]>(result);\n }\n\n /** @name Submit Onboarding Requirement */\n async submitOnboardingRequirement(body: OnboardingRequirementInput): Promise<OnboardingRequirement[]> {\n const result = await this.fetch(`/onboarding`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<OnboardingRequirement[]>(result);\n }\n}\n","import { DateTime } from 'luxon';\nconst __dt = (v: unknown, path: string): DateTime => {\n if (typeof v !== 'string') {\n throw new TypeError(`ContractKit: expected an ISO 8601 string at '${path}', received ${typeof v}.`);\n }\n const d = DateTime.fromISO(v);\n if (!d.isValid) throw new TypeError(`ContractKit: '${v}' at '${path}' is not a valid ISO 8601 datetime.`);\n return d;\n};\n\n/**\n * One of the station's mounts a speaker can play\n * generated from [OutputMount](../../../../../apps/api/data/contracts/outputs/outputs.types.ck)\n */\nexport interface OutputMount {\n format: 'mp3' | 'opus' | 'aac' | 'flac' | 'hls';\n /** Same-origin path, leading slash included, as `/nowplaying` gives it */\n path: string;\n}\n\n/**\n * A plugin that could not list its speakers\n * generated from [OutputProblem](../../../../../apps/api/data/contracts/outputs/outputs.types.ck)\n */\nexport interface OutputProblem {\n pluginId: string;\n message: string;\n}\n\n/**\n * A speaker the station is meant to be playing on, and how it is doing\n * generated from [OutputCast](../../../../../apps/api/data/contracts/outputs/outputs.types.ck)\n */\nexport interface OutputCast {\n pluginId: string;\n deviceId: string;\n /** What the speaker was called when the cast started */\n deviceName: string;\n /** Which mount it plays */\n mountPath: string;\n startedAt: DateTime;\n /** As the speaker reports it now. `opening` and `buffering` are a stream starting, not a failure; `stopped` with the station's stream still loaded is played again on its own; `unreachable` is a speaker that did not answer, which the station waits out */\n phase: 'idle' | 'opening' | 'buffering' | 'playing' | 'stopped' | 'unreachable';\n /** A sentence about the phase when it needs one, such as why a speaker is unreachable */\n detail?: string;\n}\n\n/** Rehydrates every wire-encoded scalar in a OutputCast into its runtime type. Mutates and returns `raw`. */\nexport function reviveOutputCast(raw: OutputCast): OutputCast {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['startedAt'] = __dt(__o0['startedAt'], 'OutputCast.startedAt');\n return raw;\n}\n\n/**\n * Play the station on a speaker\n * generated from [OutputCastRequest](../../../../../apps/api/data/contracts/outputs/outputs.types.ck)\n */\nexport interface OutputCastRequest {\n pluginId: string;\n deviceId: string;\n /** Which mount, from the speaker's `mounts`. Absent means its first, which is MP3 wherever the speaker takes it */\n mountPath?: string;\n}\n\n/**\n * A speaker the station can play on, as an `output` plugin listed it\n * generated from [OutputDevice](../../../../../apps/api/data/contracts/outputs/outputs.types.ck)\n */\nexport interface OutputDevice {\n /** The plugin that drives it, for example `deadair.cast` */\n pluginId: string;\n /** The plugin's own id for the speaker. Stable across restarts */\n deviceId: string;\n /** What the operator calls it */\n name: string;\n /** The make or model, where the speaker says */\n model?: string;\n /** How the plugin reaches it, for recognising rather than dialling */\n address: string;\n /** How it is driven, for a plugin that speaks several: `chromecast`, `upnp`, `bluos` */\n protocol?: string;\n /** The station's mounts this speaker can play, MP3 first. Empty when it plays none of the ones switched on */\n mounts: OutputMount[];\n /** Whether the station is meant to be playing on it now. `/outputs/casts` says how that is going */\n casting: boolean;\n}\n\n/**\n * Every speaker the station is meant to be playing on\n * generated from [OutputCastList](../../../../../apps/api/data/contracts/outputs/outputs.types.ck)\n */\nexport interface OutputCastList {\n casts: OutputCast[];\n}\n\n/** Rehydrates every wire-encoded scalar in a OutputCastList into its runtime type. Mutates and returns `raw`. */\nexport function reviveOutputCastList(raw: OutputCastList): OutputCastList {\n const __o0 = raw as unknown as Record<string, unknown>;\n {\n const __a1 = __o0['casts'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveOutputCast(__a1[__i2] as never);\n }\n }\n return raw;\n}\n\n/**\n * Every speaker every `output` plugin can play the station on\n * generated from [OutputDeviceList](../../../../../apps/api/data/contracts/outputs/outputs.types.ck)\n */\nexport interface OutputDeviceList {\n devices: OutputDevice[];\n /** Plugins that did not answer. Their speakers are missing from `devices` rather than the whole list failing */\n problems: OutputProblem[];\n /** True when the station has looked for speakers on its network and never found one, which on a container usually means its network cannot carry multicast (a bridge network). Speakers added by address still work */\n discoverySeesNothing: boolean;\n}\n","import type { SdkFetch } from '../sdk-options.js';\nimport { bigIntReplacer, parseJson } from '../sdk-options.js';\nimport type { OutputCast, OutputCastList, OutputCastRequest, OutputDeviceList } from './types/outputs.types.js';\nimport { reviveOutputCast, reviveOutputCastList } from './types/outputs.types.js';\n\nexport class OutputsClient {\n constructor(private fetch: SdkFetch) {}\n\n /**\n * @name List output devices\n * @description Every speaker the station can play on, from every `output` plugin, with the mounts each can take\n */\n async listOutputDevices(): Promise<OutputDeviceList> {\n const result = await this.fetch(`/outputs/devices`, { method: 'GET' });\n return await parseJson<OutputDeviceList>(result);\n }\n\n /**\n * @name List casts\n * @description Every speaker the station is meant to be playing on, each asked how it is doing now\n */\n async listCasts(): Promise<OutputCastList> {\n const result = await this.fetch(`/outputs/casts`, { method: 'GET' });\n return reviveOutputCastList(await parseJson<OutputCastList>(result));\n }\n\n /**\n * @name Start cast\n * @description Play the station on a speaker, replacing whatever it was playing. The station keeps it playing, through a dropped stream or a restart, until it is stopped here or somebody plays something else on it\n */\n async startCast(body: OutputCastRequest): Promise<OutputCast> {\n const result = await this.fetch(`/outputs/casts`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return reviveOutputCast(await parseJson<OutputCast>(result));\n }\n\n /**\n * @name Stop cast\n * @description Stop the station on a speaker. Answers 204 when it was not playing too\n */\n async stopCast(pluginId: string, deviceId: string): Promise<void> {\n await this.fetch(`/outputs/casts/${encodeURIComponent(pluginId)}/${encodeURIComponent(deviceId)}`, { method: 'DELETE' });\n }\n}\n","import type { SdkFetch } from '../sdk-options.js';\nimport { bigIntReplacer, parseJson, buildQueryString } from '../sdk-options.js';\nimport type {\n GeneratedPersona,\n PersonaAudition,\n PersonaAuditionList,\n PersonaAuditionRequest,\n PersonaAuditionSummary,\n PersonaFile,\n PersonaImportPlan,\n PersonaImportResult,\n PersonaInput,\n PersonaList,\n PersonaMemory,\n PersonaMemoryChange,\n PersonaMemoryRollback,\n PersonaMemoryTimeline,\n PersonaNoteList,\n PersonaNoteState,\n PersonaNoteWrite,\n PersonaRehearsal,\n PersonaRequest,\n PersonaStoryBeatWrite,\n PersonaStoryDetailWrite,\n PersonaStoryList,\n PersonaStoryState,\n PersonaStoryWrite,\n} from './types/personas.types.js';\n\nexport class PersonasClient {\n constructor(private fetch: SdkFetch) {}\n\n /**\n * @name List persona auditions\n * @description Every audition of this character, newest first, without their breaks\n */\n async listPersonaAuditions(id: string): Promise<PersonaAuditionList> {\n const result = await this.fetch(`/personas/${encodeURIComponent(id)}/auditions`, { method: 'GET' });\n return await parseJson<PersonaAuditionList>(result);\n }\n\n /**\n * @name Start persona audition\n * @description Asks the station to put this character through a playlist or a chart. It is queued, not written\n */\n async startPersonaAudition(id: string, body: PersonaAuditionRequest): Promise<PersonaAudition> {\n const result = await this.fetch(`/personas/${encodeURIComponent(id)}/auditions`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<PersonaAudition>(result);\n }\n\n /**\n * @name Get persona audition\n * @description One audition with every break it has written so far, in order\n */\n async getPersonaAudition(id: string, auditionId: string): Promise<PersonaAudition> {\n const result = await this.fetch(`/personas/${encodeURIComponent(id)}/auditions/${encodeURIComponent(auditionId)}`, { method: 'GET' });\n return await parseJson<PersonaAudition>(result);\n }\n\n /**\n * @name Cancel persona audition\n * @description Stops an audition where it stands, keeping the breaks it has already written\n */\n async cancelPersonaAudition(id: string, auditionId: string): Promise<PersonaAuditionSummary> {\n const result = await this.fetch(`/personas/${encodeURIComponent(id)}/auditions/${encodeURIComponent(auditionId)}/cancel`, { method: 'POST' });\n return await parseJson<PersonaAuditionSummary>(result);\n }\n\n /**\n * @name List personas\n * @description Every persona this station has, oldest first\n */\n async listPersonas(): Promise<PersonaList> {\n const result = await this.fetch(`/personas`, { method: 'GET' });\n return await parseJson<PersonaList>(result);\n }\n\n /**\n * @name Create persona\n * @description Writes a new persona. It is not put on air by creating it\n */\n async createPersona(body: PersonaInput): Promise<PersonaList> {\n const result = await this.fetch(`/personas`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<PersonaList>(result);\n }\n\n /**\n * @name Generate persona\n * @description Turns a description of a character into a whole persona, checked against its own sample lines and handed back unsaved\n */\n async generatePersona(body: PersonaRequest): Promise<GeneratedPersona> {\n const result = await this.fetch(`/personas/generate`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<GeneratedPersona>(result);\n }\n\n /**\n * @name Restore station personas\n * @description Writes back whichever of the station's own personas this station is missing, touching nothing it already has and putting nothing on air\n */\n async restoreStationPersonas(): Promise<PersonaList> {\n const result = await this.fetch(`/personas/restore`, { method: 'POST' });\n return await parseJson<PersonaList>(result);\n }\n\n /**\n * @name Export personas\n * @description Every character this station holds, as one file\n */\n async exportPersonas(): Promise<{ data: PersonaFile; headers: { contentDisposition?: string } }> {\n const result = await this.fetch(`/personas/export`, { method: 'GET' });\n const data = await parseJson<PersonaFile>(result);\n return { data, headers: { contentDisposition: result.headers.get('Content-Disposition') ?? undefined } };\n }\n\n /**\n * @name Export persona\n * @description One character, its sheet and its stories, as a file\n */\n async exportPersona(id: string): Promise<{ data: PersonaFile; headers: { contentDisposition?: string } }> {\n const result = await this.fetch(`/personas/${encodeURIComponent(id)}/export`, { method: 'GET' });\n const data = await parseJson<PersonaFile>(result);\n return { data, headers: { contentDisposition: result.headers.get('Content-Disposition') ?? undefined } };\n }\n\n /**\n * @name Preview persona import\n * @description Reads a file and reports what importing it would create, rewrite and skip. Writes nothing\n */\n async previewPersonaImport(body: PersonaFile, query?: { replace?: string[] }): Promise<PersonaImportPlan> {\n const qs = buildQueryString(query);\n const result = await this.fetch(`/personas/import/preview${qs}`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<PersonaImportPlan>(result);\n }\n\n /**\n * @name Import personas\n * @description Writes a file into this station: creates what is new, rewrites only the characters named in `replace`, and answers with what it did\n */\n async importPersonas(body: PersonaFile, query?: { replace?: string[] }): Promise<PersonaImportResult> {\n const qs = buildQueryString(query);\n const result = await this.fetch(`/personas/import${qs}`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<PersonaImportResult>(result);\n }\n\n /**\n * @name Update persona\n * @description Rewrites one persona. An edit to the one on air is heard on the next break\n */\n async updatePersona(id: string, body: PersonaInput): Promise<PersonaList> {\n const result = await this.fetch(`/personas/${encodeURIComponent(id)}`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<PersonaList>(result);\n }\n\n /**\n * @name Delete persona\n * @description Removes a persona, including the one on air, which leaves the station with none\n */\n async deletePersona(id: string): Promise<PersonaList> {\n const result = await this.fetch(`/personas/${encodeURIComponent(id)}`, { method: 'DELETE' });\n return await parseJson<PersonaList>(result);\n }\n\n /**\n * @name Set the station host\n * @description Makes this persona the station's own host, and the previous one no longer is\n */\n async setTheStationHost(id: string): Promise<PersonaList> {\n const result = await this.fetch(`/personas/${encodeURIComponent(id)}/default-host`, { method: 'PUT' });\n return await parseJson<PersonaList>(result);\n }\n\n /**\n * @name List persona notes\n * @description Everything this character has accumulated, oldest first, in every state\n */\n async listPersonaNotes(id: string): Promise<PersonaNoteList> {\n const result = await this.fetch(`/personas/${encodeURIComponent(id)}/notes`, { method: 'GET' });\n return await parseJson<PersonaNoteList>(result);\n }\n\n /**\n * @name Write persona note\n * @description Writes a note by hand. An operator's own note is active from the moment it exists; only the distil pass proposes\n */\n async writePersonaNote(id: string, body: PersonaNoteWrite): Promise<PersonaNoteList> {\n const result = await this.fetch(`/personas/${encodeURIComponent(id)}/notes`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<PersonaNoteList>(result);\n }\n\n /**\n * @name Update persona note\n * @description Rewrites one note's words, whoever wrote it. Editing what the station proposed is most of the point of the panel\n */\n async updatePersonaNote(id: string, noteId: string, body: PersonaNoteWrite): Promise<PersonaNoteList> {\n const result = await this.fetch(`/personas/${encodeURIComponent(id)}/notes/${encodeURIComponent(noteId)}`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<PersonaNoteList>(result);\n }\n\n /**\n * @name Delete persona note\n * @description Removes a note outright. Turning down a PROPOSAL is a state rather than this, or the next pass writes it again\n */\n async deletePersonaNote(id: string, noteId: string): Promise<PersonaNoteList> {\n const result = await this.fetch(`/personas/${encodeURIComponent(id)}/notes/${encodeURIComponent(noteId)}`, { method: 'DELETE' });\n return await parseJson<PersonaNoteList>(result);\n }\n\n /**\n * @name Set persona note state\n * @description Accepts a proposal, turns one down, or rests an active note. Mirrors the lexicon's own state route\n */\n async setPersonaNoteState(id: string, noteId: string, body: PersonaNoteState): Promise<PersonaNoteList> {\n const result = await this.fetch(`/personas/${encodeURIComponent(id)}/notes/${encodeURIComponent(noteId)}/state`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<PersonaNoteList>(result);\n }\n\n /**\n * @name List persona stories\n * @description Every story this character holds, oldest first, in every state\n */\n async listPersonaStories(id: string): Promise<PersonaStoryList> {\n const result = await this.fetch(`/personas/${encodeURIComponent(id)}/stories`, { method: 'GET' });\n return await parseJson<PersonaStoryList>(result);\n }\n\n /**\n * @name Write persona story\n * @description Writes a story by hand. An operator's own is tellable from the moment it exists; only the enrichment pass proposes\n */\n async writePersonaStory(id: string, body: PersonaStoryWrite): Promise<PersonaStoryList> {\n const result = await this.fetch(`/personas/${encodeURIComponent(id)}/stories`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<PersonaStoryList>(result);\n }\n\n /**\n * @name Update persona story\n * @description Rewrites one story's handle and telling, whoever wrote it\n */\n async updatePersonaStory(id: string, storyId: string, body: PersonaStoryWrite): Promise<PersonaStoryList> {\n const result = await this.fetch(`/personas/${encodeURIComponent(id)}/stories/${encodeURIComponent(storyId)}`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<PersonaStoryList>(result);\n }\n\n /**\n * @name Delete persona story\n * @description Removes a story outright, details and all. Turning down a PROPOSAL is a state rather than this, or the next pass writes it again\n */\n async deletePersonaStory(id: string, storyId: string): Promise<PersonaStoryList> {\n const result = await this.fetch(`/personas/${encodeURIComponent(id)}/stories/${encodeURIComponent(storyId)}`, { method: 'DELETE' });\n return await parseJson<PersonaStoryList>(result);\n }\n\n /**\n * @name Set persona story state\n * @description Accepts a proposal, turns one down, or takes a story out of the rotation without losing it\n */\n async setPersonaStoryState(id: string, storyId: string, body: PersonaStoryState): Promise<PersonaStoryList> {\n const result = await this.fetch(`/personas/${encodeURIComponent(id)}/stories/${encodeURIComponent(storyId)}/state`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<PersonaStoryList>(result);\n }\n\n /**\n * @name Add persona story detail\n * @description Adds one thing to a story that already exists\n */\n async addPersonaStoryDetail(id: string, storyId: string, body: PersonaStoryDetailWrite): Promise<PersonaStoryList> {\n const result = await this.fetch(`/personas/${encodeURIComponent(id)}/stories/${encodeURIComponent(storyId)}/details`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<PersonaStoryList>(result);\n }\n\n /**\n * @name Update persona story detail\n * @description Rewrites one detail's words\n */\n async updatePersonaStoryDetail(id: string, storyId: string, detailId: string, body: PersonaStoryDetailWrite): Promise<PersonaStoryList> {\n const result = await this.fetch(\n `/personas/${encodeURIComponent(id)}/stories/${encodeURIComponent(storyId)}/details/${encodeURIComponent(detailId)}`,\n {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n },\n );\n return await parseJson<PersonaStoryList>(result);\n }\n\n /**\n * @name Delete persona story detail\n * @description Removes one detail, leaving the story it was hung on alone\n */\n async deletePersonaStoryDetail(id: string, storyId: string, detailId: string): Promise<PersonaStoryList> {\n const result = await this.fetch(\n `/personas/${encodeURIComponent(id)}/stories/${encodeURIComponent(storyId)}/details/${encodeURIComponent(detailId)}`,\n { method: 'DELETE' },\n );\n return await parseJson<PersonaStoryList>(result);\n }\n\n /**\n * @name Set persona story detail state\n * @description Accepts a proposed detail or turns it down, which has to outlive the pass that proposed it\n */\n async setPersonaStoryDetailState(id: string, storyId: string, detailId: string, body: PersonaStoryState): Promise<PersonaStoryList> {\n const result = await this.fetch(\n `/personas/${encodeURIComponent(id)}/stories/${encodeURIComponent(storyId)}/details/${encodeURIComponent(detailId)}/state`,\n {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n },\n );\n return await parseJson<PersonaStoryList>(result);\n }\n\n /**\n * @name Rehearse persona\n * @description Writes a talk break under this persona against two fixed invented records, and answers with every writer that was asked\n */\n async rehearsePersona(id: string): Promise<PersonaRehearsal> {\n const result = await this.fetch(`/personas/${encodeURIComponent(id)}/rehearse`, { method: 'POST' });\n return await parseJson<PersonaRehearsal>(result);\n }\n\n /**\n * @name Add persona story beat\n * @description Adds one part to an arc. A script rather than a summary: the floor speaks it as it stands\n */\n async addPersonaStoryBeat(id: string, storyId: string, body: PersonaStoryBeatWrite): Promise<PersonaStoryList> {\n const result = await this.fetch(`/personas/${encodeURIComponent(id)}/stories/${encodeURIComponent(storyId)}/beats`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<PersonaStoryList>(result);\n }\n\n /**\n * @name Update persona story beat\n * @description Rewrites one part's words, or moves it in the order\n */\n async updatePersonaStoryBeat(id: string, storyId: string, beatId: string, body: PersonaStoryBeatWrite): Promise<PersonaStoryList> {\n const result = await this.fetch(\n `/personas/${encodeURIComponent(id)}/stories/${encodeURIComponent(storyId)}/beats/${encodeURIComponent(beatId)}`,\n {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n },\n );\n return await parseJson<PersonaStoryList>(result);\n }\n\n /**\n * @name Delete persona story beat\n * @description Removes one part outright, leaving the arc standing. Turning down a PROPOSAL is a state instead\n */\n async deletePersonaStoryBeat(id: string, storyId: string, beatId: string): Promise<PersonaStoryList> {\n const result = await this.fetch(\n `/personas/${encodeURIComponent(id)}/stories/${encodeURIComponent(storyId)}/beats/${encodeURIComponent(beatId)}`,\n { method: 'DELETE' },\n );\n return await parseJson<PersonaStoryList>(result);\n }\n\n /**\n * @name Set persona story beat state\n * @description Accepts a proposed part, or turns it down without losing that it was turned down\n */\n async setPersonaStoryBeatState(id: string, storyId: string, beatId: string, body: PersonaStoryState): Promise<PersonaStoryList> {\n const result = await this.fetch(\n `/personas/${encodeURIComponent(id)}/stories/${encodeURIComponent(storyId)}/beats/${encodeURIComponent(beatId)}/state`,\n {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n },\n );\n return await parseJson<PersonaStoryList>(result);\n }\n\n /**\n * @name Read persona memory\n * @description What this character has told, newest first. The timeline a moment is picked from\n */\n async readPersonaMemory(id: string): Promise<PersonaMemoryTimeline> {\n const result = await this.fetch(`/personas/${encodeURIComponent(id)}/memory`, { method: 'GET' });\n return await parseJson<PersonaMemoryTimeline>(result);\n }\n\n /**\n * @name Preview persona memory rollback\n * @description What rolling back to a moment would undo, without undoing it\n */\n async previewPersonaMemoryRollback(id: string, query?: { to?: string }): Promise<PersonaMemoryChange> {\n const qs = buildQueryString(query);\n const result = await this.fetch(`/personas/${encodeURIComponent(id)}/memory/preview${qs}`, {\n method: 'GET',\n });\n return await parseJson<PersonaMemoryChange>(result);\n }\n\n /**\n * @name Roll back persona memory\n * @description Undo it. Everything the station accrued after that moment goes; everything an operator wrote stays\n */\n async rollBackPersonaMemory(id: string, body: PersonaMemoryRollback): Promise<PersonaMemory> {\n const result = await this.fetch(`/personas/${encodeURIComponent(id)}/memory/rollback`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<PersonaMemory>(result);\n }\n}\n","import { DateTime } from 'luxon';\nconst __dt = (v: unknown, path: string): DateTime => {\n if (typeof v !== 'string') {\n throw new TypeError(`ContractKit: expected an ISO 8601 string at '${path}', received ${typeof v}.`);\n }\n const d = DateTime.fromISO(v);\n if (!d.isValid) throw new TypeError(`ContractKit: '${v}' at '${path}' is not a valid ISO 8601 datetime.`);\n return d;\n};\n\n/**\n * An action a source will permit on one playlist's items. Item-scoped: neither value covers the playlist's own name or description\n * generated from [PlaylistPermission](../../../../../apps/api/data/contracts/playlists/playlists.types.ck)\n */\nexport type PlaylistPermission = 'read' | 'edit';\n\n/**\n * One record as its PROVIDER describes it, plus what the catalog can say about the same copy.\n *\n * The first half mirrors the plugin SDK's `ProviderTrack` and stays the provider's answer: this is a\n * listing of what a playlist holds, not of what the station has ingested. The three ids below are the\n * station's own and are absent for anything it has never seen, which on most playlists is plenty of\n * rows — a playlist is a provider's list and the library is what a sync has walked\n * generated from [CatalogTrack](../../../../../apps/api/data/contracts/playlists/playlists.types.ck)\n */\nexport interface CatalogTrack {\n /** The PROVIDER's id for this copy, which is what an import names it by. Never a `deadair.tracks` id */\n id: string;\n title: string;\n /** Ordered, primary artist first. Empty array if the provider genuinely has none */\n artists: string[];\n album?: string;\n durationMs?: number;\n isrc?: string;\n artworkUrl?: string;\n /** The canonical `deadair.tracks` row this copy is bound to, when the catalog holds one */\n trackId?: string;\n /** The canonical artist behind that row */\n artistId?: string;\n /** The release that row was ingested inside. Absent for a single ingested outside any */\n albumId?: string;\n}\n\n/**\n * One catalog-capable plugin that could not be listed\n * generated from [CatalogSourceError](../../../../../apps/api/data/contracts/playlists/playlists.types.ck)\n */\nexport interface CatalogSourceError {\n pluginId: string;\n pluginName: string;\n message: string;\n}\n\n/**\n * One music source whose playlists are in this answer, and how old its list is\n * generated from [CatalogPlaylistSource](../../../../../apps/api/data/contracts/playlists/playlists.types.ck)\n */\nexport interface CatalogPlaylistSource {\n pluginId: string;\n pluginName: string;\n /** When the station last read this source's whole list of playlists. The library sync reads it in the background, so this is usually minutes old; a source listed for the first time is read for this answer */\n listedAt: DateTime;\n}\n\n/** Rehydrates every wire-encoded scalar in a CatalogPlaylistSource into its runtime type. Mutates and returns `raw`. */\nexport function reviveCatalogPlaylistSource(raw: CatalogPlaylistSource): CatalogPlaylistSource {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['listedAt'] = __dt(__o0['listedAt'], 'CatalogPlaylistSource.listedAt');\n return raw;\n}\n\n/**\n * A playlist a catalog-capable plugin offers, tagged with the plugin it came from so an aggregated list is addressable\n * generated from [CatalogPlaylist](../../../../../apps/api/data/contracts/playlists/playlists.types.ck)\n */\nexport interface CatalogPlaylist {\n pluginId: string;\n pluginName: string;\n id: string;\n name: string;\n description?: string;\n trackCount?: number;\n artworkUrl?: string;\n /** What the SOURCE permits on this playlist's items, not what this actor may do. Empty means the source permits nothing; absent means it did not say */\n permissions?: PlaylistPermission[];\n /** The source made this playlist itself rather than a person: an editorial list, or one generated for the account like Discover Weekly. Absent when it did not say */\n madeByProvider?: boolean;\n /** An operator hid this playlist from this station, so pickers leave it out and the library sync does not read it. Absent when it is not hidden */\n hidden?: boolean;\n}\n\n/**\n * generated from [CatalogPlaylistTracks](../../../../../apps/api/data/contracts/playlists/playlists.types.ck)\n */\nexport interface CatalogPlaylistTracks {\n pluginId: string;\n playlistId: string;\n tracks: CatalogTrack[];\n}\n\n/**\n * generated from [CatalogPlaylistPage](../../../../../apps/api/data/contracts/playlists/playlists.types.ck)\n */\nexport interface CatalogPlaylistPage {\n playlists: CatalogPlaylist[];\n /** Every source whose playlists are listed, including one that also has an entry in `errors`: its list is then the last one the station read. Absent from a station that predates it, which asked every source live */\n sources?: CatalogPlaylistSource[];\n errors: CatalogSourceError[];\n}\n\n/** Rehydrates every wire-encoded scalar in a CatalogPlaylistPage into its runtime type. Mutates and returns `raw`. */\nexport function reviveCatalogPlaylistPage(raw: CatalogPlaylistPage): CatalogPlaylistPage {\n const __o0 = raw as unknown as Record<string, unknown>;\n if (__o0['sources'] != null) {\n {\n const __a1 = __o0['sources'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveCatalogPlaylistSource(__a1[__i2] as never);\n }\n }\n }\n return raw;\n}\n","import { DateTime } from 'luxon';\nconst __dt = (v: unknown, path: string): DateTime => {\n if (typeof v !== 'string') {\n throw new TypeError(`ContractKit: expected an ISO 8601 string at '${path}', received ${typeof v}.`);\n }\n const d = DateTime.fromISO(v);\n if (!d.isValid) throw new TypeError(`ContractKit: '${v}' at '${path}' is not a valid ISO 8601 datetime.`);\n return d;\n};\n\n/**\n * A playlist the station owns: records it holds in its own library, in an order somebody chose, cloned\n * from somewhere else and free to differ from it afterwards\n * generated from [StationPlaylist](../../../../../apps/api/data/contracts/playlists/station.playlists.types.ck)\n */\nexport interface StationPlaylist {\n id: string;\n name: string;\n /** What this playlist is for, in the operator's own words. Empty when nobody said */\n prompt: string;\n /** The plugin this was cloned from, for a badge and nothing else. Absent for one read from a file or made here */\n originPluginId?: string;\n /** Every row, placeholders included */\n trackCount: number;\n /** The rows that name a record in the library, which are the ones that can air */\n resolvedCount: number;\n createdAt: DateTime;\n updatedAt: DateTime;\n}\n\nexport interface StationPlaylistInput {\n name: string;\n /** What this playlist is for, in the operator's own words. Empty when nobody said */\n prompt: string;\n}\n\n/** Rehydrates every wire-encoded scalar in a StationPlaylist into its runtime type. Mutates and returns `raw`. */\nexport function reviveStationPlaylist(raw: StationPlaylist): StationPlaylist {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['createdAt'] = __dt(__o0['createdAt'], 'StationPlaylist.createdAt');\n __o0['updatedAt'] = __dt(__o0['updatedAt'], 'StationPlaylist.updatedAt');\n return raw;\n}\n\n/**\n * One row of a station playlist: a record in the library, or a placeholder for one it does not hold yet\n * generated from [StationPlaylistTrack](../../../../../apps/api/data/contracts/playlists/station.playlists.types.ck)\n */\nexport interface StationPlaylistTrack {\n /** The row's own id, not the record's */\n id: string;\n position: number;\n title: string;\n /** Ordered, primary artist first */\n artists: string[];\n album?: string;\n durationMs?: number;\n /** The library record this row plays. Absent on a placeholder */\n trackId?: string;\n artistId?: string;\n albumId?: string;\n /** On a placeholder, the plugin whose copy it was cloned from. Absent on one read from a file, which names a record and no copy of it */\n originPluginId?: string;\n}\n\n/**\n * What may change about a station playlist after it exists. Absent fields are left alone\n * generated from [StationPlaylistUpdate](../../../../../apps/api/data/contracts/playlists/station.playlists.types.ck)\n */\nexport interface StationPlaylistUpdate {\n name?: string;\n prompt?: string;\n}\n\n/**\n * Where a record in a file came from, when it came from a provider's copy. Carried so a record the\n * receiving library does not hold can still be matched by that copy later\n * generated from [PlaylistFileOrigin](../../../../../apps/api/data/contracts/playlists/station.playlists.types.ck)\n */\nexport interface PlaylistFileOrigin {\n pluginId: string;\n externalId: string;\n}\n\n/**\n * A playlist one of the station's music sources holds, named the way the playlists listing names it\n * generated from [PlaylistProviderRef](../../../../../apps/api/data/contracts/playlists/station.playlists.types.ck)\n */\nexport interface PlaylistProviderRef {\n pluginId: string;\n playlistId: string;\n}\n\n/**\n * What importing one record would do here\n * generated from [PlaylistImportEntry](../../../../../apps/api/data/contracts/playlists/station.playlists.types.ck)\n */\nexport interface PlaylistImportEntry {\n position: number;\n title: string;\n artists: string[];\n /** `matched`: the library holds it. `toAdd`: it names a provider's copy, which the station can add to its library. `toLookUp`: it names only a record, which the station has to search its providers for */\n outcome: 'matched' | 'toAdd' | 'toLookUp';\n /** The library record a `matched` row plays */\n trackId?: string;\n}\n\n/**\n * generated from [StationPlaylistList](../../../../../apps/api/data/contracts/playlists/station.playlists.types.ck)\n */\nexport interface StationPlaylistList {\n playlists: StationPlaylist[];\n}\n\nexport interface StationPlaylistListInput {\n playlists: StationPlaylistInput[];\n}\n\n/** Rehydrates every wire-encoded scalar in a StationPlaylistList into its runtime type. Mutates and returns `raw`. */\nexport function reviveStationPlaylistList(raw: StationPlaylistList): StationPlaylistList {\n const __o0 = raw as unknown as Record<string, unknown>;\n {\n const __a1 = __o0['playlists'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveStationPlaylist(__a1[__i2] as never);\n }\n }\n return raw;\n}\n\n/**\n * generated from [StationPlaylistDetail](../../../../../apps/api/data/contracts/playlists/station.playlists.types.ck)\n */\nexport interface StationPlaylistDetail extends StationPlaylist {\n tracks: StationPlaylistTrack[];\n}\n\nexport interface StationPlaylistDetailInput extends StationPlaylistInput {\n tracks: StationPlaylistTrack[];\n}\n\n/** Rehydrates every wire-encoded scalar in a StationPlaylistDetail into its runtime type. Mutates and returns `raw`. */\nexport function reviveStationPlaylistDetail(raw: StationPlaylistDetail): StationPlaylistDetail {\n reviveStationPlaylist(raw as never);\n return raw;\n}\n\n/**\n * One record as a playlist file names it. By its words and its ISRC, never by an id of this station's:\n * ids are minted afresh by every library, so a file keyed by them would restore onto nothing\n * generated from [PlaylistFileTrack](../../../../../apps/api/data/contracts/playlists/station.playlists.types.ck)\n */\nexport interface PlaylistFileTrack {\n title: string;\n /** Ordered, primary artist first */\n artists: string[];\n album?: string;\n durationMs?: number;\n isrc?: string;\n origin?: PlaylistFileOrigin;\n}\n\n/**\n * What an import WOULD do, written nowhere\n * generated from [PlaylistImportPlan](../../../../../apps/api/data/contracts/playlists/station.playlists.types.ck)\n */\nexport interface PlaylistImportPlan {\n name: string;\n matched: number;\n toAdd: number;\n toLookUp: number;\n /** Lines of the source that named no record the station could read */\n skipped: number;\n entries: PlaylistImportEntry[];\n /** Anything about the source as a whole an operator should know before importing it */\n notices: string[];\n}\n\n/**\n * A playlist as a file: everything somebody would need to rebuild it on another station\n * generated from [PlaylistFile](../../../../../apps/api/data/contracts/playlists/station.playlists.types.ck)\n */\nexport interface PlaylistFile {\n /** What shape this is, so a file from a later build says so rather than being read wrongly */\n format: string;\n /** When it was exported, ISO-8601 */\n takenAt: string;\n /** The station it was taken from. Provenance only */\n station?: string;\n name: string;\n prompt?: string;\n tracks: PlaylistFileTrack[];\n}\n\n/**\n * generated from [PlaylistImportResult](../../../../../apps/api/data/contracts/playlists/station.playlists.types.ck)\n */\nexport interface PlaylistImportResult {\n plan: PlaylistImportPlan;\n playlist: StationPlaylist;\n}\n\nexport interface PlaylistImportResultInput {\n plan: PlaylistImportPlan;\n playlist: StationPlaylistInput;\n}\n\n/** Rehydrates every wire-encoded scalar in a PlaylistImportResult into its runtime type. Mutates and returns `raw`. */\nexport function revivePlaylistImportResult(raw: PlaylistImportResult): PlaylistImportResult {\n const __o0 = raw as unknown as Record<string, unknown>;\n reviveStationPlaylist(__o0['playlist'] as never);\n return raw;\n}\n\n/**\n * Something to import a playlist from. Exactly one source\n * generated from [PlaylistImportInput](../../../../../apps/api/data/contracts/playlists/station.playlists.types.ck)\n */\nexport interface PlaylistImportInput {\n /** A playlist exported from a deadair station */\n file?: PlaylistFile;\n /** A playlist another program wrote, as its text: an M3U, a CSV with a header row, or one `Artist - Title` per line */\n text?: string;\n /** Which of those `text` is. Absent works it out from the text */\n format?: 'm3u' | 'csv' | 'text';\n /** The name of the file `text` came from, which names the playlist when the text does not */\n fileName?: string;\n /** A link to a playlist at one of the station's music sources, as a browser or an app shows it */\n url?: string;\n /** A playlist a music source lists here, by its plugin and its id */\n providerPlaylist?: PlaylistProviderRef;\n /** What to call the new playlist. Absent keeps the name the source gives it */\n name?: string;\n}\n","import type { SdkFetch } from '../sdk-options.js';\nimport { bigIntReplacer, parseJson } from '../sdk-options.js';\nimport type { CatalogPlaylistPage, CatalogPlaylistTracks } from './types/playlists.types.js';\nimport { reviveCatalogPlaylistPage } from './types/playlists.types.js';\nimport type {\n PlaylistFile,\n PlaylistImportInput,\n PlaylistImportPlan,\n PlaylistImportResult,\n StationPlaylist,\n StationPlaylistDetail,\n StationPlaylistList,\n StationPlaylistUpdate,\n} from './types/station.playlists.types.js';\nimport {\n revivePlaylistImportResult,\n reviveStationPlaylist,\n reviveStationPlaylistDetail,\n reviveStationPlaylistList,\n} from './types/station.playlists.types.js';\n\nexport class PlaylistsClient {\n constructor(private fetch: SdkFetch) {}\n\n /**\n * @name List importable playlists\n * @description Every playlist the installed `catalog` plugins offer, as the library sync last read each one's list. A source with no list kept yet is asked while the request waits\n */\n async listImportablePlaylists(): Promise<CatalogPlaylistPage> {\n const result = await this.fetch(`/playlists`, { method: 'GET' });\n return reviveCatalogPlaylistPage(await parseJson<CatalogPlaylistPage>(result));\n }\n\n /**\n * @name Get playlist tracks\n * @description One playlist's tracks from one plugin\n */\n async getPlaylistTracks(pluginId: string, playlistId: string): Promise<CatalogPlaylistTracks> {\n const result = await this.fetch(`/playlists/${encodeURIComponent(pluginId)}/${encodeURIComponent(playlistId)}/tracks`, { method: 'GET' });\n return await parseJson<CatalogPlaylistTracks>(result);\n }\n\n /**\n * @name Hide playlist\n * @description Hides one playlist from this station: the listing marks it hidden, the pickers stop offering it and the library sync stops reading it. Hiding one already hidden changes nothing\n */\n async hidePlaylist(pluginId: string, playlistId: string): Promise<void> {\n await this.fetch(`/playlists/${encodeURIComponent(pluginId)}/${encodeURIComponent(playlistId)}/hidden`, { method: 'PUT' });\n }\n\n /**\n * @name Show playlist\n * @description Shows a hidden playlist again. Showing one that is not hidden changes nothing\n */\n async showPlaylist(pluginId: string, playlistId: string): Promise<void> {\n await this.fetch(`/playlists/${encodeURIComponent(pluginId)}/${encodeURIComponent(playlistId)}/hidden`, { method: 'DELETE' });\n }\n\n /**\n * @name Refresh playlists\n * @description Reads every playlist on every music source again, in the background, rather than waiting for the next scheduled read. New records reach the library; records gone from every playlist are retired\n */\n async refreshPlaylists(): Promise<void> {\n await this.fetch(`/playlists/refresh`, { method: 'POST' });\n }\n\n /**\n * @name Refresh playlist\n * @description Reads one playlist again, in the background. New records reach the library; a record taken out of it stays until the next full read judges it\n */\n async refreshPlaylist(pluginId: string, playlistId: string): Promise<void> {\n await this.fetch(`/playlists/${encodeURIComponent(pluginId)}/${encodeURIComponent(playlistId)}/refresh`, { method: 'POST' });\n }\n\n /**\n * @name List station playlists\n * @description Every playlist the station owns, newest first\n */\n async listStationPlaylists(): Promise<StationPlaylistList> {\n const result = await this.fetch(`/station-playlists`, { method: 'GET' });\n return reviveStationPlaylistList(await parseJson<StationPlaylistList>(result));\n }\n\n /**\n * @name Get station playlist\n * @description One station playlist with its records in order, placeholders included\n */\n async getStationPlaylist(id: string): Promise<StationPlaylistDetail> {\n const result = await this.fetch(`/station-playlists/${encodeURIComponent(id)}`, { method: 'GET' });\n return reviveStationPlaylistDetail(await parseJson<StationPlaylistDetail>(result));\n }\n\n /**\n * @name Update station playlist\n * @description Renames a station playlist, or rewrites what it is for\n */\n async updateStationPlaylist(id: string, body: StationPlaylistUpdate): Promise<StationPlaylist> {\n const result = await this.fetch(`/station-playlists/${encodeURIComponent(id)}`, {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return reviveStationPlaylist(await parseJson<StationPlaylist>(result));\n }\n\n /**\n * @name Delete station playlist\n * @description Deletes a station playlist. The records it named stay in the library\n */\n async deleteStationPlaylist(id: string): Promise<void> {\n await this.fetch(`/station-playlists/${encodeURIComponent(id)}`, { method: 'DELETE' });\n }\n\n /**\n * @name Fill station playlist\n * @description Looks up the records this playlist names and the library does not hold, in the background, and adds the ones a provider has. The activity feed says how it went\n */\n async fillStationPlaylist(id: string): Promise<void> {\n await this.fetch(`/station-playlists/${encodeURIComponent(id)}/fill`, { method: 'POST' });\n }\n\n /**\n * @name Export station playlist\n * @description One station playlist as a file another station can import\n */\n async exportStationPlaylist(id: string): Promise<{ data: PlaylistFile; headers: { contentDisposition?: string } }> {\n const result = await this.fetch(`/station-playlists/${encodeURIComponent(id)}/export`, { method: 'GET' });\n const data = await parseJson<PlaylistFile>(result);\n return { data, headers: { contentDisposition: result.headers.get('Content-Disposition') ?? undefined } };\n }\n\n /**\n * @name Preview playlist import\n * @description Reads a source and reports which of its records the library holds and which it would have to find. Writes nothing\n */\n async previewPlaylistImport(body: PlaylistImportInput): Promise<PlaylistImportPlan> {\n const result = await this.fetch(`/station-playlists/import/preview`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<PlaylistImportPlan>(result);\n }\n\n /**\n * @name Import playlist\n * @description Makes a new station playlist from a source and answers with what it did\n */\n async importPlaylist(body: PlaylistImportInput): Promise<PlaylistImportResult> {\n const result = await this.fetch(`/station-playlists/import`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return revivePlaylistImportResult(await parseJson<PlaylistImportResult>(result));\n }\n}\n","import type { SdkFetch } from '../sdk-options.js';\nimport { bigIntReplacer, parseJson } from '../sdk-options.js';\nimport type {\n PlayoutAlbumInput,\n PlayoutChartInput,\n PlayoutPlaylistInput,\n PlayoutStationPlaylistInput,\n PlayoutStatus,\n} from './types/playout.types.js';\n\nexport class PlayoutClient {\n constructor(private fetch: SdkFetch) {}\n\n /**\n * @name Get playout status\n * @description What the station is playing and what is queued behind it. The console polls this\n */\n async getPlayoutStatus(): Promise<PlayoutStatus> {\n const result = await this.fetch(`/playout/status`, { method: 'GET' });\n return await parseJson<PlayoutStatus>(result);\n }\n\n /**\n * @name Play a playlist\n * @description Loads a plugin playlist into the running order and starts handing it to the player. Replaces whatever was queued; what is on air finishes rather than being cut off\n */\n async playAPlaylist(body: PlayoutPlaylistInput): Promise<PlayoutStatus> {\n const result = await this.fetch(`/playout/playlist`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<PlayoutStatus>(result);\n }\n\n /**\n * @name Play a station playlist\n * @description Loads a playlist the station owns into the running order and starts handing it to the player. The same replacement a plugin playlist makes, from records the library already holds\n */\n async playAStationPlaylist(body: PlayoutStationPlaylistInput): Promise<PlayoutStatus> {\n const result = await this.fetch(`/playout/station-playlist`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<PlayoutStatus>(result);\n }\n\n /**\n * @name Play an album\n * @description Plays an album the library holds, whole and in the order it was made: by disc, then by track. A feature, so no breaks and no blends between its records, and what is on air finishes rather than being cut off. It stops at the end of the album, or when the schedule's next block starts\n */\n async playAnAlbum(body: PlayoutAlbumInput): Promise<PlayoutStatus> {\n const result = await this.fetch(`/playout/album`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<PlayoutStatus>(result);\n }\n\n /**\n * @name Play a chart\n * @description Builds the running order from a published chart and starts handing it to the player. The same replacement a playlist makes, from a document somebody else ranked\n */\n async playAChart(body: PlayoutChartInput): Promise<PlayoutStatus> {\n const result = await this.fetch(`/playout/chart`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<PlayoutStatus>(result);\n }\n\n /**\n * @name Skip the current item\n * @description Ends the item on air so the next one starts immediately. The station owns the decoder, so this lands at once rather than waiting out audio already committed to a player\n */\n async skipTheCurrentItem(): Promise<PlayoutStatus> {\n const result = await this.fetch(`/playout/skip`, { method: 'POST' });\n return await parseJson<PlayoutStatus>(result);\n }\n\n /**\n * @name Start playout\n * @description Puts the station back on air with the running order it already has, picking it up where Stop left it. Distinct from putting a playlist on air, which builds a new broadcast and throws away what was there. Refused when there is nothing left to resume\n */\n async startPlayout(): Promise<PlayoutStatus> {\n const result = await this.fetch(`/playout/start`, { method: 'POST' });\n return await parseJson<PlayoutStatus>(result);\n }\n\n /**\n * @name Stop playout\n * @description Stands the station down: stops what is on air at once and hands the mount back. The running order is LEFT as it is, so `/playout/start` can pick it up where this stopped it. deadair holds the mount on a lease it renews while it has something to play, so stopping goes quiet rather than falling through to a bed nobody programmed\n */\n async stopPlayout(): Promise<PlayoutStatus> {\n const result = await this.fetch(`/playout/stop`, { method: 'POST' });\n return await parseJson<PlayoutStatus>(result);\n }\n}\n","import { DateTime } from 'luxon';\nconst __dt = (v: unknown, path: string): DateTime => {\n if (typeof v !== 'string') {\n throw new TypeError(`ContractKit: expected an ISO 8601 string at '${path}', received ${typeof v}.`);\n }\n const d = DateTime.fromISO(v);\n if (!d.isValid) throw new TypeError(`ContractKit: '${v}' at '${path}' is not a valid ISO 8601 datetime.`);\n return d;\n};\n\n/**\n * Lifecycle state of a plugin the host knows about\n * generated from [PluginStatus](../../../../../apps/api/data/contracts/plugins/plugins.types.ck)\n */\nexport type PluginStatus = 'discovered' | 'disabled' | 'misconfigured' | 'active' | 'failed';\n\n/**\n * Where the station found a plugin: shipped inside the image, or installed by the operator into the plugins\n * directory on the data volume. Says nothing about trust; both kinds run inside the station with its privileges\n * generated from [PluginOrigin](../../../../../apps/api/data/contracts/plugins/plugins.types.ck)\n */\nexport type PluginOrigin = 'bundled' | 'installed';\n\n/**\n * generated from [ConfigFieldType](../../../../../apps/api/data/contracts/plugins/plugins.types.ck)\n */\nexport type ConfigFieldType = 'string' | 'text' | 'url' | 'secret' | 'number' | 'boolean' | 'select' | 'multiselect' | 'list' | 'note';\n\n/**\n * What a `number` field's value is measured in. The stored value is always in this unit; only the\n * control the operator touches changes, so a byte count stays a byte count everywhere it is read and\n * a `fraction` stays the share between 0 and 1 that the code multiplying by it wants\n * generated from [ConfigFieldUnit](../../../../../apps/api/data/contracts/plugins/plugins.types.ck)\n */\nexport type ConfigFieldUnit = 'bytes' | 'fraction';\n\n/**\n * The control a field asks to be drawn with, where the ordinary one for its type reads badly. Opt-in\n * per field rather than inferred, because a slider is right for a value you feel for and wrong for\n * one you have to hit exactly, and `tags` is right for a comma-separated line that is really a SET\n * and wrong for one that is prose. Nothing about the stored value changes either way\n * generated from [ConfigFieldControl](../../../../../apps/api/data/contracts/plugins/plugins.types.ck)\n */\nexport type ConfigFieldControl = 'slider' | 'tags';\n\n/**\n * One choice of a `select` config field\n * generated from [ConfigFieldOption](../../../../../apps/api/data/contracts/plugins/plugins.types.ck)\n */\nexport interface ConfigFieldOption {\n value: string;\n label: string;\n}\n\n/**\n * Where a field's or a column's choices come from when only the console can enumerate them: the\n * station's own tables, the platform's zone list, the enabled plugins that can do one of five jobs,\n * or the models the selected model plugin currently offers. Resolved by the console either way\n * generated from [ConfigFieldOptionSource](../../../../../apps/api/data/contracts/plugins/plugins.types.ck)\n */\nexport type ConfigFieldOptionSource =\n | 'station.newsCategories'\n | 'station.newsFeeds'\n | 'station.podcastShows'\n | 'station.narrationSeries'\n | 'intl.timeZones'\n | 'plugins.speech'\n | 'plugins.llm'\n | 'plugins.mixer'\n | 'plugins.analysis'\n | 'plugins.similarity'\n | 'llm.models';\n\n/**\n * A row a `list` field offers to start from instead of an empty one. Adding a row from it fills the cells it names, by column key, and nothing records which preset a row came from\n * generated from [ConfigFieldPreset](../../../../../apps/api/data/contracts/plugins/plugins.types.ck)\n */\nexport interface ConfigFieldPreset {\n /** What the operator picks it by */\n label: string;\n /** Cell values by column key. A key with no column, or a `secret` column's, is ignored */\n cells: Record<string, string>;\n}\n\n/**\n * Whether a capability has ONE answer or is asked of everything in turn. `one` stores a plugin id\n * and `ordered` stores a list of them; see `plugins/plugin.providers.ts`, which both this and the\n * station read the pairing from\n * generated from [ProviderMode](../../../../../apps/api/data/contracts/plugins/plugins.types.ck)\n */\nexport type ProviderMode = 'one' | 'ordered';\n\n/**\n * A plugin handed over from the browser. The generated client types the body as `FormData`, so\n * nothing checks this shape. It says what to send\n * generated from [PluginImport](../../../../../apps/api/data/contracts/plugins/plugins.types.ck)\n */\nexport interface PluginImport {\n /** The gzip tarball npm pack writes: every entry under package/, holding package.json and the built code, at most 64 MB */\n file: Blob;\n}\n\n/**\n * generated from [PluginLogLevel](../../../../../apps/api/data/contracts/plugins/plugins.types.ck)\n */\nexport type PluginLogLevel = 'debug' | 'info' | 'warn' | 'error';\n\n/**\n * A submitted settings form. Secret values arrive in here and are never echoed back\n * generated from [PluginConfigInput](../../../../../apps/api/data/contracts/plugins/plugins.types.ck)\n */\nexport interface PluginConfigInput {\n config: Record<string, unknown>;\n}\n\n/**\n * What a plugin may do with a capability it asked for. Denied is the default and needs no row: a\n * capability is refused until somebody allows it, so \"never answered\" and \"refused\" are one state\n * generated from [GrantDecision](../../../../../apps/api/data/contracts/plugins/plugins.types.ck)\n */\nexport type GrantDecision = 'allowed' | 'denied';\n\n/**\n * Outcome of the plugin's own `testConnection()`\n * generated from [PluginTestResult](../../../../../apps/api/data/contracts/plugins/plugins.types.ck)\n */\nexport interface PluginTestResult {\n ok: boolean;\n message?: string;\n}\n\n/**\n * Where the console should send the browser to obtain the operator's consent. Reported rather than\n * redirected to: the route is behind the Bearer floor, so a browser cannot follow a redirect from it\n * generated from [PluginOAuthStart](../../../../../apps/api/data/contracts/plugins/plugins.types.ck)\n */\nexport interface PluginOAuthStart {\n url: string;\n}\n\n/**\n * Outcome of an OAuth callback\n * generated from [PluginOAuthResult](../../../../../apps/api/data/contracts/plugins/plugins.types.ck)\n */\nexport interface PluginOAuthResult {\n pluginId: string;\n ok: boolean;\n message?: string;\n}\n\n/**\n * generated from [PluginOAuthCallbackQuery](../../../../../apps/api/data/contracts/plugins/plugins.types.ck)\n */\nexport interface PluginOAuthCallbackQuery {\n code?: string;\n state?: string;\n error?: string;\n ubi?: string;\n /**\n * What a desktop-style flow returns instead of `code`: the provider mints a token before the\n * consent screen and hands the same one back, which the plugin exchanges for a session. Last.fm's\n * auth works this way. Listed here because the route parses this query strictly, so an\n * undeclared parameter is a 400 before any plugin code runs\n */\n token?: string;\n}\n\n/**\n * One plugin's standing for one capability, as the Providers section draws it\n * generated from [ProviderCandidate](../../../../../apps/api/data/contracts/plugins/plugins.types.ck)\n */\nexport interface ProviderCandidate {\n pluginId: string;\n /** The plugin's own name, which is what an operator knows it by. The id is what is stored */\n name: string;\n enabled: boolean;\n status: PluginStatus;\n /** Where in the asking order this plugin sits, counting from 1. Absent when it cannot currently answer, which is every status but `active` */\n position?: number;\n /** Whether the operator named this plugin, as opposed to it being here because it is installed. False everywhere when nothing is set */\n listed: boolean;\n /** Whether the station reaches this plugin for this capability. Every active candidate for an `ordered` capability, and only the chosen one for a `one` */\n inUse: boolean;\n /** `enrichment` only: the number the plugin's AUTHOR gave it, which orders whatever the operator did not. Lower wins a conflicting fact */\n declaredPriority?: number;\n}\n\n/**\n * Live choices for a plugin's config fields, keyed by field key, out of the plugin's own\n * `suggestConfigOptions()`. What `ConfigFieldDescriptor.options` cannot be: fixed when the manifest\n * was written, where these are whatever the operator's own server currently says\n * generated from [PluginFieldSuggestions](../../../../../apps/api/data/contracts/plugins/plugins.types.ck)\n */\nexport interface PluginFieldSuggestions {\n /** Keys the plugin had nothing to say about are simply absent, rather than present and empty */\n fields: Record<string, ConfigFieldOption[]>;\n /**\n * False when the plugin does not implement suggestions at all, so a console can tell \"nothing to\n * suggest\" from \"asked and got nothing\", and draw a refresh control only where one would do something\n */\n supported: boolean;\n}\n\n/**\n * One column of a `list` field. Every ordinary cell is stored as a string in the row, so this describes the\n * control rather than the value; a `secret` cell is encrypted on its own and is never in the row at all\n * generated from [ConfigFieldColumn](../../../../../apps/api/data/contracts/plugins/plugins.types.ck)\n */\nexport interface ConfigFieldColumn {\n key: string;\n label: string;\n type: 'string' | 'url' | 'select' | 'secret';\n required?: boolean;\n placeholder?: string;\n options?: ConfigFieldOption[];\n optionsFrom?: ConfigFieldOptionSource;\n /** Key of another column in the same list. This cell applies only to a row whose cell there holds one of `dependsOnValues`. Stronger than a field's `dependsOn`, which only hides a control: a cell that does not apply is neither sent by the console nor read by the host, so a `url` column that does not apply to a row contributes no hostname to the plugin's allowlist. A target this list does not declare, or a target cell still empty, shows the cell */\n dependsOn?: string;\n /** The values of the `dependsOn` cell this one applies to. Omitted means any non-empty value; ignored without a target */\n dependsOnValues?: string[];\n /** `secret` only: key of the address column in the same list this credential is sent to. A save that keeps the stored credential while that row's address moves to another origin is refused */\n sentTo?: string;\n}\n\n/**\n * generated from [PluginLogEntry](../../../../../apps/api/data/contracts/plugins/plugins.types.ck)\n */\nexport interface PluginLogEntry {\n ts: string;\n level: PluginLogLevel;\n /** Must match MAX_LINE_BYTES_CEILING in apps/api/src/logging/rotating.log.store.ts. Change both together */\n text: string;\n}\n\n/**\n * generated from [PluginLogQuery](../../../../../apps/api/data/contracts/plugins/plugins.types.ck)\n */\nexport interface PluginLogQuery {\n limit?: number;\n level?: PluginLogLevel;\n}\n\n/**\n * generated from [PluginLogLevelInput](../../../../../apps/api/data/contracts/plugins/plugins.types.ck)\n */\nexport interface PluginLogLevelInput {\n level: PluginLogLevel;\n}\n\n/**\n * One capability a plugin asked for, with the station's answer. The ask is the plugin's manifest and\n * the answer is a row, so a plugin that stops asking stops appearing here whatever was stored\n * generated from [PluginGrant](../../../../../apps/api/data/contracts/plugins/plugins.types.ck)\n */\nexport interface PluginGrant {\n pluginId: string;\n pluginName: string;\n /** The host's own id for it, e.g. `network.open` */\n capability: string;\n /** What the host calls the capability */\n label: string;\n /** What allowing it opens up, in the station's words */\n describes: string;\n /** Why this plugin says it needs it, in the plugin's words */\n reason: string;\n decision: GrantDecision;\n}\n\n/**\n * generated from [PluginGrantInput](../../../../../apps/api/data/contracts/plugins/plugins.types.ck)\n */\nexport interface PluginGrantInput {\n capability: string;\n decision: GrantDecision;\n}\n\n/**\n * One capability, who can answer it, and what the operator has said about the order\n * generated from [ProviderCapabilityState](../../../../../apps/api/data/contracts/plugins/plugins.types.ck)\n */\nexport interface ProviderCapabilityState {\n /** The manifest capability, which is also the console's anchor for this block */\n capability: string;\n mode: ProviderMode;\n /** The `deadair.settings` key the console writes. Its descriptor carries the wording */\n settingKey: string;\n /** The raw stored value, so the console can tell a default order from one somebody set. Empty when nothing is stored */\n configured: string;\n /** Active plugins first, in the order the station asks them, then the ones that cannot answer */\n candidates: ProviderCandidate[];\n /** Ids named in the setting that no active plugin answers to. Ordering never gates, so these cost nothing but say nothing either until they are shown */\n stale: string[];\n /** `one` only: a plugin is named and is not an active candidate, so the station has NO provider for this. The dangerous state, because naming one is an instruction and never falls back */\n unanswered: boolean;\n}\n\n/**\n * Mirrors the plugin SDK's `ConfigField`: enough for a console to render the settings form with no per-plugin code\n * generated from [ConfigFieldDescriptor](../../../../../apps/api/data/contracts/plugins/plugins.types.ck)\n */\nexport interface ConfigFieldDescriptor {\n key: string;\n label: string;\n type: ConfigFieldType;\n required?: boolean;\n default?: string | number | boolean;\n /** `number` only, and ignored elsewhere */\n unit?: ConfigFieldUnit;\n /** `slider` for a `number` with both `min` and `max`, `tags` for a `string` holding a comma-separated set */\n control?: ConfigFieldControl;\n /** How coarsely a `control` moves, in the field's own unit. Ignored without one, and defaults to 1 */\n step?: number;\n /** `number` only: the smallest value that will be accepted, inclusive */\n min?: number;\n /** `number` only: the largest value that will be accepted, inclusive */\n max?: number;\n placeholder?: string;\n help?: string;\n options?: ConfigFieldOption[];\n /** Choices only the console can enumerate. Merged where a plugin's own suggestions are, and outranked by them */\n optionsFrom?: ConfigFieldOptionSource;\n /** `list` only, and ignored elsewhere */\n columns?: ConfigFieldColumn[];\n /** `list` only: rows the Add button offers to start from, beside an empty one */\n presets?: ConfigFieldPreset[];\n /** Key of the field this one is only relevant to */\n dependsOn?: string;\n /** Key of the `number` field that is the upper end of the range this one opens, declared on the lower end only. Still two settings, each validated by name; the console draws them as one control whose handles cannot cross */\n rangeWith?: string;\n /** `secret` only: key of the address field this credential is sent to. A save that keeps the stored credential while that address moves to another origin is refused */\n sentTo?: string;\n}\n\n/**\n * generated from [PluginLogPage](../../../../../apps/api/data/contracts/plugins/plugins.types.ck)\n */\nexport interface PluginLogPage {\n pluginId: string;\n level: PluginLogLevel;\n /** Newest first, as the activity feed and the script history send. The download is the file as written, oldest first */\n entries: PluginLogEntry[];\n}\n\n/**\n * generated from [PluginGrantList](../../../../../apps/api/data/contracts/plugins/plugins.types.ck)\n */\nexport interface PluginGrantList {\n /** Every capability every installed plugin is asking for, refused ones included */\n grants: PluginGrant[];\n}\n\n/**\n * Every capability an operator chooses between. Capabilities that fan out and merge without\n * ranking are deliberately absent: order changes nothing about a union\n * generated from [ProviderCatalogue](../../../../../apps/api/data/contracts/plugins/plugins.types.ck)\n */\nexport interface ProviderCatalogue {\n capabilities: ProviderCapabilityState[];\n}\n\n/**\n * A plugin as the settings list sees it. Carries no configured VALUES, only which secrets are set\n * generated from [PluginSummary](../../../../../apps/api/data/contracts/plugins/plugins.types.ck)\n */\nexport interface PluginSummary {\n id: string;\n name: string;\n version: string;\n capabilities: string[];\n /** Whether the manifest declares the `trackFetcher` permission, so its records reach air through the station's own track fetcher and that fetcher needs its own authorization. Not the same as the `stream` capability, which a plugin that mints its own stream URLs declares too. Absent means it does not */\n usesTrackFetcher?: boolean;\n status: PluginStatus;\n origin: PluginOrigin;\n enabled: boolean;\n description?: string;\n icon?: string;\n configFields: ConfigFieldDescriptor[];\n /** Whether a value is currently stored, per `secret` field under its own key and per `secret` cell under `field/rowId/column`. Never the value itself */\n secretsConfigured: Record<string, boolean>;\n /** When this plugin was first ever enabled. Absent means it never has been, so the console asks before it is */\n firstEnabledAt?: DateTime;\n /** The last recorded failure. Absent means it is not currently unhappy */\n lastError?: string;\n /** When the breaker will probe this plugin again on its own. Absent means no probe is pending */\n nextProbeAt?: DateTime;\n}\n\nexport interface PluginSummaryInput {\n id: string;\n name: string;\n version: string;\n capabilities: string[];\n /** Whether the manifest declares the `trackFetcher` permission, so its records reach air through the station's own track fetcher and that fetcher needs its own authorization. Not the same as the `stream` capability, which a plugin that mints its own stream URLs declares too. Absent means it does not */\n usesTrackFetcher?: boolean;\n status: PluginStatus;\n origin: PluginOrigin;\n enabled: boolean;\n description?: string;\n icon?: string;\n configFields: ConfigFieldDescriptor[];\n /** Whether a value is currently stored, per `secret` field under its own key and per `secret` cell under `field/rowId/column`. Never the value itself */\n secretsConfigured: Record<string, boolean>;\n /** The last recorded failure. Absent means it is not currently unhappy */\n lastError?: string;\n}\n\n/** Rehydrates every wire-encoded scalar in a PluginSummary into its runtime type. Mutates and returns `raw`. */\nexport function revivePluginSummary(raw: PluginSummary): PluginSummary {\n const __o0 = raw as unknown as Record<string, unknown>;\n if (__o0['firstEnabledAt'] != null) {\n __o0['firstEnabledAt'] = __dt(__o0['firstEnabledAt'], 'PluginSummary.firstEnabledAt');\n }\n if (__o0['nextProbeAt'] != null) {\n __o0['nextProbeAt'] = __dt(__o0['nextProbeAt'], 'PluginSummary.nextProbeAt');\n }\n return raw;\n}\n\n/**\n * What an import did\n * generated from [PluginImportResult](../../../../../apps/api/data/contracts/plugins/plugins.types.ck)\n */\nexport interface PluginImportResult {\n /** The id the imported plugin claimed */\n pluginId: string;\n /** The same version was already loaded, so the station runs the build it had until it restarts. False for a new plugin and for a new version */\n restartRequired: boolean;\n /** Every plugin, as the catalogue now stands. An import can take an older version away as well as add one */\n plugins: PluginSummary[];\n}\n\nexport interface PluginImportResultInput {\n /** The id the imported plugin claimed */\n pluginId: string;\n /** The same version was already loaded, so the station runs the build it had until it restarts. False for a new plugin and for a new version */\n restartRequired: boolean;\n /** Every plugin, as the catalogue now stands. An import can take an older version away as well as add one */\n plugins: PluginSummaryInput[];\n}\n\n/** Rehydrates every wire-encoded scalar in a PluginImportResult into its runtime type. Mutates and returns `raw`. */\nexport function revivePluginImportResult(raw: PluginImportResult): PluginImportResult {\n const __o0 = raw as unknown as Record<string, unknown>;\n {\n const __a1 = __o0['plugins'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n revivePluginSummary(__a1[__i2] as never);\n }\n }\n return raw;\n}\n\n/**\n * A summary plus the stored NON-SECRET configuration\n * generated from [PluginDetail](../../../../../apps/api/data/contracts/plugins/plugins.types.ck)\n */\nexport interface PluginDetail extends PluginSummary {\n /** Absolute path of the plugin's directory on the station */\n dir: string;\n config: Record<string, unknown>;\n oauthConnected?: boolean;\n logLevel: PluginLogLevel;\n}\n\nexport interface PluginDetailInput extends PluginSummaryInput {\n /** Absolute path of the plugin's directory on the station */\n dir: string;\n config: Record<string, unknown>;\n oauthConnected?: boolean;\n logLevel: PluginLogLevel;\n}\n\n/** Rehydrates every wire-encoded scalar in a PluginDetail into its runtime type. Mutates and returns `raw`. */\nexport function revivePluginDetail(raw: PluginDetail): PluginDetail {\n revivePluginSummary(raw as never);\n return raw;\n}\n","import type { SdkFetch } from '../sdk-options.js';\nimport { bigIntReplacer, parseJson, buildQueryString } from '../sdk-options.js';\nimport type {\n PluginConfigInput,\n PluginDetail,\n PluginFieldSuggestions,\n PluginGrantInput,\n PluginGrantList,\n PluginImportResult,\n PluginLogLevelInput,\n PluginLogPage,\n PluginLogQuery,\n PluginOAuthCallbackQuery,\n PluginOAuthResult,\n PluginOAuthStart,\n PluginSummary,\n PluginTestResult,\n ProviderCatalogue,\n} from './types/plugins.types.js';\nimport { revivePluginDetail, revivePluginImportResult, revivePluginSummary } from './types/plugins.types.js';\n\nexport class PluginsClient {\n constructor(private fetch: SdkFetch) {}\n\n /**\n * @name List plugins\n * @description Lists every plugin the host knows about\n */\n async listPlugins(): Promise<PluginSummary[]> {\n const result = await this.fetch(`/plugins`, { method: 'GET' });\n return (await parseJson<PluginSummary[]>(result)).map(revivePluginSummary);\n }\n\n /**\n * @name List plugin grants\n * @description Every capability an installed plugin is asking the operator for, with the answer so far\n */\n async listPluginGrants(): Promise<PluginGrantList> {\n const result = await this.fetch(`/plugins/grants`, { method: 'GET' });\n return await parseJson<PluginGrantList>(result);\n }\n\n /**\n * @name List capability providers\n * @description Every capability more than one plugin could answer, who can answer it, and in what order the station asks them\n */\n async listCapabilityProviders(): Promise<ProviderCatalogue> {\n const result = await this.fetch(`/plugins/providers`, { method: 'GET' });\n return await parseJson<ProviderCatalogue>(result);\n }\n\n /**\n * @name Rescan plugins\n * @description Rescans the mounted plugin directory: registers new plugins, unloads removed ones\n */\n async rescanPlugins(): Promise<PluginSummary[]> {\n const result = await this.fetch(`/plugins/rescan`, { method: 'POST' });\n return (await parseJson<PluginSummary[]>(result)).map(revivePluginSummary);\n }\n\n /**\n * @name Import plugin\n * @description Takes a plugin in from the browser as the tarball npm pack writes and puts it in the plugins directory. Importing runs the plugin's code: the station loads it to read its manifest, inside the server and with the server's privileges. It lands disabled, which only means the station does not use it until it is enabled. A newer version of an installed plugin replaces the older one\n */\n async importPlugin(body: FormData): Promise<PluginImportResult> {\n const result = await this.fetch(`/plugins/import`, {\n method: 'POST',\n body: body,\n });\n return revivePluginImportResult(await parseJson<PluginImportResult>(result));\n }\n\n /**\n * @name Get plugin\n * @description One plugin, including its stored non-secret configuration and last error\n */\n async getPlugin(id: string): Promise<PluginDetail> {\n const result = await this.fetch(`/plugins/${encodeURIComponent(id)}`, { method: 'GET' });\n return revivePluginDetail(await parseJson<PluginDetail>(result));\n }\n\n /**\n * @name Remove plugin\n * @description Removes a plugin the operator installed: stops it and deletes its folder. Its settings are kept, so importing it again brings them back. A bundled plugin is refused, unless an installed copy of it is left over from before the station shipped it: that copy never loads, and it is what gets removed\n */\n async removePlugin(id: string): Promise<PluginSummary[]> {\n const result = await this.fetch(`/plugins/${encodeURIComponent(id)}`, { method: 'DELETE' });\n return (await parseJson<PluginSummary[]>(result)).map(revivePluginSummary);\n }\n\n /**\n * @name Update plugin configuration\n * @description Validates against the plugin's own config schema, encrypts secrets, persists, and reinitializes\n */\n async updatePluginConfiguration(id: string, body: PluginConfigInput): Promise<PluginDetail> {\n const result = await this.fetch(`/plugins/${encodeURIComponent(id)}/config`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return revivePluginDetail(await parseJson<PluginDetail>(result));\n }\n\n /**\n * @name Enable plugin\n * @description Enables a plugin without resubmitting its configuration\n */\n async enablePlugin(id: string): Promise<PluginDetail> {\n const result = await this.fetch(`/plugins/${encodeURIComponent(id)}/enable`, { method: 'POST' });\n return revivePluginDetail(await parseJson<PluginDetail>(result));\n }\n\n /**\n * @name Disable plugin\n * @description Disables a plugin and tears its instance down, keeping its configuration\n */\n async disablePlugin(id: string): Promise<PluginDetail> {\n const result = await this.fetch(`/plugins/${encodeURIComponent(id)}/disable`, { method: 'POST' });\n return revivePluginDetail(await parseJson<PluginDetail>(result));\n }\n\n /**\n * @name Decide plugin grant\n * @description Answers one capability this plugin asked for. Takes effect on the next fetch, with no reload\n */\n async decidePluginGrant(id: string, body: PluginGrantInput): Promise<PluginGrantList> {\n const result = await this.fetch(`/plugins/${encodeURIComponent(id)}/grants`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<PluginGrantList>(result);\n }\n\n /**\n * @name Reload plugin\n * @description Reapplies the plugin's stored configuration: disposes the running instance and initializes it again\n */\n async reloadPlugin(id: string): Promise<PluginDetail> {\n const result = await this.fetch(`/plugins/${encodeURIComponent(id)}/reload`, { method: 'POST' });\n return revivePluginDetail(await parseJson<PluginDetail>(result));\n }\n\n /**\n * @name Test plugin connection\n * @description Runs the plugin's own `testConnection()` through the invoker\n */\n async testPluginConnection(id: string): Promise<PluginTestResult> {\n const result = await this.fetch(`/plugins/${encodeURIComponent(id)}/test`, { method: 'POST' });\n return await parseJson<PluginTestResult>(result);\n }\n\n /**\n * @name Suggest plugin config options\n * @description Asks the plugin what to offer for its config fields right now, through the invoker\n */\n async suggestPluginConfigOptions(id: string): Promise<PluginFieldSuggestions> {\n const result = await this.fetch(`/plugins/${encodeURIComponent(id)}/config/suggestions`, { method: 'POST' });\n return await parseJson<PluginFieldSuggestions>(result);\n }\n\n /**\n * @name Get plugin logs\n * @description Returns the plugin's buffered log lines at or above the current log level\n */\n async getPluginLogs(id: string, query?: PluginLogQuery): Promise<PluginLogPage> {\n const qs = buildQueryString(query);\n const result = await this.fetch(`/plugins/${encodeURIComponent(id)}/logs${qs}`, {\n method: 'GET',\n });\n return await parseJson<PluginLogPage>(result);\n }\n\n /**\n * @name Download plugin logs\n * @description Streams the plugin's full retained log as a plain-text attachment\n */\n async downloadPluginLogs(id: string): Promise<{ data: string; headers: { contentDisposition?: string } }> {\n const result = await this.fetch(`/plugins/${encodeURIComponent(id)}/logs/download`, { method: 'GET' });\n const data = await result.text();\n return { data, headers: { contentDisposition: result.headers.get('Content-Disposition') ?? undefined } };\n }\n\n /**\n * @name Set plugin log level\n * @description Sets the minimum severity the plugin's log store retains going forward\n */\n async setPluginLogLevel(id: string, body: PluginLogLevelInput): Promise<PluginDetail> {\n const result = await this.fetch(`/plugins/${encodeURIComponent(id)}/logs/level`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return revivePluginDetail(await parseJson<PluginDetail>(result));\n }\n\n /**\n * @name Start plugin OAuth authorization\n * @description Reports where to send the operator for the provider's consent screen\n */\n async startPluginOAuthAuthorization(id: string): Promise<PluginOAuthStart> {\n const result = await this.fetch(`/plugins/${encodeURIComponent(id)}/oauth/authorize`, { method: 'GET' });\n return await parseJson<PluginOAuthStart>(result);\n }\n\n /**\n * @name Disconnect plugin OAuth\n * @description Forgets the plugin's stored OAuth tokens and reinitializes it\n */\n async disconnectPluginOAuth(id: string): Promise<PluginDetail> {\n const result = await this.fetch(`/plugins/${encodeURIComponent(id)}/oauth`, { method: 'DELETE' });\n return revivePluginDetail(await parseJson<PluginDetail>(result));\n }\n\n /**\n * @name Complete plugin OAuth authorization\n * @description Completes the flow. Anonymous: the provider redirects the browser here with no session of ours\n */\n async completePluginOAuthAuthorization(id: string, query?: PluginOAuthCallbackQuery): Promise<PluginOAuthResult> {\n const qs = buildQueryString(query);\n const result = await this.fetch(`/plugins/${encodeURIComponent(id)}/oauth/callback${qs}`, {\n method: 'GET',\n });\n return await parseJson<PluginOAuthResult>(result);\n }\n}\n","import { DateTime } from 'luxon';\nconst __dt = (v: unknown, path: string): DateTime => {\n if (typeof v !== 'string') {\n throw new TypeError(`ContractKit: expected an ISO 8601 string at '${path}', received ${typeof v}.`);\n }\n const d = DateTime.fromISO(v);\n if (!d.isValid) throw new TypeError(`ContractKit: '${v}' at '${path}' is not a valid ISO 8601 datetime.`);\n return d;\n};\n\n/**\n * One person in a production: the presenter, or somebody cast to phone in. A snapshot rather than a\n * reference, because the persona it names may be edited or deleted while the programme is still being\n * made and what the turns were written as has to be what an operator reads back\n * generated from [ProductionCastMember](../../../../../apps/api/data/contracts/productions/productions.types.ck)\n */\nexport interface ProductionCastMember {\n role: 'host' | 'caller' | 'guest' | 'cohost';\n /** What they are called on air */\n name?: string;\n /** The persona key, for a link back to the character */\n persona?: string;\n}\n\n/**\n * Something a production was handed to read. The research pass takes the notes it states as fact out of these, keeping only claims whose words really are in the text\n * generated from [ProductionSource](../../../../../apps/api/data/contracts/productions/productions.types.ck)\n */\nexport interface ProductionSource {\n /** What the source is called, for the console and for the research pass's sense of what it is reading */\n title: string;\n /** Where it came from, when it came from somewhere */\n url?: string;\n /** What it says. Absent for a source given only by its address, which the research pass reads through whichever installed plugin can open a page */\n text?: string;\n}\n\n/**\n * Something the station makes rather than something it says: several beats of speech, written in several passes, that airs as one block\n * generated from [Production](../../../../../apps/api/data/contracts/productions/productions.types.ck)\n */\nexport interface Production {\n id: string;\n /** What sort of production: podcast, bulletin, feature. Free text, so a station that wants a documentary strand needs no migration */\n kind: string;\n title: string;\n /** What was asked for, in the operator's own words. Distinct from the title, which is only a label */\n brief?: string;\n /** What it may state as fact, one short note each. The outline divides them between the beats, and nothing else it says is offered as fact */\n notes?: string[];\n /** What it was handed to read. Its notes are taken from these by the research pass when nobody gave it any */\n sources?: ProductionSource[];\n /** Whether it was asked to find its own sources on the operator's trusted sites */\n research?: boolean;\n /** Who presents it. Absent falls back to the station's active persona when a pass runs */\n personaId?: string;\n /** How many passes to spend on it */\n writingMode: 'quick' | 'outlined' | 'polished';\n /** How long it should run. What the beat count and the per-beat word budgets are computed from */\n targetMs: number;\n /** `researching` is its sources being read for notes. `stitching` is the beats being joined into one piece of audio, and it leads to `ready` whether that worked or not */\n state: 'planned' | 'researching' | 'outlining' | 'drafting' | 'checking' | 'rendering' | 'stitching' | 'ready' | 'aired' | 'failed' | 'cancelled';\n /** Why making it did not work */\n error?: string;\n /** When it should air. Absent means as soon as it is made */\n scheduledFor?: DateTime;\n cancelledAt?: DateTime;\n /** How many beats exist so far, which is how far along the drafting is */\n beats: number;\n /** The station's own show this is an episode of, when it is one */\n showId?: string;\n /** Who is on it, decided by the first pass that ran. Empty for one nobody has started, and for a programme the presenter reads alone */\n cast: ProductionCastMember[];\n createdAt: DateTime;\n}\n\nexport interface ProductionInput {\n /** What sort of production: podcast, bulletin, feature. Free text, so a station that wants a documentary strand needs no migration */\n kind: string;\n title: string;\n /** What was asked for, in the operator's own words. Distinct from the title, which is only a label */\n brief?: string;\n /** What it may state as fact, one short note each. The outline divides them between the beats, and nothing else it says is offered as fact */\n notes?: string[];\n /** What it was handed to read. Its notes are taken from these by the research pass when nobody gave it any */\n sources?: ProductionSource[];\n /** Who presents it. Absent falls back to the station's active persona when a pass runs */\n personaId?: string;\n /** How many passes to spend on it */\n writingMode: 'quick' | 'outlined' | 'polished';\n /** How long it should run. What the beat count and the per-beat word budgets are computed from */\n targetMs: number;\n /** When it should air. Absent means as soon as it is made */\n scheduledFor?: DateTime;\n}\n\n/** Rehydrates every wire-encoded scalar in a Production into its runtime type. Mutates and returns `raw`. */\nexport function reviveProduction(raw: Production): Production {\n const __o0 = raw as unknown as Record<string, unknown>;\n if (__o0['scheduledFor'] != null) {\n __o0['scheduledFor'] = __dt(__o0['scheduledFor'], 'Production.scheduledFor');\n }\n if (__o0['cancelledAt'] != null) {\n __o0['cancelledAt'] = __dt(__o0['cancelledAt'], 'Production.cancelledAt');\n }\n __o0['createdAt'] = __dt(__o0['createdAt'], 'Production.createdAt');\n return raw;\n}\n\n/**\n * What an operator asks for. Everything else about a production is decided by the passes that make it\n * generated from [ProductionRequest](../../../../../apps/api/data/contracts/productions/productions.types.ck)\n */\nexport interface ProductionRequest {\n kind?: string;\n /** Absent is named after its kind and the moment it was asked for, which is what somebody taking a call now wants rather than a box to fill in */\n title?: string;\n brief?: string;\n /** What it may state as fact, one short note each. Absent leaves it to general knowledge, said vaguely */\n notes?: string[];\n /** What to read before writing it. Given sources and no notes, a research pass takes the notes out of these first */\n sources?: ProductionSource[];\n /** Given nothing to read, search the operator's trusted sites for its subject and read what comes back. Needs an enrichment plugin that can, such as the web search one with trusted sites */\n research?: boolean;\n personaId?: string;\n /** Absent takes the station's `render.productionWritingMode` */\n writingMode?: 'quick' | 'outlined' | 'polished';\n targetMs?: number;\n scheduledFor?: DateTime;\n}\n\n/** Rehydrates every wire-encoded scalar in a ProductionRequest into its runtime type. Mutates and returns `raw`. */\nexport function reviveProductionRequest(raw: ProductionRequest): ProductionRequest {\n const __o0 = raw as unknown as Record<string, unknown>;\n if (__o0['scheduledFor'] != null) {\n __o0['scheduledFor'] = __dt(__o0['scheduledFor'], 'ProductionRequest.scheduledFor');\n }\n return raw;\n}\n\n/**\n * generated from [ProductionList](../../../../../apps/api/data/contracts/productions/productions.types.ck)\n */\nexport interface ProductionList {\n productions: Production[];\n}\n\nexport interface ProductionListInput {\n productions: ProductionInput[];\n}\n\n/** Rehydrates every wire-encoded scalar in a ProductionList into its runtime type. Mutates and returns `raw`. */\nexport function reviveProductionList(raw: ProductionList): ProductionList {\n const __o0 = raw as unknown as Record<string, unknown>;\n {\n const __a1 = __o0['productions'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveProduction(__a1[__i2] as never);\n }\n }\n return raw;\n}\n","import { DateTime } from 'luxon';\nconst __dt = (v: unknown, path: string): DateTime => {\n if (typeof v !== 'string') {\n throw new TypeError(`ContractKit: expected an ISO 8601 string at '${path}', received ${typeof v}.`);\n }\n const d = DateTime.fromISO(v);\n if (!d.isValid) throw new TypeError(`ContractKit: '${v}' at '${path}' is not a valid ISO 8601 datetime.`);\n return d;\n};\n\n/**\n * A programme the station carries, as one installed plugin describes it\n * generated from [StationShow](../../../../../apps/api/data/contracts/podcasts/podcasts.types.ck)\n */\nexport interface StationShow {\n /** Unique across the station: the plugin's own id for the show, qualified with the plugin that offered it */\n id: string;\n pluginId: string;\n /** What the show is called, which is what a presenter says out loud */\n title: string;\n author?: string;\n /** What the show says about itself, as plain text */\n description?: string;\n artworkUrl?: string;\n homeUrl?: string;\n /** Where its feed is, when the plugin reads one */\n feedUrl?: string;\n language?: string;\n categories?: string[];\n /** Whether the publisher marked the whole show explicit. Absent means the publisher did not say, which is not the same as clean */\n explicit?: boolean;\n}\n\n/**\n * One episode of a programme the station carries, and what the station has done with it\n * generated from [StationEpisode](../../../../../apps/api/data/contracts/podcasts/podcasts.types.ck)\n */\nexport interface StationEpisode {\n /** The station's own id for this episode */\n id: string;\n /** Qualified, matching `StationShow.id` */\n showId: string;\n /** The plugin's own id for the episode, stable across refreshes */\n episodeId: string;\n showTitle: string;\n title: string;\n /** What the publisher says it is about, as plain text */\n summary?: string;\n /** The episode's page, for a person */\n url?: string;\n /** ISO-8601 */\n publishedAt?: string;\n /** How long the publisher says it runs, in milliseconds */\n durationMs?: number;\n artworkUrl?: string;\n explicit?: boolean;\n /** ISO-8601: when a refresh last saw it in its feed */\n seenAt: string;\n /** Whether the station holds its own copy of the audio, ready to air */\n fetched: boolean;\n /** ISO-8601: when the station last asked for the audio */\n fetchRequestedAt?: string;\n /** Why the last attempt to fetch the audio failed, when it did */\n fetchError?: string;\n /** ISO-8601: the slot the audio was fetched for */\n scheduledFor?: string;\n /** ISO-8601: when a listener could first have heard it. An episode airs once */\n airedAt?: string;\n}\n\n/**\n * A show a podcast plugin's directory knows about, which the station may or may not carry\n * generated from [StationDirectoryEntry](../../../../../apps/api/data/contracts/podcasts/podcasts.types.ck)\n */\nexport interface StationDirectoryEntry {\n /** The directory's own id for the show. A key in a list, and nothing more */\n id: string;\n /** The plugin whose directory answered, which is the plugin a subscription would go to */\n pluginId: string;\n title: string;\n /** Where the show's feed is, which is what subscribing needs */\n feedUrl: string;\n author?: string;\n description?: string;\n artworkUrl?: string;\n homeUrl?: string;\n categories?: string[];\n explicit?: boolean;\n}\n\n/**\n * generated from [StationDirectoryQuery](../../../../../apps/api/data/contracts/podcasts/podcasts.types.ck)\n */\nexport interface StationDirectoryQuery {\n /** Words to look a show up by: its name, its publisher, its subject */\n query: string;\n limit?: number;\n}\n\n/**\n * generated from [StationEpisodeQuery](../../../../../apps/api/data/contracts/podcasts/podcasts.types.ck)\n */\nexport interface StationEpisodeQuery {\n /** One show's episodes, or absent for every show's, newest first */\n showId?: string;\n limit?: number;\n}\n\n/**\n * A show the station makes for itself: a saved recipe for a podcast, whose every episode is a production\n * generated from [OwnShow](../../../../../apps/api/data/contracts/podcasts/podcasts.types.ck)\n */\nexport interface OwnShow {\n id: string;\n /** What the show is called. Each episode's title starts with it */\n title: string;\n /** What the show is, for the console. Never read out */\n description?: string;\n /** What an episode is about when it is asked for with no subject of its own */\n subject?: string;\n /** Who presents it. Absent is whoever is presenting when it is made */\n personaId?: string;\n /** How long an episode runs. Absent is the station's production length */\n targetMs?: number;\n /** How much of the model an episode is worth. Absent is the station's default */\n writingMode?: 'quick' | 'outlined' | 'polished';\n /** The station's news feeds an episode reads, by their qualified ids. Absent or empty is a show that does not read the news */\n newsFeedIds?: string[];\n /** How many hours of news an episode reads. Absent is a day */\n newsHours?: number;\n /** Whether an episode given nothing to read finds its own sources on the operator's trusted sites */\n research?: boolean;\n createdAt: DateTime;\n}\n\nexport interface OwnShowInput {\n /** What the show is called. Each episode's title starts with it */\n title: string;\n /** What the show is, for the console. Never read out */\n description?: string;\n /** What an episode is about when it is asked for with no subject of its own */\n subject?: string;\n /** Who presents it. Absent is whoever is presenting when it is made */\n personaId?: string;\n /** How long an episode runs. Absent is the station's production length */\n targetMs?: number;\n /** How much of the model an episode is worth. Absent is the station's default */\n writingMode?: 'quick' | 'outlined' | 'polished';\n /** The station's news feeds an episode reads, by their qualified ids. Absent or empty is a show that does not read the news */\n newsFeedIds?: string[];\n /** How many hours of news an episode reads. Absent is a day */\n newsHours?: number;\n /** Whether an episode given nothing to read finds its own sources on the operator's trusted sites */\n research?: boolean;\n}\n\n/** Rehydrates every wire-encoded scalar in a OwnShow into its runtime type. Mutates and returns `raw`. */\nexport function reviveOwnShow(raw: OwnShow): OwnShow {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['createdAt'] = __dt(__o0['createdAt'], 'OwnShow.createdAt');\n return raw;\n}\n\n/**\n * Asks one of the station's own shows for an episode. Everything is optional: a show with a standing subject needs nothing\n * generated from [OwnEpisodeRequest](../../../../../apps/api/data/contracts/podcasts/podcasts.types.ck)\n */\nexport interface OwnEpisodeRequest {\n /** What this episode is about. Absent is the show's own subject */\n topic?: string;\n /** A page for it to read first, by its address. The episode states only what it can find there */\n url?: string;\n /** What the pasted text is called */\n sourceTitle?: string;\n /** Something for it to read first. The episode states only what it can find in this. Given text, a show that reads the news reads this instead */\n text?: string;\n /** When it should air. Absent is as soon as it is made */\n airAt?: DateTime;\n}\n\n/** Rehydrates every wire-encoded scalar in a OwnEpisodeRequest into its runtime type. Mutates and returns `raw`. */\nexport function reviveOwnEpisodeRequest(raw: OwnEpisodeRequest): OwnEpisodeRequest {\n const __o0 = raw as unknown as Record<string, unknown>;\n if (__o0['airAt'] != null) {\n __o0['airAt'] = __dt(__o0['airAt'], 'OwnEpisodeRequest.airAt');\n }\n return raw;\n}\n\n/**\n * generated from [StationShowList](../../../../../apps/api/data/contracts/podcasts/podcasts.types.ck)\n */\nexport interface StationShowList {\n shows: StationShow[];\n}\n\n/**\n * generated from [StationEpisodePage](../../../../../apps/api/data/contracts/podcasts/podcasts.types.ck)\n */\nexport interface StationEpisodePage {\n /** Newest first. Empty when the station knows of none, which is not an error */\n episodes: StationEpisode[];\n}\n\n/**\n * generated from [StationDirectoryPage](../../../../../apps/api/data/contracts/podcasts/podcasts.types.ck)\n */\nexport interface StationDirectoryPage {\n /** Empty when nothing matched or no directory could be asked, which is not an error */\n results: StationDirectoryEntry[];\n}\n\n/**\n * generated from [OwnShowList](../../../../../apps/api/data/contracts/podcasts/podcasts.types.ck)\n */\nexport interface OwnShowList {\n shows: OwnShow[];\n}\n\nexport interface OwnShowListInput {\n shows: OwnShowInput[];\n}\n\n/** Rehydrates every wire-encoded scalar in a OwnShowList into its runtime type. Mutates and returns `raw`. */\nexport function reviveOwnShowList(raw: OwnShowList): OwnShowList {\n const __o0 = raw as unknown as Record<string, unknown>;\n {\n const __a1 = __o0['shows'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveOwnShow(__a1[__i2] as never);\n }\n }\n return raw;\n}\n","import type { SdkFetch } from '../sdk-options.js';\nimport { bigIntReplacer, parseJson, buildQueryString } from '../sdk-options.js';\nimport type { Production, ProductionList } from '../productions/types/productions.types.js';\nimport { reviveProduction, reviveProductionList } from '../productions/types/productions.types.js';\nimport type {\n OwnEpisodeRequest,\n OwnShow,\n OwnShowInput,\n OwnShowList,\n StationDirectoryPage,\n StationDirectoryQuery,\n StationEpisode,\n StationEpisodePage,\n StationEpisodeQuery,\n StationShowList,\n} from './types/podcasts.types.js';\nimport { reviveOwnShow, reviveOwnShowList } from './types/podcasts.types.js';\n\nexport class PodcastsClient {\n constructor(private fetch: SdkFetch) {}\n\n /**\n * @name List shows\n * @description Every programme every installed podcast plugin carries\n */\n async listShows(): Promise<StationShowList> {\n const result = await this.fetch(`/podcasts/shows`, { method: 'GET' });\n return await parseJson<StationShowList>(result);\n }\n\n /**\n * @name Search podcast directory\n * @description Looks a show up in the directories the installed podcast plugins can search\n */\n async searchPodcastDirectory(query?: StationDirectoryQuery): Promise<StationDirectoryPage> {\n const qs = buildQueryString(query);\n const result = await this.fetch(`/podcasts/search${qs}`, {\n method: 'GET',\n });\n return await parseJson<StationDirectoryPage>(result);\n }\n\n /**\n * @name List episodes\n * @description The episodes the station knows about, newest first, with what it has done with each\n */\n async listEpisodes(query?: StationEpisodeQuery): Promise<StationEpisodePage> {\n const qs = buildQueryString(query);\n const result = await this.fetch(`/podcasts/episodes${qs}`, {\n method: 'GET',\n });\n return await parseJson<StationEpisodePage>(result);\n }\n\n /**\n * @name Fetch episode\n * @description Fetches one episode's audio into the station's store now, rather than waiting for its slot to come near\n */\n async fetchEpisode(id: string): Promise<StationEpisode> {\n const result = await this.fetch(`/podcasts/episodes/${encodeURIComponent(id)}/fetch`, { method: 'POST' });\n return await parseJson<StationEpisode>(result);\n }\n\n /**\n * @name Refresh podcasts\n * @description Reads every show's feed again, in the background, rather than waiting for the next scheduled refresh\n */\n async refreshPodcasts(): Promise<void> {\n await this.fetch(`/podcasts/refresh`, { method: 'POST' });\n }\n\n /**\n * @name List own shows\n * @description The shows the station makes for itself\n */\n async listOwnShows(): Promise<OwnShowList> {\n const result = await this.fetch(`/podcasts/own`, { method: 'GET' });\n return reviveOwnShowList(await parseJson<OwnShowList>(result));\n }\n\n /**\n * @name Create own show\n * @description Makes a new show. Nothing is made until an episode is asked for\n */\n async createOwnShow(body: OwnShowInput): Promise<OwnShow> {\n const result = await this.fetch(`/podcasts/own`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return reviveOwnShow(await parseJson<OwnShow>(result));\n }\n\n /**\n * @name Update own show\n * @description Rewrites a show. Episodes already asked for keep what they were asked with\n */\n async updateOwnShow(id: string, body: OwnShowInput): Promise<OwnShow> {\n const result = await this.fetch(`/podcasts/own/${encodeURIComponent(id)}`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return reviveOwnShow(await parseJson<OwnShow>(result));\n }\n\n /**\n * @name Delete own show\n * @description Removes a show. Its episodes stay on the Productions page, no longer filed under it\n */\n async deleteOwnShow(id: string): Promise<void> {\n await this.fetch(`/podcasts/own/${encodeURIComponent(id)}`, { method: 'DELETE' });\n }\n\n /**\n * @name List own show episodes\n * @description A show's episodes, newest first, with how far along each is\n */\n async listOwnShowEpisodes(id: string): Promise<ProductionList> {\n const result = await this.fetch(`/podcasts/own/${encodeURIComponent(id)}/episodes`, { method: 'GET' });\n return reviveProductionList(await parseJson<ProductionList>(result));\n }\n\n /**\n * @name Request own show episode\n * @description Asks the show for an episode. It is queued, not started, and airs when it is made or at the time given\n */\n async requestOwnShowEpisode(id: string, body: OwnEpisodeRequest): Promise<Production> {\n const result = await this.fetch(`/podcasts/own/${encodeURIComponent(id)}/episodes`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return reviveProduction(await parseJson<Production>(result));\n }\n}\n","import type { SdkFetch } from '../sdk-options.js';\nimport { bigIntReplacer, parseJson } from '../sdk-options.js';\nimport type { Production, ProductionList, ProductionRequest } from './types/productions.types.js';\nimport { reviveProduction, reviveProductionList } from './types/productions.types.js';\n\nexport class ProductionsClient {\n constructor(private fetch: SdkFetch) {}\n\n /**\n * @name List productions\n * @description Everything the station has made or is making, newest first\n */\n async listProductions(): Promise<ProductionList> {\n const result = await this.fetch(`/productions`, { method: 'GET' });\n return reviveProductionList(await parseJson<ProductionList>(result));\n }\n\n /**\n * @name Request production\n * @description Asks the station to make one. It is queued, not started\n */\n async requestProduction(body: ProductionRequest): Promise<Production> {\n const result = await this.fetch(`/productions`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return reviveProduction(await parseJson<Production>(result));\n }\n\n /**\n * @name Cancel production\n * @description Stops a production being made, for good\n */\n async cancelProduction(id: string): Promise<Production> {\n const result = await this.fetch(`/productions/${encodeURIComponent(id)}/cancel`, { method: 'POST' });\n return reviveProduction(await parseJson<Production>(result));\n }\n}\n","import { DateTime } from 'luxon';\nconst __dt = (v: unknown, path: string): DateTime => {\n if (typeof v !== 'string') {\n throw new TypeError(`ContractKit: expected an ISO 8601 string at '${path}', received ${typeof v}.`);\n }\n const d = DateTime.fromISO(v);\n if (!d.isValid) throw new TypeError(`ContractKit: '${v}' at '${path}' is not a valid ISO 8601 datetime.`);\n return d;\n};\n\n/**\n * One thing the station can play that is not a record\n * generated from [Segment](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface Segment {\n id: string;\n /** What sort of element it is: `ident`, `stinger`, `talkbreak`, `news` */\n kind: string;\n /** One state per stage of making it. Only `ready` can go on air; the station skips anything else rather than waiting for it */\n state: 'planned' | 'writing' | 'written' | 'rendering' | 'ready' | 'failed';\n /** What the console calls it, and what the mount is labelled with while it airs */\n label: string;\n /** Who made it: `library` for a file dropped into the inbox */\n source: string;\n /** Whether there is audio behind it yet */\n playable: boolean;\n /** The words, for anything that speaks. Absent for an imported recording */\n script?: string;\n /** The words as the speech engine was handed them: symbols said, years read as a person reads them, the station's pronunciation list applied. Absent until something has spoken it */\n spokenScript?: string;\n /** The file in the inbox this came from. The bytes were copied, so emptying the inbox does not take it off the air */\n sourcePath?: string;\n /** How long it runs. A display value: the player measures the audio itself */\n durationMs?: number;\n /** Why it is `failed` */\n error?: string;\n /** The station's own name for the voice this is said in, e.g. `host`. Absent means the speech plugin's default */\n voice?: string;\n /** How the words are read: `hushed` or `frantic`. Absent is the voice's own ordinary reading, which is nearly every segment */\n delivery?: string;\n}\n\n/**\n * Something for the station to say, before anything has said it\n * generated from [SegmentCreate](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface SegmentCreate {\n /** What the console calls it, and what the mount is labelled with while it airs */\n label: string;\n /** The words to say */\n script: string;\n /** What sort of element it is. Defaults to `talkbreak` */\n kind?: string;\n /** A station voice name the speech plugin knows how to map. Absent uses its default */\n voice?: string;\n /** How to read the words: `hushed` or `frantic`, and refused otherwise. Absent is the voice's own ordinary reading. Dropped at render time by an engine that cannot perform it */\n delivery?: string;\n}\n\n/**\n * A recording arriving from the browser, as multipart form parts.\n *\n * Documentation rather than validation: a multipart body reaches the service as the raw parser and\n * the generated client types the body as `FormData`, so nothing checks this shape. It says what to\n * send\n * generated from [SegmentUpload](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface SegmentUpload {\n /** The audio itself. mp3, wav, ogg, flac or m4a, and at most 50 MB */\n file: Blob;\n /** What sort of element it is, which is also the directory it is filed under. A kind nothing else uses becomes a bookable band on the format clock */\n kind: string;\n /** What the console calls it, and what the mount is labelled with while it airs. Derived from the filename when absent */\n label?: string;\n}\n\n/**\n * A voice the station can be asked to speak in\n * generated from [Voice](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface Voice {\n /** What to pass as a segment's `voice`. Empty means the plugin's own default */\n id: string;\n /** What the console calls it */\n label: string;\n /** What it sounds like, or what it maps to on the engine */\n description?: string;\n}\n\n/**\n * Whether there are words, and if not, which way it went wrong\n * generated from [ScriptOutcome](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport type ScriptOutcome = 'written' | 'declined' | 'failed';\n\n/**\n * A record a writer was told about, kept as it was told\n * generated from [ScriptNeighbour](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface ScriptNeighbour {\n title: string;\n artist: string;\n /** What it was shown about the record. A break that said nothing interesting and one that was TOLD nothing interesting read the same from the script alone */\n facts?: string[];\n}\n\n/**\n * What the provider said the attempt cost, when it said anything\n * generated from [ScriptUsage](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface ScriptUsage {\n inputTokens?: number;\n outputTokens?: number;\n totalTokens?: number;\n}\n\n/**\n * One turn of the conversation a writer sent\n * generated from [ScriptPromptMessage](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface ScriptPromptMessage {\n role: string;\n content: string;\n}\n\n/**\n * What an operator thought of something the station said.\n *\n * The catalog's three spellings exactly, and deliberately not a second vocabulary: an opinion is an\n * opinion whether it is about a record or about a sentence, and `catalog/rating.ts` is the one place\n * the words and the column's numbers meet.\n *\n * `neutral` is a real answer rather than an absence. Rating something back to nothing is a thing an\n * operator does, and it has to be distinguishable from never having listened, which is the field\n * being absent on the attempt.\n * generated from [ScriptRating](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport type ScriptRating = 'liked' | 'neutral' | 'disliked';\n\n/**\n * Words to hear before anything has aired them\n * generated from [SpeechPreviewRequest](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface SpeechPreviewRequest {\n /** What to say. Far under a segment's 20000 because this is one break heard once, and the cap is what bounds a cache keyed on the words themselves */\n text: string;\n /** A station voice name, as a segment's `voice`. Absent uses the plugin's own default */\n voice?: string;\n /** How to read it, as a segment's `delivery`: `hushed` or `frantic`, and refused otherwise. Absent is the voice's own ordinary reading */\n delivery?: string;\n /** The board a `[sfx:name]` in the text is played from, as a character's `soundboard`. Absent, or a hit the board does not hold, and the hit is left out and only the words are spoken */\n soundboard?: string;\n}\n\n/**\n * The window the counts cover\n * generated from [ScriptHistorySummaryQuery](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface ScriptHistorySummaryQuery {\n /** How far back to count. Defaults to 24, and a week at most, because past that the nightly sweep may already have taken the rows and the count would quietly be of what survived rather than of what happened */\n hours?: number;\n}\n\n/**\n * One presenter's attempts in the window\n * generated from [ScriptHistorySummaryRow](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface ScriptHistorySummaryRow {\n /** Absent means nobody was presenting, which is an ordinary state rather than a gap in the data */\n personaKey?: string;\n written: number;\n /** A decline is the writer registry working: the model had nothing to say and the floor covered for it */\n declined: number;\n failed: number;\n}\n\n/**\n * What one pass over the inbox did\n * generated from [SegmentScanResult](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface SegmentScanResult {\n /** Audio files seen, whether or not they were already known */\n scanned: number;\n /** Segments the station did not have before this pass */\n imported: number;\n /** Files passed over: not audio it can serve, or unreadable */\n skipped: number;\n}\n\n/**\n * One name the station says differently from how it is written\n * generated from [Pronunciation](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface Pronunciation {\n id: string;\n /** What appears in a script. Matched case-insensitively, and whole words only */\n written: string;\n /** What the engine is handed instead, untouched. EMPTY is meaningful: it drops the words, which is the honest reading for a marker that got into a title and is not a word */\n spoken: string;\n /** `active` is said. `suggested` is proposed and says nothing yet. `rejected` outlives the pass that proposed it, or the same article proposes it again forever */\n state: 'active' | 'suggested' | 'rejected';\n /** Who says so. `gloss` is a pronunciation key an encyclopaedia article printed for itself */\n origin: 'operator' | 'gloss';\n /** The article. Present on anything an operator did not type */\n sourceUrl?: string;\n /** The sentence that says so, as it stands in the article, which is what the decision is actually made on */\n sourceQuote?: string;\n /** What the article was about */\n subjectKind?: 'track' | 'album' | 'artist';\n subjectId?: string;\n createdAt: string;\n}\n\n/**\n * A name and how to say it\n * generated from [PronunciationWrite](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface PronunciationWrite {\n written: string;\n /** Empty drops the words rather than saying them */\n spoken: string;\n}\n\n/**\n * Accepting a proposal, turning one down, or taking an entry out of use without losing it\n * generated from [PronunciationStateWrite](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface PronunciationStateWrite {\n state: 'active' | 'suggested' | 'rejected';\n}\n\n/**\n * One entry to hear, whether or not the lexicon holds it yet\n * generated from [PronunciationSampleRequest](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface PronunciationSampleRequest {\n /** What is spoken, with this entry applied to it */\n written: string;\n /** How this entry says it. Not empty, unlike a stored entry's: an entry that drops the words has nothing to hear */\n spoken: string;\n /** A station voice name. Absent uses the plugin's own default */\n voice?: string;\n}\n\n/**\n * Which part of the lexicon to read\n * generated from [PronunciationQuery](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface PronunciationQuery {\n /** Absent is all of it */\n state?: 'active' | 'suggested' | 'rejected';\n}\n\n/**\n * Where in a break a sound may fall. `start` is before the first word, `end` after the last, and\n * `middle` anywhere between two words\n * generated from [PadPlacement](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport type PadPlacement = 'start' | 'middle' | 'end';\n\n/**\n * A sound arriving from the browser, as multipart form parts.\n *\n * Documentation rather than validation: a multipart body reaches the service as the raw parser and\n * the generated client types the body as `FormData`, so nothing checks this shape. It says what to\n * send\n * generated from [PadUpload](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface PadUpload {\n /** The audio itself. mp3, wav, ogg, flac or m4a, and at most 25 MB */\n file: Blob;\n /** The directory it is filed under, which is also the set it joins. A new name makes both */\n board: string;\n /** What a script will write. Derived from the filename when absent, and the FILE is named after this either way */\n name?: string;\n /** What the console calls it. Derived from the filename when absent */\n label?: string;\n}\n\n/**\n * A sound the station is being told to go and get.\n *\n * The operator names the address, so this is them choosing a file exactly as dropping one in the\n * library is. Nothing inspects what comes back and nothing records a claim about its licence -- see\n * `docs/internals/render.md` under \"Pads\", whose line is redistribution rather than use\n * generated from [PadFetch](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface PadFetch {\n /** Where the audio is. Followed once, bounded, and refused unless what comes back is a format the station serves */\n url: string;\n /** The directory it is filed under, which is also the set it joins */\n board: string;\n /** What a script will write. Derived from the address when absent */\n name?: string;\n label?: string;\n}\n\n/**\n * A named collection of pads: what a presenter is actually handed.\n *\n * One library, cut as many ways as an operator likes. `personas.soundboard` holds the `key`, so\n * renaming a set unpoints every persona naming it — which is why `personas` says who those are\n * generated from [PadSet](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface PadSet {\n id: string;\n /** The slug a persona names. A directory in the pad library makes one of these */\n key: string;\n label: string;\n position: number;\n /** How many sounds are on it. Zero is ordinary: it is what a set looks like before anybody drops a file */\n pads: number;\n /** Who is pointed at it, so a rename or a delete can say what it is about to unpoint */\n personas: string[];\n}\n\nexport interface PadSetInput {\n /** The slug a persona names. A directory in the pad library makes one of these */\n key: string;\n label: string;\n position: number;\n}\n\n/**\n * A set an operator is naming, or renaming\n * generated from [PadSetWrite](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface PadSetWrite {\n key: string;\n label: string;\n position?: number;\n}\n\n/**\n * Which pad, and whether it is on the set\n * generated from [PadSetMembership](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface PadSetMembership {\n padId: string;\n on: boolean;\n}\n\n/**\n * Turning a pad down, or putting one back\n * generated from [PadState](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface PadState {\n state: 'active' | 'rejected';\n}\n\n/**\n * What one pass over the pad library did\n * generated from [PadScanResult](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface PadScanResult {\n /** Audio files seen, whether or not anything changed */\n scanned: number;\n /** Sounds the station did not have before */\n imported: number;\n /** Slots whose file changed under them, which every script naming them now plays */\n replaced: number;\n /** Sounds that reached the library but not their set, because it already answered to their name. In the library and unreachable until somebody says where they go */\n contested: number;\n /** Files passed over: not audio, unreadable, or named something no script could write */\n skipped: number;\n}\n\n/**\n * Which copy of a segment's audio. `original` is what the station airs. `share` is a small copy made for a listener to send on, AAC in an .m4a, never aired\n * generated from [SegmentAudioRendition](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport type SegmentAudioRendition = 'original' | 'share';\n\n/**\n * Everything the station can play that is not a record\n * generated from [SegmentList](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface SegmentList {\n segments: Segment[];\n}\n\n/**\n * The voices the station's current speech plugin offers\n * generated from [VoiceList](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface VoiceList {\n voices: Voice[];\n /** Which plugin answered. Absent when nothing can speak */\n pluginId?: string;\n /** Why there are no voices, when there are none */\n reason?: string;\n /** Which readings that plugin can perform right now, out of `hushed` and `frantic`. Absent or empty means none, which is most engines and is not a fault */\n deliveries?: string[];\n}\n\n/**\n * One page of what the station has written, newest first\n * generated from [ScriptHistoryQuery](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface ScriptHistoryQuery {\n limit?: number;\n /** Where the previous page ended. Opaque, and a keyset rather than an offset because rows arrive at the head continuously. Pass back whatever `nextBefore` said and nothing else */\n before?: string;\n kind?: string;\n writer?: string;\n outcome?: ScriptOutcome;\n /** Everything ONE character has said. Absent is every character and none */\n personaKey?: string;\n /** Every attempt made for ONE break, which is how a console reaches the words behind an item of the running order. Absent is the whole history */\n segmentId?: string;\n}\n\n/**\n * One attempt to write something the station would say, including the ones that came to nothing\n * generated from [ScriptAttempt](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface ScriptAttempt {\n id: string;\n at: DateTime;\n /** What sort of break it was for: `talkbreak`, `welcome`, `news` */\n kind: string;\n /** The binding that produced or declined it */\n writer: string;\n outcome: ScriptOutcome;\n /** Who was presenting, as the persona's own key. Absent means nobody was, which is an ordinary state. Stamped on every attempt including the declined ones, so a character whose model breaks are all being refused is visible rather than hidden behind the floor */\n personaKey?: string;\n label?: string;\n /** The words. Absent for an attempt that produced none */\n script?: string;\n /** How the writer chose to have the words read, `hushed` or `frantic`. Absent for an ordinary reading */\n delivery?: string;\n /** The model that said it, for a writer that used one */\n model?: string;\n /** What the line was rendered from, for a writer working from something an operator can edit */\n source?: string;\n /** Why, for anything that is not `written` */\n reason?: string;\n /** The segment this was for, while it is still known. The row outlives it */\n segmentId?: string;\n previous?: ScriptNeighbour;\n next?: ScriptNeighbour;\n /** How long the attempt took */\n durationMs?: number;\n usage?: ScriptUsage;\n /** The answer before anything read it. Only while `llm.captureWrites` is on */\n raw?: string;\n /** What the writer sent. Only while `llm.captureWrites` is on */\n prompt?: ScriptPromptMessage[];\n /** What the operator thought of it. ABSENT means nobody has said, which `neutral` does not */\n rating?: ScriptRating;\n}\n\nexport interface ScriptAttemptInput {\n id: string;\n at: DateTime;\n /** What sort of break it was for: `talkbreak`, `welcome`, `news` */\n kind: string;\n /** The binding that produced or declined it */\n writer: string;\n outcome: ScriptOutcome;\n /** Who was presenting, as the persona's own key. Absent means nobody was, which is an ordinary state. Stamped on every attempt including the declined ones, so a character whose model breaks are all being refused is visible rather than hidden behind the floor */\n personaKey?: string;\n label?: string;\n /** The words. Absent for an attempt that produced none */\n script?: string;\n /** How the writer chose to have the words read, `hushed` or `frantic`. Absent for an ordinary reading */\n delivery?: string;\n /** The model that said it, for a writer that used one */\n model?: string;\n /** What the line was rendered from, for a writer working from something an operator can edit */\n source?: string;\n /** Why, for anything that is not `written` */\n reason?: string;\n /** The segment this was for, while it is still known. The row outlives it */\n segmentId?: string;\n previous?: ScriptNeighbour;\n next?: ScriptNeighbour;\n /** How long the attempt took */\n durationMs?: number;\n usage?: ScriptUsage;\n /** The answer before anything read it. Only while `llm.captureWrites` is on */\n raw?: string;\n /** What the writer sent. Only while `llm.captureWrites` is on */\n prompt?: ScriptPromptMessage[];\n}\n\n/** Rehydrates every wire-encoded scalar in a ScriptAttempt into its runtime type. Mutates and returns `raw`. */\nexport function reviveScriptAttempt(raw: ScriptAttempt): ScriptAttempt {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['at'] = __dt(__o0['at'], 'ScriptAttempt.at');\n return raw;\n}\n\n/**\n * generated from [ScriptRatingInput](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface ScriptRatingInput {\n rating: ScriptRating;\n}\n\n/**\n * What each presenter has written lately, and over how long\n * generated from [ScriptHistorySummary](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface ScriptHistorySummary {\n /** The window actually counted, echoed so a console can label the numbers it draws */\n hours: number;\n rows: ScriptHistorySummaryRow[];\n}\n\n/**\n * The station's lexicon, oldest first\n * generated from [PronunciationList](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface PronunciationList {\n pronunciations: Pronunciation[];\n}\n\n/**\n * One sound on a soundboard, as the console draws it.\n *\n * `name` is what a script writes to hit it and `label` is what a person reads: two columns rather\n * than one, because a token for a model and prose for an operator are different things and the\n * filename produces both\n * generated from [Pad](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface Pad {\n id: string;\n /** Which directory it arrived in. Provenance: what reaches it is a set */\n board: string;\n /** The keys of the sets it is on. Empty means it is in the library and nothing can hit it */\n sets: string[];\n /** What a script writes: `[sfx:airhorn]` */\n name: string;\n label: string;\n durationMs?: number;\n /** How loud it came out, once something measured it. Absent on a station with no analyzer, which is ordinary */\n loudnessLufs?: number;\n /** Who put the file there: `library` for one the operator dropped in, `upload` or `url` for one the console wrote. It decides whether the console may delete it */\n source: string;\n /** The file in the library directory it was imported from, so the console can say where it came from */\n sourcePath?: string;\n /** When it was last hit. Absent for one nothing has reached for yet */\n lastUsedAt?: DateTime;\n state: 'active' | 'rejected';\n /** Where in a break it may land: before the first word, between two, or after the last. Every pad starts with all three */\n placements: PadPlacement[];\n /** When to reach for it, in the operator's words (\"right after a punchline\"). Shown to the presenter beside the sound; the station's own writers leave a cued pad alone */\n cue?: string;\n}\n\nexport interface PadInput {\n /** Which directory it arrived in. Provenance: what reaches it is a set */\n board: string;\n /** What a script writes: `[sfx:airhorn]` */\n name: string;\n label: string;\n durationMs?: number;\n /** How loud it came out, once something measured it. Absent on a station with no analyzer, which is ordinary */\n loudnessLufs?: number;\n /** The file in the library directory it was imported from, so the console can say where it came from */\n sourcePath?: string;\n /** When it was last hit. Absent for one nothing has reached for yet */\n lastUsedAt?: DateTime;\n state: 'active' | 'rejected';\n /** Where in a break it may land: before the first word, between two, or after the last. Every pad starts with all three */\n placements: PadPlacement[];\n /** When to reach for it, in the operator's words (\"right after a punchline\"). Shown to the presenter beside the sound; the station's own writers leave a cued pad alone */\n cue?: string;\n}\n\n/** Rehydrates every wire-encoded scalar in a Pad into its runtime type. Mutates and returns `raw`. */\nexport function revivePad(raw: Pad): Pad {\n const __o0 = raw as unknown as Record<string, unknown>;\n if (__o0['lastUsedAt'] != null) {\n __o0['lastUsedAt'] = __dt(__o0['lastUsedAt'], 'Pad.lastUsedAt');\n }\n return raw;\n}\n\n/**\n * Where and when a pad may be hit, written together because the console edits them together\n * generated from [PadUse](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface PadUse {\n /** At least one: a sound that may go nowhere is a sound turned down, which is what `PadState` is for */\n placements: PadPlacement[];\n /** Absent clears it, so the pad is fair game wherever its placements allow */\n cue?: string;\n}\n\n/**\n * generated from [SegmentAudioQuery](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface SegmentAudioQuery {\n /** A purpose the station interprets rather than a format the caller picks, so what `share` means can change without any caller changing */\n rendition?: SegmentAudioRendition;\n}\n\n/**\n * generated from [ScriptHistoryPage](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface ScriptHistoryPage {\n attempts: ScriptAttempt[];\n /** The cursor for the page after this one, absent once the history has been read to its end */\n nextBefore?: string;\n}\n\nexport interface ScriptHistoryPageInput {\n attempts: ScriptAttemptInput[];\n /** The cursor for the page after this one, absent once the history has been read to its end */\n nextBefore?: string;\n}\n\n/** Rehydrates every wire-encoded scalar in a ScriptHistoryPage into its runtime type. Mutates and returns `raw`. */\nexport function reviveScriptHistoryPage(raw: ScriptHistoryPage): ScriptHistoryPage {\n const __o0 = raw as unknown as Record<string, unknown>;\n {\n const __a1 = __o0['attempts'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveScriptAttempt(__a1[__i2] as never);\n }\n }\n return raw;\n}\n\n/**\n * Every sound the station holds, and the sets over it\n * generated from [PadList](../../../../../apps/api/data/contracts/render/render.types.ck)\n */\nexport interface PadList {\n pads: Pad[];\n sets: PadSet[];\n}\n\nexport interface PadListInput {\n pads: PadInput[];\n sets: PadSetInput[];\n}\n\n/** Rehydrates every wire-encoded scalar in a PadList into its runtime type. Mutates and returns `raw`. */\nexport function revivePadList(raw: PadList): PadList {\n const __o0 = raw as unknown as Record<string, unknown>;\n {\n const __a1 = __o0['pads'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n revivePad(__a1[__i2] as never);\n }\n }\n return raw;\n}\n","import type { SdkFetch } from '../sdk-options.js';\nimport { bigIntReplacer, parseJson, buildQueryString, readContentType } from '../sdk-options.js';\nimport type {\n PadFetch,\n PadList,\n PadScanResult,\n PadSetMembership,\n PadSetWrite,\n PadState,\n PadUse,\n PronunciationList,\n PronunciationQuery,\n PronunciationSampleRequest,\n PronunciationStateWrite,\n PronunciationWrite,\n ScriptAttempt,\n ScriptHistoryPage,\n ScriptHistoryQuery,\n ScriptHistorySummary,\n ScriptHistorySummaryQuery,\n ScriptRatingInput,\n Segment,\n SegmentAudioQuery,\n SegmentCreate,\n SegmentList,\n SegmentScanResult,\n SpeechPreviewRequest,\n VoiceList,\n} from './types/render.types.js';\nimport { revivePadList, reviveScriptAttempt, reviveScriptHistoryPage } from './types/render.types.js';\n\nexport class RenderClient {\n constructor(private fetch: SdkFetch) {}\n\n /**\n * @name List segments\n * @description Everything the station can play that is not a record\n */\n async listSegments(): Promise<SegmentList> {\n const result = await this.fetch(`/segments`, { method: 'GET' });\n return await parseJson<SegmentList>(result);\n }\n\n /**\n * @name Create segment\n * @description Plans something for the station to say, and starts rendering it\n */\n async createSegment(body: SegmentCreate): Promise<Segment> {\n const result = await this.fetch(`/segments`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<Segment>(result);\n }\n\n /**\n * @name Upload segment\n * @description Takes a recording in from the browser and puts it in the library, ready to air\n */\n async uploadSegment(body: FormData): Promise<Segment> {\n const result = await this.fetch(`/segments/upload`, {\n method: 'POST',\n body: body,\n });\n return await parseJson<Segment>(result);\n }\n\n /**\n * @name Scan the segment inbox\n * @description Takes whatever audio is sitting in the inbox directory into the library. Safe to repeat: a segment is identified by its audio, so the same recording arriving twice is one segment\n */\n async scanTheSegmentInbox(): Promise<SegmentScanResult> {\n const result = await this.fetch(`/segments/scan`, { method: 'POST' });\n return await parseJson<SegmentScanResult>(result);\n }\n\n /**\n * @name Read script history\n * @description What the station has written lately, newest first, one page at a time\n */\n async readScriptHistory(query?: ScriptHistoryQuery): Promise<ScriptHistoryPage> {\n const qs = buildQueryString(query);\n const result = await this.fetch(`/scripts${qs}`, {\n method: 'GET',\n });\n return reviveScriptHistoryPage(await parseJson<ScriptHistoryPage>(result));\n }\n\n /**\n * @name Rate script\n * @description What the operator thought of this attempt. Nothing acts on it automatically\n */\n async rateScript(id: string, body: ScriptRatingInput): Promise<ScriptAttempt> {\n const result = await this.fetch(`/scripts/${encodeURIComponent(id)}/rating`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return reviveScriptAttempt(await parseJson<ScriptAttempt>(result));\n }\n\n /**\n * @name Read script summary\n * @description Write attempts by outcome, per presenter, over a recent window\n */\n async readScriptSummary(query?: ScriptHistorySummaryQuery): Promise<ScriptHistorySummary> {\n const qs = buildQueryString(query);\n const result = await this.fetch(`/scripts/summary${qs}`, {\n method: 'GET',\n });\n return await parseJson<ScriptHistorySummary>(result);\n }\n\n /**\n * @name List voices\n * @description The voices the station can be asked to speak in\n */\n async listVoices(): Promise<VoiceList> {\n const result = await this.fetch(`/voices`, { method: 'GET' });\n return await parseJson<VoiceList>(result);\n }\n\n /**\n * @name Get default voice sample\n * @description A short line spoken in whichever voice the plugin falls back to\n */\n async getDefaultVoiceSample(): Promise<\n | {\n status: 200;\n contentType: 'audio/mpeg' | 'audio/wav' | 'audio/ogg' | 'audio/flac' | 'audio/mp4';\n data: Blob;\n headers: { cacheControl?: string; etag?: string };\n }\n | { status: 304 }\n > {\n const result = await this.fetch(`/voices/sample`, {\n method: 'GET',\n expectStatuses: [304],\n });\n switch (result.status) {\n case 304:\n return { status: 304 };\n default:\n return {\n status: 200,\n contentType: readContentType(result) as 'audio/mpeg' | 'audio/wav' | 'audio/ogg' | 'audio/flac' | 'audio/mp4',\n data: await result.blob(),\n headers: { cacheControl: result.headers.get('cache-control') ?? undefined, etag: result.headers.get('etag') ?? undefined },\n };\n }\n }\n\n /**\n * @name Get voice sample\n * @description A short line spoken in one voice, so an operator can hear it before choosing it\n */\n async getVoiceSample(voiceId: string): Promise<\n | {\n status: 200;\n contentType: 'audio/mpeg' | 'audio/wav' | 'audio/ogg' | 'audio/flac' | 'audio/mp4';\n data: Blob;\n headers: { cacheControl?: string; etag?: string };\n }\n | { status: 304 }\n > {\n const result = await this.fetch(`/voices/${encodeURIComponent(voiceId)}/sample`, {\n method: 'GET',\n expectStatuses: [304],\n });\n switch (result.status) {\n case 304:\n return { status: 304 };\n default:\n return {\n status: 200,\n contentType: readContentType(result) as 'audio/mpeg' | 'audio/wav' | 'audio/ogg' | 'audio/flac' | 'audio/mp4',\n data: await result.blob(),\n headers: { cacheControl: result.headers.get('cache-control') ?? undefined, etag: result.headers.get('etag') ?? undefined },\n };\n }\n }\n\n /**\n * @name Preview speech\n * @description Speaks the caller's words in one voice, so a break can be heard before it is written for air\n */\n async previewSpeech(\n body: SpeechPreviewRequest,\n ): Promise<{ contentType: 'audio/mpeg' | 'audio/wav' | 'audio/ogg' | 'audio/flac' | 'audio/mp4'; data: Blob }> {\n const result = await this.fetch(`/voices/preview`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return {\n contentType: readContentType(result) as 'audio/mpeg' | 'audio/wav' | 'audio/ogg' | 'audio/flac' | 'audio/mp4',\n data: await result.blob(),\n };\n }\n\n /**\n * @name Delete segment\n * @description Removes a recording and the inbox file behind it, so the next scan does not read it back in\n */\n async deleteSegment(id: string): Promise<SegmentList> {\n const result = await this.fetch(`/segments/${encodeURIComponent(id)}`, { method: 'DELETE' });\n return await parseJson<SegmentList>(result);\n }\n\n /**\n * @name Get segment audio\n * @description The audio of one segment\n */\n async getSegmentAudio(\n id: string,\n query?: SegmentAudioQuery,\n ): Promise<\n | {\n status: 200;\n contentType: 'audio/mpeg' | 'audio/wav' | 'audio/ogg' | 'audio/flac' | 'audio/mp4';\n data: Blob;\n headers: { cacheControl?: string; etag?: string; contentDisposition?: string };\n }\n | { status: 304 }\n > {\n const qs = buildQueryString(query);\n const result = await this.fetch(`/segments/${encodeURIComponent(id)}/audio${qs}`, {\n method: 'GET',\n expectStatuses: [304],\n });\n switch (result.status) {\n case 304:\n return { status: 304 };\n default:\n return {\n status: 200,\n contentType: readContentType(result) as 'audio/mpeg' | 'audio/wav' | 'audio/ogg' | 'audio/flac' | 'audio/mp4',\n data: await result.blob(),\n headers: {\n cacheControl: result.headers.get('cache-control') ?? undefined,\n etag: result.headers.get('etag') ?? undefined,\n contentDisposition: result.headers.get('content-disposition') ?? undefined,\n },\n };\n }\n }\n\n /**\n * @name Get stored audio\n * @description Audio out of the segment store, addressed by content rather than by row\n */\n async getStoredAudio(\n checksum: string,\n ext: string,\n ): Promise<\n | {\n status: 200;\n contentType: 'audio/mpeg' | 'audio/wav' | 'audio/ogg' | 'audio/flac' | 'audio/mp4';\n data: Blob;\n headers: { cacheControl?: string; etag?: string };\n }\n | { status: 304 }\n > {\n const result = await this.fetch(`/audio/${encodeURIComponent(checksum)}/${encodeURIComponent(ext)}`, {\n method: 'GET',\n expectStatuses: [304],\n });\n switch (result.status) {\n case 304:\n return { status: 304 };\n default:\n return {\n status: 200,\n contentType: readContentType(result) as 'audio/mpeg' | 'audio/wav' | 'audio/ogg' | 'audio/flac' | 'audio/mp4',\n data: await result.blob(),\n headers: { cacheControl: result.headers.get('cache-control') ?? undefined, etag: result.headers.get('etag') ?? undefined },\n };\n }\n }\n\n /**\n * @name List pronunciations\n * @description The station's lexicon: what it says, what has been proposed to it, and what it has turned down\n */\n async listPronunciations(query?: PronunciationQuery): Promise<PronunciationList> {\n const qs = buildQueryString(query);\n const result = await this.fetch(`/pronunciations${qs}`, {\n method: 'GET',\n });\n return await parseJson<PronunciationList>(result);\n }\n\n /**\n * @name Create pronunciation\n * @description Adds one the operator typed. It is said from the next render on\n */\n async createPronunciation(body: PronunciationWrite): Promise<PronunciationList> {\n const result = await this.fetch(`/pronunciations`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<PronunciationList>(result);\n }\n\n /**\n * @name Sample pronunciation\n * @description Speaks the written word as this entry says it, in one voice\n */\n async samplePronunciation(\n body: PronunciationSampleRequest,\n ): Promise<{ contentType: 'audio/mpeg' | 'audio/wav' | 'audio/ogg' | 'audio/flac' | 'audio/mp4'; data: Blob }> {\n const result = await this.fetch(`/pronunciations/sample`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return {\n contentType: readContentType(result) as 'audio/mpeg' | 'audio/wav' | 'audio/ogg' | 'audio/flac' | 'audio/mp4',\n data: await result.blob(),\n };\n }\n\n /**\n * @name Update pronunciation\n * @description Rewrites one entry's words, whoever proposed it\n */\n async updatePronunciation(id: string, body: PronunciationWrite): Promise<PronunciationList> {\n const result = await this.fetch(`/pronunciations/${encodeURIComponent(id)}`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<PronunciationList>(result);\n }\n\n /**\n * @name Delete pronunciation\n * @description Removes an entry outright. Turning a PROPOSAL down is a state rather than a deletion, because a deleted one comes back on the next pass\n */\n async deletePronunciation(id: string): Promise<PronunciationList> {\n const result = await this.fetch(`/pronunciations/${encodeURIComponent(id)}`, { method: 'DELETE' });\n return await parseJson<PronunciationList>(result);\n }\n\n /**\n * @name Set pronunciation state\n * @description Accepts a proposal, turns one down, or takes an entry out of use without losing what it said\n */\n async setPronunciationState(id: string, body: PronunciationStateWrite): Promise<PronunciationList> {\n const result = await this.fetch(`/pronunciations/${encodeURIComponent(id)}/state`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<PronunciationList>(result);\n }\n\n /**\n * @name List pads\n * @description Every sound the station holds, board by board\n */\n async listPads(): Promise<PadList> {\n const result = await this.fetch(`/pads`, { method: 'GET' });\n return revivePadList(await parseJson<PadList>(result));\n }\n\n /**\n * @name Upload pad\n * @description Takes a sound in from the browser and puts it on a board. The file lands in the pad library on disk, so it survives a rebuild and an archive carries it\n */\n async uploadPad(body: FormData): Promise<PadList> {\n const result = await this.fetch(`/pads`, {\n method: 'POST',\n body: body,\n });\n return revivePadList(await parseJson<PadList>(result));\n }\n\n /**\n * @name Scan the pad library\n * @description Takes whatever audio is sitting in the pad library directory onto its board. Safe to repeat: a file nobody has touched is seen and left alone\n */\n async scanThePadLibrary(): Promise<PadScanResult> {\n const result = await this.fetch(`/pads/scan`, { method: 'POST' });\n return await parseJson<PadScanResult>(result);\n }\n\n /**\n * @name Fetch pad\n * @description Fetches a sound from an address and puts it on a board. The operator names the address, so this is them choosing a file exactly as dropping one in the library is\n */\n async fetchPad(body: PadFetch): Promise<PadList> {\n const result = await this.fetch(`/pads/fetch`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return revivePadList(await parseJson<PadList>(result));\n }\n\n /**\n * @name Delete pad\n * @description Removes a sound the console put there, and the file it wrote for it\n */\n async deletePad(id: string): Promise<PadList> {\n const result = await this.fetch(`/pads/${encodeURIComponent(id)}`, { method: 'DELETE' });\n return revivePadList(await parseJson<PadList>(result));\n }\n\n /**\n * @name Set pad state\n * @description Turns a sound down, or puts one back. Answers the whole rack, since one pad changing state is one row moving between two sections of the same page\n */\n async setPadState(id: string, body: PadState): Promise<PadList> {\n const result = await this.fetch(`/pads/${encodeURIComponent(id)}/state`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return revivePadList(await parseJson<PadList>(result));\n }\n\n /**\n * @name Set pad use\n * @description Says where in a break a sound may land and when to reach for it. Answers the whole rack\n */\n async setPadUse(id: string, body: PadUse): Promise<PadList> {\n const result = await this.fetch(`/pads/${encodeURIComponent(id)}/use`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return revivePadList(await parseJson<PadList>(result));\n }\n\n /**\n * @name Get pad audio\n * @description The sound itself, so an operator can hear what they dropped in\n */\n async getPadAudio(id: string): Promise<\n | {\n status: 200;\n contentType: 'audio/mpeg' | 'audio/wav' | 'audio/ogg' | 'audio/flac' | 'audio/mp4';\n data: Blob;\n headers: { cacheControl?: string; etag?: string };\n }\n | { status: 304 }\n > {\n const result = await this.fetch(`/pads/${encodeURIComponent(id)}/audio`, {\n method: 'GET',\n expectStatuses: [304],\n });\n switch (result.status) {\n case 304:\n return { status: 304 };\n default:\n return {\n status: 200,\n contentType: readContentType(result) as 'audio/mpeg' | 'audio/wav' | 'audio/ogg' | 'audio/flac' | 'audio/mp4',\n data: await result.blob(),\n headers: { cacheControl: result.headers.get('cache-control') ?? undefined, etag: result.headers.get('etag') ?? undefined },\n };\n }\n }\n\n /**\n * @name Create pad set\n * @description Names a new set, or answers the one already under that key\n */\n async createPadSet(body: PadSetWrite): Promise<PadList> {\n const result = await this.fetch(`/pads/sets`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return revivePadList(await parseJson<PadList>(result));\n }\n\n /**\n * @name Update pad set\n * @description Renames a set. The KEY moves with it, so every persona naming the old one stops finding it\n */\n async updatePadSet(id: string, body: PadSetWrite): Promise<PadList> {\n const result = await this.fetch(`/pads/sets/${encodeURIComponent(id)}`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return revivePadList(await parseJson<PadList>(result));\n }\n\n /**\n * @name Delete pad set\n * @description Removes a set and its memberships, and no pads at all\n */\n async deletePadSet(id: string): Promise<PadList> {\n const result = await this.fetch(`/pads/sets/${encodeURIComponent(id)}`, { method: 'DELETE' });\n return revivePadList(await parseJson<PadList>(result));\n }\n\n /**\n * @name Set pad membership\n * @description Puts a pad on a set or takes it off. Refused where the set already answers to that name, because a script writes a name\n */\n async setPadMembership(id: string, body: PadSetMembership): Promise<PadList> {\n const result = await this.fetch(`/pads/sets/${encodeURIComponent(id)}/pads`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return revivePadList(await parseJson<PadList>(result));\n }\n}\n","import { DateTime } from 'luxon';\nconst __dt = (v: unknown, path: string): DateTime => {\n if (typeof v !== 'string') {\n throw new TypeError(`ContractKit: expected an ISO 8601 string at '${path}', received ${typeof v}.`);\n }\n const d = DateTime.fromISO(v);\n if (!d.isValid) throw new TypeError(`ContractKit: '${v}' at '${path}' is not a valid ISO 8601 datetime.`);\n return d;\n};\n\n/**\n * A music provider's copy of a record the station has not taken in yet\n * generated from [RequestableSource](../../../../../apps/api/data/contracts/requests/requests.types.ck)\n */\nexport interface RequestableSource {\n /** The plugin that carries it */\n pluginId: string;\n /** That plugin's own id for the record */\n externalId: string;\n}\n\n/**\n * generated from [RequestStatus](../../../../../apps/api/data/contracts/requests/requests.types.ck)\n */\nexport type RequestStatus = 'waiting' | 'pending' | 'queued' | 'aired' | 'declined' | 'expired';\n\n/**\n * generated from [RequestSource](../../../../../apps/api/data/contracts/requests/requests.types.ck)\n */\nexport type RequestSource = 'app' | 'chat';\n\n/**\n * Turn a request down\n * generated from [ListenerRequestDecline](../../../../../apps/api/data/contracts/requests/requests.types.ck)\n */\nexport interface ListenerRequestDecline {\n /** What to tell the listener. Omit for a plain no */\n reason?: string;\n}\n\n/**\n * A party: the pass guests join with by scanning its QR code, for as long as it lasts\n * generated from [PartyPass](../../../../../apps/api/data/contracts/requests/requests.types.ck)\n */\nexport interface PartyPass {\n /** The pass itself. Put it after `#` on the station's `/party` page, as `/party#<token>`, and that address is what the QR code holds. Anyone holding it can join until the party ends, so show it only to the room */\n token: string;\n /** When the party started */\n createdAt: DateTime;\n /** When the pass stops letting guests in, and turns away every guest who joined with it */\n expiresAt: DateTime;\n /** How many guests have joined with it */\n guests: number;\n}\n\n/** Rehydrates every wire-encoded scalar in a PartyPass into its runtime type. Mutates and returns `raw`. */\nexport function revivePartyPass(raw: PartyPass): PartyPass {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['createdAt'] = __dt(__o0['createdAt'], 'PartyPass.createdAt');\n __o0['expiresAt'] = __dt(__o0['expiresAt'], 'PartyPass.expiresAt');\n return raw;\n}\n\n/**\n * Start a party\n * generated from [PartyStart](../../../../../apps/api/data/contracts/requests/requests.types.ck)\n */\nexport interface PartyStart {\n /** How long the pass lasts. Six when omitted */\n hours?: number;\n}\n\n/**\n * Join a party as a guest, with the pass from its QR code\n * generated from [PartyJoin](../../../../../apps/api/data/contracts/requests/requests.types.ck)\n */\nexport interface PartyJoin {\n /** The pass, as it appears after `#` in the party page's address */\n token: string;\n}\n\n/**\n * A guest's way in: send it as a bearer token on the request routes\n * generated from [PartyGuestSession](../../../../../apps/api/data/contracts/requests/requests.types.ck)\n */\nexport interface PartyGuestSession {\n /** The bearer token. It lets a guest search for records, ask for one and see their own requests, and nothing else */\n accessToken: string;\n /** When it stops working, which is when the party's pass does */\n expiresAt: DateTime;\n}\n\n/** Rehydrates every wire-encoded scalar in a PartyGuestSession into its runtime type. Mutates and returns `raw`. */\nexport function revivePartyGuestSession(raw: PartyGuestSession): PartyGuestSession {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['expiresAt'] = __dt(__o0['expiresAt'], 'PartyGuestSession.expiresAt');\n return raw;\n}\n\n/**\n * A record the station could be asked for: one it holds, or one a music provider carries\n * generated from [RequestableTrack](../../../../../apps/api/data/contracts/requests/requests.types.ck)\n */\nexport interface RequestableTrack {\n /** What to send as `trackId` to make the request. Absent for a record from a provider, which is asked for by `source` instead */\n trackId?: string;\n /** Where a record the station does not hold yet comes from. Send it as `source` to ask for it */\n source?: RequestableSource;\n /** The provider, as the station names it, for a record from one */\n sourceName?: string;\n title: string;\n /** The lead artist */\n artist: string;\n album?: string;\n year?: number;\n}\n\n/**\n * Ask the station to play a record\n * generated from [ListenerRequestCreate](../../../../../apps/api/data/contracts/requests/requests.types.ck)\n */\nexport interface ListenerRequestCreate {\n /** A record from the request search that the station holds. Send this or `source`, never both */\n trackId?: string;\n /** A record from the request search that a provider carries. The station takes it in, then decides on the request as usual */\n source?: RequestableSource;\n /** What the station should call you. Omitted, you are \"a listener\": your account's email address is never shown or read out */\n name?: string;\n /** Dedicate it to somebody. The station may say this name on air */\n dedicateTo?: string;\n /** A few words to go with it. The presenter may put them in their own words on air, and leaves out anything unfit to broadcast; the words themselves are never read out */\n message?: string;\n}\n\n/**\n * A record somebody asked the station to play, and what became of it\n * generated from [ListenerRequest](../../../../../apps/api/data/contracts/requests/requests.types.ck)\n */\nexport interface ListenerRequest {\n id: string;\n /** `waiting` for an operator to approve it, `pending` while its audio is fetched or a place is found for it, `queued` in the running order, `aired` once heard, `declined` or `expired` when it never will be */\n status: RequestStatus;\n /** The record, as it was called when it was asked for */\n title: string;\n artist: string;\n /** Who asked, by the name their account or chat platform gave */\n requesterName: string;\n /** Whether it came from an app or a chat platform */\n source: RequestSource;\n /** When it was asked for */\n createdAt: DateTime;\n /** Why it was declined or expired, in the station's words or an operator's */\n reason?: string;\n /** When it aired */\n airedAt?: DateTime;\n /** Who the listener dedicated it to */\n dedicateTo?: string;\n /** What the listener asked to have said with it, in their own words */\n message?: string;\n /** True when a guest at a party asked for it, through the party pass. Absent otherwise */\n fromParty?: boolean;\n /** True on a declined request whoever asked may still insist on, with `POST /requests/{id}/insist`: the station turned it down for its own taste (aired lately, a cooldown, a dislike, the period, a length) rather than a rule nobody overrules. Absent otherwise, and once it has been insisted on */\n overrulable?: boolean;\n /** True when whoever asked insisted on it after the station turned it down, so the station's own taste was overruled. Absent otherwise */\n insisted?: boolean;\n}\n\n/** Rehydrates every wire-encoded scalar in a ListenerRequest into its runtime type. Mutates and returns `raw`. */\nexport function reviveListenerRequest(raw: ListenerRequest): ListenerRequest {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['createdAt'] = __dt(__o0['createdAt'], 'ListenerRequest.createdAt');\n if (__o0['airedAt'] != null) {\n __o0['airedAt'] = __dt(__o0['airedAt'], 'ListenerRequest.airedAt');\n }\n return raw;\n}\n\n/**\n * The party, if one is on\n * generated from [PartyState](../../../../../apps/api/data/contracts/requests/requests.types.ck)\n */\nexport interface PartyState {\n /** Absent when no party is on */\n party?: PartyPass;\n}\n\n/** Rehydrates every wire-encoded scalar in a PartyState into its runtime type. Mutates and returns `raw`. */\nexport function revivePartyState(raw: PartyState): PartyState {\n const __o0 = raw as unknown as Record<string, unknown>;\n if (__o0['party'] != null) {\n revivePartyPass(__o0['party'] as never);\n }\n return raw;\n}\n\n/**\n * Records matching a search, best matches first, the station's own before any a provider carries\n * generated from [RequestableTrackList](../../../../../apps/api/data/contracts/requests/requests.types.ck)\n */\nexport interface RequestableTrackList {\n tracks: RequestableTrack[];\n}\n\n/**\n * Requests, newest first\n * generated from [ListenerRequestList](../../../../../apps/api/data/contracts/requests/requests.types.ck)\n */\nexport interface ListenerRequestList {\n requests: ListenerRequest[];\n}\n\n/** Rehydrates every wire-encoded scalar in a ListenerRequestList into its runtime type. Mutates and returns `raw`. */\nexport function reviveListenerRequestList(raw: ListenerRequestList): ListenerRequestList {\n const __o0 = raw as unknown as Record<string, unknown>;\n {\n const __a1 = __o0['requests'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveListenerRequest(__a1[__i2] as never);\n }\n }\n return raw;\n}\n","import type { PartyGuestSession, PartyJoin, PartyPass, PartyStart, PartyState } from './types/requests.types.js';\nimport { revivePartyGuestSession, revivePartyPass, revivePartyState } from './types/requests.types.js';\nimport type { SdkFetch } from '../sdk-options.js';\nimport { bigIntReplacer, parseJson } from '../sdk-options.js';\n\n/**\n * generated from [requests.party.ck](../../../../apps/api/data/contracts/requests/requests.party.ck)\n */\nexport class RequestsPartyClient {\n constructor(private fetch: SdkFetch) {}\n\n /**\n * @name Get party\n * @description The party that is on, with its pass, so the console can show the QR code again\n */\n async getParty(): Promise<PartyState> {\n const result = await this.fetch(`/party`, { method: 'GET' });\n return revivePartyState(await parseJson<PartyState>(result));\n }\n\n /**\n * @name Start party\n * @description Start a party. A party already on is ended first, which turns its guests away, so there is only ever one pass to scan\n */\n async startParty(body: PartyStart): Promise<PartyPass> {\n const result = await this.fetch(`/party`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return revivePartyPass(await parseJson<PartyPass>(result));\n }\n\n /**\n * @name End party\n * @description End the party. Its pass stops working and every guest who joined with it is turned away on their next request\n */\n async endParty(): Promise<void> {\n await this.fetch(`/party`, { method: 'DELETE' });\n }\n\n /**\n * @name Join party\n * @description Join the party as a guest. Answers 404 for a pass that is unknown, ended or run out, without saying which\n */\n async joinParty(body: PartyJoin): Promise<PartyGuestSession> {\n const result = await this.fetch(`/party/join`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return revivePartyGuestSession(await parseJson<PartyGuestSession>(result));\n }\n}\n","import type { SdkFetch } from '../sdk-options.js';\nimport { bigIntReplacer, parseJson, buildQueryString } from '../sdk-options.js';\nimport type {\n ListenerRequest,\n ListenerRequestCreate,\n ListenerRequestDecline,\n ListenerRequestList,\n RequestStatus,\n RequestableTrackList,\n} from './types/requests.types.js';\nimport { reviveListenerRequest, reviveListenerRequestList } from './types/requests.types.js';\nimport { RequestsPartyClient } from './requests.party.client.js';\n\nexport class RequestsClient {\n readonly party: RequestsPartyClient;\n\n constructor(private fetch: SdkFetch) {\n this.party = new RequestsPartyClient(fetch);\n }\n\n /**\n * @name Search requestable records\n * @description Records the station could be asked to play, matching a title or an artist, then what the music providers carry in the room left\n */\n async searchRequestableRecords(query: { q: string; limit?: number }): Promise<RequestableTrackList> {\n const qs = buildQueryString(query);\n const result = await this.fetch(`/requests/search${qs}`, {\n method: 'GET',\n });\n return await parseJson<RequestableTrackList>(result);\n }\n\n /**\n * @name List requests\n * @description Every recent request, for the operator deciding on them\n */\n async listRequests(query?: { status?: RequestStatus }): Promise<ListenerRequestList> {\n const qs = buildQueryString(query);\n const result = await this.fetch(`/requests${qs}`, {\n method: 'GET',\n });\n return reviveListenerRequestList(await parseJson<ListenerRequestList>(result));\n }\n\n /**\n * @name Create request\n * @description Ask the station to play a record. Answers with the request whatever became of it, so a refusal says why in `reason`\n */\n async createRequest(body: ListenerRequestCreate): Promise<ListenerRequest> {\n const result = await this.fetch(`/requests`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return reviveListenerRequest(await parseJson<ListenerRequest>(result));\n }\n\n /**\n * @name List my requests\n * @description The signed-in account's own recent requests\n */\n async listMyRequests(): Promise<ListenerRequestList> {\n const result = await this.fetch(`/requests/mine`, { method: 'GET' });\n return reviveListenerRequestList(await parseJson<ListenerRequestList>(result));\n }\n\n /**\n * @name Insist on request\n * @description Ask again for a record the station turned down for its own taste, overruling it. Only your own request, only one marked `overrulable`, and only once. Answers with the NEW request this makes, decided like any other: it can still wait for an operator, or be refused for who is asking or how full the line is\n */\n async insistOnRequest(id: string): Promise<ListenerRequest> {\n const result = await this.fetch(`/requests/${encodeURIComponent(id)}/insist`, { method: 'POST' });\n return reviveListenerRequest(await parseJson<ListenerRequest>(result));\n }\n\n /**\n * @name Grant request\n * @description Let a waiting request through. It goes into the running order once its audio is here\n */\n async grantRequest(id: string): Promise<ListenerRequest> {\n const result = await this.fetch(`/requests/${encodeURIComponent(id)}/grant`, { method: 'POST' });\n return reviveListenerRequest(await parseJson<ListenerRequest>(result));\n }\n\n /**\n * @name Decline request\n * @description Turn a request down. One already in the running order is left there; take it out of the order instead\n */\n async declineRequest(id: string, body: ListenerRequestDecline): Promise<ListenerRequest> {\n const result = await this.fetch(`/requests/${encodeURIComponent(id)}/decline`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return reviveListenerRequest(await parseJson<ListenerRequest>(result));\n }\n}\n","import type { SdkFetch } from '../sdk-options.js';\nimport { bigIntReplacer, parseJson, buildQueryString } from '../sdk-options.js';\nimport type {\n ScheduleNow,\n ScheduleSlotInput,\n ScheduleSlotList,\n ScheduleTimetable,\n ScheduleTimetableQuery,\n SlotPlaylistPosition,\n} from './types/schedule.types.js';\n\nexport class ScheduleClient {\n constructor(private fetch: SdkFetch) {}\n\n /**\n * @name List schedule\n * @description Every slot in this station's schedule, earliest in the day first\n */\n async listSchedule(): Promise<ScheduleSlotList> {\n const result = await this.fetch(`/schedule`, { method: 'GET' });\n return await parseJson<ScheduleSlotList>(result);\n }\n\n /**\n * @name Create schedule slot\n * @description Adds a slot. The station does not change over until its start time comes round\n */\n async createScheduleSlot(body: ScheduleSlotInput): Promise<ScheduleSlotList> {\n const result = await this.fetch(`/schedule`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<ScheduleSlotList>(result);\n }\n\n /**\n * @name Read current slot\n * @description Which slot the clock says should be on, and which one the station is actually airing\n */\n async readCurrentSlot(): Promise<ScheduleNow> {\n const result = await this.fetch(`/schedule/current`, { method: 'GET' });\n return await parseJson<ScheduleNow>(result);\n }\n\n /**\n * @name Read timetable\n * @description The station's day as blocks, contiguous and gapless, for drawing\n */\n async readTimetable(query?: ScheduleTimetableQuery): Promise<ScheduleTimetable> {\n const qs = buildQueryString(query);\n const result = await this.fetch(`/schedule/timetable${qs}`, {\n method: 'GET',\n });\n return await parseJson<ScheduleTimetable>(result);\n }\n\n /**\n * @name Update schedule slot\n * @description Rewrites a slot. Takes effect at its next boundary rather than immediately\n */\n async updateScheduleSlot(id: string, body: ScheduleSlotInput): Promise<ScheduleSlotList> {\n const result = await this.fetch(`/schedule/${encodeURIComponent(id)}`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<ScheduleSlotList>(result);\n }\n\n /**\n * @name Delete schedule slot\n * @description Removes a slot. Whatever is on air stays on until the next slot begins\n */\n async deleteScheduleSlot(id: string): Promise<ScheduleSlotList> {\n const result = await this.fetch(`/schedule/${encodeURIComponent(id)}`, { method: 'DELETE' });\n return await parseJson<ScheduleSlotList>(result);\n }\n\n /**\n * @name Read slot playlist position\n * @description The record a slot that resumes its playlist will open on next time, or nothing when it would start from the top\n */\n async readSlotPlaylistPosition(id: string): Promise<SlotPlaylistPosition> {\n const result = await this.fetch(`/schedule/${encodeURIComponent(id)}/playlist-position`, { method: 'GET' });\n return await parseJson<SlotPlaylistPosition>(result);\n }\n\n /**\n * @name Restart slot playlist\n * @description Forgets where a slot got to in its playlist, so it starts from the top the next time it opens\n */\n async restartSlotPlaylist(id: string): Promise<void> {\n await this.fetch(`/schedule/${encodeURIComponent(id)}/playlist-position`, { method: 'DELETE' });\n }\n}\n","import type { SdkFetch } from '../sdk-options.js';\nimport { bigIntReplacer, parseJson, buildQueryString } from '../sdk-options.js';\nimport type {\n InvitationPreview,\n InvitationPreviewQuery,\n SigninProvidersCheck,\n StationSettings,\n StationSettingsInput,\n} from './types/settings.types.js';\n\nexport class SettingsClient {\n constructor(private fetch: SdkFetch) {}\n\n /**\n * @name Get settings\n * @description Every station setting, its descriptor and its current value\n */\n async getSettings(): Promise<StationSettings> {\n const result = await this.fetch(`/settings`, { method: 'GET' });\n return await parseJson<StationSettings>(result);\n }\n\n /**\n * @name Update settings\n * @description Applies a submitted settings form and answers with the settings as they now stand\n */\n async updateSettings(body: StationSettingsInput): Promise<StationSettings> {\n const result = await this.fetch(`/settings`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<StationSettings>(result);\n }\n\n /**\n * @name Check sign-in providers\n * @description Asks each identity provider in the sign-in settings for its discovery document, the way a sign-in would, and says which answered\n */\n async checkSignInProviders(): Promise<SigninProvidersCheck> {\n const result = await this.fetch(`/settings/signin/check`, { method: 'GET' });\n return await parseJson<SigninProvidersCheck>(result);\n }\n\n /**\n * @name Preview invitation\n * @description Renders the invitation email as it would be sent now, in the station's saved wording, with sample values in place of a real link, inviter and date\n */\n async previewInvitation(query?: InvitationPreviewQuery): Promise<InvitationPreview> {\n const qs = buildQueryString(query);\n const result = await this.fetch(`/settings/mail/invitation/preview${qs}`, {\n method: 'GET',\n });\n return await parseJson<InvitationPreview>(result);\n }\n}\n","import { DateTime } from 'luxon';\nconst __dt = (v: unknown, path: string): DateTime => {\n if (typeof v !== 'string') {\n throw new TypeError(`ContractKit: expected an ISO 8601 string at '${path}', received ${typeof v}.`);\n }\n const d = DateTime.fromISO(v);\n if (!d.isValid) throw new TypeError(`ContractKit: '${v}' at '${path}' is not a valid ISO 8601 datetime.`);\n return d;\n};\n\n/**\n * Five values, where `PluginLogLevel` next door has four. The plugin enum is the narrower one on\n * purpose — that is the vocabulary a plugin's own `PluginLogger` offers — while `api.log` is written\n * by `DeadairLogger`, which tees every level the app-wide `Logger` has, `trace` included. Narrowing\n * here would make a `trace` line unrepresentable in the type of the surface that reads the file it\n * is in.\n * generated from [LogLevel](../../../../../apps/api/data/contracts/station/logs.types.ck)\n */\nexport type LogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error';\n\n/**\n * One log file this install has, whether or not anything has been written to it\n * generated from [LogSource](../../../../../apps/api/data/contracts/station/logs.types.ck)\n */\nexport interface LogSource {\n /** A closed set the API owns: `api`, `liquidsoap`, `shim`. Never a path */\n id: string;\n label: string;\n /** What writes it, in a sentence, because \"shim\" means nothing to somebody who has not read the tree */\n description: string;\n /** Whether the file is there at all. A station that never ran the stream has no stream logs, which is a state rather than a fault */\n present: boolean;\n /** Whether its lines carry a level, so the console knows whether to offer the filter */\n levels: boolean;\n /** Retained size across every segment. Zero when absent */\n bytes: number;\n /** Absent when nothing has ever been written */\n lastWriteAt?: DateTime;\n}\n\n/** Rehydrates every wire-encoded scalar in a LogSource into its runtime type. Mutates and returns `raw`. */\nexport function reviveLogSource(raw: LogSource): LogSource {\n const __o0 = raw as unknown as Record<string, unknown>;\n if (__o0['lastWriteAt'] != null) {\n __o0['lastWriteAt'] = __dt(__o0['lastWriteAt'], 'LogSource.lastWriteAt');\n }\n return raw;\n}\n\n/**\n * One line, as far as it could be read back\n * generated from [LogLine](../../../../../apps/api/data/contracts/station/logs.types.ck)\n */\nexport interface LogLine {\n /** Absent on a line this API did not write, and on one of its own that did not parse */\n ts?: string;\n /** Absent for the same two reasons */\n level?: LogLevel;\n /** Must match MAX_LINE_BYTES_CEILING in apps/api/src/logging/rotating.log.store.ts. Change both together */\n text: string;\n}\n\n/**\n * generated from [LogQuery](../../../../../apps/api/data/contracts/station/logs.types.ck)\n */\nexport interface LogQuery {\n limit?: number;\n /** Ignored by a source whose lines carry no level */\n level?: LogLevel;\n}\n\n/**\n * generated from [LogSourceList](../../../../../apps/api/data/contracts/station/logs.types.ck)\n */\nexport interface LogSourceList {\n /** Every source, in a fixed order, including the ones that are not present */\n sources: LogSource[];\n}\n\n/** Rehydrates every wire-encoded scalar in a LogSourceList into its runtime type. Mutates and returns `raw`. */\nexport function reviveLogSourceList(raw: LogSourceList): LogSourceList {\n const __o0 = raw as unknown as Record<string, unknown>;\n {\n const __a1 = __o0['sources'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveLogSource(__a1[__i2] as never);\n }\n }\n return raw;\n}\n\n/**\n * generated from [LogPage](../../../../../apps/api/data/contracts/station/logs.types.ck)\n */\nexport interface LogPage {\n sourceId: string;\n /** The minimum severity that was applied. Absent when the source carries no levels, so a filter that did nothing cannot look as though it worked */\n level?: LogLevel;\n /** Whether the read hit its byte budget, so the oldest line here is not the file's first */\n truncated: boolean;\n /** Newest first, as the plugin log page, the activity feed and the script history all send */\n lines: LogLine[];\n}\n","import { DateTime } from 'luxon';\nconst __dt = (v: unknown, path: string): DateTime => {\n if (typeof v !== 'string') {\n throw new TypeError(`ContractKit: expected an ISO 8601 string at '${path}', received ${typeof v}.`);\n }\n const d = DateTime.fromISO(v);\n if (!d.isValid) throw new TypeError(`ContractKit: '${v}' at '${path}' is not a valid ISO 8601 datetime.`);\n return d;\n};\nconst __dtf = (v: unknown, path: string, fmt: string): DateTime => {\n if (typeof v !== 'string') {\n throw new TypeError(`ContractKit: expected a string at '${path}' in format ${fmt}, received ${typeof v}.`);\n }\n const d = DateTime.fromFormat(v, fmt);\n if (!d.isValid) throw new TypeError(`ContractKit: '${v}' at '${path}' does not match format ${fmt}.`);\n return d;\n};\n\n/**\n * One concrete thing an attention row is about, so the reason does not live a page away.\n *\n * The row above it counts and categorises; this names. \"4 records have no copy left that will play\"\n * is a category an operator can do nothing with until they know WHICH four and WHY each one, and\n * every one of those facts was already stored — the fetch error on `track_audio.last_error`, the\n * provider's refusal on `track_sources.playable` — and reachable only by finding the record and\n * hovering a cell on its page. This is that fact travelling with the row that counted it.\n * generated from [AttentionEvidence](../../../../../apps/api/data/contracts/station/station.types.ck)\n */\nexport interface AttentionEvidence {\n /** The thing itself, as an operator would name it: a record's title and who made it */\n label: string;\n /** Why THIS one, in the station's own sentence. The row's `detail` says what the category means; this says what happened here */\n reason: string;\n /** The page holding the whole of it. Absent where there is no page for it, which the running order can hold: a record the catalog never ingested has none */\n route?: string;\n}\n\n/**\n * One loop the station runs, and when it last came round.\n *\n * Two timestamps and no verdict, because the loop cannot supply one: a five-second reconcile and a\n * nightly sweep are both healthy and no single threshold describes both. `Heartbeat` itself takes\n * this position — it answers how long it has been and lets the reader decide — and a `stalled`\n * boolean here would be this module inventing the threshold that file deliberately refuses to.\n *\n * `lastBeat` is absent until a loop finishes its first pass, which is why `startedAt` is there: from\n * the two of them a reader can tell a loop that has never completed anything from one that stopped.\n * generated from [StationHeartbeat](../../../../../apps/api/data/contracts/station/station.types.ck)\n */\nexport interface StationHeartbeat {\n name: string;\n /** When the loop registered, which is when it was last (re)started */\n startedAt: DateTime;\n /** When it last completed a pass. Absent until it completes its first */\n lastBeat?: DateTime;\n}\n\nexport interface StationHeartbeatInput {}\n\n/** Rehydrates every wire-encoded scalar in a StationHeartbeat into its runtime type. Mutates and returns `raw`. */\nexport function reviveStationHeartbeat(raw: StationHeartbeat): StationHeartbeat {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['startedAt'] = __dt(__o0['startedAt'], 'StationHeartbeat.startedAt');\n if (__o0['lastBeat'] != null) {\n __o0['lastBeat'] = __dt(__o0['lastBeat'], 'StationHeartbeat.lastBeat');\n }\n return raw;\n}\n\n/**\n * How much of the library the station has actually looked at.\n *\n * The counts `/catalog/tracks` already answers with, lifted out of a page of rows: a check-up wants\n * the sentence \"13 of 581 measured\" without asking for thirteen tracks to get it.\n * generated from [StationBacklog](../../../../../apps/api/data/contracts/station/station.types.ck)\n */\nexport interface StationBacklog {\n total: number;\n cached: number;\n measured: number;\n}\n\nexport interface StationBacklogInput {}\n\n/**\n * Who has the station's one model slot, and how many are waiting for it.\n *\n * The model is shared by every break, every programme refill and every production, one generation at\n * a time, so a slot held for far longer than any generation takes is the station's ability to speak\n * stuck behind one answer. Nothing else exposes it.\n * generated from [StationModelHolder](../../../../../apps/api/data/contracts/station/station.types.ck)\n */\nexport interface StationModelHolder {\n /** Whose work it is: `breaking` and `air` have a deadline, `background` (a refill, a production) does not, `preview` is an operator trying something */\n priority: 'breaking' | 'air' | 'background' | 'preview';\n /** When it took the slot. Every generation is bounded at ten minutes, so a holder older than that is a stream that stopped arriving */\n heldSince: DateTime;\n /** The model plugin answering it */\n plugin?: string;\n}\n\nexport interface StationModelHolderInput {}\n\n/** Rehydrates every wire-encoded scalar in a StationModelHolder into its runtime type. Mutates and returns `raw`. */\nexport function reviveStationModelHolder(raw: StationModelHolder): StationModelHolder {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['heldSince'] = __dt(__o0['heldSince'], 'StationModelHolder.heldSince');\n return raw;\n}\n\n/**\n * One release of the station, in the words its changelog entry used\n * generated from [StationRelease](../../../../../apps/api/data/contracts/station/station.types.ck)\n */\nexport interface StationRelease {\n /** The release, as its tag names it without the leading `v` */\n version: string;\n /** The day it went out. Absent where the entry named none */\n date?: DateTime;\n /** What changed, as the Markdown of its changelog entry. Empty for a release that recorded nothing */\n notes: string;\n /** The release's page on GitHub. Present on a release this station does not contain yet, which is where its notes came from */\n url?: string;\n}\n\nexport interface StationReleaseInput {}\n\n/** Rehydrates every wire-encoded scalar in a StationRelease into its runtime type. Mutates and returns `raw`. */\nexport function reviveStationRelease(raw: StationRelease): StationRelease {\n const __o0 = raw as unknown as Record<string, unknown>;\n if (__o0['date'] != null) {\n __o0['date'] = __dtf(__o0['date'], 'StationRelease.date', 'yyyy-MM-dd');\n }\n return raw;\n}\n\n/**\n * One thing that wants the operator's attention, or the fact that nothing does\n * generated from [AttentionItem](../../../../../apps/api/data/contracts/station/station.types.ck)\n */\nexport interface AttentionItem {\n /** What this is, as a stable key: `silence`, `benchedCopies`, `noPersona`. The console groups and counts on it rather than on the sentence */\n code: string;\n /** `failure` is the station not doing its job, `warning` is something failing beside a station that is working, and `notice` is a thing nobody has set up yet. A notice is not a fault and must not be drawn as one */\n severity: 'failure' | 'warning' | 'notice';\n /** The line an operator reads first */\n title: string;\n /** The whole of it, in a sentence. Where the station already has words for a fact, these are those words rather than a second phrasing of them */\n detail: string;\n /** The console page that can do something about it */\n route: string;\n /** How many things this is about, where that is a number rather than a state */\n count?: number;\n /** The operator may accept this row as it stands, through `POST /station/attention/{code}/dismiss`. It comes back by itself when something new joins it. Absent on a row that only goes away when its cause does */\n dismissible?: boolean;\n /** A HANDFUL of the things this row is about, never all of them: this answer is polled and a row about four hundred records must not be four hundred sentences. `count` stays the true figure, and a console showing fewer than it says so */\n evidence?: AttentionEvidence[];\n}\n\n/**\n * The model slot and its queue\n * generated from [StationModel](../../../../../apps/api/data/contracts/station/station.types.ck)\n */\nexport interface StationModel {\n /** Callers queued behind whoever holds the slot */\n waiting: number;\n /** Absent while the model is free */\n holder?: StationModelHolder;\n}\n\nexport interface StationModelInput {}\n\n/** Rehydrates every wire-encoded scalar in a StationModel into its runtime type. Mutates and returns `raw`. */\nexport function reviveStationModel(raw: StationModel): StationModel {\n const __o0 = raw as unknown as Record<string, unknown>;\n if (__o0['holder'] != null) {\n reviveStationModelHolder(__o0['holder'] as never);\n }\n return raw;\n}\n\n/**\n * What this build is, and what changed in it\n * generated from [StationReleases](../../../../../apps/api/data/contracts/station/station.types.ck)\n */\nexport interface StationReleases {\n /** The newest release this build contains, read off the changelog it was built with. Present on a build that follows `main` too, where `version` on the check-up is absent: every build carries the entry of the last release merged before it. Absent only when the build carries no changelog to read */\n current?: string;\n /** Every release this build contains, newest first */\n notes: StationRelease[];\n /** Whether the station asks GitHub for newer releases, which the operator switches under Settings, Station */\n checks: boolean;\n /** When GitHub last answered. Absent until it has, and while the check is switched off */\n checkedAt?: DateTime;\n /** Releases newer than this build, newest first, each with its notes and its page. Empty when there are none, while the check is off, and until GitHub has answered */\n available: StationRelease[];\n}\n\nexport interface StationReleasesInput {}\n\n/** Rehydrates every wire-encoded scalar in a StationReleases into its runtime type. Mutates and returns `raw`. */\nexport function reviveStationReleases(raw: StationReleases): StationReleases {\n const __o0 = raw as unknown as Record<string, unknown>;\n {\n const __a1 = __o0['notes'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveStationRelease(__a1[__i2] as never);\n }\n }\n if (__o0['checkedAt'] != null) {\n __o0['checkedAt'] = __dt(__o0['checkedAt'], 'StationReleases.checkedAt');\n }\n {\n const __a3 = __o0['available'] as unknown[];\n for (let __i4 = 0; __i4 < __a3.length; __i4++) {\n reviveStationRelease(__a3[__i4] as never);\n }\n }\n return raw;\n}\n\n/**\n * Everything wrong or waiting, worst first\n * generated from [StationAttention](../../../../../apps/api/data/contracts/station/station.types.ck)\n */\nexport interface StationAttention {\n items: AttentionItem[];\n}\n\n/**\n * One reading of the machinery, for a page that assembles the station's health.\n *\n * It carries ONLY the signals nothing else exposes. Everything else a check-up shows — the\n * silence verdict, the listener count, what needs somebody, the plugin statuses, the disk — is\n * already on a contract the console reads, and composing them again here would be a second answer\n * that can disagree with the first. `/playout/status` in particular is polled every two seconds for\n * the transport strip, so asking for it a second way would be a second reading of the same fact.\n *\n * Each section is OPTIONAL and absent means that reader failed. A page saying what is wrong is the\n * worst place for one broken reader to take the whole answer down, which is the rule\n * `StationAttentionService` already works to. `revision` is the one exception and says so on its\n * own line: it cannot fail, so absent there means something else.\n *\n * The revision is on THIS contract rather than composed from `/health`, which also reports it, and\n * that is not the second-answer problem the paragraph above describes. Both read one string from one\n * place at boot, so they cannot disagree. What they differ in is who can reach them: `/health` is\n * `operation(internal)`, deliberately, so it generates no SDK method and the console cannot call it\n * — which would leave \"which build is this\" answerable only from a shell, the one thing carrying it\n * here exists to fix.\n * generated from [StationCheckup](../../../../../apps/api/data/contracts/station/station.types.ck)\n */\nexport interface StationCheckup {\n /** When this reading was taken, so a stale page cannot pass itself off as now */\n readAt: DateTime;\n /** The commit this station was built from, as the image's `org.opencontainers.image.revision` label says it. Unlike the sections below, absent is not a failed reader: it means nothing stamped this build, which is what a development tree and a hand-built image both are */\n revision?: string;\n /** The release this station is, as the image's `org.opencontainers.image.version` label says it. Absent on the same terms as `revision` and for a second reason: only a tagged build carries one, so a station following `latest` reports a commit and no version */\n version?: string;\n heartbeats?: StationHeartbeat[];\n backlog?: StationBacklog;\n model?: StationModel;\n}\n\nexport interface StationCheckupInput {}\n\n/** Rehydrates every wire-encoded scalar in a StationCheckup into its runtime type. Mutates and returns `raw`. */\nexport function reviveStationCheckup(raw: StationCheckup): StationCheckup {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['readAt'] = __dt(__o0['readAt'], 'StationCheckup.readAt');\n if (__o0['heartbeats'] != null) {\n {\n const __a1 = __o0['heartbeats'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveStationHeartbeat(__a1[__i2] as never);\n }\n }\n }\n if (__o0['model'] != null) {\n reviveStationModel(__o0['model'] as never);\n }\n return raw;\n}\n","import { DateTime } from 'luxon';\nconst __dt = (v: unknown, path: string): DateTime => {\n if (typeof v !== 'string') {\n throw new TypeError(`ContractKit: expected an ISO 8601 string at '${path}', received ${typeof v}.`);\n }\n const d = DateTime.fromISO(v);\n if (!d.isValid) throw new TypeError(`ContractKit: '${v}' at '${path}' is not a valid ISO 8601 datetime.`);\n return d;\n};\n\n/**\n * Whether a call produced what it was asked for. Two values on purpose: every finer distinction —\n * timed out, was preempted, came back empty — is a fact the caller knew and the recorder did not, so\n * it lives in `detail` where it can be named\n * generated from [TraceOutcome](../../../../../apps/api/data/contracts/station/traces.types.ck)\n */\nexport type TraceOutcome = 'ok' | 'failed';\n\n/**\n * One decision, folded: a job execution or a request\n * generated from [TraceDecision](../../../../../apps/api/data/contracts/station/traces.types.ck)\n */\nexport interface TraceDecision {\n /** The job id or the request id. Already the station's correlation id, never generated for this */\n id: string;\n /** A queue name, or a method and path */\n kind: string;\n /** The decision that enqueued this one. Absent on a request, a cron job and anything at boot */\n parent?: string;\n /** When its first recorded call ended */\n at: DateTime;\n /** Wall clock, off the `job.run` span. Zero for a decision recorded before that span existed */\n ms: number;\n /** Everything it did, not counting the `job.run` that contains them */\n calls: number;\n /** How many of those did not produce what they were asked for */\n failed: number;\n}\n\n/** Rehydrates every wire-encoded scalar in a TraceDecision into its runtime type. Mutates and returns `raw`. */\nexport function reviveTraceDecision(raw: TraceDecision): TraceDecision {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['at'] = __dt(__o0['at'], 'TraceDecision.at');\n return raw;\n}\n\n/**\n * Which slice of the kept window to read\n * generated from [TracesQuery](../../../../../apps/api/data/contracts/station/traces.types.ck)\n */\nexport interface TracesQuery {\n limit?: number;\n /** An exact queue name or route, for reading one kind of decision on its own */\n kind?: string;\n /** Only decisions carrying at least one failed call */\n failedOnly?: boolean;\n}\n\n/**\n * One call inside a decision, and what it cost\n * generated from [TraceSpan](../../../../../apps/api/data/contracts/station/traces.types.ck)\n */\nexport interface TraceSpan {\n /** When the call ended, which is when its cost was known */\n at: DateTime;\n /** Dotted and stable: `job.run`, `plugin.invoke`, `llm.generate` */\n op: string;\n /** Which one: a plugin and its method, or a model */\n target?: string;\n /** How long it held, measured around the call rather than reported by it */\n ms: number;\n outcome: TraceOutcome;\n /** The failure, summarized to a shape rather than a stack */\n error?: string;\n /** Whatever this `op` is worth reading back: tokens, a finish reason, the bound it was given */\n detail?: Record<string, unknown>;\n}\n\n/** Rehydrates every wire-encoded scalar in a TraceSpan into its runtime type. Mutates and returns `raw`. */\nexport function reviveTraceSpan(raw: TraceSpan): TraceSpan {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['at'] = __dt(__o0['at'], 'TraceSpan.at');\n return raw;\n}\n\n/**\n * generated from [TracesPage](../../../../../apps/api/data/contracts/station/traces.types.ck)\n */\nexport interface TracesPage {\n /** Newest first */\n decisions: TraceDecision[];\n /** How many the window holds before `limit`, so a page can say it is showing a slice */\n total: number;\n /** How many calls were read to answer, which is the honest cost of this page */\n spans: number;\n}\n\n/** Rehydrates every wire-encoded scalar in a TracesPage into its runtime type. Mutates and returns `raw`. */\nexport function reviveTracesPage(raw: TracesPage): TracesPage {\n const __o0 = raw as unknown as Record<string, unknown>;\n {\n const __a1 = __o0['decisions'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveTraceDecision(__a1[__i2] as never);\n }\n }\n return raw;\n}\n\n/**\n * One decision, its calls, and the decisions on either side of it\n * generated from [TraceDetail](../../../../../apps/api/data/contracts/station/traces.types.ck)\n */\nexport interface TraceDetail {\n decision: TraceDecision;\n /** In the order they happened */\n spans: TraceSpan[];\n /** What enqueued this, when that decision is still inside the kept window */\n parent?: TraceDecision;\n /** What this one went on to enqueue */\n caused: TraceDecision[];\n}\n\n/** Rehydrates every wire-encoded scalar in a TraceDetail into its runtime type. Mutates and returns `raw`. */\nexport function reviveTraceDetail(raw: TraceDetail): TraceDetail {\n const __o0 = raw as unknown as Record<string, unknown>;\n reviveTraceDecision(__o0['decision'] as never);\n {\n const __a1 = __o0['spans'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveTraceSpan(__a1[__i2] as never);\n }\n }\n if (__o0['parent'] != null) {\n reviveTraceDecision(__o0['parent'] as never);\n }\n {\n const __a3 = __o0['caused'] as unknown[];\n for (let __i4 = 0; __i4 < __a3.length; __i4++) {\n reviveTraceDecision(__a3[__i4] as never);\n }\n }\n return raw;\n}\n","import type { SdkFetch } from '../sdk-options.js';\nimport { parseJson, buildQueryString } from '../sdk-options.js';\nimport type { LogPage, LogQuery, LogSourceList } from './types/logs.types.js';\nimport { reviveLogSourceList } from './types/logs.types.js';\nimport type { StationAttention, StationCheckup, StationReleases } from './types/station.types.js';\nimport { reviveStationCheckup, reviveStationReleases } from './types/station.types.js';\nimport type { TraceDetail, TracesPage, TracesQuery } from './types/traces.types.js';\nimport { reviveTraceDetail, reviveTracesPage } from './types/traces.types.js';\n\nexport class StationClient {\n constructor(private fetch: SdkFetch) {}\n\n /**\n * @name List logs\n * @description Every log this install has, present or not, with its size and when it was last written\n */\n async listLogs(): Promise<LogSourceList> {\n const result = await this.fetch(`/logs`, { method: 'GET' });\n return reviveLogSourceList(await parseJson<LogSourceList>(result));\n }\n\n /**\n * @name Read log\n * @description A tail of one log, newest first\n */\n async readLog(id: string, query?: LogQuery): Promise<LogPage> {\n const qs = buildQueryString(query);\n const result = await this.fetch(`/logs/${encodeURIComponent(id)}${qs}`, {\n method: 'GET',\n });\n return await parseJson<LogPage>(result);\n }\n\n /**\n * @name Download log\n * @description The retained log as a plain-text attachment, oldest first, as the file is written\n */\n async downloadLog(id: string): Promise<{ data: string; headers: { contentDisposition?: string } }> {\n const result = await this.fetch(`/logs/${encodeURIComponent(id)}/download`, { method: 'GET' });\n const data = await result.text();\n return { data, headers: { contentDisposition: result.headers.get('Content-Disposition') ?? undefined } };\n }\n\n /**\n * @name Read station attention\n * @description Everything wrong or waiting, worst first, each with the console page that can act on it\n */\n async readStationAttention(): Promise<StationAttention> {\n const result = await this.fetch(`/station/attention`, { method: 'GET' });\n return await parseJson<StationAttention>(result);\n }\n\n /**\n * @name Dismiss station attention\n * @description Accept an attention row as it stands, until something new joins it\n */\n async dismissStationAttention(code: string): Promise<void> {\n await this.fetch(`/station/attention/${encodeURIComponent(code)}/dismiss`, { method: 'POST' });\n }\n\n /**\n * @name Read station checkup\n * @description The loops the station runs and how much of the library it has looked at\n */\n async readStationCheckup(): Promise<StationCheckup> {\n const result = await this.fetch(`/station/checkup`, { method: 'GET' });\n return reviveStationCheckup(await parseJson<StationCheckup>(result));\n }\n\n /**\n * @name Read station releases\n * @description The releases this build contains and what each one changed, newest first\n */\n async readStationReleases(): Promise<StationReleases> {\n const result = await this.fetch(`/station/releases`, { method: 'GET' });\n return reviveStationReleases(await parseJson<StationReleases>(result));\n }\n\n /**\n * @name Check station releases\n * @description Asks GitHub for newer releases now, and answers with what the station then knows\n */\n async checkStationReleases(): Promise<StationReleases> {\n const result = await this.fetch(`/station/releases/check`, { method: 'POST' });\n return reviveStationReleases(await parseJson<StationReleases>(result));\n }\n\n /**\n * @name Read traces\n * @description Recent decisions, newest first, folded to one row each\n */\n async readTraces(query?: TracesQuery): Promise<TracesPage> {\n const qs = buildQueryString(query);\n const result = await this.fetch(`/traces${qs}`, {\n method: 'GET',\n });\n return reviveTracesPage(await parseJson<TracesPage>(result));\n }\n\n /**\n * @name Read trace\n * @description One decision: every call it made, and the decisions on either side of it\n */\n async readTrace(id: string): Promise<TraceDetail> {\n const result = await this.fetch(`/traces/${encodeURIComponent(id)}`, { method: 'GET' });\n return reviveTraceDetail(await parseJson<TraceDetail>(result));\n }\n}\n","import { DateTime } from 'luxon';\nconst __dt = (v: unknown, path: string): DateTime => {\n if (typeof v !== 'string') {\n throw new TypeError(`ContractKit: expected an ISO 8601 string at '${path}', received ${typeof v}.`);\n }\n const d = DateTime.fromISO(v);\n if (!d.isValid) throw new TypeError(`ContractKit: '${v}' at '${path}' is not a valid ISO 8601 datetime.`);\n return d;\n};\n\n/**\n * Which store, as a stable id the console can key off rather than a name it renders.\n * generated from [StorageStoreId](../../../../../apps/api/data/contracts/storage/storage.types.ck)\n */\nexport type StorageStoreId = 'tracks' | 'art' | 'segments' | 'voices';\n\n/**\n * One content store: what is on disk, and what the database says should be.\n *\n * The two halves are deliberately separate numbers rather than one reconciled figure. They disagree\n * in two directions and each direction means something different — a file nothing claims is what a\n * crash between writing bytes and writing a row leaves behind, and a row whose file is gone is what\n * an operator emptying a directory leaves. Reporting one number would hide both.\n * generated from [StorageStore](../../../../../apps/api/data/contracts/storage/storage.types.ck)\n */\nexport interface StorageStore {\n id: StorageStoreId;\n /** What to call it on a page */\n label: string;\n /** Where it is, so `du` and this can be compared */\n path: string;\n /** Files actually there */\n files: number;\n /** What they weigh */\n bytes: number;\n /** Rows pointing at a file. Absent when no table backs this store */\n rows?: number;\n /** What those rows say those files weigh. Absent where the table does not record a size */\n accountedBytes?: number;\n /** The limit an operator set, where the store has one. Absent means no limit */\n capBytes?: number;\n /** Files no row claims. Reported and never cleaned up automatically */\n orphanFiles: number;\n orphanBytes: number;\n /** Claims whose file is not there. The station re-fetches or re-renders these */\n rowsWithNoFile: number;\n}\n\nexport interface StorageStoreInput {}\n\n/**\n * Every store, plus the number an operator actually wants first.\n *\n * `readAt` is not decoration: the figures come from walking directories, which is real I/O on a\n * station holding tens of thousands of files, so the answer is cached for a short while and this is\n * what stops a page mistaking it for live.\n * generated from [StorageReport](../../../../../apps/api/data/contracts/storage/storage.types.ck)\n */\nexport interface StorageReport {\n readAt: DateTime;\n totalFiles: number;\n totalBytes: number;\n stores: StorageStore[];\n}\n\nexport interface StorageReportInput {\n stores: StorageStoreInput[];\n}\n\n/** Rehydrates every wire-encoded scalar in a StorageReport into its runtime type. Mutates and returns `raw`. */\nexport function reviveStorageReport(raw: StorageReport): StorageReport {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['readAt'] = __dt(__o0['readAt'], 'StorageReport.readAt');\n return raw;\n}\n","import type { SdkFetch } from '../sdk-options.js';\nimport { parseJson } from '../sdk-options.js';\nimport type { StorageReport } from './types/storage.types.js';\nimport { reviveStorageReport } from './types/storage.types.js';\n\nexport class StorageClient {\n constructor(private fetch: SdkFetch) {}\n\n /**\n * @name Read storage\n * @description What is on disk, per store, against what the database says should be\n */\n async readStorage(): Promise<StorageReport> {\n const result = await this.fetch(`/storage`, { method: 'GET' });\n return reviveStorageReport(await parseJson<StorageReport>(result));\n }\n}\n","import type { SdkFetch } from '../sdk-options.js';\nimport { bigIntReplacer, parseJson } from '../sdk-options.js';\nimport type {\n FetcherAuthorization,\n FetcherAuthorizationFinished,\n FetcherAuthorizationInput,\n FetcherAuthorizationStart,\n} from './types/stream.types.js';\n\nexport class StreamClient {\n constructor(private fetch: SdkFetch) {}\n\n /**\n * @name Get HLS playlist\n * @description One HLS playlist, and the tick that says somebody is still listening to it\n */\n async getHLSPlaylist(name: string): Promise<{ data: Blob; headers: { cacheControl?: string } }> {\n const result = await this.fetch(`/hls/${encodeURIComponent(name)}`, { method: 'GET' });\n const data = await result.blob();\n return { data, headers: { cacheControl: result.headers.get('cache-control') ?? undefined } };\n }\n\n /**\n * @name Get tune-in pls\n * @description The station's streams as a PLS playlist, MP3 first, for a player that takes a playlist file rather than a stream address\n */\n async getTuneInPls(): Promise<Blob> {\n const result = await this.fetch(`/listen.pls`, { method: 'GET' });\n return await result.blob();\n }\n\n /**\n * @name Get tune-in m3u\n * @description The station's streams as an M3U playlist, MP3 first, for a player that takes a playlist file rather than a stream address\n */\n async getTuneInM3u(): Promise<Blob> {\n const result = await this.fetch(`/listen.m3u`, { method: 'GET' });\n return await result.blob();\n }\n\n /**\n * @name Read fetcher authorization\n * @description What the track fetcher holds by way of a Spotify login, and whether an authorization is already waiting to be finished\n */\n async readFetcherAuthorization(): Promise<FetcherAuthorization> {\n const result = await this.fetch(`/stream/authorization`, { method: 'GET' });\n return await parseJson<FetcherAuthorization>(result);\n }\n\n /**\n * @name Start fetcher authorization\n * @description Starts the fetcher's one-time authorization and answers with the URL to open. Starting another replaces whichever was pending\n */\n async startFetcherAuthorization(): Promise<FetcherAuthorizationStart> {\n const result = await this.fetch(`/stream/authorization`, { method: 'POST' });\n return await parseJson<FetcherAuthorizationStart>(result);\n }\n\n /**\n * @name Finish fetcher authorization\n * @description Finishes an authorization from the address the operator's browser ended up at\n */\n async finishFetcherAuthorization(body: FetcherAuthorizationInput): Promise<FetcherAuthorizationFinished> {\n const result = await this.fetch(`/stream/authorization/complete`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<FetcherAuthorizationFinished>(result);\n }\n}\n","import type { SdkFetch } from '../sdk-options.js';\nimport { bigIntReplacer, parseJson, buildQueryString } from '../sdk-options.js';\nimport type { TopicInput, TopicKindList, TopicList, TopicQuery } from './types/topics.types.js';\n\nexport class TopicsClient {\n constructor(private fetch: SdkFetch) {}\n\n /**\n * @name List topics\n * @description Every subject this station has named, for one sort of break or for all of them\n */\n async listTopics(query?: TopicQuery): Promise<TopicList> {\n const qs = buildQueryString(query);\n const result = await this.fetch(`/topics${qs}`, {\n method: 'GET',\n });\n return await parseJson<TopicList>(result);\n }\n\n /**\n * @name Create topic\n * @description Names a new subject. Nothing uses it until something points at it\n */\n async createTopic(body: TopicInput): Promise<TopicList> {\n const result = await this.fetch(`/topics`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<TopicList>(result);\n }\n\n /**\n * @name List topic kinds\n * @description Which sorts of break have subjects, and the form each one's settings are edited with\n */\n async listTopicKinds(): Promise<TopicKindList> {\n const result = await this.fetch(`/topics/kinds`, { method: 'GET' });\n return await parseJson<TopicKindList>(result);\n }\n\n /**\n * @name Update topic\n * @description Rewrites one subject. A break already written keeps the words it was given\n */\n async updateTopic(id: string, body: TopicInput): Promise<TopicList> {\n const result = await this.fetch(`/topics/${encodeURIComponent(id)}`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<TopicList>(result);\n }\n\n /**\n * @name Delete topic\n * @description Removes a subject, and any band on the format clock that asked for it\n */\n async deleteTopic(id: string): Promise<TopicList> {\n const result = await this.fetch(`/topics/${encodeURIComponent(id)}`, { method: 'DELETE' });\n return await parseJson<TopicList>(result);\n }\n}\n","import { DateTime } from 'luxon';\nimport type { Pagination } from '../../shared/types/pagination.js';\nimport type { PaginationInput } from '../../shared/types/pagination.js';\nimport type { PaginationWithActive } from '../../shared/types/pagination.js';\nimport type { PaginationWithActiveInput } from '../../shared/types/pagination.js';\nimport type { PlatformRole } from '../../authentication/types/authentication.types.js';\nimport type { Session } from '../../authentication/types/authentication.types.js';\nimport { reviveSession } from '../../authentication/types/authentication.types.js';\nimport type { SessionInput } from '../../authentication/types/authentication.types.js';\n\nconst __dt = (v: unknown, path: string): DateTime => {\n if (typeof v !== 'string') {\n throw new TypeError(`ContractKit: expected an ISO 8601 string at '${path}', received ${typeof v}.`);\n }\n const d = DateTime.fromISO(v);\n if (!d.isValid) throw new TypeError(`ContractKit: '${v}' at '${path}' is not a valid ISO 8601 datetime.`);\n return d;\n};\n\n/**\n * Which people to list\n * generated from [UserQuery](../../../../../apps/api/data/contracts/users/users.types.ck)\n */\nexport interface UserQuery extends PaginationWithActive {\n /** Part of an email address */\n search?: string;\n /** Only people holding this role */\n role?: PlatformRole;\n}\n\nexport interface UserQueryInput extends PaginationWithActiveInput {\n /** Part of an email address */\n search?: string;\n /** Only people holding this role */\n role?: PlatformRole;\n}\n\n/**\n * A person with an account on the station\n * generated from [UserSummary](../../../../../apps/api/data/contracts/users/users.types.ck)\n */\nexport interface UserSummary {\n /** The person's account id */\n id: string;\n /** The address they sign in with. Absent for an account that has none, such as one made through a provider that shared no address */\n email?: string;\n /** The one role they hold. Absent for an account nobody has granted one */\n role?: PlatformRole;\n /** False once the account has been switched off. A switched-off person cannot sign in, and every session they held has ended */\n active: boolean;\n /** When the account was made */\n createdAt: DateTime;\n /** When they last signed in. Absent if they never have */\n lastSignInAt?: DateTime;\n /** Whether they have an authenticator app or a passkey, which the phone apps need to sign in with */\n hasStrongFactor: boolean;\n}\n\n/** Rehydrates every wire-encoded scalar in a UserSummary into its runtime type. Mutates and returns `raw`. */\nexport function reviveUserSummary(raw: UserSummary): UserSummary {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['createdAt'] = __dt(__o0['createdAt'], 'UserSummary.createdAt');\n if (__o0['lastSignInAt'] != null) {\n __o0['lastSignInAt'] = __dt(__o0['lastSignInAt'], 'UserSummary.lastSignInAt');\n }\n return raw;\n}\n\n/**\n * One way a person signs in. Never the secret itself\n * generated from [UserFactor](../../../../../apps/api/data/contracts/users/users.types.ck)\n */\nexport interface UserFactor {\n /** What kind of factor it is */\n method: 'email' | 'password' | 'authenticator' | 'fido' | 'oidc' | 'phone';\n /** Which factor of that kind */\n methodId: string;\n /** What it proves */\n kind: 'knowledge' | 'possession' | 'biometric';\n /** How it is shown, such as a masked address or the authenticator's name */\n label?: string;\n}\n\n/**\n * One time a person signed in\n * generated from [UserSignIn](../../../../../apps/api/data/contracts/users/users.types.ck)\n */\nexport interface UserSignIn {\n /** When */\n occurredAt: DateTime;\n /** The factor they signed in with */\n method: string;\n /** Whether a second factor was proved */\n mfaSatisfied: boolean;\n /** The address the request came from */\n ip?: string;\n /** The app or browser that asked */\n userAgent?: string;\n}\n\n/** Rehydrates every wire-encoded scalar in a UserSignIn into its runtime type. Mutates and returns `raw`. */\nexport function reviveUserSignIn(raw: UserSignIn): UserSignIn {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['occurredAt'] = __dt(__o0['occurredAt'], 'UserSignIn.occurredAt');\n return raw;\n}\n\n/**\n * The role a person should hold\n * generated from [UserRoleChange](../../../../../apps/api/data/contracts/users/users.types.ck)\n */\nexport interface UserRoleChange {\n /** Replaces whatever role they held */\n role: PlatformRole;\n}\n\n/**\n * One page of people\n * generated from [UserPage](../../../../../apps/api/data/contracts/users/users.types.ck)\n */\nexport interface UserPage {\n meta: Pagination;\n data: UserSummary[];\n}\n\nexport interface UserPageInput {\n meta: PaginationInput;\n data: UserSummary[];\n}\n\n/** Rehydrates every wire-encoded scalar in a UserPage into its runtime type. Mutates and returns `raw`. */\nexport function reviveUserPage(raw: UserPage): UserPage {\n const __o0 = raw as unknown as Record<string, unknown>;\n {\n const __a1 = __o0['data'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveUserSummary(__a1[__i2] as never);\n }\n }\n return raw;\n}\n\n/**\n * A person, with how they sign in and where they are signed in\n * generated from [UserDetail](../../../../../apps/api/data/contracts/users/users.types.ck)\n */\nexport interface UserDetail extends UserSummary {\n /** Every way they can sign in */\n factors: UserFactor[];\n /** Where they are signed in now */\n sessions: Session[];\n /** Their most recent sign-ins, newest first */\n signIns: UserSignIn[];\n}\n\nexport interface UserDetailInput extends UserSummary {\n /** Every way they can sign in */\n factors: UserFactor[];\n /** Where they are signed in now */\n sessions: SessionInput[];\n /** Their most recent sign-ins, newest first */\n signIns: UserSignIn[];\n}\n\n/** Rehydrates every wire-encoded scalar in a UserDetail into its runtime type. Mutates and returns `raw`. */\nexport function reviveUserDetail(raw: UserDetail): UserDetail {\n const __o0 = raw as unknown as Record<string, unknown>;\n reviveUserSummary(raw as never);\n {\n const __a1 = __o0['sessions'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveSession(__a1[__i2] as never);\n }\n }\n {\n const __a3 = __o0['signIns'] as unknown[];\n for (let __i4 = 0; __i4 < __a3.length; __i4++) {\n reviveUserSignIn(__a3[__i4] as never);\n }\n }\n return raw;\n}\n","import { DateTime } from 'luxon';\nimport type { FidoFactorAttestation } from '../../authentication/types/registration.types.js';\nimport type { PlatformRole } from '../../authentication/types/authentication.types.js';\nimport type { PublicKeyCredentialWithAttestation } from '../../authentication/types/authentication.types.js';\n\nconst __dt = (v: unknown, path: string): DateTime => {\n if (typeof v !== 'string') {\n throw new TypeError(`ContractKit: expected an ISO 8601 string at '${path}', received ${typeof v}.`);\n }\n const d = DateTime.fromISO(v);\n if (!d.isValid) throw new TypeError(`ContractKit: '${v}' at '${path}' is not a valid ISO 8601 datetime.`);\n return d;\n};\n\n/**\n * Where an invitation stands. `expired` is a pending invitation whose time ran out\n * generated from [InvitationState](../../../../../apps/api/data/contracts/users/invitations.types.ck)\n */\nexport type InvitationState = 'pending' | 'accepted' | 'revoked' | 'expired';\n\n/**\n * Invite somebody by their address\n * generated from [InvitationCreate](../../../../../apps/api/data/contracts/users/invitations.types.ck)\n */\nexport interface InvitationCreate {\n /** The address the account will have */\n email: string;\n /** The role the account will hold */\n role: PlatformRole;\n /** Email the link to the address too. Refused with a 503, and nothing made, when the station has no mail server */\n send?: boolean;\n}\n\n/**\n * An invitation's link token, as it appears after `#` on the invite page\n * generated from [InvitationToken](../../../../../apps/api/data/contracts/users/invitations.types.ck)\n */\nexport interface InvitationToken {\n /** The token */\n token: string;\n}\n\n/**\n * What an open invitation is for, shown to the person before they accept\n * generated from [InvitationDetails](../../../../../apps/api/data/contracts/users/invitations.types.ck)\n */\nexport interface InvitationDetails {\n /** The address the account will have */\n email: string;\n /** The role it will hold */\n role: PlatformRole;\n /** What the station calls itself */\n stationName: string;\n /** When the link stops working */\n expiresAt: DateTime;\n}\n\n/** Rehydrates every wire-encoded scalar in a InvitationDetails into its runtime type. Mutates and returns `raw`. */\nexport function reviveInvitationDetails(raw: InvitationDetails): InvitationDetails {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['expiresAt'] = __dt(__o0['expiresAt'], 'InvitationDetails.expiresAt');\n return raw;\n}\n\n/**\n * How the person will prove it is them after their password: an authenticator app, or a passkey\n * generated from [InvitationSecondStep](../../../../../apps/api/data/contracts/users/invitations.types.ck)\n */\nexport type InvitationSecondStep = 'authenticator' | 'fido';\n\n/**\n * An authenticator app to scan, for an invitation being accepted\n * generated from [InvitationAuthenticatorSetup](../../../../../apps/api/data/contracts/users/invitations.types.ck)\n */\nexport interface InvitationAuthenticatorSetup {\n /** Discriminator */\n method: 'authenticator';\n /** Send this back with the first code */\n registrationId: string;\n /** The key, for an app that cannot scan */\n secret: string;\n /** The `otpauth://` address the QR code holds */\n uri: string;\n /** The QR code, as a data URL */\n qrCode: string;\n}\n\n/**\n * A passkey to make, for an invitation being accepted\n * generated from [InvitationPasskeySetup](../../../../../apps/api/data/contracts/users/invitations.types.ck)\n */\nexport interface InvitationPasskeySetup {\n /** Discriminator */\n method: 'fido';\n /** Send this back with the credential */\n registrationId: string;\n /** What to hand `navigator.credentials.create` */\n attestation: FidoFactorAttestation;\n}\n\n/**\n * Accept with the first code from the authenticator app\n * generated from [InvitationAcceptWithAuthenticator](../../../../../apps/api/data/contracts/users/invitations.types.ck)\n */\nexport interface InvitationAcceptWithAuthenticator {\n /** Discriminator */\n method: 'authenticator';\n /** The invitation's token */\n token: string;\n /** The same password as at the start */\n password: string;\n /** From the start */\n registrationId: string;\n /** The first code the app shows */\n code: string;\n}\n\n/**\n * Accept with the passkey the browser just made\n * generated from [InvitationAcceptWithPasskey](../../../../../apps/api/data/contracts/users/invitations.types.ck)\n */\nexport interface InvitationAcceptWithPasskey {\n /** Discriminator */\n method: 'fido';\n /** The invitation's token */\n token: string;\n /** The same password as at the start */\n password: string;\n /** From the start */\n registrationId: string;\n /** What `navigator.credentials.create` answered */\n credential: PublicKeyCredentialWithAttestation;\n}\n\n/**\n * The account made from an invitation. Sign in with it as usual\n * generated from [InvitationAccepted](../../../../../apps/api/data/contracts/users/invitations.types.ck)\n */\nexport interface InvitationAccepted {\n /** The address to sign in with */\n email: string;\n /** The role it holds */\n role: PlatformRole;\n}\n\n/**\n * An invitation for somebody to take an account on the station\n * generated from [Invitation](../../../../../apps/api/data/contracts/users/invitations.types.ck)\n */\nexport interface Invitation {\n /** The invitation's id */\n id: string;\n /** The address the account will have. The person cannot change it while accepting */\n email: string;\n /** The role the account will hold */\n role: PlatformRole;\n /** Where it stands */\n state: InvitationState;\n /** When it was made */\n createdAt: DateTime;\n /** When the link stops working, if nobody has used it */\n expiresAt: DateTime;\n /** The address of the admin who made it. Absent once their account is gone */\n invitedBy?: string;\n /** When somebody accepted it */\n acceptedAt?: DateTime;\n /** When it was withdrawn, by an admin or by a newer invitation to the same address */\n revokedAt?: DateTime;\n /** The invitation itself, only while it is pending. Put it after `#` on the station's `/invite` page, as `/invite#<token>`. Anyone holding it can claim the account, so show it only to the person invited */\n token?: string;\n}\n\n/** Rehydrates every wire-encoded scalar in a Invitation into its runtime type. Mutates and returns `raw`. */\nexport function reviveInvitation(raw: Invitation): Invitation {\n const __o0 = raw as unknown as Record<string, unknown>;\n __o0['createdAt'] = __dt(__o0['createdAt'], 'Invitation.createdAt');\n __o0['expiresAt'] = __dt(__o0['expiresAt'], 'Invitation.expiresAt');\n if (__o0['acceptedAt'] != null) {\n __o0['acceptedAt'] = __dt(__o0['acceptedAt'], 'Invitation.acceptedAt');\n }\n if (__o0['revokedAt'] != null) {\n __o0['revokedAt'] = __dt(__o0['revokedAt'], 'Invitation.revokedAt');\n }\n return raw;\n}\n\n/**\n * Choose a password and a second step. Nothing is saved yet\n * generated from [InvitationAcceptStart](../../../../../apps/api/data/contracts/users/invitations.types.ck)\n */\nexport interface InvitationAcceptStart {\n /** The invitation's token */\n token: string;\n /** The password the account will have. Refused here if it is too weak, so the person learns before setting anything else up */\n password: string;\n /** The second step to set up */\n method: InvitationSecondStep;\n}\n\n/**\n * generated from [InvitationAcceptStartResponse](../../../../../apps/api/data/contracts/users/invitations.types.ck)\n */\nexport type InvitationAcceptStartResponse = InvitationAuthenticatorSetup | InvitationPasskeySetup;\n\n/**\n * generated from [InvitationAccept](../../../../../apps/api/data/contracts/users/invitations.types.ck)\n */\nexport type InvitationAccept = InvitationAcceptWithAuthenticator | InvitationAcceptWithPasskey;\n\n/**\n * The station's invitations, newest first\n * generated from [InvitationList](../../../../../apps/api/data/contracts/users/invitations.types.ck)\n */\nexport interface InvitationList {\n data: Invitation[];\n}\n\n/** Rehydrates every wire-encoded scalar in a InvitationList into its runtime type. Mutates and returns `raw`. */\nexport function reviveInvitationList(raw: InvitationList): InvitationList {\n const __o0 = raw as unknown as Record<string, unknown>;\n {\n const __a1 = __o0['data'] as unknown[];\n for (let __i2 = 0; __i2 < __a1.length; __i2++) {\n reviveInvitation(__a1[__i2] as never);\n }\n }\n return raw;\n}\n","import type {\n Invitation,\n InvitationAccept,\n InvitationAcceptStart,\n InvitationAcceptStartResponse,\n InvitationAccepted,\n InvitationCreate,\n InvitationDetails,\n InvitationList,\n InvitationToken,\n} from './types/invitations.types.js';\nimport { reviveInvitation, reviveInvitationDetails, reviveInvitationList } from './types/invitations.types.js';\nimport type { SdkFetch } from '../sdk-options.js';\nimport { bigIntReplacer, parseJson } from '../sdk-options.js';\n\n/**\n * generated from [invitations.ck](../../../../apps/api/data/contracts/users/invitations.ck)\n */\nexport class UsersInvitationsClient {\n constructor(private fetch: SdkFetch) {}\n\n /**\n * @name List invitations\n * @description Every invitation, newest first, with the link of each one still open\n */\n async listInvitations(): Promise<InvitationList> {\n const result = await this.fetch(`/invitations`, { method: 'GET' });\n return reviveInvitationList(await parseJson<InvitationList>(result));\n }\n\n /**\n * @name Create invitation\n * @description Invite somebody into a role. An open invitation to the same address is withdrawn first, so this is also how one is sent again. Refused for an address that already has an account\n */\n async createInvitation(body: InvitationCreate): Promise<Invitation> {\n const result = await this.fetch(`/invitations`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return reviveInvitation(await parseJson<Invitation>(result));\n }\n\n /**\n * @name Revoke invitation\n * @description Withdraw an invitation. Its link stops working at once. Nothing is deleted: it stays in the list as withdrawn\n */\n async revokeInvitation(id: string): Promise<Invitation> {\n const result = await this.fetch(`/invitations/${encodeURIComponent(id)}`, { method: 'DELETE' });\n return reviveInvitation(await parseJson<Invitation>(result));\n }\n\n /**\n * @name Read invitation\n * @description What an open invitation is for: the address, the role and the station. Changes nothing\n */\n async readInvitation(body: InvitationToken): Promise<InvitationDetails> {\n const result = await this.fetch(`/invitations/accept/details`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return reviveInvitationDetails(await parseJson<InvitationDetails>(result));\n }\n\n /**\n * @name Start accepting invitation\n * @description Check the password and start setting up the second step. Nothing is saved, and starting again replaces the setup\n */\n async startAcceptingInvitation(body: InvitationAcceptStart): Promise<InvitationAcceptStartResponse> {\n const result = await this.fetch(`/invitations/accept/start`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<InvitationAcceptStartResponse>(result);\n }\n\n /**\n * @name Accept invitation\n * @description Accept: make the account with its password, its second step and its role, all at once, and spend the invitation\n */\n async acceptInvitation(body: InvitationAccept): Promise<InvitationAccepted> {\n const result = await this.fetch(`/invitations/accept`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return await parseJson<InvitationAccepted>(result);\n }\n}\n","import type { SdkFetch } from '../sdk-options.js';\nimport { bigIntReplacer, parseJson, buildQueryString } from '../sdk-options.js';\nimport type { UserDetail, UserPage, UserQueryInput, UserRoleChange, UserSummary } from './types/users.types.js';\nimport { reviveUserDetail, reviveUserPage, reviveUserSummary } from './types/users.types.js';\nimport { UsersInvitationsClient } from './invitations.client.js';\n\nexport class UsersClient {\n readonly invitations: UsersInvitationsClient;\n\n constructor(private fetch: SdkFetch) {\n this.invitations = new UsersInvitationsClient(fetch);\n }\n\n /**\n * @name List users\n * @description The station's people, one page at a time, ordered by when their account was made\n */\n async listUsers(query?: UserQueryInput): Promise<UserPage> {\n const qs = buildQueryString(query);\n const result = await this.fetch(`/users${qs}`, {\n method: 'GET',\n });\n return reviveUserPage(await parseJson<UserPage>(result));\n }\n\n /**\n * @name Get user\n * @description One person, with every way they sign in, where they are signed in and their recent sign-ins\n */\n async getUser(id: string): Promise<UserDetail> {\n const result = await this.fetch(`/users/${encodeURIComponent(id)}`, { method: 'GET' });\n return reviveUserDetail(await parseJson<UserDetail>(result));\n }\n\n /**\n * @name Change user role\n * @description Give a person a different role. They hold exactly one, so the role they had is taken away. Refused for your own account, and for the last admin\n */\n async changeUserRole(id: string, body: UserRoleChange): Promise<UserSummary> {\n const result = await this.fetch(`/users/${encodeURIComponent(id)}/role`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body, bigIntReplacer),\n });\n return reviveUserSummary(await parseJson<UserSummary>(result));\n }\n\n /**\n * @name Deactivate user\n * @description Switch a person off. They are signed out everywhere and cannot sign in, and their API keys, connected apps and chat links stop working, until they are switched back on. Nothing is deleted. Refused for your own account, and for the last admin\n */\n async deactivateUser(id: string): Promise<UserSummary> {\n const result = await this.fetch(`/users/${encodeURIComponent(id)}/deactivate`, { method: 'POST' });\n return reviveUserSummary(await parseJson<UserSummary>(result));\n }\n\n /**\n * @name Reactivate user\n * @description Switch a person back on. They sign in as they did before, and their API keys, connected apps and chat links work again\n */\n async reactivateUser(id: string): Promise<UserSummary> {\n const result = await this.fetch(`/users/${encodeURIComponent(id)}/reactivate`, { method: 'POST' });\n return reviveUserSummary(await parseJson<UserSummary>(result));\n }\n\n /**\n * @name Sign out user\n * @description Sign a person out everywhere. They can sign straight back in\n */\n async signOutUser(id: string): Promise<void> {\n await this.fetch(`/users/${encodeURIComponent(id)}/sign-out`, { method: 'POST' });\n }\n\n /**\n * @name Reset user MFA\n * @description Remove a person's authenticator apps and passkeys and sign them out everywhere, for when they have lost the device. They sign in with their password and set a new one up\n */\n async resetUserMFA(id: string): Promise<void> {\n await this.fetch(`/users/${encodeURIComponent(id)}/mfa/reset`, { method: 'POST' });\n }\n}\n","import type { SdkOptions } from './sdk-options.js';\nimport { createSdkFetch } from './sdk-options.js';\nimport { ActivityClient } from './activity/activity.client.js';\nimport { ArtClient } from './art/art.client.js';\nimport { AuthenticationClient } from './authentication/authentication.client.js';\nimport { CatalogClient } from './catalog/catalog.client.js';\nimport { ChartsClient } from './charts/charts.client.js';\nimport { DirectorClient } from './director/director.client.js';\nimport { EventsClient } from './events/events.client.js';\nimport { HistoryClient } from './history/history.client.js';\nimport { LanguagesClient } from './languages/languages.client.js';\nimport { MessagingClient } from './messaging/messaging.client.js';\nimport { MetricsClient } from './metrics/metrics.client.js';\nimport { NarrationsClient } from './narrations/narrations.client.js';\nimport { NewsClient } from './news/news.client.js';\nimport { NowplayingClient } from './nowplaying/nowplaying.client.js';\nimport { OauthClient } from './oauth/oauth.client.js';\nimport { OnboardingClient } from './onboarding/onboarding.client.js';\nimport { OutputsClient } from './outputs/outputs.client.js';\nimport { PersonasClient } from './personas/personas.client.js';\nimport { PlaylistsClient } from './playlists/playlists.client.js';\nimport { PlayoutClient } from './playout/playout.client.js';\nimport { PluginsClient } from './plugins/plugins.client.js';\nimport { PodcastsClient } from './podcasts/podcasts.client.js';\nimport { ProductionsClient } from './productions/productions.client.js';\nimport { RenderClient } from './render/render.client.js';\nimport { RequestsClient } from './requests/requests.client.js';\nimport { ScheduleClient } from './schedule/schedule.client.js';\nimport { SettingsClient } from './settings/settings.client.js';\nimport { StationClient } from './station/station.client.js';\nimport { StorageClient } from './storage/storage.client.js';\nimport { StreamClient } from './stream/stream.client.js';\nimport { TopicsClient } from './topics/topics.client.js';\nimport { UsersClient } from './users/users.client.js';\n\nexport class DeadairSdk {\n readonly activity: ActivityClient;\n readonly art: ArtClient;\n readonly authentication: AuthenticationClient;\n readonly catalog: CatalogClient;\n readonly charts: ChartsClient;\n readonly director: DirectorClient;\n readonly events: EventsClient;\n readonly history: HistoryClient;\n readonly languages: LanguagesClient;\n readonly messaging: MessagingClient;\n readonly metrics: MetricsClient;\n readonly narrations: NarrationsClient;\n readonly news: NewsClient;\n readonly nowplaying: NowplayingClient;\n readonly oauth: OauthClient;\n readonly onboarding: OnboardingClient;\n readonly outputs: OutputsClient;\n readonly personas: PersonasClient;\n readonly playlists: PlaylistsClient;\n readonly playout: PlayoutClient;\n readonly plugins: PluginsClient;\n readonly podcasts: PodcastsClient;\n readonly productions: ProductionsClient;\n readonly render: RenderClient;\n readonly requests: RequestsClient;\n readonly schedule: ScheduleClient;\n readonly settings: SettingsClient;\n readonly station: StationClient;\n readonly storage: StorageClient;\n readonly stream: StreamClient;\n readonly topics: TopicsClient;\n readonly users: UsersClient;\n\n constructor(options: SdkOptions) {\n const sdkFetch = options.fetch ?? createSdkFetch(options);\n this.activity = new ActivityClient(sdkFetch);\n this.art = new ArtClient(sdkFetch);\n this.authentication = new AuthenticationClient(sdkFetch);\n this.catalog = new CatalogClient(sdkFetch);\n this.charts = new ChartsClient(sdkFetch);\n this.director = new DirectorClient(sdkFetch);\n this.events = new EventsClient(sdkFetch);\n this.history = new HistoryClient(sdkFetch);\n this.languages = new LanguagesClient(sdkFetch);\n this.messaging = new MessagingClient(sdkFetch);\n this.metrics = new MetricsClient(sdkFetch);\n this.narrations = new NarrationsClient(sdkFetch);\n this.news = new NewsClient(sdkFetch);\n this.nowplaying = new NowplayingClient(sdkFetch);\n this.oauth = new OauthClient(sdkFetch);\n this.onboarding = new OnboardingClient(sdkFetch);\n this.outputs = new OutputsClient(sdkFetch);\n this.personas = new PersonasClient(sdkFetch);\n this.playlists = new PlaylistsClient(sdkFetch);\n this.playout = new PlayoutClient(sdkFetch);\n this.plugins = new PluginsClient(sdkFetch);\n this.podcasts = new PodcastsClient(sdkFetch);\n this.productions = new ProductionsClient(sdkFetch);\n this.render = new RenderClient(sdkFetch);\n this.requests = new RequestsClient(sdkFetch);\n this.schedule = new ScheduleClient(sdkFetch);\n this.settings = new SettingsClient(sdkFetch);\n this.station = new StationClient(sdkFetch);\n this.storage = new StorageClient(sdkFetch);\n this.stream = new StreamClient(sdkFetch);\n this.topics = new TopicsClient(sdkFetch);\n this.users = new UsersClient(sdkFetch);\n }\n}\n"],"mappings":"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","names":["SdkError","Error","status","statusText","body","headers","name","bigIntReplacer","_","value","toString","bigIntReviver","test","BigInt","slice","readContentType","res","get","split","trim","randomRequestId","crypto","randomUUID","bytes","getRandomValues","Uint8Array","hex","Array","from","b","padStart","join","createSdkFetch","options","getRequestId","requestIdFactory","url","init","baseHeaders","fetch","baseUrl","ok","expectStatuses","includes","text","JSON","parse","buildQueryString","query","searchParams","URLSearchParams","k","v","Object","entries","undefined","isArray","item","append","String","set","qs","buildHeaders","out","map","parseBigIntHeader","replace","stringify","sseRequestHeaders","Accept","lastEventId","parseSse","data","iterated","events","reader","pipeThrough","TextDecoderStream","getReader","buffer","chunk","read","done","end","search","length","line","startsWith","colon","indexOf","field","push","cancel","catch","Symbol","asyncIterator","parseJson","parseJsonWithBigInt","DateTime","__dt","v","path","TypeError","d","DateTime","fromISO","isValid","reviveActivityEntry","raw","__o0","reviveActivityPage","__a1","__i2","length","ActivityClient","fetch","readActivity","query","qs","buildQueryString","result","method","reviveActivityPage","parseJson","ArtClient","fetch","listBreakArtwork","result","method","parseJson","replaceBreakArtwork","kind","body","encodeURIComponent","revertBreakArtwork","getSourceArt","token","expectStatuses","status","contentType","readContentType","data","blob","headers","cacheControl","get","undefined","etag","getSourceArtFile","filename","getArt","id","getArtFile","listPersonaPortraits","replacePersonaPortrait","personaId","removePersonaPortrait","DateTime","__dt","v","path","TypeError","d","DateTime","fromISO","isValid","reviveAuthenticationRegistration","raw","__o0","reviveFactorChallengePhoneStartResponse","reviveFactorChallengePhoneStartResponseOutput","reviveFactorChallengeEmailStartResponse","reviveFactorChallengeEmailStartResponseOutput","reviveSessionFactor","reviveLogin","reviveBaseAuthenticationLoginStartResponse","reviveSession","__a1","__i2","length","reviveApiKey","reviveApiKeyCreate","reviveCodeAuthenticationLoginStartResponse","reviveLinkAuthenticationLoginStartResponse","reviveOidcAuthenticationLoginStartResponse","reviveMfaRequiredResponse","reviveMfaRequiredResponseOutput","reviveFidoAuthenticationLoginStartResponse","reviveFactorChallengeFidoStartResponse","reviveFactorChallengeFidoStartResponseOutput","reviveApiKeyList","reviveApiKeyIssued","reviveStepUpStartResponse","__v","__d0","reviveStepUpStartResponseOutput","reviveAuthenticationTokenResponse","reviveAuthenticationTokenResponseOutput","reviveAuthenticationLoginStartResponse","reviveFactorChallengeStartResponse","reviveFactorChallengeStartResponseOutput","AuthenticationApikeysClient","fetch","listAPIKeys","result","method","reviveApiKeyList","parseJson","createAPIKey","body","headers","JSON","stringify","bigIntReplacer","reviveApiKeyIssued","rotateAPIKey","id","encodeURIComponent","revokeAPIKey","DateTime","__dt","v","path","TypeError","d","DateTime","fromISO","isValid","revivePhoneFactorRegistrationResponse","raw","__o0","reviveEmailFactorRegistrationResponse","reviveAuthenticatorFactorRegistrationResponse","reviveOidcFactorRegistrationResponse","reviveMfaEnrollPhoneStartResponse","reviveFidoFactorRegistrationResponse","reviveMfaEnrollFidoStartResponse","reviveAuthenticationFactorRegistrationResponse","__v","__d0","AuthenticationFactorsClient","fetch","listFactors","result","method","parseJson","registerFactor","body","headers","JSON","stringify","bigIntReplacer","reviveAuthenticationFactorRegistrationResponse","setPassword","verifyFactorRegistration","startFactorChallenge","reviveFactorChallengeStartResponseOutput","startMFAChallenge","reviveStepUpStartResponseOutput","removeFactor","methodId","encodeURIComponent","AuthenticationSessionsClient","fetch","logout","method","readSession","result","parseJson","AuthenticationClient","apikeys","factors","sessions","fetch","AuthenticationApikeysClient","AuthenticationFactorsClient","AuthenticationSessionsClient","requestToken","body","options","__contentType","contentType","__serialized","URLSearchParams","toString","JSON","stringify","bigIntReplacer","result","method","headers","reviveAuthenticationTokenResponseOutput","parseJson","registerLogin","reviveAuthenticationRegistration","verifyLoginRegistration","startLogin","reviveAuthenticationLoginStartResponse","listSignInProviders","DateTime","__dt","v","path","TypeError","d","DateTime","fromISO","isValid","reviveTrackBinding","raw","__o0","reviveTrackAnalysis","reviveTrackPlay","reviveFactClaim","reviveTrackDetail","__a1","__i2","length","__a3","__i4","reviveTrackLyricsSource","reviveTrackEnrichmentSource","reviveArtistEnrichmentSource","reviveAlbumEnrichmentSource","reviveTrackLyricsSources","reviveTrackEnrichmentDetail","reviveArtistEnrichmentDetail","reviveAlbumEnrichmentDetail","CatalogClient","fetch","listArtists","query","qs","buildQueryString","result","method","parseJson","getArtist","id","encodeURIComponent","getArtistEnrichment","reviveArtistEnrichmentDetail","listArtistAlbums","rateArtist","body","headers","JSON","stringify","bigIntReplacer","listAlbums","getAlbum","getAlbumEnrichment","reviveAlbumEnrichmentDetail","listAlbumTracks","rateAlbum","getTrack","reviveTrackDetail","clearTrackAudio","clearTrackAnalysis","getVocalMarkers","setVocalMarkers","clearVocalMarkers","getTrackLyrics","listTrackLyricsSources","reviveTrackLyricsSources","retryTrackAudio","offerTrackCopiesAgain","getTrackEnrichment","reviveTrackEnrichmentDetail","clearTrackEnrichment","listTracks","rateTrack","ChartsClient","fetch","listCharts","result","method","parseJson","readChart","id","query","qs","buildQueryString","encodeURIComponent","DateTime","__dt","v","path","TypeError","d","DateTime","fromISO","isValid","reviveBlockRule","raw","__o0","reviveGenreSteer","reviveBlockRuleList","__a1","__i2","length","reviveGenreSteerReading","DirectorClient","fetch","listClockBands","result","method","parseJson","createClockBand","body","headers","JSON","stringify","bigIntReplacer","updateClockBand","id","encodeURIComponent","deleteClockBand","getStationAir","putTheStationOnAir","setTheAirMode","getTheRunningOrder","recastTheBroadcast","extendTheRunningOrder","replanTheRunningOrder","requestABreak","previewAnArtistRoute","holdTheStationAgainstTheSchedule","releaseTheStationToTheSchedule","shuffleTheRunningOrder","addASegmentToTheRunningOrder","addARecordToTheRunningOrder","moveARunningOrderItem","itemId","removeARunningOrderItem","skipToARunningOrderItem","listNeverPlayRules","reviveBlockRuleList","addANeverPlayRule","readTheGenreSteer","reviveGenreSteerReading","steerTowardGenres","stopSteering","changeANeverPlayRule","removeANeverPlayRule","DateTime","__dt","v","path","TypeError","d","DateTime","fromISO","isValid","reviveEventDestination","raw","__o0","reviveEventDelivery","reviveEventDestinationList","__a1","__i2","length","reviveEventDestinationCreated","__v","reviveEventDeliveryList","EventsClient","fetch","listEventTypes","result","method","parseJson","listEventDestinations","reviveEventDestinationList","createEventDestination","body","headers","JSON","stringify","bigIntReplacer","reviveEventDestinationCreated","updateEventDestination","id","encodeURIComponent","reviveEventDestination","deleteEventDestination","rotateEventDestinationSecret","testEventDestination","listEventDeliveries","reviveEventDeliveryList","DateTime","__dt","v","path","TypeError","d","DateTime","fromISO","isValid","reviveHistoryEntry","raw","__o0","reviveHistoryPage","__a1","__i2","length","HistoryClient","fetch","readHistory","query","qs","buildQueryString","result","method","reviveHistoryPage","parseJson","DateTime","__dt","v","path","TypeError","d","DateTime","fromISO","isValid","reviveConsoleLanguage","raw","__o0","reviveConsoleLanguageList","__a1","__i2","length","LanguagesClient","fetch","getMyConsoleLanguage","result","method","parseJson","chooseMyConsoleLanguage","body","headers","JSON","stringify","bigIntReplacer","listConsoleLanguages","reviveConsoleLanguageList","getConsoleLanguage","locale","encodeURIComponent","importConsoleLanguage","removeConsoleLanguage","DateTime","__dt","v","path","TypeError","d","DateTime","fromISO","isValid","reviveMessagingLinkCode","raw","__o0","reviveMessagingLink","reviveMessagingLinkList","__a1","__i2","length","MessagingClient","fetch","listMessagingLinks","result","method","reviveMessagingLinkList","parseJson","createMessagingLinkCode","reviveMessagingLinkCode","removeMessagingLink","pluginId","platformUserId","encodeURIComponent","DateTime","__dt","v","path","TypeError","d","DateTime","fromISO","isValid","reviveMetricSeriesQuery","raw","__o0","reviveMetricPoint","reviveMetricName","reviveMetricSeries","__a1","__i2","length","reviveMetricNames","reviveMetricSeriesPage","MetricsClient","fetch","readMetricSeries","query","qs","buildQueryString","result","method","reviveMetricSeriesPage","parseJson","readMetricNames","reviveMetricNames","NarrationsClient","fetch","listSeries","result","method","parseJson","listPieces","query","qs","buildQueryString","renderPiece","id","encodeURIComponent","refreshNarrations","NewsClient","fetch","listFeeds","result","method","parseJson","readNews","query","qs","buildQueryString","NowplayingClient","fetch","getNowPlaying","result","method","parseJson","getNowPlayingLyrics","DateTime","__dt","v","path","TypeError","d","DateTime","fromISO","isValid","reviveOAuthGrant","raw","__o0","reviveOAuthClientSummary","reviveOAuthGrantList","__a1","__i2","length","reviveOAuthClientList","reviveOAuthClientIssued","OauthClient","fetch","describeAuthorizationRequest","body","result","method","headers","JSON","stringify","bigIntReplacer","parseJson","approveAuthorizationRequest","denyAuthorizationRequest","listOAuthClients","reviveOAuthClientList","createOAuthClient","reviveOAuthClientIssued","revokeOAuthClient","clientId","encodeURIComponent","listOAuthGrants","reviveOAuthGrantList","revokeOAuthGrant","id","OnboardingClient","fetch","getOnboardingRequirements","result","method","parseJson","submitOnboardingRequirement","body","headers","JSON","stringify","bigIntReplacer","DateTime","__dt","v","path","TypeError","d","DateTime","fromISO","isValid","reviveOutputCast","raw","__o0","reviveOutputCastList","__a1","__i2","length","OutputsClient","fetch","listOutputDevices","result","method","parseJson","listCasts","reviveOutputCastList","startCast","body","headers","JSON","stringify","bigIntReplacer","reviveOutputCast","stopCast","pluginId","deviceId","encodeURIComponent","PersonasClient","fetch","listPersonaAuditions","id","result","encodeURIComponent","method","parseJson","startPersonaAudition","body","headers","JSON","stringify","bigIntReplacer","getPersonaAudition","auditionId","cancelPersonaAudition","listPersonas","createPersona","generatePersona","restoreStationPersonas","exportPersonas","data","contentDisposition","get","undefined","exportPersona","previewPersonaImport","query","qs","buildQueryString","importPersonas","updatePersona","deletePersona","setTheStationHost","listPersonaNotes","writePersonaNote","updatePersonaNote","noteId","deletePersonaNote","setPersonaNoteState","listPersonaStories","writePersonaStory","updatePersonaStory","storyId","deletePersonaStory","setPersonaStoryState","addPersonaStoryDetail","updatePersonaStoryDetail","detailId","deletePersonaStoryDetail","setPersonaStoryDetailState","rehearsePersona","addPersonaStoryBeat","updatePersonaStoryBeat","beatId","deletePersonaStoryBeat","setPersonaStoryBeatState","readPersonaMemory","previewPersonaMemoryRollback","rollBackPersonaMemory","DateTime","__dt","v","path","TypeError","d","DateTime","fromISO","isValid","reviveCatalogPlaylistSource","raw","__o0","reviveCatalogPlaylistPage","__a1","__i2","length","DateTime","__dt","v","path","TypeError","d","DateTime","fromISO","isValid","reviveStationPlaylist","raw","__o0","reviveStationPlaylistList","__a1","__i2","length","reviveStationPlaylistDetail","revivePlaylistImportResult","PlaylistsClient","fetch","listImportablePlaylists","result","method","reviveCatalogPlaylistPage","parseJson","getPlaylistTracks","pluginId","playlistId","encodeURIComponent","hidePlaylist","showPlaylist","refreshPlaylists","refreshPlaylist","listStationPlaylists","reviveStationPlaylistList","getStationPlaylist","id","reviveStationPlaylistDetail","updateStationPlaylist","body","headers","JSON","stringify","bigIntReplacer","reviveStationPlaylist","deleteStationPlaylist","fillStationPlaylist","exportStationPlaylist","data","contentDisposition","get","undefined","previewPlaylistImport","importPlaylist","revivePlaylistImportResult","PlayoutClient","fetch","getPlayoutStatus","result","method","parseJson","playAPlaylist","body","headers","JSON","stringify","bigIntReplacer","playAStationPlaylist","playAnAlbum","playAChart","skipTheCurrentItem","startPlayout","stopPlayout","DateTime","__dt","v","path","TypeError","d","DateTime","fromISO","isValid","revivePluginSummary","raw","__o0","revivePluginImportResult","__a1","__i2","length","revivePluginDetail","PluginsClient","fetch","listPlugins","result","method","parseJson","map","revivePluginSummary","listPluginGrants","listCapabilityProviders","rescanPlugins","importPlugin","body","revivePluginImportResult","getPlugin","id","encodeURIComponent","revivePluginDetail","removePlugin","updatePluginConfiguration","headers","JSON","stringify","bigIntReplacer","enablePlugin","disablePlugin","decidePluginGrant","reloadPlugin","testPluginConnection","suggestPluginConfigOptions","getPluginLogs","query","qs","buildQueryString","downloadPluginLogs","data","text","contentDisposition","get","undefined","setPluginLogLevel","startPluginOAuthAuthorization","disconnectPluginOAuth","completePluginOAuthAuthorization","DateTime","__dt","v","path","TypeError","d","DateTime","fromISO","isValid","reviveProduction","raw","__o0","reviveProductionRequest","reviveProductionList","__a1","__i2","length","DateTime","__dt","v","path","TypeError","d","DateTime","fromISO","isValid","reviveOwnShow","raw","__o0","reviveOwnEpisodeRequest","reviveOwnShowList","__a1","__i2","length","PodcastsClient","fetch","listShows","result","method","parseJson","searchPodcastDirectory","query","qs","buildQueryString","listEpisodes","fetchEpisode","id","encodeURIComponent","refreshPodcasts","listOwnShows","reviveOwnShowList","createOwnShow","body","headers","JSON","stringify","bigIntReplacer","reviveOwnShow","updateOwnShow","deleteOwnShow","listOwnShowEpisodes","reviveProductionList","requestOwnShowEpisode","reviveProduction","ProductionsClient","fetch","listProductions","result","method","reviveProductionList","parseJson","requestProduction","body","headers","JSON","stringify","bigIntReplacer","reviveProduction","cancelProduction","id","encodeURIComponent","DateTime","__dt","v","path","TypeError","d","DateTime","fromISO","isValid","reviveScriptAttempt","raw","__o0","revivePad","reviveScriptHistoryPage","__a1","__i2","length","revivePadList","RenderClient","fetch","listSegments","result","method","parseJson","createSegment","body","headers","JSON","stringify","bigIntReplacer","uploadSegment","scanTheSegmentInbox","readScriptHistory","query","qs","buildQueryString","reviveScriptHistoryPage","rateScript","id","encodeURIComponent","reviveScriptAttempt","readScriptSummary","listVoices","getDefaultVoiceSample","expectStatuses","status","contentType","readContentType","data","blob","cacheControl","get","undefined","etag","getVoiceSample","voiceId","previewSpeech","deleteSegment","getSegmentAudio","contentDisposition","getStoredAudio","checksum","ext","listPronunciations","createPronunciation","samplePronunciation","updatePronunciation","deletePronunciation","setPronunciationState","listPads","revivePadList","uploadPad","scanThePadLibrary","fetchPad","deletePad","setPadState","setPadUse","getPadAudio","createPadSet","updatePadSet","deletePadSet","setPadMembership","DateTime","__dt","v","path","TypeError","d","DateTime","fromISO","isValid","revivePartyPass","raw","__o0","revivePartyGuestSession","reviveListenerRequest","revivePartyState","reviveListenerRequestList","__a1","__i2","length","RequestsPartyClient","fetch","getParty","result","method","revivePartyState","parseJson","startParty","body","headers","JSON","stringify","bigIntReplacer","revivePartyPass","endParty","joinParty","revivePartyGuestSession","RequestsClient","party","fetch","RequestsPartyClient","searchRequestableRecords","query","qs","buildQueryString","result","method","parseJson","listRequests","reviveListenerRequestList","createRequest","body","headers","JSON","stringify","bigIntReplacer","reviveListenerRequest","listMyRequests","insistOnRequest","id","encodeURIComponent","grantRequest","declineRequest","ScheduleClient","fetch","listSchedule","result","method","parseJson","createScheduleSlot","body","headers","JSON","stringify","bigIntReplacer","readCurrentSlot","readTimetable","query","qs","buildQueryString","updateScheduleSlot","id","encodeURIComponent","deleteScheduleSlot","readSlotPlaylistPosition","restartSlotPlaylist","SettingsClient","fetch","getSettings","result","method","parseJson","updateSettings","body","headers","JSON","stringify","bigIntReplacer","checkSignInProviders","previewInvitation","query","qs","buildQueryString","DateTime","__dt","v","path","TypeError","d","DateTime","fromISO","isValid","reviveLogSource","raw","__o0","reviveLogSourceList","__a1","__i2","length","DateTime","__dt","v","path","TypeError","d","DateTime","fromISO","isValid","__dtf","fmt","fromFormat","reviveStationHeartbeat","raw","__o0","reviveStationModelHolder","reviveStationRelease","reviveStationModel","reviveStationReleases","__a1","__i2","length","__a3","__i4","reviveStationCheckup","DateTime","__dt","v","path","TypeError","d","DateTime","fromISO","isValid","reviveTraceDecision","raw","__o0","reviveTraceSpan","reviveTracesPage","__a1","__i2","length","reviveTraceDetail","__a3","__i4","StationClient","fetch","listLogs","result","method","reviveLogSourceList","parseJson","readLog","id","query","qs","buildQueryString","encodeURIComponent","downloadLog","data","text","headers","contentDisposition","get","undefined","readStationAttention","dismissStationAttention","code","readStationCheckup","reviveStationCheckup","readStationReleases","reviveStationReleases","checkStationReleases","readTraces","reviveTracesPage","readTrace","reviveTraceDetail","DateTime","__dt","v","path","TypeError","d","DateTime","fromISO","isValid","reviveStorageReport","raw","__o0","StorageClient","fetch","readStorage","result","method","reviveStorageReport","parseJson","StreamClient","fetch","getHLSPlaylist","name","result","encodeURIComponent","method","data","blob","headers","cacheControl","get","undefined","getTuneInPls","getTuneInM3u","readFetcherAuthorization","parseJson","startFetcherAuthorization","finishFetcherAuthorization","body","JSON","stringify","bigIntReplacer","TopicsClient","fetch","listTopics","query","qs","buildQueryString","result","method","parseJson","createTopic","body","headers","JSON","stringify","bigIntReplacer","listTopicKinds","updateTopic","id","encodeURIComponent","deleteTopic","DateTime","__dt","v","path","TypeError","d","DateTime","fromISO","isValid","reviveUserSummary","raw","__o0","reviveUserSignIn","reviveUserPage","__a1","__i2","length","reviveUserDetail","reviveSession","__a3","__i4","DateTime","__dt","v","path","TypeError","d","DateTime","fromISO","isValid","reviveInvitationDetails","raw","__o0","reviveInvitation","reviveInvitationList","__a1","__i2","length","UsersInvitationsClient","fetch","listInvitations","result","method","reviveInvitationList","parseJson","createInvitation","body","headers","JSON","stringify","bigIntReplacer","reviveInvitation","revokeInvitation","id","encodeURIComponent","readInvitation","reviveInvitationDetails","startAcceptingInvitation","acceptInvitation","UsersClient","invitations","fetch","UsersInvitationsClient","listUsers","query","qs","buildQueryString","result","method","reviveUserPage","parseJson","getUser","id","encodeURIComponent","reviveUserDetail","changeUserRole","body","headers","JSON","stringify","bigIntReplacer","reviveUserSummary","deactivateUser","reactivateUser","signOutUser","resetUserMFA","DeadairSdk","activity","art","authentication","catalog","charts","director","events","history","languages","messaging","metrics","narrations","news","nowplaying","oauth","onboarding","outputs","personas","playlists","playout","plugins","podcasts","productions","render","requests","schedule","settings","station","storage","stream","topics","users","options","sdkFetch","fetch","createSdkFetch","ActivityClient","ArtClient","AuthenticationClient","CatalogClient","ChartsClient","DirectorClient","EventsClient","HistoryClient","LanguagesClient","MessagingClient","MetricsClient","NarrationsClient","NewsClient","NowplayingClient","OauthClient","OnboardingClient","OutputsClient","PersonasClient","PlaylistsClient","PlayoutClient","PluginsClient","PodcastsClient","ProductionsClient","RenderClient","RequestsClient","ScheduleClient","SettingsClient","StationClient","StorageClient","StreamClient","TopicsClient","UsersClient"]}
|