UNPKG

@datocms/cma-client

Version:
330 lines (329 loc) 14.8 kB
import type * as ApiTypes from '../generated/ApiTypes'; import type * as RawApiTypes from '../generated/RawApiTypes'; interface GenericClient { itemTypes: { rawList(): Promise<{ data: RawApiTypes.ItemType[]; }>; }; fields: { rawList(itemTypeId: string): Promise<{ data: RawApiTypes.Field[]; }>; rawReferencing(itemTypeId: string): Promise<{ data: RawApiTypes.Field[]; }>; }; fieldsets: { rawList(itemTypeId: string): Promise<{ data: RawApiTypes.Fieldset[]; }>; }; plugins: { rawList(): Promise<{ data: RawApiTypes.Plugin[]; }>; }; site: { rawFind(params: { include: string; }): Promise<{ data: any; included?: Array<RawApiTypes.ItemType | RawApiTypes.Field | any>; }>; }; } /** * Repository for DatoCMS schema entities including item types, fields, and plugins. * Provides caching and efficient lookup functionality for schema-related operations. * * ## Purpose * * SchemaRepository is designed to solve the performance problem of repeatedly fetching * the same schema information during complex operations that traverse nested blocks, * structured text, or modular content. It acts as an in-memory cache/memoization layer * for schema entities to avoid redundant API calls. * * ## What it's for: * * - **Caching schema entities**: Automatically caches item types, fields, fieldsets, * and plugins after the first API request, returning cached results on subsequent calls * - **Complex traversal operations**: Essential when using utilities like * `mapBlocksInNonLocalizedFieldValue()` that need to repeatedly lookup block models and fields * while traversing nested content structures * - **Bulk operations**: Ideal for scripts that process multiple records of different * types and need efficient access to schema information * - **Read-heavy workflows**: Perfect for scenarios where you need to repeatedly access * the same schema information without making redundant API calls * * ## What it's NOT for: * * - **Schema modification**: Do NOT use SchemaRepository if your script modifies models, * fields, fieldsets, or plugins, as the cache will become stale * - **Record/content operations**: This is only for schema entities, not for records, * uploads, or other content * - **Long-running applications**: The cache has no expiration or invalidation mechanism, * so it's not suitable for applications that need fresh schema data over time * - **Concurrent schema changes**: No protection against cache inconsistency if other * processes modify the schema while your script runs * * ## Usage Pattern * * ```typescript * const schemaRepository = new SchemaRepository(client); * * // These calls will hit the API and cache the results * const models = await schemaRepository.getAllModels(); * const blogPost = await schemaRepository.getItemTypeByApiKey('blog_post'); * * // These subsequent calls will return cached results (no API calls) * const sameModels = await schemaRepository.getAllModels(); * const sameBlogPost = await schemaRepository.getItemTypeByApiKey('blog_post'); * * // Pass the repository to utilities that need schema information * await mapBlocksInNonLocalizedFieldValue(schemaRepository, record, (block) => { * // The utility will use the cached schema data internally * }); * ``` * * ## Performance Benefits * * Without SchemaRepository, a script processing structured text with nested blocks * might make the same `client.itemTypes.list()` or `client.fields.list()` calls * dozens of times. SchemaRepository ensures each unique schema request is made only once. * * ## Best Practices * * - Use SchemaRepository consistently throughout your script — if you need it for one * utility call, use it for all schema operations to maximize cache efficiency * - Create one instance per script execution, not per operation * - Only use when you have read-only access to schema entities * - Consider using optimistic locking for any record updates to handle potential * version conflicts when working with cached schema information */ export declare class SchemaRepository { private client; private itemTypesPromise; private itemTypesByApiKey; private itemTypesById; private fieldsByItemType; private fieldsetsByItemType; private pluginsPromise; private pluginsById; private pluginsByPackageName; private prefetchPromise; /** * Creates a new SchemaRepository instance. * @param client - The DatoCMS client instance */ constructor(client: GenericClient); /** * Loads and caches all item types from the DatoCMS API. * This method is called lazily and caches the result for subsequent calls. * @returns Promise that resolves to an array of item types */ private loadItemTypes; /** * Gets all item types from the DatoCMS project. * @returns Promise that resolves to an array of all item types */ getAllItemTypes(): Promise<ApiTypes.ItemType[]>; /** * Gets all item types from the DatoCMS project. * @returns Promise that resolves to an array of all item types */ getAllRawItemTypes(): Promise<RawApiTypes.ItemType[]>; /** * Gets all item types that are models (not modular blocks). * @returns Promise that resolves to an array of model item types */ getAllModels(): Promise<ApiTypes.ItemType[]>; /** * Gets all item types that are models (not modular blocks). * @returns Promise that resolves to an array of model item types */ getAllRawModels(): Promise<RawApiTypes.ItemType[]>; /** * Gets all item types that are modular blocks. * @returns Promise that resolves to an array of block model item types */ getAllBlockModels(): Promise<ApiTypes.ItemType[]>; /** * Gets all item types that are modular blocks. * @returns Promise that resolves to an array of block model item types */ getAllRawBlockModels(): Promise<RawApiTypes.ItemType[]>; /** * Gets an item type by its API key. * @param apiKey - The API key of the item type to retrieve * @returns Promise that resolves to the item type * @throws Error if the item type is not found */ getItemTypeByApiKey(apiKey: string): Promise<ApiTypes.ItemType>; /** * Gets an item type by its API key. * @param apiKey - The API key of the item type to retrieve * @returns Promise that resolves to the item type * @throws Error if the item type is not found */ getRawItemTypeByApiKey(apiKey: string): Promise<RawApiTypes.ItemType>; /** * Gets an item type by its ID. * @param id - The ID of the item type to retrieve * @returns Promise that resolves to the item type * @throws Error if the item type is not found */ getItemTypeById(id: string): Promise<ApiTypes.ItemType>; /** * Gets an item type by its ID. * @param id - The ID of the item type to retrieve * @returns Promise that resolves to the item type * @throws Error if the item type is not found */ getRawItemTypeById(id: string): Promise<RawApiTypes.ItemType>; /** * Gets all fields for a given item type. * Fields are cached after the first request for performance. * @param itemType - The item type to get fields for * @returns Promise that resolves to an array of fields */ getItemTypeFields(itemType: ApiTypes.ItemType | RawApiTypes.ItemType): Promise<ApiTypes.Field[]>; /** * Gets all fields for a given item type. * Fields are cached after the first request for performance. * @param itemType - The item type to get fields for * @returns Promise that resolves to an array of fields */ getRawItemTypeFields(itemType: ApiTypes.ItemType | RawApiTypes.ItemType): Promise<RawApiTypes.Field[]>; /** * Gets all fieldsets for a given item type. * Fieldsets are cached after the first request for performance. * @param itemType - The item type to get fieldsets for * @returns Promise that resolves to an array of fieldsets */ getItemTypeFieldsets(itemType: ApiTypes.ItemType | RawApiTypes.ItemType): Promise<ApiTypes.Fieldset[]>; /** * Gets all fieldsets for a given item type. * Fieldsets are cached after the first request for performance. * @param itemType - The item type to get fieldsets for * @returns Promise that resolves to an array of fieldsets */ getRawItemTypeFieldsets(itemType: ApiTypes.ItemType | RawApiTypes.ItemType): Promise<RawApiTypes.Fieldset[]>; /** * Loads and caches all plugins from the DatoCMS API. * This method is called lazily and caches the result for subsequent calls. * @returns Promise that resolves to an array of plugins */ private loadPlugins; /** * Gets all plugins from the DatoCMS project. * @returns Promise that resolves to an array of all plugins */ getAllPlugins(): Promise<ApiTypes.Plugin[]>; /** * Gets all plugins from the DatoCMS project. * @returns Promise that resolves to an array of all plugins */ getAllRawPlugins(): Promise<RawApiTypes.Plugin[]>; /** * Gets a plugin by its ID. * @param id - The ID of the plugin to retrieve * @returns Promise that resolves to the plugin * @throws Error if the plugin is not found */ getPluginById(id: string): Promise<ApiTypes.Plugin>; /** * Gets a plugin by its ID. * @param id - The ID of the plugin to retrieve * @returns Promise that resolves to the plugin * @throws Error if the plugin is not found */ getRawPluginById(id: string): Promise<RawApiTypes.Plugin>; /** * Gets a plugin by its package name. * @param packageName - The package name of the plugin to retrieve * @returns Promise that resolves to the plugin * @throws Error if the plugin is not found */ getPluginByPackageName(packageName: string): Promise<ApiTypes.Plugin>; /** * Gets a plugin by its package name. * @param packageName - The package name of the plugin to retrieve * @returns Promise that resolves to the plugin * @throws Error if the plugin is not found */ getRawPluginByPackageName(packageName: string): Promise<RawApiTypes.Plugin>; /** * Prefetches all models and their fields in a single optimized API call. * This method populates the internal caches for both item types and fields, * making subsequent lookups very fast without additional API calls. * * This is more efficient than lazy loading when you know you'll need access * to multiple models and fields, as it reduces the number of API requests * from potentially dozens down to just one. * * @returns Promise that resolves when all data has been fetched and cached */ prefetchAllModelsAndFields(): Promise<void>; /** * Gets all models that directly or indirectly embed the given block models. * This method recursively traverses the schema to find all models that reference * the provided blocks, either directly through block fields or indirectly through * other block models that reference them. * * @param blocks - Array of block models to find references to * @returns Promise that resolves to array of models that embed these blocks */ getRawModelsEmbeddingBlocks(blocks: Array<ApiTypes.ItemType | RawApiTypes.ItemType>): Promise<Array<RawApiTypes.ItemType>>; /** * Gets all models that directly or indirectly embed the given block models. * This method recursively traverses the schema to find all models that reference * the provided blocks, either directly through block fields or indirectly through * other block models that reference them. * * @param blocks - Array of block models to find references to * @returns Promise that resolves to array of models that embed these blocks */ getModelsEmbeddingBlocks(blocks: Array<ApiTypes.ItemType | RawApiTypes.ItemType>): Promise<Array<ApiTypes.ItemType>>; /** * Gets all block models that are directly or indirectly nested within the given item types. * This method recursively traverses the schema to find all blocks that are nested * within the provided item types, either directly through block fields or indirectly through * other nested block models. * * @param itemTypes - Array of item types to find nested blocks for * @returns Promise that resolves to array of all block models nested in these item types */ getRawNestedBlocks(itemTypes: Array<ApiTypes.ItemType | RawApiTypes.ItemType>): Promise<Array<RawApiTypes.ItemType>>; /** * Gets all block models that are directly or indirectly nested within the given item types. * This method recursively traverses the schema to find all blocks that are nested * within the provided item types, either directly through block fields or indirectly through * other nested block models. * * @param itemTypes - Array of item types to find nested blocks for * @returns Promise that resolves to array of all block models nested in these item types */ getNestedBlocks(itemTypes: Array<ApiTypes.ItemType | RawApiTypes.ItemType>): Promise<Array<ApiTypes.ItemType>>; /** * Gets all models that are directly or indirectly nested/referenced within the given item types. * This method recursively traverses the schema to find all models that are referenced * by the provided item types through link fields, either directly or indirectly through * other referenced blocks. * * @param itemTypes - Array of item types to find nested models for * @returns Promise that resolves to array of all models nested in these item types */ getRawNestedModels(itemTypes: Array<ApiTypes.ItemType | RawApiTypes.ItemType>): Promise<Array<RawApiTypes.ItemType>>; /** * Gets all models that are directly or indirectly nested/referenced within the given item types. * This method recursively traverses the schema to find all models that are referenced * by the provided item types through link fields, either directly or indirectly through * other referenced blocks. * * @param itemTypes - Array of item types to find nested models for * @returns Promise that resolves to array of all models nested in these item types */ getNestedModels(itemTypes: Array<ApiTypes.ItemType | RawApiTypes.ItemType>): Promise<Array<ApiTypes.ItemType>>; } export {};