Athena

Athena.js Snippet Catalog

Exhaustive code-snippet catalog imported from athena-js source documentation.

This page aggregates snippet blocks from xylex-group/athena-js documentation sources so every example is available in one place.

Total snippets imported: 159.

Sources included: README.md, CONTRIBUTING.md, docs/**/*.md(x), and test-sdk/**/*.md(x) from the athena-js repository.

Context7 _autodocs

Source: Context7 library /xylex-group/athena-js (autogenerated reference corpus excerpts)

AthenaAuthSdkClient Interface

interface AthenaAuthSdkClient {
  signIn: {
    email(input: AthenaEmailSignInRequest): Promise<AthenaAuthResult<AthenaAuthSignInResponse>>
    username(input: AthenaUsernameSignInRequest): Promise<AthenaAuthResult<AthenaAuthSignInResponse>>
    social(input: AthenaSocialSignInRequest): Promise<AthenaAuthResult<AthenaAuthSignInResponse | AthenaAuthSocialRedirectResponse>>
  }
  
  signUp: {
    email(input: AthenaEmailSignUpRequest): Promise<AthenaAuthResult<AthenaAuthSignInResponse>>
  }
  
  session: {
    get(): Promise<AthenaAuthResult<AthenaAuthSessionResponse>>
    list(): Promise<AthenaAuthResult<AthenaAuthSession[]>>
  }
  
  signOut(): Promise<AthenaAuthResult<AthenaAuthSignOutResponse>>
  
  password: {
    forget(input: AthenaForgetPasswordRequest): Promise<AthenaAuthResult<void>>
    reset(input: AthenaResetPasswordRequest): Promise<AthenaAuthResult<void>>
  }
  
  email: {
    verify(input: AthenaVerifyEmailRequest): Promise<AthenaAuthResult<void>>
    change(input: AthenaChangeEmailRequest): Promise<AthenaAuthResult<void>>
    sendVerification(input: AthenaSendVerificationEmailRequest): Promise<AthenaAuthResult<void>>
  }
  
  user: {
    update(input: AthenaUpdateUserRequest): Promise<AthenaAuthResult<AthenaAuthUser>>
    delete(input: AthenaDeleteUserRequest): Promise<AthenaAuthResult<void>>
  }
  
  account: {
    link(input: AthenaLinkSocialRequest): Promise<AthenaAuthResult<AthenaAuthLinkedAccount>>
    unlink(input: AthenaUnlinkAccountRequest): Promise<AthenaAuthResult<void>>
    list(): Promise<AthenaAuthResult<AthenaAuthLinkedAccount[]>>
    token(input: AthenaOAuthAccountTokenRequest): Promise<AthenaAuthResult<AthenaOAuthTokenBundle>>
  }
  
  refresh: {
    token(): Promise<AthenaAuthResult<{ token: string }>>
  }
}

TypedAthenaClient Interface

interface TypedAthenaClient<TRegistry extends RegistryConstraint, TTenantMap extends TenantKeyMap = Record<never, string>> extends AthenaSdkClient {
  readonly registry: TRegistry
  readonly tenantKeyMap: Readonly<TTenantMap>
  readonly tenantContext: TenantContext<TTenantMap>
  
  fromModel<TDatabase extends keyof TRegistry & string, TSchema extends keyof TRegistry[TDatabase]['schemas'] & string, TModel extends keyof TRegistry[TDatabase]['schemas'][TSchema]['models'] & string>(database: TDatabase, schema: TSchema, model: TModel): TableQueryBuilder<RowOf<ModelAt<TRegistry, TDatabase, TSchema, TModel>>>
  
  withTenantContext(context: TenantContext<TTenantMap>): TypedAthenaClient<TRegistry, TTenantMap>
}

Query Runtime Exports

## Query Runtime Exports

### Description
Core components and hooks for client-side querying with Athena.

### Available Exports
- `AthenaQueryClient`
- `createAthenaQueryClient`
- `attachStateAdapter`
- `AthenaQueryClientProvider`
- `useAthenaQueryClient`
- `useQuery`
- `useMutation`

CONTRIBUTING.md

Source: https://github.com/xylex-group/athena-js/blob/main/CONTRIBUTING.md

Development setup (1)

git clone https://github.com/xylex-group/athena-js
cd athena-js

npm install
npm run build

Project structure (2)

athena-js/
├── src/
│   ├── gateway/     # HTTP client, React hook, types
│   └── supabase.ts   # Athena query builder
├── docs/
└── test/

Validation checks (3)

pnpm typecheck
pnpm check:all

docs/api-reference.md

Source: https://github.com/xylex-group/athena-js/blob/main/docs/api-reference.md

Core result contract (1)

interface AthenaResult<T> {
  data: T | null
  error: string | null
  errorDetails?: AthenaGatewayErrorDetails | null
  status: number
  count?: number | null
  raw: unknown
}

createClient(url, apiKey, options?) (2)

function createClient(
  url: string,
  apiKey: string,
  options?: Pick<AthenaGatewayCallOptions, "client" | "headers" | "backend"> & {
    auth?: AthenaAuthClientConfig
  },
): AthenaSdkClientWithAuth

AthenaClient.builder() (3)

interface AthenaClientBuilder {
  url(url: string): AthenaClientBuilder
  key(apiKey: string): AthenaClientBuilder
  backend(backend: BackendConfig | BackendType): AthenaClientBuilder
  client(clientName: string): AthenaClientBuilder
  headers(headers: Record<string, string>): AthenaClientBuilder
  healthTracking(enabled: boolean): AthenaClientBuilder
  build(): AthenaSdkClientWithAuth
}

Backend constants (4)

const Backend = {
  Athena: { type: "athena" },
  Postgrest: { type: "postgrest" },
  PostgreSQL: { type: "postgresql" },
  ScyllaDB: { type: "scylladb" },
} as const;

Backend constants (5)

type BackendType = "athena" | "postgrest" | "postgresql" | "scylladb"

AthenaSdkClient (6)

interface AthenaSdkClient {
  from<Row = Record<string, AthenaJsonValue | undefined>, Insert = Partial<Row>, Update = Partial<Insert>>(
    table: string,
  ): TableQueryBuilder<Row, Insert, Update>

  rpc<Row = unknown, Args extends AthenaJsonObject = AthenaJsonObject>(
    fn: string,
    args?: Args,
    options?: AthenaRpcCallOptions,
  ): RpcQueryBuilder<Row>

  query<Row = unknown>(
    query: string,
    options?: AthenaGatewayCallOptions,
  ): Promise<AthenaResult<Row[]>>
}

interface AthenaSdkClientWithAuth extends AthenaSdkClient {
  auth: AthenaAuthBindings
}

TableQueryBuilder<Row, Insert, Update> (7)

interface TableQueryBuilder<Row, Insert = Partial<Row>, Update = Partial<Insert>> {
  select<T = Row>(columns?: string | string[], options?: AthenaGatewayCallOptions): SelectChain<Row, T>

  insert(values: Insert, options?: AthenaGatewayCallOptions): MutationQuery<Row>
  insert(values: Insert[], options?: AthenaGatewayCallOptions): MutationQuery<Row[]>

  upsert(
    values: Insert,
    options?: AthenaGatewayCallOptions & {
      updateBody?: Update
      onConflict?: string | string[]
    },
  ): MutationQuery<Row>

  upsert(
    values: Insert[],
    options?: AthenaGatewayCallOptions & {
      updateBody?: Update
      onConflict?: string | string[]
    },
  ): MutationQuery<Row[]>

  update(values: Update, options?: AthenaGatewayCallOptions): UpdateChain<Row>

  delete(options?: AthenaGatewayCallOptions & { resourceId?: string }): MutationQuery<Row | null>

  single<T = Row>(columns?: string | string[], options?: AthenaGatewayCallOptions): Promise<AthenaResult<T | null>>
  maybeSingle<T = Row>(columns?: string | string[], options?: AthenaGatewayCallOptions): Promise<AthenaResult<T | null>>

  reset(): TableQueryBuilder<Row, Insert, Update>
}

SelectChain<Row, SelectedRow = Row> (8)

interface SelectChain<Row, SelectedRow = Row>
  extends PromiseLike<AthenaResult<SelectedRow[]>> {
  single<T = SelectedRow>(
    columns?: string | string[],
    options?: AthenaGatewayCallOptions,
  ): Promise<AthenaResult<T | null>>

  maybeSingle<T = SelectedRow>(
    columns?: string | string[],
    options?: AthenaGatewayCallOptions,
  ): Promise<AthenaResult<T | null>>
}

MutationQuery<Result> (9)

interface MutationQuery<Result> extends PromiseLike<AthenaResult<Result>> {
  select(columns?: string | string[], options?: AthenaGatewayCallOptions): Promise<AthenaResult<Result>>
  returning(columns?: string | string[], options?: AthenaGatewayCallOptions): Promise<AthenaResult<Result>>

  single(
    columns?: string | string[],
    options?: AthenaGatewayCallOptions,
  ): Promise<AthenaResult<Result extends Array<infer Item> ? Item | null : Result | null>>

  maybeSingle(
    columns?: string | string[],
    options?: AthenaGatewayCallOptions,
  ): Promise<AthenaResult<Result extends Array<infer Item> ? Item | null : Result | null>>
}

UpdateChain<Row> (10)

interface UpdateChain<Row> extends MutationQuery<Row[]> {}

RpcQueryBuilder<Row> (11)

