Skip to content

Commit fc08305

Browse files
authored
Merge pull request #28 from Netcracker/feature/export-build-tasks-support-fixes
fix: export issues
2 parents 73a46bd + 5594cde commit fc08305

36 files changed

+669
-578
lines changed

package-lock.json

Lines changed: 0 additions & 90 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@
6767
"jest-extended": "^4.0.2",
6868
"mime-types": "^3.0.1",
6969
"openapi-types": "^12.1.0",
70-
"rollup-plugin-copy": "^3.5.0",
7170
"ts-jest": "29.1.2",
7271
"ts-node": "^10.9.1",
7372
"tslint": "^6.1.3",

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,24 @@ 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+
ExportFormat,
29+
} from '../../types'
30+
import { FILE_FORMAT, FILE_FORMAT_HTML, FILE_FORMAT_JSON } from '../../consts'
31+
import {
32+
createBundlingErrorHandler,
33+
EXPORT_FORMAT_TO_FILE_FORMAT,
34+
getBundledFileDataWithDependencies,
35+
getDocumentTitle,
36+
} from '../../utils'
37+
import { dump } from './rest.utils'
38+
import { generateHtmlPage } from '../../utils/export'
39+
import { removeOasExtensions } from '../../utils/removeOasExtensions'
40+
import { OpenApiExtensionKey } from '@netcracker/qubership-apihub-api-unifier'
2741

2842
const openApiDocumentMeta = (data: OpenAPIV3.Document): RestDocumentInfo => {
2943
if (typeof data !== 'object' || !data) {
@@ -99,8 +113,41 @@ export const buildRestDocument: DocumentBuilder<OpenAPIV3.Document> = async (par
99113
}
100114

101115
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' })
116+
return new Blob(...dump(document.data, format ?? FILE_FORMAT_JSON))
117+
}
118+
119+
export async function createRestExportDocument(
120+
filename: string,
121+
data: string,
122+
format: ExportFormat,
123+
packageName: string,
124+
version: string,
125+
templateResolver: _TemplateResolver,
126+
allowedOasExtensions?: OpenApiExtensionKey[],
127+
generatedHtmlExportDocuments?: ExportDocument[],
128+
addBackLink?: boolean,
129+
): Promise<ExportDocument> {
130+
const exportFilename = `${getDocumentTitle(filename)}.${format}`
131+
const [[document], blobProperties] = dump(removeOasExtensions(JSON.parse(data), allowedOasExtensions), EXPORT_FORMAT_TO_FILE_FORMAT.get(format)!)
132+
133+
if (format === FILE_FORMAT_HTML) {
134+
const htmlExportDocument = {
135+
data: await generateHtmlPage(
136+
document,
137+
getDocumentTitle(filename),
138+
packageName,
139+
version,
140+
templateResolver,
141+
addBackLink,
142+
),
143+
filename: exportFilename,
144+
}
145+
generatedHtmlExportDocuments?.push(htmlExportDocument)
146+
return htmlExportDocument
147+
}
148+
149+
return {
150+
data: new Blob([document], blobProperties),
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+
type TextBlobConstructorParameters = [[string], BlobPropertyBag]
71+
72+
export const dump = (value: unknown, format: typeof FILE_FORMAT_YAML | typeof FILE_FORMAT_JSON): TextBlobConstructorParameters => {
73+
if (format === FILE_FORMAT_YAML) {
74+
return [[YAML.dump(value)], { type: 'application/yaml' }]
75+
}
76+
if (format === FILE_FORMAT_JSON) {
77+
return [[JSON.stringify(value, undefined, 2)], { type: 'application/json' }]
78+
}
79+
throw new Error(`Unsupported format: ${format}`)
80+
}

src/builder.ts

Lines changed: 4 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[] = []
@@ -816,6 +816,8 @@ export class PackageVersionBuilder implements IPackageVersionBuilder {
816816
this.packageChangesCache.clear()
817817
this.operations.clear()
818818
this.documents.clear()
819+
this.exportDocuments = []
820+
this.exportFileName = undefined
819821
this.comparisons = []
820822

821823
this.notifications = []

src/components/package.ts

Lines changed: 11 additions & 41 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,
@@ -36,9 +36,8 @@ import {
3636
} from '../types'
3737
import { unknownApiBuilder } from '../apitypes'
3838
import { BUILD_TYPE, MESSAGE_SEVERITY, PACKAGE } from '../consts'
39-
import { takeIf, toPackageDocument } from '../utils'
39+
import { EXPORT_FORMAT_TO_FILE_FORMAT, 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,
@@ -85,27 +65,14 @@ export const createVersionPackage = async (
8565

8666
const documents = buildResultDto.merged ? [buildResultDto.merged] : [...buildResultDto.documents.values()]
8767

88-
// todo refactor accordingly to new reqs
8968
switch (buildResult.config.buildType) {
90-
case BUILD_TYPE.EXPORT_REST_DOCUMENT:
91-
if (buildResult.exportDocuments.length === 1) {
92-
return Buffer.from(await dumpRestDocument(buildResultDto.exportDocuments[0], ctx.config.format).arrayBuffer())
93-
}
94-
await createExportDocumentDataFiles(zip, buildResultDto.exportDocuments, ctx)
95-
return await zip.buildResult(options)
96-
9769
case BUILD_TYPE.EXPORT_VERSION:
98-
if (buildResult.exportDocuments.length === 1) {
99-
return Buffer.from(await dumpRestDocument(buildResultDto.exportDocuments[0], ctx.config.format).arrayBuffer())
100-
}
101-
await createExportDocumentDataFiles(zip, buildResultDto.exportDocuments, ctx)
102-
return await zip.buildResult(options)
103-
70+
case BUILD_TYPE.EXPORT_REST_DOCUMENT:
10471
case BUILD_TYPE.EXPORT_REST_OPERATIONS_GROUP:
10572
if (buildResult.exportDocuments.length === 1) {
106-
return Buffer.from(await dumpRestDocument(buildResultDto.exportDocuments[0], ctx.config.format).arrayBuffer())
73+
return Buffer.from(await buildResultDto.exportDocuments[0].data.arrayBuffer())
10774
}
108-
await createExportDocumentDataFiles(zip, buildResultDto.exportDocuments, ctx)
75+
await createExportDocumentDataFiles(zip, buildResultDto.exportDocuments)
10976
return await zip.buildResult(options)
11077
}
11178

@@ -163,7 +130,8 @@ const writeDocumentsToZip = async (zip: ZipTool, documents: ZippableDocument[],
163130

164131
const apiBuilder =
165132
apiBuilders.find(({ types }) => types.includes(document.type)) || unknownApiBuilder
166-
const data = apiBuilder.dumpDocument(document, format)
133+
const documentFormat = EXPORT_FORMAT_TO_FILE_FORMAT.get(format!)
134+
const data = apiBuilder.dumpDocument(document, documentFormat)
167135
await zip.file(document.filename, data)
168136
}
169137
}
@@ -173,8 +141,10 @@ const createDocumentDataFiles = async (zip: ZipTool, documents: VersionDocument[
173141
await writeDocumentsToZip(documentsDir, documents, ctx)
174142
}
175143

176-
const createExportDocumentDataFiles = async (zip: ZipTool, documents: ZippableDocument[], ctx: BuilderContext): Promise<void> => {
177-
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+
}
178148
}
179149

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

0 commit comments

Comments
 (0)