/** * Upload/overwrite solutions to UiPath Studio Web. * Consolidates the upload logic previously duplicated in solution-tool and maestro-sdk. */ import { type FailureOutput } from "@uipath/common"; import type { IFileSystem } from "@uipath/filesystem"; import type { SolutionImportResponse, StudioWebConfig } from "./types"; /** Which Studio Web endpoint refused the upload. */ export type SolutionUploadOperation = "import" | "overwrite"; /** An overwrite always names its target; an import has none yet. */ type SolutionUploadFailureDetails = { status: number; method: string; /** Request path as the URL carries it: no scheme or host, but the * organization prefix is part of the path and stays. */ endpoint: string; /** Full request URL, for diagnostics. */ url: string; body: string; /** Raw `WWW-Authenticate` when the response carried one. Parsed, never * echoed whole — see {@link parseAuthChallenge}. */ authChallenge?: string; message: string; } & ({ operation: "import"; } | { operation: "overwrite"; solutionId: string; }); /** * A Studio Web upload endpoint answered non-2xx. * * Carries what a caller needs to report the failure without re-parsing * anything: which endpoint ran, the status, the raw body, and the platform's * own `code` / `message` when the body carries them. * * `status` and the `message` wording are part of the contract — * `uip solution upload` shape-matches `status === 404` and quotes `message` in * its stale-id envelope. */ export declare class SolutionUploadHttpError extends Error { readonly status: number; readonly operation: SolutionUploadOperation; readonly method: string; readonly endpoint: string; readonly url: string; readonly body: string; /** Present only for an overwrite. */ readonly solutionId?: string; /** From a `{"code":…,"message":…}` body; undefined for any other shape. */ readonly parsedErrorCode?: string; readonly parsedErrorMessage?: string; /** Raw `WWW-Authenticate`, when the response had one. On a real 401 from * Studio Web this is often the *only* diagnostic: the body is empty * (`content-length: 0`) and the reason is in this header. */ readonly authChallenge?: string; constructor(details: SolutionUploadFailureDetails); } /** Matched by shape, not `instanceof`: tools bundle their own copy of this * package, so a cross-bundle `instanceof` is not reliable. */ export declare function isSolutionUploadHttpError(error: unknown): error is SolutionUploadHttpError; /** Replace anything token-shaped in `text`. Exported for the auth-refusal * paths and their tests; not re-exported from the package barrel. */ export declare function redactTokens(text: string): string; /** * Pull the reason out of a `WWW-Authenticate` challenge. * * Measured against alpha: a real Studio Web 401 comes back with * `content-length: 0` and puts the whole diagnostic in this header — * `Bearer realm="…", error="invalid_token", error_description="The audience * 'empty' is invalid"`. Without this the CLI has nothing to tell the user, and * the envelope ends up asking them to report a platform response that does not * exist. * * Only the two RFC 6750 fields are taken. `realm` is deliberately dropped: it * is an internal endpoint URL, it says nothing about why the call failed, and * echoing routing metadata into user-facing errors is the pattern the security * checklist warns about. `error` is a small fixed vocabulary; `error_description` * is free text, so it goes through {@link redactTokens} and a length cap in * case Identity ever quotes the presented credential back. */ export declare function parseAuthChallenge(header?: string): { error?: string; description?: string; }; /** Quote a platform body for an auth refusal, minus anything token-shaped. * Redaction runs before `summarizePlatformBody`'s length cap, so a token * cannot survive by being truncated mid-string into something the pattern no * longer matches. */ export declare function summarizeAuthRefusalBody(body: string): string; /** * Build the CLI failure envelope for a Studio Web upload refusal. * * The upload runs before anything executes, so on a refusal nothing reached * the tenant and nothing ran: the envelope points at the upload, not at the * project's contents. Shared by every command that pushes a solution, so the * text names no command of its own. * * `subject` names what the caller was pushing ("flow", "case", "process", * "agent"), so the text can say which artifact is off the hook. `importCheckHint` * is appended on an import refusal, where the package itself was rejected and * the caller has a command for checking it; an overwrite refusal is about the * target solution, not the package. * * `identityType` (with `clientId` when it is known) only changes the wording * of a 401/403: who the session acts as decides whether "check your Studio Web * access" or "check the external application's scopes" is the useful sentence. * It is read from unverified token claims, so it must never be used for * anything but text — see `SessionIdentity` in `@uipath/auth`. * * `Context.httpStatus` is what gives the envelope its `ErrorCode`, except on an * application 401 — see {@link buildAuthRefusalInstructions}. */ export declare function buildSolutionUploadFailureOutput(err: SolutionUploadHttpError, options?: { subject?: string; importCheckHint?: string; identityType?: "User" | "Application"; clientId?: string; }): FailureOutput; /** * Escape hatch for very large solutions or unusually slow links: * `UIPATH_SOLUTION_UPLOAD_TIMEOUT_MS=300000`. Anything non-numeric or * non-positive falls back to the default — the ceiling can be raised, not * removed, so the silent hang cannot come back through a typo. * * Exported for tests only — not re-exported from the package barrel. */ export declare function resolveUploadTimeoutMs(): number; /** * Probe Studio Web for the existence of a solution by id. * Returns true on 2xx, false on 404. Throws on any other status so callers * don't silently treat transient errors (auth, 5xx) as "missing". * * Routes through `@uipath/studioweb-sdk`'s generated `SolutionApi` * (`Solution_GetSolution` → `GET /api/Solution/{solutionId}`) so the URL, * auth header composition, and tenant routing come from the Studio Web * swagger instead of being hand-typed here. The `Raw` variant is used so we * can branch on response status (404 = missing) without forcing the body * parse. */ export declare function solutionExistsOnStudioWeb(config: StudioWebConfig, organizationName: string, solutionId: string): Promise; /** * Upload a .uis file to Studio Web Import endpoint (new solution). */ export declare function importSolution(config: StudioWebConfig, organizationName: string, fileBuffer: Uint8Array, fileName: string): Promise; /** * Overwrite an existing solution on Studio Web: replaces its contents in * place under the same id, keeping existing version history. With * `createSnapshot` the replaced contents are first recorded as a restorable * version; the default (false) matches the server's and keeps debug pushes * from minting a version per iteration — `uip solution upload` opts in. */ export declare function overwriteSolution(config: StudioWebConfig, organizationName: string, fileBuffer: Uint8Array, fileName: string, solutionId: string, createSnapshot?: boolean): Promise; /** * Upload or overwrite a solution on Studio Web. * If solutionId is provided, tries overwrite first with 404 fallback to import. * * Accepts either a file buffer or a file path (reads the file using fs). */ export declare function uploadOrOverwriteSolution(config: StudioWebConfig, organizationName: string, fileBufferOrPath: Uint8Array | string, solutionId: string | undefined, fs?: IFileSystem): Promise; export {};