interface RpcQueryBuilder<Row> extends PromiseLike<AthenaResult<Row[]>> {
  eq(column: string, value: AthenaConditionValue): RpcQueryBuilder<Row>
  neq(column: string, value: AthenaConditionValue): RpcQueryBuilder<Row>
  gt(column: string, value: AthenaConditionValue): RpcQueryBuilder<Row>
  gte(column: string, value: AthenaConditionValue): RpcQueryBuilder<Row>
  lt(column: string, value: AthenaConditionValue): RpcQueryBuilder<Row>
  lte(column: string, value: AthenaConditionValue): RpcQueryBuilder<Row>
  like(column: string, value: AthenaConditionValue): RpcQueryBuilder<Row>
  ilike(column: string, value: AthenaConditionValue): RpcQueryBuilder<Row>
  is(column: string, value: AthenaConditionValue): RpcQueryBuilder<Row>
  in(column: string, values: AthenaConditionArrayValue): RpcQueryBuilder<Row>
  order(column: string, options?: { ascending?: boolean }): RpcQueryBuilder<Row>
  limit(count: number): RpcQueryBuilder<Row>
  offset(count: number): RpcQueryBuilder<Row>
  range(from: number, to: number): RpcQueryBuilder<Row>

  select(columns?: string | string[], options?: AthenaRpcCallOptions): Promise<AthenaResult<Row[]>>
  single<T = Row>(columns?: string | string[], options?: AthenaRpcCallOptions): Promise<AthenaResult<T | null>>
  maybeSingle<T = Row>(columns?: string | string[], options?: AthenaRpcCallOptions): Promise<AthenaResult<T | null>>
}

JSON-safe primitives (12)

type AthenaJsonPrimitive = string | number | boolean | null

type AthenaJsonValue = AthenaJsonPrimitive | AthenaJsonObject | AthenaJsonArray

interface AthenaJsonObject {
  [key: string]: AthenaJsonValue
}

type AthenaJsonArray = AthenaJsonValue[]

Condition primitives (13)

type AthenaConditionValue = AthenaJsonPrimitive
type AthenaConditionArrayValue = Array<AthenaConditionValue>
type AthenaConditionCastType = string

AthenaGatewayCallOptions (14)

interface AthenaGatewayCallOptions {
  baseUrl?: string
  apiKey?: string
  client?: string
  backend?: BackendConfig | BackendType
  publishEvent?: string
  headers?: Record<string, string>
  userId?: string | null
  organizationId?: string | null

  schema?: string
  count?: "exact" | "planned" | "estimated"
  head?: boolean
  defaultToNull?: boolean
  stripNulls?: boolean
  onConflict?: string | string[]
  updateBody?: AthenaJsonObject
}

AthenaRpcCallOptions (15)

interface AthenaRpcCallOptions extends AthenaGatewayCallOptions {
  count?: "exact" | "planned" | "estimated"
  get?: boolean
}

Fetch payload (16)

interface AthenaFetchPayload {
  view_name?: string
  table_name?: string
  columns?: string[] | string
  conditions?: AthenaGatewayCondition[]
  limit?: number
  offset?: number
  current_page?: number
  page_size?: number
  total_pages?: number
  strip_nulls?: boolean
  group_by?: string
  time_granularity?: "day" | "hour" | "minute"
  aggregation_column?: string
  aggregation_strategy?: "cumulative_sum"
  aggregation_dedup?: boolean
  sort_by?: AthenaSortBy
}

Insert payload (17)

interface AthenaInsertPayload<TInsertBody = AthenaJsonObject, TUpdateBody = AthenaJsonObject> {
  table_name: string
  insert_body: TInsertBody | TInsertBody[]
  update_body?: TUpdateBody
  columns?: string[] | string
  count?: "exact" | "planned" | "estimated"
  head?: boolean
  default_to_null?: boolean
  on_conflict?: string | string[]
}

Update payload (18)

interface AthenaUpdatePayload<TUpdateBody = AthenaJsonObject> extends AthenaFetchPayload {
  set?: TUpdateBody
  data?: TUpdateBody
}

Delete payload (19)

interface AthenaDeletePayload {
  table_name: string
  resource_id?: string
  columns?: string[] | string
  conditions?: AthenaGatewayCondition[]
  sort_by?: AthenaSortBy
  current_page?: number
  page_size?: number
  total_pages?: number
}

RPC payload (20)

interface AthenaRpcPayload<TArgs = AthenaJsonObject> {
  function: string
  function_name?: string
  schema?: string
  args?: TArgs
  select?: string
  filters?: AthenaRpcFilter[]
  count?: "exact" | "planned" | "estimated"
  head?: boolean
  limit?: number
  offset?: number
  order?: AthenaRpcOrder
}

Query payload (21)

interface AthenaQueryPayload {
  query: string
}

Gateway response/error contracts (22)

interface AthenaGatewayResponse<T = unknown> {
  ok: boolean
  status: number
  data: T | null
  count?: number | null
  error?: string
  errorDetails?: AthenaGatewayErrorDetails | null
  raw: unknown
}

type AthenaGatewayErrorCode =
  | "NETWORK_ERROR"
  | "HTTP_ERROR"
  | "INVALID_JSON"
  | "UNKNOWN_ERROR"

interface AthenaGatewayErrorDetails {
  code: AthenaGatewayErrorCode
  message: string
  status: number
  endpoint?: "/gateway/fetch" | "/gateway/insert" | "/gateway/update" | "/gateway/delete" | "/gateway/rpc" | "/gateway/query" | `/rpc/${string}`
  method?: "GET" | "POST" | "PUT" | "DELETE"
  requestId?: string
  hint?: string
  cause?: string
}

Error classification primitives (23)

type AthenaErrorKind = "unique_violation" | "not_found" | "validation" | "auth" | "rate_limit" | "transient" | "unknown"

type AthenaErrorCode =
  | "UNIQUE_VIOLATION"
  | "NOT_FOUND"
  | "VALIDATION_FAILED"
  | "AUTH_UNAUTHORIZED"
  | "AUTH_FORBIDDEN"
  | "RATE_LIMITED"
  | "NETWORK_UNAVAILABLE"
  | "TRANSIENT_FAILURE"
  | "HTTP_FAILURE"
  | "UNKNOWN"

type AthenaErrorCategory = "transport" | "client" | "server" | "database" | "unknown"

Model declarations (24)

function defineModel<Row, Insert = Partial<Row>, Update = Partial<Insert>, Meta extends ModelMetadata<Row> = ModelMetadata<Row>>(
  input: { meta: Meta },
): ModelDef<Row, Insert, Update, Meta>

function defineSchema<Models extends Record<string, AnyModelDef>>(models: Models): SchemaDef<Models>
function defineDatabase<Schemas extends Record<string, SchemaDef<Record<string, AnyModelDef>>>>(schemas: Schemas): DatabaseDef<Schemas>
function defineRegistry<Databases extends Record<string, DatabaseDef<Record<string, SchemaDef<Record<string, AnyModelDef>>>>>>(databases: Databases): RegistryDef<Databases>

Typed client (25)

interface TypedClientOptions<TMap extends TenantKeyMap = TenantKeyMap>
  extends Pick<AthenaGatewayCallOptions, "backend" | "client" | "headers"> {
  tenantKeyMap?: TMap
  tenantContext?: TenantContext<TMap>
}

interface TypedAthenaClient<TRegistry, TTenantMap> extends AthenaSdkClient {
  readonly registry: TRegistry
  readonly tenantKeyMap: Readonly<TTenantMap>
  readonly tenantContext: TenantContext<TTenantMap>

  withTenantContext(context: TenantContext<TTenantMap>): TypedAthenaClient<TRegistry, TTenantMap>

  fromModel<
    TDatabase extends keyof TRegistry & string,
    TSchema extends keyof TRegistry[TDatabase]["schemas"] & string,
    TModel extends keyof TRegistry[TDatabase]["schemas"][TSchema]["models"] & string,
  >(
    database: TDatabase,
    schema: TSchema,
    model: TModel,
  ): TableQueryBuilder<
    RowOf<ModelAt<TRegistry, TDatabase, TSchema, TModel>>,
    InsertOf<ModelAt<TRegistry, TDatabase, TSchema, TModel>>,
    UpdateOf<ModelAt<TRegistry, TDatabase, TSchema, TModel>>
  >
}

function createTypedClient(registry, url, apiKey, options?): TypedAthenaClient

Generator API (26)

interface AthenaGeneratorConfig {
  provider: GeneratorProviderConfig
  output: GeneratorOutputConfig
  naming?: Partial<GeneratorNamingConfig>
  features?: Partial<GeneratorFeatureFlags>
  experimental?: Partial<GeneratorExperimentalFlags>
}

Gateway hook (27)

useAthenaGateway(config?: AthenaGatewayHookConfig): AthenaGatewayHookResult

Validation commands (28)

pnpm typecheck
pnpm check:all

Command line usage (29)

athena-js generate --dry-run

docs/auth-client-bindings.md

Source: https://github.com/xylex-group/athena-js/blob/main/docs/auth-client-bindings.md

Athena Auth Client Bindings (1)

type AthenaAuthResult<T> = {
  ok: boolean
  status: number
  data: T | null
  error: string | null
  errorDetails?: AthenaAuthErrorDetails | null
  raw: unknown
}

Client setup (2)

import { createClient } from "@xylex-group/athena"

const client = createClient("http://localhost:3001", "gateway_api_key", {
  auth: { baseUrl: "http://localhost:3001/api/auth" },
})

React useSession parity (3)

import { useSession } from "@xylex-group/athena/react"
import { createClient } from "@xylex-group/athena"

const client = createClient("http://localhost:3001", "gateway_api_key", {
  auth: { baseUrl: "http://localhost:3001/api/auth" },
})

function SessionPanel() {
  const { data, isPending, isRefetching, error, refetch } = useSession(client)
  return null
}

docs/auth/admin.mdx

Source: https://github.com/xylex-group/athena-js/blob/main/docs/auth/admin.mdx

Examples (1)

import { client } from "./auth-client"

await client.auth.admin.role.set({
  userId: "usr_1",
  role: "admin",
})

await client.auth.admin.user.list()
await client.auth.admin.user.session.list({ userId: "usr_1" })

await client.auth.admin.user.create({
  email: "new-user@example.com",
  password: "temporary-password",
})

await client.auth.admin.user.unban({ userId: "usr_1" })
await client.auth.admin.user.ban({ userId: "usr_2", banReason: "policy violation" })

