Skip to content

Commit 874f81f

Browse files
committed
feat: use templateResolver to allow template overriding
1 parent b72c9e1 commit 874f81f

File tree

11 files changed

+97
-51
lines changed

11 files changed

+97
-51
lines changed

src/builder.ts

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,9 @@ import { BuildStrategy, ChangelogStrategy, DocumentGroupStrategy, PrefixGroupsCh
7474
import { BuilderStrategyContext } from './builder-strategy'
7575
import { MergedDocumentGroupStrategy } from './strategies/merged-document-group.strategy'
7676
import { asyncDebugPerformance } from './utils/logs'
77-
// import { ExportRestOperationsGroupStrategy } from './strategies/rest-operations-group.strategy'
7877
import { ExportVersionStrategy } from './strategies/export-version.strategy'
7978
import { ExportRestDocumentStrategy } from './strategies/export-rest-document.strategy'
79+
import { ExportRestOperationsGroupStrategy } from './strategies/rest-operations-group.strategy'
8080

8181
export const DEFAULT_RUN_OPTIONS: BuilderRunOptions = {
8282
cleanCache: false,
@@ -182,6 +182,7 @@ export class PackageVersionBuilder implements IPackageVersionBuilder {
182182
// todo only used in build strategy, move to the dedicated BuilderContext subtype
183183
basePath: basePath,
184184
versionDeprecatedResolver: this.versionDeprecatedResolver.bind(this),
185+
templateResolver: this.templateResolver.bind(this),
185186
parsedFileResolver: this.parsedFileResolver.bind(this),
186187
rawDocumentResolver: this.rawDocumentResolver.bind(this),
187188
operationResolver: (operationId: OperationId) => this.operations.get(operationId) ?? null,
@@ -191,7 +192,7 @@ export class PackageVersionBuilder implements IPackageVersionBuilder {
191192
builderRunOptions: this.builderRunOptions,
192193
groupDocumentsResolver: this.groupDocumentsResolver.bind(this),
193194
versionDocumentsResolver: this.versionDocumentsResolver.bind(this),
194-
templateResolver: this.params.resolvers.templateResolver,
195+
groupExportTemplateResolver: this.params.resolvers.groupExportTemplateResolver,
195196
versionLabels: this.config.metadata?.versionLabels as Array<string>,
196197
}
197198
}
@@ -259,7 +260,6 @@ export class PackageVersionBuilder implements IPackageVersionBuilder {
259260
}
260261

261262
if (buildType === BUILD_TYPE.EXPORT_REST_OPERATIONS_GROUP) {
262-
const { ExportRestOperationsGroupStrategy } = await import('./strategies/rest-operations-group.strategy')
263263
builderStrategyContext.setStrategy(new ExportRestOperationsGroupStrategy())
264264
}
265265

@@ -287,6 +287,21 @@ export class PackageVersionBuilder implements IPackageVersionBuilder {
287287
return await this.parseFile(fileId, source)
288288
}
289289

290+
async templateResolver(
291+
templatePath: string,
292+
): Promise<Blob> {
293+
if (!this.params.resolvers.templateResolver) {
294+
throw new Error('templateResolver is not provided')
295+
}
296+
297+
const template = await this.params.resolvers.templateResolver(templatePath)
298+
if (!template) {
299+
throw new Error(`Template ${templatePath} is missing`)
300+
}
301+
302+
return template
303+
}
304+
290305
async rawDocumentResolver(
291306
version: VersionId,
292307
packageId: PackageId,

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

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616

1717
import {
18+
_TemplateResolver,
1819
BuilderStrategy,
1920
BuildResult,
2021
BuildTypeContexts,
@@ -30,23 +31,24 @@ import { removeOasExtensions } from '../utils/removeOasExtensions'
3031
import {
3132
createCommonStaticExportDocuments,
3233
createExportDocument,
33-
generateHtmlPage,
3434
createSingleFileExportName,
35+
generateHtmlPage,
3536
} from '../utils/export'
3637

3738
async function createTransformedDocument(
3839
file: File,
3940
format: OperationsGroupExportFormat,
4041
packageId: string,
4142
version: string,
43+
templateResolver: _TemplateResolver,
4244
allowedOasExtensions?: OpenApiExtensionKey[],
4345
): Promise<ZippableDocument> {
4446
const data = removeOasExtensions(JSON.parse(await file.text()), allowedOasExtensions)
4547

4648
if (format === HTML_EXPORT_GROUP_FORMAT) {
4749
return createExportDocument(
4850
`${getDocumentTitle(file.name)}.${HTML_EXPORT_GROUP_FORMAT}`,
49-
await generateHtmlPage(JSON.stringify(data, undefined, 2), getDocumentTitle(file.name), packageId, version),
51+
await generateHtmlPage(JSON.stringify(data, undefined, 2), getDocumentTitle(file.name), packageId, version, templateResolver),
5052
)
5153
}
5254

@@ -64,19 +66,19 @@ async function createTransformedDocument(
6466
export class ExportRestDocumentStrategy implements BuilderStrategy {
6567
async execute(config: ExportRestDocumentBuildConfig, buildResult: BuildResult, contexts: BuildTypeContexts): Promise<BuildResult> {
6668
const { builderContext } = contexts
67-
const builderContextObject = builderContext(config)
69+
const { rawDocumentResolver, templateResolver } = builderContext(config)
6870
const { packageId, version, documentId, format, allowedOasExtensions } = config
6971

70-
const file = await builderContextObject.rawDocumentResolver(
72+
const file = await rawDocumentResolver(
7173
version,
7274
packageId,
7375
documentId, //document.slug,
7476
)
7577

76-
buildResult.exportDocuments.push(await createTransformedDocument(file, format, packageId, version, allowedOasExtensions))
78+
buildResult.exportDocuments.push(await createTransformedDocument(file, format, packageId, version, templateResolver, allowedOasExtensions))
7779

7880
if (format === HTML_EXPORT_GROUP_FORMAT) {
79-
buildResult.exportDocuments.push(...await createCommonStaticExportDocuments(packageId, version, buildResult.exportDocuments[0].fileId))
81+
buildResult.exportDocuments.push(...await createCommonStaticExportDocuments(packageId, version, templateResolver, buildResult.exportDocuments[0].fileId))
8082
buildResult.exportFileName = createSingleFileExportName(packageId, version, getDocumentTitle(file.name), 'zip')
8183
return buildResult
8284
}

src/strategies/export-version.strategy.ts

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616

1717
import {
18+
_TemplateResolver,
1819
BuilderStrategy,
1920
BuildResult,
2021
BuildTypeContexts,
@@ -62,6 +63,7 @@ async function createTransformedDocument(
6263
packageId: string,
6364
version: string,
6465
generatedHtmlExportDocuments: ZippableDocument[],
66+
templateResolver: _TemplateResolver,
6567
allowedOasExtensions?: OpenApiExtensionKey[],
6668
): Promise<ZippableDocument> {
6769
const { fileId, type } = document
@@ -71,7 +73,7 @@ async function createTransformedDocument(
7173
if (isRestDocument(document) && format === HTML_EXPORT_GROUP_FORMAT) {
7274
const htmlExportDocument = createExportDocument(
7375
`${getDocumentTitle(file.name)}.${HTML_EXPORT_GROUP_FORMAT}`,
74-
await generateHtmlPage(JSON.stringify(removeOasExtensions(JSON.parse(data), allowedOasExtensions), undefined, 2), getDocumentTitle(file.name), packageId, version, true),
76+
await generateHtmlPage(JSON.stringify(removeOasExtensions(JSON.parse(data), allowedOasExtensions), undefined, 2), getDocumentTitle(file.name), packageId, version, templateResolver, true),
7577
)
7678
generatedHtmlExportDocuments.push(htmlExportDocument)
7779
return htmlExportDocument
@@ -91,29 +93,29 @@ async function createTransformedDocument(
9193
export class ExportVersionStrategy implements BuilderStrategy {
9294
async execute(config: ExportVersionBuildConfig, buildResult: BuildResult, contexts: BuildTypeContexts): Promise<BuildResult> {
9395
const { builderContext } = contexts
94-
const builderContextObject = builderContext(config)
96+
const { versionDocumentsResolver, rawDocumentResolver, templateResolver } = builderContext(config)
9597
const { packageId, version, format = JSON_EXPORT_GROUP_FORMAT, allowedOasExtensions } = config
9698

97-
const { documents } = await builderContextObject.versionDocumentsResolver(
99+
const { documents } = await versionDocumentsResolver(
98100
version,
99101
packageId,
100102
) ?? { documents: [] }
101103

102104
const generatedHtmlExportDocuments: ZippableDocument[] = []
103105
const transformedDocuments = await Promise.all(documents.map(async document => {
104-
const file = await builderContextObject.rawDocumentResolver(version, packageId, document.slug)
105-
return await createTransformedDocument(document, file, format, packageId, version, generatedHtmlExportDocuments, allowedOasExtensions)
106+
const file = await rawDocumentResolver(version, packageId, document.slug)
107+
return await createTransformedDocument(document, file, format, packageId, version, generatedHtmlExportDocuments, templateResolver, allowedOasExtensions)
106108
}))
107109

108110
buildResult.exportDocuments.push(...transformedDocuments)
109111

110112
const restDocuments = documents.filter(isRestDocument)
111113
if (format === HTML_EXPORT_GROUP_FORMAT && restDocuments.length > 0) {
112-
buildResult.exportDocuments.push(...await createCommonStaticExportDocuments(packageId, version))
114+
buildResult.exportDocuments.push(...await createCommonStaticExportDocuments(packageId, version, templateResolver))
113115
const readme = buildResult.exportDocuments.find(({ fileId }) => fileId.toLowerCase() === 'readme.md')?.description
114116

115117
if (restDocuments.length > 1 || readme) {
116-
buildResult.exportDocuments.push(createExportDocument('index.html', await generateIndexHtmlPage(packageId, version, generatedHtmlExportDocuments, readme)))
118+
buildResult.exportDocuments.push(createExportDocument('index.html', await generateIndexHtmlPage(packageId, version, generatedHtmlExportDocuments, templateResolver, readme)))
117119
}
118120
}
119121

src/strategies/merged-document-group.strategy.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ export class MergedDocumentGroupStrategy implements BuilderStrategy {
6464
const { builderContext } = contexts
6565
const builderContextObject = builderContext(config)
6666

67-
const template = await builderContextObject.templateResolver?.(
67+
const template = await builderContextObject.groupExportTemplateResolver?.(
6868
apiType,
6969
version,
7070
packageId,

src/strategies/rest-operations-group.strategy.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616

1717
import {
18+
_TemplateResolver,
1819
BuilderStrategy,
1920
BuildResult,
2021
BuildTypeContexts,
@@ -57,6 +58,7 @@ export class ExportRestOperationsGroupStrategy implements BuilderStrategy {
5758

5859
async function exportMergedDocument(config: ExportRestOperationsGroupBuildConfig, buildResult: BuildResult, contexts: BuildTypeContexts): Promise<BuildResult> {
5960
const { packageId, version, groupName, format = JSON_EXPORT_GROUP_FORMAT, allowedOasExtensions } = config
61+
const { templateResolver } = contexts.builderContext(config)
6062

6163
await new MergedDocumentGroupStrategy().execute({
6264
...config,
@@ -71,10 +73,10 @@ async function exportMergedDocument(config: ExportRestOperationsGroupBuildConfig
7173
if (format === HTML_EXPORT_GROUP_FORMAT) {
7274
const htmlExportDocument = createExportDocument(
7375
`${getDocumentTitle(buildResult.merged.filename)}.${HTML_EXPORT_GROUP_FORMAT}`,
74-
await generateHtmlPage(JSON.stringify(removeOasExtensions(buildResult.merged?.data, allowedOasExtensions), undefined, 2), getDocumentTitle(buildResult.merged.filename), packageId, version, false),
76+
await generateHtmlPage(JSON.stringify(removeOasExtensions(buildResult.merged?.data, allowedOasExtensions), undefined, 2), getDocumentTitle(buildResult.merged.filename), packageId, version, templateResolver, false),
7577
)
7678
buildResult.exportDocuments.push(htmlExportDocument)
77-
buildResult.exportDocuments.push(...await createCommonStaticExportDocuments(packageId, version, htmlExportDocument.filename))
79+
buildResult.exportDocuments.push(...await createCommonStaticExportDocuments(packageId, version, templateResolver, htmlExportDocument.filename))
7880
buildResult.exportFileName = `${packageId}_${version}_${groupName}.zip`
7981
return buildResult
8082
}
@@ -94,6 +96,7 @@ async function exportMergedDocument(config: ExportRestOperationsGroupBuildConfig
9496

9597
async function exportReducedDocuments(config: ExportRestOperationsGroupBuildConfig, buildResult: BuildResult, contexts: BuildTypeContexts): Promise<BuildResult> {
9698
const { packageId, version, groupName, format = JSON_EXPORT_GROUP_FORMAT, allowedOasExtensions } = config
99+
const { templateResolver } = contexts.builderContext(config)
97100

98101
await new DocumentGroupStrategy().execute({
99102
...config,
@@ -103,14 +106,14 @@ async function exportReducedDocuments(config: ExportRestOperationsGroupBuildConf
103106

104107
const generatedHtmlExportDocuments: ZippableDocument[] = []
105108
const transformedDocuments = await Promise.all([...buildResult.documents.values()].map(async document => {
106-
return await createTransformedDocument(document, format, packageId, version, generatedHtmlExportDocuments, allowedOasExtensions)
109+
return await createTransformedDocument(document, format, packageId, version, generatedHtmlExportDocuments, templateResolver, allowedOasExtensions)
107110
}))
108111

109112
buildResult.exportDocuments.push(...transformedDocuments)
110113

111114
if (format === HTML_EXPORT_GROUP_FORMAT) {
112-
buildResult.exportDocuments.push(createExportDocument('index.html', await generateIndexHtmlPage(packageId, version, generatedHtmlExportDocuments)))
113-
buildResult.exportDocuments.push(...await createCommonStaticExportDocuments(packageId, version))
115+
buildResult.exportDocuments.push(createExportDocument('index.html', await generateIndexHtmlPage(packageId, version, generatedHtmlExportDocuments, templateResolver)))
116+
buildResult.exportDocuments.push(...await createCommonStaticExportDocuments(packageId, version, templateResolver))
114117
}
115118

116119
if (buildResult.exportDocuments.length > 1) {
@@ -128,14 +131,15 @@ async function createTransformedDocument(
128131
packageId: string,
129132
version: string,
130133
generatedHtmlExportDocuments: ZippableDocument[],
134+
templateResolver: _TemplateResolver,
131135
allowedOasExtensions?: OpenApiExtensionKey[],
132136
): Promise<ZippableDocument> {
133137
const { fileId, type } = document
134138

135139
if (isRestDocument(document) && format === HTML_EXPORT_GROUP_FORMAT) {
136140
const htmlExportDocument = createExportDocument(
137141
`${getDocumentTitle(document.filename)}.${HTML_EXPORT_GROUP_FORMAT}`,
138-
await generateHtmlPage(JSON.stringify(removeOasExtensions(document.data, allowedOasExtensions), undefined, 2), getDocumentTitle(document.filename), packageId, version, true),
142+
await generateHtmlPage(JSON.stringify(removeOasExtensions(document.data, allowedOasExtensions), undefined, 2), getDocumentTitle(document.filename), packageId, version, templateResolver, true),
139143
)
140144
generatedHtmlExportDocuments.push(htmlExportDocument)
141145
return htmlExportDocument

src/types/external/documents.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
* limitations under the License.
1515
*/
1616

17-
import { OperationsApiType, PackageId, VersionId } from './types'
17+
import { FileId, OperationsApiType, PackageId, TemplatePath, VersionId } from './types'
1818
import { ResolvedReferenceMap } from './references'
1919
import { FileFormat } from '../internal'
2020

@@ -70,3 +70,7 @@ export type RawDocumentResolver = (
7070
packageId: PackageId,
7171
slug: string,
7272
) => Promise<File | null>
73+
74+
export type FileResolver = (fileId: FileId) => Promise<Blob | null>
75+
76+
export type TemplateResolver = (templatePath: TemplatePath) => Promise<Blob | null>

src/types/external/resolvers.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,17 @@
1616

1717
import { VersionComparisonResolver } from './comparison'
1818
import { VersionDeprecatedResolver } from './deprecated'
19-
import { GroupDocumentsResolver, RawDocumentResolver, VersionDocumentsResolver } from './documents'
19+
import {
20+
FileResolver,
21+
GroupDocumentsResolver,
22+
RawDocumentResolver,
23+
TemplateResolver,
24+
VersionDocumentsResolver,
25+
} from './documents'
2026
import { VersionOperationsResolver } from './operations'
2127
import { VersionReferencesResolver } from './references'
2228
import { VersionResolver } from './version'
23-
import { FileId } from './types'
24-
import { TemplateResolver } from '../internal'
25-
26-
export type FileResolver = (fileId: FileId) => Promise<Blob | null>
29+
import { GroupExportTemplateResolver } from '../internal'
2730

2831
export interface BuilderResolvers {
2932
fileResolver: FileResolver
@@ -35,5 +38,6 @@ export interface BuilderResolvers {
3538
groupDocumentsResolver?: GroupDocumentsResolver
3639
versionDocumentsResolver?: VersionDocumentsResolver
3740
rawDocumentResolver?: RawDocumentResolver
41+
groupExportTemplateResolver?: GroupExportTemplateResolver
3842
templateResolver?: TemplateResolver
3943
}

src/types/external/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,6 @@ export type KeyOfConstType<T> = T[keyof T]
1919
export type OperationsApiType = 'rest' | 'graphql'
2020
export type PackageId = string
2121
export type FileId = string
22+
export type TemplatePath = string
2223
export type VersionId = string | `${string}@${number}`
2324
export type OperationId = string

src/types/internal/apiBuilder.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,14 @@ import {
1818
BuildConfig,
1919
BuildConfigFile,
2020
BuildConfigRef,
21+
FileId,
2122
GroupDocumentsResolver,
23+
OperationId,
2224
OperationsApiType,
2325
OperationsGroupExportFormat,
2426
PackageId,
2527
ResolvedOperation,
28+
TemplatePath,
2629
VersionDeprecatedResolver,
2730
VersionDocumentsResolver,
2831
VersionId,
@@ -51,18 +54,19 @@ export interface BuilderContext<T = any> {
5154
versionDeprecatedResolver: VersionDeprecatedResolver
5255
basePath: string
5356
parsedFileResolver: _ParsedFileResolver
57+
templateResolver: _TemplateResolver
5458
notifications: NotificationMessage[]
5559
config: BuildConfig
5660
builderRunOptions: BuilderRunOptions
5761
configuration?: BuilderConfiguration
5862
versionDocumentsResolver: VersionDocumentsResolver
5963
groupDocumentsResolver: GroupDocumentsResolver
60-
templateResolver?: TemplateResolver
64+
groupExportTemplateResolver?: GroupExportTemplateResolver
6165
rawDocumentResolver: _RawDocumentResolver
6266
versionLabels?: Array<string>
6367
}
6468

65-
export type TemplateResolver = (
69+
export type GroupExportTemplateResolver = (
6670
apiType: OperationsApiType,
6771
version: VersionId,
6872
packageId: PackageId,
@@ -115,5 +119,6 @@ export interface ApiBuilder<T = any, O = any, M = any> {
115119
export type _VersionResolver = (packageId: PackageId, version: VersionId) => Promise<VersionCache | null>
116120
export type _VersionReferencesResolver = (packageId: PackageId, version: VersionId) => Promise<BuildConfigRef[]>
117121

118-
export type _ParsedFileResolver = (fileId: string) => Promise<SourceFile | null>
119-
export type _OperationResolver = (operationId: string) => ResolvedOperation | null
122+
export type _ParsedFileResolver = (fileId: FileId) => Promise<SourceFile | null>
123+
export type _TemplateResolver = (templatePath: TemplatePath) => Promise<Blob>
124+
export type _OperationResolver = (operationId: OperationId) => ResolvedOperation | null

0 commit comments

Comments
 (0)