webiny / webiny-js

Open-source serverless enterprise CMS. Includes a headless CMS, page builder, form builder, and file manager. Easy to customize and expand. Deploys to AWS.
https://www.webiny.com
Other
7.29k stars 601 forks source link

feat(api-headless-cms): content entry traverser #4072

Closed Pavel910 closed 5 months ago

Pavel910 commented 5 months ago

Changes

This PR adds a utility to convert Content Model fields hierarchy into a traversable AST, and another utility, to traverse the content entry values.

One of the improvements to the codebase is splitting of the giant types.ts file into smaller, more focused, types files, for example: types/model.ts, types/modelField.ts, etc.

Example of Content Entry Traversal

// Get traverser instance.
const traverser = await context.cms.getEntryTraverser("article");

// Create a container for your custom output.
const output: Record<string, any> = {};

// We will skip values of the following field types.
const skipFieldTypes = ["object", "dynamicZone"];

// Traverse and create a flat object with value path as object key.
traverser.traverse(entry, ({ field, value, path }) => {
    /**
     * Most of the time you won't care about complex fields like "object" and "dynamicZone", but only their child fields.
     * The traverser will still go into the child fields, but this way you can conditionally apply your logic.
     */
    if (skipFieldTypes.includes(field.type)) {
        return;
    }

    output[path] = value;
});

expect(output).toEqual({
    title: "Article #1",
    body: richTextValue,
    categories: [{ modelId: "category", entryId: "12345678" }],
    "content.0.title": "Hero #1",
    "content.1.settings.title": "Title",
    "content.1.settings.seo.0.title": "title-0",
    "content.1.settings.seo.1.title": "title-1"
});

How Has This Been Tested?

Jest.

Documentation

TODO.