Untitled
typescript
21 days ago
2.2 kB
2
Indexable
Never
// ---> ---> 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" }) }