Skip to content

Commit 7c4d740

Browse files
committed
refactor: move common logic to createRestExportDocument
1 parent dddd867 commit 7c4d740

File tree

15 files changed

+177
-208
lines changed

15 files changed

+177
-208
lines changed

src/apitypes/graphql/graphql.document.ts

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,5 @@ export const buildGraphQLDocument: DocumentBuilder<GraphApiSchema> = async (pars
5252
}
5353

5454
export const dumpGraphQLDocument: DocumentDumper<GraphApiSchema> = (document) => {
55-
if (document.data) {
56-
return new Blob([printGraphApi(document.data)], { type: 'text/plain' })
57-
}
58-
if (document.source) {
59-
return document.source
60-
}
61-
throw new Error(`Document ${document.fileId} has neither data nor source`)
55+
return new Blob([printGraphApi(document.data)], { type: 'text/plain' })
6256
}

src/apitypes/rest/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
import { OpenAPIV3 } from 'openapi-types'
1818

19-
import { buildRestDocument, dumpRestDocument } from './rest.document'
19+
import { buildRestDocument, createRestExportDocument, dumpRestDocument } from './rest.document'
2020
import { REST_API_TYPE, REST_DOCUMENT_TYPE } from './rest.consts'
2121
import { compareRestOperationsData } from './rest.changes'
2222
import { buildRestOperations, createNormalizedOperationId } from './rest.operations'
@@ -35,4 +35,5 @@ export const restApiBuilder: ApiBuilder<OpenAPIV3.Document> = {
3535
dumpDocument: dumpRestDocument,
3636
compareOperationsData: compareRestOperationsData,
3737
createNormalizedOperationId: createNormalizedOperationId,
38+
createExportDocument: createRestExportDocument,
3839
}

src/apitypes/rest/rest.document.ts

Lines changed: 54 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,25 @@ import { convertObj } from 'swagger2openapi'
2020
import { REST_DOCUMENT_TYPE, REST_KIND_KEY } from './rest.consts'
2121
import type { RestDocumentInfo } from './rest.types'
2222

23-
import { DocumentBuilder, DocumentDumper, YAML_EXPORT_GROUP_FORMAT } from '../../types'
24-
import { FILE_FORMAT } from '../../consts'
25-
import { createBundlingErrorHandler, getBundledFileDataWithDependencies, getDocumentTitle } from '../../utils'
26-
import YAML from 'js-yaml'
23+
import {
24+
_TemplateResolver,
25+
DocumentBuilder,
26+
DocumentDumper,
27+
ExportDocument,
28+
HTML_EXPORT_GROUP_FORMAT,
29+
OperationsGroupExportFormat,
30+
} from '../../types'
31+
import { FILE_FORMAT, FILE_FORMAT_JSON } from '../../consts'
32+
import {
33+
createBundlingErrorHandler,
34+
EXPORT_FORMAT_TO_FILE_FORMAT,
35+
getBundledFileDataWithDependencies,
36+
getDocumentTitle,
37+
} from '../../utils'
38+
import { dump } from './rest.utils'
39+
import { generateHtmlPage } from '../../utils/export'
40+
import { removeOasExtensions } from '../../utils/removeOasExtensions'
41+
import { OpenApiExtensionKey } from '@netcracker/qubership-apihub-api-unifier'
2742

