diff options
Diffstat (limited to 'lib/soap/mdg/utils.ts')
| -rw-r--r-- | lib/soap/mdg/utils.ts | 111 |
1 files changed, 85 insertions, 26 deletions
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<T> = { @@ -203,42 +204,100 @@ export function processNestedArray<T, U>( return items.map(item => converter(item, fkData)); } +// Helper: SOAP Envelope 빌더 +function buildSoapEnvelope(namespace: string, bodyContent: string = ''): string { + return `<?xml version="1.0" encoding="UTF-8"?> +<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tns="${namespace}"> + <soap:Body> + ${bodyContent} + </soap:Body> +</soap:Envelope>`; +} + +// Generic: JS object → XML string 변환 +function objectToXML(obj: Record<string, unknown>): 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<string, unknown> +): 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 전달 시 <EV_TYPE>E</EV_TYPE> 구조로 응답 (100자 제한) +export function createErrorResponse( + error: unknown, + namespace?: string, + elementName?: string +): NextResponse { console.error('API Error:', error); - - const errorResponse = `<?xml version="1.0" encoding="UTF-8"?> -<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> - <soap:Body> - <soap:Fault> + + 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}> + <EV_TYPE>E</EV_TYPE> + <EV_MESSAGE>${truncatedMsg}</EV_MESSAGE> + </${elementName}>`; + + return new NextResponse(buildSoapEnvelope(namespace, body), { + headers: { 'Content-Type': 'text/xml; charset=utf-8' }, + }); + } + + // Fallback: SOAP Fault (기존 호환) + const errorResponse = buildSoapEnvelope( + namespace || '', + `<soap:Fault> <faultcode>soap:Server</faultcode> <faultstring>${error instanceof Error ? ('[from eVCP]: ' + error.message) : 'Unknown error'}</faultstring> - </soap:Fault> - </soap:Body> -</soap:Envelope>`; - + </soap:Fault>` + ); + 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 = `<?xml version="1.0" encoding="UTF-8"?> -<soap:Envelope - xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" - xmlns:tns="${namespace}"> - <soap:Body> - </soap:Body> -</soap:Envelope>`; - - 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 ? `<EV_MESSAGE>${evMessage}</EV_MESSAGE>` : ''; + const body = `<${elementName}> + <EV_TYPE>${evType}</EV_TYPE> + ${msgTag} + </${elementName}>`; + 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' }, }); } |