await client.auth.admin.user.impersonate({ userId: "usr_3" })
await client.auth.admin.user.stopImpersonating({ userId: "usr_3" })

// single payload -> /admin/revoke-user-session
await client.auth.admin.user.session.revoke({
  userId: "usr_3",
  sessionToken: "sess_token_1",
})

// multiple payloads -> /admin/revoke-user-sessions
await client.auth.admin.user.session.revoke([
  { userId: "usr_3", sessionToken: "sess_token_2" },
  { userId: "usr_3", sessionToken: "sess_token_3" },
])

// direct plural payload -> /admin/revoke-user-sessions
await client.auth.admin.user.session.revoke({
  userId: "usr_3",
})

await client.auth.admin.user.remove({ userId: "usr_4" })
await client.auth.admin.user.setPassword({
  userId: "usr_4",
  newPassword: "new-password",
})

await client.auth.admin.hasPermission({
  permissions: { users: ["manage"] },
})

await client.auth.admin.apiKey.create({
  name: "admin-key",
  expiresIn: 3600,
})

await client.auth.admin.athenaClient.create({
  clientName: "dashboard-client",
})
await client.auth.admin.athenaClient.list()

await client.auth.admin.auditLog.list()

await client.auth.admin.email.get({
  query: { id: "email_1" },
})

await client.auth.admin.email.create({
  recipientEmail: "to@example.com",
  subject: "Welcome",
  fromAddress: "no-reply@example.com",
  provider: "resend",
})

await client.auth.admin.email.update({
  id: "email_1",
  subject: "Welcome Updated",
})

await client.auth.admin.email.delete({
  id: "email_1",
})

await client.auth.admin.email.failure.list()
await client.auth.admin.email.failure.get({
  query: { id: "failure_1" },
})
await client.auth.admin.email.failure.create({
  recipientEmail: "to@example.com",
  flow: "transactional",
  errorMessage: "bounce",
})
await client.auth.admin.email.failure.update({
  id: "failure_1",
  resolved: true,
})
await client.auth.admin.email.failure.delete({
  id: "failure_1",
})

await client.auth.admin.email.list()

await client.auth.admin.email.template.create({
  templateKey: "welcome",
  subjectTemplate: "Welcome",
})
await client.auth.admin.email.template.get({
  query: { id: "tmpl_1" },
})
await client.auth.admin.email.template.list()
await client.auth.admin.email.template.update({
  id: "tmpl_1",
  subjectTemplate: "Welcome Updated",
})
await client.auth.admin.email.template.delete({ id: "tmpl_1" })

// legacy alias
await client.auth.admin.emailTemplate.create({
  templateKey: "legacy",
  subjectTemplate: "Legacy",
})
await client.auth.admin.emailTemplate.get({
  query: { id: "legacy_tmpl_1" },
})
await client.auth.admin.emailTemplate.list()
await client.auth.admin.emailTemplate.update({
  id: "legacy_tmpl_1",
  subjectTemplate: "Legacy Updated",
})
await client.auth.admin.emailTemplate.delete({ id: "legacy_tmpl_1" })

docs/auth/api-key.mdx

Source: https://github.com/xylex-group/athena-js/blob/main/docs/auth/api-key.mdx

Examples (1)

import { client } from "./auth-client"

await client.auth.apiKey.create({
  name: "mobile-client-key",
  expiresIn: "3600",
  remaining: "1000",
})

await client.auth.apiKey.get({
  query: { id: "api_key_id" },
})

await client.auth.apiKey.update({
  keyId: "api_key_id",
  name: "mobile-client-key-updated",
  expiresIn: "3600",
  permissions: "{}",
})

await client.auth.apiKey.delete({ keyId: "api_key_id" })

await client.auth.apiKey.list()

await client.auth.apiKey.verify({
  key: "prefix.secret",
})

await client.auth.apiKey.deleteAllExpired()

docs/auth/callback.mdx

Source: https://github.com/xylex-group/athena-js/blob/main/docs/auth/callback.mdx

Example (1)

import { client } from "./auth-client"

await client.auth.callback.provider({
  provider: "github",
  code: "oauth_authorization_code",
  state: "oauth_state_value",
})

docs/auth/index.mdx

Source: https://github.com/xylex-group/athena-js/blob/main/docs/auth/index.mdx

Base setup (1)

import { createClient } from "@xylex-group/athena"

export const client = createClient("http://localhost:3001", "gateway_api_key", {
  auth: { baseUrl: "http://localhost:3001/api/auth" },
})

docs/auth/organization-invitations.mdx

Source: https://github.com/xylex-group/athena-js/blob/main/docs/auth/organization-invitations.mdx

Examples (1)

import { client } from "./auth-client"

await client.auth.organization.invitation.cancel({
  invitationId: "inv_1",
})

await client.auth.organization.invitation.accept({
  invitationId: "inv_1",
})

await client.auth.organization.invitation.get({
  query: { id: "inv_1" },
})

await client.auth.organization.invitation.reject({
  invitationId: "inv_1",
})

await client.auth.organization.invitation.list({
  query: { organizationId: "org_1" },
})

docs/auth/organization-members.mdx

Source: https://github.com/xylex-group/athena-js/blob/main/docs/auth/organization-members.mdx

Examples (1)

import { client } from "./auth-client"

await client.auth.organization.member.remove({
  memberIdOrEmail: "member@example.com",
})

await client.auth.organization.member.updateRole({
  memberId: "member_1",
  role: "admin",
})

await client.auth.organization.member.invite({
  email: "new-member@example.com",
  role: "member",
})

await client.auth.organization.member.getActive()

await client.auth.organization.member.list({
  query: {
    organizationId: "org_1",
    limit: 50,
    sortBy: "createdAt",
    sortDirection: "desc",
  },
})

docs/auth/organization.mdx

Source: https://github.com/xylex-group/athena-js/blob/main/docs/auth/organization.mdx

Examples (1)

import { client } from "./auth-client"

await client.auth.organization.create({
  name: "Acme",
  slug: "acme",
})

await client.auth.organization.update({
  organizationId: "org_1",
  data: { name: "Acme Updated" },
})

await client.auth.organization.delete({
  organizationId: "org_1",
})

await client.auth.organization.setActive({
  organizationId: "org_1",
})

await client.auth.organization.list()

await client.auth.organization.getFull({
  query: { organizationId: "org_1" },
})

await client.auth.organization.checkSlug({
  slug: "acme",
})

await client.auth.organization.leave({
  organizationId: "org_1",
})

await client.auth.organization.listUserInvitations()

await client.auth.organization.hasPermission({
  permissions: { project: ["create"] },
})

docs/auth/passkey.mdx

Source: https://github.com/xylex-group/athena-js/blob/main/docs/auth/passkey.mdx

Examples (1)

import { client } from "./auth-client"

await client.auth.passkey.generateRegisterOptions()
await client.auth.passkey.generateAuthenticateOptions()

await client.auth.passkey.verifyRegistration({
  response: "webauthn-registration-response",
})

await client.auth.passkey.verifyAuthentication({
  response: "webauthn-authentication-response",
})

await client.auth.passkey.listUserPasskeys()

await client.auth.passkey.deletePasskey({ id: "passkey_id" })
await client.auth.passkey.updatePasskey({
  id: "passkey_id",
  name: "My Laptop Passkey",
})

await client.auth.passkey.getRelatedOrigins()

docs/auth/session.mdx

Source: https://github.com/xylex-group/athena-js/blob/main/docs/auth/session.mdx

Examples (1)

import { client } from "./auth-client"

const session = await client.auth.getSession()
const signOut = await client.auth.signOut()

const sessions = await client.auth.session.list()

// single -> /revoke-session
await client.auth.session.revoke({ token: "session_token_1" })

// array length 1 -> /revoke-session
await client.auth.session.revoke([{ token: "session_token_2" }])

// array length > 1 -> /revoke-sessions
await client.auth.session.revoke([
  { token: "session_token_3" },
  { token: "session_token_4" },
])

// tokens list length > 1 -> /revoke-sessions
await client.auth.session.revoke({ tokens: ["session_token_5", "session_token_6"] })

const revokeOther = await client.auth.session.revokeOther()

docs/auth/sign-in-up.mdx

Source: https://github.com/xylex-group/athena-js/blob/main/docs/auth/sign-in-up.mdx

Examples (1)

import { client } from "./auth-client"

await client.auth.signIn.social({
  provider: "google",
  callbackURL: "https://app.example.com/auth/callback",
})

await client.auth.signIn.email({
  email: "user@example.com",
  password: "password",
  rememberMe: true,
})

await client.auth.signIn.username({
  username: "user1",
  password: "password",
  rememberMe: true,
})

await client.auth.signUp.email({
  name: "New User",
  email: "new-user@example.com",
  password: "password",
  callbackURL: "https://app.example.com/onboarding",
})

docs/auth/social-account.mdx

Source: https://github.com/xylex-group/athena-js/blob/main/docs/auth/social-account.mdx

Examples (1)

import { client } from "./auth-client"

await client.auth.social.link({
  provider: "google",
  callbackURL: "https://app.example.com/auth/callback",
})

await client.auth.account.list()

await client.auth.account.unlink({
  providerId: "google",
  accountId: "acc_123",
})

await client.auth.deleteUser.callback({
  token: "delete_callback_token",
  callbackURL: "https://app.example.com/delete-callback",
})

await client.auth.refreshToken({
  providerId: "google",
  accountId: "acc_123",
  userId: "usr_123",
})

await client.auth.getAccessToken({
  providerId: "google",
  accountId: "acc_123",
  userId: "usr_123",
})

await client.auth.health()
await client.auth.ok()
await client.auth.error()

docs/auth/two-factor.mdx

Source: https://github.com/xylex-group/athena-js/blob/main/docs/auth/two-factor.mdx

Examples (1)

import { client } from "./auth-client"

