contentful-typescript-codegen icon indicating copy to clipboard operation
contentful-typescript-codegen copied to clipboard

Update to work with Contentful v10

Open prichey opened this issue 1 year ago • 8 comments

Just wanted to report that the types as generated do not appear to work with contentful.js@^10.

It looks like this is due to (among other things) the type of Entry changing significantly internally. For now I'm going to hold off on migrating but eventual support for v10 would be great. Or if v10 will not be supported it might be good to update docs to give folks that information.

Thanks!

prichey avatar Apr 20 '23 18:04 prichey

Bumping this

thejessewinton avatar Jun 14 '23 19:06 thejessewinton

bump!!!

joecf avatar Jun 23 '23 23:06 joecf

bump!!!

1Ghasthunter1 avatar Jul 02 '23 22:07 1Ghasthunter1

Just curious if there's any movement on this or future plans. This package is really valueable and I really appreciate everyone that's put the work in here. But this issue is definitely blocking us from moving to Contentful v10

sean415 avatar Aug 31 '23 20:08 sean415

I use this project at work and am interested at giving the v10 compat a go. I'm hoping to have a first draft to review here sometime in the next several days

kadencartwright avatar Sep 15 '23 21:09 kadencartwright

Any movement on this?

dylanwrightCO avatar Oct 31 '23 17:10 dylanwrightCO

Any movement on this?

No, I've not had the free time recently to keep pushing on this. If anyone is interested in taking over go right ahead.

I'm trying to get away from using contentful at work anyways. It's unacceptable that they don't build typegen themselves imo

kadencartwright avatar Nov 01 '23 00:11 kadencartwright

The current documentation for typescript suggests you could do manual:

type BlogPostSkeleton =
{
  contentTypeId: "blogPost",
  fields: {
    productName: Contentful.EntryFieldTypes.Text,
    image: Contentful.EntryFieldTypes.Asset,
    price: Contentful.EntryFieldTypes.Number,
    categories: Contentful.EntryFieldTypes.Array<Contentful.EntryFieldTypes.EntryLink<CategorySkeleton>>,
  }
}

client.getEntries<BlogPostSkeleton>()

Preceded by:

NOTE: We recommend to automate this step instead of doing it manually. To learn how to automatically generate types for your Contentful content models, refer to Generating type definitions for content types.

That file:

It is recommended to define field types for all your content types. This helps the type system to infer all possible query keys/value types for you. Doing this manually is cumbersome, but do not worry! There are several OSS projects out there to generate type definitions for Contentful content types:

Suggests: cf-content-types-generator in the https://github.com/contentful-userland which has a v10 argument.

I've spent a couple hours and have it working with v10, though it does break your break and code a bit. Examples:

CLI:

cf-content-types-generator --v10 -o src/lib/contentful/generated -s CF_SPACE_ID -t CF_MANAGEMENT_API_ACCESS_TOKEN

Client: src/lib/contentful.copy.ts

import client from "./client";
import { TypeCopySkeleton } from "./generated";
import type { Entry } from "contentful";

enum Slugs {
  GenericContentThankYou = "generic-contact-thank-you",
}

// https://app.contentful.com/spaces/****/content_types/copy/fields
const content_type = "copy";

export type CopyTypeWithoutUnresolvableLinksAndASingleLocale = Entry<
  TypeCopySkeleton,
  "WITHOUT_UNRESOLVABLE_LINKS"
>;

type GetParams = {};

export const getCopyGenericContentThankYouWithoutLocales = async (
  params?: GetParams,
): Promise<CopyTypeWithoutUnresolvableLinksAndASingleLocale> =>
  getCopy({
    ...params,
    slug: Slugs.GenericContentThankYou,
  });

type GetParamsWithSlug = GetParams & {
  slug: string;
};
const getCopy = async (
  params: GetParamsWithSlug,
): Promise<CopyTypeWithoutUnresolvableLinksAndASingleLocale> => {
  const query = {
    limit: 1,
    include: 10,
    // locale: params.locale,
    "fields.slug": params.slug,
    content_type,
  };
  const {
    items: [copy],
  } = await client.withoutUnresolvableLinks.getEntries(query);
  if (!copy) {
    throw new Error(`Contentful copy ${params.slug} undefined`);
  }
  return copy as CopyTypeWithoutUnresolvableLinksAndASingleLocale;
};

Component: src/components/Copy/index.tsx

import { ReactNode } from "react";
import RichText from "../RichText";
import { CopyTypeWithoutUnresolvableLinksAndASingleLocale } from "../../../lib/contentful/contentful.copy";

export type CopyProps = {
  fields: CopyTypeWithoutUnresolvableLinksAndASingleLocale["fields"];
};
export default function Copy({ fields }: CopyProps): ReactNode {
  return (
    <div>
      <RichText document={fields.body} />
    </div>
  );
}

Story: src/components/Copy/index.stories.tsx

import { Meta, StoryObj } from "@storybook/react";
import Component from "./index";
import { CopyTypeWithoutUnresolvableLinksAndASingleLocale } from "../../../lib/contentful/contentful.copy";
import { BLOCKS } from "@contentful/rich-text-types";

const copy: CopyTypeWithoutUnresolvableLinksAndASingleLocale["fields"] = {
  title: "Generic contact thank you",
  slug: "generic-contact-thank-you",
  apiIntegrated: true,
  body: {
    data: {},
    content: [
      {
        data: {},
        content: [
          {
            data: {},
            marks: [],
            value: "Thank you for your message.",
            nodeType: "text",
          },
        ],
        nodeType: BLOCKS.PARAGRAPH,
      },
      {
        data: {},
        content: [
          {
            data: {},
            marks: [],
            value: "Someone will get back to you shortly.",
            nodeType: "text",
          },
        ],
        nodeType: BLOCKS.PARAGRAPH,
      },
    ],
    nodeType: BLOCKS.DOCUMENT,
  },
};

// More on how to set up stories at: https://storybook.js.org/docs/react/writing-stories/introduction#default-export
const meta: Meta<typeof Component> = {
  component: Component,
  // This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/7.0/react/writing-docs/docs-page
  tags: ["autodocs"],
  parameters: {
    // More on Story layout: https://storybook.js.org/docs/react/configure/story-layout
    layout: "centered",
  },
  // More on argTypes: https://storybook.js.org/docs/react/api/argtypes
  argTypes: {},
  args: {
    fields: copy,
  },
};

export default meta;
type Story = StoryObj<typeof Component>;

// More on component templates: https://storybook.js.org/docs/react/writing-stories/introduction#using-args
export const Default: Story = {
  // More on args: https://storybook.js.org/docs/react/writing-stories/args
  args: {},
};

Hope that helps if anyone needs to migrate due to v10 requirements.

lancegliser avatar Jan 10 '24 19:01 lancegliser