### Install @datocms/rest-api-reference Source: https://github.com/datocms/js-rest-api-clients/blob/main/packages/rest-api-reference/README.md Install the package using npm. ```bash npm install @datocms/rest-api-reference ``` -------------------------------- ### Install Dependencies and Bootstrap Source: https://github.com/datocms/js-rest-api-clients/blob/main/README.md Run these commands after cloning the repository to install project dependencies and bootstrap the monorepo. ```bash npm install lerna bootstrap ``` -------------------------------- ### Build Project Source: https://github.com/datocms/js-rest-api-clients/blob/main/README.md Execute this command to build the project after installing dependencies or making changes. ```bash npm run build ``` -------------------------------- ### Install Schema Types Generator Source: https://github.com/datocms/js-rest-api-clients/blob/main/packages/cma-schema-types-generator/README.md Install the package using npm. `@datocms/cma-client` is a peer dependency. ```bash npm install @datocms/cma-schema-types-generator ``` -------------------------------- ### Install CMA Client Analysis Tools Source: https://github.com/datocms/js-rest-api-clients/blob/main/packages/cma-client-analysis/README.md Install the necessary packages for CMA client analysis, including the analysis tool itself, the CMA client node package, and the rest API reference. ```bash npm install @datocms/cma-client-analysis @datocms/cma-client-node @datocms/rest-api-reference typescript ``` -------------------------------- ### Example Generated Schema Types Source: https://github.com/datocms/js-rest-api-clients/blob/main/packages/cma-schema-types-generator/README.md Illustrates the output format of `generateSchemaTypes`, including `ItemTypeDefinition` aliases and runtime constants for item types. ```typescript import type { ItemTypeDefinition } from '@datocms/cma-client'; type EnvironmentSettings = { locales: 'en' | 'it'; }; export type BlogPost = ItemTypeDefinition< EnvironmentSettings, '12345', { title: { type: 'string'; localized: true }; content: { type: 'rich_text'; blocks: Hero }; } >; export const BlogPost = { ID: '12345', REF: { type: 'item_type', id: '12345' }, } as const; export type Hero = ItemTypeDefinition; export const Hero = { ID: '67890', REF: { type: 'item_type', id: '67890' }, } as const; export type AnyBlock = Hero; export type AnyModel = BlogPost; export type AnyBlockOrModel = AnyBlock | AnyModel; ``` -------------------------------- ### Install runtime Schema in remote-mcp mainCode Source: https://github.com/datocms/js-rest-api-clients/blob/main/packages/cma-schema-types-generator/PLAN.md Modify the mainCode in updateSnapshot.ts for remote-mcp to include the runtime Schema installation before importing script.mjs. This ensures both type and value sides of Schema are available. ```typescript const mainCode = [ `import { buildClient } from "@datocms/cma-client-node";`, `import * as Schema from "./schema.mjs";`, // NEW `const client = buildClient({ … });`, `Object.assign(globalThis, { client, Schema });`, // include Schema `await import("./script.mjs");`, ].join("\n"); ``` -------------------------------- ### Schema Globals Example Source: https://github.com/datocms/js-rest-api-clients/blob/main/packages/cma-schema-types-generator/PLAN.md Consumers requiring global access to schema types can implement a simple `schema-globals.ts` file to alias the generated module, as the `wrapInGlobalNamespace` option is removed. ```typescript declare global { export import Schema = SchemaModule; } ``` -------------------------------- ### Usage Example: Narrowing Block Types with isBlockOfType Source: https://github.com/datocms/js-rest-api-clients/blob/main/packages/cma-client/README.md Demonstrates how to use the curried and direct forms of `isBlockOfType` to correctly narrow block types in TypeScript, improving type safety when filtering or checking blocks. ```typescript import { isBlockOfType } from '@datocms/cma-client'; // ID of the ImageBlock model, one of several allowed inside Article `content` const IMAGE_BLOCK_ID = 'FJM79jjKRMSVg-fR6k6X2A' as const; const article = await client.items.find(articleId, { nested: true }); // Before: inline === check does not narrow const images = article.content.filter( (b) => b.relationships.item_type.data.id === IMAGE_BLOCK_ID, ); images[0].attributes.upload_id; // ❌ property does not exist on union // After (curried): guard narrows the filter result const images = article.content.filter(isBlockOfType(IMAGE_BLOCK_ID)); images[0].attributes.upload_id; // ✅ narrowed // After (direct): inline narrowing on a single block const first = article.content[0]; if (isBlockOfType(IMAGE_BLOCK_ID, first)) { first.attributes.upload_id; // ✅ narrowed } ``` -------------------------------- ### Extract All Method Names for a Resource Source: https://github.com/datocms/js-rest-api-clients/blob/main/packages/cma-client-analysis/README.md Get a list of all available method names for a specific resource, such as 'items'. This is useful for understanding the full API surface of a resource. ```typescript import { getCmaClientProgram, extractAllMethodNames, } from '@datocms/cma-client-analysis'; const { program, checker, clientClass } = getCmaClientProgram(); extractAllMethodNames(checker, clientClass, 'items'); // → ['list', 'find', 'create', 'rawList', 'rawFind', 'rawCreate', ...] ``` -------------------------------- ### Generate Schema Types with CMA Client Source: https://github.com/datocms/js-rest-api-clients/blob/main/packages/cma-schema-types-generator/README.md Import and use `generateSchemaTypes` with an initialized CMA client to get a string of TypeScript code. ```typescript import { buildClient } from '@datocms/cma-client'; import { generateSchemaTypes } from '@datocms/cma-schema-types-generator'; const client = buildClient({ apiToken: process.env.DATOCMS_API_TOKEN! }); const code = await generateSchemaTypes(client); ``` -------------------------------- ### Run Test Suite Source: https://github.com/datocms/js-rest-api-clients/blob/main/README.md To execute the test suite, use this command. ```bash npm run test ``` -------------------------------- ### List and Describe API Resources Source: https://github.com/datocms/js-rest-api-clients/blob/main/packages/rest-api-reference/README.md List all available resources grouped by theme. Describe a specific resource and its available actions. ```typescript // List all available resources grouped by theme const listing = listResources(hyperschema, resourcesSchema); // Describe a specific resource and its available actions const resource = describeResource(hyperschema, resourcesSchema, 'items'); // Describe a specific action with examples const action = describeResourceAction( hyperschema, resourcesSchema, 'items', 'create', ); ``` -------------------------------- ### Import Lower-Level Utilities Source: https://github.com/datocms/js-rest-api-clients/blob/main/packages/rest-api-reference/README.md Import finder functions and a Markdown builder for more granular control over schema interaction and rendering. ```typescript import { findHyperschemaEntity, findHyperschemaLink, findResourcesEntityByJsonApiType, findResourcesEntityByNamespace, findResourcesEndpointByRel, render, h1, h2, p, ul, li, code, } from '@datocms/rest-api-reference'; ``` -------------------------------- ### Initialize and Use SchemaRepository Source: https://github.com/datocms/js-rest-api-clients/blob/main/packages/cma-client/README.md Instantiate SchemaRepository with a client. The first calls to schema methods fetch data from the API and cache it. Subsequent calls use the cached data, avoiding further API requests. ```typescript const schemaRepository = new SchemaRepository(client); // First call: fetches from API and caches result const blogPost = await schemaRepository.getItemTypeByApiKey('blog_post'); const fields = await schemaRepository.getItemTypeFields(blogPost); // Next calls: resolved instantly from cache (no API calls) const sameBlogPost = await schemaRepository.getItemTypeByApiKey('blog_post'); const sameFields = await schemaRepository.getItemTypeFields(blogPost); // Works seamlessly with block-processing utilities await mapBlocksInNonLocalizedFieldValue( fieldValue, fieldType, schemaRepository, // share cached lookups async (block) => { // transform block here } ); ``` -------------------------------- ### Type-Safe Item Creation and Narrowing Source: https://github.com/datocms/js-rest-api-clients/blob/main/packages/cma-schema-types-generator/README.md Demonstrates using generated schema types for type-safe item creation with `client.items.create` and for narrowing types using `Schema.HeroBlock.ID`. ```typescript import { buildClient } from '@datocms/cma-client'; import * as Schema from './generated/schema'; const client = buildClient({ apiToken: process.env.DATOCMS_API_TOKEN! }); await client.items.create({ item_type: Schema.LandingPage.REF, title: 'Hello world', }); if (block.__itemTypeId === Schema.HeroBlock.ID) { // narrowed to Schema.HeroBlock } ``` -------------------------------- ### Initialize CMA Client Program Source: https://github.com/datocms/js-rest-api-clients/blob/main/packages/cma-client-analysis/README.md Build a TypeScript program over the @datocms/cma-client-node's .d.ts entry. This is an expensive operation and should be done once and the result threaded through subsequent calls. ```typescript import { getCmaClientProgram, } from '@datocms/cma-client-analysis'; const { program, checker, clientClass } = getCmaClientProgram(); ``` -------------------------------- ### Expand Details in Resource Actions Source: https://github.com/datocms/js-rest-api-clients/blob/main/packages/rest-api-reference/README.md Optionally expand specific `
` blocks within resource action descriptions by providing an array of `` texts. ```typescript const expanded = describeResourceAction( hyperschema, resourcesSchema, 'items', 'create', ['Example: Basic creation'], ); ``` -------------------------------- ### Write schema-globals.ts for script-workspace Source: https://github.com/datocms/js-rest-api-clients/blob/main/packages/cma-schema-types-generator/PLAN.md This snippet shows how to write a per-run schema-globals.ts file with fixed content for the script-workspace. It ensures that the Schema module is available globally. ```typescript import * as SchemaModule from './schema.js'; declare global { export import Schema = SchemaModule; } (globalThis as unknown as { Schema: typeof SchemaModule }).Schema = SchemaModule; ``` -------------------------------- ### Fetch and Parse API Schemas Source: https://github.com/datocms/js-rest-api-clients/blob/main/packages/rest-api-reference/README.md Fetch and dereference hyperschema using shorthand, dashboard API, or a custom URL. Parse a resources.json file. ```typescript import { fetchHyperschema, parseResourcesSchema, listResources, describeResource, describeResourceAction, } from '@datocms/rest-api-reference'; // Fetch and dereference a hyperschema using a shorthand... const hyperschema = await fetchHyperschema('cma'); // ...or the dashboard API const dashboardSchema = await fetchHyperschema('dashboard'); // ...or a custom URL const custom = await fetchHyperschema('https://example.com/schema.json'); // Parse a resources.json file (shipped with @datocms/cma-client) const resourcesSchema = parseResourcesSchema(rawResourcesJson); ``` -------------------------------- ### buildBlockRecord() Source: https://github.com/datocms/js-rest-api-clients/blob/main/packages/cma-client/README.md Converts block data into the correct format for API requests. ```APIDOC ## buildBlockRecord() ### Description Converts a block data object into the proper format for API requests. ### Signature ```typescript function buildBlockRecord( body: ItemUpdateSchema> ): NewBlockInRequest> ``` ### Parameters - `body` (ItemUpdateSchema): Block data in update schema format. ### Returns NewBlockInRequest: Formatted block record ready for API requests. ``` -------------------------------- ### Regenerate Code from Schema Source: https://github.com/datocms/js-rest-api-clients/blob/main/README.md Use these commands to regenerate the API client code based on the latest DatoCMS JSON API schema. ```bash npm run generate npm run build ``` -------------------------------- ### Dynamically import schema-globals.ts in script-workspace runner Source: https://github.com/datocms/js-rest-api-clients/blob/main/packages/cma-schema-types-generator/PLAN.md This code demonstrates how to dynamically import schema-globals.ts before importing the user script in the script-workspace runner. This ensures that globalThis.Schema is populated. ```typescript const runDir = path.dirname(scriptPath); const schemaGlobalsUrl = pathToFileURL( path.join(runDir, 'schema-globals.ts'), ).href; await import(schemaGlobalsUrl); ``` -------------------------------- ### Write Generated Types to File Source: https://github.com/datocms/js-rest-api-clients/blob/main/packages/cma-schema-types-generator/README.md Use Node.js `fs/promises` to write the generated TypeScript code to a file. ```typescript import { writeFile } from 'node:fs/promises'; await writeFile('src/generated/schema.ts', code); ``` -------------------------------- ### Structured Text Response Variations Source: https://github.com/datocms/js-rest-api-clients/blob/main/packages/cma-client/README.md Demonstrates the different formats for structured text fields in regular responses, 'Nested Mode' responses, and for requests. Includes type guards for runtime validation. ```typescript import { StructuredTextFieldValue, StructuredTextFieldValueInRequest, StructuredTextFieldValueInNestedResponse, // Type guards for all variations (also available for single_block and rich_text) isStructuredTextFieldValue, isStructuredTextFieldValueInRequest, isStructuredTextFieldValueInNestedResponse } from '@datocms/cma-client'; // Regular response - blocks as string IDs const standard: StructuredTextFieldValue = { document: { type: "root", children: [ { type: "block", // String ID reference item: "IdMLV2GJTXyQ0Bfns7R4IQ" } ] } }; // Nested Mode response (?nested=true) - blocks as full objects const nested: StructuredTextFieldValueInNestedResponse = { document: { type: "root", children: [ { type: "block", // Always full block object item: { id: "IdMLV2GJTXyQ0Bfns7R4IQ", type: "item", attributes: { /* ... */ }, relationships: { /* ... */ } } } ] } }; // Request format - flexible block representation const request: StructuredTextFieldValueInRequest = { document: { type: "root", children: [ { type: "block", // Can be string ID, to keep block unchanged... item: "FicV5CxCSQ6yOrgfwRoiKA" }, { type: "block", // ...or full block object (to create new blocks or update existing ones) item: { type: "item", attributes: { /* ... */ }, relationships: { /* ... */ } } } ] } }; // Runtime validation for different contexts if (isStructuredTextFieldValueInNestedResponse(someStructuredText)) { // someStructuredText has blocks as full objects } if (isStructuredTextFieldValueInRequest(requestData)) { // requestData allows flexible block representations } ``` -------------------------------- ### Extract Methods for a REST Endpoint Source: https://github.com/datocms/js-rest-api-clients/blob/main/packages/cma-client-analysis/README.md Identify all client methods that implement a given REST endpoint, matched by its documentation URL. This requires parsing the resources schema and finding the corresponding endpoint. ```typescript import { getCmaClientProgram, extractResourcesEndpointMethods, } from '@datocms/cma-client-analysis'; import { findResourcesEntityByNamespace, findResourcesEndpointByRel, parseResourcesSchema, } from '@datocms/rest-api-reference'; import resourcesJson from '@datocms/cma-client/resources.json'; const { program, checker, clientClass } = getCmaClientProgram(); const resourcesSchema = parseResourcesSchema(resourcesJson); const entity = findResourcesEntityByNamespace(resourcesSchema, 'menuItems'); const endpoint = findResourcesEndpointByRel(entity!, 'create'); const methods = extractResourcesEndpointMethods(checker, clientClass, endpoint!); ``` -------------------------------- ### SchemaRepository Class Signature Source: https://github.com/datocms/js-rest-api-clients/blob/main/packages/cma-client/README.md Overview of the SchemaRepository class methods for retrieving item types, fields, fieldsets, plugins, and their raw API response formats. ```typescript class SchemaRepository { constructor(client: GenericClient) // Item Type methods async getAllItemTypes(): Promise async getAllModels(): Promise async getAllBlockModels(): Promise async getItemTypeByApiKey(apiKey: string): Promise async getItemTypeById(id: string): Promise // Field methods async getItemTypeFields(itemType: ItemType): Promise async getItemTypeFieldsets(itemType: ItemType): Promise // Higher-level utilities async getModelsEmbeddingBlocks(blocks: ItemType[]): Promise async getNestedBlocks(itemTypes: ItemType[]): Promise async getNestedModels(itemTypes: ItemType[]): Promise // Plugin methods async getAllPlugins(): Promise async getPluginById(id: string): Promise async getPluginByPackageName(packageName: string): Promise // Raw variants (return API response format) async getAllRawItemTypes(): Promise async getRawItemTypeByApiKey(apiKey: string): Promise async getRawNestedBlocks(itemTypes: Array): Promise> async getRawNestedModels(itemTypes: Array): Promise> // ... and more raw variants } ``` -------------------------------- ### visitNormalizedFieldValues / visitNormalizedFieldValuesAsync Source: https://github.com/datocms/js-rest-api-clients/blob/main/packages/cma-client/README.md Iterates over each value within a field, accommodating both localized and non-localized field structures. A visitor function is executed for every value encountered, enabling side effects or data inspection. ```APIDOC ## visitNormalizedFieldValues() / visitNormalizedFieldValuesAsync() ### Description Visit each value in a field, handling both localized and non-localized fields. ### Signatures ```typescript function visitNormalizedFieldValues( localizedOrNonLocalizedFieldValue: T | LocalizedFieldValue, field: Field, visitFn: (locale: string | undefined, localeValue: T) => void ): void async function visitNormalizedFieldValuesAsync( localizedOrNonLocalizedFieldValue: T | LocalizedFieldValue, field: Field, visitFn: (locale: string | undefined, localeValue: T) => Promise ): Promise ``` ### Parameters - `localizedOrNonLocalizedFieldValue` (T | LocalizedFieldValue) - The field value to visit. - `field` (Field) - The DatoCMS field definition. - `visitFn` ((locale: string | undefined, localeValue: T) => void | Promise) - Function called for each value. ### Returns - `void` or `Promise`. ``` -------------------------------- ### Visit Field Values (Localized & Non-Localized) (TypeScript) Source: https://github.com/datocms/js-rest-api-clients/blob/main/packages/cma-client/README.md Visits each value in a field, uniformly handling both localized and non-localized fields. The visit function receives the locale (or undefined for non-localized) and the value. ```typescript function visitNormalizedFieldValues( localizedOrNonLocalizedFieldValue: T | LocalizedFieldValue, field: Field, visitFn: (locale: string | undefined, localeValue: T) => void ): void ``` ```typescript async function visitNormalizedFieldValuesAsync( localizedOrNonLocalizedFieldValue: T | LocalizedFieldValue, field: Field, visitFn: (locale: string | undefined, localeValue: T) => Promise ): Promise ``` -------------------------------- ### File and Gallery Field Type Variations Source: https://github.com/datocms/js-rest-api-clients/blob/main/packages/cma-client/README.md Handles different type requirements for File and Gallery fields between API requests and responses. Use specific type guards like `isFileFieldValueInRequest` and `isGalleryFieldValue` to validate values in their respective contexts. Response formats include all metadata, while request formats allow optional metadata. ```typescript import { FileFieldValue, FileFieldValueInRequest, GalleryFieldValue, GalleryFieldValueInRequest, // Type guards for runtime validation isFileFieldValue, isFileFieldValueInRequest, isGalleryFieldValue, isGalleryFieldValueInRequest } from '@datocms/cma-client'; // API Response format - all metadata fields present with defaults const fileResponse: FileFieldValue = { upload_id: "12345", alt: null, // Always present (default: null) title: null, // Always present (default: null) custom_data: {}, // Always present (default: {}) focal_point: null // Always present (default: null) }; // API Request format - metadata fields are optional const fileRequest: FileFieldValueInRequest = { upload_id: "12345" // alt, title, custom_data, focal_point are optional }; // Runtime validation for different contexts if (isFileFieldValueInRequest(someFileValue)) { // someFileValue has optional metadata fields } if (isGalleryFieldValue(someGalleryValue)) { // someGalleryValue is array of files with all metadata present } ``` -------------------------------- ### duplicateBlockRecord() Source: https://github.com/datocms/js-rest-api-clients/blob/main/packages/cma-client/README.md Creates a deep copy of a block record, including nested blocks, and removes IDs to prepare for creating new instances. ```APIDOC ## duplicateBlockRecord() ### Description Creates a deep copy of a block record, including all nested blocks, removing IDs to create new instances. ### Signature ```typescript async function duplicateBlockRecord( existingBlock: ItemWithOptionalIdAndMeta>, schemaRepository: SchemaRepository ): Promise>> ``` ### Parameters - `existingBlock` (ItemWithOptionalIdAndMeta): The block to duplicate. - `schemaRepository` (SchemaRepository): Repository for schema lookups. ### Returns Promise: New block record without IDs, ready to be created. ``` -------------------------------- ### Current Item Type Referencing Source: https://github.com/datocms/js-rest-api-clients/blob/main/packages/cma-schema-types-generator/PLAN.md Consumers currently need to hardcode item type IDs when creating or referencing items. This approach is prone to errors and difficult to maintain. ```typescript client.items.create({ item_type: { type: "item_type", id: "UZyfjdBES8y2W2ruMEHSoA" }, title: "...", }); isBlockOfType("Dy9C52o4S6eF3mqSOmeUtg"); ``` -------------------------------- ### Extract and Expand Type Dependencies Source: https://github.com/datocms/js-rest-api-clients/blob/main/packages/cma-client-analysis/README.md Generate inline TypeScript declarations for a set of referenced types, walking up to a specified maximum depth. This helps in understanding complex type relationships within the client. ```typescript import { getCmaClientProgram, extractTypeDependencies, } from '@datocms/cma-client-analysis'; const { program, checker, clientClass } = getCmaClientProgram(); const signature = extractMethodSignature(checker, clientClass, 'items', 'create'); const { expandedTypes, notExpandedTypes } = extractTypeDependencies( checker, program, Array.from(signature!.referencedTypeSymbols.keys()), signature!.referencedTypeSymbols, { maxDepth: 2 }, ); ``` -------------------------------- ### Build Block Record for API Request Source: https://github.com/datocms/js-rest-api-clients/blob/main/packages/cma-client/README.md Converts a block data object into the correct format for API requests. ```typescript function buildBlockRecord( body: ItemUpdateSchema> ): NewBlockInRequest> ``` -------------------------------- ### Extract Method Signature Source: https://github.com/datocms/js-rest-api-clients/blob/main/packages/cma-client-analysis/README.md Retrieve the full signature for a specific method on a resource, including its parameters, return type, and referenced type symbols. This is useful for detailed API introspection. ```typescript import { getCmaClientProgram, extractMethodSignature, } from '@datocms/cma-client-analysis'; const { program, checker, clientClass } = getCmaClientProgram(); const signature = extractMethodSignature(checker, clientClass, 'items', 'create'); // → { methodName, parameters, returnType, referencedTypeSymbols, ... } ``` -------------------------------- ### isBlockOfType() Source: https://github.com/datocms/js-rest-api-clients/blob/main/packages/cma-client/README.md Builds a type guard to narrow a union of block shapes to one matching a given model ID. Useful for filtering arrays of blocks. ```APIDOC ## isBlockOfType() ### Description Builds a type guard that narrows a union of block shapes to the one matching a given model. Meant for `Array#filter` / `Array#find` over block-bearing fields. ### Signature ```typescript // Curried — returns a predicate (use with .filter / .find) function isBlockOfType( itemTypeId: Id ): (block: T) => block is NarrowBlockByItemType // Direct — checks a single block inline (use inside `if`) function isBlockOfType( itemTypeId: Id, block: T ): block is NarrowBlockByItemType type NarrowBlockByItemType = Extract< T, { relationships: { item_type: { data: { type: 'item_type'; id: Id } } } } > ``` ### Parameters - `itemTypeId` (string literal): The item-type ID literal. Use `as const` for literal typing. - `block` (T, direct form only): The block to check. ### Returns - Curried form: A predicate `(block) => block is D-typed-block`. - Direct form: A `boolean` that also acts as a type guard on `block`. ### Usage Example ```typescript import { isBlockOfType } from '@datocms/cma-client'; const IMAGE_BLOCK_ID = 'FJM79jjKRMSVg-fR6k6X2A' as const; // Curried form with .filter const images = article.content.filter(isBlockOfType(IMAGE_BLOCK_ID)); // Direct form with `if` const first = article.content[0]; if (isBlockOfType(IMAGE_BLOCK_ID, first)) { // `first` is now narrowed } ``` ``` -------------------------------- ### Inspect DatoCMS Item Structure Source: https://github.com/datocms/js-rest-api-clients/blob/main/packages/cma-client/README.md Use the `inspectItem` function to generate a visual, tree-structured representation of DatoCMS records or blocks in the console for debugging. ```typescript import { inspectItem } from '@datocms/cma-client'; const record = await client.items.find('MgCNaAI0RxSG8CA9sDXCHg'); console.log(inspectItem(record)); // Output: // Item "MgCNaAI0RxSG8CA9sDXCHg" (item_type: "bJse85JFR0GbA37ey6kA1w") // ├─ title: "My Blog Post" // ├─ slug: "my-blog-post" // └─ content: // ├─ en: "This is the English content..." // └─ it: "Questo è il contenuto italiano..." ``` -------------------------------- ### Generate Schema Types for Migration Source: https://github.com/datocms/js-rest-api-clients/blob/main/packages/cma-schema-types-generator/README.md Use `generateSchemaTypesForMigration` to produce inlineable TypeScript declarations without the `ItemTypeDefinition` import, suitable for migration scripts. Allows filtering by model API keys. ```typescript import { generateSchemaTypesForMigration } from '@datocms/cma-schema-types-generator'; const inline = await generateSchemaTypesForMigration(client, { itemTypesFilter: 'blog_post,author', }); ``` -------------------------------- ### mapNormalizedFieldValues / mapNormalizedFieldValuesAsync Source: https://github.com/datocms/js-rest-api-clients/blob/main/packages/cma-client/README.md Applies a transformation function to field values, consistently handling both localized and non-localized fields. This function ensures that the transformation logic works seamlessly regardless of the field's localization status. ```APIDOC ## mapNormalizedFieldValues() / mapNormalizedFieldValuesAsync() ### Description Apply a transformation function to field values, handling both localized and non-localized fields uniformly. ### Signatures ```typescript function mapNormalizedFieldValues( localizedOrNonLocalizedFieldValue: TInput | LocalizedFieldValue, field: Field, mapFn: (locale: string | undefined, localeValue: TInput) => TOutput ): TOutput | LocalizedFieldValue async function mapNormalizedFieldValuesAsync( localizedOrNonLocalizedFieldValue: TInput | LocalizedFieldValue, field: Field, mapFn: (locale: string | undefined, localeValue: TInput) => Promise ): Promise> ``` ### Parameters - `localizedOrNonLocalizedFieldValue` (TInput | LocalizedFieldValue) - The field value (localized or non-localized). - `field` (Field) - The DatoCMS field definition. - `mapFn` ((locale: string | undefined, localeValue: TInput) => TOutput | Promise) - Function to transform each value (receives locale for localized fields, undefined for non-localized). ### Returns - `TOutput | LocalizedFieldValue` or `Promise>` - Transformed value maintaining the same structure. ``` -------------------------------- ### toNormalizedFieldValueEntries / fromNormalizedFieldValueEntries Source: https://github.com/datocms/js-rest-api-clients/blob/main/packages/cma-client/README.md Converts field values to and from a normalized entry format for uniform processing. Useful for handling localized field values consistently. ```APIDOC ## toNormalizedFieldValueEntries() / fromNormalizedFieldValueEntries() ### Description Convert field values to/from a normalized entry format for uniform processing. ### Parameters - `localizedOrNonLocalizedFieldValue`/`entries` (T | LocalizedFieldValue | NormalizedFieldValueEntry[]) - Value to convert from/to. - `field` (Field) - The DatoCMS field definition. ### Returns - `NormalizedFieldValueEntry[] | T | LocalizedFieldValue` - Normalized entries array or reconstructed field value. ### Type Definition ```typescript type NormalizedFieldValueEntry = { locale: string | undefined; value: T; } ``` ### Usage Example ```typescript // Convert to entries for processing const entries = toNormalizedFieldValueEntries(fieldValue, field); // Process entries uniformly const processed = entries.map(({ locale, value }) => ({ locale, value: processValue(value) })); // Convert back to field value format const result = fromNormalizedFieldValueEntries(processed, field); ``` ``` -------------------------------- ### findAllBlocksInNonLocalizedFieldValue Source: https://github.com/datocms/js-rest-api-clients/blob/main/packages/cma-client/README.md Finds all blocks that match a given predicate, searching recursively through nested blocks. ```APIDOC ## findAllBlocksInNonLocalizedFieldValue() ### Description Finds all blocks that match a given predicate, searching recursively through nested blocks. ### Signature ```typescript async function findAllBlocksInNonLocalizedFieldValue( nonLocalizedFieldValue: unknown, fieldType: string, schemaRepository: SchemaRepository, predicate: (item: BlockInRequest, path: TreePath) => boolean | Promise, ): Promise> ``` ### Parameters - **nonLocalizedFieldValue** (unknown) - The non-localized field value to search. - **fieldType** (string) - The type of DatoCMS field (ie. `string`, `rich_text`, etc.). - **schemaRepository** (SchemaRepository) - Repository for caching schema lookups. - **predicate** ((item: BlockInRequest, path: TreePath) => boolean | Promise) - Function that tests each block. ### Returns Array of all matching blocks with their paths. ``` -------------------------------- ### Convert field values to/from normalized entries (TypeScript) Source: https://github.com/datocms/js-rest-api-clients/blob/main/packages/cma-client/README.md Use `toNormalizedFieldValueEntries` to convert field values into a normalized array of entries for uniform processing. Use `fromNormalizedFieldValueEntries` to convert these entries back into the original field value format. ```typescript function toNormalizedFieldValueEntries( localizedOrNonLocalizedFieldValue: T | LocalizedFieldValue, field: Field ): NormalizedFieldValueEntry[] function fromNormalizedFieldValueEntries( entries: NormalizedFieldValueEntry[], field: Field ): T | LocalizedFieldValue type NormalizedFieldValueEntry = { locale: string | undefined; value: T; } ``` ```typescript // Convert to entries for processing const entries = toNormalizedFieldValueEntries(fieldValue, field); // Process entries uniformly const processed = entries.map(({ locale, value }) => ({ locale, value: processValue(value) })); // Convert back to field value format const result = fromNormalizedFieldValueEntries(processed, field); ``` -------------------------------- ### Generated Type and Constant Pair Source: https://github.com/datocms/js-rest-api-clients/blob/main/packages/cma-schema-types-generator/PLAN.md For each item type, the generator will now emit a type definition and a corresponding constant object containing the ID and REF. The `as const` assertion is crucial for type narrowing. ```typescript export type Book = ItemTypeDefinition<…>; export const Book = { ID: 'UZyfjdBES8y2W2ruMEHSoA', REF: { type: 'item_type', id: 'UZyfjdBES8y2W2ruMEHSoA' }, } as const; ``` -------------------------------- ### everyNormalizedFieldValue / everyNormalizedFieldValueAsync Source: https://github.com/datocms/js-rest-api-clients/blob/main/packages/cma-client/README.md Checks if all values within a field pass a given test function. Supports both synchronous and asynchronous predicate functions. ```APIDOC ## everyNormalizedFieldValue() / everyNormalizedFieldValueAsync() ### Description Checks if all field values pass the test. ### Parameters - `localizedOrNonLocalizedFieldValue` (T | LocalizedFieldValue) - The field value to test. - `field` (Field) - The DatoCMS field definition. - `testFn` ((locale: string | undefined, localeValue: T) => boolean | Promise) - Predicate function. ### Returns - `boolean` - True if all values pass the test. ### Signatures ```typescript function everyNormalizedFieldValue(localizedOrNonLocalizedFieldValue: T | LocalizedFieldValue, field: Field, testFn: (locale: string | undefined, localeValue: T) => boolean): boolean async function everyNormalizedFieldValueAsync(localizedOrNonLocalizedFieldValue: T | LocalizedFieldValue, field: Field, testFn: (locale: string | undefined, localeValue: T) => Promise): Promise ``` ``` -------------------------------- ### Check All Blocks in Non-Localized Field Value (TypeScript) Source: https://github.com/datocms/js-rest-api-clients/blob/main/packages/cma-client/README.md Checks if all blocks within a non-localized field value match a given predicate. Requires schema repository for lookups. ```typescript async function everyBlockInNonLocalizedFieldValue( nonLocalizedFieldValue: unknown, fieldType: string, schemaRepository: SchemaRepository, predicate: (item: BlockInRequest, path: TreePath) => boolean | Promise, ): Promise ``` -------------------------------- ### Output Emission using TS Printer Source: https://github.com/datocms/js-rest-api-clients/blob/main/packages/cma-schema-types-generator/PLAN.md The TypeScript printer factory is used to create variable statements for the constant ID and REF, ensuring correct emission as `export const X = { ... } as const;`. ```typescript ts.factory.createVariableStatement( NodeFlags.Const, createObjectLiteralExpression([ createPropertyAssignment('ID', createStringLiteral('UZyfjdBES8y2W2ruMEHSoA')), createPropertyAssignment('REF', createObjectLiteralExpression([ createPropertyAssignment('type', createStringLiteral('item_type')), createPropertyAssignment('id', createStringLiteral('UZyfjdBES8y2W2ruMEHSoA')) ])) ]) ); ``` -------------------------------- ### Find All Blocks Recursively in Non-Localized Field Value Source: https://github.com/datocms/js-rest-api-clients/blob/main/packages/cma-client/README.md Search recursively through all blocks in a non-localized field value to find those matching a given predicate. Returns an array containing each matching block and its path. Useful for locating specific blocks across all nesting levels. ```typescript async function findAllBlocksInNonLocalizedFieldValue( nonLocalizedFieldValue: unknown, fieldType: string, schemaRepository: SchemaRepository, predicate: (item: BlockInRequest, path: TreePath) => boolean | Promise, ): Promise> ``` -------------------------------- ### Create Block Type Guard (Curried) Source: https://github.com/datocms/js-rest-api-clients/blob/main/packages/cma-client/README.md Returns a predicate function for narrowing block types, suitable for use with Array.filter or Array.find. Requires an item-type ID literal. ```typescript // Curried — returns a predicate (use with .filter / .find) function isBlockOfType( itemTypeId: Id, ): (block: T) => block is NarrowBlockByItemType ``` -------------------------------- ### someNormalizedFieldValues / someNormalizedFieldValuesAsync Source: https://github.com/datocms/js-rest-api-clients/blob/main/packages/cma-client/README.md Checks if at least one value within a field passes a given test function. Supports both synchronous and asynchronous predicate functions. ```APIDOC ## someNormalizedFieldValues() / someNormalizedFieldValuesAsync() ### Description Checks if at least one field value passes the test. ### Parameters - `localizedOrNonLocalizedFieldValue` (T | LocalizedFieldValue) - The field value to test. - `field` (Field) - The DatoCMS field definition. - `testFn` ((locale: string | undefined, localeValue: T) => boolean | Promise) - Predicate function. ### Returns - `boolean` - True if any value passes the test. ### Signatures ```typescript function someNormalizedFieldValues(localizedOrNonLocalizedFieldValue: T | LocalizedFieldValue, field: Field, testFn: (locale: string | undefined, localeValue: T) => boolean): boolean async function someNormalizedFieldValuesAsync(localizedOrNonLocalizedFieldValue: T | LocalizedFieldValue, field: Field, testFn: (locale: string | undefined, localeValue: T) => Promise): Promise ``` ``` -------------------------------- ### filterNormalizedFieldValues / filterNormalizedFieldValuesAsync Source: https://github.com/datocms/js-rest-api-clients/blob/main/packages/cma-client/README.md Filters field values based on a provided predicate function, supporting both localized and non-localized fields. This utility allows for selective data retrieval or manipulation across different field types. ```APIDOC ## filterNormalizedFieldValues() / filterNormalizedFieldValuesAsync() ### Description Filter field values based on a predicate, handling both localized and non-localized fields. ### Signatures ```typescript function filterNormalizedFieldValues( localizedOrNonLocalizedFieldValue: T | LocalizedFieldValue, field: Field, filterFn: (locale: string | undefined, localeValue: T) => boolean ): T | LocalizedFieldValue | undefined async function filterNormalizedFieldValuesAsync( localizedOrNonLocalizedFieldValue: T | LocalizedFieldValue, field: Field, filterFn: (locale: string | undefined, localeValue: T) => Promise ): Promise | undefined> ``` ### Parameters - `localizedOrNonLocalizedFieldValue` (T | LocalizedFieldValue) - The field value to filter. - `field` (Field) - The DatoCMS field definition. - `filterFn` ((locale: string | undefined, localeValue: T) => boolean | Promise) - Predicate function for filtering. ### Returns - `T | LocalizedFieldValue | undefined` or `Promise | undefined>` - Filtered value or undefined if all filtered out. ``` -------------------------------- ### Duplicate Block Record Source: https://github.com/datocms/js-rest-api-clients/blob/main/packages/cma-client/README.md Creates a deep copy of a block record, including nested blocks, by removing IDs to ensure new instances. ```typescript async function duplicateBlockRecord( existingBlock: ItemWithOptionalIdAndMeta>, schemaRepository: SchemaRepository ): Promise>> ``` -------------------------------- ### TypeScript Generics for Field Types Source: https://github.com/datocms/js-rest-api-clients/blob/main/packages/cma-client/README.md Utilize TypeScript generics with field value types and type guards for precise typing of block-containing fields according to your specific schema. ```typescript import type { MyArticle, MyArticleSection } from './schema'; // Fully typed structured text with specific block types const content: StructuredTextFieldValueInRequest = { document: { type: "root", children: [/* ... */] } }; // Type guard with generic for precise validation if (isStructuredTextFieldValueInNestedResponse(value)) { // value is now typed with your specific block schema } ``` -------------------------------- ### Check if all field values pass a test (TypeScript) Source: https://github.com/datocms/js-rest-api-clients/blob/main/packages/cma-client/README.md Use `everyNormalizedFieldValue` to verify that all values in a field satisfy a given test function. For asynchronous tests, use `everyNormalizedFieldValueAsync`. ```typescript function everyNormalizedFieldValue( localizedOrNonLocalizedFieldValue: T | LocalizedFieldValue, field: Field, testFn: (locale: string | undefined, localeValue: T) => boolean ): boolean async function everyNormalizedFieldValueAsync( localizedOrNonLocalizedFieldValue: T | LocalizedFieldValue, field: Field, testFn: (locale: string | undefined, localeValue: T) => Promise ): Promise ``` -------------------------------- ### Proposed Item Type Referencing Source: https://github.com/datocms/js-rest-api-clients/blob/main/packages/cma-schema-types-generator/PLAN.md The proposed change allows consumers to reference item types using generated constants, improving code readability and maintainability. This leverages TypeScript's declaration merging. ```typescript client.items.create({ item_type: Schema.Book.REF, title: "...", }); isBlockOfType(Schema.TestimonialBlock.ID); if (block.__itemTypeId === Schema.HeroBlock.ID) { /* narrows */ } ``` -------------------------------- ### visitBlocksInNonLocalizedFieldValue Source: https://github.com/datocms/js-rest-api-clients/blob/main/packages/cma-client/README.md Recursively visits every block in a non-localized field value, including nested blocks. A visitor function is called for each block encountered. ```APIDOC ## visitBlocksInNonLocalizedFieldValue() ### Description Recursively visits every block in a non-localized field value, including nested blocks. A visitor function is called for each block encountered. ### Signature ```typescript async function visitBlocksInNonLocalizedFieldValue( nonLocalizedFieldValue: unknown, fieldType: string, schemaRepository: SchemaRepository, visitor: (item: BlockInRequest, path: TreePath) => void | Promise, ): Promise ``` ### Parameters - **nonLocalizedFieldValue** (unknown) - The non-localized field value. - **fieldType** (string) - The type of DatoCMS field (ie. `string`, `rich_text`, etc.). - **schemaRepository** (SchemaRepository) - Repository for caching schema lookups. - **visitor** ((item: BlockInRequest, path: TreePath) => void | Promise) - Function called for each block (including nested). ``` -------------------------------- ### Check Blocks in Non-Localized Field Value (TypeScript) Source: https://github.com/datocms/js-rest-api-clients/blob/main/packages/cma-client/README.md Checks if any block within a non-localized field value matches a given predicate. Requires schema repository for lookups. ```typescript async function someBlocksInNonLocalizedFieldValue( nonLocalizedFieldValue: unknown, fieldType: string, schemaRepository: SchemaRepository, predicate: (item: BlockInRequest, path: TreePath) => boolean | Promise, ): Promise ``` -------------------------------- ### Map Field Values (Localized & Non-Localized) (TypeScript) Source: https://github.com/datocms/js-rest-api-clients/blob/main/packages/cma-client/README.md Applies a transformation function to field values, uniformly handling both localized and non-localized fields. The map function receives the locale (or undefined for non-localized) and the value. ```typescript function mapNormalizedFieldValues( localizedOrNonLocalizedFieldValue: TInput | LocalizedFieldValue, field: Field, mapFn: (locale: string | undefined, localeValue: TInput) => TOutput ): TOutput | LocalizedFieldValue ``` ```typescript async function mapNormalizedFieldValuesAsync( localizedOrNonLocalizedFieldValue: TInput | LocalizedFieldValue, field: Field, mapFn: (locale: string | undefined, localeValue: TInput) => Promise ): Promise> ``` -------------------------------- ### everyBlockInNonLocalizedFieldValue Source: https://github.com/datocms/js-rest-api-clients/blob/main/packages/cma-client/README.md Verifies if all blocks, including nested ones, within a non-localized field value satisfy a given predicate function. Returns true only if every block meets the criteria. ```APIDOC ## everyBlockInNonLocalizedFieldValue() ### Description Checks if every block (including nested) matches the predicate. ### Signature ```typescript async function everyBlockInNonLocalizedFieldValue( nonLocalizedFieldValue: unknown, fieldType: string, schemaRepository: SchemaRepository, predicate: (item: BlockInRequest, path: TreePath) => boolean | Promise, ): Promise ``` ### Parameters - `nonLocalizedFieldValue` (unknown) - The non-localized field value to test. - `fieldType` (string) - The type of DatoCMS field (ie. `string`, `rich_text`, etc.). - `schemaRepository` (SchemaRepository) - Repository for caching schema lookups. - `predicate` ((item: BlockInRequest, path: TreePath) => boolean | Promise) - Function that tests each block. ### Returns - `Promise` - True if all blocks match. ``` -------------------------------- ### Visit Blocks Recursively in Non-Localized Field Value Source: https://github.com/datocms/js-rest-api-clients/blob/main/packages/cma-client/README.md Use this function to iterate over every block within a non-localized field, including those nested at any depth. It's useful for side effects or data collection where each block needs to be processed. ```typescript async function visitBlocksInNonLocalizedFieldValue( nonLocalizedFieldValue: unknown, fieldType: string, schemaRepository: SchemaRepository, visitor: (item: BlockInRequest, path: TreePath) => void | Promise, ): Promise ``` -------------------------------- ### Check Block Type Inline (Direct) Source: https://github.com/datocms/js-rest-api-clients/blob/main/packages/cma-client/README.md Directly checks a single block for a specific type, acting as a type guard within an if statement. Requires an item-type ID literal. ```typescript // Direct — checks a single block inline (use inside `if`) function isBlockOfType( itemTypeId: Id, block: T, ): block is NarrowBlockByItemType ``` -------------------------------- ### LatLon Field Type Utilities Source: https://github.com/datocms/js-rest-api-clients/blob/main/packages/cma-client/README.md Provides type definitions and runtime validation functions for the `lat_lon` field type. Use type guards like `isLatLonFieldValue` and `isLocalizedLatLonFieldValue` for runtime checks. Validator and appearance types are also available for type-safe configuration. ```typescript import { isLatLonFieldValue, isLocalizedLatLonFieldValue } from '@datocms/cma-client'; import type { LatLonFieldValue, LatLonFieldValidators, LatLonFieldAppearance } from '@datocms/cma-client'; // Field value type - object with latitude/longitude or null const value: LatLonFieldValue = { latitude: 45.4642, longitude: 9.1900 }; // Type guard functions for validation if (isLatLonFieldValue(someValue)) { // someValue is guaranteed to be { latitude: number; longitude: number } | null } if (isLocalizedLatLonFieldValue(localizedValue)) { // localizedValue is a localized lat/lon field } // Validator and appearance types available for type-safe configuration type Validators = LatLonFieldValidators; type Appearance = LatLonFieldAppearance; ``` -------------------------------- ### reduceBlocksInNonLocalizedFieldValue Source: https://github.com/datocms/js-rest-api-clients/blob/main/packages/cma-client/README.md Reduces all blocks recursively to a single value using a reducer function. ```APIDOC ## reduceBlocksInNonLocalizedFieldValue() ### Description Reduces all blocks recursively to a single value using a reducer function. ### Signature ```typescript async function reduceBlocksInNonLocalizedFieldValue( nonLocalizedFieldValue: unknown, fieldType: string, schemaRepository: SchemaRepository, reducer: (accumulator: R, item: BlockInRequest, path: TreePath) => R | Promise, initialValue: R, ): Promise ``` ### Parameters - **nonLocalizedFieldValue** (unknown) - The non-localized field value to reduce. - **fieldType** (string) - The type of DatoCMS field (ie. `string`, `rich_text`, etc.). - **schemaRepository** (SchemaRepository) - Repository for caching schema lookups. - **reducer** ((accumulator: R, item: BlockInRequest, path: TreePath) => R | Promise) - Function that processes each block. - **initialValue** (R) - Initial accumulator value. ### Returns The final accumulated value. ``` -------------------------------- ### Filter Field Values (Localized & Non-Localized) (TypeScript) Source: https://github.com/datocms/js-rest-api-clients/blob/main/packages/cma-client/README.md Filters field values based on a predicate, uniformly handling both localized and non-localized fields. The filter function receives the locale (or undefined for non-localized) and the value. ```typescript function filterNormalizedFieldValues( localizedOrNonLocalizedFieldValue: T | LocalizedFieldValue, field: Field, filterFn: (locale: string | undefined, localeValue: T) => boolean ): T | LocalizedFieldValue | undefined ``` ```typescript async function filterNormalizedFieldValuesAsync( localizedOrNonLocalizedFieldValue: T | LocalizedFieldValue, field: Field, filterFn: (locale: string | undefined, localeValue: T) => Promise ): Promise | undefined> ```