await client.auth.twoFactor.getTotpUri({ password: "current-password" })
await client.auth.twoFactor.verifyTotp({ code: "123456" })

await client.auth.twoFactor.sendOtp()
await client.auth.twoFactor.verifyOtp({ code: "123456" })

await client.auth.twoFactor.verifyBackupCode({ code: "backup-code-value" })
await client.auth.twoFactor.generateBackupCodes({
  password: "current-password",
})

await client.auth.twoFactor.enable({ password: "current-password" })
await client.auth.twoFactor.disable({ password: "current-password" })

docs/auth/use-session.mdx

Source: https://github.com/xylex-group/athena-js/blob/main/docs/auth/use-session.mdx

Hook API (1)

import { useSession } from "@xylex-group/athena/react"
import { createClient } from "@xylex-group/athena"

const client = createClient("http://localhost:3001", "gateway_api_key", {
  auth: { baseUrl: "http://localhost:3001/api/auth" },
})

const session = useSession(client, {
  enabled: true,
  refetchOnMount: true,
  fetchInput: undefined,
  callOptions: undefined,
})

Example component (2)

import { createClient } from "@xylex-group/athena"
import { useSession } from "@xylex-group/athena/react"

const client = createClient("http://localhost:3001", "gateway_api_key", {
  auth: { baseUrl: "http://localhost:3001/api/auth" },
})

export function SessionPanel() {
  const { data, error, isPending, isRefetching, refetch } = useSession(client)

  if (isPending) return <div>Loading session...</div>
  if (error) return <div>Session error: {error.message}</div>

  return (
    <div>
      <div>User: {data?.user.email ?? "none"}</div>
      <button disabled={isRefetching} onClick={() => void refetch()}>
        {isRefetching ? "Refreshing..." : "Refetch session"}
      </button>
    </div>
  )
}

docs/auth/user.mdx

Source: https://github.com/xylex-group/athena-js/blob/main/docs/auth/user.mdx

Examples (1)

import { client } from "./auth-client"

await client.auth.forgetPassword({
  email: "user@example.com",
  redirectTo: "https://app.example.com/reset-password",
})

await client.auth.resetPassword({
  newPassword: "new-strong-password",
  token: "reset_token",
})

await client.auth.resetPassword.token({
  token: "reset_token",
  callbackURL: "https://app.example.com/reset-password",
})

await client.auth.setPassword({ newPassword: "new-strong-password" })

await client.auth.verifyEmail({
  token: "verify_token",
  callbackURL: "https://app.example.com/verified",
})

await client.auth.sendVerificationEmail({
  email: "user@example.com",
  callbackURL: "https://app.example.com/verify",
})

await client.auth.changeEmail({
  newEmail: "new-user@example.com",
  callbackURL: "https://app.example.com/change-email",
})

await client.auth.changeEmailVerify({
  query: { token: "change_email_token" },
})

await client.auth.deleteUserVerify({
  query: { token: "delete_user_token" },
})

await client.auth.changePassword({
  currentPassword: "old-password",
  newPassword: "new-password",
  revokeOtherSessions: true,
})

await client.auth.user.update({
  name: "Updated Name",
  image: "https://cdn.example.com/avatar.png",
})

await client.auth.user.delete({
  password: "current-password",
})

await client.auth.user.email.list()

docs/cli-command-reference.md

Source: https://github.com/xylex-group/athena-js/blob/main/docs/cli-command-reference.md

Root commands (1)

athena-js
athena-js --help
athena-js -h
athena-js help
athena-js help generate

Generate command (2)

athena-js generate
athena-js generate --dry-run
athena-js generate --config ./athena.config.ts
athena-js generate --config ./athena.config.ts --dry-run
athena-js generate --help

Local vs global execution (3)

pnpm exec athena-js generate --dry-run

Local vs global execution (4)

pnpm add -g @xylex-group/athena

Windows global shim troubleshooting (5)

Get-Command athena-js | Format-List Source,Definition

Windows global shim troubleshooting (6)

pnpm remove -g @xylex-group/athena
pnpm add -g @xylex-group/athena

Windows global shim troubleshooting (7)

athena-js --help
athena-js generate --help

ERR_MODULE_NOT_FOUND for dist/cli/index.js (8)

Cannot find module .../@xylex-group/athena/dist/cli/index.js

Postgres 3D000 (database "<name>" does not exist) (9)

PostgreSQL database "app_db" does not exist (code 3D000).

Debugging mode (10)

$env:ATHENA_JS_DEBUG="1"
athena-js generate --config ./athena.config.ts --dry-run

docs/generator-cicd.md

Source: https://github.com/xylex-group/athena-js/blob/main/docs/generator-cicd.md

Athena JS Generator CI/CD Guide (1)

athena-js generate [--config <path>] [--dry-run]

Pipeline pattern 1: direct pg_url introspection (2)

export default {
  provider: {
    kind: "postgres",
    mode: "direct",
    connectionString: process.env.PG_URL!,
    database: "app_db",
    schemas: ["public", "athena"],
  },
  output: {
    targets: {
      model: "athena/models/{schema_kebab}/{model_kebab}.ts",
      schema: "athena/schemas/{schema_kebab}.ts",
      database: "athena/relations.ts",
      registry: "athena/config.ts",
    },
    placeholderMap: {},
  },
};

Pipeline pattern 1: direct pg_url introspection (3)

name: generator-direct
on:
  pull_request:
    branches: [main]

jobs:
  generate:
    runs-on: ubuntu-latest
    timeout-minutes: 15
    steps:
      - uses: actions/checkout@v4
      - uses: pnpm/action-setup@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - run: pnpm install --frozen-lockfile

      # dry-run verification (no files written)
      - name: Verify generator (dry-run)
        env:
          PG_URL: ${{ secrets.GENERATOR_PG_URL }}
        run: pnpm exec athena-js generate --config ./athena.config.ts --dry-run

      # optional write + diff gate for PRs that include generated artifacts
      - name: Enforce generated artifacts are committed
        env:
          PG_URL: ${{ secrets.GENERATOR_PG_URL }}
        run: |
          pnpm exec athena-js generate --config ./athena.config.ts
          git diff --exit-code

Pipeline pattern 2: gateway-only introspection via Athena /gateway/query (4)

export default {
  provider: {
    kind: "postgres",
    mode: "gateway",
    gatewayUrl: process.env.ATHENA_URL!,
    apiKey: process.env.ATHENA_API_KEY!,
    database: "app_db",
    schemas: ["public", "athena"],
    backend: "postgresql",
  },
  output: {
    targets: {
      model: "athena/models/{schema_kebab}/{model_kebab}.ts",
      schema: "athena/schemas/{schema_kebab}.ts",
      database: "athena/relations.ts",
      registry: "athena/config.ts",
    },
    placeholderMap: {},
  },
};

Pipeline pattern 2: gateway-only introspection via Athena /gateway/query (5)

name: generator-gateway
on:
  pull_request:
    branches: [main]

jobs:
  generate:
    runs-on: ubuntu-latest
    timeout-minutes: 15
    steps:
      - uses: actions/checkout@v4
      - uses: pnpm/action-setup@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - run: pnpm install --frozen-lockfile

      # dry-run verification (no files written)
      - name: Verify generator (dry-run)
        env:
          ATHENA_URL: ${{ secrets.ATHENA_GENERATOR_URL }}
          ATHENA_API_KEY: ${{ secrets.ATHENA_GENERATOR_API_KEY }}
        run: pnpm exec athena-js generate --config ./athena.config.ts --dry-run

      # optional write + diff gate for PRs that include generated artifacts
      - name: Enforce generated artifacts are committed
        env:
          ATHENA_URL: ${{ secrets.ATHENA_GENERATOR_URL }}
          ATHENA_API_KEY: ${{ secrets.ATHENA_GENERATOR_API_KEY }}
        run: |
          pnpm exec athena-js generate --config ./athena.config.ts
          git diff --exit-code

Dry-run verification strategy (6)

pnpm exec athena-js generate --config ./athena.config.ts --dry-run

Artifact diff strategy for PR checks (7)

pnpm exec athena-js generate --config ./athena.config.ts
git diff --exit-code

Failure handling and retry guidance (8)

#!/usr/bin/env bash
set -euo pipefail

for attempt in 1 2 3; do
  if pnpm exec athena-js generate --config ./athena.config.ts --dry-run; then
    exit 0
  fi

  # deterministic failures should fail immediately
  if [[ $attempt -eq 1 ]]; then
    # If your CI captures stderr, pattern-match known deterministic messages here.
    # Keep this conservative to avoid masking real config problems.
    :
  fi

  if [[ $attempt -lt 3 ]]; then
    sleep $((attempt * 5))
  fi
done

exit 1

docs/generator-codex-handoff-prompt-pack.md

Source: https://github.com/xylex-group/athena-js/blob/main/docs/generator-codex-handoff-prompt-pack.md

1) Prompt: Canonical Handoff (1)

You are documenting the Athena JS typed schema generator. Treat this as a production docs task.

Goals:
1. Keep docs accurate with current implementation.
2. Explain both PostgreSQL introspection modes:
   - direct pg_url (`provider.mode = "direct"`)
   - gateway-only query path (`provider.mode = "gateway"`, using Athena `/gateway/query`)
3. Preserve backward compatibility messaging for existing createClient/from<T> users.
4. Document naming, placeholders, feature flags, and edge cases.
5. Include migration and troubleshooting sections.
6. Keep all examples runnable and consistent with current exports.

Current implementation facts (must reflect):
- Generator config discovery supports:
  athena.config.ts/js, athena-js.config.ts/js, .athena.config.ts/js
- CLI command is:
  athena-js generate [--config <path>] [--dry-run]
