@energica-city/shared-amplify-utils
Version:
Shared utilities for AWS Amplify projects
77 lines • 3.14 kB
JavaScript
import { initializeQueries, createRestAwareQueryOperations, } from '../../queries';
import { buildRestContext, getErrorMessage } from './utils';
/**
* Creates REST model initializer middleware
*
* Creates a middleware function that initializes Amplify Data models
* for use in REST API handlers. Provides connection pooling, timeout
* handling, optional caching, and type-safe model access through the middleware chain.
*
* **Key Feature**: Automatically wraps all models with REST-aware error handling
* that converts database errors to appropriate HTTP status codes (404, 400, 409, 500).
*
* Features:
* - Lazy initialization with caching
* - Connection timeout protection
* - Optional in-memory caching with LRU eviction
* - Type-safe model selection
* - Automatic REST error conversion
* - Structured logging integration
*/
export function createRestModelInitializer(config) {
const { schema, amplifyOutputs, entities, clientKey = 'default', timeout = 5000, cache, } = config;
let isInitialized = false;
let initPromise = null;
const initialize = async (input) => {
const context = buildRestContext(input);
// Initialize queries with cache configuration
const rawModels = await Promise.race([
initializeQueries({
amplifyOutputs,
schema,
entities,
clientKey,
cache,
}),
new Promise((_, reject) => setTimeout(() => reject(new Error(`Initialization timeout after ${timeout}ms`)), timeout)),
]);
// Wrap each model with REST-aware error handling
const restAwareModels = {};
for (const [modelName, rawModel] of Object.entries(rawModels)) {
restAwareModels[modelName] = createRestAwareQueryOperations(rawModel, modelName, context);
}
return restAwareModels;
};
return async (input, next) => {
try {
// Lazy initialization: create promise on first request
if (!initPromise) {
initPromise = initialize(input);
}
// Wait for initialization to complete
const models = await initPromise;
isInitialized = true;
// Pass models to next middleware - REST errors will bubble up naturally
return await next({ ...input, models });
}
catch (error) {
// Only catch initialization errors - re-throw all others
if (!isInitialized) {
// Reset state on initialization failure
isInitialized = false;
initPromise = null;
const message = getErrorMessage(error);
return {
statusCode: 500,
body: JSON.stringify({
error: 'Model initialization failed',
message,
}),
};
}
// Re-throw REST errors and other errors to be handled by RestErrorHandler
throw error;
}
};
}
//# sourceMappingURL=RestModelInitializer.js.map