// ---> ---> utils/XMLTools.ts
import { Effect, Context, Layer } from 'effect/index';
import libxmljs, { XMLDocument } from "libxmljs";
const XSD = `
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
.....
</xs:schema>
`
class XMLParserError extends Error {
readonly _tag = "XMLParserError";
constructor () { super() }
}
class ValidateError extends Error {
readonly _tag = "ValidateError";
public errors: any[];
constructor (errors: any[]) {
super();
this.errors = errors;
}
}
const wrapHtmlWithCData = (xmlString: string): string => {
const htmlTagRegex = /<html>(.*?)<\/html>/gs;
return xmlString.replace(htmlTagRegex, (_, innerHtml: string) => `<html><![CDATA[${innerHtml}]]></html>`);
};
interface XMLParserService {
parser: (xml: string) => Effect.Effect<never, XMLParserError, XMLDocument>
validate: (xml: XMLDocument) => Effect.Effect<never, ValidateError, boolean>
}
const XMLParserService = Context.Tag<XMLParserService>();
export const XMLParserLayer = Layer.succeed(
XMLParserService,
XMLParserService.of({
parser: (xml: string) => Effect.tryPromise({
try: () => libxmljs.parseXmlAsync(xml),
catch: () => new XMLParserError(),
}),
validate: (xml: XMLDocument) => Effect.tryPromise({
try: () => libxmljs.parseXmlAsync(XSD)
.then(xsd => Boolean(xml.validate(xsd)))
.then(bool => {
if (bool) return bool;
else throw new ValidateError(xml.validationErrors);
}),
catch: () => new ValidateError(xml.validationErrors),
})
})
)
export const parserXML = (xmlData: string) =>
Effect.gen(function* (_) {
const XMLParser = yield* _(XMLParserService);
const resultXML = yield* _(XMLParser.parser(wrapHtmlWithCData(xmlData)));
yield* _( XMLParser.validate(resultXML) );
return resultXML;
})
// ---> ---> ---> api/slides/route.ts
export async function POST(request: NextRequest) {
if (!request.body) return NextResponse.json(new BodyIsEmptyError("Body пустое"))
const xml = await streamToText(request.body)
const result = await Effect.runPromise(
Effect.provideLayer(
parserXML(xml),
XMLParserLayer,
)
);
console.log(result);
return NextResponse.json({ message: "Hello" })
}