import { type SlugTokenFactory } from "./slug.js"; import type { TypedQueryClient } from "./generated/storage-kit/query.js"; import type { AddDomainInput, Click, ClickInput, CreateLinkInput, Domain, Link, LinkStats } from "./types.js"; export type PgAdapterLike = { get(sql: string, ...params: unknown[]): Promise; all(sql: string, ...params: unknown[]): Promise; run(sql: string, ...params: unknown[]): Promise; close?: () => Promise; }; /** * Adapt a vendored storage-kit `TypedQueryClient` (which speaks `$1` positional * params) to the `?`-placeholder `PgAdapterLike` the store queries are written * against. This lets `shortlinks-serve` reuse the exact same SQL as the CLI while * opening its cloud pool through the sanctioned kit (`createCloudPoolFromEnv`). */ export declare function createKitPgAdapter(client: TypedQueryClient): PgAdapterLike; export interface PgShortlinksStoreOptions { /** Injectable only for deterministic collision tests; production uses cryptographic randomness. */ tokenFactory?: SlugTokenFactory; managedDefaultDomain?: string; reservedSlugs?: Iterable; } export declare class PgShortlinksStore { private readonly pg; private readonly tokenFactory; private readonly managedDefaultDomain; private readonly reservedSlugs; constructor(pg: PgAdapterLike, options?: PgShortlinksStoreOptions); /** * Build a store over a vendored storage-kit query client. This is the ONLY * constructor: the serve entrypoint opens its pool via `createCloudPoolFromEnv` * (server-side) and hands the client here. There is deliberately no * DSN-from-env / connection-string path so this store can never be misused to * open the raw RDS from a client. */ static fromQueryClient(client: TypedQueryClient, options?: PgShortlinksStoreOptions): PgShortlinksStore; close(): Promise; addDomain(input: AddDomainInput): Promise; listDomains(): Promise; getDomain(hostnameOrId: string): Promise; getDefaultDomain(): Promise; private ensureDefaultDomain; deleteDomain(hostnameOrId: string): Promise; createLink(input: CreateLinkInput): Promise; listLinks(options?: { domain?: string; activeOnly?: boolean; limit?: number; }): Promise; getLink(domainOrSlug: string, maybeSlug?: string): Promise; totalStats(): Promise<{ domains: number; links: number; clicks: number; }>; resolve(hostname: string, slug: string): Promise; setLinkActive(domainOrSlug: string, maybeSlugOrActive: string | boolean, maybeActive?: boolean): Promise; deleteLink(domainOrSlug: string, maybeSlug?: string): Promise; recordClick(link: Link, input?: ClickInput): Promise; getStats(domainOrSlug: string, maybeSlug?: string): Promise; private hashIp; }