Files
xslt-tools/src/transform/transformService.ts

63 lines
1.7 KiB
TypeScript

import { nativeXsltEngine } from './nativeXsltEngine';
import { saxonJsDynamicEngine } from './saxonJsDynamicEngine';
import type {
TransformEngine,
TransformEngineId,
TransformRequest,
TransformResult,
} from './transformTypes';
import {
assertTransformInputWithinLimits,
assertTransformOutputWithinLimits,
withTransformationTimeout,
} from './transformLimits';
import { createSha256Hash } from './hash';
import {
isStylesheetExecutionTrusted,
type TrustedStylesheet,
} from './stylesheetTrust';
export interface TransformationAuthorization {
trustedStylesheet: TrustedStylesheet;
currentRevision: number;
}
const engines: Record<TransformEngineId, TransformEngine> = {
'saxon-js-dynamic': saxonJsDynamicEngine,
'native-xsltprocessor': nativeXsltEngine,
};
export function getTransformEngine(id: TransformEngineId): TransformEngine {
return engines[id] ?? saxonJsDynamicEngine;
}
export async function runTransformation(
request: TransformRequest,
authorization: TransformationAuthorization
): Promise<TransformResult> {
const stylesheetHash = await createSha256Hash(request.xsltText);
if (
!authorization ||
!isStylesheetExecutionTrusted(
authorization.trustedStylesheet,
stylesheetHash,
authorization.currentRevision
)
) {
throw new Error(
'Transformation refused: review and trust this exact stylesheet first.'
);
}
assertTransformInputWithinLimits(request);
const engine = getTransformEngine(request.engine);
const result = await withTransformationTimeout(() =>
engine.transform(request)
);
assertTransformOutputWithinLimits(result);
return result;
}
export const availableTransformEngines = Object.values(engines);