All files / integrations/src/koa coherent-koa.js

10.71% Statements 3/28
25% Branches 4/16
28.57% Functions 2/7
10.71% Lines 3/28

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125                                                  1x   1x                                                       1x                                                                                                                                          
/**
 * Koa.js integration for Coherent.js
 * Provides middleware and utilities for using Coherent.js with Koa
 */
 
import {
  importPeerDependency,
  renderWithTemplate,
  renderComponentFactory,
  isCoherentComponent
} from '@coherent.js/core';
 
/**
 * Coherent.js Koa middleware
 * Automatically renders Coherent.js components and handles errors
 *
 * @param {Object} options - Configuration options
 * @param {boolean} options.enablePerformanceMonitoring - Enable performance monitoring
 * @param {string} options.template - HTML template with {{content}} placeholder
 * @returns {Function} Koa middleware function
 */
export function coherentKoaMiddleware(options = {}) {
  const {
    enablePerformanceMonitoring = false,
    template = '<!DOCTYPE html>\n{{content}}'
  } = options;
 
  return async (ctx, next) => {
    await next();
 
    // If response body is a Coherent.js object, render it
    if (isCoherentComponent(ctx.body)) {
      try {
        // Use shared rendering utility
        const finalHtml = renderWithTemplate(ctx.body, { enablePerformanceMonitoring, template });
 
        // Set content type and body
        ctx.type = 'text/html';
        ctx.body = finalHtml;
      } catch (_error) {
        console.error('Coherent.js rendering _error:', _error);
        throw _error;
      }
    }
  };
}
 
/**
 * Create a Koa route handler for Coherent.js components
 *
 * @param {Function} componentFactory - Function that returns a Coherent.js component
 * @param {Object} options - Handler options
 * @returns {Function} Koa route handler
 */
export function createHandler(componentFactory, options = {}) {
  return async (ctx, next) => {
    try {
      // Use shared rendering utility
      const finalHtml = await renderComponentFactory(
        componentFactory,
        [ctx, next],
        options
      );
 
      // Set response
      ctx.type = 'text/html';
      ctx.body = finalHtml;
    } catch (_error) {
      console.error('Coherent.js handler _error:', _error);
      throw _error;
    }
  };
}
 
/**
 * Setup Coherent.js with Koa app
 *
 * @param {Object} app - Koa app instance
 * @param {Object} options - Setup options
 */
export function setupCoherent(app, options = {}) {
  const {
    useMiddleware = true,
    enablePerformanceMonitoring = false
  } = options;
 
  // Use middleware for automatic rendering
  if (useMiddleware) {
    app.use(coherentKoaMiddleware({ enablePerformanceMonitoring }));
  }
}
 
/**
 * Create Koa integration with dependency checking
 * This function ensures Koa is available before setting up the integration
 *
 * @param {Object} options - Setup options
 * @returns {Promise<Function>} - Function to setup Koa integration
 */
export async function createKoaIntegration(options = {}) {
  try {
    // Verify Koa is available
    await importPeerDependency('koa', 'Koa.js');
 
    return function(app) {
      if (!app || typeof app.use !== 'function') {
        throw new Error('Invalid Koa app instance provided');
      }
 
      setupCoherent(app, options);
      return app;
    };
  } catch (_error) {
    throw _error;
  }
}
 
// Export all utilities
export default {
  coherentKoaMiddleware,
  createHandler,
  setupCoherent,
  createKoaIntegration
};