// Userland runtime context v0 declarations for coding agents.
// Generated by the Userland docs artifact build from the public runtime contract.

export interface UserlandRuntimeContext {
  app: {
    id: string;
    app_id: string;
    origin: string;
    releaseId: string;
    release_id: string;
  };
  auth: UserlandAuthNamespace;
  data: UserlandDataNamespace;
  files: UserlandFilesNamespace;
  secrets: UserlandSecretsNamespace;
  jobs: UserlandJobsNamespace;
  webhooks: UserlandWebhooksNamespace;
  log: UserlandLogNamespace;
}

export interface UserlandAuthNamespace {
  readonly app_id: string;
  currentUser(request: Request): Promise<UserlandAppUser | null>;
  requireUser(request: Request): Promise<UserlandAppUser>;
  requireRole(request: Request, role: string): Promise<UserlandAppUser>;
  createSession(userId: string): Promise<UserlandResponseCookie>;
  endSession(request: Request): Promise<void>;
}

export interface UserlandAppUser {
  id: string;
  app_user_id: string;
  email: string;
  roles: string[];
}

export interface UserlandResponseCookie {
  name: string;
  value: string;
  header: string;
  expires_at: string;
}

export interface UserlandDataNamespace {
  readonly app_id: string;
  collection(name: string): UserlandDataCollection;
  transaction<T>(callback: (tx: UserlandDataNamespace) => Promise<T> | T): Promise<T>;
}

export interface UserlandDataCollection {
  create(row: Record<string, unknown>): Promise<UserlandDataRow>;
  get(id: string): Promise<UserlandDataRow | null>;
  update(id: string, patch: Record<string, unknown>): Promise<UserlandDataRow>;
  delete(id: string): Promise<void>;
  list(query?: UserlandDataQuery): Promise<UserlandDataListResult>;
  query(query?: UserlandDataQuery): Promise<UserlandDataListResult>;
}

export interface UserlandDataRow {
  id: string;
  created_at: string;
  updated_at: string;
  data: Record<string, unknown>;
  [field: string]: unknown;
}

export interface UserlandDataQuery {
  where?: Record<string, unknown>;
  order_by?: Array<{ field: string; direction?: "asc" | "desc" }>;
  limit?: number;
  cursor?: string;
}

export interface UserlandDataListResult {
  rows: UserlandDataRow[];
  cursor?: string;
}

export interface UserlandFilesNamespace {
  readonly app_id: string;
  store(name: string): UserlandFileStore;
}

export interface UserlandFileStore {
  createUpload(bytes: ArrayBuffer | Uint8Array | string, options: UserlandFileCreateOptions): Promise<UserlandFileRecord>;
  getPublicUrl(fileId: string): Promise<string>;
  getSignedUrl(fileId: string, options?: UserlandFileSignedUrlOptions): Promise<string>;
  delete(fileId: string): Promise<void>;
  list(query?: UserlandFileListQuery): Promise<UserlandFileListResult>;
}

export interface UserlandFileCreateOptions {
  path?: string;
  filename?: string;
  content_type: string;
  metadata?: Record<string, unknown>;
}

export interface UserlandFileSignedUrlOptions {
  expires_in_seconds?: number;
}

export interface UserlandFileListQuery {
  limit?: number;
  cursor?: string;
}

export interface UserlandFileListResult {
  files: UserlandFileRecord[];
  cursor?: string;
}

export interface UserlandFileRecord {
  file_id: string;
  id: string;
  store_name: string;
  path: string;
  url: string;
  content_type: string;
  size_bytes: number;
  metadata: Record<string, unknown>;
  created_at: string;
  updated_at: string;
}

export interface UserlandSecretsNamespace {
  readonly app_id: string;
  get(name: string): Promise<string | undefined>;
  require(name: string): Promise<string>;
}

export interface UserlandJobsNamespace {
  readonly app_id: string;
  enqueue(name: string, payload?: Record<string, unknown>, options?: UserlandJobEnqueueOptions): Promise<UserlandEnqueuedJob>;
}

export interface UserlandJobEnqueueOptions {
  delay_seconds?: number;
  run_after?: string;
}

export interface UserlandEnqueuedJob {
  job_id: string;
  name: string;
  status: "queued";
  run_after: string;
}

export interface UserlandWebhooksNamespace {
  readonly app_id: string;
}

export interface UserlandLogNamespace {
  debug(message: string, metadata?: Record<string, unknown>): Promise<void>;
  info(message: string, metadata?: Record<string, unknown>): Promise<void>;
  warn(message: string, metadata?: Record<string, unknown>): Promise<void>;
  error(message: string, metadata?: Record<string, unknown>): Promise<void>;
}

export interface UserlandJobEvent {
  job_id: string;
  name: string;
  payload: Record<string, unknown>;
}

export interface UserlandWebhookEvent {
  webhook_delivery_id: string;
  name: string;
  headers: Record<string, string>;
  payload: unknown;
}

export interface UserlandServerModule {
  fetch?: (request: Request, ctx: UserlandRuntimeContext) => Promise<Response> | Response;
  job?: (event: UserlandJobEvent, ctx: UserlandRuntimeContext) => Promise<void> | void;
  webhook?: (event: UserlandWebhookEvent, ctx: UserlandRuntimeContext) => Promise<Response | void> | Response | void;
}

