npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

eslint-plugin-contentful-migrations

v1.0.0

Published

ESLint rules for Contentful migration scripts to enforce GraphQL Field Resolver annotations.

Downloads

14

Readme

eslint-plugin-contentful-migrations

An ESLint plugin to enforce correct Contentful:GraphQLFieldResolver annotations on 'JSON' type fields in Contentful migration scripts with Cloudinary integration, ensuring proper "Resolve content on delivery" functionality.

Table of Contents


Why This Plugin?

When working with Contentful content models, especially when utilizing GraphQL field resolvers for "Resolve content on delivery" features on a JSON type Cloudinary Image field, inconsistencies can arise in generated migration scripts.

The Problem:

Contentful migration generation sometimes fails to properly include the Contentful:GraphQLFieldResolver annotation with its required appFunctionId and appDefinitionId parameters. This leads to the "Resolve content on delivery" option being unchecked or ineffective in your target Contentful environment, preventing fields from being resolved via the Contentful GraphQL API.

Observed Scenarios:

  1. When creating a new field and setting its UI control (and potentially "Resolve content on delivery" simultaneously): The migration script might only generate createField and changeFieldControl lines, completely omitting the setAnnotations call for GraphQL resolvers.

    Example (Problematic):

    function migrationFunction(migration, context) {
      const testSample = migration.createContentType("testSample");
      testSample.name("testSampleImg").description("");
    
      const testSampleImg = testSampleImg.createField("image");
      testSampleImgTestSampleImgField
        .name("image")
        .type("Object") // This is an Object field!
        .localized(false)
        .required(false)
        .validations([])
        .disabled(false)
        .omitted(false);
      // Missing setAnnotations!
    }
  2. When modifying an existing field or creating a new field and then later applying "Resolve content on delivery" (which might trigger a re-evaluation by the Contentful migration tool): The migration script might generate the setAnnotations(["Contentful:GraphQLFieldResolver"]) line, but fails to include the necessary parameters object containing appFunctionId and appDefinitionId.

    Example (Problematic):

    function migrationFunction(migration, context) {
      const testSampleImg = testSample.editField("image");
      testSampleImg.setAnnotations(["Contentful:GraphQLFieldResolver"]); // Missing parameters object!
    }

The Solution:

This plugin identifies these missing or incomplete annotations for 'Object' type fields and provides an autofix to ensure they always include the correct Contentful:GraphQLFieldResolver annotation with the necessary appFunctionId and appDefinitionId.

Corrected Snippet Example:

const testSampleImg = testSample.editField("image");

testSampleImg.setAnnotations(["Contentful:GraphQLFieldResolver"], {
  parameters: {
    appFunctionId: "YOUR_APP_FUNCTION_ID",
    appDefinitionId: "YOUR_APP_DEFINITION_ID",
  },
});

Installation

First, install the plugin from npm:

npm install --save-dev eslint-plugin-contentful-migrations
# OR
yarn add --dev eslint-plugin-contentful-migrations

You will also need eslint itself:

npm install --save-dev eslint
# OR
yarn add --dev eslint

Usage

Depending on your ESLint version, you will configure the plugin slightly differently.

In your eslint.config.js (or similar eslintrc), import the plugin and configure it within a config object.

You MUST provide appFunctionId and appDefinitionId directly in the rule's options array.

// eslint.config.js
import { defineConfig } from "eslint/config";
import contentfulCloudinaryGraphqlFieldResolverPlugin from "eslint-plugin-contentful-cloudinary-graphql-field-resolver";

export default defineConfig([
  // --- General configuration (if any) ---
  {
    files: ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"],
    // ... your general plugins and rules
  },

  // --- Specific configuration for migration files with parameters ---
  {
    files: ["**/migrations/*.js"], // Target only JS files within 'migrations' directories
    plugins: {
      // Give your plugin an alias (e.g., 'contentfulCloudinary')
      contentfulCloudinary: contentfulCloudinaryGraphqlFieldResolverPlugin,
    },
    rules: {
      // Enable your custom rule for these specific files and pass parameters
      "contentfulCloudinary/enforce-contentful-cloudinary-graphql-field-resolver":
        [
          "error", // Rule severity (e.g., "error", "warn", "off")
          {
            appFunctionId: "YOUR_APP_FUNCTION_ID", // Replace with your actual App Function ID
            appDefinitionId: "YOUR_APP_DEFINITION_ID", // Replace with your actual App Definition ID
          },
        ],
      // You can also override other rules for these files here if needed
      "no-console": "off", // Example: allow console logs in migrations
    },
  },

  // Add more configurations as needed
]);

Rule

contentful-migrations/enforce-graphql-field-resolver

This rule ensures that:

  1. Any Object type field (created with createField set to type 'Object') has a setAnnotations call.
  2. If the Contentful:GraphQLFieldResolver annotation is present, its second argument (the options object) must contain a parameters object, which in turn must contain appFunctionId and appDefinitionId.
  3. If appFunctionId or appDefinitionId are missing from the ESLint rule configuration, the rule will report an error but will not provide a fix.

Configuration Options:

The rule accepts an object with the following properties:

  • appFunctionId (string, required for autofix): The ID of your Contentful App Function to be used as the GraphQL Field Resolver.
  • appDefinitionId (string, required for autofix): The ID of your Contentful App Definition.

Example Configuration (part of your .eslintrc.js or eslint.config.js):

// For eslint.config.js (rule options)
'contentful-migrations/enforce-graphql-field-resolver': ['error', {
  appFunctionId: 'YOUR_APP_FUNCTION_ID',
  appDefinitionId: 'YOUR_APP_DEFINITION_ID',
}]

Autofixing

This rule is fixable. When you run ESLint with the --fix flag, it will automatically:

  • Add the complete setAnnotations(["Contentful:GraphQLFieldResolver"], { parameters: { appFunctionId: '...', appDefinitionId: '...' } }) call if an 'Object' type field is missing it.
  • Correct or add the parameters object with appFunctionId and appDefinitionId if the Contentful:GraphQLFieldResolver annotation is present but incomplete.

Example CLI usage:

npx eslint "your-migration-file.js" --fix
# Or to fix all migration files in a directory
npx eslint "migrations/**/*.js" --fix

Finding appFunctionId and appDefinitionId

If you don't have these IDs handy, you can find them using the Contentful CLI:

  1. Ensure you have the Contentful CLI installed:
    npm install -g contentful-cli
  2. Log in to the CLI:
    contentful login
  3. Export your content model:
    contentful space export --space-id {YOUR_SPACE_ID} --skip-content --skip-assets --content-model-only --output-file content-model-export.json
  4. Open content-model-export.json. You can typically find the appDefinitionId and the appFunctionId.