slackmark 0.6.0 → 0.6.2

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/slack.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"slack.js","names":[],"sources":["../src/receipts.ts","../src/errors.ts","../src/slack/slack-upload-error.ts","../src/slack/fetch-slack-uploader.ts"],"sourcesContent":["export const UploadPhase = {\n Requested: \"requested\",\n Allocated: \"allocated\",\n Uploaded: \"uploaded\",\n Completed: \"completed\",\n Shared: \"shared\",\n Unknown: \"unknown\",\n} as const;\n\nexport type UploadPhase = (typeof UploadPhase)[keyof typeof UploadPhase];\n\nexport const UploadProcessing = {\n NotRequested: \"not-requested\",\n Pending: \"pending\",\n Verified: \"verified\",\n Unverified: \"unverified\",\n} as const;\n\nexport type UploadProcessing = (typeof UploadProcessing)[keyof typeof UploadProcessing];\n\nexport const RetrySafety = {\n Never: \"never\",\n Safe: \"safe\",\n MayDuplicate: \"may-duplicate\",\n} as const;\n\nexport type RetrySafety = (typeof RetrySafety)[keyof typeof RetrySafety];\n\nexport interface UploadReceipt {\n readonly kind: \"upload\";\n readonly provider: string;\n readonly rendererId?: string | undefined;\n readonly filename?: string | undefined;\n readonly phase: UploadPhase;\n readonly fileId?: string | undefined;\n readonly shared: boolean;\n readonly processing: UploadProcessing;\n readonly status?: number | undefined;\n readonly retryAfterMs?: number | undefined;\n readonly providerCode?: string | undefined;\n readonly retrySafety: RetrySafety;\n}\n","import type { UploadReceipt } from \"./receipts.js\";\n\n/**\n * Registry-keyed markers, not module-local symbols.\n *\n * Each published entry (`slackmark`, `slackmark/renderers`, `slackmark/slack`) is bundled\n * without code splitting, so every entry carries its own copy of these classes and\n * `instanceof` is false for an error that crosses an entry boundary. `Symbol.for` keys are\n * shared by every copy, which is what makes the exported guards below reliable. Prefer\n * those guards to `instanceof` for any error that can cross an entry.\n */\nconst RECEIPT_SNAPSHOT_LOCK = Symbol.for(\"slackmark.receiptSnapshotLock\");\nconst OPERATION_ERROR_CARRIER = Symbol.for(\"slackmark.operationErrorCarrier\");\nconst CONFIGURATION_ERROR_BRAND = Symbol.for(\"slackmark.error.configuration\");\nconst OPERATION_ERROR_BRAND = Symbol.for(\"slackmark.error.operation\");\n\n/**\n * Marks a class prototype so instances from any bundled copy answer to one identity.\n * Subclasses inherit the brand, and instances carry no extra own property.\n */\nexport function brandErrorPrototype(prototype: object, brand: symbol): void {\n Object.defineProperty(prototype, brand, {\n configurable: false,\n enumerable: false,\n value: true,\n writable: false,\n });\n}\n\n/**\n * Reads a brand without trusting the value: a hostile getter must not escape a guard.\n */\nexport function hasErrorBrand(value: unknown, brand: symbol): boolean {\n if (typeof value !== \"object\" || value === null) {\n return false;\n }\n try {\n return Reflect.get(value, brand) === true;\n } catch {\n return false;\n }\n}\n\n/**\n * Programmer/configuration error thrown only from the composition root.\n */\nexport interface ConfigurationErrorOptions {\n readonly code?: string | undefined;\n readonly stage?: string | undefined;\n readonly receipts?: ReadonlyArray<UploadReceipt> | undefined;\n readonly settledReceipts?: Promise<ReadonlyArray<UploadReceipt>> | undefined;\n readonly cause?: unknown;\n}\n\nexport class ConfigurationError extends Error {\n static {\n brandErrorPrototype(this.prototype, CONFIGURATION_ERROR_BRAND);\n }\n\n override readonly name: string;\n readonly code: string;\n readonly stage: string | undefined;\n readonly retryable: false;\n readonly receipts: ReadonlyArray<UploadReceipt>;\n readonly settledReceipts: Promise<ReadonlyArray<UploadReceipt>>;\n\n constructor(message: string, options: ConfigurationErrorOptions = {}) {\n super(message, options?.cause !== undefined ? { cause: options.cause } : undefined);\n this.name = \"ConfigurationError\";\n this.code = options.code ?? \"invalid_configuration\";\n this.stage = options.stage;\n this.retryable = false;\n this.receipts = freezeReceipts(options.receipts ?? []);\n this.settledReceipts = options.settledReceipts ?? Promise.resolve(this.receipts);\n }\n}\n\nexport const OperationErrorCode = {\n Aborted: \"operation_aborted\",\n DeadlineExceeded: \"operation_deadline_exceeded\",\n Shutdown: \"operation_shutdown\",\n} as const;\n\nexport type OperationErrorCode = (typeof OperationErrorCode)[keyof typeof OperationErrorCode];\n\nexport interface OperationErrorOptions {\n readonly receipts?: ReadonlyArray<UploadReceipt> | undefined;\n readonly settledReceipts?: Promise<ReadonlyArray<UploadReceipt>> | undefined;\n readonly cause?: unknown;\n}\n\n/**\n * Operational control-flow error. These failures are never degradations.\n */\nexport class OperationError extends Error {\n static {\n brandErrorPrototype(this.prototype, OPERATION_ERROR_BRAND);\n }\n\n override readonly name: string;\n readonly code: OperationErrorCode;\n readonly stage: string;\n readonly retryable: boolean;\n readonly receipts: ReadonlyArray<UploadReceipt>;\n readonly settledReceipts: Promise<ReadonlyArray<UploadReceipt>>;\n\n constructor(\n message: string,\n code: OperationErrorCode,\n stage: string,\n retryable: boolean,\n options: OperationErrorOptions = {},\n ) {\n super(message, options.cause !== undefined ? { cause: options.cause } : undefined);\n this.name = \"OperationError\";\n this.code = code;\n this.stage = stage;\n this.retryable = retryable;\n this.receipts = freezeReceipts(options.receipts ?? []);\n this.settledReceipts = options.settledReceipts ?? Promise.resolve(this.receipts);\n }\n}\n\nexport class OperationAbortedError extends OperationError {\n override readonly name: string;\n\n constructor(stage: string, options: OperationErrorOptions = {}) {\n super(\"Operation aborted by caller\", OperationErrorCode.Aborted, stage, false, options);\n this.name = \"OperationAbortedError\";\n }\n}\n\nexport class OperationDeadlineExceededError extends OperationError {\n override readonly name: string;\n\n constructor(stage: string, options: OperationErrorOptions = {}) {\n super(\"Operation deadline exceeded\", OperationErrorCode.DeadlineExceeded, stage, true, options);\n this.name = \"OperationDeadlineExceededError\";\n }\n}\n\nexport class OperationShutdownError extends OperationError {\n override readonly name: string;\n\n constructor(stage: string, options: OperationErrorOptions = {}) {\n super(\"Operation interrupted by shutdown\", OperationErrorCode.Shutdown, stage, true, options);\n this.name = \"OperationShutdownError\";\n }\n}\n\n/**\n * Identifies a {@link ConfigurationError} from any entry of this package.\n *\n * Use this instead of `instanceof` when the error may have been thrown by a different\n * entry — for example a `ConfigurationError` from `slackmark/renderers` caught by code\n * that imported the class from `slackmark`.\n */\nexport function isConfigurationError(value: unknown): value is ConfigurationError {\n return hasErrorBrand(value, CONFIGURATION_ERROR_BRAND);\n}\n\n/**\n * Identifies an {@link OperationError} — abort, deadline, or shutdown — from any entry of\n * this package, including its subclasses.\n *\n * Use this instead of `instanceof` when the error may have been thrown by a different\n * entry — for example an abort raised inside `FetchSlackUploader` from `slackmark/slack`\n * caught by code that imported the class from `slackmark`. Narrow further with `code`\n * against {@link OperationErrorCode} rather than testing a subclass with `instanceof`.\n */\nexport function isOperationError(value: unknown): value is OperationError {\n return hasErrorBrand(value, OPERATION_ERROR_BRAND);\n}\n\nexport function cloneOperationError(error: OperationError, fallbackStage: string): OperationError {\n const stage = error.stage.length > 0 ? error.stage : fallbackStage;\n const options: OperationErrorOptions = {\n cause: error,\n receipts: error.receipts,\n settledReceipts: error.settledReceipts,\n };\n let cloned: OperationError;\n switch (error.code) {\n case OperationErrorCode.Aborted:\n cloned = new OperationAbortedError(stage, options);\n break;\n case OperationErrorCode.DeadlineExceeded:\n cloned = new OperationDeadlineExceededError(stage, options);\n break;\n case OperationErrorCode.Shutdown:\n cloned = new OperationShutdownError(stage, options);\n break;\n }\n Reflect.defineProperty(cloned, OPERATION_ERROR_CARRIER, {\n configurable: false,\n enumerable: false,\n value: true,\n writable: false,\n });\n return cloned;\n}\n\nexport function isOperationErrorCarrier(error: OperationError): boolean {\n return Reflect.get(error, OPERATION_ERROR_CARRIER) === true;\n}\n\nexport function cloneConfigurationError(error: ConfigurationError): ConfigurationError {\n return new ConfigurationError(error.message, {\n code: error.code,\n stage: error.stage,\n cause: error,\n receipts: error.receipts,\n settledReceipts: error.settledReceipts,\n });\n}\n\nexport function attachReceipts(\n error: unknown,\n receipts: ReadonlyArray<UploadReceipt>,\n settledReceipts?: Promise<ReadonlyArray<UploadReceipt>>,\n): unknown {\n if (!(error instanceof Error)) {\n return error;\n }\n try {\n if (Reflect.get(error, RECEIPT_SNAPSHOT_LOCK) === true) {\n return error;\n }\n } catch {\n return error;\n }\n let existing: ReadonlyArray<UploadReceipt> = [];\n try {\n const candidate = Reflect.get(error, \"receipts\");\n if (Array.isArray(candidate)) {\n existing = candidate.filter(isUploadReceipt);\n }\n } catch {\n existing = [];\n }\n Reflect.defineProperty(error, \"receipts\", {\n configurable: true,\n enumerable: true,\n value: freezeReceipts(mergeReceipts(existing, receipts)),\n writable: false,\n });\n if (settledReceipts !== undefined) {\n const finalReceipts = freezeSettledReceipts(settledReceipts, receipts);\n Reflect.defineProperty(error, \"settledReceipts\", {\n configurable: true,\n enumerable: true,\n value: finalReceipts,\n writable: false,\n });\n }\n return error;\n}\n\nexport function lockReceiptSnapshot(error: unknown): unknown {\n if (error instanceof Error) {\n Reflect.defineProperty(error, RECEIPT_SNAPSHOT_LOCK, {\n configurable: false,\n enumerable: false,\n value: true,\n writable: false,\n });\n }\n return error;\n}\n\nasync function freezeSettledReceipts(\n settledReceipts: Promise<ReadonlyArray<UploadReceipt>>,\n fallback: ReadonlyArray<UploadReceipt>,\n): Promise<ReadonlyArray<UploadReceipt>> {\n try {\n return freezeReceipts(await settledReceipts);\n } catch {\n return freezeReceipts(fallback);\n }\n}\n\nfunction mergeReceipts(\n existing: ReadonlyArray<UploadReceipt>,\n incoming: ReadonlyArray<UploadReceipt>,\n): ReadonlyArray<UploadReceipt> {\n const existingGroups = groupReceipts(existing);\n const incomingGroups = groupReceipts(incoming);\n const merged: UploadReceipt[] = [...incoming];\n for (const [key, values] of existingGroups) {\n const overlap = incomingGroups.get(key)?.length ?? 0;\n if (values.length > overlap) {\n merged.push(...values.slice(overlap));\n }\n }\n return merged;\n}\n\nfunction groupReceipts(\n receipts: ReadonlyArray<UploadReceipt>,\n): ReadonlyMap<string, ReadonlyArray<UploadReceipt>> {\n const grouped = new Map<string, UploadReceipt[]>();\n for (const receipt of receipts) {\n const key = receiptKey(receipt);\n const values = grouped.get(key);\n if (values === undefined) {\n grouped.set(key, [receipt]);\n } else {\n values.push(receipt);\n }\n }\n return grouped;\n}\n\nfunction receiptKey(receipt: UploadReceipt): string {\n return [\n receipt.provider,\n receipt.phase,\n receipt.fileId ?? \"\",\n String(receipt.shared),\n receipt.processing,\n String(receipt.status ?? \"\"),\n String(receipt.retryAfterMs ?? \"\"),\n receipt.providerCode ?? \"\",\n receipt.retrySafety,\n ].join(\"\\u0000\");\n}\n\nfunction freezeReceipts(receipts: ReadonlyArray<UploadReceipt>): ReadonlyArray<UploadReceipt> {\n return Object.freeze(receipts.map((receipt) => Object.freeze({ ...receipt })));\n}\n\nfunction isUploadReceipt(value: unknown): value is UploadReceipt {\n return typeof value === \"object\" && value !== null && Reflect.get(value, \"kind\") === \"upload\";\n}\n","import { brandErrorPrototype, hasErrorBrand } from \"../errors.js\";\nimport { RetrySafety, UploadPhase, UploadProcessing, type UploadReceipt } from \"../types.js\";\n\n/** See the brand rationale in `errors.ts`: this class is bundled into more than one entry. */\nconst SLACK_UPLOAD_ERROR_BRAND = Symbol.for(\"slackmark.error.slackUpload\");\n\nexport const SlackUploadStage = {\n Admission: \"admission\",\n GetUploadUrl: \"get-upload-url\",\n UploadBytes: \"upload-bytes\",\n CompleteUpload: \"complete-upload\",\n FileInfo: \"file-info\",\n ProcessingTimeout: \"processing-timeout\",\n} as const;\n\nexport type SlackUploadStage = (typeof SlackUploadStage)[keyof typeof SlackUploadStage];\n\nexport interface SlackUploadErrorDetails {\n readonly stage: SlackUploadStage;\n readonly status?: number | undefined;\n readonly code?: string | undefined;\n readonly retryable?: boolean | undefined;\n readonly retryAfterMs?: number | undefined;\n readonly receipt?: UploadReceipt | undefined;\n readonly cause?: unknown;\n}\n\n/**\n * Integration error from one explicit stage of Slack's external-upload flow.\n */\nexport class SlackUploadError extends Error {\n static {\n brandErrorPrototype(this.prototype, SLACK_UPLOAD_ERROR_BRAND);\n }\n\n override readonly name: string;\n readonly stage: SlackUploadStage;\n readonly status: number | undefined;\n readonly code: string | undefined;\n readonly retryable: boolean;\n readonly retryAfterMs: number | undefined;\n readonly receipt: UploadReceipt;\n readonly receipts: ReadonlyArray<UploadReceipt>;\n readonly settledReceipts: Promise<ReadonlyArray<UploadReceipt>>;\n\n constructor(message: string, details: SlackUploadErrorDetails) {\n super(message, details.cause !== undefined ? { cause: details.cause } : undefined);\n this.name = \"SlackUploadError\";\n this.stage = details.stage;\n this.status = details.status;\n this.code = details.code;\n this.retryable = details.retryable ?? isRetryable(details.status, details.code);\n this.retryAfterMs = details.retryAfterMs;\n this.receipt = Object.freeze(\n details.receipt ?? {\n kind: \"upload\",\n provider: \"slack\",\n phase: UploadPhase.Requested,\n fileId: undefined,\n shared: false,\n processing: UploadProcessing.NotRequested,\n status: details.status,\n retryAfterMs: details.retryAfterMs,\n providerCode: details.code,\n retrySafety: RetrySafety.Safe,\n },\n );\n this.receipts = Object.freeze([this.receipt]);\n this.settledReceipts = Promise.resolve(this.receipts);\n }\n}\n\n/**\n * Identifies a {@link SlackUploadError} from any entry of this package. `slackmark` and\n * `slackmark/slack` each bundle their own copy, so `instanceof` is unreliable when the\n * error crosses between them.\n */\nexport function isSlackUploadError(value: unknown): value is SlackUploadError {\n return hasErrorBrand(value, SLACK_UPLOAD_ERROR_BRAND);\n}\n\nfunction isRetryable(status: number | undefined, code: string | undefined): boolean {\n return (\n status === 429 ||\n (status !== undefined && status >= 500) ||\n code === \"fetch_failed\" ||\n code === \"request_timeout\" ||\n code === \"processing_timeout\"\n );\n}\n","import {\n RetrySafety,\n UploadPhase,\n UploadProcessing,\n type BytesImage,\n type OperationContext,\n type SlackUploader,\n type UploadReceipt,\n} from \"../types.js\";\nimport {\n ConfigurationError,\n OperationAbortedError,\n OperationDeadlineExceededError,\n OperationErrorCode,\n attachReceipts,\n isOperationError,\n type OperationError,\n} from \"../errors.js\";\n\nimport {\n SlackUploadError,\n SlackUploadStage,\n isSlackUploadError,\n type SlackUploadStage as SlackUploadStageType,\n} from \"./slack-upload-error.js\";\n\nconst SLACK_API_BASE_URL = \"https://slack.com/api\";\nconst DEFAULT_POLL_INTERVAL_MS = 250;\nconst DEFAULT_POLL_MAX_ATTEMPTS = 20;\nconst DEFAULT_POLL_TIMEOUT_MS = 30_000;\nconst DEFAULT_REQUEST_TIMEOUT_MS = 10_000;\n\nexport interface SlackFetchRequestInit {\n readonly method: \"POST\";\n readonly headers: Readonly<Record<string, string>>;\n readonly body: string | Uint8Array;\n readonly signal?: AbortSignal;\n}\n\nexport interface SlackFetchResponse {\n readonly ok: boolean;\n readonly status: number;\n readonly headers?: { get(name: string): string | null };\n json(): Promise<unknown>;\n}\n\nexport type SlackFetch = (\n input: string,\n init: SlackFetchRequestInit,\n) => Promise<SlackFetchResponse>;\n\nexport type SlackUploadSleep = (milliseconds: number) => Promise<void>;\nexport type SlackUploadClock = () => number;\n\nexport interface SlackUploadPollOptions {\n readonly intervalMs?: number;\n readonly maxAttempts?: number;\n readonly timeoutMs?: number;\n readonly sleep?: SlackUploadSleep;\n readonly clock?: SlackUploadClock;\n}\n\nexport interface FetchSlackUploaderOptions {\n readonly token: string;\n readonly fetch?: SlackFetch;\n readonly channelId?: string;\n readonly requestTimeoutMs?: number;\n readonly waitForProcessing?: boolean;\n readonly poll?: SlackUploadPollOptions;\n}\n\ninterface UploadTarget {\n readonly uploadUrl: string;\n readonly fileId: string;\n}\n\ninterface ResolvedFetchSlackUploaderOptions {\n readonly token: string;\n readonly fetcher: SlackFetch;\n readonly channelId: string | undefined;\n readonly requestTimeoutMs: number;\n readonly waitForProcessing: boolean;\n readonly pollIntervalMs: number;\n readonly pollMaxAttempts: number;\n readonly pollTimeoutMs: number;\n readonly sleep: SlackUploadSleep;\n readonly clock: SlackUploadClock;\n}\n\n/**\n * Web-standard implementation of Slack's external file-upload flow.\n *\n * @see https://docs.slack.dev/messaging/working-with-files\n */\nexport class FetchSlackUploader implements SlackUploader {\n private readonly token: string;\n private readonly fetcher: SlackFetch;\n private readonly channelId: string | undefined;\n private readonly requestTimeoutMs: number;\n private readonly waitForProcessing: boolean;\n private readonly pollIntervalMs: number;\n private readonly pollMaxAttempts: number;\n private readonly pollTimeoutMs: number;\n private readonly sleep: SlackUploadSleep;\n private readonly clock: SlackUploadClock;\n\n constructor(options: FetchSlackUploaderOptions) {\n const resolved = resolveUploaderOptions(options);\n this.token = resolved.token;\n this.fetcher = resolved.fetcher;\n this.channelId = resolved.channelId;\n this.requestTimeoutMs = resolved.requestTimeoutMs;\n this.waitForProcessing = resolved.waitForProcessing;\n this.pollIntervalMs = resolved.pollIntervalMs;\n this.pollMaxAttempts = resolved.pollMaxAttempts;\n this.pollTimeoutMs = resolved.pollTimeoutMs;\n this.sleep = resolved.sleep;\n this.clock = resolved.clock;\n }\n\n async upload(\n img: BytesImage,\n context: OperationContext,\n ): Promise<{ readonly fileId: string; readonly receipt: UploadReceipt }> {\n let receipt = slackReceipt({\n phase: UploadPhase.Requested,\n processing: UploadProcessing.NotRequested,\n retrySafety: RetrySafety.Safe,\n });\n try {\n const target = await this.getUploadTarget(img, context);\n receipt = slackReceipt({\n phase: UploadPhase.Allocated,\n fileId: target.fileId,\n processing: UploadProcessing.NotRequested,\n retrySafety: RetrySafety.MayDuplicate,\n });\n await this.uploadBytes(target, img, context);\n receipt = slackReceipt({\n phase: UploadPhase.Uploaded,\n fileId: target.fileId,\n processing: UploadProcessing.NotRequested,\n retrySafety: RetrySafety.MayDuplicate,\n });\n await this.completeUpload(target.fileId, img.filename, context);\n receipt = slackReceipt({\n phase: this.channelId === undefined ? UploadPhase.Completed : UploadPhase.Shared,\n fileId: target.fileId,\n shared: this.channelId !== undefined,\n processing: this.waitForProcessing\n ? UploadProcessing.Pending\n : UploadProcessing.NotRequested,\n retrySafety: RetrySafety.Never,\n });\n if (this.waitForProcessing) {\n try {\n await this.waitUntilProcessed(target.fileId, receipt, context);\n receipt = slackReceipt({\n ...receipt,\n processing: UploadProcessing.Verified,\n });\n } catch (error) {\n if (isOperationError(error)) {\n throw attachReceipts(error, [receipt]);\n }\n if (isSlackUploadError(error)) {\n receipt = slackReceipt({\n ...receipt,\n processing: UploadProcessing.Unverified,\n status: error.status,\n retryAfterMs: error.retryAfterMs,\n providerCode: error.code,\n });\n } else {\n receipt = slackReceipt({\n ...receipt,\n processing: UploadProcessing.Unverified,\n providerCode: \"processing_failed\",\n });\n }\n }\n }\n return { fileId: target.fileId, receipt };\n } catch (error) {\n if (isSlackUploadError(error)) {\n throw withReceipt(error, receipt);\n }\n if (isOperationError(error)) {\n throw attachReceipts(error, [receipt]);\n }\n throw error;\n }\n }\n\n private async getUploadTarget(img: BytesImage, control: OperationContext): Promise<UploadTarget> {\n const payload = await this.callSlackApi(\n \"files.getUploadURLExternal\",\n encodeForm([\n [\"filename\", img.filename],\n [\"length\", String(img.data.byteLength)],\n ]),\n SlackUploadStage.GetUploadUrl,\n control,\n );\n const uploadUrl = payload[\"upload_url\"];\n const fileId = payload[\"file_id\"];\n if (!isNonEmptyString(uploadUrl) || !isNonEmptyString(fileId)) {\n throw new SlackUploadError(\"files.getUploadURLExternal returned no upload_url or file_id\", {\n stage: SlackUploadStage.GetUploadUrl,\n code: \"invalid_response\",\n });\n }\n return { uploadUrl, fileId };\n }\n\n private async uploadBytes(\n target: UploadTarget,\n img: BytesImage,\n control: OperationContext,\n ): Promise<void> {\n const stageSignal = createStageSignal(control, this.requestTimeoutMs, this.clock);\n let response: SlackFetchResponse;\n try {\n response = await this.fetcher(target.uploadUrl, {\n method: \"POST\",\n headers: { \"content-type\": img.mimeType },\n body: img.data,\n signal: stageSignal.signal,\n });\n } catch (cause) {\n const operationError = stageSignal.operationError(SlackUploadStage.UploadBytes, cause);\n if (operationError !== undefined) {\n throw operationError;\n }\n throw new SlackUploadError(\"Slack byte upload failed\", {\n stage: SlackUploadStage.UploadBytes,\n code: stageSignal.code(),\n cause,\n });\n } finally {\n stageSignal.cleanup();\n }\n if (!response.ok) {\n throw new SlackUploadError(\"Slack byte upload was rejected\", {\n stage: SlackUploadStage.UploadBytes,\n status: response.status,\n code: `http_${String(response.status)}`,\n retryAfterMs: retryAfterMs(response),\n });\n }\n }\n\n private async completeUpload(\n fileId: string,\n filename: string,\n control: OperationContext,\n ): Promise<void> {\n const fields: Array<readonly [string, string]> = [\n [\n \"files\",\n JSON.stringify([\n {\n id: fileId,\n title: filename,\n },\n ]),\n ],\n ];\n if (this.channelId !== undefined) {\n fields.push([\"channel_id\", this.channelId]);\n }\n await this.callSlackApi(\n \"files.completeUploadExternal\",\n encodeForm(fields),\n SlackUploadStage.CompleteUpload,\n control,\n );\n }\n\n private async waitUntilProcessed(\n fileId: string,\n receipt: UploadReceipt,\n control: OperationContext,\n ): Promise<void> {\n const startedAt = this.clock();\n const pollDeadlineMs = startedAt + this.pollTimeoutMs;\n const pollOwnsDeadline =\n control.deadlineMs === undefined || pollDeadlineMs < control.deadlineMs;\n const pollContext: OperationContext = {\n signal: control.signal,\n deadlineMs: Math.min(control.deadlineMs ?? Number.POSITIVE_INFINITY, pollDeadlineMs),\n };\n\n for (let attempt = 1; attempt <= this.pollMaxAttempts; attempt += 1) {\n if (this.clock() >= pollDeadlineMs) {\n throw processingTimeout(receipt, attempt - 1);\n }\n let payload: Record<string, unknown>;\n try {\n payload = await this.callSlackApi(\n \"files.info\",\n encodeForm([[\"file\", fileId]]),\n SlackUploadStage.FileInfo,\n pollContext,\n );\n } catch (error) {\n if (pollOwnsDeadline && isOperationDeadline(error)) {\n throw processingTimeout(receipt, attempt);\n }\n throw error;\n }\n if (isProcessedImageFile(payload[\"file\"])) {\n return;\n }\n\n if (attempt === this.pollMaxAttempts || this.clock() - startedAt >= this.pollTimeoutMs) {\n throw processingTimeout(receipt, attempt);\n }\n\n try {\n await controlledSleep(\n this.sleep,\n Math.min(this.pollIntervalMs, Math.max(0, pollDeadlineMs - this.clock())),\n pollContext,\n this.clock,\n );\n } catch (error) {\n if (pollOwnsDeadline && isOperationDeadline(error)) {\n throw processingTimeout(receipt, attempt);\n }\n throw error;\n }\n\n if (this.clock() - startedAt >= this.pollTimeoutMs) {\n throw processingTimeout(receipt, attempt);\n }\n }\n }\n\n private async callSlackApi(\n method: string,\n body: string,\n stage: SlackUploadStageType,\n control: OperationContext,\n ): Promise<Record<string, unknown>> {\n const stageSignal = createStageSignal(control, this.requestTimeoutMs, this.clock);\n let response: SlackFetchResponse;\n try {\n response = await this.fetcher(`${SLACK_API_BASE_URL}/${method}`, {\n method: \"POST\",\n headers: {\n authorization: `Bearer ${this.token}`,\n \"content-type\": \"application/x-www-form-urlencoded;charset=UTF-8\",\n },\n body,\n signal: stageSignal.signal,\n });\n } catch (cause) {\n const operationError = stageSignal.operationError(stage, cause);\n stageSignal.cleanup();\n if (operationError !== undefined) {\n throw operationError;\n }\n throw new SlackUploadError(\"Slack API request failed\", {\n stage,\n code: stageSignal.code(),\n cause,\n });\n }\n\n let payload: unknown;\n try {\n payload = await raceWithSignal(response.json(), stageSignal.signal);\n } catch (cause) {\n const operationError = stageSignal.operationError(stage, cause);\n const signalCode = stageSignal.code();\n if (operationError !== undefined) {\n throw operationError;\n }\n throw new SlackUploadError(\"Slack API returned invalid JSON\", {\n stage,\n status: response.status,\n code: signalCode === \"fetch_failed\" ? \"invalid_json\" : signalCode,\n cause,\n });\n } finally {\n stageSignal.cleanup();\n }\n\n const slackCode = getSlackErrorCode(payload);\n if (!response.ok || !isRecord(payload) || payload[\"ok\"] !== true) {\n throw new SlackUploadError(\"Slack API rejected the request\", {\n stage,\n status: response.status,\n code: slackCode ?? (response.ok ? \"invalid_response\" : `http_${String(response.status)}`),\n retryAfterMs: retryAfterMs(response),\n });\n }\n return payload;\n }\n}\n\nfunction resolveUploaderOptions(\n options: FetchSlackUploaderOptions,\n): ResolvedFetchSlackUploaderOptions {\n assertKnownPlainObject(\n options,\n [\"token\", \"fetch\", \"channelId\", \"requestTimeoutMs\", \"waitForProcessing\", \"poll\"],\n \"FetchSlackUploader options\",\n );\n let token: unknown;\n let fetcher: unknown;\n let channelId: unknown;\n let requestTimeoutMs: unknown;\n let waitForProcessing: unknown;\n let poll: unknown;\n try {\n token = Reflect.get(options, \"token\");\n fetcher = Reflect.get(options, \"fetch\");\n channelId = Reflect.get(options, \"channelId\");\n requestTimeoutMs = Reflect.get(options, \"requestTimeoutMs\");\n waitForProcessing = Reflect.get(options, \"waitForProcessing\");\n poll = Reflect.get(options, \"poll\");\n } catch (cause) {\n throw invalidUploaderOptions(\"Uploader options could not be read\", cause);\n }\n if (typeof token !== \"string\" || token.length === 0 || token !== token.trim()) {\n throw invalidUploaderOptions(\"token must be a nonempty trimmed string\");\n }\n if (\n channelId !== undefined &&\n (typeof channelId !== \"string\" || channelId.length === 0 || channelId !== channelId.trim())\n ) {\n throw invalidUploaderOptions(\"channelId must be a nonempty trimmed string\");\n }\n if (fetcher !== undefined && typeof fetcher !== \"function\") {\n throw invalidUploaderOptions(\"fetch must be a function\");\n }\n if (\n requestTimeoutMs !== undefined &&\n (typeof requestTimeoutMs !== \"number\" ||\n !Number.isFinite(requestTimeoutMs) ||\n requestTimeoutMs <= 0)\n ) {\n throw invalidUploaderOptions(\"requestTimeoutMs must be positive\");\n }\n if (waitForProcessing !== undefined && typeof waitForProcessing !== \"boolean\") {\n throw invalidUploaderOptions(\"waitForProcessing must be boolean\");\n }\n\n const resolvedPoll = resolvePollOptions(poll);\n return {\n token,\n fetcher: (fetcher as SlackFetch | undefined) ?? defaultFetch,\n channelId: channelId as string | undefined,\n requestTimeoutMs: (requestTimeoutMs as number | undefined) ?? DEFAULT_REQUEST_TIMEOUT_MS,\n waitForProcessing: (waitForProcessing as boolean | undefined) ?? false,\n pollIntervalMs: resolvedPoll.intervalMs,\n pollMaxAttempts: resolvedPoll.maxAttempts,\n pollTimeoutMs: resolvedPoll.timeoutMs,\n sleep: resolvedPoll.sleep,\n clock: resolvedPoll.clock,\n };\n}\n\nfunction resolvePollOptions(poll: unknown): {\n readonly intervalMs: number;\n readonly maxAttempts: number;\n readonly timeoutMs: number;\n readonly sleep: SlackUploadSleep;\n readonly clock: SlackUploadClock;\n} {\n if (poll === undefined) {\n return {\n intervalMs: DEFAULT_POLL_INTERVAL_MS,\n maxAttempts: DEFAULT_POLL_MAX_ATTEMPTS,\n timeoutMs: DEFAULT_POLL_TIMEOUT_MS,\n sleep: defaultSleep,\n clock: defaultClock,\n };\n }\n assertKnownPlainObject(\n poll,\n [\"intervalMs\", \"maxAttempts\", \"timeoutMs\", \"sleep\", \"clock\"],\n \"poll options\",\n );\n let intervalMs: unknown;\n let maxAttempts: unknown;\n let timeoutMs: unknown;\n let sleep: unknown;\n let clock: unknown;\n try {\n intervalMs = Reflect.get(poll, \"intervalMs\");\n maxAttempts = Reflect.get(poll, \"maxAttempts\");\n timeoutMs = Reflect.get(poll, \"timeoutMs\");\n sleep = Reflect.get(poll, \"sleep\");\n clock = Reflect.get(poll, \"clock\");\n } catch (cause) {\n throw invalidUploaderOptions(\"poll options could not be read\", cause);\n }\n const resolvedInterval = (intervalMs as number | undefined) ?? DEFAULT_POLL_INTERVAL_MS;\n const resolvedAttempts = (maxAttempts as number | undefined) ?? DEFAULT_POLL_MAX_ATTEMPTS;\n const resolvedTimeout = (timeoutMs as number | undefined) ?? DEFAULT_POLL_TIMEOUT_MS;\n if (!Number.isInteger(resolvedInterval) || resolvedInterval < 0) {\n throw invalidUploaderOptions(\"poll.intervalMs must be a non-negative integer\");\n }\n if (!Number.isInteger(resolvedAttempts) || resolvedAttempts <= 0) {\n throw invalidUploaderOptions(\"poll.maxAttempts must be a positive integer\");\n }\n if (!Number.isFinite(resolvedTimeout) || resolvedTimeout <= 0) {\n throw invalidUploaderOptions(\"poll.timeoutMs must be positive\");\n }\n if (sleep !== undefined && typeof sleep !== \"function\") {\n throw invalidUploaderOptions(\"poll.sleep must be a function\");\n }\n if (clock !== undefined && typeof clock !== \"function\") {\n throw invalidUploaderOptions(\"poll.clock must be a function\");\n }\n return {\n intervalMs: resolvedInterval,\n maxAttempts: resolvedAttempts,\n timeoutMs: resolvedTimeout,\n sleep: (sleep as SlackUploadSleep | undefined) ?? defaultSleep,\n clock: (clock as SlackUploadClock | undefined) ?? defaultClock,\n };\n}\n\nfunction assertKnownPlainObject(\n value: unknown,\n allowed: ReadonlyArray<string>,\n label: string,\n): asserts value is object {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n throw invalidUploaderOptions(`${label} must be a plain object`);\n }\n let prototype: object | null;\n let keys: ReadonlyArray<string>;\n try {\n prototype = Object.getPrototypeOf(value);\n keys = Object.keys(value);\n } catch (cause) {\n throw invalidUploaderOptions(`${label} could not be inspected`, cause);\n }\n if (prototype !== Object.prototype && prototype !== null) {\n throw invalidUploaderOptions(`${label} must be a plain object`);\n }\n const allowedKeys = new Set(allowed);\n for (const key of keys) {\n if (!allowedKeys.has(key)) {\n throw invalidUploaderOptions(`Unknown ${label} key: ${key}`);\n }\n }\n}\n\nfunction invalidUploaderOptions(message: string, cause?: unknown): ConfigurationError {\n return new ConfigurationError(message, {\n code: \"invalid_slack_uploader_options\",\n stage: \"configuration\",\n cause,\n });\n}\n\nfunction encodeForm(fields: ReadonlyArray<readonly [string, string]>): string {\n return fields\n .map(([name, value]) => `${encodeURIComponent(name)}=${encodeURIComponent(value)}`)\n .join(\"&\");\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction isNonEmptyString(value: unknown): value is string {\n return typeof value === \"string\" && value.length > 0;\n}\n\nfunction isPositiveNumber(value: unknown): value is number {\n return typeof value === \"number\" && Number.isFinite(value) && value > 0;\n}\n\nfunction isProcessedImageFile(value: unknown): boolean {\n if (!isRecord(value)) {\n return false;\n }\n return (\n isNonEmptyString(value[\"mimetype\"]) &&\n isNonEmptyString(value[\"filetype\"]) &&\n isPositiveNumber(value[\"original_w\"]) &&\n isPositiveNumber(value[\"original_h\"])\n );\n}\n\nfunction getSlackErrorCode(payload: unknown): string | undefined {\n if (!isRecord(payload)) {\n return undefined;\n }\n const error = payload[\"error\"];\n return typeof error === \"string\" ? error : undefined;\n}\n\nfunction processingTimeout(receipt: UploadReceipt, attempts: number): SlackUploadError {\n return new SlackUploadError(\n `Slack file processing did not complete after ${String(attempts)} polls`,\n {\n stage: SlackUploadStage.ProcessingTimeout,\n code: \"processing_timeout\",\n receipt: slackReceipt({\n ...receipt,\n processing: UploadProcessing.Unverified,\n providerCode: \"processing_timeout\",\n }),\n },\n );\n}\n\n/**\n * Subclass identity is as bundle-sensitive as the base class, so discriminate on `code`.\n */\nfunction isOperationDeadline(error: unknown): boolean {\n return isOperationError(error) && error.code === OperationErrorCode.DeadlineExceeded;\n}\n\ninterface StageSignal {\n readonly signal: AbortSignal;\n cleanup(): void;\n code(): \"aborted\" | \"request_timeout\" | \"fetch_failed\";\n operationError(stage: string, cause: unknown): OperationError | undefined;\n}\n\nfunction createStageSignal(\n control: OperationContext,\n requestTimeoutMs: number,\n clock: SlackUploadClock,\n): StageSignal {\n const controller = new AbortController();\n let timeoutKind: \"operation\" | \"request\" | undefined;\n const abortFromCaller = (): void => {\n controller.abort(control.signal?.reason);\n };\n if (control.signal?.aborted === true) {\n abortFromCaller();\n } else {\n control.signal?.addEventListener(\"abort\", abortFromCaller, { once: true });\n }\n const requestDeadlineMs = clock() + requestTimeoutMs;\n const operationDeadlineMs = control.deadlineMs ?? Number.POSITIVE_INFINITY;\n const stageDeadline = Math.min(requestDeadlineMs, operationDeadlineMs);\n const remaining = Math.max(0, stageDeadline - clock());\n const timeout = setTimeout(() => {\n timeoutKind = operationDeadlineMs <= requestDeadlineMs ? \"operation\" : \"request\";\n controller.abort(new Error(\"Slack request deadline exceeded\"));\n }, remaining);\n return {\n signal: controller.signal,\n cleanup: (): void => {\n clearTimeout(timeout);\n control.signal?.removeEventListener(\"abort\", abortFromCaller);\n },\n code: (): \"aborted\" | \"request_timeout\" | \"fetch_failed\" => {\n if (timeoutKind !== undefined) {\n return \"request_timeout\";\n }\n return control.signal?.aborted === true ? \"aborted\" : \"fetch_failed\";\n },\n operationError: (stage: string, cause: unknown): OperationError | undefined => {\n if (control.signal?.aborted === true) {\n return new OperationAbortedError(stage, { cause });\n }\n if (timeoutKind === \"operation\") {\n return new OperationDeadlineExceededError(stage, { cause });\n }\n return undefined;\n },\n };\n}\n\nfunction controlledSleep(\n sleep: SlackUploadSleep,\n milliseconds: number,\n control: OperationContext,\n clock: SlackUploadClock,\n): Promise<void> {\n if (control.signal?.aborted === true) {\n return Promise.reject(\n new OperationAbortedError(SlackUploadStage.ProcessingTimeout, {\n cause: control.signal.reason,\n }),\n );\n }\n if (control.deadlineMs !== undefined && clock() >= control.deadlineMs) {\n return Promise.reject(new OperationDeadlineExceededError(SlackUploadStage.ProcessingTimeout));\n }\n return new Promise<void>((resolve, reject) => {\n const onAbort = (): void => {\n cleanup();\n reject(\n new OperationAbortedError(SlackUploadStage.ProcessingTimeout, {\n cause: control.signal?.reason,\n }),\n );\n };\n const onDeadline = (): void => {\n cleanup();\n reject(new OperationDeadlineExceededError(SlackUploadStage.ProcessingTimeout));\n };\n const deadlineTimer =\n control.deadlineMs === undefined\n ? undefined\n : setTimeout(onDeadline, Math.max(0, control.deadlineMs - clock()));\n const cleanup = (): void => {\n if (deadlineTimer !== undefined) {\n clearTimeout(deadlineTimer);\n }\n control.signal?.removeEventListener(\"abort\", onAbort);\n };\n control.signal?.addEventListener(\"abort\", onAbort, { once: true });\n void sleep(milliseconds).then(\n () => {\n cleanup();\n resolve();\n return undefined;\n },\n (error: unknown) => {\n cleanup();\n reject(error);\n return undefined;\n },\n );\n });\n}\n\nfunction raceWithSignal<T>(promise: Promise<T>, signal: AbortSignal): Promise<T> {\n if (signal.aborted) {\n return Promise.reject(signal.reason);\n }\n return new Promise<T>((resolve, reject) => {\n const onAbort = (): void => {\n signal.removeEventListener(\"abort\", onAbort);\n reject(signal.reason);\n };\n signal.addEventListener(\"abort\", onAbort, { once: true });\n void promise.then(\n (value) => {\n signal.removeEventListener(\"abort\", onAbort);\n resolve(value);\n return undefined;\n },\n (error: unknown) => {\n signal.removeEventListener(\"abort\", onAbort);\n reject(error);\n return undefined;\n },\n );\n });\n}\n\nfunction slackReceipt(options: {\n readonly phase: UploadReceipt[\"phase\"];\n readonly fileId?: string | undefined;\n readonly shared?: boolean | undefined;\n readonly processing: UploadReceipt[\"processing\"];\n readonly status?: number | undefined;\n readonly retryAfterMs?: number | undefined;\n readonly providerCode?: string | undefined;\n readonly retrySafety?: UploadReceipt[\"retrySafety\"] | undefined;\n}): UploadReceipt {\n return Object.freeze({\n kind: \"upload\",\n provider: \"slack\",\n phase: options.phase,\n fileId: options.fileId,\n shared: options.shared ?? false,\n processing: options.processing,\n status: options.status,\n retryAfterMs: options.retryAfterMs,\n providerCode: options.providerCode,\n retrySafety: options.retrySafety ?? RetrySafety.Never,\n });\n}\n\nfunction withReceipt(error: SlackUploadError, receipt: UploadReceipt): SlackUploadError {\n return new SlackUploadError(error.message, {\n stage: error.stage,\n status: error.status,\n code: error.code,\n retryable: error.retryable,\n retryAfterMs: error.retryAfterMs,\n receipt: slackReceipt({\n ...receipt,\n status: error.status,\n retryAfterMs: error.retryAfterMs,\n providerCode: error.code,\n retrySafety:\n receipt.phase === UploadPhase.Requested\n ? RetrySafety.Safe\n : receipt.phase === UploadPhase.Completed || receipt.phase === UploadPhase.Shared\n ? RetrySafety.Never\n : RetrySafety.MayDuplicate,\n }),\n cause: error.cause,\n });\n}\n\nfunction retryAfterMs(response: SlackFetchResponse): number | undefined {\n const raw = response.headers?.get(\"retry-after\");\n if (raw === undefined || raw === null) {\n return undefined;\n }\n const seconds = Number(raw);\n return Number.isFinite(seconds) && seconds >= 0 ? seconds * 1_000 : undefined;\n}\n\nfunction defaultFetch(input: string, init: SlackFetchRequestInit): Promise<SlackFetchResponse> {\n return globalThis.fetch(input, init);\n}\n\nfunction defaultSleep(milliseconds: number): Promise<void> {\n return new Promise((resolve) => {\n setTimeout(resolve, milliseconds);\n });\n}\n\nfunction defaultClock(): number {\n return Date.now();\n}\n"],"mappings":";AAAA,MAAa,cAAc;CACzB,WAAW;CACX,WAAW;CACX,UAAU;CACV,WAAW;CACX,QAAQ;CACR,SAAS;AACX;AAIA,MAAa,mBAAmB;CAC9B,cAAc;CACd,SAAS;CACT,UAAU;CACV,YAAY;AACd;AAIA,MAAa,cAAc;CACzB,OAAO;CACP,MAAM;CACN,cAAc;AAChB;;;;;;;;;;;;ACbA,MAAM,wBAAwB,OAAO,IAAI,+BAA+B;AAExE,MAAM,4BAA4B,OAAO,IAAI,+BAA+B;AAC5E,MAAM,wBAAwB,OAAO,IAAI,2BAA2B;;;;;AAMpE,SAAgB,oBAAoB,WAAmB,OAAqB;CAC1E,OAAO,eAAe,WAAW,OAAO;EACtC,cAAc;EACd,YAAY;EACZ,OAAO;EACP,UAAU;CACZ,CAAC;AACH;;;;AAKA,SAAgB,cAAc,OAAgB,OAAwB;CACpE,IAAI,OAAO,UAAU,YAAY,UAAU,MACzC,OAAO;CAET,IAAI;EACF,OAAO,QAAQ,IAAI,OAAO,KAAK,MAAM;CACvC,QAAQ;EACN,OAAO;CACT;AACF;AAaA,IAAa,qBAAb,cAAwC,MAAM;CAC5C;EACE,oBAAoB,KAAK,WAAW,yBAAyB;CAC/D;CAEA;CACA;CACA;CACA;CACA;CACA;CAEA,YAAY,SAAiB,UAAqC,CAAC,GAAG;EACpE,MAAM,SAAS,SAAS,UAAU,KAAA,IAAY,EAAE,OAAO,QAAQ,MAAM,IAAI,KAAA,CAAS;EAClF,KAAK,OAAO;EACZ,KAAK,OAAO,QAAQ,QAAQ;EAC5B,KAAK,QAAQ,QAAQ;EACrB,KAAK,YAAY;EACjB,KAAK,WAAW,eAAe,QAAQ,YAAY,CAAC,CAAC;EACrD,KAAK,kBAAkB,QAAQ,mBAAmB,QAAQ,QAAQ,KAAK,QAAQ;CACjF;AACF;AAEA,MAAa,qBAAqB;CAChC,SAAS;CACT,kBAAkB;CAClB,UAAU;AACZ;;;;AAaA,IAAa,iBAAb,cAAoC,MAAM;CACxC;EACE,oBAAoB,KAAK,WAAW,qBAAqB;CAC3D;CAEA;CACA;CACA;CACA;CACA;CACA;CAEA,YACE,SACA,MACA,OACA,WACA,UAAiC,CAAC,GAClC;EACA,MAAM,SAAS,QAAQ,UAAU,KAAA,IAAY,EAAE,OAAO,QAAQ,MAAM,IAAI,KAAA,CAAS;EACjF,KAAK,OAAO;EACZ,KAAK,OAAO;EACZ,KAAK,QAAQ;EACb,KAAK,YAAY;EACjB,KAAK,WAAW,eAAe,QAAQ,YAAY,CAAC,CAAC;EACrD,KAAK,kBAAkB,QAAQ,mBAAmB,QAAQ,QAAQ,KAAK,QAAQ;CACjF;AACF;AAEA,IAAa,wBAAb,cAA2C,eAAe;CACxD;CAEA,YAAY,OAAe,UAAiC,CAAC,GAAG;EAC9D,MAAM,+BAA+B,mBAAmB,SAAS,OAAO,OAAO,OAAO;EACtF,KAAK,OAAO;CACd;AACF;AAEA,IAAa,iCAAb,cAAoD,eAAe;CACjE;CAEA,YAAY,OAAe,UAAiC,CAAC,GAAG;EAC9D,MAAM,+BAA+B,mBAAmB,kBAAkB,OAAO,MAAM,OAAO;EAC9F,KAAK,OAAO;CACd;AACF;;;;;;;;;;AA+BA,SAAgB,iBAAiB,OAAyC;CACxE,OAAO,cAAc,OAAO,qBAAqB;AACnD;AA4CA,SAAgB,eACd,OACA,UACA,iBACS;CACT,IAAI,EAAE,iBAAiB,QACrB,OAAO;CAET,IAAI;EACF,IAAI,QAAQ,IAAI,OAAO,qBAAqB,MAAM,MAChD,OAAO;CAEX,QAAQ;EACN,OAAO;CACT;CACA,IAAI,WAAyC,CAAC;CAC9C,IAAI;EACF,MAAM,YAAY,QAAQ,IAAI,OAAO,UAAU;EAC/C,IAAI,MAAM,QAAQ,SAAS,GACzB,WAAW,UAAU,OAAO,eAAe;CAE/C,QAAQ;EACN,WAAW,CAAC;CACd;CACA,QAAQ,eAAe,OAAO,YAAY;EACxC,cAAc;EACd,YAAY;EACZ,OAAO,eAAe,cAAc,UAAU,QAAQ,CAAC;EACvD,UAAU;CACZ,CAAC;CACD,IAAI,oBAAoB,KAAA,GAAW;EACjC,MAAM,gBAAgB,sBAAsB,iBAAiB,QAAQ;EACrE,QAAQ,eAAe,OAAO,mBAAmB;GAC/C,cAAc;GACd,YAAY;GACZ,OAAO;GACP,UAAU;EACZ,CAAC;CACH;CACA,OAAO;AACT;AAcA,eAAe,sBACb,iBACA,UACuC;CACvC,IAAI;EACF,OAAO,eAAe,MAAM,eAAe;CAC7C,QAAQ;EACN,OAAO,eAAe,QAAQ;CAChC;AACF;AAEA,SAAS,cACP,UACA,UAC8B;CAC9B,MAAM,iBAAiB,cAAc,QAAQ;CAC7C,MAAM,iBAAiB,cAAc,QAAQ;CAC7C,MAAM,SAA0B,CAAC,GAAG,QAAQ;CAC5C,KAAK,MAAM,CAAC,KAAK,WAAW,gBAAgB;EAC1C,MAAM,UAAU,eAAe,IAAI,GAAG,CAAC,EAAE,UAAU;EACnD,IAAI,OAAO,SAAS,SAClB,OAAO,KAAK,GAAG,OAAO,MAAM,OAAO,CAAC;CAExC;CACA,OAAO;AACT;AAEA,SAAS,cACP,UACmD;CACnD,MAAM,0BAAU,IAAI,IAA6B;CACjD,KAAK,MAAM,WAAW,UAAU;EAC9B,MAAM,MAAM,WAAW,OAAO;EAC9B,MAAM,SAAS,QAAQ,IAAI,GAAG;EAC9B,IAAI,WAAW,KAAA,GACb,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC;OAE1B,OAAO,KAAK,OAAO;CAEvB;CACA,OAAO;AACT;AAEA,SAAS,WAAW,SAAgC;CAClD,OAAO;EACL,QAAQ;EACR,QAAQ;EACR,QAAQ,UAAU;EAClB,OAAO,QAAQ,MAAM;EACrB,QAAQ;EACR,OAAO,QAAQ,UAAU,EAAE;EAC3B,OAAO,QAAQ,gBAAgB,EAAE;EACjC,QAAQ,gBAAgB;EACxB,QAAQ;CACV,CAAC,CAAC,KAAK,IAAQ;AACjB;AAEA,SAAS,eAAe,UAAsE;CAC5F,OAAO,OAAO,OAAO,SAAS,KAAK,YAAY,OAAO,OAAO,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAC;AAC/E;AAEA,SAAS,gBAAgB,OAAwC;CAC/D,OAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,QAAQ,IAAI,OAAO,MAAM,MAAM;AACvF;;;;ACzUA,MAAM,2BAA2B,OAAO,IAAI,6BAA6B;AAEzE,MAAa,mBAAmB;CAC9B,WAAW;CACX,cAAc;CACd,aAAa;CACb,gBAAgB;CAChB,UAAU;CACV,mBAAmB;AACrB;;;;AAiBA,IAAa,mBAAb,cAAsC,MAAM;CAC1C;EACE,oBAAoB,KAAK,WAAW,wBAAwB;CAC9D;CAEA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CAEA,YAAY,SAAiB,SAAkC;EAC7D,MAAM,SAAS,QAAQ,UAAU,KAAA,IAAY,EAAE,OAAO,QAAQ,MAAM,IAAI,KAAA,CAAS;EACjF,KAAK,OAAO;EACZ,KAAK,QAAQ,QAAQ;EACrB,KAAK,SAAS,QAAQ;EACtB,KAAK,OAAO,QAAQ;EACpB,KAAK,YAAY,QAAQ,aAAa,YAAY,QAAQ,QAAQ,QAAQ,IAAI;EAC9E,KAAK,eAAe,QAAQ;EAC5B,KAAK,UAAU,OAAO,OACpB,QAAQ,WAAW;GACjB,MAAM;GACN,UAAU;GACV,OAAO,YAAY;GACnB,QAAQ,KAAA;GACR,QAAQ;GACR,YAAY,iBAAiB;GAC7B,QAAQ,QAAQ;GAChB,cAAc,QAAQ;GACtB,cAAc,QAAQ;GACtB,aAAa,YAAY;EAC3B,CACF;EACA,KAAK,WAAW,OAAO,OAAO,CAAC,KAAK,OAAO,CAAC;EAC5C,KAAK,kBAAkB,QAAQ,QAAQ,KAAK,QAAQ;CACtD;AACF;;;;;;AAOA,SAAgB,mBAAmB,OAA2C;CAC5E,OAAO,cAAc,OAAO,wBAAwB;AACtD;AAEA,SAAS,YAAY,QAA4B,MAAmC;CAClF,OACE,WAAW,OACV,WAAW,KAAA,KAAa,UAAU,OACnC,SAAS,kBACT,SAAS,qBACT,SAAS;AAEb;;;AC/DA,MAAM,qBAAqB;AAC3B,MAAM,2BAA2B;AACjC,MAAM,4BAA4B;AAClC,MAAM,0BAA0B;AAChC,MAAM,6BAA6B;;;;;;AAgEnC,IAAa,qBAAb,MAAyD;CACvD;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CAEA,YAAY,SAAoC;EAC9C,MAAM,WAAW,uBAAuB,OAAO;EAC/C,KAAK,QAAQ,SAAS;EACtB,KAAK,UAAU,SAAS;EACxB,KAAK,YAAY,SAAS;EAC1B,KAAK,mBAAmB,SAAS;EACjC,KAAK,oBAAoB,SAAS;EAClC,KAAK,iBAAiB,SAAS;EAC/B,KAAK,kBAAkB,SAAS;EAChC,KAAK,gBAAgB,SAAS;EAC9B,KAAK,QAAQ,SAAS;EACtB,KAAK,QAAQ,SAAS;CACxB;CAEA,MAAM,OACJ,KACA,SACuE;EACvE,IAAI,UAAU,aAAa;GACzB,OAAO,YAAY;GACnB,YAAY,iBAAiB;GAC7B,aAAa,YAAY;EAC3B,CAAC;EACD,IAAI;GACF,MAAM,SAAS,MAAM,KAAK,gBAAgB,KAAK,OAAO;GACtD,UAAU,aAAa;IACrB,OAAO,YAAY;IACnB,QAAQ,OAAO;IACf,YAAY,iBAAiB;IAC7B,aAAa,YAAY;GAC3B,CAAC;GACD,MAAM,KAAK,YAAY,QAAQ,KAAK,OAAO;GAC3C,UAAU,aAAa;IACrB,OAAO,YAAY;IACnB,QAAQ,OAAO;IACf,YAAY,iBAAiB;IAC7B,aAAa,YAAY;GAC3B,CAAC;GACD,MAAM,KAAK,eAAe,OAAO,QAAQ,IAAI,UAAU,OAAO;GAC9D,UAAU,aAAa;IACrB,OAAO,KAAK,cAAc,KAAA,IAAY,YAAY,YAAY,YAAY;IAC1E,QAAQ,OAAO;IACf,QAAQ,KAAK,cAAc,KAAA;IAC3B,YAAY,KAAK,oBACb,iBAAiB,UACjB,iBAAiB;IACrB,aAAa,YAAY;GAC3B,CAAC;GACD,IAAI,KAAK,mBACP,IAAI;IACF,MAAM,KAAK,mBAAmB,OAAO,QAAQ,SAAS,OAAO;IAC7D,UAAU,aAAa;KACrB,GAAG;KACH,YAAY,iBAAiB;IAC/B,CAAC;GACH,SAAS,OAAO;IACd,IAAI,iBAAiB,KAAK,GACxB,MAAM,eAAe,OAAO,CAAC,OAAO,CAAC;IAEvC,IAAI,mBAAmB,KAAK,GAC1B,UAAU,aAAa;KACrB,GAAG;KACH,YAAY,iBAAiB;KAC7B,QAAQ,MAAM;KACd,cAAc,MAAM;KACpB,cAAc,MAAM;IACtB,CAAC;SAED,UAAU,aAAa;KACrB,GAAG;KACH,YAAY,iBAAiB;KAC7B,cAAc;IAChB,CAAC;GAEL;GAEF,OAAO;IAAE,QAAQ,OAAO;IAAQ;GAAQ;EAC1C,SAAS,OAAO;GACd,IAAI,mBAAmB,KAAK,GAC1B,MAAM,YAAY,OAAO,OAAO;GAElC,IAAI,iBAAiB,KAAK,GACxB,MAAM,eAAe,OAAO,CAAC,OAAO,CAAC;GAEvC,MAAM;EACR;CACF;CAEA,MAAc,gBAAgB,KAAiB,SAAkD;EAC/F,MAAM,UAAU,MAAM,KAAK,aACzB,8BACA,WAAW,CACT,CAAC,YAAY,IAAI,QAAQ,GACzB,CAAC,UAAU,OAAO,IAAI,KAAK,UAAU,CAAC,CACxC,CAAC,GACD,iBAAiB,cACjB,OACF;EACA,MAAM,YAAY,QAAQ;EAC1B,MAAM,SAAS,QAAQ;EACvB,IAAI,CAAC,iBAAiB,SAAS,KAAK,CAAC,iBAAiB,MAAM,GAC1D,MAAM,IAAI,iBAAiB,gEAAgE;GACzF,OAAO,iBAAiB;GACxB,MAAM;EACR,CAAC;EAEH,OAAO;GAAE;GAAW;EAAO;CAC7B;CAEA,MAAc,YACZ,QACA,KACA,SACe;EACf,MAAM,cAAc,kBAAkB,SAAS,KAAK,kBAAkB,KAAK,KAAK;EAChF,IAAI;EACJ,IAAI;GACF,WAAW,MAAM,KAAK,QAAQ,OAAO,WAAW;IAC9C,QAAQ;IACR,SAAS,EAAE,gBAAgB,IAAI,SAAS;IACxC,MAAM,IAAI;IACV,QAAQ,YAAY;GACtB,CAAC;EACH,SAAS,OAAO;GACd,MAAM,iBAAiB,YAAY,eAAe,iBAAiB,aAAa,KAAK;GACrF,IAAI,mBAAmB,KAAA,GACrB,MAAM;GAER,MAAM,IAAI,iBAAiB,4BAA4B;IACrD,OAAO,iBAAiB;IACxB,MAAM,YAAY,KAAK;IACvB;GACF,CAAC;EACH,UAAU;GACR,YAAY,QAAQ;EACtB;EACA,IAAI,CAAC,SAAS,IACZ,MAAM,IAAI,iBAAiB,kCAAkC;GAC3D,OAAO,iBAAiB;GACxB,QAAQ,SAAS;GACjB,MAAM,QAAQ,OAAO,SAAS,MAAM;GACpC,cAAc,aAAa,QAAQ;EACrC,CAAC;CAEL;CAEA,MAAc,eACZ,QACA,UACA,SACe;EACf,MAAM,SAA2C,CAC/C,CACE,SACA,KAAK,UAAU,CACb;GACE,IAAI;GACJ,OAAO;EACT,CACF,CAAC,CACH,CACF;EACA,IAAI,KAAK,cAAc,KAAA,GACrB,OAAO,KAAK,CAAC,cAAc,KAAK,SAAS,CAAC;EAE5C,MAAM,KAAK,aACT,gCACA,WAAW,MAAM,GACjB,iBAAiB,gBACjB,OACF;CACF;CAEA,MAAc,mBACZ,QACA,SACA,SACe;EACf,MAAM,YAAY,KAAK,MAAM;EAC7B,MAAM,iBAAiB,YAAY,KAAK;EACxC,MAAM,mBACJ,QAAQ,eAAe,KAAA,KAAa,iBAAiB,QAAQ;EAC/D,MAAM,cAAgC;GACpC,QAAQ,QAAQ;GAChB,YAAY,KAAK,IAAI,QAAQ,cAAc,OAAO,mBAAmB,cAAc;EACrF;EAEA,KAAK,IAAI,UAAU,GAAG,WAAW,KAAK,iBAAiB,WAAW,GAAG;GACnE,IAAI,KAAK,MAAM,KAAK,gBAClB,MAAM,kBAAkB,SAAS,UAAU,CAAC;GAE9C,IAAI;GACJ,IAAI;IACF,UAAU,MAAM,KAAK,aACnB,cACA,WAAW,CAAC,CAAC,QAAQ,MAAM,CAAC,CAAC,GAC7B,iBAAiB,UACjB,WACF;GACF,SAAS,OAAO;IACd,IAAI,oBAAoB,oBAAoB,KAAK,GAC/C,MAAM,kBAAkB,SAAS,OAAO;IAE1C,MAAM;GACR;GACA,IAAI,qBAAqB,QAAQ,OAAO,GACtC;GAGF,IAAI,YAAY,KAAK,mBAAmB,KAAK,MAAM,IAAI,aAAa,KAAK,eACvE,MAAM,kBAAkB,SAAS,OAAO;GAG1C,IAAI;IACF,MAAM,gBACJ,KAAK,OACL,KAAK,IAAI,KAAK,gBAAgB,KAAK,IAAI,GAAG,iBAAiB,KAAK,MAAM,CAAC,CAAC,GACxE,aACA,KAAK,KACP;GACF,SAAS,OAAO;IACd,IAAI,oBAAoB,oBAAoB,KAAK,GAC/C,MAAM,kBAAkB,SAAS,OAAO;IAE1C,MAAM;GACR;GAEA,IAAI,KAAK,MAAM,IAAI,aAAa,KAAK,eACnC,MAAM,kBAAkB,SAAS,OAAO;EAE5C;CACF;CAEA,MAAc,aACZ,QACA,MACA,OACA,SACkC;EAClC,MAAM,cAAc,kBAAkB,SAAS,KAAK,kBAAkB,KAAK,KAAK;EAChF,IAAI;EACJ,IAAI;GACF,WAAW,MAAM,KAAK,QAAQ,GAAG,mBAAmB,GAAG,UAAU;IAC/D,QAAQ;IACR,SAAS;KACP,eAAe,UAAU,KAAK;KAC9B,gBAAgB;IAClB;IACA;IACA,QAAQ,YAAY;GACtB,CAAC;EACH,SAAS,OAAO;GACd,MAAM,iBAAiB,YAAY,eAAe,OAAO,KAAK;GAC9D,YAAY,QAAQ;GACpB,IAAI,mBAAmB,KAAA,GACrB,MAAM;GAER,MAAM,IAAI,iBAAiB,4BAA4B;IACrD;IACA,MAAM,YAAY,KAAK;IACvB;GACF,CAAC;EACH;EAEA,IAAI;EACJ,IAAI;GACF,UAAU,MAAM,eAAe,SAAS,KAAK,GAAG,YAAY,MAAM;EACpE,SAAS,OAAO;GACd,MAAM,iBAAiB,YAAY,eAAe,OAAO,KAAK;GAC9D,MAAM,aAAa,YAAY,KAAK;GACpC,IAAI,mBAAmB,KAAA,GACrB,MAAM;GAER,MAAM,IAAI,iBAAiB,mCAAmC;IAC5D;IACA,QAAQ,SAAS;IACjB,MAAM,eAAe,iBAAiB,iBAAiB;IACvD;GACF,CAAC;EACH,UAAU;GACR,YAAY,QAAQ;EACtB;EAEA,MAAM,YAAY,kBAAkB,OAAO;EAC3C,IAAI,CAAC,SAAS,MAAM,CAAC,SAAS,OAAO,KAAK,QAAQ,UAAU,MAC1D,MAAM,IAAI,iBAAiB,kCAAkC;GAC3D;GACA,QAAQ,SAAS;GACjB,MAAM,cAAc,SAAS,KAAK,qBAAqB,QAAQ,OAAO,SAAS,MAAM;GACrF,cAAc,aAAa,QAAQ;EACrC,CAAC;EAEH,OAAO;CACT;AACF;AAEA,SAAS,uBACP,SACmC;CACnC,uBACE,SACA;EAAC;EAAS;EAAS;EAAa;EAAoB;EAAqB;CAAM,GAC/E,4BACF;CACA,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;EACF,QAAQ,QAAQ,IAAI,SAAS,OAAO;EACpC,UAAU,QAAQ,IAAI,SAAS,OAAO;EACtC,YAAY,QAAQ,IAAI,SAAS,WAAW;EAC5C,mBAAmB,QAAQ,IAAI,SAAS,kBAAkB;EAC1D,oBAAoB,QAAQ,IAAI,SAAS,mBAAmB;EAC5D,OAAO,QAAQ,IAAI,SAAS,MAAM;CACpC,SAAS,OAAO;EACd,MAAM,uBAAuB,sCAAsC,KAAK;CAC1E;CACA,IAAI,OAAO,UAAU,YAAY,MAAM,WAAW,KAAK,UAAU,MAAM,KAAK,GAC1E,MAAM,uBAAuB,yCAAyC;CAExE,IACE,cAAc,KAAA,MACb,OAAO,cAAc,YAAY,UAAU,WAAW,KAAK,cAAc,UAAU,KAAK,IAEzF,MAAM,uBAAuB,6CAA6C;CAE5E,IAAI,YAAY,KAAA,KAAa,OAAO,YAAY,YAC9C,MAAM,uBAAuB,0BAA0B;CAEzD,IACE,qBAAqB,KAAA,MACpB,OAAO,qBAAqB,YAC3B,CAAC,OAAO,SAAS,gBAAgB,KACjC,oBAAoB,IAEtB,MAAM,uBAAuB,mCAAmC;CAElE,IAAI,sBAAsB,KAAA,KAAa,OAAO,sBAAsB,WAClE,MAAM,uBAAuB,mCAAmC;CAGlE,MAAM,eAAe,mBAAmB,IAAI;CAC5C,OAAO;EACL;EACA,SAAU,WAAsC;EACrC;EACX,kBAAmB,oBAA2C;EAC9D,mBAAoB,qBAA6C;EACjE,gBAAgB,aAAa;EAC7B,iBAAiB,aAAa;EAC9B,eAAe,aAAa;EAC5B,OAAO,aAAa;EACpB,OAAO,aAAa;CACtB;AACF;AAEA,SAAS,mBAAmB,MAM1B;CACA,IAAI,SAAS,KAAA,GACX,OAAO;EACL,YAAY;EACZ,aAAa;EACb,WAAW;EACX,OAAO;EACP,OAAO;CACT;CAEF,uBACE,MACA;EAAC;EAAc;EAAe;EAAa;EAAS;CAAO,GAC3D,cACF;CACA,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;CACJ,IAAI;EACF,aAAa,QAAQ,IAAI,MAAM,YAAY;EAC3C,cAAc,QAAQ,IAAI,MAAM,aAAa;EAC7C,YAAY,QAAQ,IAAI,MAAM,WAAW;EACzC,QAAQ,QAAQ,IAAI,MAAM,OAAO;EACjC,QAAQ,QAAQ,IAAI,MAAM,OAAO;CACnC,SAAS,OAAO;EACd,MAAM,uBAAuB,kCAAkC,KAAK;CACtE;CACA,MAAM,mBAAoB,cAAqC;CAC/D,MAAM,mBAAoB,eAAsC;CAChE,MAAM,kBAAmB,aAAoC;CAC7D,IAAI,CAAC,OAAO,UAAU,gBAAgB,KAAK,mBAAmB,GAC5D,MAAM,uBAAuB,gDAAgD;CAE/E,IAAI,CAAC,OAAO,UAAU,gBAAgB,KAAK,oBAAoB,GAC7D,MAAM,uBAAuB,6CAA6C;CAE5E,IAAI,CAAC,OAAO,SAAS,eAAe,KAAK,mBAAmB,GAC1D,MAAM,uBAAuB,iCAAiC;CAEhE,IAAI,UAAU,KAAA,KAAa,OAAO,UAAU,YAC1C,MAAM,uBAAuB,+BAA+B;CAE9D,IAAI,UAAU,KAAA,KAAa,OAAO,UAAU,YAC1C,MAAM,uBAAuB,+BAA+B;CAE9D,OAAO;EACL,YAAY;EACZ,aAAa;EACb,WAAW;EACX,OAAQ,SAA0C;EAClD,OAAQ,SAA0C;CACpD;AACF;AAEA,SAAS,uBACP,OACA,SACA,OACyB;CACzB,IAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,MAAM,QAAQ,KAAK,GACpE,MAAM,uBAAuB,GAAG,MAAM,wBAAwB;CAEhE,IAAI;CACJ,IAAI;CACJ,IAAI;EACF,YAAY,OAAO,eAAe,KAAK;EACvC,OAAO,OAAO,KAAK,KAAK;CAC1B,SAAS,OAAO;EACd,MAAM,uBAAuB,GAAG,MAAM,0BAA0B,KAAK;CACvE;CACA,IAAI,cAAc,OAAO,aAAa,cAAc,MAClD,MAAM,uBAAuB,GAAG,MAAM,wBAAwB;CAEhE,MAAM,cAAc,IAAI,IAAI,OAAO;CACnC,KAAK,MAAM,OAAO,MAChB,IAAI,CAAC,YAAY,IAAI,GAAG,GACtB,MAAM,uBAAuB,WAAW,MAAM,QAAQ,KAAK;AAGjE;AAEA,SAAS,uBAAuB,SAAiB,OAAqC;CACpF,OAAO,IAAI,mBAAmB,SAAS;EACrC,MAAM;EACN,OAAO;EACP;CACF,CAAC;AACH;AAEA,SAAS,WAAW,QAA0D;CAC5E,OAAO,OACJ,KAAK,CAAC,MAAM,WAAW,GAAG,mBAAmB,IAAI,EAAE,GAAG,mBAAmB,KAAK,GAAG,CAAC,CAClF,KAAK,GAAG;AACb;AAEA,SAAS,SAAS,OAAkD;CAClE,OAAO,OAAO,UAAU,YAAY,UAAU;AAChD;AAEA,SAAS,iBAAiB,OAAiC;CACzD,OAAO,OAAO,UAAU,YAAY,MAAM,SAAS;AACrD;AAEA,SAAS,iBAAiB,OAAiC;CACzD,OAAO,OAAO,UAAU,YAAY,OAAO,SAAS,KAAK,KAAK,QAAQ;AACxE;AAEA,SAAS,qBAAqB,OAAyB;CACrD,IAAI,CAAC,SAAS,KAAK,GACjB,OAAO;CAET,OACE,iBAAiB,MAAM,WAAW,KAClC,iBAAiB,MAAM,WAAW,KAClC,iBAAiB,MAAM,aAAa,KACpC,iBAAiB,MAAM,aAAa;AAExC;AAEA,SAAS,kBAAkB,SAAsC;CAC/D,IAAI,CAAC,SAAS,OAAO,GACnB;CAEF,MAAM,QAAQ,QAAQ;CACtB,OAAO,OAAO,UAAU,WAAW,QAAQ,KAAA;AAC7C;AAEA,SAAS,kBAAkB,SAAwB,UAAoC;CACrF,OAAO,IAAI,iBACT,gDAAgD,OAAO,QAAQ,EAAE,SACjE;EACE,OAAO,iBAAiB;EACxB,MAAM;EACN,SAAS,aAAa;GACpB,GAAG;GACH,YAAY,iBAAiB;GAC7B,cAAc;EAChB,CAAC;CACH,CACF;AACF;;;;AAKA,SAAS,oBAAoB,OAAyB;CACpD,OAAO,iBAAiB,KAAK,KAAK,MAAM,SAAS,mBAAmB;AACtE;AASA,SAAS,kBACP,SACA,kBACA,OACa;CACb,MAAM,aAAa,IAAI,gBAAgB;CACvC,IAAI;CACJ,MAAM,wBAA8B;EAClC,WAAW,MAAM,QAAQ,QAAQ,MAAM;CACzC;CACA,IAAI,QAAQ,QAAQ,YAAY,MAC9B,gBAAgB;MAEhB,QAAQ,QAAQ,iBAAiB,SAAS,iBAAiB,EAAE,MAAM,KAAK,CAAC;CAE3E,MAAM,oBAAoB,MAAM,IAAI;CACpC,MAAM,sBAAsB,QAAQ,cAAc,OAAO;CAEzD,MAAM,YAAY,KAAK,IAAI,GADL,KAAK,IAAI,mBAAmB,mBACR,IAAI,MAAM,CAAC;CACrD,MAAM,UAAU,iBAAiB;EAC/B,cAAc,uBAAuB,oBAAoB,cAAc;EACvE,WAAW,sBAAM,IAAI,MAAM,iCAAiC,CAAC;CAC/D,GAAG,SAAS;CACZ,OAAO;EACL,QAAQ,WAAW;EACnB,eAAqB;GACnB,aAAa,OAAO;GACpB,QAAQ,QAAQ,oBAAoB,SAAS,eAAe;EAC9D;EACA,YAA4D;GAC1D,IAAI,gBAAgB,KAAA,GAClB,OAAO;GAET,OAAO,QAAQ,QAAQ,YAAY,OAAO,YAAY;EACxD;EACA,iBAAiB,OAAe,UAA+C;GAC7E,IAAI,QAAQ,QAAQ,YAAY,MAC9B,OAAO,IAAI,sBAAsB,OAAO,EAAE,MAAM,CAAC;GAEnD,IAAI,gBAAgB,aAClB,OAAO,IAAI,+BAA+B,OAAO,EAAE,MAAM,CAAC;EAG9D;CACF;AACF;AAEA,SAAS,gBACP,OACA,cACA,SACA,OACe;CACf,IAAI,QAAQ,QAAQ,YAAY,MAC9B,OAAO,QAAQ,OACb,IAAI,sBAAsB,iBAAiB,mBAAmB,EAC5D,OAAO,QAAQ,OAAO,OACxB,CAAC,CACH;CAEF,IAAI,QAAQ,eAAe,KAAA,KAAa,MAAM,KAAK,QAAQ,YACzD,OAAO,QAAQ,OAAO,IAAI,+BAA+B,iBAAiB,iBAAiB,CAAC;CAE9F,OAAO,IAAI,SAAe,SAAS,WAAW;EAC5C,MAAM,gBAAsB;GAC1B,QAAQ;GACR,OACE,IAAI,sBAAsB,iBAAiB,mBAAmB,EAC5D,OAAO,QAAQ,QAAQ,OACzB,CAAC,CACH;EACF;EACA,MAAM,mBAAyB;GAC7B,QAAQ;GACR,OAAO,IAAI,+BAA+B,iBAAiB,iBAAiB,CAAC;EAC/E;EACA,MAAM,gBACJ,QAAQ,eAAe,KAAA,IACnB,KAAA,IACA,WAAW,YAAY,KAAK,IAAI,GAAG,QAAQ,aAAa,MAAM,CAAC,CAAC;EACtE,MAAM,gBAAsB;GAC1B,IAAI,kBAAkB,KAAA,GACpB,aAAa,aAAa;GAE5B,QAAQ,QAAQ,oBAAoB,SAAS,OAAO;EACtD;EACA,QAAQ,QAAQ,iBAAiB,SAAS,SAAS,EAAE,MAAM,KAAK,CAAC;EACjE,MAAW,YAAY,CAAC,CAAC,WACjB;GACJ,QAAQ;GACR,QAAQ;EAEV,IACC,UAAmB;GAClB,QAAQ;GACR,OAAO,KAAK;EAEd,CACF;CACF,CAAC;AACH;AAEA,SAAS,eAAkB,SAAqB,QAAiC;CAC/E,IAAI,OAAO,SACT,OAAO,QAAQ,OAAO,OAAO,MAAM;CAErC,OAAO,IAAI,SAAY,SAAS,WAAW;EACzC,MAAM,gBAAsB;GAC1B,OAAO,oBAAoB,SAAS,OAAO;GAC3C,OAAO,OAAO,MAAM;EACtB;EACA,OAAO,iBAAiB,SAAS,SAAS,EAAE,MAAM,KAAK,CAAC;EACxD,QAAa,MACV,UAAU;GACT,OAAO,oBAAoB,SAAS,OAAO;GAC3C,QAAQ,KAAK;EAEf,IACC,UAAmB;GAClB,OAAO,oBAAoB,SAAS,OAAO;GAC3C,OAAO,KAAK;EAEd,CACF;CACF,CAAC;AACH;AAEA,SAAS,aAAa,SASJ;CAChB,OAAO,OAAO,OAAO;EACnB,MAAM;EACN,UAAU;EACV,OAAO,QAAQ;EACf,QAAQ,QAAQ;EAChB,QAAQ,QAAQ,UAAU;EAC1B,YAAY,QAAQ;EACpB,QAAQ,QAAQ;EAChB,cAAc,QAAQ;EACtB,cAAc,QAAQ;EACtB,aAAa,QAAQ,eAAe,YAAY;CAClD,CAAC;AACH;AAEA,SAAS,YAAY,OAAyB,SAA0C;CACtF,OAAO,IAAI,iBAAiB,MAAM,SAAS;EACzC,OAAO,MAAM;EACb,QAAQ,MAAM;EACd,MAAM,MAAM;EACZ,WAAW,MAAM;EACjB,cAAc,MAAM;EACpB,SAAS,aAAa;GACpB,GAAG;GACH,QAAQ,MAAM;GACd,cAAc,MAAM;GACpB,cAAc,MAAM;GACpB,aACE,QAAQ,UAAU,YAAY,YAC1B,YAAY,OACZ,QAAQ,UAAU,YAAY,aAAa,QAAQ,UAAU,YAAY,SACvE,YAAY,QACZ,YAAY;EACtB,CAAC;EACD,OAAO,MAAM;CACf,CAAC;AACH;AAEA,SAAS,aAAa,UAAkD;CACtE,MAAM,MAAM,SAAS,SAAS,IAAI,aAAa;CAC/C,IAAI,QAAQ,KAAA,KAAa,QAAQ,MAC/B;CAEF,MAAM,UAAU,OAAO,GAAG;CAC1B,OAAO,OAAO,SAAS,OAAO,KAAK,WAAW,IAAI,UAAU,MAAQ,KAAA;AACtE;AAEA,SAAS,aAAa,OAAe,MAA0D;CAC7F,OAAO,WAAW,MAAM,OAAO,IAAI;AACrC;AAEA,SAAS,aAAa,cAAqC;CACzD,OAAO,IAAI,SAAS,YAAY;EAC9B,WAAW,SAAS,YAAY;CAClC,CAAC;AACH;AAEA,SAAS,eAAuB;CAC9B,OAAO,KAAK,IAAI;AAClB"}
1
+ {"version":3,"file":"slack.js","names":[],"sources":["../src/errors.ts","../src/receipts.ts","../src/slack/slack-upload-error.ts","../src/slack/fetch-slack-uploader.ts"],"sourcesContent":["import type { UploadReceipt } from \"./receipts.js\";\n\n/**\n * Registry-keyed markers, not module-local symbols.\n *\n * Each published entry (`slackmark`, `slackmark/renderers`, `slackmark/slack`) is bundled\n * without code splitting, so every entry carries its own copy of these classes and\n * `instanceof` is false for an error that crosses an entry boundary. `Symbol.for` keys are\n * shared by every copy, which is what makes the exported guards below reliable. Prefer\n * those guards to `instanceof` for any error that can cross an entry.\n */\nconst RECEIPT_SNAPSHOT_LOCK = Symbol.for(\"slackmark.receiptSnapshotLock\");\nconst OPERATION_ERROR_CARRIER = Symbol.for(\"slackmark.operationErrorCarrier\");\nconst CONFIGURATION_ERROR_BRAND = Symbol.for(\"slackmark.error.configuration\");\nconst OPERATION_ERROR_BRAND = Symbol.for(\"slackmark.error.operation\");\n\n/**\n * Marks a class prototype so instances from any bundled copy answer to one identity.\n * Subclasses inherit the brand, and instances carry no extra own property.\n */\nexport function brandErrorPrototype(prototype: object, brand: symbol): void {\n Object.defineProperty(prototype, brand, {\n configurable: false,\n enumerable: false,\n value: true,\n writable: false,\n });\n}\n\n/**\n * Reads a brand without trusting the value: a hostile getter must not escape a guard.\n */\nexport function hasErrorBrand(value: unknown, brand: symbol): boolean {\n if (typeof value !== \"object\" || value === null) {\n return false;\n }\n try {\n return Reflect.get(value, brand) === true;\n } catch {\n return false;\n }\n}\n\n/**\n * Programmer/configuration error thrown only from the composition root.\n */\nexport interface ConfigurationErrorOptions {\n readonly code?: string | undefined;\n readonly stage?: string | undefined;\n readonly receipts?: ReadonlyArray<UploadReceipt> | undefined;\n readonly settledReceipts?: Promise<ReadonlyArray<UploadReceipt>> | undefined;\n readonly cause?: unknown;\n}\n\nexport class ConfigurationError extends Error {\n static {\n brandErrorPrototype(this.prototype, CONFIGURATION_ERROR_BRAND);\n }\n\n override readonly name: string;\n readonly code: string;\n readonly stage: string | undefined;\n readonly retryable: false;\n readonly receipts: ReadonlyArray<UploadReceipt>;\n readonly settledReceipts: Promise<ReadonlyArray<UploadReceipt>>;\n\n constructor(message: string, options: ConfigurationErrorOptions = {}) {\n super(message, options?.cause !== undefined ? { cause: options.cause } : undefined);\n this.name = \"ConfigurationError\";\n this.code = options.code ?? \"invalid_configuration\";\n this.stage = options.stage;\n this.retryable = false;\n this.receipts = freezeReceipts(options.receipts ?? []);\n this.settledReceipts = options.settledReceipts ?? Promise.resolve(this.receipts);\n }\n}\n\nexport const OperationErrorCode = {\n Aborted: \"operation_aborted\",\n DeadlineExceeded: \"operation_deadline_exceeded\",\n Shutdown: \"operation_shutdown\",\n} as const;\n\nexport type OperationErrorCode = (typeof OperationErrorCode)[keyof typeof OperationErrorCode];\n\nexport interface OperationErrorOptions {\n readonly receipts?: ReadonlyArray<UploadReceipt> | undefined;\n readonly settledReceipts?: Promise<ReadonlyArray<UploadReceipt>> | undefined;\n readonly cause?: unknown;\n}\n\n/**\n * Operational control-flow error. These failures are never degradations.\n */\nexport class OperationError extends Error {\n static {\n brandErrorPrototype(this.prototype, OPERATION_ERROR_BRAND);\n }\n\n override readonly name: string;\n readonly code: OperationErrorCode;\n readonly stage: string;\n readonly retryable: boolean;\n readonly receipts: ReadonlyArray<UploadReceipt>;\n readonly settledReceipts: Promise<ReadonlyArray<UploadReceipt>>;\n\n constructor(\n message: string,\n code: OperationErrorCode,\n stage: string,\n retryable: boolean,\n options: OperationErrorOptions = {},\n ) {\n super(message, options.cause !== undefined ? { cause: options.cause } : undefined);\n this.name = \"OperationError\";\n this.code = code;\n this.stage = stage;\n this.retryable = retryable;\n this.receipts = freezeReceipts(options.receipts ?? []);\n this.settledReceipts = options.settledReceipts ?? Promise.resolve(this.receipts);\n }\n}\n\nexport class OperationAbortedError extends OperationError {\n override readonly name: string;\n\n constructor(stage: string, options: OperationErrorOptions = {}) {\n super(\"Operation aborted by caller\", OperationErrorCode.Aborted, stage, false, options);\n this.name = \"OperationAbortedError\";\n }\n}\n\nexport class OperationDeadlineExceededError extends OperationError {\n override readonly name: string;\n\n constructor(stage: string, options: OperationErrorOptions = {}) {\n super(\"Operation deadline exceeded\", OperationErrorCode.DeadlineExceeded, stage, true, options);\n this.name = \"OperationDeadlineExceededError\";\n }\n}\n\nexport class OperationShutdownError extends OperationError {\n override readonly name: string;\n\n constructor(stage: string, options: OperationErrorOptions = {}) {\n super(\"Operation interrupted by shutdown\", OperationErrorCode.Shutdown, stage, true, options);\n this.name = \"OperationShutdownError\";\n }\n}\n\n/**\n * Identifies a {@link ConfigurationError} from any entry of this package.\n *\n * Use this instead of `instanceof` when the error may have been thrown by a different\n * entry — for example a `ConfigurationError` from `slackmark/renderers` caught by code\n * that imported the class from `slackmark`.\n */\nexport function isConfigurationError(value: unknown): value is ConfigurationError {\n return hasErrorBrand(value, CONFIGURATION_ERROR_BRAND);\n}\n\n/**\n * Identifies an {@link OperationError} — abort, deadline, or shutdown — from any entry of\n * this package, including its subclasses.\n *\n * Use this instead of `instanceof` when the error may have been thrown by a different\n * entry — for example an abort raised inside `FetchSlackUploader` from `slackmark/slack`\n * caught by code that imported the class from `slackmark`. Narrow further with `code`\n * against {@link OperationErrorCode} rather than testing a subclass with `instanceof`.\n */\nexport function isOperationError(value: unknown): value is OperationError {\n return hasErrorBrand(value, OPERATION_ERROR_BRAND);\n}\n\nexport function cloneOperationError(error: OperationError, fallbackStage: string): OperationError {\n const stage = error.stage.length > 0 ? error.stage : fallbackStage;\n const options: OperationErrorOptions = {\n cause: error,\n receipts: error.receipts,\n settledReceipts: error.settledReceipts,\n };\n let cloned: OperationError;\n switch (error.code) {\n case OperationErrorCode.Aborted:\n cloned = new OperationAbortedError(stage, options);\n break;\n case OperationErrorCode.DeadlineExceeded:\n cloned = new OperationDeadlineExceededError(stage, options);\n break;\n case OperationErrorCode.Shutdown:\n cloned = new OperationShutdownError(stage, options);\n break;\n }\n Reflect.defineProperty(cloned, OPERATION_ERROR_CARRIER, {\n configurable: false,\n enumerable: false,\n value: true,\n writable: false,\n });\n return cloned;\n}\n\nexport function isOperationErrorCarrier(error: OperationError): boolean {\n return Reflect.get(error, OPERATION_ERROR_CARRIER) === true;\n}\n\nexport function cloneConfigurationError(error: ConfigurationError): ConfigurationError {\n return new ConfigurationError(error.message, {\n code: error.code,\n stage: error.stage,\n cause: error,\n receipts: error.receipts,\n settledReceipts: error.settledReceipts,\n });\n}\n\nexport function attachReceipts(\n error: unknown,\n receipts: ReadonlyArray<UploadReceipt>,\n settledReceipts?: Promise<ReadonlyArray<UploadReceipt>>,\n): unknown {\n if (!(error instanceof Error)) {\n return error;\n }\n try {\n if (Reflect.get(error, RECEIPT_SNAPSHOT_LOCK) === true) {\n return error;\n }\n } catch {\n return error;\n }\n let existing: ReadonlyArray<UploadReceipt> = [];\n try {\n const candidate = Reflect.get(error, \"receipts\");\n if (Array.isArray(candidate)) {\n existing = candidate.filter(isUploadReceipt);\n }\n } catch {\n existing = [];\n }\n Reflect.defineProperty(error, \"receipts\", {\n configurable: true,\n enumerable: true,\n value: freezeReceipts(mergeReceipts(existing, receipts)),\n writable: false,\n });\n if (settledReceipts !== undefined) {\n const finalReceipts = freezeSettledReceipts(settledReceipts, receipts);\n Reflect.defineProperty(error, \"settledReceipts\", {\n configurable: true,\n enumerable: true,\n value: finalReceipts,\n writable: false,\n });\n }\n return error;\n}\n\nexport function lockReceiptSnapshot(error: unknown): unknown {\n if (error instanceof Error) {\n Reflect.defineProperty(error, RECEIPT_SNAPSHOT_LOCK, {\n configurable: false,\n enumerable: false,\n value: true,\n writable: false,\n });\n }\n return error;\n}\n\nasync function freezeSettledReceipts(\n settledReceipts: Promise<ReadonlyArray<UploadReceipt>>,\n fallback: ReadonlyArray<UploadReceipt>,\n): Promise<ReadonlyArray<UploadReceipt>> {\n try {\n return freezeReceipts(await settledReceipts);\n } catch {\n return freezeReceipts(fallback);\n }\n}\n\nfunction mergeReceipts(\n existing: ReadonlyArray<UploadReceipt>,\n incoming: ReadonlyArray<UploadReceipt>,\n): ReadonlyArray<UploadReceipt> {\n const existingGroups = groupReceipts(existing);\n const incomingGroups = groupReceipts(incoming);\n const merged: UploadReceipt[] = [...incoming];\n for (const [key, values] of existingGroups) {\n const overlap = incomingGroups.get(key)?.length ?? 0;\n if (values.length > overlap) {\n merged.push(...values.slice(overlap));\n }\n }\n return merged;\n}\n\nfunction groupReceipts(\n receipts: ReadonlyArray<UploadReceipt>,\n): ReadonlyMap<string, ReadonlyArray<UploadReceipt>> {\n const grouped = new Map<string, UploadReceipt[]>();\n for (const receipt of receipts) {\n const key = receiptKey(receipt);\n const values = grouped.get(key);\n if (values === undefined) {\n grouped.set(key, [receipt]);\n } else {\n values.push(receipt);\n }\n }\n return grouped;\n}\n\nfunction receiptKey(receipt: UploadReceipt): string {\n return [\n receipt.provider,\n receipt.phase,\n receipt.fileId ?? \"\",\n String(receipt.shared),\n receipt.processing,\n String(receipt.status ?? \"\"),\n String(receipt.retryAfterMs ?? \"\"),\n receipt.providerCode ?? \"\",\n receipt.retrySafety,\n ].join(\"\\u0000\");\n}\n\nfunction freezeReceipts(receipts: ReadonlyArray<UploadReceipt>): ReadonlyArray<UploadReceipt> {\n return Object.freeze(receipts.map((receipt) => Object.freeze({ ...receipt })));\n}\n\nfunction isUploadReceipt(value: unknown): value is UploadReceipt {\n return typeof value === \"object\" && value !== null && Reflect.get(value, \"kind\") === \"upload\";\n}\n","export const UploadPhase = {\n Requested: \"requested\",\n Allocated: \"allocated\",\n Uploaded: \"uploaded\",\n Completed: \"completed\",\n Shared: \"shared\",\n Unknown: \"unknown\",\n} as const;\n\nexport type UploadPhase = (typeof UploadPhase)[keyof typeof UploadPhase];\n\nexport const UploadProcessing = {\n NotRequested: \"not-requested\",\n Pending: \"pending\",\n Verified: \"verified\",\n Unverified: \"unverified\",\n} as const;\n\nexport type UploadProcessing = (typeof UploadProcessing)[keyof typeof UploadProcessing];\n\nexport const RetrySafety = {\n Never: \"never\",\n Safe: \"safe\",\n MayDuplicate: \"may-duplicate\",\n} as const;\n\nexport type RetrySafety = (typeof RetrySafety)[keyof typeof RetrySafety];\n\nexport interface UploadReceipt {\n readonly kind: \"upload\";\n readonly provider: string;\n readonly rendererId?: string | undefined;\n readonly filename?: string | undefined;\n readonly phase: UploadPhase;\n readonly fileId?: string | undefined;\n readonly shared: boolean;\n readonly processing: UploadProcessing;\n readonly status?: number | undefined;\n readonly retryAfterMs?: number | undefined;\n readonly providerCode?: string | undefined;\n readonly retrySafety: RetrySafety;\n}\n","import { brandErrorPrototype, hasErrorBrand } from \"../errors.js\";\nimport { RetrySafety, UploadPhase, UploadProcessing, type UploadReceipt } from \"../types.js\";\n\n/** See the brand rationale in `errors.ts`: this class is bundled into more than one entry. */\nconst SLACK_UPLOAD_ERROR_BRAND = Symbol.for(\"slackmark.error.slackUpload\");\n\nexport const SlackUploadStage = {\n Admission: \"admission\",\n GetUploadUrl: \"get-upload-url\",\n UploadBytes: \"upload-bytes\",\n CompleteUpload: \"complete-upload\",\n FileInfo: \"file-info\",\n ProcessingTimeout: \"processing-timeout\",\n} as const;\n\nexport type SlackUploadStage = (typeof SlackUploadStage)[keyof typeof SlackUploadStage];\n\nexport interface SlackUploadErrorDetails {\n readonly stage: SlackUploadStage;\n readonly status?: number | undefined;\n readonly code?: string | undefined;\n readonly retryable?: boolean | undefined;\n readonly retryAfterMs?: number | undefined;\n readonly receipt?: UploadReceipt | undefined;\n readonly cause?: unknown;\n}\n\n/**\n * Integration error from one explicit stage of Slack's external-upload flow.\n */\nexport class SlackUploadError extends Error {\n static {\n brandErrorPrototype(this.prototype, SLACK_UPLOAD_ERROR_BRAND);\n }\n\n override readonly name: string;\n readonly stage: SlackUploadStage;\n readonly status: number | undefined;\n readonly code: string | undefined;\n readonly retryable: boolean;\n readonly retryAfterMs: number | undefined;\n readonly receipt: UploadReceipt;\n readonly receipts: ReadonlyArray<UploadReceipt>;\n readonly settledReceipts: Promise<ReadonlyArray<UploadReceipt>>;\n\n constructor(message: string, details: SlackUploadErrorDetails) {\n super(message, details.cause !== undefined ? { cause: details.cause } : undefined);\n this.name = \"SlackUploadError\";\n this.stage = details.stage;\n this.status = details.status;\n this.code = details.code;\n this.retryable = details.retryable ?? isRetryable(details.status, details.code);\n this.retryAfterMs = details.retryAfterMs;\n this.receipt = Object.freeze(\n details.receipt ?? {\n kind: \"upload\",\n provider: \"slack\",\n phase: UploadPhase.Requested,\n fileId: undefined,\n shared: false,\n processing: UploadProcessing.NotRequested,\n status: details.status,\n retryAfterMs: details.retryAfterMs,\n providerCode: details.code,\n retrySafety: RetrySafety.Safe,\n },\n );\n this.receipts = Object.freeze([this.receipt]);\n this.settledReceipts = Promise.resolve(this.receipts);\n }\n}\n\n/**\n * Identifies a {@link SlackUploadError} from any entry of this package. `slackmark` and\n * `slackmark/slack` each bundle their own copy, so `instanceof` is unreliable when the\n * error crosses between them.\n */\nexport function isSlackUploadError(value: unknown): value is SlackUploadError {\n return hasErrorBrand(value, SLACK_UPLOAD_ERROR_BRAND);\n}\n\nfunction isRetryable(status: number | undefined, code: string | undefined): boolean {\n return (\n status === 429 ||\n (status !== undefined && status >= 500) ||\n code === \"fetch_failed\" ||\n code === \"request_timeout\" ||\n code === \"processing_timeout\"\n );\n}\n","import {\n RetrySafety,\n UploadPhase,\n UploadProcessing,\n type BytesImage,\n type OperationContext,\n type SlackUploader,\n type UploadReceipt,\n} from \"../types.js\";\nimport {\n ConfigurationError,\n OperationAbortedError,\n OperationDeadlineExceededError,\n OperationErrorCode,\n attachReceipts,\n isOperationError,\n type OperationError,\n} from \"../errors.js\";\n\nimport {\n SlackUploadError,\n SlackUploadStage,\n isSlackUploadError,\n type SlackUploadStage as SlackUploadStageType,\n} from \"./slack-upload-error.js\";\n\nconst SLACK_API_BASE_URL = \"https://slack.com/api\";\nconst DEFAULT_POLL_INTERVAL_MS = 250;\nconst DEFAULT_POLL_MAX_ATTEMPTS = 20;\nconst DEFAULT_POLL_TIMEOUT_MS = 30_000;\nconst DEFAULT_REQUEST_TIMEOUT_MS = 10_000;\n\nexport interface SlackFetchRequestInit {\n readonly method: \"POST\";\n readonly headers: Readonly<Record<string, string>>;\n readonly body: string | Uint8Array;\n readonly signal?: AbortSignal;\n}\n\nexport interface SlackFetchResponse {\n readonly ok: boolean;\n readonly status: number;\n readonly headers?: { get(name: string): string | null };\n json(): Promise<unknown>;\n}\n\nexport type SlackFetch = (\n input: string,\n init: SlackFetchRequestInit,\n) => Promise<SlackFetchResponse>;\n\nexport type SlackUploadSleep = (milliseconds: number) => Promise<void>;\nexport type SlackUploadClock = () => number;\n\nexport interface SlackUploadPollOptions {\n readonly intervalMs?: number;\n readonly maxAttempts?: number;\n readonly timeoutMs?: number;\n readonly sleep?: SlackUploadSleep;\n readonly clock?: SlackUploadClock;\n}\n\nexport interface FetchSlackUploaderOptions {\n readonly token: string;\n readonly fetch?: SlackFetch;\n readonly channelId?: string;\n readonly requestTimeoutMs?: number;\n readonly waitForProcessing?: boolean;\n readonly poll?: SlackUploadPollOptions;\n}\n\ninterface UploadTarget {\n readonly uploadUrl: string;\n readonly fileId: string;\n}\n\ninterface ResolvedFetchSlackUploaderOptions {\n readonly token: string;\n readonly fetcher: SlackFetch;\n readonly channelId: string | undefined;\n readonly requestTimeoutMs: number;\n readonly waitForProcessing: boolean;\n readonly pollIntervalMs: number;\n readonly pollMaxAttempts: number;\n readonly pollTimeoutMs: number;\n readonly sleep: SlackUploadSleep;\n readonly clock: SlackUploadClock;\n}\n\n/**\n * Web-standard implementation of Slack's external file-upload flow.\n *\n * @see https://docs.slack.dev/messaging/working-with-files\n */\nexport class FetchSlackUploader implements SlackUploader {\n private readonly token: string;\n private readonly fetcher: SlackFetch;\n private readonly channelId: string | undefined;\n private readonly requestTimeoutMs: number;\n private readonly waitForProcessing: boolean;\n private readonly pollIntervalMs: number;\n private readonly pollMaxAttempts: number;\n private readonly pollTimeoutMs: number;\n private readonly sleep: SlackUploadSleep;\n private readonly clock: SlackUploadClock;\n\n constructor(options: FetchSlackUploaderOptions) {\n const resolved = resolveUploaderOptions(options);\n this.token = resolved.token;\n this.fetcher = resolved.fetcher;\n this.channelId = resolved.channelId;\n this.requestTimeoutMs = resolved.requestTimeoutMs;\n this.waitForProcessing = resolved.waitForProcessing;\n this.pollIntervalMs = resolved.pollIntervalMs;\n this.pollMaxAttempts = resolved.pollMaxAttempts;\n this.pollTimeoutMs = resolved.pollTimeoutMs;\n this.sleep = resolved.sleep;\n this.clock = resolved.clock;\n }\n\n async upload(\n img: BytesImage,\n context: OperationContext,\n ): Promise<{ readonly fileId: string; readonly receipt: UploadReceipt }> {\n let receipt = slackReceipt({\n phase: UploadPhase.Requested,\n processing: UploadProcessing.NotRequested,\n retrySafety: RetrySafety.Safe,\n });\n try {\n const target = await this.getUploadTarget(img, context);\n receipt = slackReceipt({\n phase: UploadPhase.Allocated,\n fileId: target.fileId,\n processing: UploadProcessing.NotRequested,\n retrySafety: RetrySafety.MayDuplicate,\n });\n await this.uploadBytes(target, img, context);\n receipt = slackReceipt({\n phase: UploadPhase.Uploaded,\n fileId: target.fileId,\n processing: UploadProcessing.NotRequested,\n retrySafety: RetrySafety.MayDuplicate,\n });\n await this.completeUpload(target.fileId, img.filename, context);\n receipt = slackReceipt({\n phase: this.channelId === undefined ? UploadPhase.Completed : UploadPhase.Shared,\n fileId: target.fileId,\n shared: this.channelId !== undefined,\n processing: this.waitForProcessing\n ? UploadProcessing.Pending\n : UploadProcessing.NotRequested,\n retrySafety: RetrySafety.Never,\n });\n if (this.waitForProcessing) {\n try {\n await this.waitUntilProcessed(target.fileId, receipt, context);\n receipt = slackReceipt({\n ...receipt,\n processing: UploadProcessing.Verified,\n });\n } catch (error) {\n if (isOperationError(error)) {\n throw attachReceipts(error, [receipt]);\n }\n if (isSlackUploadError(error)) {\n receipt = slackReceipt({\n ...receipt,\n processing: UploadProcessing.Unverified,\n status: error.status,\n retryAfterMs: error.retryAfterMs,\n providerCode: error.code,\n });\n } else {\n receipt = slackReceipt({\n ...receipt,\n processing: UploadProcessing.Unverified,\n providerCode: \"processing_failed\",\n });\n }\n }\n }\n return { fileId: target.fileId, receipt };\n } catch (error) {\n if (isSlackUploadError(error)) {\n throw withReceipt(error, receipt);\n }\n if (isOperationError(error)) {\n throw attachReceipts(error, [receipt]);\n }\n throw error;\n }\n }\n\n private async getUploadTarget(img: BytesImage, control: OperationContext): Promise<UploadTarget> {\n const payload = await this.callSlackApi(\n \"files.getUploadURLExternal\",\n encodeForm([\n [\"filename\", img.filename],\n [\"length\", String(img.data.byteLength)],\n ]),\n SlackUploadStage.GetUploadUrl,\n control,\n );\n const uploadUrl = payload[\"upload_url\"];\n const fileId = payload[\"file_id\"];\n if (!isNonEmptyString(uploadUrl) || !isNonEmptyString(fileId)) {\n throw new SlackUploadError(\"files.getUploadURLExternal returned no upload_url or file_id\", {\n stage: SlackUploadStage.GetUploadUrl,\n code: \"invalid_response\",\n });\n }\n return { uploadUrl, fileId };\n }\n\n private async uploadBytes(\n target: UploadTarget,\n img: BytesImage,\n control: OperationContext,\n ): Promise<void> {\n const stageSignal = createStageSignal(control, this.requestTimeoutMs, this.clock);\n let response: SlackFetchResponse;\n try {\n response = await this.fetcher(target.uploadUrl, {\n method: \"POST\",\n headers: { \"content-type\": img.mimeType },\n body: img.data,\n signal: stageSignal.signal,\n });\n } catch (cause) {\n const operationError = stageSignal.operationError(SlackUploadStage.UploadBytes, cause);\n if (operationError !== undefined) {\n throw operationError;\n }\n throw new SlackUploadError(\"Slack byte upload failed\", {\n stage: SlackUploadStage.UploadBytes,\n code: stageSignal.code(),\n cause,\n });\n } finally {\n stageSignal.cleanup();\n }\n if (!response.ok) {\n throw new SlackUploadError(\"Slack byte upload was rejected\", {\n stage: SlackUploadStage.UploadBytes,\n status: response.status,\n code: `http_${String(response.status)}`,\n retryAfterMs: retryAfterMs(response),\n });\n }\n }\n\n private async completeUpload(\n fileId: string,\n filename: string,\n control: OperationContext,\n ): Promise<void> {\n const fields: Array<readonly [string, string]> = [\n [\n \"files\",\n JSON.stringify([\n {\n id: fileId,\n title: filename,\n },\n ]),\n ],\n ];\n if (this.channelId !== undefined) {\n fields.push([\"channel_id\", this.channelId]);\n }\n await this.callSlackApi(\n \"files.completeUploadExternal\",\n encodeForm(fields),\n SlackUploadStage.CompleteUpload,\n control,\n );\n }\n\n private async waitUntilProcessed(\n fileId: string,\n receipt: UploadReceipt,\n control: OperationContext,\n ): Promise<void> {\n const startedAt = this.clock();\n const pollDeadlineMs = startedAt + this.pollTimeoutMs;\n const pollOwnsDeadline =\n control.deadlineMs === undefined || pollDeadlineMs < control.deadlineMs;\n const pollContext: OperationContext = {\n signal: control.signal,\n deadlineMs: Math.min(control.deadlineMs ?? Number.POSITIVE_INFINITY, pollDeadlineMs),\n };\n\n for (let attempt = 1; attempt <= this.pollMaxAttempts; attempt += 1) {\n if (this.clock() >= pollDeadlineMs) {\n throw processingTimeout(receipt, attempt - 1);\n }\n let payload: Record<string, unknown>;\n try {\n payload = await this.callSlackApi(\n \"files.info\",\n encodeForm([[\"file\", fileId]]),\n SlackUploadStage.FileInfo,\n pollContext,\n );\n } catch (error) {\n if (pollOwnsDeadline && isOperationDeadline(error)) {\n throw processingTimeout(receipt, attempt);\n }\n throw error;\n }\n if (isProcessedImageFile(payload[\"file\"])) {\n return;\n }\n\n if (attempt === this.pollMaxAttempts || this.clock() - startedAt >= this.pollTimeoutMs) {\n throw processingTimeout(receipt, attempt);\n }\n\n try {\n await controlledSleep(\n this.sleep,\n Math.min(this.pollIntervalMs, Math.max(0, pollDeadlineMs - this.clock())),\n pollContext,\n this.clock,\n );\n } catch (error) {\n if (pollOwnsDeadline && isOperationDeadline(error)) {\n throw processingTimeout(receipt, attempt);\n }\n throw error;\n }\n\n if (this.clock() - startedAt >= this.pollTimeoutMs) {\n throw processingTimeout(receipt, attempt);\n }\n }\n }\n\n private async callSlackApi(\n method: string,\n body: string,\n stage: SlackUploadStageType,\n control: OperationContext,\n ): Promise<Record<string, unknown>> {\n const stageSignal = createStageSignal(control, this.requestTimeoutMs, this.clock);\n let response: SlackFetchResponse;\n try {\n response = await this.fetcher(`${SLACK_API_BASE_URL}/${method}`, {\n method: \"POST\",\n headers: {\n authorization: `Bearer ${this.token}`,\n \"content-type\": \"application/x-www-form-urlencoded;charset=UTF-8\",\n },\n body,\n signal: stageSignal.signal,\n });\n } catch (cause) {\n const operationError = stageSignal.operationError(stage, cause);\n stageSignal.cleanup();\n if (operationError !== undefined) {\n throw operationError;\n }\n throw new SlackUploadError(\"Slack API request failed\", {\n stage,\n code: stageSignal.code(),\n cause,\n });\n }\n\n let payload: unknown;\n try {\n payload = await raceWithSignal(response.json(), stageSignal.signal);\n } catch (cause) {\n const operationError = stageSignal.operationError(stage, cause);\n const signalCode = stageSignal.code();\n if (operationError !== undefined) {\n throw operationError;\n }\n throw new SlackUploadError(\"Slack API returned invalid JSON\", {\n stage,\n status: response.status,\n code: signalCode === \"fetch_failed\" ? \"invalid_json\" : signalCode,\n cause,\n });\n } finally {\n stageSignal.cleanup();\n }\n\n const slackCode = getSlackErrorCode(payload);\n if (!response.ok || !isRecord(payload) || payload[\"ok\"] !== true) {\n throw new SlackUploadError(\"Slack API rejected the request\", {\n stage,\n status: response.status,\n code: slackCode ?? (response.ok ? \"invalid_response\" : `http_${String(response.status)}`),\n retryAfterMs: retryAfterMs(response),\n });\n }\n return payload;\n }\n}\n\nfunction resolveUploaderOptions(\n options: FetchSlackUploaderOptions,\n): ResolvedFetchSlackUploaderOptions {\n assertKnownPlainObject(\n options,\n [\"token\", \"fetch\", \"channelId\", \"requestTimeoutMs\", \"waitForProcessing\", \"poll\"],\n \"FetchSlackUploader options\",\n );\n let token: unknown;\n let fetcher: unknown;\n let channelId: unknown;\n let requestTimeoutMs: unknown;\n let waitForProcessing: unknown;\n let poll: unknown;\n try {\n token = Reflect.get(options, \"token\");\n fetcher = Reflect.get(options, \"fetch\");\n channelId = Reflect.get(options, \"channelId\");\n requestTimeoutMs = Reflect.get(options, \"requestTimeoutMs\");\n waitForProcessing = Reflect.get(options, \"waitForProcessing\");\n poll = Reflect.get(options, \"poll\");\n } catch (cause) {\n throw invalidUploaderOptions(\"Uploader options could not be read\", cause);\n }\n if (typeof token !== \"string\" || token.length === 0 || token !== token.trim()) {\n throw invalidUploaderOptions(\"token must be a nonempty trimmed string\");\n }\n if (\n channelId !== undefined &&\n (typeof channelId !== \"string\" || channelId.length === 0 || channelId !== channelId.trim())\n ) {\n throw invalidUploaderOptions(\"channelId must be a nonempty trimmed string\");\n }\n if (fetcher !== undefined && typeof fetcher !== \"function\") {\n throw invalidUploaderOptions(\"fetch must be a function\");\n }\n if (\n requestTimeoutMs !== undefined &&\n (typeof requestTimeoutMs !== \"number\" ||\n !Number.isFinite(requestTimeoutMs) ||\n requestTimeoutMs <= 0)\n ) {\n throw invalidUploaderOptions(\"requestTimeoutMs must be positive\");\n }\n if (waitForProcessing !== undefined && typeof waitForProcessing !== \"boolean\") {\n throw invalidUploaderOptions(\"waitForProcessing must be boolean\");\n }\n\n const resolvedPoll = resolvePollOptions(poll);\n return {\n token,\n fetcher: (fetcher as SlackFetch | undefined) ?? defaultFetch,\n channelId: channelId as string | undefined,\n requestTimeoutMs: (requestTimeoutMs as number | undefined) ?? DEFAULT_REQUEST_TIMEOUT_MS,\n waitForProcessing: (waitForProcessing as boolean | undefined) ?? false,\n pollIntervalMs: resolvedPoll.intervalMs,\n pollMaxAttempts: resolvedPoll.maxAttempts,\n pollTimeoutMs: resolvedPoll.timeoutMs,\n sleep: resolvedPoll.sleep,\n clock: resolvedPoll.clock,\n };\n}\n\nfunction resolvePollOptions(poll: unknown): {\n readonly intervalMs: number;\n readonly maxAttempts: number;\n readonly timeoutMs: number;\n readonly sleep: SlackUploadSleep;\n readonly clock: SlackUploadClock;\n} {\n if (poll === undefined) {\n return {\n intervalMs: DEFAULT_POLL_INTERVAL_MS,\n maxAttempts: DEFAULT_POLL_MAX_ATTEMPTS,\n timeoutMs: DEFAULT_POLL_TIMEOUT_MS,\n sleep: defaultSleep,\n clock: defaultClock,\n };\n }\n assertKnownPlainObject(\n poll,\n [\"intervalMs\", \"maxAttempts\", \"timeoutMs\", \"sleep\", \"clock\"],\n \"poll options\",\n );\n let intervalMs: unknown;\n let maxAttempts: unknown;\n let timeoutMs: unknown;\n let sleep: unknown;\n let clock: unknown;\n try {\n intervalMs = Reflect.get(poll, \"intervalMs\");\n maxAttempts = Reflect.get(poll, \"maxAttempts\");\n timeoutMs = Reflect.get(poll, \"timeoutMs\");\n sleep = Reflect.get(poll, \"sleep\");\n clock = Reflect.get(poll, \"clock\");\n } catch (cause) {\n throw invalidUploaderOptions(\"poll options could not be read\", cause);\n }\n const resolvedInterval = (intervalMs as number | undefined) ?? DEFAULT_POLL_INTERVAL_MS;\n const resolvedAttempts = (maxAttempts as number | undefined) ?? DEFAULT_POLL_MAX_ATTEMPTS;\n const resolvedTimeout = (timeoutMs as number | undefined) ?? DEFAULT_POLL_TIMEOUT_MS;\n if (!Number.isInteger(resolvedInterval) || resolvedInterval < 0) {\n throw invalidUploaderOptions(\"poll.intervalMs must be a non-negative integer\");\n }\n if (!Number.isInteger(resolvedAttempts) || resolvedAttempts <= 0) {\n throw invalidUploaderOptions(\"poll.maxAttempts must be a positive integer\");\n }\n if (!Number.isFinite(resolvedTimeout) || resolvedTimeout <= 0) {\n throw invalidUploaderOptions(\"poll.timeoutMs must be positive\");\n }\n if (sleep !== undefined && typeof sleep !== \"function\") {\n throw invalidUploaderOptions(\"poll.sleep must be a function\");\n }\n if (clock !== undefined && typeof clock !== \"function\") {\n throw invalidUploaderOptions(\"poll.clock must be a function\");\n }\n return {\n intervalMs: resolvedInterval,\n maxAttempts: resolvedAttempts,\n timeoutMs: resolvedTimeout,\n sleep: (sleep as SlackUploadSleep | undefined) ?? defaultSleep,\n clock: (clock as SlackUploadClock | undefined) ?? defaultClock,\n };\n}\n\nfunction assertKnownPlainObject(\n value: unknown,\n allowed: ReadonlyArray<string>,\n label: string,\n): asserts value is object {\n if (typeof value !== \"object\" || value === null || Array.isArray(value)) {\n throw invalidUploaderOptions(`${label} must be a plain object`);\n }\n let prototype: object | null;\n let keys: ReadonlyArray<string>;\n try {\n prototype = Object.getPrototypeOf(value);\n keys = Object.keys(value);\n } catch (cause) {\n throw invalidUploaderOptions(`${label} could not be inspected`, cause);\n }\n if (prototype !== Object.prototype && prototype !== null) {\n throw invalidUploaderOptions(`${label} must be a plain object`);\n }\n const allowedKeys = new Set(allowed);\n for (const key of keys) {\n if (!allowedKeys.has(key)) {\n throw invalidUploaderOptions(`Unknown ${label} key: ${key}`);\n }\n }\n}\n\nfunction invalidUploaderOptions(message: string, cause?: unknown): ConfigurationError {\n return new ConfigurationError(message, {\n code: \"invalid_slack_uploader_options\",\n stage: \"configuration\",\n cause,\n });\n}\n\nfunction encodeForm(fields: ReadonlyArray<readonly [string, string]>): string {\n return fields\n .map(([name, value]) => `${encodeURIComponent(name)}=${encodeURIComponent(value)}`)\n .join(\"&\");\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction isNonEmptyString(value: unknown): value is string {\n return typeof value === \"string\" && value.length > 0;\n}\n\nfunction isPositiveNumber(value: unknown): value is number {\n return typeof value === \"number\" && Number.isFinite(value) && value > 0;\n}\n\nfunction isProcessedImageFile(value: unknown): boolean {\n if (!isRecord(value)) {\n return false;\n }\n return (\n isNonEmptyString(value[\"mimetype\"]) &&\n isNonEmptyString(value[\"filetype\"]) &&\n isPositiveNumber(value[\"original_w\"]) &&\n isPositiveNumber(value[\"original_h\"])\n );\n}\n\nfunction getSlackErrorCode(payload: unknown): string | undefined {\n if (!isRecord(payload)) {\n return undefined;\n }\n const error = payload[\"error\"];\n return typeof error === \"string\" ? error : undefined;\n}\n\nfunction processingTimeout(receipt: UploadReceipt, attempts: number): SlackUploadError {\n return new SlackUploadError(\n `Slack file processing did not complete after ${String(attempts)} polls`,\n {\n stage: SlackUploadStage.ProcessingTimeout,\n code: \"processing_timeout\",\n receipt: slackReceipt({\n ...receipt,\n processing: UploadProcessing.Unverified,\n providerCode: \"processing_timeout\",\n }),\n },\n );\n}\n\n/**\n * Subclass identity is as bundle-sensitive as the base class, so discriminate on `code`.\n */\nfunction isOperationDeadline(error: unknown): boolean {\n return isOperationError(error) && error.code === OperationErrorCode.DeadlineExceeded;\n}\n\ninterface StageSignal {\n readonly signal: AbortSignal;\n cleanup(): void;\n code(): \"aborted\" | \"request_timeout\" | \"fetch_failed\";\n operationError(stage: string, cause: unknown): OperationError | undefined;\n}\n\nfunction createStageSignal(\n control: OperationContext,\n requestTimeoutMs: number,\n clock: SlackUploadClock,\n): StageSignal {\n const controller = new AbortController();\n let timeoutKind: \"operation\" | \"request\" | undefined;\n const abortFromCaller = (): void => {\n controller.abort(control.signal?.reason);\n };\n if (control.signal?.aborted === true) {\n abortFromCaller();\n } else {\n control.signal?.addEventListener(\"abort\", abortFromCaller, { once: true });\n }\n const requestDeadlineMs = clock() + requestTimeoutMs;\n const operationDeadlineMs = control.deadlineMs ?? Number.POSITIVE_INFINITY;\n const stageDeadline = Math.min(requestDeadlineMs, operationDeadlineMs);\n const remaining = Math.max(0, stageDeadline - clock());\n const timeout = setTimeout(() => {\n timeoutKind = operationDeadlineMs <= requestDeadlineMs ? \"operation\" : \"request\";\n controller.abort(new Error(\"Slack request deadline exceeded\"));\n }, remaining);\n return {\n signal: controller.signal,\n cleanup: (): void => {\n clearTimeout(timeout);\n control.signal?.removeEventListener(\"abort\", abortFromCaller);\n },\n code: (): \"aborted\" | \"request_timeout\" | \"fetch_failed\" => {\n if (timeoutKind !== undefined) {\n return \"request_timeout\";\n }\n return control.signal?.aborted === true ? \"aborted\" : \"fetch_failed\";\n },\n operationError: (stage: string, cause: unknown): OperationError | undefined => {\n if (control.signal?.aborted === true) {\n return new OperationAbortedError(stage, { cause });\n }\n if (timeoutKind === \"operation\") {\n return new OperationDeadlineExceededError(stage, { cause });\n }\n return undefined;\n },\n };\n}\n\nfunction controlledSleep(\n sleep: SlackUploadSleep,\n milliseconds: number,\n control: OperationContext,\n clock: SlackUploadClock,\n): Promise<void> {\n if (control.signal?.aborted === true) {\n return Promise.reject(\n new OperationAbortedError(SlackUploadStage.ProcessingTimeout, {\n cause: control.signal.reason,\n }),\n );\n }\n if (control.deadlineMs !== undefined && clock() >= control.deadlineMs) {\n return Promise.reject(new OperationDeadlineExceededError(SlackUploadStage.ProcessingTimeout));\n }\n return new Promise<void>((resolve, reject) => {\n const onAbort = (): void => {\n cleanup();\n reject(\n new OperationAbortedError(SlackUploadStage.ProcessingTimeout, {\n cause: control.signal?.reason,\n }),\n );\n };\n const onDeadline = (): void => {\n cleanup();\n reject(new OperationDeadlineExceededError(SlackUploadStage.ProcessingTimeout));\n };\n const deadlineTimer =\n control.deadlineMs === undefined\n ? undefined\n : setTimeout(onDeadline, Math.max(0, control.deadlineMs - clock()));\n const cleanup = (): void => {\n if (deadlineTimer !== undefined) {\n clearTimeout(deadlineTimer);\n }\n control.signal?.removeEventListener(\"abort\", onAbort);\n };\n control.signal?.addEventListener(\"abort\", onAbort, { once: true });\n void sleep(milliseconds).then(\n () => {\n cleanup();\n resolve();\n return undefined;\n },\n (error: unknown) => {\n cleanup();\n reject(error);\n return undefined;\n },\n );\n });\n}\n\nfunction raceWithSignal<T>(promise: Promise<T>, signal: AbortSignal): Promise<T> {\n if (signal.aborted) {\n return Promise.reject(signal.reason);\n }\n return new Promise<T>((resolve, reject) => {\n const onAbort = (): void => {\n signal.removeEventListener(\"abort\", onAbort);\n reject(signal.reason);\n };\n signal.addEventListener(\"abort\", onAbort, { once: true });\n void promise.then(\n (value) => {\n signal.removeEventListener(\"abort\", onAbort);\n resolve(value);\n return undefined;\n },\n (error: unknown) => {\n signal.removeEventListener(\"abort\", onAbort);\n reject(error);\n return undefined;\n },\n );\n });\n}\n\nfunction slackReceipt(options: {\n readonly phase: UploadReceipt[\"phase\"];\n readonly fileId?: string | undefined;\n readonly shared?: boolean | undefined;\n readonly processing: UploadReceipt[\"processing\"];\n readonly status?: number | undefined;\n readonly retryAfterMs?: number | undefined;\n readonly providerCode?: string | undefined;\n readonly retrySafety?: UploadReceipt[\"retrySafety\"] | undefined;\n}): UploadReceipt {\n return Object.freeze({\n kind: \"upload\",\n provider: \"slack\",\n phase: options.phase,\n fileId: options.fileId,\n shared: options.shared ?? false,\n processing: options.processing,\n status: options.status,\n retryAfterMs: options.retryAfterMs,\n providerCode: options.providerCode,\n retrySafety: options.retrySafety ?? RetrySafety.Never,\n });\n}\n\nfunction withReceipt(error: SlackUploadError, receipt: UploadReceipt): SlackUploadError {\n return new SlackUploadError(error.message, {\n stage: error.stage,\n status: error.status,\n code: error.code,\n retryable: error.retryable,\n retryAfterMs: error.retryAfterMs,\n receipt: slackReceipt({\n ...receipt,\n status: error.status,\n retryAfterMs: error.retryAfterMs,\n providerCode: error.code,\n retrySafety:\n receipt.phase === UploadPhase.Requested\n ? RetrySafety.Safe\n : receipt.phase === UploadPhase.Completed || receipt.phase === UploadPhase.Shared\n ? RetrySafety.Never\n : RetrySafety.MayDuplicate,\n }),\n cause: error.cause,\n });\n}\n\nfunction retryAfterMs(response: SlackFetchResponse): number | undefined {\n const raw = response.headers?.get(\"retry-after\");\n if (raw === undefined || raw === null) {\n return undefined;\n }\n const seconds = Number(raw);\n return Number.isFinite(seconds) && seconds >= 0 ? seconds * 1_000 : undefined;\n}\n\nfunction defaultFetch(input: string, init: SlackFetchRequestInit): Promise<SlackFetchResponse> {\n return globalThis.fetch(input, init);\n}\n\nfunction defaultSleep(milliseconds: number): Promise<void> {\n return new Promise((resolve) => {\n setTimeout(resolve, milliseconds);\n });\n}\n\nfunction defaultClock(): number {\n return Date.now();\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"validate-blocks.d.ts","sourceRoot":"","sources":["../../src/validate/validate-blocks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAA6C,MAAM,oBAAoB,CAAC;AAwB3F,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,OAAO,CAAC,MAAM,oBAAoB,EAAE,OAAO,MAAM,CAAC;AAElD;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,aAAa,CAAC,KAAK,CAAC,GAAG;IACnD,QAAQ,CAAC,CAAC,oBAAoB,CAAC,EAAE,IAAI,CAAC;CACvC,CAAC;AASF;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,aAAa,CAAC,KAAK,CAAC,GAAG,eAAe,CAmD5E"}
1
+ {"version":3,"file":"validate-blocks.d.ts","sourceRoot":"","sources":["../../src/validate/validate-blocks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAA6C,MAAM,oBAAoB,CAAC;AAyB3F,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,OAAO,CAAC,MAAM,oBAAoB,EAAE,OAAO,MAAM,CAAC;AAElD;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,aAAa,CAAC,KAAK,CAAC,GAAG;IACnD,QAAQ,CAAC,CAAC,oBAAoB,CAAC,EAAE,IAAI,CAAC;CACvC,CAAC;AASF;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,aAAa,CAAC,KAAK,CAAC,GAAG,eAAe,CAmD5E"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "slackmark",
3
- "version": "0.6.0",
3
+ "version": "0.6.2",
4
4
  "description": "Compile SlackMark (CommonMark and GFM plus Slack extensions) to Slack Block Kit JSON",
5
5
  "keywords": [
6
6
  "block kit",