Documentation Index
Fetch the complete documentation index at: https://mintlify.com/theopenlane/openlane-ui/llms.txt
Use this file to discover all available pages before exploring further.
Overview
The @repo/codegen package provides GraphQL code generation using @graphql-codegen. It generates TypeScript types, hooks, and utilities from GraphQL queries and mutations, enabling type-safe interactions with the Openlane Core GraphQL API.
Installation
Key Features
- Auto-generated TypeScript types from GraphQL schema
- Type-safe query and mutation hooks
- GraphQL document nodes for use with GraphQL clients
- Introspection schema for tooling support
- Custom scalar mappings (DateTime, UUID, JSON, etc.)
Architecture
The package uses graphql-codegen.yml configuration to generate code from:
- Schema Source:
https://raw.githubusercontent.com/theopenlane/core/main/internal/graphapi/clientschema/schema.graphql
- Query/Mutation Files:
./query/**/*.ts
- Output:
./src/schema.ts and ./src/introspectionschema.json
Generated Files
| File | Description |
|---|
src/schema.ts | Main export with all types, queries, mutations |
src/type-names.ts | Object type constants and metadata |
src/introspectionschema.json | Schema introspection data |
query/*.ts | GraphQL query/mutation definitions |
Usage
Importing Types
import {
User,
Organization,
OrderDirection,
CreateEntityInput,
UpdateEntityInput
} from '@repo/codegen/src/schema'
Using Generated Hooks
The package generates hooks for queries and mutations based on your GraphQL documents:
import { useUpdateUserNameMutation } from '@repo/codegen/src/schema'
function UserProfile({ userId }: { userId: string }) {
const [{ fetching: isSubmitting }, updateUserName] = useUpdateUserNameMutation()
const handleUpdateName = async (firstName: string, lastName: string) => {
await updateUserName({
updateUserId: userId,
input: {
firstName,
lastName,
},
})
}
return (
<form onSubmit={(e) => {
e.preventDefault()
handleUpdateName('John', 'Doe')
}}>
{/* form fields */}
</form>
)
}
Importing Type Constants
import { ObjectTypes, ObjectNames, OBJECT_TYPE_PERMISSIONS_CONFIG } from '@repo/codegen/src/type-names'
// Use object type constants
const entityType = ObjectTypes.Entity
const entityName = ObjectNames.Entity
Using Enums
import {
OrderDirection,
OrgMembershipRole,
TaskTaskStatus
} from '@repo/codegen/src/schema'
// Sort configuration
const sortConditions = [
{ field: 'createdAt', direction: OrderDirection.DESC },
{ field: 'name', direction: OrderDirection.ASC }
]
// Role checks
if (membership.role === OrgMembershipRole.ADMIN) {
// Admin-specific logic
}
Code Generation Workflow
1. Create GraphQL Queries
Add queries/mutations to /query directory. Group by domain (e.g., organization.graphql, user.graphql):
# query/organization.ts
import { gql } from 'graphql-request'
export const GET_ORGANIZATIONS = gql`
query GetOrganizations($where: OrganizationWhereInput) {
organizations(where: $where) {
edges {
node {
id
name
displayName
}
}
}
}
`
2. Run Code Generation
Or directly:
3. Use Generated Code
import { useGetOrganizationsQuery } from '@repo/codegen/src/schema'
function OrganizationList() {
const [{ data, fetching }] = useGetOrganizationsQuery({
variables: {
where: { displayName: { contains: 'Acme' } }
}
})
if (fetching) return <div>Loading...</div>
return (
<ul>
{data?.organizations?.edges?.map((edge) => (
<li key={edge.node.id}>{edge.node.displayName}</li>
))}
</ul>
)
}
Configuration
Scalar Mappings
Custom scalars are mapped to TypeScript types:
scalars:
DateTime: string
Date: string
Decimal: number
UUID: string
ID: string
JSON: any
Upload: any
CodeGen Features
exposeDocument: true - Adds document field to each hook
exposeQueryKeys: true - Generates getKey() functions for cache updates
addInfiniteQuery: true - Generates infinite query hooks
exposeMutationKeys: true - Generates mutation keys
exposeFetcher: true - Generates fetcher functions
Common Patterns
Filtering and Pagination
import {
EntityWhereInput,
EntityOrderField,
OrderDirection
} from '@repo/codegen/src/schema'
const where: EntityWhereInput = {
name: { contains: 'vendor' },
status: { eq: 'ACTIVE' }
}
const orderBy = {
field: EntityOrderField.CreatedAt,
direction: OrderDirection.DESC
}
Type-safe Mutations
import {
CreateEntityInput,
UpdateEntityInput
} from '@repo/codegen/src/schema'
const createInput: CreateEntityInput = {
name: 'New Entity',
entityType: 'vendor',
status: EntityEntityStatus.Active
}
const updateInput: UpdateEntityInput = {
name: 'Updated Name',
description: 'New description'
}
Working with Fragments
import {
ControlListFieldsFragment,
User
} from '@repo/codegen/src/schema'
function ControlCard({ control }: { control: ControlListFieldsFragment }) {
return (
<div>
<h3>{control.name}</h3>
<p>{control.description}</p>
</div>
)
}
Best Practices
- Use Apollo GraphQL Explorer for query development: Apollo Sandbox
- Group queries by domain - Keep related queries in the same file
- Use fragments for reusable field selections
- Run codegen after schema changes - Keep generated types in sync
- Import from schema.ts - All generated types are exported from the main schema file
Troubleshooting
Types not updating
Run the codegen command to regenerate types:
Import errors
Ensure you’re importing from the correct path:
// Correct
import { User } from '@repo/codegen/src/schema'
// Incorrect
import { User } from '@repo/codegen'
Schema changes not reflected
The schema is fetched from the upstream repository. If Core API changes, run codegen to pull the latest schema.