Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Contentful external references, crashes rendering in ResouceLink #384

Open
NielsRavn opened this issue Nov 15, 2024 · 0 comments
Open

Contentful external references, crashes rendering in ResouceLink #384

NielsRavn opened this issue Nov 15, 2024 · 0 comments

Comments

@NielsRavn
Copy link

We use contentful nataive external references and ran into a problem where the whole rendering process gets blocked by a throw line in the renderer:

throw new Error(`Unknown type "${resource.type}"`);

To fix this i have made a generator file which just logs the unknown type instead, so that all the other types work, we might implement som rendering for it in the future but for now this works, and then we handle the type manually.

A field that fails, its the allowedResouces that messes it up:

{
  "id": "test",
  "name": "test",
  "type": "Array",
  "localized": false,
  "required": false,
  "validations": [
  ],
  "disabled": false,
  "omitted": false,
  "items": {
    "type": "ResourceLink",
    "validations": [
    ]
  },
  "allowedResources": [
    {
      "type": "TMDB:Person"
    },
    {
      "type": "TMDB:Movie"
    }
  ]
}

I have fixed it by writing a part of the rendering my self and removed the throw error part.

import {
    CFDefinitionsBuilder,
    type CFEditorInterface,
    createV10Context,
    type FieldRenderer,
    type RenderContext,
    renderTypeGeneric,
    V10ContentTypeRenderer,
    v10Renderers,
    V10TypeGuardRenderer
} from 'cf-content-types-generator';
import type { ContentTypeField, ContentTypeFieldType } from 'contentful';
import * as path from 'node:path';
import * as fs from 'node:fs';
import content from './export.json';

export default async function createContentfulTypes() {
    try {
        const renderes = new CustomV10ContentTypeRenderer();

        const builder = new CFDefinitionsBuilder([renderes, new V10TypeGuardRenderer()]);

        const editorInterfaces = content.editorInterfaces as CFEditorInterface[] | undefined;

        for (const model of content.contentTypes) {
            const editorInterface = editorInterfaces?.find((e) => e.sys.contentType.sys.id === model.sys.id);
            builder.appendType(model, editorInterface);
        }

        const outDir = path.resolve('./wwwdev/types/autogen/contentful');
        if (fs.existsSync(outDir)) {
            fs.rmSync(outDir, { recursive: true, force: true });
        }

        fs.mkdirSync(outDir);
        await builder.write('./wwwdev/types/autogen/contentful', async (filePath, content) =>
            fs.writeFileSync(filePath, content)
        );
    } catch (error) {
        console.error(`Error: ${error.message}`);
    }
}

class CustomV10ContentTypeRenderer extends V10ContentTypeRenderer {
    renderPropResourceLinkV10(field: ContentTypeField, context: RenderContext): string {
        for (const resource of field.allowedResources) {
            if (resource.type !== 'Contentful:Entry') {
                console.warn(`unknown type ${resource.type}`);
            }
        }

        context.imports.add({
            moduleSpecifier: 'contentful',
            namedImports: ['EntryFieldTypes', 'EntrySkeletonType'],
            isTypeOnly: true
        });

        return renderTypeGeneric('EntryFieldTypes.EntryResourceLink', 'EntrySkeletonType');
    }

    public createContext(): RenderContext {
        const context = createV10Context();
        context.getFieldRenderer = <FType extends ContentTypeFieldType>(fieldType: FType) => {
            if (fieldType === 'ResourceLink') return this.renderPropResourceLinkV10;

            return v10Renderers[fieldType] as FieldRenderer<FType>;
        };

        return context;
    }
}

createContentfulTypes();

The code can be called by creating a package.json script with this
tsx ./contentfulTypes.ts

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant