@stackbit/types
Version:
Types for Stackbit config and Content Source Interface
905 lines (847 loc) • 37.2 kB
text/typescript
import type { ChildProcessWithoutNullStreams } from 'child_process';
import type { Model } from './models';
import type { FieldPath } from './model-fields';
import type { Logger } from './logger';
import type { ScheduledAction, ScheduledActionActionType } from './content-source-scheduled-action';
import type { Document, Asset, TypeDocument, TypeAsset, DocumentStatus } from './content-source-document';
import type { UpdateOperation, UpdateOperationField } from './content-source-operation';
import type { DocumentVersion, DocumentVersionWithDocument } from './content-source-document-versions';
import type { PluginRef } from './content-engine';
/**
* A class implementing the `ContentSourceInterface` allows Stackbit to
* communicate with the underlying content source.
*
* The instantiation of the content source is done inside the stackbit.config.ts
* file. The content source may define arbitrary construction options needed to
* connect and communicate with the underlying content source. For example,
* construction options may include project ID, API keys, etc.
*
* The Content Source Interface has four generic types:
* - `SchemaContext`: A generic type the content source instance may use to
* store custom data in the {@link Schema.context} property. Stackbit will
* cache the custom data with the rest of the {@link Schema} data. The cached
* {@link Schema} can be retrieved using the {@link InitOptions.cache.getSchema}
* method provided to the {@link init} method.
* - `UserContext`: A generic type defining user-specific context properties
* like a username, an email address and an OAuth accessToken. To use the
* `UserContext`, it is required to create an OAuth integration between
* Stackbit and the underlying content. Please contact Stackbit support for
* more info.
* - `DocumentContext`: A generic type the content source instance may use to
* store custom data in the {@link Document.context} property. Stackbit will
* cache the custom data with the rest of the {@link Document} data. The cached
* {@link Document} can be retrieved using the {@link InitOptions.cache.getDocuments}
* and {@link InitOptions.cache.getDocumentById} methods provided to the
* {@link init} method.
* - `AssetContext`: A generic type the content source instance may use to store
* custom data in the {@link Asset.context} property. Stackbit will cache the
* custom data with the rest of the {@link Asset} data. The cached {@link Asset}
* can be retrieved using the {@link InitOptions.cache.getAssets} and
* {@link InitOptions.cache.getAssetById} methods provided to the {@link init}
* method.
*/
export interface ContentSourceInterface<
UserContext = unknown,
SchemaContext = unknown,
DocumentContext = unknown,
AssetContext = unknown,
ModelContext = unknown
> {
/**
* The `getVersion` method should return the {@link Version} specifying
* the ContentSourceInterface version the content source module implements,
* and the version of the content source module, possibly matching the
* version in the `package.json`.
*
* You can use the {@link import('./utils').getVersion} utility method to
* read the content source module version from the package.json and get
* the current content source interface version:
* @example
* async getVersion(): Promise<Version> {
* return getVersion({
* packageJsonPath: path.join(__dirname, '../package.json')
* });
* }
*/
getVersion(): Promise<Version>;
/**
* The `getContentSourceType` method should return the type of the content
* source. The content source type must be unique among other content
* sources used by the same project.
*/
getContentSourceType(): string;
/**
* The `getProjectId` method should return the unique identifier of the
* content source instance. This identified must be unique among other
* content sources instances of the same content source type.
*/
getProjectId(): string;
/**
* @deprecated
*
* The `getProjectEnvironment` method should return a string representing
* additional segmentation of a particular content source instance. This
* might be useful when a content source supports projects with multiple
* environments.
*/
getProjectEnvironment(): string;
/**
* The `getProjectManageUrl` method should return the URL address of the
* underlying content source's web application. Stackbit uses this URL to
* show links to the content source web application.
*/
getProjectManageUrl(): string;
/**
* The `init` method should initialize the content source instance.
*
* This is a good place to create and initialize API clients using the
* options passed to the constructor, fetch and cache meta-data that does
* not frequently change, such as users, locales, and other configuration.
*
* The content source instance should remain stateless and should not store
* models, documents, or assets. After initializing the content source,
* Stackbit will fetch and cache the needed data using the methods like
* {@link getSchema}, {@link getDocuments}, and {@link getAssets}. When
* the content source instance needs to access the cached data, it may call
* functions with matching names passed to this method inside the
* `options.cache` property. This paradigm ensures that Stackbit and the
* content source instance work on the same data.
*
* @param {InitOptions} options
*/
init(options: InitOptions<SchemaContext, DocumentContext, AssetContext, ModelContext>): Promise<void>;
/**
* The `reset` method should reset the internal state, clean up any instance
* variables, and cached meta-data fetched in the `init` method and
* re-fetch it again.
*/
reset(): Promise<void>;
/**
* This function should destroy the content source instance by clearing any
* listeners and observers that might keep the instance from being garbage
* collected.
*
* This function is called when Stackbit reloads the stackbit.config.ts file.
* For example, when the config file is changed. Once the config file is
* reloaded, new instances of content sources are created and initialized.
* And the old instances are destroyed.
*/
destroy(): Promise<void>;
/**
* Stackbit calls the `onWebhook` method when the underlying content
* source calls a previously configured webhook.
*
* The content source module may set up webhooks between the underlying
* content source and Stackbit using the {@link InitOptions.webhookUrl}
* passed to the {@link init} method. When the underlying content source
* calls the webhook, Stackbit passes the webhook request to this method
* with its data and request headers. Webhooks can be used to trigger the
* {@link InitOptions.cache.updateContent}, and the
* {@link InitOptions.cache.invalidateSchema} callbacks passed to the
* {@link init} method.
*
* This method is not called in local development (when
* {@link InitOptions.localDev} is `true`).
* To debug webhooks locally, you need to create a public URL that
* forwards external webhooks to stackbit dev's internal port: `localhost:8090`.
* You can use a tool like 'ngrok' and run `ngrok http 8090` to create a
* public URL that forwards webhooks to stackbit dev. Ngrok will print the
* public URL it created (e.g., https://xyz.ngrok.io). Then use this URL
* when running stackbit dev:
* `stackbit dev --log-level=debug --csi-webhook-url=https://xyz.ngrok.io/_stackbit/onWebhook`
*
* @param data
* @param {any} data.data
* @param {Record<string, string>} data.headers
*/
onWebhook?(data: { data: unknown; headers: Record<string, string> }): void;
/**
* Stackbit calls the `onFilesChange` method when it detects changes in
* the project files. This method is optional and should be used when the
* content source stores its schema or content in files within the project
* repository. Therefore, if your content source relies on files within
* the project repository, you don't need to set up any file-watching
* processes. Stackbit will watch the files for you and call this method
* when the files are changed.
*
* When this method is called, the content source module should check if the
* changed files represent a document or a model and return a matching result.
*
* @param options
* @param {string[]} options.updatedFiles
* A list of updated files. The file paths are relative to the project
* root folder.
*/
onFilesChange?({
updatedFiles
}: {
updatedFiles: string[];
}): Promise<{ invalidateSchema?: boolean; contentChanges?: ContentChanges<DocumentContext, AssetContext> }>;
/**
* Stackbit calls the `startWatchingContentUpdates` method after it has
* initialized the content source instance and loaded its schema, documents
* and assets, and is ready to receive the content and the schema updates.
*
* This method may also be called after calling the
* {@link stopWatchingContentUpdates} and as soon as Stackbit app becomes
* active again.
*
* This method should start watching for content and schema updates using
* any available content synchronization mechanism. For example, polling the
* content source's synchronization API or setting up a server-to-server
* listeners.
*
* When the content source instance detects a change in the content or the
* schema, it should call the `updateContent` or the `invalidateSchema`
* callbacks provided inside the `cache` object to the {@link init} method.
*
* Note: if you use webhooks as your content synchronization mechanism, you
* don't need to implement this method.
*
* Note: The content source module should remain stateless in respect to the
* fetched content and schema. It should not store models, documents, or
* assets. If you need to access models, documents, or assets previously
* returned from `getSchema`, `getDocuments`, or `getAssets` methods, use
* the matching functions provided to the {@link init} method inside the
* `options.cache` property.
*
* @param {object} options
* The 'options' parameter is deprecated, use methods passed to the
* {@link init} method.
*/
startWatchingContentUpdates?(): void;
/**
* Stackbit calls the `stopWatchingContentUpdates` method after Stackbit app
* has not been used for a while.
*
* You can use this method to stop watching for content and schema updates,
* and stop calling the `updateContent` and the `invalidateSchema` callbacks
* provided to the {@link init} method until the
* {@link startWatchingContentUpdates} method is called again.
*
* This method may be useful when the content synchronization mechanism uses
* rapid polling requests that may consume the monthly API request limit of
* a headless CMS.
*
* Note: if you use webhooks as your content synchronization mechanism, you
* don't need to implement this method.
*/
stopWatchingContentUpdates?(): void;
/**
* The `getSchema` method should fetch all the content models from the
* underlying content source and convert them to an array of Stackbit
* [Models]{@link Model}.
*
* Optionally, if the underlying content source supports locales, this
* method may fetch the available locales and convert them to an array of
* Stackbit [Locales]{@link Locale}.
*
* The returned object should be of type {@link Schema} having the
* following interface:
* ```typescript
* interface Schema {
* models: Model[],
* locales?: Locale[]
* }
* ```
*/
getSchema(): Promise<Schema<SchemaContext, ModelContext>>;
/**
* The `getDocuments` method should fetch all the documents from the
* underlying content source and convert them to an array of Stackbit
* [Documents]{@link Document}. You can define the `DocumentContext` generic
* type to set the {@link Document.context} to a custom data that your
* content source may need. Stackbit will cache the documents with the
* context data.
*/
getDocuments(options?: {
syncContext?: unknown;
}): Promise<Document<DocumentContext>[] | { documents: Document<DocumentContext>[]; syncContext?: unknown }>;
/**
* The `getAssets` method should fetch all the assets from the underlying
* content source and convert them to an array Stackbit [Assets]{@link Asset}.
* You can define the `AssetContext` generic type to set the
* {@link Asset.context} to a custom data that your content source may need.
* Stackbit will cache the assets with the context data.
*/
getAssets(options?: {
syncContext?: unknown;
}): Promise<Asset<AssetContext>[] | { assets: Asset<AssetContext>[]; syncContext?: unknown }>;
/**
* The `hasAccess` method should check if the current user has read/write
* access to the content source.
*
* @param {Object} options
* @param {UserContext} [options.userContext]
* User properties provided by the OAuth flow between Stackbit and the
* underlying content source. The type of the `userContext` is defined by
* the `UserContext` generic type. The `userContext` is passed only if
* there is an OAuth integration between Stackbit and the underlying
* content source. Please contact Stackbit support if you want to
* integrate your content source's OAuth flow with Stackbit.
*/
hasAccess(options: {
userContext?: User<UserContext>;
}): Promise<{ hasConnection: boolean; hasPermissions: boolean }>;
/**
* The `createDocument` method should create a document in the underlying
* content source and return the id of the created document.
*
* @param {Object} options
* @param {Record<string, UpdateOperationField>} options.updateOperationFields
* A map of update operation fields by field names.
* @param {Model} options.model
* A model representing the document to be created.
* @param {string} [options.locale]
* A locale id for the document to be created.
* @param {UserContext} [options.userContext]
* User properties provided by the OAuth flow between Stackbit and the
* underlying content source. The type of the `userContext` is defined by
* the `UserContext` generic type. The `userContext` is passed only if
* there is an OAuth integration between Stackbit and the underlying
* content source.
*/
createDocument(options: {
updateOperationFields: Record<string, UpdateOperationField>;
model: Model<ModelContext>;
locale?: string;
defaultLocaleDocumentId?: string;
userContext?: User<UserContext>;
}): Promise<{ documentId: string }>;
/**
* The `updateDocument()` method should update a document in the underlying
* content source and return the updated document as a Stackbit Document.
*
* @param {Object} options
* @param {Document} options.document
* A document to be updated.
* @param {UpdateOperation[]} options.operations
* An array of update operations.
* @param {UserContext} [options.userContext]
* User properties provided by the OAuth flow between Stackbit and the
* underlying content source. The type of the `userContext` is defined by
* the `UserContext` generic type. The `userContext` is passed only if
* there is an OAuth integration between Stackbit and the underlying
* content source.
*/
updateDocument(options: {
document: Document<DocumentContext>;
operations: UpdateOperation[];
userContext?: User<UserContext>;
}): Promise<void>;
/**
* The `deleteDocument` method should delete a document from the underlying
* content source.
*
* @param {Object} options
* @param {Document} options.document
* A document to be deleted.
* @param {UserContext} [options.userContext]
* User properties provided by the OAuth flow between Stackbit and the
* underlying content source. The type of the `userContext` is defined by
* the `UserContext` generic type. The `userContext` is passed only if
* there is an OAuth integration between Stackbit and the underlying
* content source.
*/
deleteDocument(options: { document: Document<DocumentContext>; userContext?: User<UserContext> }): Promise<void>;
/**
* The `archiveDocument` method should archive a document from the underlying
* content source.
*
* @param {Object} options
* @param {Document} options.document
* A document to be archived.
* @param {UserContext} [options.userContext]
* User properties provided by the OAuth flow between Stackbit and the
* underlying content source. The type of the `userContext` is defined by
* the `UserContext` generic type. The `userContext` is passed only if
* there is an OAuth integration between Stackbit and the underlying
* content source.
*/
archiveDocument?(options: { document: Document<DocumentContext>; userContext?: User<UserContext> }): Promise<void>;
/**
* The `unarchiveDocument` method should unarchive a document from the underlying
* content source.
*
* @param {Object} options
* @param {Document} options.document
* A document to be unarchived.
* @param {UserContext} [options.userContext]
* User properties provided by the OAuth flow between Stackbit and the
* underlying content source. The type of the `userContext` is defined by
* the `UserContext` generic type. The `userContext` is passed only if
* there is an OAuth integration between Stackbit and the underlying
* content source.
*/
unarchiveDocument?(options: {
document: Document<DocumentContext>;
userContext?: User<UserContext>;
}): Promise<void>;
/**
* The `getScheduledActions` method should fetch all the scheduled actions (publish | unpublish) from the
* underlying content source and convert them to an array of Stackbit
* [ScheduledAction]{@link ScheduledAction}.
*/
getScheduledActions?(): Promise<ScheduledAction[]>;
/**
* The `createScheduledAction` method should create a scheduled action in the underlying
* content source.
*
* @param {Object} options
* @param {string} options.name Name of the scheduled action
* @param {ScheduledActionActionType} options.action type of Action (publish | unpublish)
* @param {string[]} options.documentIds A list of document ids to schedule
* @param {string} options.executeAt The date to execute the action in ISO format
* @param {UserContext} options.userContext
* User properties provided by the OAuth flow between Stackbit and the
* underlying content source. The type of the `userContext` is defined by
* the `UserContext` generic type. The `userContext` is passed only if
* there is an OAuth integration between Stackbit and the underlying
* content source.
*/
createScheduledAction?(options: {
name: string;
action: ScheduledActionActionType;
documentIds: string[];
executeAt: string;
userContext?: User<UserContext>;
}): Promise<{ newScheduledActionId: string }>;
/**
* The `cancelScheduledAction` method should delete a scheduled action from the underlying
* content source.
*
* @param {Object} options
* @param {string} options.scheduledActionId The id of the schedule to cancel
* @param {UserContext} [options.userContext]
* User properties provided by the OAuth flow between Stackbit and the
* underlying content source. The type of the `userContext` is defined by
* the `UserContext` generic type. The `userContext` is passed only if
* there is an OAuth integration between Stackbit and the underlying
* content source.
*/
cancelScheduledAction?(options: {
scheduledActionId: string;
userContext?: User<UserContext>;
}): Promise<{ cancelledScheduledActionId: string }>;
/**
* The `updateScheduledAction` method should edit a scheduled action in the underlying
* content source.
*
* @param {Object} options
* @param {string} options.scheduledActionId The id of the schedule to edit
* @param {string} [options.name] Name of the scheduled action
* @param {string[]} [options.documentIds] A list of document ids to schedule
* @param {string} [options.executeAt] The date to execute the action in ISO format
* @param {UserContext} [options.userContext]
* User properties provided by the OAuth flow between Stackbit and the
* underlying content source. The type of the `userContext` is defined by
* the `UserContext` generic type. The `userContext` is passed only if
* there is an OAuth integration between Stackbit and the underlying
* content source.
*/
updateScheduledAction?(options: {
scheduledActionId: string;
name?: string;
documentIds?: string[];
executeAt?: string;
userContext?: User<UserContext>;
}): Promise<{ updatedScheduledActionId: string }>;
/**
* The `uploadAsset` method should upload an asset to the underlying
* content source and return the upload asset as a Stackbit Asset.
*
* @param {Object} options
* @param {string} options.fileName
* The fileName of the asset.
* @param {string} options.mimeType
* The mimeType of the asset.
* @param {string} [options.locale]
* The locale id for the asset.
* @param {UserContext} [options.userContext]
* User properties provided by the OAuth flow between Stackbit and the
* underlying content source. The type of the `userContext` is defined by
* the `UserContext` generic type. The `userContext` is passed only if
* there is an OAuth integration between Stackbit and the underlying
* content source.
*/
uploadAsset(options: {
url?: string;
base64?: string;
fileName: string;
mimeType: string;
locale?: string;
userContext?: User<UserContext>;
}): Promise<Asset<AssetContext>>;
/**
* The `updateAsset()` method should update an asset in the underlying
* content source
*
* @param {Object} options
* @param {Asset} options.asset
* An asset to be updated.
* @param {UpdateOperation[]} options.operations
* An array of update operations.
* @param {UserContext} [options.userContext]
* User properties provided by the OAuth flow between Stackbit and the
* underlying content source. The type of the `userContext` is defined by
* the `UserContext` generic type. The `userContext` is passed only if
* there is an OAuth integration between Stackbit and the underlying
* content source.
*/
updateAsset?(options: {
asset: Asset<AssetContext>;
operations: UpdateOperation[];
userContext?: User<UserContext>;
}): Promise<void>;
/**
* The `validateDocuments` method should validate documents according to
* the underlying content source validation rules and return an array of
* {@link ValidationError} if the documents do not pass validation.
*/
validateDocuments(options: {
documents: Document<DocumentContext>[];
assets: Asset<AssetContext>[];
locale?: string;
userContext?: User<UserContext>;
}): Promise<{ errors: ValidationError[] }>;
/**
* The `publishDocuments` method should publish documents in the
* underlying content source.
*
* @param {Object} options
* @param {Document[]} options.documents
* The array of documents to be published.
* @param {Asset[]} options.assets
* The array of assets to be published.
* @param {UserContext} [options.userContext]
* User properties provided by the OAuth flow between Stackbit and the
* underlying content source. The type of the `userContext` is defined by
* the `UserContext` generic type. The `userContext` is passed only if
* there is an OAuth integration between Stackbit and the underlying
* content source.
*/
publishDocuments(options: {
documents: Document<DocumentContext>[];
assets: Asset<AssetContext>[];
userContext?: User<UserContext>;
}): Promise<void>;
/**
* The `unpublishDocuments` method should unpublish documents in the
* underlying content source.
*
* @param {Object} options
* @param {Document[]} options.documents
* The array of documents to be unpublished.
* @param {Asset[]} options.assets
* The array of assets to be unpublished.
* @param {UserContext} [options.userContext]
* User properties provided by the OAuth flow between Stackbit and the
* underlying content source. The type of the `userContext` is defined by
* the `UserContext` generic type. The `userContext` is passed only if
* there is an OAuth integration between Stackbit and the underlying
* content source.
*/
unpublishDocuments?(options: {
documents: Document<DocumentContext>[];
assets: Asset<AssetContext>[];
userContext?: User<UserContext>;
}): Promise<void>;
/**
* Returns a list of plugins to be used by content engine.
*/
getContentEngineConfig?(): ContentEngineConfig;
/**
* Get content versions of the document. Result object might optionally have document with fields
* if CMS can return them in the same request
* @param {Object} options
* @param {string} options.documentId
*/
getDocumentVersions?(options: { documentId: string }): Promise<{ versions: DocumentVersion[] }>;
/**
* Get content version of the document with fields
* @param {Object} options
* @param {string} options.documentId
* @param {string} options.versionId
*/
getDocumentForVersion?(options: {
documentId: string;
versionId: string;
}): Promise<{ version: DocumentVersionWithDocument }>;
}
export type ReturnTypeOfCSIMethod<Method extends keyof ContentSourceInterface> = ReturnType<
NonNullable<ContentSourceInterface[Method]>
>;
export type ParametersOfCSIMethod<Method extends keyof ContentSourceInterface> = Parameters<
NonNullable<ContentSourceInterface[Method]>
>;
/**
* The config for a linked content engine connector
*/
export interface ContentEngineConfig {
/**
* The name of the connector. Used to handle selective syncing
*/
connector: string;
/**
* Plugins to add to content engine. Ensure these are also dependencies of the package.
* @see https://github.com/netlify/content-engine#public-content-engine-api
*/
plugins: PluginRef[] | PluginRef;
}
export interface Version {
/**
* The ContentSourceInterface version the content source module implements.
* Use the `getInterfaceVersion()` utility method to get the current version.
*/
interfaceVersion: string;
/**
* The current version of the Content Source module. This should be the
* version stored in the package.json of the content source.
*/
contentSourceVersion: string;
}
export interface InitOptions<
SchemaContext = unknown,
DocumentContext = unknown,
AssetContext = unknown,
ModelContext = unknown
> {
/**
* @type Logger
* A logger object used to log messages to the terminal console. Messages
* logged with this logger will be shown in the console when running
* `stackbit dev`. Use the `--log-level` argument to configure the log
* levels printed by `stackbit dev`.
*
* Use this logger to debug the content source when working locally with
* `stackbit dev`
*
* @example:
* stackbit dev --log-level debug
**/
logger: Logger;
/**
* @type Logger
* A logger object used to log messages to the "log" panel in the Stackbit
* client application.
*
* Use this logger to print important messages to the user using the
* Stackbit UI.
*/
userLogger: Logger;
/**
* @type boolean
* A boolean flag indicating if the content source is running in local
* development mode using the `stackbit dev` command (true), or if it is
* running in Stackbit cloud project (false).
*/
localDev: boolean;
stackbitConfigFilePath: string;
userCommandSpawner?: UserCommandSpawner;
/**
* @type string
* A string representing a Stackbit webhook URL that the content source
* module may use to create webhooks between the content source and Stackbit.
*
* Webhooks need to be set once. Use predefined webhook names to check if
* the webhook was already created. This parameter is empty when `localDev`
* is `true`.
*/
webhookUrl?: string;
devAppRestartNeeded?: () => void;
/**
* @type Cache
* A Stackbit managed cache for documents, assets and models returned by the
* content source. Use cache methods to get, update, delete and invalidate
* data stored in the cache.
*/
cache: Cache<SchemaContext, DocumentContext, AssetContext, ModelContext>;
git: GitServiceInterface;
runCommand: CommandRunner;
}
export type UserSSOProfile = {
idpId: string;
firstName?: string;
lastName?: string;
emails?: {
value: string;
type?: string;
primary?: boolean;
}[];
attributes?: Record<string, any>;
};
export type User<UserContext = unknown> = {
name: string;
email: string;
role?: string;
sso?: UserSSOProfile;
} & UserContext;
export type UserCommandSpawner = (options: SpawnUserCommandOptions) => ChildProcessWithoutNullStreams;
export interface SpawnUserCommandOptions {
command: string;
args?: string[];
cwd?: string;
env?: NodeJS.ProcessEnv;
}
export type RunResult = { stdout: string; stderr: string; exitCode?: number; err?: Error };
export type CommandRunner = (
command: string,
args?: string[],
options?: { cwd?: string; shell?: boolean; env?: NodeJS.ProcessEnv; logger?: Logger }
) => Promise<RunResult>;
export interface GitFileCommitDescriptor {
filePath: string;
description: string;
}
export interface GitAuthor {
name?: string;
email: string;
}
export interface GitCommitLogEntry {
author: string;
timestamp: Date;
commitHash: string;
changes: {
status: Extract<DocumentStatus, 'modified' | 'added' | 'deleted'>;
filePath: string;
fromFilePath?: string;
}[];
}
// Git service listeners
export type GitServicePullListener = (options: { branch: string; updatedFiles: string[] }) => Promise<void>;
export type GitServicePushListener = () => Promise<void>;
export type GitFileStatus = {
filePath: string;
status: 'modified' | 'added' | 'deleted';
};
export interface GitServiceInterface {
getRepoUrl(): string;
getRepoBranch(): string;
getRepoPublishBranch(): string;
getRepoDir(): string;
setRepoUrl(repoUrl: string): void;
setRepoBranch(repoBranch: string): void;
setRepoPublishBranch(publishBranch: string): void;
commitAndPush: (author: GitAuthor, files: GitFileCommitDescriptor[]) => Promise<void>;
publish(author: GitAuthor, filePaths?: string[]): Promise<void>;
commitLog(): Promise<GitCommitLogEntry[]>;
diff(): Promise<string[]>;
addPullListener(listener: GitServicePullListener): void;
removePullListener(listener: GitServicePullListener): void;
addPushListener(listener: GitServicePushListener): void;
removePushListener(listener: GitServicePushListener): void;
diffFilesWithFetchHead(): Promise<GitFileStatus[]>;
pullFilesFromFetchHead(files: GitFileStatus[]): Promise<void>;
createShadowRepo(): Promise<void>;
}
/**
* A Stackbit managed cache for documents, assets and models returned by the
* content source module. Use cache methods to get, update, delete and invalidate
* data stored in the cache.
*/
export interface Cache<
SchemaContext = unknown,
DocumentContext = unknown,
AssetContext = unknown,
ModelContext = unknown
> {
/**
* Returns the documents that were originally returned from the content
* source's [getDocuments]{@link ContentSourceInterface#getDocuments} method.
* @return Document[]
*/
getDocuments: () => Document<DocumentContext>[];
/**
* Returns the assets that were originally returned from the content
* source's [getAssets]{@link ContentSourceInterface#getAssets} method.
* @return Asset[]
*/
getAssets: () => Asset<AssetContext>[];
/**
* Returns the scheduled actions that were originally returned from the content
* source's [getScheduledActions]{@link ContentSourceInterface#getScheduledActions} method.
* @return ScheduledAction[]
*/
getScheduledActions: () => ScheduledAction[];
/**
* Returns the scheduled actions that contain the passed documentId that were originally returned from the content
* source's [getScheduledActions]{@link ContentSourceInterface#getScheduledActions} method.
* @param {string} documentId filter only scheduled for a specific document
* @return ScheduledAction[]
*/
getScheduledActionsForDocumentId: (documentId: string) => ScheduledAction[];
/**
* Returns the schema that were originally returned from the content
* source's [getSchema]{@link ContentSourceInterface#getSchema} method.
*
* @return Schema
*/
getSchema: () => Schema<SchemaContext, ModelContext>;
/**
* Returns a document by [Document.id]{@link Document.id}.
* @param options
* @param {string} options.documentId
* @return Document | undefined
*/
getDocumentById: (documentId: string) => Document<DocumentContext> | undefined;
/**
* Returns an asset by [Asset.id]{@link Asset.id}.
* @param options
* @param {string} options.assetId
* @return Asset | undefined
*/
getAssetById: (assetId: string) => Asset<AssetContext> | undefined;
/**
* Returns a model by [Model.name]{@link Model.name}.
* @param {string} modelName
* @return Model | undefined
*/
getModelByName: (modelName: string) => Model<ModelContext> | undefined;
getSyncContext: () => {
documentsSyncContext?: unknown;
assetsSyncContext?: unknown;
};
clearSyncContext: (options?: {
clearDocumentsSyncContext?: boolean;
clearAssetsSyncContext?: boolean;
}) => Promise<void>;
requestSync: (options?: { clearDocumentsSyncContext?: boolean; clearAssetsSyncContext?: boolean }) => Promise<void>;
updateContent: (contentChanges: ContentChanges<DocumentContext, AssetContext>) => Promise<void>;
invalidateSchema: () => Promise<void>;
/** Experimental, local-dev mode only, allows getting arbitrary key-value from file-based cache */
get: (key: string) => Promise<unknown>;
/** Experimental, local-dev mode only, allows setting arbitrary key-value into file-based cache */
set: (key: string, value: unknown) => Promise<void>;
/** Experimental, local-dev mode only, allows removing arbitrary key-value file-based cache */
remove: (key: string) => Promise<void>;
}
export interface ContentChanges<DocumentContext = unknown, AssetContext = unknown> {
documents?: Document<DocumentContext>[];
assets?: Asset<AssetContext>[];
scheduledActions?: ScheduledAction[];
deletedDocumentIds?: string[];
deletedAssetIds?: string[];
deletedScheduledActionIds?: string[];
}
// backward compatibility
export type ContentChangeEvent<DocumentContext = unknown, AssetContext = unknown> = Required<
ContentChanges<DocumentContext, AssetContext>
>;
export interface Schema<SchemaContext = unknown, ModelContext = unknown> {
models: Model<ModelContext>[];
locales?: Locale[];
context: SchemaContext;
}
export type SchemaWithSource = Schema & { srcType: string; srcProjectId: string };
export type ModelMap = Record<string, Model>;
export interface Locale {
code: string;
default?: boolean;
}
export type ValidationError = {
message: string;
objectType: TypeDocument | TypeAsset;
objectId: string;
fieldPath: FieldPath;
isUniqueValidation?: boolean;
};