2843
const openApiDocumentMeta = (data: OpenAPIV3.Document): RestDocumentInfo => {
2944
if (typeof data !== 'object' || !data) {
@@ -99,8 +114,40 @@ export const buildRestDocument: DocumentBuilder<OpenAPIV3.Document> = async (par
99114
}
100115

101116
export const dumpRestDocument: DocumentDumper<OpenAPIV3.Document> = (document, format) => {
102-
if (format === YAML_EXPORT_GROUP_FORMAT) {
103-
return new Blob([YAML.dump(document.data)], { type: 'application/yaml' })
117+
return new Blob(...dump(document.data, format ?? FILE_FORMAT_JSON))
118+
}
119+
120+
export async function createRestExportDocument(
121+
filename: string,
122+
data: string,
123+
format: OperationsGroupExportFormat,
124+
packageName: string,
125+
version: string,
126+
templateResolver: _TemplateResolver,
127+
allowedOasExtensions?: OpenApiExtensionKey[],
128+
generatedHtmlExportDocuments?: ExportDocument[],
129+
): Promise<ExportDocument> {
130+
const exportFilename = `${getDocumentTitle(filename)}.${format}`
131+
const [d, bp] = dump(removeOasExtensions(JSON.parse(data), allowedOasExtensions), EXPORT_FORMAT_TO_FILE_FORMAT.get(format)!)
132+
133+
if (format === HTML_EXPORT_GROUP_FORMAT) {
134+
const htmlExportDocument = {
135+
data: await generateHtmlPage(
136+
d[0],
137+
getDocumentTitle(filename),
138+
packageName,
139+
version,
140+
templateResolver,
141+
true,
142+
),
143+
filename: exportFilename,
144+
}
145+
generatedHtmlExportDocuments?.push(htmlExportDocument)
146+
return htmlExportDocument
147+
}
148+
149+
return {
150+
data: new Blob(d, bp),
151+
filename: exportFilename,
104152
}
105-
return new Blob([JSON.stringify(document.data, undefined, 2)], { type: 'application/json' })
106153
}

src/apitypes/rest/rest.utils.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ import { OpenAPIV3 } from 'openapi-types'
1818
import { CustomTags } from './rest.types'
1919
import { API_AUDIENCE_EXTERNAL, API_AUDIENCE_INTERNAL, API_AUDIENCE_UNKNOWN, ApiAudience } from '../../types'
2020
import { isObject } from '@netcracker/qubership-apihub-json-crawl'
21-
import { CUSTOM_PARAMETER_API_AUDIENCE } from '../../consts'
21+
import { CUSTOM_PARAMETER_API_AUDIENCE, FILE_FORMAT_JSON, FILE_FORMAT_YAML } from '../../consts'
22+
import YAML from 'js-yaml'
2223

2324
export const getOperationBasePath = (servers?: OpenAPIV3.ServerObject[]): string => {
2425
if (!Array.isArray(servers) || !servers.length) { return '' }
@@ -65,3 +66,15 @@ export const resolveApiAudience = (info: unknown): ApiAudience => {
6566
apiAudience = [API_AUDIENCE_INTERNAL, API_AUDIENCE_EXTERNAL].includes(apiAudience) ? apiAudience : API_AUDIENCE_UNKNOWN
6667
return apiAudience
6768
}
69+
70+
export const dump = (value: unknown, format: typeof FILE_FORMAT_YAML | typeof FILE_FORMAT_JSON): [[string], BlobPropertyBag] => {
71+
if (format === FILE_FORMAT_YAML) {
72+
return [[YAML.dump(value)], { type: 'application/yaml' }]
73+
// return new Blob([YAML.dump(value)], { type: 'application/yaml' })
74+
}
75+
if (format === FILE_FORMAT_JSON) {
76+
return [[JSON.stringify(value, undefined, 2)], { type: 'application/json' }]
77+
// return new Blob([JSON.stringify(value, undefined, 2)], { type: 'application/json' })
78+
}
79+
throw new Error(`Unsupported format: ${format}`)
80+
}

src/builder.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import {
1919
BuildConfigBase,
2020
BuildConfigFile,
2121
BuildConfigRef,
22+
ExportDocument,
2223
FileId,
2324
isPublishBuildConfig,
2425
OperationId,
@@ -32,7 +33,6 @@ import {
3233
ResolvedVersionDocuments,
3334
VersionId,
3435
VersionsComparison,
35-
ZippableDocument,
3636
} from './types'
3737
import {
3838
ApiBuilder,
@@ -86,7 +86,7 @@ export const DEFAULT_RUN_OPTIONS: BuilderRunOptions = {
8686
export class PackageVersionBuilder implements IPackageVersionBuilder {
8787
apiBuilders: ApiBuilder[] = []
8888
documents = new Map<string, VersionDocument>()
89-
exportDocuments: ZippableDocument[] = []
89+
exportDocuments: ExportDocument[] = []
9090
exportFileName?: string
9191
operations = new Map<string, ApiOperation>()
9292
comparisons: VersionsComparison[] = []

src/components/package.ts

Lines changed: 8 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import {
2222
BuilderContext,
2323
BuildResult,
2424
BuildResultDto,
25-
HTML_EXPORT_GROUP_FORMAT,
25+
ExportDocument,
2626
PackageComparison,
2727
PackageComparisonOperations,
2828
PackageComparisons,
@@ -38,7 +38,6 @@ import { unknownApiBuilder } from '../apitypes'
3838
import { BUILD_TYPE, MESSAGE_SEVERITY, PACKAGE } from '../consts'
3939
import { takeIf, toPackageDocument } from '../utils'
4040
import { toVersionsComparisonDto } from '../utils/transformToDto'
41-
import { dumpRestDocument } from '../apitypes/rest/rest.document'
4241

4342
export interface ZipTool {
4443
// todo method should only accept Blob content, transformation is not a responsibility of this method
@@ -47,25 +46,6 @@ export interface ZipTool {
4746
buildResult: (options?: JSZip.JSZipGeneratorOptions) => Promise<any>
4847
}
4948

50-
export const createExportResult = async (
51-
buildResult: BuildResult,
52-
zip: ZipTool,
53-
ctx: BuilderContext,
54-
options?: JSZip.JSZipGeneratorOptions,
55-
): Promise<any> => {
56-
const { config: { format } } = ctx
57-
58-
for (const document of [...buildResult.documents.values()]) {
59-
// const apiBuilder = apiBuilders.find(({ types }) => types.includes(document.type)) || unknownApiBuilder
60-
// const data = apiBuilder.dumpDocument(document, format)
61-
const data = dumpRestDocument(document, format)
62-
63-
await zip.file(document.filename, data)
64-
}
65-
66-
return await zip.buildResult(options)
67-
}
68-
6949
export const createVersionPackage = async (
7050
buildResult: BuildResult,
7151
zip: ZipTool,
@@ -90,9 +70,9 @@ export const createVersionPackage = async (
9070
case BUILD_TYPE.EXPORT_REST_DOCUMENT:
9171
case BUILD_TYPE.EXPORT_REST_OPERATIONS_GROUP:
9272
if (buildResult.exportDocuments.length === 1) {
93-
return Buffer.from(await dumpRestDocument(buildResultDto.exportDocuments[0], ctx.config.format).arrayBuffer())
73+
return Buffer.from(await buildResultDto.exportDocuments[0].data.arrayBuffer())
9474
}
95-
await createExportDocumentDataFiles(zip, buildResultDto.exportDocuments, ctx)
75+
await createExportDocumentDataFiles(zip, buildResultDto.exportDocuments)
9676
return await zip.buildResult(options)
9777
}
9878

@@ -150,6 +130,7 @@ const writeDocumentsToZip = async (zip: ZipTool, documents: ZippableDocument[],
150130

151131
const apiBuilder =
152132
apiBuilders.find(({ types }) => types.includes(document.type)) || unknownApiBuilder
133+
// @ts-ignore todo
153134
const data = apiBuilder.dumpDocument(document, format)
154135
await zip.file(document.filename, data)
155136
}
@@ -160,8 +141,10 @@ const createDocumentDataFiles = async (zip: ZipTool, documents: VersionDocument[
160141
await writeDocumentsToZip(documentsDir, documents, ctx)
161142
}
162143

163-
const createExportDocumentDataFiles = async (zip: ZipTool, documents: ZippableDocument[], ctx: BuilderContext): Promise<void> => {
164-
await writeDocumentsToZip(zip, documents, ctx)
144+
const createExportDocumentDataFiles = async (zip: ZipTool, documents: ExportDocument[]): Promise<void> => {
145+
for (const document of documents) {
146+
await zip.file(document.filename, document.data)
147+
}
165148
}
166149

167150
const createOperationsFile = (zip: ZipTool, operations: Map<string, ApiOperation>): void => {

src/strategies/export-rest-document.strategy.ts

Lines changed: 10 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -19,48 +19,28 @@ import {
1919
BuilderStrategy,
2020
BuildResult,
2121
BuildTypeContexts,
22+
DocumentExporter,
23+
ExportDocument,
2224
ExportRestDocumentBuildConfig,
2325
HTML_EXPORT_GROUP_FORMAT,
2426
OperationsGroupExportFormat,
25-
ZippableDocument,
2627
} from '../types'
27-
import { REST_DOCUMENT_TYPE } from '../apitypes'
2828
import { getDocumentTitle, getSplittedVersionKey } from '../utils'
2929
import { OpenApiExtensionKey } from '@netcracker/qubership-apihub-api-unifier'
30-
import { removeOasExtensions } from '../utils/removeOasExtensions'
31-
import {
32-
createCommonStaticExportDocuments,
33-
createExportDocument,
34-
createSingleFileExportName,
35-
generateHtmlPage,
36-
} from '../utils/export'
30+
import { createCommonStaticExportDocuments, createSingleFileExportName } from '../utils/export'
31+
import { createRestExportDocument } from '../apitypes/rest/rest.document'
3732

3833
async function createTransformedDocument(
3934
file: File,
4035
format: OperationsGroupExportFormat,
4136
packageName: string,
4237
version: string,
4338
templateResolver: _TemplateResolver,
39+
createExportDocument: DocumentExporter,
4440
allowedOasExtensions?: OpenApiExtensionKey[],
45-
): Promise<ZippableDocument> {
46-
const data = removeOasExtensions(JSON.parse(await file.text()), allowedOasExtensions)
47-
48-
if (format === HTML_EXPORT_GROUP_FORMAT) {
49-
return createExportDocument(
50-
`${getDocumentTitle(file.name)}.${HTML_EXPORT_GROUP_FORMAT}`,
51-
await generateHtmlPage(JSON.stringify(data, undefined, 2), getDocumentTitle(file.name), packageName, version, templateResolver),
52-
)
53-
}
54-
55-
return {
56-
data: data,
57-
fileId: file.name,
58-
type: REST_DOCUMENT_TYPE.OAS3, // todo one of REST_DOCUMENT_TYPE
59-
description: '',
60-
publish: true,
61-
filename: `${getDocumentTitle(file.name)}.${format}`,
62-
source: file,
63-
}
41+
generatedHtmlExportDocuments?: ExportDocument[],
42+
): Promise<ExportDocument> {
43+
return createExportDocument?.(file.name, await file.text(), format, packageName, version, templateResolver, allowedOasExtensions, generatedHtmlExportDocuments)
6444
}
6545

6646
export class ExportRestDocumentStrategy implements BuilderStrategy {
@@ -77,10 +57,10 @@ export class ExportRestDocumentStrategy implements BuilderStrategy {
7757
)
7858
const { name: packageName } = await packageResolver(packageId)
7959

80-
buildResult.exportDocuments.push(await createTransformedDocument(file, format, packageName, version, templateResolver, allowedOasExtensions))
60+
buildResult.exportDocuments.push(await createTransformedDocument(file, format, packageName, version, templateResolver, createRestExportDocument, allowedOasExtensions))
8161

8262
if (format === HTML_EXPORT_GROUP_FORMAT) {
83-
buildResult.exportDocuments.push(...await createCommonStaticExportDocuments(packageName, version, templateResolver, buildResult.exportDocuments[0].fileId))
63+
buildResult.exportDocuments.push(...await createCommonStaticExportDocuments(packageName, version, templateResolver, buildResult.exportDocuments[0].filename))
8464
buildResult.exportFileName = createSingleFileExportName(packageId, version, getDocumentTitle(file.name), 'zip')
8565
return buildResult
8666
}

0 commit comments

Comments
 (0)