# Schema generation (/docs/codegen/schema-generation)



`@kysoql/codegen` reads Salesforce metadata and writes the schema consumed by `Kysoql<YourSchema>`.

Generate with an identity that represents your application's access, then regenerate when relevant fields, relationships, picklists, object capabilities, or permissions change.

For repeatable settings, use [`kysoql.config.ts`](/docs/codegen/configuration).

## Generate from the CLI [#generate-from-the-cli]

```bash
pnpm exec kysoql generate --no-config \
  --auth config/salesforce.auth.ts \
  --object Account \
  --object Contact \
  --object Opportunity \
  --schema-name SalesforceSchema
```

| Option                    | Default                                 | What it does                                                              |
| ------------------------- | --------------------------------------- | ------------------------------------------------------------------------- |
| `--api-version <version>` | Config or `65.0`                        | Chooses the Salesforce REST version without a `v` prefix.                 |
| `--auth <path>`           | Config `auth`                           | Loads a trusted module whose default export returns a Salesforce session. |
| `--config <path>`         | Auto-discover                           | Chooses a config file explicitly.                                         |
| `--no-config`             | Off                                     | Skips config discovery and evaluation.                                    |
| `--object <api-name>`     | Config list or all queryable objects    | Selects objects to generate. Repeat for more than one.                    |
| `--output <path>`         | Config or normal generated-file default | Chooses the output file.                                                  |
| `--schema-name <name>`    | `SalesforceSchema`                      | Chooses the generated interface name.                                     |
| `--help`                  | N/A                                     | Shows the CLI help.                                                       |

Authentication is explicit. Add `auth` to config or pass `--auth <module>`. Codegen does not read Salesforce access-token or instance-URL environment variables on its own.

```bash
pnpm exec kysoql --help
pnpm exec kysoql generate --help
```

If you do not provide an object list, codegen generates every queryable object returned by Salesforce global Describe. For a large org, start with an explicit list.

## Include relationship targets [#include-relationship-targets]

Generating `Contact` does not automatically generate every object it references.

If a query selects `Account.Name` from `Contact`, generate `Account` too. The same idea applies to child subqueries and `TYPEOF` branches.

```ts
import { defineConfig } from "@kysoql/codegen";

export default defineConfig({
  objects: ["Contact", "Account", "User"],
});
```

The virtual polymorphic `.Type` qualifier is derived from the reference field metadata and does not require every possible target object to be generated.

## What the generated schema remembers [#what-the-generated-schema-remembers]

The generated types include the metadata Kysoql needs for useful query checks, including:

* field value types and nullability
* filter, sort, group, and aggregate capabilities
* standard and custom field status
* parent and child relationships
* reference targets and polymorphic references
* active picklist metadata used by supported operations
* object scopes and MRU capability
* supported Data 360 query options

Date, datetime, and time values are typed as strings in query results. Location fields use `{ latitude, longitude }`. Unknown Salesforce field types fall back conservatively.

Generated files include a `Do not edit manually` header. Regenerate them instead of patching the output by hand.

## Generate a smaller field surface [#generate-a-smaller-field-surface]

The optional [`fields` configuration](/docs/codegen/field-filtering) can include or exclude exact field API names per object.

Filtering changes the generated TypeScript surface. It does not reduce Salesforce Describe requests or change Salesforce permissions.

Objects with explicit field rules are marked as partial schemas, so typed `selectFields(...)` selectors are disabled for them. Explicit `.select(...)` continues to work with the retained fields.

## Big Objects [#big-objects]

Custom Big Objects ending in `__b` do not support normal REST Describe. When you explicitly list a Big Object, native codegen reads its field and ordered index metadata through Salesforce Tooling API.

Generated files export `salesforceSchemaMetadata`. Pass that metadata to `Kysoql` so Big Object filters can be validated against the generated index order:

```ts
import { Kysoql } from "@kysoql/core";
import {
  salesforceSchemaMetadata,
  type SalesforceSchema,
} from "./kysoql/salesforce.generated";

const db = new Kysoql<SalesforceSchema>({
  schemaMetadata: salesforceSchemaMetadata,
});
```

## Knowledge categories [#knowledge-categories]

For `KnowledgeArticleVersion` and concrete `__kav` article objects, native codegen also loads the visible data-category tree used by Kysoql's typed Knowledge query helpers.

What codegen can see depends on the authenticated Salesforce user. A custom `SalesforceDescribeClient` can provide its own category metadata when it uses another transport.

## Generate programmatically [#generate-programmatically]

Use the library API when schema generation belongs inside your own tooling:

```ts
import { createRestDescribeClient, generateSchema } from "@kysoql/codegen";

export async function generateForOrg(
  instanceUrl: string,
  accessToken: string,
) {
  await generateSchema({
    client: createRestDescribeClient({
      instanceUrl,
      accessToken,
      apiVersion: "65.0",
    }),
    objects: ["Account", "Contact"],
    output: "src/kysoql/salesforce.generated.ts",
  });
}
```

Programmatic generation does not discover `kysoql.config.ts`. Pass the options you need directly.

For lower-level workflows, `loadSchema()` loads and validates metadata without writing a file, and `renderSchema()` turns loaded descriptions into TypeScript.

## Keep generated types current [#keep-generated-types-current]

Put the generator behind an application script so the command is easy to run consistently.

You can commit the generated file and review changes, or regenerate it in a controlled build step with secure credentials. Avoid making every application startup depend on live Describe requests.

After regeneration, run your normal TypeScript checks. New type errors can be useful signals that an object, field, relationship, or capability changed in Salesforce.