- Direct mode uses pg connection string and catalog introspection.
- Gateway mode introspects by executing SQL catalog queries through Athena query endpoint.
- Output artifacts are model/schema/database/registry.
- Output registry emission can be disabled with features.emitRegistry=false.
- Relation metadata emission can be disabled with features.emitRelations=false.
- Postgres type mapping handles numeric/text/boolean/binary/uuid/json/jsonb/temporal/network/geometric/bit/xml/full-text/enum/domain/range/multirange/composite/arrays.
- Unsafe/reserved identifiers are emitted safely in generated TS property keys.

Deliverables:
- Update docs/generator-config.md as the primary reference.
- Add or update a quickstart section in README linking to generator docs.
- Add a troubleshooting section with concrete failure patterns and fixes.
- Add a migration section for teams moving from manual model typing to generated registry files.
- Add a "CI usage" section with direct and gateway-only examples.
- Keep wording explicit, concise, and implementation-accurate.

Validation requirements:
- No contradictions with actual config keys or exported APIs.
- Every code snippet should be self-consistent.
- Mention known limitations clearly (Scylla contract placeholder, custom SQL deferred).

2) Prompt: Troubleshooting-Focused Expansion (2)

Expand Athena JS generator troubleshooting docs only.

Required sections:
1. Config discovery failures (file name and location mismatch)
2. Gateway auth/header/backend mismatches
3. Empty snapshot / missing schema results
4. Duplicate output path collisions from placeholder templates
5. Unsafe identifier rendering expectations
6. Type mapping surprises (e.g. bigint as string)

For each section include:
- Symptom
- Likely cause
- How to confirm
- Exact fix

Keep examples aligned with:
- provider.mode direct (pg_url)
- provider.mode gateway (Athena /gateway/query)

3) Prompt: CI/Automation-Focused Expansion (3)

Write CI/CD documentation for Athena JS generator.

Requirements:
- Include two pipeline patterns:
  1) direct pg_url introspection
  2) gateway-only introspection via Athena query endpoint
- Include secure secret mapping examples.
- Include dry-run verification step.
- Include artifact diff strategy for PR checks.
- Include failure handling strategy and retry guidance.
- Include branch policy advice for generated files.

Keep it implementation-accurate and avoid introducing non-existent CLI flags.

docs/generator-config.md

Source: https://github.com/xylex-group/athena-js/blob/main/docs/generator-config.md

CLI entrypoint (1)

athena-js generate
athena-js generate --dry-run
athena-js generate --config ./athena.config.ts
athena-js generate --help
athena-js help generate

Config surface at a glance (2)

export interface AthenaGeneratorConfig {
  provider: GeneratorProviderConfig
  output: GeneratorOutputConfig
  naming?: Partial<GeneratorNamingConfig>
  features?: Partial<GeneratorFeatureFlags>
  experimental?: Partial<GeneratorExperimentalFlags>
}

defineGeneratorConfig helper (3)

import { defineGeneratorConfig } from "@xylex-group/athena";

export default defineGeneratorConfig({
  provider: {
    kind: "postgres",
    mode: "direct",
    connectionString: process.env.DATABASE_URL!,
    database: "app_db",
    schemas: (process.env.ATHENA_GENERATOR_SCHEMAS ?? "public,athena").split(","),
  },
  output: {
    targets: {
      model: "athena/models/{schema_kebab}/{model_kebab}.ts",
      schema: "athena/schemas/{schema_kebab}.ts",
      database: "athena/relations.ts",
      registry: "athena/config.ts",
    },
  },
});

Postgres direct mode (4)

{
  kind: "postgres",
  mode: "direct",
  connectionString: "postgres://user:pass@host:5432/db",
  database: "app_db",
  schemas: ["public", "athena"],
}

Postgres gateway mode (5)

{
  kind: "postgres",
  mode: "gateway",
  gatewayUrl: "https://athena.example.com",
  apiKey: process.env.ATHENA_API_KEY!,
  database: "app_db",
  schemas: ["public", "athena"],
  backend: "athena",
}

Scylla mode (contract placeholder) (6)

{
  kind: "scylla",
  mode: "direct",
  contactPoints: ["127.0.0.1:9042"],
  keyspace: "app",
  datacenter: "eu-west-1",
}

Output contract (7)

interface GeneratorOutputConfig {
  targets: GeneratorOutputTargets;
  placeholderMap: Record<string, string>;
}

interface GeneratorOutputTargets {
  model: string;
  schema: string;
  database: string;
  registry: string;
}

Schema selection (8)

schemas: ["public", "athena"]
// or
schemas: process.env.ATHENA_GENERATOR_SCHEMAS ?? "public,athena"

placeholderMap (9)

output: {
  targets: {
    model: "src/{namespace}/{schema_snake}/{model_snake}.ts",
  },
  placeholderMap: {
    namespace: "{database_kebab}/{schema_kebab}",
  },
}

Naming controls (10)

interface GeneratorNamingConfig {
  modelType: "preserve" | "camel" | "pascal" | "snake" | "kebab";
  modelConst: "preserve" | "camel" | "pascal" | "snake" | "kebab";
  schemaConst: "preserve" | "camel" | "pascal" | "snake" | "kebab";
  databaseConst: "preserve" | "camel" | "pascal" | "snake" | "kebab";
  registryConst: "preserve" | "camel" | "pascal" | "snake" | "kebab";
}

Feature flags (11)

interface GeneratorFeatureFlags {
  emitRelations: boolean;
  emitRegistry: boolean;
}

Feature flags (12)

features: {
  emitRegistry: false,
},

Experimental flags (13)

interface GeneratorExperimentalFlags {
  postgresGatewayIntrospection: boolean;
  scyllaProviderContracts: boolean;
}

Local development (direct DB) (14)

import { defineGeneratorConfig } from "@xylex-group/athena";

export default defineGeneratorConfig({
  provider: {
    kind: "postgres",
    mode: "direct",
    connectionString: process.env.DATABASE_URL!,
    database: "app_db",
    schemas: ["public", "athena"],
  },
  output: {
    targets: {
      model: "athena/models/{schema_kebab}/{model_kebab}.ts",
      schema: "athena/schemas/{schema_kebab}.ts",
      database: "athena/relations.ts",
      registry: "src/generated/registry.ts",
    },
    placeholderMap: {
      namespace: "{database_kebab}/{schema_kebab}",
    },
  },
  naming: {
    modelType: "pascal",
    modelConst: "camel",
    schemaConst: "snake",
  },
});

Gateway-only environment (15)

export default {
  provider: {
    kind: "postgres",
    mode: "gateway",
    gatewayUrl: process.env.ATHENA_URL!,
    apiKey: process.env.ATHENA_API_KEY!,
    database: "app_db",
    schemas: ["public", "athena"],
    backend: "athena",
  },
  output: {
    targets: {
      model: "athena/models/{schema_kebab}/{model_kebab}.ts",
      schema: "athena/schemas/{schema_kebab}.ts",
      database: "athena/relations.ts",
      registry: "athena/config.ts",
    },
    placeholderMap: {},
  },
};

Pipeline integration tips (16)

athena-js generate --config ./athena.config.ts --dry-run

docs/getting-started.md

Source: https://github.com/xylex-group/athena-js/blob/main/docs/getting-started.md

2) Install (1)

pnpm add @xylex-group/athena

createClient (fastest) (2)

import { createClient } from "@xylex-group/athena";

const athena = createClient(process.env.ATHENA_URL!, process.env.ATHENA_API_KEY!, {
  client: "web-dashboard",
  backend: { type: "athena" },
});

AthenaClient.builder() (explicit configuration) (3)

import { AthenaClient, Backend } from "@xylex-group/athena";

const athena = AthenaClient.builder()
  .url(process.env.ATHENA_URL!)
  .key(process.env.ATHENA_API_KEY!)
  .backend(Backend.Athena)
  .client("web-dashboard")
  .headers({ "X-App-Region": "eu" })
  .build();

AthenaClient.fromEnvironment() (ops-friendly) (4)

import { AthenaClient } from "@xylex-group/athena";

const athena = AthenaClient.fromEnvironment();

4) Read data with table builders (5)

type UserRow = {
  id: string;
  email: string;
  active: boolean;
  created_at: string;
};

const result = await athena
  .from<UserRow>("users")
  .select("id, email, active")
  .eq("active", true)
  .order("created_at", { ascending: false })
  .limit(25);

Important chain behavior (6)

const one = await athena.from<UserRow>("users").eq("id", "u-1").single("id, email");

5) Filter, paging, and schema-qualified calls (7)

const page = await athena
  .from<UserRow>("users")
  .select("id, email")
  .currentPage(2)
  .pageSize(50)
  .order("created_at", { ascending: false });

const usersInPublic = await athena
  .from<UserRow>("users")
  .select("id, email", { schema: "public" });

Insert (8)

await athena
  .from<{ id: string; email: string }, { email: string }>("users")
  .insert({ email: "user@example.com" })
  .select("id, email");

Update (9)

await athena
  .from<{ id: string; email: string }, { email: string }, { email?: string }>("users")
  .eq("id", "u-1")
  .update({ email: "new@example.com" })
  .select("id, email");

Upsert (10)

await athena
  .from<{ id: string; email: string }, { id: string; email: string }, { email?: string }>("users")
  .upsert(
    { id: "u-1", email: "user@example.com" },
    {
      onConflict: "id",
      updateBody: { email: "user@example.com" },
    },
  )
  .select("id, email");

RPC (11)

const rpcResult = await athena
  .rpc<{ count: number }, { active_only: boolean }>("list_users", { active_only: true })
  .single("count");

Raw query (12)

const rows = await athena.query<{ id: string; email: string }>(
  "select id, email from users where active = true",
);

8) Handle responses safely (13)

import { isOk, unwrapRows, unwrapOne, requireAffected } from "@xylex-group/athena";

const list = await athena.from<{ id: string }>("users").select("id");
if (!isOk(list)) throw new Error(list.error ?? "Unknown error");
const rows = unwrapRows(list);

const single = await athena.from<{ id: string }>("users").eq("id", "u-1").single("id");
const user = unwrapOne(single, { allowNull: true });

