https://github.com/contentful-userland/cf-content-types-generator
Generate TS declarations for content types
https://github.com/contentful-userland/cf-content-types-generator
builder cli contentful generator type-tool typescript
Last synced: 2 months ago
JSON representation
Generate TS declarations for content types
- Host: GitHub
- URL: https://github.com/contentful-userland/cf-content-types-generator
- Owner: contentful-userland
- License: mit
- Created: 2020-02-24T13:27:55.000Z (over 6 years ago)
- Default Branch: master
- Last Pushed: 2025-09-15T18:58:08.000Z (9 months ago)
- Last Synced: 2025-09-15T20:28:41.880Z (9 months ago)
- Topics: builder, cli, contentful, generator, type-tool, typescript
- Language: TypeScript
- Homepage:
- Size: 1.53 MB
- Stars: 134
- Watchers: 19
- Forks: 30
- Open Issues: 19
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# cf-content-types-generator
Generate TypeScript types from your Contentful content model, either from a local `contentful space export` JSON file or by fetching the model directly from Contentful.
Use the generated types with `contentful.js` v10+ for safer queries, autocomplete, and less schema drift between Contentful and your app.
> As of v3.x, pre-v10 output is removed. If you are upgrading from `2.x`, modern `contentful.js` typing is now the default and only output model.
[](https://oclif.io)
[](https://npmjs.org/package/cf-content-types-generator)
[](https://npmjs.org/package/cf-content-types-generator)
[](https://github.com/contentful-userland/cf-content-types-generator/blob/master/package.json)
[](https://coveralls.io/github/contentful-userland/cf-content-types-generator)
```ts
import type { TypeAnimal } from './@types/generated';
```
## Install
```bash
npm install --save-dev cf-content-types-generator
```
## Quickstart In 60 Seconds
You can generate types in two ways:
- from a local export JSON file in the exact [Input](#input) shape, usually created with `contentful space export`
- by providing Contentful credentials and letting the CLI fetch the same model data on the fly
### Path A: Generate From A Local Export JSON File
Export your space model:
```bash
contentful space export --config ./export-config.json
```
Generate types:
```bash
cf-content-types-generator ./contentful-export.json -o src/@types/generated
```
Use the generated type:
```ts
import type { TypeAnimal } from './@types/generated';
```
### Path B: Generate By Fetching From Contentful
```bash
cf-content-types-generator \
-s \
-t \
-e \
--proxy https://user:password@proxy.example:8443 \
-o src/@types/generated
```
If your network requires a proxy, you can also add `--rawProxy` to pass the proxy config straight to Axios.
## What It’s For
- turn a Contentful content model into generated TypeScript types
- use those generated types in apps built with `contentful.js` v10+
- optionally add JSDoc, type guards, and response aliases
### When To Use It
- you keep Contentful schema in source control and want generated app types
- you use `contentful.js` in TypeScript and want typed entries based on your real model
- you want type generation in CI from either exports or live space data
Further reading: if you want broader context on typing Contentful projects with TypeScript, see Contentful’s guide to [TypeScript and Contentful](https://www.contentful.com/blog/contentful-typescript/).
## CLI Usage
```text
cf-content-types-generator [FILE]
```
Common tasks:
- generate from a local export JSON file: `cf-content-types-generator ./contentful-export.json -o src/@types/generated`
- generate by fetching live data: `cf-content-types-generator -s -t -e -o src/@types/generated`
- add optional helpers: `cf-content-types-generator ./contentful-export.json -o src/@types/generated --jsdoc --typeguard --response`
Key flags:
- `-o, --out` output directory
- `-p, --preserve` preserve existing output folder
- `-d, --jsdoc` add JSDoc comments
- `-g, --typeguard` add modern type guards
- `-r, --response` add response aliases
- `-s, --spaceId` Contentful space id
- `-t, --token` Contentful management token
- `-e, --environment` Contentful environment
- `-a, --host` Management API host
- `--proxy` proxy URL in HTTP auth format
- `--rawProxy` pass proxy config to Axios directly
Removed in v3.x:
- `--v10`
- `--localized`
Both now error with explicit migration hints.
## Optional Renderers
All examples below use the same generated base type:
```ts
export interface TypeAnimalFields {
breed?: EntryFieldTypes.Symbol;
}
export type TypeAnimalSkeleton = EntrySkeletonType;
export type TypeAnimal<
Modifiers extends ChainModifiers,
Locales extends LocaleCode = LocaleCode,
> = Entry;
```
### `-d, --jsdoc`
Adds generated comments to fields, skeletons, and entries.
```diff
/**
* Fields type definition for content type 'TypeAnimal'
* @name TypeAnimalFields
* @type {TypeAnimalFields}
* @memberof TypeAnimal
*/
export interface TypeAnimalFields {
/**
* Field type definition for field 'breed' (Breed)
* @name Breed
* @localized false
*/
breed?: EntryFieldTypes.Symbol;
}
```
### `-g, --typeguard`
Adds a runtime predicate for the generated entry type.
```ts
export function isTypeAnimal(
entry: Entry,
): entry is TypeAnimal {
return entry.sys.contentType.sys.id === 'animal';
}
```
### `-r, --response`
Adds aliases for common response modifier combinations.
```ts
export type TypeAnimalWithoutLinkResolutionResponse = TypeAnimal<'WITHOUT_LINK_RESOLUTION'>;
export type TypeAnimalWithAllLocalesResponse = TypeAnimal<
'WITH_ALL_LOCALES',
Locales
>;
```
These aliases are convenience aliases for the top-level entry type only. Linked entries still stay typed as `Entry`, which is expected and matches `contentful.js`.
### Link Resolution Tips
If you want resolved assets and entries without unresolved-link unions, call the client with the matching chain modifier:
```ts
const articles = await client.withoutUnresolvableLinks.getEntries({
content_type: 'blogArticle',
include: 4,
});
articles.items[0]?.fields.image?.fields.file?.url;
articles.items[0]?.fields.category?.[0]?.fields;
```
If a reference field allows multiple content types, generate type guards with `--typeguard` and narrow linked entries where you use them.
## Programmatic Usage
```ts
import {
CFDefinitionsBuilder,
ContentTypeRenderer,
ResponseTypeRenderer,
TypeGuardRenderer,
} from 'cf-content-types-generator';
const builder = new CFDefinitionsBuilder([
new ContentTypeRenderer(),
new TypeGuardRenderer(),
new ResponseTypeRenderer(),
]);
```
If you want custom output, extend `BaseContentTypeRenderer` or implement the `Renderer` interface.
## Input
This tool accepts either:
- a local JSON file in the exact shape produced by `contentful space export`
- or enough CLI credentials for the generator to fetch equivalent model data live
Typical export command:
```bash
contentful space export --config ./export-config.json
```
If you pass a local file, that exported JSON shape is the exact shape this tool expects.
When you fetch the model remotely, this tool intentionally skips entry data and only reads schema data. A log line about skipping content entries is expected and does not mean generation is incomplete.
At minimum, this generator needs a JSON object with a `contentTypes` field. A full `contentful space export` dump usually also contains keys such as `entries`, `assets`, `locales`, `roles`, `webhooks`, and `editorInterfaces`, but this generator mainly reads `contentTypes` and `editorInterfaces`.
Example shape:
```json
{
"contentTypes": [
{
"sys": {
"id": "animal",
"type": "ContentType"
},
"name": "Animal",
"fields": [
{
"id": "breed",
"type": "Symbol",
"required": false,
"localized": false,
"omitted": false,
"disabled": false,
"validations": []
}
]
}
]
}
```
## Migration From 2.x To 3.x
`3.x` removes all pre-v10 output behavior. If you are upgrading from `2.x`, use this migration path:
1. Remove `--v10` from CLI usage.
2. Remove `--localized`; no replacement needed.
3. Rename programmatic imports:
`V10ContentTypeRenderer` -> `ContentTypeRenderer`
`V10TypeGuardRenderer` -> `TypeGuardRenderer`
`createV10Context()` -> `createContext()`
4. Regenerate all generated types.
5. Update downstream code that still assumes classic `Entry` output.
CLI before:
```bash
cf-content-types-generator ./contentful-export.json -o src/@types/generated --v10 --response
```
CLI after:
```bash
cf-content-types-generator ./contentful-export.json -o src/@types/generated --response
```
Programmatic before:
```ts
import {
CFDefinitionsBuilder,
V10ContentTypeRenderer,
V10TypeGuardRenderer,
} from 'cf-content-types-generator';
const builder = new CFDefinitionsBuilder([
new V10ContentTypeRenderer(),
new V10TypeGuardRenderer(),
]);
```
Programmatic after:
```ts
import {
CFDefinitionsBuilder,
ContentTypeRenderer,
TypeGuardRenderer,
} from 'cf-content-types-generator';
const builder = new CFDefinitionsBuilder([new ContentTypeRenderer(), new TypeGuardRenderer()]);
```
If downstream code still expects classic output, regenerate and adapt those types in the same change.
## Development
```bash
pnpm test
pnpm build
```
Related app: [cf-content-types-generator-app](https://github.com/marcolink/cf-content-types-generator-app)