proofkit-fmodata

Type-safe ORM for FileMaker's OData API with TypeScript code generation.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "proofkit-fmodata" with this command: npx skills add proofgeist/proofkit/proofgeist-proofkit-proofkit-fmodata

ProofKit FMOData

Type-safe ORM for FileMaker's OData API with TypeScript code generation.

Up-to-Date Documentation

For the latest docs, fetch from proofkit.dev:

Quick Setup

1. Install packages

pnpm add @proofkit/fmodata@beta @proofkit/typegen

2. Create config (proofkit-typegen.config.jsonc)

npx @proofkit/typegen init

3. Set env vars

FM_SERVER=https://your-server.com FM_DATABASE=YourDatabase.fmp12 OTTO_API_KEY=your-api-key # or FM_USERNAME/FM_PASSWORD

4. Generate types

npx @proofkit/typegen generate

5. Or use interactive UI

npx @proofkit/typegen ui

Define Tables

import { fmTableOccurrence, textField, numberField, timestampField } from "@proofkit/fmodata"; import { z } from "zod";

export const Users = fmTableOccurrence("Users", { id: textField().primaryKey().entityId("FMFID:100001"), name: textField().notNull(), email: textField().notNull(), active: numberField() .readValidator(z.coerce.boolean()) .writeValidator(z.boolean().transform(v => v ? 1 : 0)), createdAt: timestampField().readOnly(), }, { entityId: "FMTID:1000001", navigationPaths: ["Contacts", "Orders"], });

Query Patterns

import { FMServerConnection, eq, and, gt, asc, contains } from "@proofkit/fmodata";

const connection = new FMServerConnection({ serverUrl: process.env.FM_SERVER, auth: { apiKey: process.env.OTTO_API_KEY } }); const db = connection.database("MyDatabase.fmp12");

// List with filters const result = await db.from(Users).list() .where(and(eq(Users.active, true), gt(Users.age, 18))) .orderBy(asc(Users.name)) .top(10) .execute();

// Get single record const user = await db.from(Users).get("user-123").execute();

// Select specific fields const result = await db.from(Users).list() .select({ userId: Users.id, userName: Users.name }) .execute();

// String filters .where(contains(Users.email, "@example.com")) .where(startsWith(Users.name, "John"))

CRUD Operations

// Insert const result = await db.from(Users) .insert({ name: "John", email: "john@example.com" }) .execute();

// Update const result = await db.from(Users) .update({ name: "Jane" }) .byId("user-123") .execute();

// Delete const result = await db.from(Users) .delete() .byId("user-123") .execute();

// Batch operations (atomic) const result = await db.batch([ db.from(Users).list().top(10), db.from(Users).insert({ name: "Alice", email: "alice@example.com" }), ]).execute();

Relationships

// Expand related records const result = await db.from(Users).list() .expand(Contacts, (b) => b.select({ name: Contacts.name }) .where(eq(Contacts.active, true)) ) .execute();

// Navigate from a record const result = await db.from(Contacts).get("contact-123") .navigate(Users) .select({ username: Users.username }) .execute();

Error Handling

import { isHTTPError, ValidationError, TimeoutError } from "@proofkit/fmodata";

const result = await db.from(Users).list().execute();

if (result.error) { if (isHTTPError(result.error)) { if (result.error.isNotFound()) console.log("Not found"); if (result.error.is5xx()) console.log("Server error"); } else if (result.error instanceof ValidationError) { console.log("Validation failed:", result.error.issues); } else if (result.error instanceof TimeoutError) { console.log("Request timed out"); } }

Troubleshooting

Connection Issues

"Unauthorized" or 401 errors

  • Verify OTTO_API_KEY or FM_USERNAME /FM_PASSWORD env vars

  • Ensure FM account has fmodata privilege enabled

  • Check OData service is enabled on FM Server

"Not Found" or 404 errors

  • Verify database name includes .fmp12 extension

  • Check table/layout name matches exactly (case-sensitive)

  • Ensure OData is enabled for the table occurrence

Type Generation Issues

typegen can't connect

  • Run npx @proofkit/typegen ui to debug interactively

  • Check connection health indicator in UI

  • Verify env vars are loaded (check --env-path flag)

Generated types don't match FM schema

  • Re-run npx @proofkit/typegen generate after FM schema changes

  • Use --reset-overrides to recreate override files

  • Check field type mappings in config

Query Issues

"Field not found" errors

  • Ensure field is defined in fmTableOccurrence

  • Check entityId matches FM field ID (use typegen to auto-generate)

  • Verify field is on the OData-exposed table occurrence

Validation errors on read/write

  • Check readValidator /writeValidator schemas match FM data types

  • FM stores booleans as 0/1 numbers - use coercion validators

  • Empty strings may need .catch("") or .nullable()

Performance Issues

Slow queries

  • Add .top(n) to limit results

  • Use .select() to fetch only needed fields

  • Avoid expanding large related record sets

References

  • fmodata-api.md - Complete API reference: field builders, operators, query methods

  • typegen-config.md - Configuration options and examples

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

Todoist CLI Skill

Manage tasks and projects in Todoist using the Official Todoist CLI tool (https://github.com/Doist/todoist-cli). Use when user asks about tasks, to-dos, remi...

Registry SourceRecently Updated
Coding

Claw Insights Install

Install and run Claw Insights, a read-only observability dashboard that monitors your OpenClaw agent with zero intrusion — no code changes, no cloud dependen...

Registry SourceRecently Updated
Coding

Wip Release

One-command release pipeline. Bumps version, updates changelog + SKILL.md, publishes to npm + GitHub.

Registry SourceRecently Updated
Coding

You.com Web Search & Research API

Integrate You.com APIs (Research, Search, Contents) into any language using direct HTTP calls — no SDK required. - MANDATORY TRIGGERS: YDC API, You.com API i...

Registry SourceRecently Updated