const inserted = await athena.from<{ id: string }, { email: string }>("users").insert({ email: "a@b.com" });
requireAffected(inserted, { min: 1 });

9) Move to typed model registry (14)

import {
  createTypedClient,
  defineDatabase,
  defineModel,
  defineRegistry,
  defineSchema,
} from "@xylex-group/athena";

const users = defineModel<
  { id: string; email: string; created_at: string | null },
  { email: string },
  { email?: string }
>({
  meta: {
    primaryKey: ["id"],
    nullable: { id: false, email: false, created_at: true },
  },
});

const registry = defineRegistry({
  app: defineDatabase({
    public: defineSchema({ users }),
  }),
});

const typed = createTypedClient(registry, process.env.ATHENA_URL!, process.env.ATHENA_API_KEY!);

await typed
  .fromModel("app", "public", "users")
  .select("id, email")
  .eq("email", "user@example.com");

10) Tenant header propagation (15)

const scopedClient = createTypedClient(registry, process.env.ATHENA_URL!, process.env.ATHENA_API_KEY!, {
  tenantKeyMap: {
    organizationId: "X-Organization-Id",
    workspaceId: "X-Workspace-Id",
  },
});

const tenantBound = scopedClient.withTenantContext({ organizationId: "org-1", workspaceId: "ws-4" });

await tenantBound.fromModel("app", "public", "users").select("id, email");

11) Form contracts with Zod and React Hook Form (16)

import { z } from "zod";
import type { InsertOf, UpdateOf } from "@xylex-group/athena";

const userCreateSchema = z.object({
  email: z.string().email(),
  active: z.boolean().default(true),
});

type UserModel = typeof registry.app.schemas.public.models.users;
type UserInsert = InsertOf<UserModel>;
type UserUpdate = UpdateOf<UserModel>;

function toInsert(input: unknown): UserInsert {
  return userCreateSchema.parse(input);
}

function toUpdate(input: unknown): UserUpdate {
  return userCreateSchema.partial().parse(input);
}

12) Generate registry code from PostgreSQL (17)

athena-js generate
athena-js generate --dry-run
athena-js generate --config ./athena.config.ts
athena-js generate --help

12) Generate registry code from PostgreSQL (18)

import { defineGeneratorConfig } from "@xylex-group/athena";

export default defineGeneratorConfig({
  provider: {
    kind: "postgres",
    mode: "direct",
    connectionString: process.env.DATABASE_URL!,
    database: "app_db",
    schemas: ["public", "athena"],
  },
  output: {
    targets: {
      model: "athena/models/{schema_kebab}/{model_kebab}.ts",
      schema: "athena/schemas/{schema_kebab}.ts",
      database: "athena/relations.ts",
      registry: "athena/config.ts",
    },
  },
});

13) Production checklist (19)

provider: {
  kind: "postgres",
  mode: "gateway",
  gatewayUrl: process.env.ATHENA_URL!,
  apiKey: process.env.ATHENA_API_KEY!,
  database: "app_db",
  schemas: ["public", "athena"],
}

docs/index.md

Source: https://github.com/xylex-group/athena-js/blob/main/docs/index.md

Concept map (1)

Runtime client (createClient / AthenaClient.builder)
  -> Optional typed client (createTypedClient)
    -> Registry contracts (defineModel / defineSchema / defineDatabase / defineRegistry)
      -> Optional generator pipeline (athena-js generate)
        -> Generated model/schema/database/registry files
          -> Runtime query builders + app/domain form surfaces

docs/type-safety-playbook.md

Source: https://github.com/xylex-group/athena-js/blob/main/docs/type-safety-playbook.md

3) Tri-generic model pattern (1)

const invoices = defineModel<
  {
    id: string;
    organization_id: string;
    amount_cents: number;
    status: "draft" | "sent" | "paid";
    due_at: string | null;
  },
  {
    organization_id: string;
    amount_cents: number;
    status?: "draft" | "sent" | "paid";
    due_at?: string | null;
  },
  {
    amount_cents?: number;
    status?: "draft" | "sent" | "paid";
    due_at?: string | null;
  }
>({
  meta: {
    primaryKey: ["id"],
    nullable: {
      id: false,
      organization_id: false,
      amount_cents: false,
      status: false,
      due_at: true,
    },
  },
});

4) Typed query-builder behavior to leverage (2)

await typed
  .fromModel("billing", "public", "invoices")
  .eq("organization_id", "org-1")
  .order("due_at", { ascending: true })
  .select("id, amount_cents, status");

5) Zod alignment pattern (3)

import { z } from "zod";
import type { InsertOf, UpdateOf } from "@xylex-group/athena";

type InvoiceModel = typeof registry.billing.schemas.public.models.invoices;
type InvoiceInsert = InsertOf<InvoiceModel>;
type InvoiceUpdate = UpdateOf<InvoiceModel>;

const invoiceCreateSchema = z.object({
  organization_id: z.string().min(1),
  amount_cents: z.number().int().nonnegative(),
  status: z.enum(["draft", "sent", "paid"]).default("draft"),
  due_at: z.string().datetime().nullable().optional(),
});

const invoicePatchSchema = invoiceCreateSchema
  .pick({ amount_cents: true, status: true, due_at: true })
  .partial();

function parseCreate(input: unknown): InvoiceInsert {
  return invoiceCreateSchema.parse(input);
}

function parsePatch(input: unknown): InvoiceUpdate {
  return invoicePatchSchema.parse(input);
}

6) React Hook Form alignment pattern (4)

import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";

const form = useForm<z.input<typeof invoiceCreateSchema>>({
  resolver: zodResolver(invoiceCreateSchema),
  defaultValues: {
    status: "draft",
  },
});

async function onSubmit(raw: z.input<typeof invoiceCreateSchema>) {
  const payload: InvoiceInsert = invoiceCreateSchema.parse(raw);
  await typed.fromModel("billing", "public", "invoices").insert(payload);
}

Typed create helper (5)

function createUser(payload: InsertOf<typeof registry.app.schemas.public.models.users>) {
  return typed.fromModel("app", "public", "users").insert(payload).single("id, email");
}

Typed patch helper (6)

function updateUser(id: string, patch: UpdateOf<typeof registry.app.schemas.public.models.users>) {
  return typed.fromModel("app", "public", "users").eq("id", id).update(patch).single("id, email");
}

Typed list helper (7)

function listUsers() {
  return typed
    .fromModel("app", "public", "users")
    .select("id, email, created_at")
    .order("created_at", { ascending: false });
}

docs/typed-schema-registry.md

Source: https://github.com/xylex-group/athena-js/blob/main/docs/typed-schema-registry.md

1) Core contracts (1)

import {
  defineModel,
  defineSchema,
  defineDatabase,
  defineRegistry,
  createTypedClient,
} from "@xylex-group/athena";

const users = defineModel<
  { id: string; email: string; createdAt: string | null },
  { id?: string; email: string },
  { email?: string }
>({
  meta: {
    primaryKey: ["id"],
    nullable: { id: false, email: false, createdAt: true },
  },
});

const primarySchema = defineSchema({ users });
const primaryDb = defineDatabase({ public: primarySchema });
const registry = defineRegistry({ app: primaryDb });

const client = createTypedClient(registry, process.env.ATHENA_URL!, process.env.ATHENA_API_KEY!);

3) Client behavior and type coupling (2)

const typed = createTypedClient(registry, "https://athena-db.com", "secret", {
  tenantKeyMap: {
    organizationId: "X-Organization-Id",
    workspaceId: "X-Workspace-Id",
  },
});

await typed
  .withTenantContext({ organizationId: "org-1" })
  .fromModel("app", "public", "users")
  .select("id, email")
  .eq("active", true);

Tenant context behavior (3)

const scoped = typed.withTenantContext({ organizationId: "org-1" });
const scopedAgain = scoped.withTenantContext({ workspaceId: "ws-2" });
// scopedAgain sends both tenant headers

5) Relation metadata (4)

type Kind = "one-to-one" | "many-to-one" | "one-to-many" | "many-to-many";

{
  kind: Kind;
  sourceColumns: string[];
  targetSchema: string;
  targetModel: string;
  targetColumns: string[];
  targetDatabase?: string;
  through?: {
    schema: string;
    model: string;
    sourceColumns: string[];
    targetColumns: string[];
  };
}

10) Model-to-form adapter (React Hook Form + Zod) (5)

import { defineModel, createModelFormAdapter } from "@xylex-group/athena";

const profiles = defineModel<{
  id: string;
  display_name: string | null;
  age: number | null;
}>({
  meta: {
    primaryKey: ["id"],
    nullable: { id: false, display_name: true, age: true },
  },
});

const formAdapter = createModelFormAdapter(profiles);

// Edit defaults for RHF (null -> "")
const defaultValues = formAdapter.toDefaults(existingRow);

// Submit payload ("" -> null on nullable fields)
const insertPayload = formAdapter.toInsert(formValues);

README.md

Source: https://github.com/xylex-group/athena-js/blob/main/README.md

Install (1)

npm install @xylex-group/athena
# or
pnpm add @xylex-group/athena
# or
yarn add @xylex-group/athena

Install (2)

npm install react  # React >=17 required for the hook

Quick start (3)

import { createClient } from "@xylex-group/athena";

const athenaClient = createClient(ATHENA_URL, ATHENA_API_KEY, {
  client: "CLIENT_NAME",
  backend: { type: "athena" },
});

const { data, error } = await athenaClient.from("characters").select(`
    id,
    name,
    from:sender_id(name),
    to:receiver_id(name)
  `);

if (error) {
  console.error("gateway error", error);
} else {
  console.table(data);
}

Auth client (Athena Auth server) (4)

import { createClient } from "@xylex-group/athena";

const athena = createClient(ATHENA_URL, ATHENA_API_KEY, {
  client: "CLIENT_NAME",
  auth: {
    baseUrl: "http://localhost:3001/api/auth",
    // optional: bearer token if you are not using cookie-based sessions
    bearerToken: process.env.AUTH_BEARER_TOKEN,
  },
});

