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

Add mechanism for prop migration #41

Closed
chrisvxd opened this issue Sep 6, 2023 · 1 comment · Fixed by #263
Closed

Add mechanism for prop migration #41

chrisvxd opened this issue Sep 6, 2023 · 1 comment · Fixed by #263

Comments

@chrisvxd
Copy link
Member

chrisvxd commented Sep 6, 2023

Problem

Source: https://news.ycombinator.com/item?id=37392861

Sometimes a user might need to rename or remove a property provided to a component. For example, remaining description to subtitle.

The user currently has two options:

  1. Manually migrate their saved data before updating their Puck configuration
  2. (Preferred) Retain the old prop and map it to the new prop inside the render function.

These solutions either require repetitive work, or require the user to republish each page manually.

Proposal

Add a first-party mechanism for transforming data on a per-component basis.

This would probably live under a separate package (/packages/transform or /packages/migrate) and provide a user with a mechanism to 1) patch their data on the fly in a standardised manor and 2) batch transform their puck data consistently to adhere to the new props.

Create transformer

import { createTransform } from "@measured/puck-transform";

const transform = createTransform({
  HeadingBlock: ({ subtitle, ...props }) => {
    return {
      ...props,
      description: subtitle,
    };
  },
});

Patch data inline

// Pull from backend
const data = {
  type: "HeadingBlock",
  props: {
    subtitle: "Hello, world",
  },
};

export default () => <Puck data={transform(data)} config={config} />;

Patch all existing data

// Example data
const allData = [
  {
    path: "/",
    data: {
      root: {},
      content: [
        {
          type: "HeadingBlock",
          props: {
            subtitle: "Hello, world",
          },
        },
      ],
    },
  },
];

// Run the transformer
const patchedData = allData.map((page) => ({
  ...page,
  data: transform(page.data),
}));

// Write to your db
const save = () => {};
save(patchedData);

Considerations

  • TypeScript - How to tightly manage the types?
@chrisvxd
Copy link
Member Author

chrisvxd commented Oct 6, 2023

Additional, related concern - renaming components (not just props)

May wish to consider expanding the proposals above to capture this use case, too.

@chrisvxd chrisvxd added ready Assumed ready enough to start and removed opinions wanted labels Nov 24, 2023
This was referenced Nov 24, 2023
@chrisvxd chrisvxd added in progress and removed ready Assumed ready enough to start labels Dec 4, 2023
@chrisvxd chrisvxd self-assigned this Dec 4, 2023
@chrisvxd chrisvxd mentioned this issue Dec 7, 2023
9 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant