@roxyon/api-client 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/account.ts","../src/applications.ts","../src/auth.ts","../src/constants.ts","../src/query.ts","../src/client.ts","../src/domains.ts","../src/sites.ts","../src/subscriptions.ts","../src/tokens.ts","../src/env.ts","../src/runtimes.ts"],"sourcesContent":["import { AccountApi } from './account.js';\nimport { ApplicationsApi } from './applications.js';\nimport { AuthApi } from './auth.js';\nimport { RoxyonClient, type RoxyonClientOptions } from './client.js';\nimport { DomainsApi } from './domains.js';\nimport { SitesApi } from './sites.js';\nimport { SubscriptionsApi } from './subscriptions.js';\nimport { TokensApi } from './tokens.js';\n\nexport { RoxyonClient } from './client.js';\nexport type { RoxyonClientOptions, RequestOptions } from './client.js';\nexport { AuthApi } from './auth.js';\nexport type { RoxyonUser, LoginResult, LoginPrecheck, SessionGrant } from './auth.js';\nexport { ApplicationsApi } from './applications.js';\nexport type {\n Application,\n ApplicationProcess,\n ApplicationRoute,\n CreateApplicationInput,\n CreateOnDeploy,\n DeployResult,\n} from './applications.js';\nexport { SitesApi } from './sites.js';\nexport type { StaticDeployResult } from './sites.js';\nexport { DomainsApi } from './domains.js';\nexport type { Domain } from './domains.js';\nexport { SubscriptionsApi } from './subscriptions.js';\nexport type { Subscription, Privilege } from './subscriptions.js';\nexport { AccountApi } from './account.js';\nexport type {\n AccountApp,\n AccountContext,\n AccountSubscription,\n AccountDomain,\n} from './account.js';\nexport { TokensApi } from './tokens.js';\nexport type { TokenScope, TokenSummary, CreatedToken } from './tokens.js';\nexport { RoxyonApiError, rxError, isAuthError, assertOk } from './errors.js';\nexport { parseEnv, formatEnv, envFromStored } from './env.js';\nexport { RUNTIMES, LUMEN_BUILD } from './runtimes.js';\nexport type { RuntimeName, RuntimeSpec, DeployKind } from './runtimes.js';\nexport { toQueryString } from './query.js';\nexport { DEFAULT_BAAS_URL, DEFAULT_CONSOLE_URL, DEFAULT_APP } from './constants.js';\n\n/**\n * Convenience facade bundling every sub-API over one {@link RoxyonClient}.\n *\n * ```ts\n * const roxyon = new Roxyon({ sessionToken }); // or a roxp_ PAT\n * const ctx = await roxyon.account.context(); // user + subs + domains\n * ```\n */\nexport class Roxyon {\n readonly client: RoxyonClient;\n readonly auth: AuthApi;\n readonly account: AccountApi;\n readonly tokens: TokensApi;\n readonly subscriptions: SubscriptionsApi;\n readonly domains: DomainsApi;\n readonly applications: ApplicationsApi;\n readonly sites: SitesApi;\n\n constructor(options: RoxyonClientOptions | RoxyonClient = {}) {\n this.client = options instanceof RoxyonClient ? options : new RoxyonClient(options);\n this.auth = new AuthApi(this.client);\n this.account = new AccountApi(this.client);\n this.tokens = new TokensApi(this.client);\n this.subscriptions = new SubscriptionsApi(this.client);\n this.domains = new DomainsApi(this.client);\n this.applications = new ApplicationsApi(this.client);\n this.sites = new SitesApi(this.client);\n }\n\n get sessionToken(): string | undefined {\n return this.client.getSessionToken();\n }\n}\n","/**\n * The Roxyon BaaS (\"RX\" engine) resolves failed writes rather than rejecting\n * them — a rejected promise never fires and a failure is shaped like a success\n * body with an `error` string on it (top-level, or inside `results[]`). Every\n * write must be run through {@link rxError} before it is treated as having\n * worked. This mirrors `rxError()` in `console.roxyon.com/src/index.js`.\n *\n * Known failure shapes:\n * { \"results\": [ { \"code\": 1054, \"error\": \"Unknown column ...\", \"type\": \"DBQueryError\" } ] }\n * { \"code\": 105, \"error\": \"Invalid Field Name\", \"type\": \"InvalidFieldName\" }\n */\n\nexport interface RxErrorBody {\n code?: number;\n error?: string;\n type?: string;\n results?: unknown;\n}\n\n/** Returns the error message from a BaaS response, or `''` when the call worked. */\nexport function rxError(r: unknown): string {\n if (r === null || r === undefined) return 'No response from the server.';\n if (typeof r !== 'object') return '';\n const body = r as RxErrorBody;\n if (typeof body.error === 'string' && body.error) return body.error;\n const rows = body.results;\n if (Array.isArray(rows)) {\n for (const row of rows) {\n if (row && typeof row === 'object' && typeof (row as RxErrorBody).error === 'string') {\n const msg = (row as RxErrorBody).error;\n if (msg) return msg;\n }\n }\n }\n return '';\n}\n\nexport class RoxyonApiError extends Error {\n readonly code?: number;\n readonly type?: string;\n readonly status?: number;\n readonly body: unknown;\n\n constructor(\n message: string,\n opts: { code?: number; type?: string; status?: number; body?: unknown } = {},\n ) {\n super(message);\n this.name = 'RoxyonApiError';\n this.code = opts.code;\n this.type = opts.type;\n this.status = opts.status;\n this.body = opts.body;\n }\n}\n\nconst AUTH_CODES = new Set([101, 141, 209, 1060, 1063, 401]);\nconst AUTH_HINTS = [\n 'invalid session',\n 'session token',\n 'unauthorized',\n 'not authorized',\n 'invalid token',\n 'expired',\n 'log in again',\n];\n\n/** True when an error looks like \"the session/token is gone\", so the caller can re-auth. */\nexport function isAuthError(err: unknown): boolean {\n if (err instanceof RoxyonApiError) {\n if (err.status === 401 || err.status === 403) return true;\n if (err.code !== undefined && AUTH_CODES.has(err.code)) return true;\n }\n const msg = (\n err instanceof Error ? err.message : typeof err === 'string' ? err : rxError(err)\n ).toLowerCase();\n return AUTH_HINTS.some((h) => msg.includes(h));\n}\n\n/** Locate the object (top-level or a `results[]` row) that carries the error. */\nfunction erroringNode(r: unknown): RxErrorBody | undefined {\n if (!r || typeof r !== 'object') return undefined;\n const body = r as RxErrorBody;\n if (typeof body.error === 'string' && body.error) return body;\n if (Array.isArray(body.results)) {\n for (const row of body.results) {\n if (row && typeof row === 'object' && (row as RxErrorBody).error) return row as RxErrorBody;\n }\n }\n return undefined;\n}\n\n/** Throw a {@link RoxyonApiError} if `r` carries a BaaS error; otherwise return it typed. */\nexport function assertOk<T>(r: T): T {\n const msg = rxError(r);\n if (msg) {\n const node = erroringNode(r);\n throw new RoxyonApiError(msg, { code: node?.code, type: node?.type, body: r });\n }\n return r;\n}\n","import type { RoxyonClient } from './client.js';\nimport { RoxyonApiError } from './errors.js';\nimport type { TokenScope } from './tokens.js';\n\nexport interface AccountSubscription {\n id: string;\n name: string;\n status: string;\n node: string;\n datacenter: string;\n container: string;\n}\n\nexport interface AccountDomain {\n id: string;\n name: string;\n subscription: string;\n}\n\nexport interface AccountContext {\n user: { id: string; email: string };\n scopes: (TokenScope | '*')[];\n subscriptions: AccountSubscription[];\n domains: AccountDomain[];\n}\n\nexport interface AccountApp {\n id: string;\n name: string;\n status: string;\n desiredState: string;\n runtime: string;\n configRevision: number;\n appliedRevision: number;\n lastError: string | null;\n sourcePath: string;\n repo: { url: string; branch: string } | null;\n}\n\n/**\n * `GET /account/context` — one call the CLI / MCP server use to plan a deploy:\n * the signed-in user, their subscriptions (with node), and their domains.\n * Resolvable by a session token OR a Personal Access Token, so a CI job with\n * only a PAT never has to touch the BaaS.\n */\nexport class AccountApi {\n private cache?: Promise<AccountContext>;\n\n constructor(private readonly client: RoxyonClient) {}\n\n context(opts: { fresh?: boolean } = {}): Promise<AccountContext> {\n if (!this.cache || opts.fresh) this.cache = this.fetch();\n return this.cache;\n }\n\n private async fetch(): Promise<AccountContext> {\n const r = await this.client.console<AccountContext & { ok?: boolean; error?: string }>(\n 'GET',\n '/account/context',\n { tolerateHttpError: true },\n );\n if (!r?.ok || !r.user?.id) {\n throw new RoxyonApiError(r?.error || 'Could not load the account context.', { body: r });\n }\n return {\n user: r.user,\n scopes: r.scopes ?? [],\n subscriptions: r.subscriptions ?? [],\n domains: r.domains ?? [],\n };\n }\n\n /** `GET /account/apps` — the account's applications (list, PAT-safe). */\n async apps(): Promise<AccountApp[]> {\n const r = await this.client.console<{\n ok?: boolean;\n applications?: AccountApp[];\n error?: string;\n }>('GET', '/account/apps', { tolerateHttpError: true });\n if (!r?.ok) throw new RoxyonApiError(r?.error || 'Could not list applications.', { body: r });\n return r.applications ?? [];\n }\n\n /** One application by id, PAT-safe (filters {@link apps}). */\n async getApp(id: string): Promise<AccountApp | undefined> {\n return (await this.apps()).find((a) => a.id === id);\n }\n\n /** Pick the subscription to deploy against — the preferred one, else the only/first. */\n async resolveSubscription(preferred?: string): Promise<AccountSubscription> {\n const { subscriptions } = await this.context();\n if (subscriptions.length === 0) {\n throw new RoxyonApiError('This account has no subscriptions.');\n }\n if (preferred) {\n const hit = subscriptions.find((s) => s.id === preferred || s.name === preferred);\n if (hit) return hit;\n }\n return subscriptions[0]!;\n }\n}\n","import type { RoxyonClient } from './client.js';\nimport { RoxyonApiError, assertOk } from './errors.js';\n\nexport interface Application {\n objectId: string;\n Name: string;\n Status?: string;\n DesiredState?: string;\n SourcePath?: string;\n Runtime?: string;\n RuntimeVersion?: string;\n Preset?: string;\n ConfigRevision?: number;\n AppliedRevision?: number;\n LastError?: string;\n Env?: string;\n RepoUrl?: string;\n Subscription?: string;\n [k: string]: unknown;\n}\n\nexport interface ApplicationProcess {\n objectId: string;\n Application?: string;\n Type?: string;\n Command?: string;\n Status?: string;\n Port?: number;\n}\n\nexport interface ApplicationRoute {\n objectId: string;\n Application?: string;\n Domain?: string;\n Path?: string;\n Enabled?: number | string;\n}\n\ninterface Results<T> {\n results?: T[];\n error?: string;\n}\n\nexport interface DeployResult {\n ok: boolean;\n application: string;\n created?: boolean;\n configRevision?: number;\n files?: number;\n bytes?: number;\n error?: string;\n}\n\n/** Params for creating an application on its first deploy (no id yet). */\nexport interface CreateOnDeploy {\n host: string;\n folder?: string;\n runtime: 'node' | 'python' | 'php';\n runtimeVersion?: string;\n preset?: string;\n command?: string;\n public?: boolean;\n}\n\nexport interface CreateApplicationInput {\n subscription: string;\n name: string;\n /** Absolute source path: `/home/www/<host>/public_html/<folder>`. */\n sourcePath: string;\n runtime: string;\n runtimeVersion: string;\n preset: string;\n /** The web process start command. */\n command: string;\n /** Route host (`Domains.objectId`). */\n domainId: string;\n /** `.env`-style object stored as JSON on `Applications.Env`. */\n env?: Record<string, string>;\n /** Make the app public (route serves the app instead of the host's files). */\n public?: boolean;\n}\n\n/**\n * The Roxyon Applications system. Deployment is declarative: rows describe the\n * desired state and every meaningful change bumps `ConfigRevision`; a\n * server-side reconciler builds the source in an isolated release dir and\n * (re)starts a systemd unit, writing back `Status` / `AppliedRevision` /\n * `LastError`. Mirrors `applications.view` + `modals/app_form.view`.\n */\nexport class ApplicationsApi {\n constructor(private readonly client: RoxyonClient) {}\n\n async list(subscriptionId: string): Promise<Application[]> {\n const r = await this.client.get<Results<Application>>('/Applications', {\n fields:\n 'objectId,Name,Status,DesiredState,SourcePath,Runtime,RuntimeVersion,Preset,ConfigRevision,AppliedRevision,LastError,Env,RepoUrl,Subscription',\n limit: -1,\n order: 'Name',\n where: { Subscription: subscriptionId },\n });\n return r.results ?? [];\n }\n\n async get(id: string): Promise<Application | undefined> {\n const r = await this.client.get<Results<Application>>('/Applications', {\n fields:\n 'objectId,Name,Status,DesiredState,SourcePath,Runtime,RuntimeVersion,Preset,ConfigRevision,AppliedRevision,LastError,Env,RepoUrl,Subscription',\n limit: 1,\n where: { objectId: id },\n });\n return r.results?.[0];\n }\n\n /** Create the application + its web process + a route, matching `createNew()`. */\n async create(\n input: CreateApplicationInput,\n ): Promise<{ application: string; process: string; route: string }> {\n const appRes = assertOk(\n await this.client.post<Results<{ objectId: string }>>('/Applications', {\n Subscription: input.subscription,\n Name: input.name,\n Preset: input.preset,\n SourcePath: input.sourcePath,\n Runtime: input.runtime,\n RuntimeVersion: input.runtimeVersion,\n Env: JSON.stringify(input.env ?? {}),\n Status: 'pending',\n DesiredState: 'running',\n ConfigRevision: 1,\n AppliedRevision: 0,\n LastError: '',\n }),\n );\n const appId = appRes.results?.[0]?.objectId;\n if (!appId) throw new RoxyonApiError('No application id returned.', { body: appRes });\n\n const procRes = assertOk(\n await this.client.post<Results<{ objectId: string }>>('/ApplicationProcesses', {\n Application: appId,\n Type: 'web',\n Port: 0, // allocated by the backend at deploy time\n Command: input.command,\n Status: 'pending',\n }),\n );\n const procId = procRes.results?.[0]?.objectId ?? '';\n\n const routeRes = assertOk(\n await this.client.post<Results<{ objectId: string }>>('/ApplicationRoutes', {\n Application: appId,\n Domain: input.domainId,\n Path: '/',\n Enabled: input.public ? 1 : 0,\n }),\n );\n const routeId = routeRes.results?.[0]?.objectId ?? '';\n\n return { application: appId, process: procId, route: routeId };\n }\n\n // ---- console endpoints (session token or PAT) ----\n\n /** Read an application's environment. `GET /applications/env`. */\n async getEnv(applicationId: string): Promise<Record<string, string>> {\n const r = await this.client.console<{\n ok?: boolean;\n env?: Record<string, string>;\n error?: string;\n }>('GET', '/applications/env', {\n query: { application: applicationId },\n tolerateHttpError: true,\n });\n if (!r?.ok)\n throw new RoxyonApiError(r?.error || 'Could not read the environment.', { body: r });\n return r.env ?? {};\n }\n\n /**\n * Merge `set` and delete `remove`, bumping `ConfigRevision`. `PORT`/`HOST` are\n * ignored (platform-managed). `POST /applications/env`. Returns the new env.\n */\n async setEnv(\n applicationId: string,\n changes: { set?: Record<string, string>; remove?: string[] },\n ): Promise<{ env: Record<string, string>; changed: string[]; configRevision: number }> {\n const r = await this.client.console<{\n ok?: boolean;\n env?: Record<string, string>;\n changed?: string[];\n configRevision?: number;\n error?: string;\n }>('POST', '/applications/env', {\n query: { application: applicationId },\n body: { set: changes.set ?? {}, remove: changes.remove ?? [] },\n tolerateHttpError: true,\n });\n if (!r?.ok)\n throw new RoxyonApiError(r?.error || 'Could not update the environment.', { body: r });\n return { env: r.env ?? {}, changed: r.changed ?? [], configRevision: r.configRevision ?? 0 };\n }\n\n /** Rebuild from the latest source and restart. `POST /applications/action`. */\n async deploy(applicationId: string): Promise<void> {\n const r = await this.client.console<{ error?: string }>('POST', '/applications/action', {\n body: { application: applicationId, action: 'deploy' },\n tolerateHttpError: true,\n });\n if (r?.error) throw new RoxyonApiError(r.error);\n }\n\n /** Bounce the process only — no rebuild. `POST /applications/action`. */\n async restart(applicationId: string): Promise<void> {\n const r = await this.client.console<{ error?: string }>('POST', '/applications/action', {\n body: { application: applicationId, action: 'restart' },\n tolerateHttpError: true,\n });\n if (r?.error) throw new RoxyonApiError(r.error);\n }\n\n /**\n * Tail the app's journal. `POST /applications/logs` returns one block per\n * process (`{ type, unit, output }`); this flattens them to lines, each\n * prefixed with the process type when there is more than one.\n */\n async logs(applicationId: string, lines = 100): Promise<string[]> {\n const r = await this.client.console<{\n processes?: Array<{ type?: string; unit?: string; output?: string }>;\n error?: string;\n }>('POST', '/applications/logs', {\n body: { application: applicationId, lines },\n tolerateHttpError: true,\n });\n if (r?.error) throw new RoxyonApiError(r.error);\n const procs = r?.processes ?? [];\n const multi = procs.length > 1;\n const out: string[] = [];\n for (const p of procs) {\n const body = (p.output ?? '').split('\\n').filter(Boolean);\n for (const line of body) out.push(multi ? `[${p.type ?? 'web'}] ${line}` : line);\n }\n return out;\n }\n\n /** Connect a git remote for push-to-deploy. `POST /applications/repo/connect`. */\n async repoConnect(\n applicationId: string,\n repoUrl: string,\n branch = 'main',\n ): Promise<{\n provider?: string;\n deployKey?: string;\n webhookUrl?: string;\n secret?: string;\n hint?: string;\n }> {\n const r = await this.client.console<{\n error?: string;\n provider?: string;\n deployKey?: string;\n webhookUrl?: string;\n secret?: string;\n hint?: string;\n branch?: string;\n }>('POST', '/applications/repo/connect', {\n body: { application: applicationId, repoUrl, branch },\n tolerateHttpError: true,\n });\n if (r?.error) throw new RoxyonApiError(r.error);\n return r;\n }\n\n /**\n * Upload a gzipped tarball of the project source. The endpoint lands it in the\n * application's `SourcePath` and bumps `ConfigRevision` (the reconciler then\n * builds it in a release dir exactly as for a git deploy).\n *\n * `POST /applications/deploy` — NEW endpoint (see `backend/` in this repo).\n */\n async uploadSource(target: string | CreateOnDeploy, tarball: Uint8Array): Promise<DeployResult> {\n const query: Record<string, string> =\n typeof target === 'string'\n ? { application: target }\n : {\n host: target.host,\n folder: target.folder ?? '',\n runtime: target.runtime,\n ...(target.runtimeVersion ? { runtimeVersion: target.runtimeVersion } : {}),\n ...(target.preset ? { preset: target.preset } : {}),\n ...(target.command ? { command: target.command } : {}),\n public: target.public === false ? '0' : '1',\n };\n const r = await this.client.console<DeployResult>('POST', '/applications/deploy', {\n query,\n headers: { 'content-type': 'application/gzip' },\n body: tarball,\n tolerateHttpError: true,\n });\n if (!r?.ok) throw new RoxyonApiError(r?.error || 'Upload failed.', { body: r });\n return r;\n }\n}\n","import type { RoxyonClient } from './client.js';\nimport { RoxyonApiError } from './errors.js';\n\nexport interface SessionGrant {\n session_token: string;\n refresh_token?: string;\n expires_in?: number;\n status?: string;\n}\n\nexport interface RoxyonUser {\n objectId: string;\n Email?: string;\n Username?: string;\n Name?: string;\n Currency?: string;\n Language?: string;\n [k: string]: unknown;\n}\n\nexport interface LoginPrecheck {\n ok?: boolean;\n error?: string;\n stepUpRequired?: boolean;\n challengeId?: string;\n}\n\nexport interface LoginResult {\n sessionToken: string;\n refreshToken?: string;\n expiresIn?: number;\n /** True when an OTP code is still required — call {@link AuthApi.verifyOtp}. */\n stepUpRequired?: boolean;\n challengeId?: string;\n}\n\n/**\n * Wraps the console's login flow:\n * 1. `POST /_account/login-precheck` — validates credentials, decides whether\n * an OTP step-up is required, and (when it is) returns a `challengeId`.\n * 2a. no step-up -> `POST /Auth/login` finalises and returns a session token.\n * 2b. step-up -> caller collects the code, then `POST /Auth/login/otp-verify`.\n *\n * Mirrors `signin.view` / `otp.view` in `console.roxyon.com`.\n */\nexport class AuthApi {\n constructor(private readonly client: RoxyonClient) {}\n\n /**\n * Best-effort device/step-up precheck. `/_account/login-precheck` is a console\n * cloud function that may be gated behind the REST key (not reachable from a\n * public client) — in that case this resolves to `{}` and login falls back to\n * `/Auth/login`, which is itself the security boundary and re-checks the\n * device. Only a definitive `{ ok: false }` / `stepUpRequired` is acted on.\n */\n async precheck(\n email: string,\n password: string,\n metadata: Record<string, string> = {},\n ): Promise<LoginPrecheck> {\n try {\n const r = await this.client.post<LoginPrecheck & { code?: number }>(\n '/_account/login-precheck',\n { Email: email, Password: password, metadata },\n { tolerateHttpError: true },\n );\n // Endpoint not available to this client — ignore, let /Auth/login decide.\n if (r?.code === 401 || (r?.error && /rest api key/i.test(r.error))) return {};\n return r ?? {};\n } catch {\n return {};\n }\n }\n\n /**\n * Full login. Returns a session token on success, or `stepUpRequired` with a\n * `challengeId` when an OTP code is needed next.\n */\n async login(\n email: string,\n password: string,\n metadata: Record<string, string> = {},\n ): Promise<LoginResult> {\n const pre = await this.precheck(email, password, metadata);\n if (pre.ok === false && pre.error && !pre.stepUpRequired) {\n throw new RoxyonApiError(pre.error, { type: 'CredentialsError' });\n }\n if (pre.stepUpRequired) {\n return { sessionToken: '', stepUpRequired: true, challengeId: pre.challengeId };\n }\n\n const grant = await this.client.post<\n SessionGrant & { error?: string; stepUpRequired?: boolean; challengeId?: string }\n >('/Auth/login', { Email: email, Password: password, metadata }, { tolerateHttpError: true });\n\n // Some accounts step up at /Auth/login itself rather than at precheck.\n if (grant?.stepUpRequired || (grant?.challengeId && !grant.session_token)) {\n return { sessionToken: '', stepUpRequired: true, challengeId: grant.challengeId };\n }\n if (!grant?.session_token) {\n throw new RoxyonApiError(grant?.error || 'Wrong email or password.', {\n type: 'CredentialsError',\n });\n }\n this.client.setSessionToken(grant.session_token);\n return {\n sessionToken: grant.session_token,\n refreshToken: grant.refresh_token,\n expiresIn: grant.expires_in,\n };\n }\n\n /** Complete an OTP step-up with the code the user received. */\n async verifyOtp(challengeId: string, code: string): Promise<LoginResult> {\n const grant = await this.client.post<SessionGrant & { error?: string }>(\n '/Auth/login/otp-verify',\n { challengeId, code },\n { tolerateHttpError: true },\n );\n if (grant?.status !== 'authenticated' || !grant.session_token) {\n throw new RoxyonApiError(grant?.error || 'That code did not verify.', {\n type: 'OtpError',\n body: grant,\n });\n }\n this.client.setSessionToken(grant.session_token);\n return {\n sessionToken: grant.session_token,\n refreshToken: grant.refresh_token,\n expiresIn: grant.expires_in,\n };\n }\n\n /** Start an OTP-only sign-in (no password). Returns a `challengeId`. */\n async startOtp(email: string): Promise<{ challengeId: string }> {\n const r = await this.client.post<{ challengeId?: string; error?: string }>(\n '/Auth/login/otp',\n { Email: email },\n { tolerateHttpError: true },\n );\n if (!r?.challengeId) {\n throw new RoxyonApiError(r?.error || 'Could not start OTP sign-in.', { body: r });\n }\n return { challengeId: r.challengeId };\n }\n\n /** The currently authenticated user. Requires a session token on the client. */\n async me(): Promise<RoxyonUser> {\n const user = await this.client.post<RoxyonUser & { error?: string }>('/Auth/me', {});\n if (!user?.objectId) {\n throw new RoxyonApiError(user?.error || 'Not signed in.', { status: 401, body: user });\n }\n return user;\n }\n\n async logout(): Promise<void> {\n await this.client.post('/Auth/logout', {}, { tolerateHttpError: true }).catch(() => undefined);\n this.client.setSessionToken(undefined);\n }\n}\n","/**\n * Default endpoints and the public application credentials the client uses to\n * mint an anonymous token before a user logs in.\n *\n * `X-BEA-JavaScript-Key` is a **public** key (it ships in browser bundles by\n * design — see `console.roxyon.com/src/index.js`). It is safe to embed here.\n * The REST key is never embedded — user actions always run under a session\n * token or a Personal Access Token.\n *\n * TODO(M1): provision a dedicated `roxyon-cli` BaaS application and swap these\n * for its App-ID / JavaScript-Key so CLI traffic is attributable and rate-limited\n * separately from the web console. Until then the client reuses the console's\n * public pair, which is already exposed in shipped frontend code.\n */\nexport const DEFAULT_BAAS_URL = 'https://www.beaapis.com/1';\nexport const DEFAULT_CONSOLE_URL = 'https://console.roxyon.com';\n\nexport const DEFAULT_APP = {\n appId: 'jAtp2zHGU3FbnrQWrToALFakd_vbiY0ywihn4Hj54lw',\n javascriptKey: 'w2Y9USRg0COtNe-fUqOaC1OOOlNCnV2BG8GZF80w4x8',\n} as const;\n\n/** Header names, lower-cased (the API is case-insensitive but the SDK uses these). */\nexport const H = {\n appId: 'x-bea-application-id',\n jsKey: 'x-bea-javascript-key',\n restKey: 'x-bea-authorization',\n sessionToken: 'x-bea-session-token',\n accessToken: 'x-bea-access-token',\n refreshToken: 'x-bea-refresh-token',\n} as const;\n","/**\n * GET query serialisation for the BaaS, matching the `Obj2Par` helper in the\n * browser SDK (`rx.js`): nested objects become PHP-style bracket keys\n * (`where[User]=abc`, `where[Status][in]=a,b,c`).\n *\n * Two hard-won rules (see the `roxyon-api-write-failures` notes):\n * - The `in` operator takes a **comma-joined string, not an array**. An array\n * serialises to `where[X][in][0]=…` bracket notation the API does not read.\n * Pass `{ in: ['a', 'b'] }` here and we join it for you.\n * - A `select` subquery nested inside an `or` group crashes the API. Resolve\n * ids in a first query, then `or: [..., { objectId: { in: 'a,b' } }]`.\n */\n\nexport type QueryValue =\n | string\n | number\n | boolean\n | null\n | undefined\n | QueryValue[]\n | { [k: string]: QueryValue };\n\nexport type QueryObject = Record<string, QueryValue>;\n\nfunction encode(k: string, v: string): string {\n return `${encodeURIComponent(k)}=${encodeURIComponent(v)}`;\n}\n\nfunction walk(value: QueryValue, prefix: string, out: string[]): void {\n if (value === null || value === undefined) return;\n\n if (Array.isArray(value)) {\n // A bare array under a normal key -> repeated bracket-index entries. The\n // only array we actually want is `in`, and that is handled below before we\n // ever get here, so this branch is a best-effort fallback.\n value.forEach((item, i) => walk(item, `${prefix}[${i}]`, out));\n return;\n }\n\n if (typeof value === 'object') {\n for (const [key, child] of Object.entries(value)) {\n if (key === 'in' || key === 'nin' || key === 'notIn') {\n const joined = Array.isArray(child) ? child.join(',') : String(child);\n out.push(encode(`${prefix}[${key === 'notIn' ? 'nin' : key}]`, joined));\n continue;\n }\n walk(child, `${prefix}[${key}]`, out);\n }\n return;\n }\n\n out.push(encode(prefix, String(value)));\n}\n\n/** Serialise a query object to a `key=value&...` string (no leading `?`). */\nexport function toQueryString(query: QueryObject | undefined): string {\n if (!query) return '';\n const out: string[] = [];\n for (const [key, value] of Object.entries(query)) {\n walk(value, key, out);\n }\n return out.join('&');\n}\n","import { DEFAULT_APP, DEFAULT_BAAS_URL, DEFAULT_CONSOLE_URL, H } from './constants.js';\nimport { RoxyonApiError } from './errors.js';\nimport { type QueryObject, toQueryString } from './query.js';\n\nexport interface RoxyonClientOptions {\n /** BaaS application id. Defaults to the public console app. */\n appId?: string;\n /** Public JavaScript key, used to mint an anonymous token. */\n javascriptKey?: string;\n /** REST API key. Optional; grants full access — only for trusted server use. */\n restKey?: string;\n /** A user session token (from {@link AuthApi.login}). */\n sessionToken?: string;\n /** BaaS REST base, e.g. `https://www.beaapis.com/1`. */\n baseUrl?: string;\n /** Console base that serves the `/applications/*` endpoints. */\n consoleUrl?: string;\n /** Custom fetch (tests / proxies). */\n fetch?: typeof fetch;\n}\n\nexport interface RequestOptions {\n query?: QueryObject;\n body?: unknown;\n headers?: Record<string, string>;\n /** Skip the Authorization/session header entirely (used for token minting). */\n skipAuth?: boolean;\n /** Send/parse the response even on a non-2xx status instead of throwing. */\n tolerateHttpError?: boolean;\n signal?: AbortSignal;\n}\n\ninterface AnonToken {\n access_token?: string;\n session_token?: string;\n refresh_token?: string;\n expires_in?: number;\n /** epoch ms this token becomes unusable */\n _expiresAt?: number;\n}\n\n/**\n * Low-level transport for the Roxyon BaaS and console app endpoints.\n *\n * Auth precedence per request: explicit `sessionToken` -> `restKey` ->\n * a lazily-minted anonymous access token (public app credentials).\n */\nexport class RoxyonClient {\n readonly baseUrl: string;\n readonly consoleUrl: string;\n private readonly appId: string;\n private readonly javascriptKey: string;\n private readonly restKey?: string;\n private readonly _fetch: typeof fetch;\n private sessionToken?: string;\n private anon?: AnonToken;\n\n constructor(opts: RoxyonClientOptions = {}) {\n this.baseUrl = (opts.baseUrl ?? DEFAULT_BAAS_URL).replace(/\\/+$/, '');\n this.consoleUrl = (opts.consoleUrl ?? DEFAULT_CONSOLE_URL).replace(/\\/+$/, '');\n this.appId = opts.appId ?? DEFAULT_APP.appId;\n this.javascriptKey = opts.javascriptKey ?? DEFAULT_APP.javascriptKey;\n this.restKey = opts.restKey;\n this.sessionToken = opts.sessionToken;\n this._fetch = opts.fetch ?? globalThis.fetch;\n if (typeof this._fetch !== 'function') {\n throw new Error('No fetch implementation available (need Node >= 20 or pass opts.fetch).');\n }\n }\n\n getSessionToken(): string | undefined {\n return this.sessionToken;\n }\n\n setSessionToken(token: string | undefined): void {\n this.sessionToken = token;\n }\n\n /** Mint (or reuse) an anonymous access token from the public app credentials. */\n private async anonToken(): Promise<AnonToken> {\n if (this.anon?._expiresAt && this.anon._expiresAt > Date.now() + 5_000) {\n return this.anon;\n }\n const res = await this._fetch(`${this.baseUrl}/Auth`, {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n [H.appId]: this.appId,\n [H.jsKey]: this.javascriptKey,\n },\n body: JSON.stringify({ scope: 'public' }),\n });\n const json = (await res.json().catch(() => ({}))) as AnonToken;\n if (!json.access_token && !json.session_token) {\n throw new RoxyonApiError('Could not obtain an anonymous BaaS token.', {\n status: res.status,\n body: json,\n });\n }\n json._expiresAt = Date.now() + (json.expires_in ? json.expires_in * 1000 : 3_600_000);\n this.anon = json;\n return json;\n }\n\n /** A Personal Access Token (`roxp_…`) authenticates the console endpoints via\n * `Authorization: Bearer`; it is not a BaaS session token. */\n private get isPat(): boolean {\n return this.sessionToken?.startsWith('roxp_') ?? false;\n }\n\n private async authHeaders(\n skipAuth: boolean,\n isConsole: boolean,\n ): Promise<Record<string, string>> {\n const base: Record<string, string> = { [H.appId]: this.appId };\n if (skipAuth) return base;\n if (this.isPat) {\n // Console: Bearer. BaaS: nothing useful — PAT clients resolve identity and\n // subscriptions through the console's /account/context instead.\n return isConsole ? { ...base, authorization: `Bearer ${this.sessionToken}` } : base;\n }\n if (this.sessionToken) return { ...base, [H.sessionToken]: this.sessionToken };\n if (this.restKey) return { ...base, [H.restKey]: this.restKey };\n const anon = await this.anonToken();\n if (anon.session_token) return { ...base, [H.sessionToken]: anon.session_token };\n return { ...base, [H.accessToken]: anon.access_token ?? '' };\n }\n\n /** A raw BaaS request. `path` is relative to {@link baseUrl} (leading `/`). */\n async request<T = unknown>(method: string, path: string, opts: RequestOptions = {}): Promise<T> {\n return this.rawRequest<T>(this.baseUrl, method, path, opts);\n }\n\n /** A request against the console app endpoints ({@link consoleUrl}). */\n async console<T = unknown>(method: string, path: string, opts: RequestOptions = {}): Promise<T> {\n return this.rawRequest<T>(this.consoleUrl, method, path, opts);\n }\n\n private async rawRequest<T>(\n root: string,\n method: string,\n path: string,\n opts: RequestOptions,\n ): Promise<T> {\n const qs = toQueryString(opts.query);\n const url = `${root}${path.startsWith('/') ? path : `/${path}`}${qs ? `?${qs}` : ''}`;\n const headers: Record<string, string> = {\n ...(await this.authHeaders(opts.skipAuth ?? false, root === this.consoleUrl)),\n ...opts.headers,\n };\n const hasBody = method !== 'GET' && method !== 'HEAD' && opts.body !== undefined;\n let body: string | Uint8Array | ArrayBuffer | FormData | undefined;\n if (hasBody) {\n if (\n typeof opts.body === 'string' ||\n opts.body instanceof Uint8Array ||\n opts.body instanceof ArrayBuffer ||\n (typeof FormData !== 'undefined' && opts.body instanceof FormData)\n ) {\n body = opts.body as string | Uint8Array | ArrayBuffer | FormData;\n } else {\n headers['content-type'] = headers['content-type'] ?? 'application/json';\n body = JSON.stringify(opts.body);\n }\n }\n\n let res: Response;\n try {\n res = await this._fetch(url, { method, headers, body, signal: opts.signal });\n } catch (cause) {\n throw new RoxyonApiError(`Network error calling ${method} ${url}`, { body: cause });\n }\n\n const text = await res.text();\n let json: unknown;\n try {\n json = text ? JSON.parse(text) : {};\n } catch {\n json = { error: text || `HTTP ${res.status}`, _raw: text };\n }\n\n if (!res.ok && !opts.tolerateHttpError) {\n const msg =\n (json &&\n typeof json === 'object' &&\n 'error' in json &&\n (json as { error: string }).error) ||\n `HTTP ${res.status} calling ${method} ${path}`;\n throw new RoxyonApiError(String(msg), { status: res.status, body: json });\n }\n return json as T;\n }\n\n get<T = unknown>(path: string, query?: QueryObject, opts?: RequestOptions): Promise<T> {\n return this.request<T>('GET', path, { ...opts, query });\n }\n post<T = unknown>(path: string, body?: unknown, opts?: RequestOptions): Promise<T> {\n return this.request<T>('POST', path, { ...opts, body });\n }\n put<T = unknown>(path: string, body?: unknown, opts?: RequestOptions): Promise<T> {\n return this.request<T>('PUT', path, { ...opts, body });\n }\n del<T = unknown>(path: string, body?: unknown, opts?: RequestOptions): Promise<T> {\n return this.request<T>('DELETE', path, { ...opts, body });\n }\n}\n","import type { RoxyonClient } from './client.js';\n\nexport interface Domain {\n objectId: string;\n Name: string;\n}\n\n/** Domains (hosts) attached to a subscription — used to place an application. */\nexport class DomainsApi {\n constructor(private readonly client: RoxyonClient) {}\n\n async list(subscriptionId: string): Promise<Domain[]> {\n const r = await this.client.get<{ results?: Domain[] }>('/Domains', {\n fields: 'objectId,Name',\n limit: -1,\n order: 'Name',\n where: { Subscription: subscriptionId },\n });\n return r.results ?? [];\n }\n}\n","import type { RoxyonClient } from './client.js';\nimport { RoxyonApiError } from './errors.js';\n\nexport interface StaticDeployResult {\n ok: boolean;\n host: string;\n path: string;\n files?: number;\n error?: string;\n}\n\n/**\n * Static-site deploy: upload built files (a LumenJS `--serverless` build, or any\n * static output) into a host's document root\n * (`/home/www/<host>/public_html[/<folder>]`), served directly by nginx. No\n * Application row, no process.\n *\n * `POST /sites/deploy` — NEW endpoint (see `backend/` in this repo).\n */\nexport class SitesApi {\n constructor(private readonly client: RoxyonClient) {}\n\n async deploy(host: string, folder: string, tarball: Uint8Array): Promise<StaticDeployResult> {\n const r = await this.client.console<StaticDeployResult>('POST', '/sites/deploy', {\n query: { host, folder },\n headers: { 'content-type': 'application/gzip' },\n body: tarball,\n tolerateHttpError: true,\n });\n if (!r?.ok) throw new RoxyonApiError(r?.error || 'Static deploy failed.', { body: r });\n return r;\n }\n}\n","import type { RoxyonClient } from './client.js';\nimport { RoxyonApiError } from './errors.js';\n\nexport interface Subscription {\n objectId: string;\n Name?: string;\n Status?: string;\n Username?: string;\n /** Infra node the subscription's container lives on (internal). */\n Node?: string;\n Datacenter?: string;\n [k: string]: unknown;\n}\n\nexport interface Privilege {\n objectId: string;\n Type?: string;\n Subscription?: string;\n _Subscription?: { results: Subscription[] };\n [k: string]: unknown;\n}\n\ninterface ListResponse<T> {\n results?: T[];\n error?: string;\n}\n\n/** Access to the caller's subscriptions (via their Privileges rows). */\nexport class SubscriptionsApi {\n constructor(private readonly client: RoxyonClient) {}\n\n /** All subscriptions the signed-in user has a Privilege on. */\n async list(userId: string): Promise<Subscription[]> {\n const r = await this.client.get<ListResponse<Privilege>>('/Privileges', {\n where: { User: userId },\n fields: 'objectId,Type,Subscription',\n limit: -1,\n include: [\n {\n className: 'Subscriptions',\n field: 'Subscription',\n fields: 'objectId,Name,Status,Username,Node,Datacenter',\n },\n ],\n });\n if (!Array.isArray(r.results)) {\n throw new RoxyonApiError(r.error || 'Could not load subscriptions.', {\n status: 401,\n body: r,\n });\n }\n const subs: Subscription[] = [];\n for (const priv of r.results) {\n const sub = priv._Subscription?.results?.[0];\n if (sub) subs.push(sub);\n }\n return subs;\n }\n\n /**\n * Resolve the subscription to act on. Prefers an exact `objectId` or `Name`\n * match against `preferred`; otherwise the first active subscription; otherwise\n * the first one. Throws when the account has none.\n */\n async resolve(userId: string, preferred?: string): Promise<Subscription> {\n const subs = await this.list(userId);\n if (subs.length === 0) {\n throw new RoxyonApiError(\n 'This account has no active subscription — add a plan in the console first.',\n );\n }\n if (preferred) {\n const hit = subs.find(\n (s) => s.objectId === preferred || s.Name === preferred || s.Username === preferred,\n );\n if (hit) return hit;\n throw new RoxyonApiError(`No subscription matches \"${preferred}\".`);\n }\n return subs.find((s) => s.Status === 'active') ?? subs[0]!;\n }\n}\n","import type { RoxyonClient } from './client.js';\nimport { RoxyonApiError } from './errors.js';\n\nexport type TokenScope = 'deploy' | 'logs' | 'read';\n\nexport interface TokenSummary {\n id: string;\n name: string;\n prefix: string;\n scopes: TokenScope[];\n lastUsedAt: string | null;\n expiresAt: string | null;\n createdAt: string;\n}\n\nexport interface CreatedToken {\n /** The full `roxp_…` secret — shown once. Use it as `ROXYON_TOKEN`. */\n token: string;\n name: string;\n scopes: TokenScope[];\n expiresAt: string | null;\n}\n\n/**\n * Personal Access Tokens — for the CLI in CI and for the MCP server running\n * headless. Managed only while signed in with a session (`roxyon login`); a PAT\n * cannot mint or revoke another PAT.\n *\n * `GET/POST/DELETE /account/tokens` — console endpoints.\n */\nexport class TokensApi {\n constructor(private readonly client: RoxyonClient) {}\n\n async list(): Promise<TokenSummary[]> {\n const r = await this.client.console<{ ok?: boolean; tokens?: TokenSummary[]; error?: string }>(\n 'GET',\n '/account/tokens',\n { tolerateHttpError: true },\n );\n if (!r?.ok) throw new RoxyonApiError(r?.error || 'Could not list tokens.', { body: r });\n return r.tokens ?? [];\n }\n\n async create(\n name: string,\n opts: { scopes?: TokenScope[]; expiresInDays?: number } = {},\n ): Promise<CreatedToken> {\n const r = await this.client.console<CreatedToken & { ok?: boolean; error?: string }>(\n 'POST',\n '/account/tokens',\n {\n body: {\n name,\n scopes: opts.scopes ?? ['deploy', 'logs'],\n ...(opts.expiresInDays ? { expiresInDays: opts.expiresInDays } : {}),\n },\n tolerateHttpError: true,\n },\n );\n if (!r?.ok || !r.token) {\n throw new RoxyonApiError(r?.error || 'Could not create the token.', { body: r });\n }\n return { token: r.token, name: r.name, scopes: r.scopes, expiresAt: r.expiresAt ?? null };\n }\n\n async revoke(id: string): Promise<void> {\n const r = await this.client.console<{ ok?: boolean; error?: string }>(\n 'DELETE',\n '/account/tokens',\n { query: { id }, tolerateHttpError: true },\n );\n if (!r?.ok) throw new RoxyonApiError(r?.error || 'Could not revoke the token.', { body: r });\n }\n}\n","/**\n * `.env`-style block <-> JSON object, ported verbatim from `appfEnvParse` /\n * `appfEnvToLines` in `console.roxyon.com/.../modals/app_form.view` so the CLI\n * and the console form agree byte-for-byte on what `Applications.Env` holds.\n *\n * The server re-sanitises again (`ApplicationRenderer::envPair`), so this only\n * needs to be reasonable. `PORT` and `HOST` are set by the platform — callers\n * should not write them.\n */\nexport function parseEnv(text: string): Record<string, string> {\n const out: Record<string, string> = {};\n for (let line of String(text || '').split(/\\r?\\n/)) {\n line = line.trim();\n if (!line || line.startsWith('#')) continue;\n line = line.replace(/^export\\s+/, '');\n const eq = line.indexOf('=');\n if (eq < 1) continue;\n const k = line.slice(0, eq).trim();\n let v = line.slice(eq + 1).trim();\n if (v.length >= 2 && (v[0] === '\"' || v[0] === \"'\") && v[v.length - 1] === v[0]) {\n v = v.slice(1, -1);\n }\n if (/^[A-Za-z_][A-Za-z0-9_]*$/.test(k)) out[k] = v;\n }\n return out;\n}\n\nexport function formatEnv(obj: Record<string, string> | null | undefined): string {\n if (!obj || typeof obj !== 'object') return '';\n return Object.keys(obj)\n .map((k) => `${k}=${obj[k] == null ? '' : String(obj[k])}`)\n .join('\\n');\n}\n\n/** Parse the JSON string stored on `Applications.Env`. */\nexport function envFromStored(jsonStr: string | undefined): Record<string, string> {\n if (!jsonStr) return {};\n try {\n const obj = JSON.parse(jsonStr);\n return obj && typeof obj === 'object' ? (obj as Record<string, string>) : {};\n } catch {\n return {};\n }\n}\n","/**\n * Runtime / version / framework catalog — a verbatim copy of the `RUNTIMES`\n * table in `console.roxyon.com/.../modals/app_form.view`. These are the versions\n * actually installed in the Cloud Hosting containers; offering an uninstalled\n * one produces a deploy that fails at build time for a reason the user cannot\n * act on.\n *\n * TODO(M4): the console form and this file should both import one shared JSON\n * published at `roxyon.com/runtimes.json` so they never drift.\n */\nexport type RuntimeName = 'lumen' | 'node' | 'python' | 'php';\n\nexport interface RuntimeSpec {\n versions: string[];\n defaultVersion: string;\n presets: Array<[value: string, label: string]>;\n command: string;\n}\n\nexport const RUNTIMES: Record<Exclude<RuntimeName, 'lumen'>, RuntimeSpec> = {\n node: {\n versions: ['23.11.1', '22.23.1', '20.20.2', '18.20.8'],\n defaultVersion: '20.20.2',\n presets: [\n ['nextjs', 'Next.js'],\n ['nuxt', 'Nuxt'],\n ['node', 'No framework'],\n ],\n command: 'npm run start',\n },\n python: {\n versions: ['3.11'],\n defaultVersion: '3.11',\n presets: [['python', 'No framework']],\n command: 'gunicorn app:app',\n },\n php: {\n versions: ['8.4', '8.3', '8.2', '8.1', '7.4'],\n defaultVersion: '8.4',\n presets: [\n ['swoole', 'Swoole'],\n ['php', 'No framework'],\n ],\n command: 'php8.4 server.php',\n },\n};\n\n/**\n * A LumenJS project (`runtime: \"lumen\"`) builds to static files with\n * `lm build --serverless` and is served straight from the host's document root\n * by nginx — no long-running process, no systemd unit, no Application row. It\n * deploys through the \"static\" path (upload the built `dist/` to\n * `/home/www/<host>/public_html[/<folder>]`).\n *\n * Node / Python / PHP projects deploy through the \"app\" path (the Applications\n * system: upload source, bump ConfigRevision, reconciler builds + runs it).\n */\nexport type DeployKind = 'static' | 'app';\n\nexport const LUMEN_BUILD = {\n command: 'lm build --serverless',\n /** Directory `lm build --serverless` writes to, relative to the project root. */\n outDir: 'dist',\n} as const;\n"],"mappings":"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","names":[]}