CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-gatsby-plugin-utils

Gatsby utils that help creating plugins

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

schema-validation.mddocs/

Schema Validation

Comprehensive plugin options validation system using Joi schemas with async support, detailed error reporting, and Gatsby-specific extensions.

Capabilities

validateOptionsSchema

Validates plugin options against a Joi schema with comprehensive error handling and warning support.

/**
 * Validates plugin options against a Joi schema
 * @param pluginSchema - Joi object schema for validation
 * @param pluginOptions - Plugin options to validate
 * @param options - Validation configuration options
 * @returns Promise with validated value and warnings
 */
function validateOptionsSchema(
  pluginSchema: ObjectSchema,
  pluginOptions: IPluginInfoOptions,
  options: {
    validateExternalRules?: boolean;
    returnWarnings?: boolean;
  } = {
    validateExternalRules: true,
    returnWarnings: true
  }
): Promise<{
  value: IPluginInfoOptions;
  warning: {
    message: string;
    details: Array<{
      message: string;
      path: Array<string>;
      type: string;
      context: Array<Record<string, unknown>>;
    }>;
  };
}>;

Usage Examples:

import { validateOptionsSchema, Joi } from "gatsby-plugin-utils";

// Define schema
const pluginSchema = Joi.object({
  apiKey: Joi.string().required().description("API key for service"),
  timeout: Joi.number().min(1000).default(5000).description("Request timeout in ms"),
  retries: Joi.number().min(0).max(5).default(3).description("Number of retry attempts"),
  enableCache: Joi.boolean().default(true).description("Enable response caching"),
  endpoints: Joi.object({
    graphql: Joi.string().uri().required(),
    rest: Joi.string().uri().optional()
  }).required()
});

// Validate options
async function validateMyPluginOptions(pluginOptions) {
  try {
    const result = await validateOptionsSchema(pluginSchema, pluginOptions, {
      validateExternalRules: true,
      returnWarnings: true
    });
    
    console.log("Validated options:", result.value);
    if (result.warning?.details?.length > 0) {
      console.warn("Validation warnings:", result.warning.details);
    }
    
    return result.value;
  } catch (error) {
    console.error("Validation failed:", error.details);
    throw error;
  }
}

// Example plugin options
const pluginOptions = {
  apiKey: "sk-1234567890",
  timeout: 3000,
  endpoints: {
    graphql: "https://api.example.com/graphql"
  }
};

const validatedOptions = await validateMyPluginOptions(pluginOptions);

testPluginOptionsSchema

Utility for testing plugin options schemas in test environments with comprehensive result reporting.

/**
 * Tests plugin options schema for validation behavior
 * @param pluginSchemaFunction - Function that returns Joi schema
 * @param pluginOptions - Options to test against schema
 * @returns Promise with detailed test results
 */
function testPluginOptionsSchema(
  pluginSchemaFunction: (args: { Joi: PluginOptionsSchemaJoi }) => ObjectSchema,
  pluginOptions: IPluginInfoOptions
): Promise<{
  errors: Array<string>;
  warnings: Array<string>;
  isValid: boolean;
  hasWarnings: boolean;
}>;

Usage Examples:

import { testPluginOptionsSchema } from "gatsby-plugin-utils";

// Test schema function
const pluginSchema = ({ Joi }) =>
  Joi.object({
    name: Joi.string().required(),
    version: Joi.string().pattern(/^\d+\.\d+\.\d+$/),
    features: Joi.array().items(Joi.string()).default([])
  });

// Test cases
describe("Plugin Options Schema", () => {
  it("should validate correct options", async () => {
    const { isValid, errors, warnings } = await testPluginOptionsSchema(
      pluginSchema,
      {
        name: "my-plugin",
        version: "1.0.0",
        features: ["feature-a", "feature-b"]
      }
    );
    
    expect(isValid).toBe(true);
    expect(errors).toHaveLength(0);
  });

  it("should fail with missing required field", async () => {
    const { isValid, errors } = await testPluginOptionsSchema(
      pluginSchema,
      {
        version: "1.0.0"
      }
    );
    
    expect(isValid).toBe(false);
    expect(errors).toContain('"name" is required');
  });

  it("should warn about unknown fields", async () => {
    const { isValid, hasWarnings, warnings } = await testPluginOptionsSchema(
      pluginSchema,
      {
        name: "my-plugin",
        version: "1.0.0",
        unknownField: "value"
      }
    );
    
    expect(isValid).toBe(true);
    expect(hasWarnings).toBe(true);
    expect(warnings).toContain('"unknownField" is not allowed');
  });
});

Validation Options

interface ValidationOptions {
  /**
   * Whether to validate external rules (default: true)
   */
  validateExternalRules?: boolean;
  
  /**
   * Whether to return warnings alongside validation results (default: true)
   */
  returnWarnings?: boolean;
}

Error Handling

The validation system provides detailed error information for debugging:

try {
  await validateOptionsSchema(schema, options);
} catch (validationError) {
  // validationError.details contains array of specific validation failures
  validationError.details.forEach(detail => {
    console.log(`Field: ${detail.path.join('.')}`);
    console.log(`Error: ${detail.message}`);
    console.log(`Type: ${detail.type}`);
  });
}

Gatsby-Specific Extensions

The validation system includes Gatsby-specific Joi extensions:

SubPlugins Validation

// Extended Joi with subPlugins validation
const Joi = require("gatsby-plugin-utils").Joi;

const schemaWithSubPlugins = Joi.object({
  plugins: Joi.subPlugins().description("Array of sub-plugins")
});

// Validates arrays of plugin references:
// ["plugin-name"] or [{ resolve: "plugin-name", options: {...} }]

Integration with gatsby-node.js

// gatsby-node.js
const { validateOptionsSchema } = require("gatsby-plugin-utils");

exports.pluginOptionsSchema = ({ Joi }) => {
  return Joi.object({
    apiToken: Joi.string().required().description("API authentication token"),
    apiUrl: Joi.string().uri().default("https://api.example.com"),
    cacheTimeout: Joi.number().min(0).default(300000)
  });
};

exports.onPreInit = async ({ reporter }, pluginOptions) => {
  try {
    const schema = exports.pluginOptionsSchema({ Joi: require("gatsby-plugin-utils").Joi });
    await validateOptionsSchema(schema, pluginOptions);
    reporter.info("Plugin options validated successfully");
  } catch (error) {
    reporter.panic("Invalid plugin options", error);
  }
};

docs

graphql-resolvers.md

image-cdn-polyfill.md

index.md

joi-schemas.md

runtime-compatibility.md

schema-validation.md

tile.json