# ProofKit: typegen
> TypeScript type generator from FileMaker layouts
Documentation for the @proofkit/typegen package.
---
# Configuration (OData)
URL: https://proofkit.dev/docs/typegen/config-odata
import { TypeTable } from "fumadocs-ui/components/type-table";
import { Tabs, Tab } from "fumadocs-ui/components/tabs";
The typegen tool supports OData-based type generation using the `fmodata` config type. This is configured using the `proofkit-typegen-config.jsonc` file at the root of your project.
The `@proofkit/fmodata` package is still in beta. Some of these options may change.
The config key can also be an array of configs, which is useful if you need to connect to multiple databases, or with different settings for different sets of tables.
```jsonc title="proofkit-typegen-config.jsonc" tab="Single OData config"
{
"$schema": "https://proofkit.dev/typegen-config-schema.json",
"config": {
"type": "fmodata",
// ... your OData config here
},
}
```
```jsonc title="proofkit-typegen-config.jsonc" tab="Multiple configs"
{
"$schema": "https://proofkit.dev/typegen-config-schema.json",
"config": [
{
"type": "fmodata",
// ... your OData config here
},
{
"type": "fmdapi",
// ... your Data API config here
},
],
}
```
## Config options
### `type` (required)
Must be set to `"fmodata"` to use OData-based type generation.
### `configName` (optional)
An optional name for this configuration. Useful when using multiple configs to identify which config is being used.
### `path` (default: `"schema"`)
The path to the directory where the generated files will be saved.
### `reduceMetadata` (optional)
If set to `true`, reduced OData annotations will be requested from the server to reduce payload size. This will prevent comments, entity ids, and other properties from being generated.
This can also be set per-table in the `tables` array to override the top-level setting for specific tables.
### `clearOldFiles` (default: `false`)
If set to `false`, the path will not be cleared before the new files are written. Only the `client` and `generated` directories are cleared to allow for potential overrides to be kept.
This is different from the Data API config, which defaults to `true`. For OData configs, we preserve existing files by default to allow for customizations.
### `alwaysOverrideFieldNames` (default: `true`)
If set to `true` (default), field names will always be updated to match metadata, even when matching by entity ID. If set to `false`, existing field names are preserved when matching by entity ID.
This can also be set per-table in the `tables` array to override the top-level setting for specific tables.
### `envNames` (optional)
If set, will use the specified environment variable names for your OData connection.
Only use the **names** of your environment variables, not the values for security reasons.
The `envNames` object supports:
- `server`: The environment variable name for the OData server URL
- `db`: The environment variable name for the database name
- `auth`: An object with either:
- `apiKey`: The environment variable name for the API key, or
- `username` and `password`: The environment variable names for username and password
## Table options
The `tables` array in the config is where you define the tables (entity sets) that you want to generate types for. You must define at least one table in the config.
### `tableName` (required)
The entity set name (table occurrence name) to generate. This table will be included in metadata download and type generation. Must match exactly the name of an entity set in your OData service.
### `variableName` (optional)
Override the generated TypeScript variable name. The original entity set name is still used for the OData path, but you can use a different name in your TypeScript code.
For example, if your entity set is named `"Customers_Table"` but you want to use `Customers` in your code:
```jsonc
{
"tableName": "Customers_Table",
"variableName": "Customers"
}
```
### `reduceMetadata` (optional)
If undefined, the top-level setting will be used. If set to `true` or `false`, it will override the top-level `reduceMetadata` setting for this specific table.
### `alwaysOverrideFieldNames` (optional)
If undefined, the top-level setting will be used. If set to `true` or `false`, it will override the top-level `alwaysOverrideFieldNames` setting for this specific table.
## Field options
Within each table's `fields` array, you can specify field-level overrides.
### `fieldName` (required)
The field name this override applies to. Must match exactly the name of a field in the table's metadata.
### `exclude` (optional)
If set to `true`, this field will be excluded from generation entirely. Useful for fields you don't need in your TypeScript types.
### `typeOverride` (optional)
Override the inferred field type from metadata. The available options are:
- `"text"`: Treats the field as a text field
- `"number"`: Treats the field as a number field
- `"boolean"`: Treats the field as a boolean (validated with `z.coerce.boolean()`)
- `"date"`: Treats the field as a date field
- `"timestamp"`: Treats the field as a timestamp field
- `"container"`: Treats the field as a container field
- `"list"`: Treats the field as a FileMaker return-delimited list via `listField()` (defaults to `string[]`)
The typegen tool will attempt to infer the correct field type from the OData metadata. Use `typeOverride` only when you need to override the inferred type.
## Example configuration
Here's a complete example of an OData configuration:
```jsonc title="proofkit-typegen-config.jsonc"
{
"$schema": "https://proofkit.dev/typegen-config-schema.json",
"config": {
"type": "fmodata",
"configName": "Production OData",
"path": "schema/odata",
"reduceMetadata": true,
"clearOldFiles": false,
"alwaysOverrideFieldNames": true,
"envNames": {
"server": "ODATA_SERVER_URL",
"db": "ODATA_DATABASE_NAME",
"auth": {
"apiKey": "ODATA_API_KEY"
}
},
"tables": [
{
"tableName": "Customers",
"variableName": "Customers",
"fields": [
{
"fieldName": "InternalID",
"exclude": true
},
{
"fieldName": "Status",
"typeOverride": "boolean"
}
]
},
{
"tableName": "Orders",
"reduceMetadata": false,
"fields": [
{
"fieldName": "OrderDate",
"typeOverride": "date"
}
]
}
]
}
}
```
---
# Configuration (Data API)
URL: https://proofkit.dev/docs/typegen/config
import { TypeTable } from "fumadocs-ui/components/type-table";
import { Tabs, Tab } from "fumadocs-ui/components/tabs";
import { typegenConfig } from "@proofkit/typegen/config";
The typegen tool is configured using the `proofkit-typegen-config.jsonc` file at the root of your project.
JSONC is just JSON with comments. `@proofkit/typegen` will also work with
standard JSON files.
The config key can also be an array of configs, which is useful if you need to connect to multiple databases, or with different settings for different sets of layouts.
```jsonc title="proofkit-typegen-config.jsonc" tab="Single config"
{
"$schema": "https://proofkit.dev/typegen-config-schema.json",
"config": {
// ... your config here
},
}
```
```jsonc title="proofkit-typegen-config.jsonc" tab="Multiple configs"
{
"$schema": "https://proofkit.dev/typegen-config-schema.json",
"config": [
{
// ... your config here
},
{
// ... your other config here
},
],
}
```
## Config options
### `generateClient` (default: `true`)
If set to `false`, will only generate the zod schema and/or typescript types, but not the client files. Use this to customize the generated client, but still use the typegen tool to keep your schema up to date.
### `webviewerScriptName`
If set, will generate the client using the [@proofkit/webviewer](/docs/webviewer) package. This allows all calls to run via a FileMaker script rather than a network request. For more information, see the [@proofkit/webviewer](/docs/webviewer) documentation.
### `clientSuffix` (default: `"Layout"`)
The suffix to add to the client name.
For example, if the `schemaName` is `"Customers"`, the client name will be `"CustomersLayout"` and you'll import it as `import { CustomersLayout } from "./schema/client";` in your application code.
### `validator` (default: `"zod/v4"`)
The validator to use for the schema. Can be `"zod/v4"` or `"zod/v3"`. If set to `false`, only TypeScript types will be generated and no runtime validation will be performed when data is returned from the database.
### `clearOldFiles` (default: `true`)
If set to `true`, will delete all existing files in the output directory before generating new files. Useful to clean up old layouts that are no longer defined in the config.
### `path` (default: `"schema"`)
The path to the directory where the generated files will be saved.
### `envNames`
If set, will use the specified environment variable names for your FileMaker connection.
Only use the **names** of your environment variables, not the values for security reasons.
## Layout options
The `layouts` array in the config is where you define the layouts that you want to generate clients for. You must define at least one layout in the config.
### `schemaName` (required)
The name of the schema to generate. This will end up being the name of the generated client and what you'll see most throughout your codebase.
### `layoutName` (required)
The name of the layout to generate a client for. Must match exactly the name of a layout in your FileMaker database.
### `strictNumbers` (default: `false`)
If set to `true`, will force all number fields to be typed as `number | null`. This is useful if you want to ensure that all numbers are properly validated and not just strings.
By default, number fields are typed as `string | number` because FileMaker may return numbers as strings in certain cases (such as very large numbers in scientific notation or blank fields). This ensures you properly account for this in your frontend code.
We suggest only turning on `strictNumbers` if you are sure that your data will not hit these conditions or if you are also using a validator like Zod.
### `generateClient` (default: `inherit`)
Use this setting to override the `generateClient` setting from the root of the config.
### `valueLists` (default: `"ignore"`)
- `"strict"`: Will force all value list fields to be typed as the actual value from the value list. This is useful if you want to ensure that all value list fields are properly validated and not just strings.
- `"allowEmpty"`: Will show the possible values from the value list, but also allow the value to be an empty string, which is the default behavior of FileMaker.
- `"ignore"`: Any value lists defined on fields in the layout will be ignored and typed as `string`.
Even if you ignore the value lists for type purposes, the value lists will still be available in the generated schema file for use in your own code.
This setting will apply to all fields with value lists in the layout. For more granular control, override the Zod schema using the `extend` method. See the [Transformations](/docs/fmdapi/validation) page for more details.
---
# Customization
URL: https://proofkit.dev/docs/typegen/customization
How to customize the generated code produced by the typegen tool
## Customize the generated clients
You'll notice that the generated clients have a strict warning that says not to ever edit them, but if you need customizations for any reason, you probably need to just write the client files yourself.
However, this doesn't mean you can't use the typegen tool. If you simply pass `generateClient: false` to the typegen tool, it will still generate the zod schema and/or typescript types, which you can use in your own files and still keep the field names up to date as your database changes.
## Customize the generated schema
If you want to change the shape of the schema validator, you **can** edit the files in the main schema directory. The only files that will be overwritten each time that you run the typegen command are in the generated and client directories (if `generateClient` is enabled). For more details on this, see the [Transformations](/docs/fmdapi/validation) page.
---
# FAQ
URL: https://proofkit.dev/docs/typegen/faq
### I don't like the way the code is generated. Can I edit the generated files?
Editing the generated files (in the `client` and `generated` directories) is not reccommended as it would undermine the main benefit of being able to re-run the script at a later date when the schema changes—all your edits would be overritten. You can and should edit the files in the root of your specified directory if you need some custom overrides.
### Why are number fields typed as a `string | number`?
FileMaker may return numbers as strings in certain cases (such as very large numbers in scientific notation or blank fields). This ensures you properly account for this in your frontend code. If you wish to force all numbers to be typed as `number | null`, you can enable the `strictNumbers` flag per layout in your definition.
**WARNING:** the `strictNumbers` setting is disabled by default because it may result in false types if you are not using Zod or the auto-generated layout specific client. It works by applying a transformer to the zod schema to force all number fields to be either `number` or `null`.
### How does the code generation handle Value Lists?
Values lists are exported as their own types within the schema file, but they are not enforced within the schema by default because the actual data in the field may not be fully validated.
If you want the type to be enforced to a value from the value list, you can enable the `strictValueLists` flag per schema in your definition. This feature is only reccommended when you're also using the Zod library, as your returned data will fail the validation if the value is not in the value list.
### What about date/time/timestamp fields?
For now, these are all typed as strings. You probably want to transform these values anyway, so we keep it simple at the automated level.
### Why Zod instead of just TypeScript?
**In short:** Zod is a TypeScript-first schema declaration and validation library. When you use it, you get _runtime_ validation of your data instead of just compile-time validation.
FileMaker is great for being able to change schema very quickly and easily. Yes, you probably have naming conventions in place that help protect against these changes in your web apps, but no system is perfect. Zod lets you start with the assumption that any data coming from an external API might be in a format that you don't expect and then valdiates it so that you can catch errors early. This allows the typed object that it returns to you to be much more trusted throughout your app.
**But wait, does this mean that I might get a fatal error in my production app if the FileMaker schema changes?** Yes, yes it does. This is actually what you'd want to happen. Without validating the data returned from an API, it's possible to get other unexpcted side-effects in your app that don't present as errors, which may lead to bugs that are hard to track down or inconsistencies in your data.
---
# Quick Start
URL: https://proofkit.dev/docs/typegen
@proofkit/typegen
import { Tabs, TabItem } from "fumadocs-ui/components/tabs";
import { Callout } from "fumadocs-ui/components/callout";
import { File, Folder, Files } from "fumadocs-ui/components/files";
import { IconFileTypeTs } from "@tabler/icons-react";
import { CliCommand } from "@/components/CliCommand";
A utility for generating runtime validators and TypeScript files from your
own FileMaker layouts.
## Quick Start
Run this command to initialize `@proofkit/typegen` in your project:
## Configuring Typegen
The first time you run the command, you'll be prompted to create a config file. This is where you'll specifcy the layouts that you want to generate types for.
To see all the options available, see the [Configuration](/docs/typegen/config) page.
### Environment Variables
This tool will connect to your FileMaker solution using the `@proofkit/fmdapi` package and read the layout metadata for each layout you specify in the config file. By default it will expect the following environment variables to be set:
```bash
FM_SERVER=https://your-server.com # must start with https://
FM_DATABASE=MyFile.fmp12 # must end with .fmp12
# If using OttoFMS
OTTO_API_KEY=dk_123...abc
# otherwise (fmrest privilege must be enabled on this account)
FM_USERNAME=fmrest
FM_PASSWORD=your-password
```
If you need to use different env variable names (i.e. for multiple FileMaker connections), set the `envNames` option in the [config](/docs/typegen/config) file.
## Running Typegen
Once you have a config file setup, you can run the command to generate the types:
We suggest adding a script to your `package.json` to run this command more easily
### Example Generated Files
If your typegen config is setup with 2 layouts and the path set to `schema`, this is what the generated files will look like:
} />
} />
} />
} />
} />
} />
} />
The `client` folder is where you'll import from in other files of your app to use the layout-specific clients.
The `generated` folder is where the typegen will put the generated files. These files are auto-generated and should not be edited, since your changes would just be overwritten the next time you run an update to your schema.
The other files in the root of the `schema` folder are what will be used in the generated clients, and can be safely modifed to allow for customizations.
---
# CLI Options
URL: https://proofkit.dev/docs/typegen/options
import { TypeTable } from "fumadocs-ui/components/type-table";
Most configuration can be done with the [config file](/docs/typegen/config) in your project, but some options can be set at runtime.
```bash
npx @proofkit/typegen
```
## Global Options
### `--config `
Set a custom filename/path for where the config file is located or will be created. The file name must end with either `jsonc` or `json`.
- For `generate`, this specifies where to find the config file.
- For `init`, this specifies where to create the config file.
## `generate` command
```bash
npx @proofkit/typegen generate
```
This is also the default command, so "generate" is optional. If this command is run without any config file detected, you will be prompted to create the config file (the `init` command).
### `--env-path `
Set a custom path for where your environment variables are stored.
### `--reset-overrides`
Recreate the overrides file(s), even if they already exist.
## `ui` command
```bash
npx @proofkit/typegen ui
```
Launch the typegen web interface for easy configuration.
## `init` command
```bash
npx @proofkit/typegen init
```
Use this command to create a config file in the current directory.
See [Global Options](#global-options) for `--config` usage.
---
# Typegen UI
URL: https://proofkit.dev/docs/typegen/ui
import { CliCommand } from "@/components/CliCommand";
The typegen tool has a built-in web interface for editing your JSON config file and running the typegen scripts. It's helpful for making sure your environment variables are setup correctly and can help autocomplete layout/field/table names into the config file.
To launch the UI, run the following command and a browser window will open at `http://localhost:3141`:
## CLI options
The UI can be configured with the following CLI options:
### `--port `
Set the port for the UI server.
### `--config `
Set a custom filename/path for where the config file is located or will be created. The file name must end with either `jsonc` or `json`.
### `--no-open`
Don't automatically open the browser.