const login = await athena.auth.signIn.email({
  email: "demo@example.com",
  password: "super-secret",
  rememberMe: true,
});

const session = await athena.auth.getSession();
const sessions = await athena.auth.session.list();

// clear one session
await athena.auth.session.revoke({ token: "session_token_here" });
// or clear all sessions
await athena.auth.session.revoke([{ token: "session_token_here" }, { token: "session_token_2" }]);

await athena.auth.signOut();

// additional core flows
await athena.auth.forgetPassword({ email: "demo@example.com", redirectTo: "https://app/reset-password" });
await athena.auth.resetPassword({ newPassword: "new-secret", token: "reset_token" });
await athena.auth.verifyEmail({ token: "verify_token", callbackURL: "https://app/verified" });
await athena.auth.changePassword({ currentPassword: "old-secret", newPassword: "new-secret" });
await athena.auth.user.update({ name: "Demo User" });

Typed schema registry (model-first) (5)

import {
  createTypedClient,
  defineDatabase,
  defineModel,
  defineRegistry,
  defineSchema,
} from "@xylex-group/athena";

const registry = defineRegistry({
  primary: defineDatabase({
    public: defineSchema({
      users: defineModel<{ id: string; email: string }>({
        meta: {
          primaryKey: ["id"],
          nullable: { id: false, email: false },
        },
      }),
    }),
  }),
});

const typed = createTypedClient(registry, ATHENA_URL, ATHENA_API_KEY, {
  tenantKeyMap: {
    organizationId: "X-Organization-Id",
  },
});

await typed
  .withTenantContext({ organizationId: "org_1" })
  .fromModel("primary", "public", "users")
  .select("*");

Typed schema generator (6)

athena-js generate
athena-js generate --dry-run
athena-js generate --config ./athena.config.ts
athena-js generate --help
athena-js help generate

Result unwrapping and success guards (7)

import {
  isOk,
  unwrap,
  unwrapRows,
  unwrapOne,
  requireSuccess,
  requireAffected,
} from "@xylex-group/athena";

const result = await athena.from("users").select("id,name");

if (isOk(result)) {
  const rows = unwrapRows(result); // typed User[]
  console.log(rows.length);
}

const one = await athena.from("users").eq("id", 1).single("id,name");
const user = unwrapOne(one, { allowNull: true });

const inserted = await athena
  .from("users")
  .insert({ name: "Alice" })
  .select("id", { count: "exact" });

requireSuccess(inserted, { table: "users", operation: "insert" });
requireAffected(inserted, { min: 1 }, { table: "users", operation: "insert" });

Error normalization (8)

import { normalizeAthenaError } from "@xylex-group/athena";

const result = await athena.from("users").insert({ id: 1 }).select();
if (result.error) {
  const err = normalizeAthenaError(result, {
    table: "users",
    operation: "insert",
  });
  if (err.kind === "unique_violation") {
    // deterministic conflict handling
  }
}

Numeric coercion (9)

import { coerceInt, assertInt } from "@xylex-group/athena";

const maybeCaseId = coerceInt(req.query.case_id, { min: 1 });
if (maybeCaseId == null) throw new Error("Invalid case id");

const caseId = assertInt(req.query.case_id, "case_id", { min: 1 });

Retry helper (10)

import { withRetry } from "@xylex-group/athena";

const result = await withRetry(
  {
    retries: 3,
    backoff: "exponential",
    baseDelayMs: 100,
    jitter: true,
  },
  () => athena.from("users").select("id,name"),
);

Reading rows (11)

// select all columns
const { data } = await athena.from("users").select();

// select specific columns
const { data } = await athena.from("users").select("id, name, email");

// select with type annotation
const { data } = await athena.from<User>("users").select("id, name");

Filters (12)

const { data } = await athena
  .from("characters")
  .select("id, name")
  .eq("active", true) // column = value
  .eqUuid("session_id", "550e8400-e29b-41d4-a716-446655440000") // explicit UUID cast
  .eqCast("session_id", "550e8400-e29b-41d4-a716-446655440000", "uuid") // explicit cast type
  .neq("role", "guest") // column != value
  .gt("level", 5) // column > value
  .gte("score", 100) // column >= value
  .lt("age", 30) // column < value
  .lte("created_at", "2024-01-01") // column <= value
  .like("name", "Ali%") // SQL LIKE (case-sensitive)
  .ilike("email", "%@example%") // SQL ILIKE (case-insensitive)
  .is("deleted_at", null) // IS NULL / IS TRUE etc.
  .in("status", ["active", "pending"]) // IN (…)
  .contains("tags", ["hero"]) // array contains value
  .containedBy("tags", ["hero", "villain"]) // array is subset of value
  .match({ role: "admin", active: true }) // multiple eq filters at once
  .not("role", "eq", "banned") // NOT col op val
  .or("status.eq.active,status.eq.pending"); // OR expression

Filters (13)

const { data } = await athena
  .from("instruments")
  .select("name, section_id")
  .eq("name", "violin");

Pagination (14)

// 1. offset / limit — contiguous windows
const { data } = await athena.from("users").select().limit(25).offset(50);

// range shorthand: offset = from, limit = to - from + 1
const { data: firstTwentyFive } = await athena.from("users").select().range(0, 24);

// 2. page based — maps to current_page / page_size / total_pages
const { data: page2 } = await athena
  .from("orders")
  .select("id, total")
  .currentPage(2)
  .pageSize(25);

// .totalPages() is an optional hint some backends use in the response envelope
const { data: hinted } = await athena
  .from("orders")
  .select("id, total")
  .currentPage(1)
  .pageSize(25)
  .totalPages(10);

Ordering (15)

// descending + limit
// SELECT * FROM rsf_messages WHERE room_id = $1 ORDER BY created_at DESC LIMIT 100
const { data } = await athena
  .from("rsf_messages")
  .eq("room_id", roomId)
  .select("*", { stripNulls: false })
  .order("created_at", { ascending: false })
  .limit(100);

// ascending (default) + page-based pagination
const { data: page } = await athena
  .from("orders")
  .select("id, total, created_at")
  .order("created_at")
  .currentPage(1)
  .pageSize(25);

// combine with .single() to grab the newest / oldest row
const { data: latest } = await athena
  .from("messages")
  .eq("room_id", roomId)
  .select("*")
  .order("created_at", { ascending: false })
  .single();

Single row (16)

// returns the first row or null instead of an array
const { data: user } = await athena
  .from("users")
  .select("id, name")
  .eq("id", 42)
  .single();

Table schema targeting (17)

const { data } = await athena
  .from("users")
  .select("id,email", { schema: "public" });

RPC (18)

const { data, count } = await athena
  .rpc("list_users", { role: "admin" }, { count: "exact", schema: "public" })
  .eq("active", true)
  .order("created_at", { ascending: false })
  .range(0, 24)
  .select(["id", "email"]);

const { data: firstUser } = await athena
  .rpc<{ id: number; email: string }>("list_users", { role: "admin" })
  .single("id,email");

const { data: readOnlyUser } = await athena
  .rpc<{
    id: number;
    email: string;
  }>(
    "list_users",
    { role: "admin" },
    { get: true, count: "planned", head: true },
  )
  .eq("id", 1)
  .single("id,email");

Options (19)

const { data } = await athena
  .from("orders")
  .select("id", { count: "exact", stripNulls: false });

Insert (20)

const { data: inserted } = await athena
  .from("countries")
  .insert({ name: "Mordor" })
  .select("id, name");

// insert multiple rows
const { data } = await athena
  .from("characters")
  .insert([{ name: "Frodo" }, { name: "Sam" }])
  .select();

// Type inference differs by payload shape:
// - insert(one) => AthenaResult<Row>
// - insert(many) => AthenaResult<Row[]>

Update (21)

const { data: updated } = await athena
  .from("countries")
  .update({ name: "Gondor" })
  .eq("id", 1)
  .select();

Upsert (22)

const { data } = await athena
  .from("countries")
  .upsert(
    { id: 2, name: "Rohan" },
    { updateBody: { name: "Rohan" }, onConflict: "id" },
  )
  .select();

// Type inference differs by payload shape:
// - upsert(one) => AthenaResult<Row>
// - upsert(many) => AthenaResult<Row[]>

Delete (23)

// delete by id filter
await athena.from("countries").eq("id", 1).delete();

// delete with explicit resourceId option
await athena.from("countries").delete({ resourceId: "abc-123" });

// chain .select() to get the deleted row back
const { data: deleted } = await athena
  .from("countries")
  .eq("resource_id", "abc-123")
  .delete()
  .select("id, name");

MutationQuery chaining (24)

const mutation = athena.from("users").insert({ name: "Alice" });

await mutation.select("id, name");        // fire request, return rows
await mutation.returning("id");           // alias for .select()
await mutation.single("id");              // return first row or null
await mutation.maybeSingle("id");         // same as .single()
await mutation;                           // fire request, return default columns
mutation.then(({ data }) => …);           // thenable
mutation.catch(err => …);
mutation.finally(() => …);

React hooks (25)

"use client";

import {
  AthenaQueryClientProvider,
  createAthenaQueryClient,
  useAthenaGateway,
  useMutation,
  useQuery,
} from "@xylex-group/athena/react";
import { createClient } from "@xylex-group/athena";

const queryClient = createAthenaQueryClient({
  cache: { mode: "none" }, // default: no persistent data cache, inflight dedupe only
});

const athena = createClient(
  process.env.NEXT_PUBLIC_ATHENA_URL!,
  process.env.NEXT_PUBLIC_ATHENA_API_KEY!,
);

type Product = {
  id: string;
  name: string;
  price: number;
};

type CreateProductInput = {
  name: string;
  price: number;
};

