From 8f19c063aeb3df1eed9cab58f4bf7cac22ab13dc Mon Sep 17 00:00:00 2001 From: joonhoekim <26rote@gmail.com> Date: Mon, 21 Jul 2025 05:56:55 +0000 Subject: ECC PO_INFORMATION 수신 라우트 구성 및 응답 메시지를 위한 유틸리티 함수 확장 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/soap/mdg/utils.ts | 111 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 85 insertions(+), 26 deletions(-) (limited to 'lib') diff --git a/lib/soap/mdg/utils.ts b/lib/soap/mdg/utils.ts index 02dd088e..52c82d47 100644 --- a/lib/soap/mdg/utils.ts +++ b/lib/soap/mdg/utils.ts @@ -5,6 +5,7 @@ import { join } from "path"; import { eq } from "drizzle-orm"; import db from "@/db/db"; import { soapLogs, type LogDirection, type SoapLogInsert } from "@/db/schema/SOAP/soap"; +import { XMLBuilder } from 'fast-xml-parser'; // for object→XML 변환 // XML 파싱용 타입 유틸리티: 스키마에서 XML 타입 생성 export type ToXMLFields = { @@ -203,42 +204,100 @@ export function processNestedArray( return items.map(item => converter(item, fkData)); } +// Helper: SOAP Envelope 빌더 +function buildSoapEnvelope(namespace: string, bodyContent: string = ''): string { + return ` + + + ${bodyContent} + +`; +} + +// Generic: JS object → XML string 변환 +function objectToXML(obj: Record): string { + const builder = new XMLBuilder({ + ignoreAttributes: false, + attributeNamePrefix: '@_', + format: false, + suppressEmptyNode: true, + }); + return builder.build(obj); +} + +// 범용 SOAP 응답 생성 함수 +// body는 XML string이거나 JS 객체(자동으로 XML 변환) +export function createSoapResponse( + namespace: string, + body: string | Record +): NextResponse { + const bodyXml = typeof body === 'string' ? body : objectToXML(body); + return new NextResponse(buildSoapEnvelope(namespace, bodyXml), { + headers: { 'Content-Type': 'text/xml; charset=utf-8' }, + }); +} + // 에러 응답 생성 -export function createErrorResponse(error: unknown): NextResponse { +// 기본: 기존 SOAP Fault 유지 +// 추가: namespace & elementName 전달 시 E 구조로 응답 (100자 제한) +export function createErrorResponse( + error: unknown, + namespace?: string, + elementName?: string +): NextResponse { console.error('API Error:', error); - - const errorResponse = ` - - - + + if (namespace && elementName) { + const rawMessage = error instanceof Error ? error.message : 'Unknown error'; + const truncatedMsg = rawMessage.length > 100 ? rawMessage.slice(0, 100) : rawMessage; + const body = `<${elementName}> + E + ${truncatedMsg} + `; + + return new NextResponse(buildSoapEnvelope(namespace, body), { + headers: { 'Content-Type': 'text/xml; charset=utf-8' }, + }); + } + + // Fallback: SOAP Fault (기존 호환) + const errorResponse = buildSoapEnvelope( + namespace || '', + ` soap:Server ${error instanceof Error ? ('[from eVCP]: ' + error.message) : 'Unknown error'} - - -`; - + ` + ); + return new NextResponse(errorResponse, { status: 500, - headers: { - 'Content-Type': 'text/xml; charset=utf-8', - }, + headers: { 'Content-Type': 'text/xml; charset=utf-8' }, }); } // 성공 응답 생성 -export function createSuccessResponse(namespace: string): NextResponse { - const xmlResponse = ` - - - -`; - - return new NextResponse(xmlResponse, { - headers: { - 'Content-Type': 'text/xml; charset=utf-8', - }, +// 기본: Body 비어있는 기존 형태 유지 +// elementName 전달 시 EV_TYPE(S/E) 및 EV_MESSAGE 포함 +export function createSuccessResponse( + namespace: string, + elementName?: string, + evType: 'S' | 'E' = 'S', + evMessage?: string +): NextResponse { + if (elementName) { + const msgTag = evMessage ? `${evMessage}` : ''; + const body = `<${elementName}> + ${evType} + ${msgTag} + `; + return new NextResponse(buildSoapEnvelope(namespace, body), { + headers: { 'Content-Type': 'text/xml; charset=utf-8' }, + }); + } + + // 기본(빈 Body) 응답 + return new NextResponse(buildSoapEnvelope(namespace), { + headers: { 'Content-Type': 'text/xml; charset=utf-8' }, }); } -- cgit v1.2.3