docs-util: extract feature flags in generated OAS (#12554)
This commit is contained in:
@@ -605,10 +605,12 @@ class DefaultKindGenerator<T extends ts.Node = ts.Node> {
|
||||
getInformationFromTags(node: ts.Node): {
|
||||
deprecatedTag: ts.JSDocTag | undefined
|
||||
versionTag: ts.JSDocTag | undefined
|
||||
featureFlagTag: ts.JSDocTag | undefined
|
||||
} {
|
||||
const nodeComments = ts.getJSDocCommentsAndTags(node)
|
||||
let deprecatedTag: ts.JSDocTag | undefined
|
||||
let versionTag: ts.JSDocTag | undefined
|
||||
let featureFlagTag: ts.JSDocTag | undefined
|
||||
|
||||
nodeComments.forEach((comment) => {
|
||||
if (!("tags" in comment)) {
|
||||
@@ -623,12 +625,17 @@ class DefaultKindGenerator<T extends ts.Node = ts.Node> {
|
||||
if (tag.tagName.getText() === "version") {
|
||||
versionTag = tag
|
||||
}
|
||||
|
||||
if (tag.tagName.getText() === "featureFlag") {
|
||||
featureFlagTag = tag
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
return {
|
||||
deprecatedTag,
|
||||
versionTag,
|
||||
featureFlagTag,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -435,7 +435,8 @@ class OasKindGenerator extends FunctionKindGenerator {
|
||||
}
|
||||
|
||||
// check deprecation and version in tags
|
||||
const { deprecatedTag, versionTag } = this.getInformationFromTags(node)
|
||||
const { deprecatedTag, versionTag, featureFlagTag } =
|
||||
this.getInformationFromTags(node)
|
||||
|
||||
if (deprecatedTag) {
|
||||
oas.deprecated = true
|
||||
@@ -450,6 +451,12 @@ class OasKindGenerator extends FunctionKindGenerator {
|
||||
: undefined
|
||||
}
|
||||
|
||||
if (featureFlagTag) {
|
||||
oas["x-featureFlag"] = featureFlagTag.comment
|
||||
? (featureFlagTag.comment as string)
|
||||
: undefined
|
||||
}
|
||||
|
||||
return formatOas(oas, oasPrefix)
|
||||
}
|
||||
|
||||
@@ -784,7 +791,8 @@ class OasKindGenerator extends FunctionKindGenerator {
|
||||
}
|
||||
|
||||
// check deprecation and version in tags
|
||||
const { deprecatedTag, versionTag } = this.getInformationFromTags(node)
|
||||
const { deprecatedTag, versionTag, featureFlagTag } =
|
||||
this.getInformationFromTags(node)
|
||||
|
||||
if (deprecatedTag) {
|
||||
oas.deprecated = true
|
||||
@@ -804,6 +812,14 @@ class OasKindGenerator extends FunctionKindGenerator {
|
||||
delete oas["x-version"]
|
||||
}
|
||||
|
||||
if (featureFlagTag) {
|
||||
oas["x-featureFlag"] = featureFlagTag.comment
|
||||
? (featureFlagTag.comment as string)
|
||||
: undefined
|
||||
} else {
|
||||
delete oas["x-featureFlag"]
|
||||
}
|
||||
|
||||
return formatOas(oas, oasPrefix)
|
||||
}
|
||||
|
||||
@@ -1562,6 +1578,27 @@ class OasKindGenerator extends FunctionKindGenerator {
|
||||
})
|
||||
}) || undefined // avoid showing it as false in the generated OAS
|
||||
|
||||
let featureFlag: string | undefined
|
||||
|
||||
commentsAndTags.some((comment) => {
|
||||
if (!("tags" in comment)) {
|
||||
return false
|
||||
}
|
||||
|
||||
comment.tags?.some((tag) => {
|
||||
if (tag.tagName.getText() !== "featureFlag" || !tag.comment) {
|
||||
return false
|
||||
}
|
||||
|
||||
featureFlag =
|
||||
typeof tag.comment === "string" ? tag.comment : tag.comment.join(" ")
|
||||
|
||||
return true
|
||||
})
|
||||
|
||||
return featureFlag !== undefined
|
||||
})
|
||||
|
||||
switch (true) {
|
||||
case isEnum || isEnumParent:
|
||||
const enumMembers: string[] = []
|
||||
@@ -1584,6 +1621,7 @@ class OasKindGenerator extends FunctionKindGenerator {
|
||||
description,
|
||||
enum: enumMembers,
|
||||
deprecated: isDeprecated,
|
||||
"x-featureFlag": featureFlag,
|
||||
}
|
||||
case itemType.isLiteral() || typeAsString === "RegExp":
|
||||
const isString =
|
||||
@@ -1602,6 +1640,7 @@ class OasKindGenerator extends FunctionKindGenerator {
|
||||
name: title,
|
||||
}),
|
||||
deprecated: isDeprecated,
|
||||
"x-featureFlag": featureFlag,
|
||||
}
|
||||
case itemType.flags === ts.TypeFlags.String ||
|
||||
itemType.flags === ts.TypeFlags.Number ||
|
||||
@@ -1622,6 +1661,7 @@ class OasKindGenerator extends FunctionKindGenerator {
|
||||
name: title,
|
||||
}),
|
||||
deprecated: isDeprecated,
|
||||
"x-featureFlag": featureFlag,
|
||||
}
|
||||
case ("intrinsicName" in itemType &&
|
||||
itemType.intrinsicName === "boolean") ||
|
||||
@@ -1634,6 +1674,7 @@ class OasKindGenerator extends FunctionKindGenerator {
|
||||
? this.getDefaultValue(symbol?.valueDeclaration)
|
||||
: undefined,
|
||||
deprecated: isDeprecated,
|
||||
"x-featureFlag": featureFlag,
|
||||
}
|
||||
case this.checker.isArrayType(itemType):
|
||||
return {
|
||||
@@ -1656,6 +1697,7 @@ class OasKindGenerator extends FunctionKindGenerator {
|
||||
saveSchema,
|
||||
...rest,
|
||||
}),
|
||||
"x-featureFlag": featureFlag,
|
||||
}
|
||||
case itemType.isUnion():
|
||||
// if it's a union of literal types,
|
||||
@@ -1675,6 +1717,7 @@ class OasKindGenerator extends FunctionKindGenerator {
|
||||
enum: cleanedUpTypes.map(
|
||||
(unionType) => (unionType as ts.LiteralType).value
|
||||
),
|
||||
"x-featureFlag": featureFlag,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1690,12 +1733,17 @@ class OasKindGenerator extends FunctionKindGenerator {
|
||||
)
|
||||
|
||||
if (oneOfItems.length === 1) {
|
||||
return oneOfItems[0]
|
||||
return {
|
||||
...oneOfItems[0],
|
||||
"x-featureFlag": oneOfItems[0]["x-featureFlag"] || featureFlag,
|
||||
deprecated: oneOfItems[0].deprecated || isDeprecated,
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
oneOf: oneOfItems,
|
||||
deprecated: isDeprecated,
|
||||
"x-featureFlag": featureFlag,
|
||||
}
|
||||
case itemType.isIntersection():
|
||||
const allOfItems = this.typesHelper
|
||||
@@ -1712,12 +1760,17 @@ class OasKindGenerator extends FunctionKindGenerator {
|
||||
})
|
||||
|
||||
if (allOfItems.length === 1) {
|
||||
return allOfItems[0]
|
||||
return {
|
||||
...allOfItems[0],
|
||||
"x-featureFlag": allOfItems[0]["x-featureFlag"] || featureFlag,
|
||||
deprecated: allOfItems[0].deprecated || isDeprecated,
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
allOf: allOfItems,
|
||||
deprecated: isDeprecated,
|
||||
"x-featureFlag": featureFlag,
|
||||
}
|
||||
case typeAsString.startsWith("Pick"):
|
||||
const pickTypeArgs =
|
||||
@@ -1807,6 +1860,7 @@ class OasKindGenerator extends FunctionKindGenerator {
|
||||
: undefined,
|
||||
// this is changed later
|
||||
required: undefined,
|
||||
"x-featureFlag": featureFlag,
|
||||
}
|
||||
|
||||
const properties: Record<
|
||||
@@ -2472,6 +2526,19 @@ class OasKindGenerator extends FunctionKindGenerator {
|
||||
}
|
||||
}
|
||||
|
||||
if (oldSchemaObj?.["x-featureFlag"] !== newSchemaObj?.["x-featureFlag"]) {
|
||||
// avoid many changes to exising OAS
|
||||
if (!newSchemaObj?.["x-featureFlag"]) {
|
||||
if (oldSchemaObj!["x-featureFlag"]) {
|
||||
wasUpdated = true
|
||||
}
|
||||
delete oldSchemaObj!["x-featureFlag"]
|
||||
} else {
|
||||
oldSchemaObj!["x-featureFlag"] = newSchemaObj["x-featureFlag"]
|
||||
wasUpdated = true
|
||||
}
|
||||
}
|
||||
|
||||
if (!wasUpdated) {
|
||||
const requiredChanged =
|
||||
oldSchemaObj!.required?.length !== newSchemaObj?.required?.length ||
|
||||
|
||||
@@ -13,6 +13,7 @@ export declare type OpenApiOperation = Partial<OpenAPIV3.OperationObject> & {
|
||||
"x-events"?: OasEvent[]
|
||||
"x-deprecated_message"?: string
|
||||
"x-version"?: string
|
||||
"x-featureFlag"?: string
|
||||
}
|
||||
|
||||
export declare type CommonCliOptions = {
|
||||
@@ -23,6 +24,7 @@ export declare type CommonCliOptions = {
|
||||
|
||||
export declare type OpenApiSchema = OpenAPIV3.SchemaObject & {
|
||||
"x-schemaName"?: string
|
||||
"x-featureFlag"?: string
|
||||
}
|
||||
|
||||
export declare interface OpenApiTagObject extends OpenAPIV3.TagObject {
|
||||
|
||||
Reference in New Issue
Block a user