- 저장본에 sentinel 유지 및 편집기 사용 시 실주소로 치환 - 응답유형별 서버 실주소 계산 유틸 함수 추가
This commit is contained in:
@@ -29,6 +29,10 @@
|
|||||||
// (enricher 는 oauth·api_key 를 모두 apiKey-in-header 로 모델링하므로 scheme.type 만으로 구분 불가)
|
// (enricher 는 oauth·api_key 를 모두 apiKey-in-header 로 모델링하므로 scheme.type 만으로 구분 불가)
|
||||||
var djbAuthType = '';
|
var djbAuthType = '';
|
||||||
|
|
||||||
|
// 저장 스펙의 서버 자리표시자. 포탈이 제공 시점에 응답유형(sample/mock/gw)별 실주소로 치환한다.
|
||||||
|
// (포탈 DjbTestbedSpecServerRewriter.SERVER_SENTINEL 과 동일 문자열 — 양쪽을 같이 바꿔야 한다)
|
||||||
|
const SERVER_SENTINEL = 'http://swagger-server-url';
|
||||||
|
|
||||||
// ============================================================
|
// ============================================================
|
||||||
// 2. 유틸
|
// 2. 유틸
|
||||||
// ============================================================
|
// ============================================================
|
||||||
@@ -108,7 +112,13 @@
|
|||||||
// ============================================================
|
// ============================================================
|
||||||
// 3. OpenAPI 스펙 빌더 (state.data → OpenAPI 3.1 객체)
|
// 3. OpenAPI 스펙 빌더 (state.data → OpenAPI 3.1 객체)
|
||||||
// ============================================================
|
// ============================================================
|
||||||
function buildOpenApiSpec() {
|
/**
|
||||||
|
* state.data → OpenAPI 3.1 객체.
|
||||||
|
*
|
||||||
|
* @param resolveHost true 면 응답유형별 실주소를 서버에 부착(편집기 미리보기·다운로드용),
|
||||||
|
* false/생략이면 서버를 sentinel 로 남긴다(저장본 — 포탈이 제공 시점에 치환).
|
||||||
|
*/
|
||||||
|
function buildOpenApiSpec(resolveHost) {
|
||||||
const d = state.data;
|
const d = state.data;
|
||||||
syncResponseExamplesFromSchema(); // 응답 예제 = 응답 정보(스키마·예제값) 파생 — 저장/미리보기 일관
|
syncResponseExamplesFromSchema(); // 응답 예제 = 응답 정보(스키마·예제값) 파생 — 저장/미리보기 일관
|
||||||
const spec = {
|
const spec = {
|
||||||
@@ -195,21 +205,19 @@
|
|||||||
// - gw : djb.gateway.base-url (PortalProperty) → [gw호스트 + 어댑터경로 + 경로]
|
// - gw : djb.gateway.base-url (PortalProperty) → [gw호스트 + 어댑터경로 + 경로]
|
||||||
// - mock : Mock Server URL(전체 URL) → [mock URL 그대로] (어댑터/오퍼레이션 경로 미부착)
|
// - mock : Mock Server URL(전체 URL) → [mock URL 그대로] (어댑터/오퍼레이션 경로 미부착)
|
||||||
// - 그 외 : 호스트 없음 → [어댑터경로 + 경로]
|
// - 그 외 : 호스트 없음 → [어댑터경로 + 경로]
|
||||||
var _rt = (d.portal && d.portal.responseType) || 'sample';
|
//
|
||||||
var _host;
|
// 단 이 실주소 부착은 "미리보기/다운로드" 표현에만 적용한다(resolveHost=true).
|
||||||
var _pathKey = op.path.value;
|
// 저장본은 서버를 sentinel 로 남겨 환경 독립을 유지하고, 포탈이 제공 시점에 응답유형별 실주소로
|
||||||
if (_rt === 'gw') {
|
// 치환한다(DjbTestbedSpecServerRewriter). 저장본에 실주소를 굳히면 포탈의 재치환이 무력화되고
|
||||||
_host = (window.DJB_CTX && window.DJB_CTX.gwAddress) || 'http://127.0.0.1:39310';
|
// 저장 환경(dev)의 GW 주소가 다른 환경까지 따라간다.
|
||||||
} else if (_rt === 'mock') {
|
if (resolveHost) {
|
||||||
// Mock 은 전체 호출 URL. origin=서버, pathname(+query)=경로로 분해해 경로가 뒤에 덧붙지 않도록 한다.
|
var _resolved = resolveSpecServer();
|
||||||
var _mk = splitFullUrl((d.portal && d.portal.mockUrl) || '');
|
if (_resolved.host) spec.servers = [{ url: _resolved.host }];
|
||||||
_host = _mk.origin;
|
spec.paths[_resolved.path] = { [op.method.value.toLowerCase()]: operation };
|
||||||
_pathKey = _mk.path;
|
|
||||||
} else {
|
} else {
|
||||||
_host = '';
|
spec.servers = [{ url: SERVER_SENTINEL }];
|
||||||
|
spec.paths[op.path.value] = { [op.method.value.toLowerCase()]: operation };
|
||||||
}
|
}
|
||||||
if (_host) spec.servers = [{ url: _host }];
|
|
||||||
spec.paths[_pathKey] = { [op.method.value.toLowerCase()]: operation };
|
|
||||||
|
|
||||||
// 보안 스킴
|
// 보안 스킴
|
||||||
d.securitySchemes.forEach(s => {
|
d.securitySchemes.forEach(s => {
|
||||||
@@ -981,6 +989,24 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 응답유형별 실주소 { host, path }. 편집기 미리보기·다운로드에서만 사용(저장본은 sentinel).
|
||||||
|
// - gw : DJB_CTX.gwAddress + [어댑터경로 + 경로]
|
||||||
|
// - mock : Mock Server URL 을 origin/path 로 분해 → 경로가 뒤에 덧붙지 않음
|
||||||
|
// - 그 외 : 호스트 없음 + [어댑터경로 + 경로]
|
||||||
|
function resolveSpecServer() {
|
||||||
|
var d = state.data;
|
||||||
|
var rt = (d.portal && d.portal.responseType) || 'sample';
|
||||||
|
var path = d.operation.path.value;
|
||||||
|
if (rt === 'gw') {
|
||||||
|
return { host: (window.DJB_CTX && window.DJB_CTX.gwAddress) || 'http://127.0.0.1:39310', path: path };
|
||||||
|
}
|
||||||
|
if (rt === 'mock') {
|
||||||
|
var mk = splitFullUrl((d.portal && d.portal.mockUrl) || '');
|
||||||
|
return { host: mk.origin, path: mk.path };
|
||||||
|
}
|
||||||
|
return { host: '', path: path };
|
||||||
|
}
|
||||||
|
|
||||||
// 전체 URL → { origin, path }. Mock Server URL 을 서버+경로로 분해(경로를 별도로 덧붙이지 않기 위함).
|
// 전체 URL → { origin, path }. Mock Server URL 을 서버+경로로 분해(경로를 별도로 덧붙이지 않기 위함).
|
||||||
function splitFullUrl(u) {
|
function splitFullUrl(u) {
|
||||||
u = (u || '').trim();
|
u = (u || '').trim();
|
||||||
@@ -1103,7 +1129,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function mountSwagger() {
|
function mountSwagger() {
|
||||||
const spec = buildOpenApiSpec();
|
// 미리보기는 실주소로 — sentinel 이 가짜 주소로 보이면 안 된다.
|
||||||
|
const spec = buildOpenApiSpec(true);
|
||||||
swaggerInstance = SwaggerUIBundle({
|
swaggerInstance = SwaggerUIBundle({
|
||||||
spec: spec,
|
spec: spec,
|
||||||
domNode: $('#preview-swagger'),
|
domNode: $('#preview-swagger'),
|
||||||
@@ -1121,7 +1148,7 @@
|
|||||||
|
|
||||||
function updateMonacoFromState() {
|
function updateMonacoFromState() {
|
||||||
if (!monacoReady) return;
|
if (!monacoReady) return;
|
||||||
const spec = buildOpenApiSpec();
|
const spec = buildOpenApiSpec(true); // YAML 미리보기도 실주소 표시
|
||||||
const yaml = jsyaml.dump(spec, { noRefs: true, lineWidth: 120 });
|
const yaml = jsyaml.dump(spec, { noRefs: true, lineWidth: 120 });
|
||||||
if (monacoEditor.getValue() !== yaml) monacoEditor.setValue(yaml);
|
if (monacoEditor.getValue() !== yaml) monacoEditor.setValue(yaml);
|
||||||
}
|
}
|
||||||
@@ -1620,7 +1647,7 @@
|
|||||||
// 16. Export
|
// 16. Export
|
||||||
// ============================================================
|
// ============================================================
|
||||||
function downloadSpec(format) {
|
function downloadSpec(format) {
|
||||||
const spec = buildOpenApiSpec();
|
const spec = buildOpenApiSpec(true); // 편집기 다운로드는 실주소 산출물
|
||||||
if (format === 'yaml') { doDownload(jsyaml.dump(spec, { noRefs: true }), 'text/yaml', 'yaml'); return; }
|
if (format === 'yaml') { doDownload(jsyaml.dump(spec, { noRefs: true }), 'text/yaml', 'yaml'); return; }
|
||||||
if (format === 'json') { doDownload(JSON.stringify(spec, null, 2), 'application/json', 'json'); return; }
|
if (format === 'json') { doDownload(JSON.stringify(spec, null, 2), 'application/json', 'json'); return; }
|
||||||
// html — 폐쇄망 자립: 벤더 swagger css/js 를 fetch 해 인라인
|
// html — 폐쇄망 자립: 벤더 swagger css/js 를 fetch 해 인라인
|
||||||
@@ -2023,6 +2050,7 @@
|
|||||||
function saveSpec(temp) {
|
function saveSpec(temp) {
|
||||||
var ctx = window.DJB_CTX || {};
|
var ctx = window.DJB_CTX || {};
|
||||||
if (!ctx.saveUrl || !ctx.eaiSvcName) { toast('저장 대상이 없습니다', 'error'); return; }
|
if (!ctx.saveUrl || !ctx.eaiSvcName) { toast('저장 대상이 없습니다', 'error'); return; }
|
||||||
|
// 저장본은 sentinel 유지 — 실주소는 포탈이 제공 시점에 응답유형별로 치환한다.
|
||||||
var spec = buildOpenApiSpec();
|
var spec = buildOpenApiSpec();
|
||||||
var d = state.data;
|
var d = state.data;
|
||||||
var reqEx = (d.examples && d.examples.request && d.examples.request[d.requestBody && d.requestBody.mediaType || 'application/json'] || {}).default || '';
|
var reqEx = (d.examples && d.examples.request && d.examples.request[d.requestBody && d.requestBody.mediaType || 'application/json'] || {}).default || '';
|
||||||
|
|||||||
Reference in New Issue
Block a user