Untitled

mail@pastecode.io avatar
unknown
typescript
a year ago
2.2 kB
3
Indexable
// ---> ---> 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" })
}