@stackbit/types
Version:
Types for Stackbit config and Content Source Interface
197 lines (178 loc) • 6.46 kB
text/typescript
/**
* Stackbit Model Types
*/
import type {
Field,
FieldExtension,
FieldGroupItem,
DocumentPreview,
DocumentFieldPreview,
PreviewFields,
ClientField
} from './model-fields';
import { ModelPermissions, ModelPermissionsFunction } from './content-permissions';
import type { Document } from './content-source-document';
import {
CustomActionClientModel,
CustomActionDocument,
CustomActionModel,
CustomActionModelObject,
CustomActionObjectModel
} from './custom-actions';
export type Model<ModelContext = unknown> =
| ObjectModel<ModelContext>
| DataModel<ModelContext>
| PageModel<ModelContext>
| ConfigModel<ModelContext>;
export type ModelWithSource<ModelType extends Model = Model> = ModelType & { srcType: string; srcProjectId: string };
export type ClientModel = ObjectClientModel | DataClientModel | PageClientModel | ConfigClientModel;
export type NamelessModelMap = Record<string, NamelessModel>;
export type NamelessModel = DistributeNamelessModels<Model>;
export type DistributeNamelessModels<Type extends Model> = Type extends Model ? Omit<Type, 'name'> : never;
// Convert all models to have all their properties to be optional except the 'name', and add 'srcType' and 'srcProjectId' properties
// prettier-ignore
export type DistributeModelExtensions<Type extends Model> =
Type extends Model
? Partial<Omit<Type, 'name' | 'fields'>>
& { name: string; fields?: FieldExtension[] }
& { srcType?: string; srcProjectId?: string; }
: never;
export type ModelExtension = DistributeModelExtensions<Model>;
export interface ModelCommonFields<ModelContext = unknown> {
/**
* The name of the model, must be unique.
* When extending content source models using the {@link Config.modelExtensions}
* property, set it to the unique name or the unique ID of the model as it
* appear in the CMS.
**/
name: string;
/** The label of the model. If not specified, the name will be title cased. */
label?: string;
description?: string;
thumbnail?: string;
/** @deprecated */
extends?: string | string[];
readOnly?: boolean;
labelField?: string;
/** @deprecated */
variantField?: string;
groups?: string[];
fieldGroups?: FieldGroupItem[];
fields?: Field[];
context?: ModelContext;
hidden?: boolean;
permissions?: ModelPermissionsFunction | ModelPermissions;
}
export interface ModelMatchFields {
singleInstance?: boolean;
file?: string;
folder?: string;
match?: string | string[];
exclude?: string | string[];
}
export interface ObjectModel<ModelContext = unknown> extends ModelCommonFields<ModelContext> {
type: 'object';
preview?: DocumentFieldPreview;
actions?: (CustomActionObjectModel | CustomActionModelObject)[];
}
export type ObjectClientModel = Omit<ObjectModel, 'context' | 'preview' | 'actions' | 'fields' | 'permissions'> & {
preview?: PreviewFields;
actions?: CustomActionClientModel<CustomActionObjectModel | CustomActionModelObject>[];
fields: ClientField[];
permissions?: ModelPermissions;
};
/** @deprecated */
export interface ConfigModel<ModelContext = unknown> extends ModelCommonFields<ModelContext>, ModelLocalized {
type: 'config';
file?: string;
}
/** @deprecated */
export type ConfigClientModel = Omit<
ConfigModel,
'context' | 'preview' | 'actions' | 'locale' | 'fields' | 'permissions'
> & {
preview?: PreviewFields;
actions?: CustomActionClientModel<CustomActionObjectModel | CustomActionModelObject>[];
fields: ClientField[];
permissions?: ModelPermissions;
};
export interface PageModel<ModelContext = unknown>
extends ModelCommonFields<ModelContext>,
ModelMatchFields,
ModelLocalized {
type: 'page';
/** @deprecated */
layout?: string;
/**
* @deprecated
* Use the {@link StackbitConfig.sitemap} function to define the relations
* between documents representing website pages and their URL.
*/
urlPath?: string;
/** The filePath property should be used with git-cms models only. */
filePath?: string | DocumentFilePathFunction;
/**
* By default, the markdown content below the frontmatter in .md files will
* be exposed under the 'markdown_content' markdown field.
* If the content of the .md file does not need to be edited,
* set this property to false.
* This property should be used with git-cms models only.
*/
hideContent?: boolean;
preview?: DocumentPreview;
actions?: (CustomActionDocument | CustomActionModel)[];
canDelete?: boolean;
}
export type PageClientModel = Omit<
PageModel,
'context' | 'preview' | 'actions' | 'filePath' | 'locale' | 'fields' | 'permissions'
> & {
preview?: PreviewFields;
actions?: CustomActionClientModel<CustomActionDocument | CustomActionModel>[];
filePath?: string;
fields: ClientField[];
permissions?: ModelPermissions;
};
export interface DataModel<ModelContext = unknown>
extends ModelCommonFields<ModelContext>,
ModelMatchFields,
ModelLocalized {
type: 'data';
/** The filePath property should be used with git-cms models only. */
filePath?: string | DocumentFilePathFunction;
preview?: DocumentPreview;
actions?: (CustomActionDocument | CustomActionModel)[];
canDelete?: boolean;
}
export type DataClientModel = Omit<
DataModel,
'context' | 'preview' | 'actions' | 'locale' | 'fields' | 'permissions'
> & {
preview?: PreviewFields;
actions?: CustomActionClientModel<CustomActionDocument | CustomActionModel>[];
fields: ClientField[];
permissions?: ModelPermissions;
};
export interface ModelLocalized {
/**
* Boolean flag indicating if documents belonging to this model are localized.
* If localized is set to true, provide the `locale` function to set the
* document `locale`
*/
localized?: boolean;
/**
* The `locale` function should return the locale for the passed `document`.
*/
locale?: (options: {
document: Document;
/**
* The model of the passed `document`.
*/
model: DataModel | PageModel;
}) => string;
}
export type DocumentFilePathFunction = (options: {
data: Record<string, any>;
model: DataModel | PageModel;
currentLocale?: string;
}) => Promise<string>;