function ProductsInner() {
  const products = useQuery<Product[]>({
    queryKey: ["products"],
    queryFn: () =>
      athena.from("products").select("id,name,price").limit(50),
  });

  const createProduct = useMutation<CreateProductInput, Product>({
    mutationFn: (input) =>
      athena.from("products").insert(input).select("id,name,price").single(),
    onSuccess: () => {
      void products.refetch();
    },
  });

  if (products.isLoading) return <div>Loading...</div>;
  if (products.error) return <div>{products.error.message}</div>;

  return (
    <div>
      <button
        onClick={() => {
          createProduct.mutate({ name: "New product", price: 99 });
        }}
      >
        Add Product
      </button>
      {products.data?.map((product) => (
        <div key={product.id}>
          {product.name} - {product.price}
        </div>
      ))}
    </div>
  );
}

export function Products() {
  return (
    <AthenaQueryClientProvider client={queryClient}>
      <ProductsInner />
    </AthenaQueryClientProvider>
  );
}

React hooks (26)

import { useAthenaGateway } from "@xylex-group/athena/react";
import { useEffect } from "react";

export function UsersPanel() {
  const { fetchGateway, lastResponse, isLoading, error } = useAthenaGateway({
    baseUrl: "https://athena-db.com",
    apiKey: process.env.NEXT_PUBLIC_ATHENA_API_KEY,
  });

  useEffect(() => {
    void fetchGateway({
      table_name: "users",
      columns: ["id", "email"],
      limit: 25,
    });
  }, [fetchGateway]);

  if (error) return <div>Error: {error}</div>;
  if (isLoading) return <div>Loading…</div>;

  return <pre>{JSON.stringify(lastResponse?.data, null, 2)}</pre>;
}

User context headers (27)

const athena = createClient(
  "https://athena-db.com",
  process.env.ATHENA_API_KEY,
  {
    headers: {
      "X-User-Id": currentUser.id,
      "X-Organization-Id": currentUser.organizationId ?? "",
    },
  },
);

Custom headers (28)

const athena = createClient(
  "https://athena-db.com",
  process.env.ATHENA_API_KEY,
  {
    headers: {
      "X-Custom-Header": "value",
    },
  },
);

TypeScript (29)

interface User {
  id: number;
  name: string;
  email: string;
  active: boolean;
}

const { data } = await athena
  .from<User>("users")
  .select("id, name")
  .eq("active", true);
// data is User[] | null

Development Validation (30)

pnpm typecheck   # compile-time type compatibility checks
pnpm check:all   # lint + typecheck + test + build

test-sdk/examples/generator/README.md

Source: https://github.com/xylex-group/athena-js/blob/main/test-sdk/examples/generator/README.md

Validation (1)

pnpm test:e2e

test-sdk/examples/react-hooks/README.md

Source: https://github.com/xylex-group/athena-js/blob/main/test-sdk/examples/react-hooks/README.md

Athena credentials (1)

import { createExampleAthenaClient } from './shared'

const athena = createExampleAthenaClient({
  athenaUrl: process.env.NEXT_PUBLIC_ATHENA_URL!,
  apiKey: process.env.NEXT_PUBLIC_ATHENA_API_KEY!,
  client: process.env.NEXT_PUBLIC_ATHENA_CLIENT,
})

Athena credentials (2)

import { DemoProductsPanel } from './products-panel'

export default function Page() {
  return <DemoProductsPanel athena={athena} />
}

Direct Athena hook pattern (3)

const products = useQuery({
  queryKey: ['products', organizationId],
  enabled: Boolean(organizationId),
  queryFn: async () => {
    const result = await athena
      .from('products')
      .select('id,name,price')
      .eq('organization_id', organizationId)
      .limit(50)

    if (result.error) throw new Error(result.error)
    return result.data ?? []
  },
})

const createProduct = useMutation({
  mutationFn: async (input) => {
    const result = await athena
      .from('products')
      .insert(input)
      .select('id,name,price')
      .single()

    if (result.error || !result.data) throw new Error(result.error ?? 'insert failed')
    return result.data
  },
  onSuccess: () => void products.refetch(),
})

test-sdk/README.md

Source: https://github.com/xylex-group/athena-js/blob/main/test-sdk/README.md

Setup (1)

pnpm build
cd test-sdk
pnpm install

Run (2)

pnpm start
# or
pnpm dev

Run E2E tests (3)

pnpm test:e2e

Run E2E tests (4)

node --import tsx --test test/react-test-sdk-hooks-integration.test.ts

Generator full-utilization examples (5)

pnpm test:e2e:generator

Error response shape (6)

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "limit must be a non-negative integer",
    "details": {
      "field": "limit",
      "received": "abc"
    }
  },
  "responseTimeMs": 2
}

On this page

Context7 _autodocsAthenaAuthSdkClient InterfaceTypedAthenaClient InterfaceQuery Runtime ExportsCONTRIBUTING.mdDevelopment setup (1)Project structure (2)Validation checks (3)docs/api-reference.mdCore result contract (1)createClient(url, apiKey, options?) (2)AthenaClient.builder() (3)Backend constants (4)Backend constants (5)AthenaSdkClient (6)TableQueryBuilder<Row, Insert, Update> (7)SelectChain<Row, SelectedRow = Row> (8)MutationQuery<Result> (9)UpdateChain<Row> (10)RpcQueryBuilder<Row> (11)JSON-safe primitives (12)Condition primitives (13)AthenaGatewayCallOptions (14)AthenaRpcCallOptions (15)Fetch payload (16)Insert payload (17)Update payload (18)Delete payload (19)RPC payload (20)Query payload (21)Gateway response/error contracts (22)Error classification primitives (23)Model declarations (24)Typed client (25)Generator API (26)Gateway hook (27)Validation commands (28)Command line usage (29)docs/auth-client-bindings.mdAthena Auth Client Bindings (1)Client setup (2)React useSession parity (3)docs/auth/admin.mdxExamples (1)docs/auth/api-key.mdxExamples (1)docs/auth/callback.mdxExample (1)docs/auth/index.mdxBase setup (1)docs/auth/organization-invitations.mdxExamples (1)docs/auth/organization-members.mdxExamples (1)docs/auth/organization.mdxExamples (1)docs/auth/passkey.mdxExamples (1)docs/auth/session.mdxExamples (1)docs/auth/sign-in-up.mdxExamples (1)docs/auth/social-account.mdxExamples (1)docs/auth/two-factor.mdxExamples (1)docs/auth/use-session.mdxHook API (1)Example component (2)docs/auth/user.mdxExamples (1)docs/cli-command-reference.mdRoot commands (1)Generate command (2)Local vs global execution (3)Local vs global execution (4)Windows global shim troubleshooting (5)Windows global shim troubleshooting (6)Windows global shim troubleshooting (7)ERR_MODULE_NOT_FOUND for dist/cli/index.js (8)Postgres 3D000 (database "<name>" does not exist) (9)Debugging mode (10)docs/generator-cicd.mdAthena JS Generator CI/CD Guide (1)Pipeline pattern 1: direct pg_url introspection (2)Pipeline pattern 1: direct pg_url introspection (3)Pipeline pattern 2: gateway-only introspection via Athena /gateway/query (4)Pipeline pattern 2: gateway-only introspection via Athena /gateway/query (5)Dry-run verification strategy (6)Artifact diff strategy for PR checks (7)Failure handling and retry guidance (8)docs/generator-codex-handoff-prompt-pack.md1) Prompt: Canonical Handoff (1)2) Prompt: Troubleshooting-Focused Expansion (2)3) Prompt: CI/Automation-Focused Expansion (3)docs/generator-config.mdCLI entrypoint (1)Config surface at a glance (2)defineGeneratorConfig helper (3)Postgres direct mode (4)Postgres gateway mode (5)Scylla mode (contract placeholder) (6)Output contract (7)Schema selection (8)placeholderMap (9)Naming controls (10)Feature flags (11)Feature flags (12)Experimental flags (13)Local development (direct DB) (14)Gateway-only environment (15)Pipeline integration tips (16)docs/getting-started.md2) Install (1)createClient (fastest) (2)AthenaClient.builder() (explicit configuration) (3)AthenaClient.fromEnvironment() (ops-friendly) (4)4) Read data with table builders (5)Important chain behavior (6)5) Filter, paging, and schema-qualified calls (7)Insert (8)Update (9)Upsert (10)RPC (11)Raw query (12)8) Handle responses safely (13)9) Move to typed model registry (14)10) Tenant header propagation (15)11) Form contracts with Zod and React Hook Form (16)12) Generate registry code from PostgreSQL (17)12) Generate registry code from PostgreSQL (18)13) Production checklist (19)docs/index.mdConcept map (1)docs/type-safety-playbook.md3) Tri-generic model pattern (1)4) Typed query-builder behavior to leverage (2)5) Zod alignment pattern (3)6) React Hook Form alignment pattern (4)Typed create helper (5)Typed patch helper (6)Typed list helper (7)docs/typed-schema-registry.md1) Core contracts (1)3) Client behavior and type coupling (2)Tenant context behavior (3)5) Relation metadata (4)10) Model-to-form adapter (React Hook Form + Zod) (5)README.mdInstall (1)Install (2)Quick start (3)Auth client (Athena Auth server) (4)Typed schema registry (model-first) (5)Typed schema generator (6)Result unwrapping and success guards (7)Error normalization (8)Numeric coercion (9)Retry helper (10)Reading rows (11)Filters (12)Filters (13)Pagination (14)Ordering (15)Single row (16)Table schema targeting (17)RPC (18)Options (19)Insert (20)Update (21)Upsert (22)Delete (23)MutationQuery chaining (24)React hooks (25)React hooks (26)User context headers (27)Custom headers (28)TypeScript (29)Development Validation (30)test-sdk/examples/generator/README.mdValidation (1)test-sdk/examples/react-hooks/README.mdAthena credentials (1)Athena credentials (2)Direct Athena hook pattern (3)test-sdk/README.mdSetup (1)Run (2)Run E2E tests (3)Run E2E tests (4)Generator full-utilization examples (5)Error response shape (6)