docs-util: fix workflows not picked for some routes + generate OAS (#13342)

* generated oas

* fixes and improvements
This commit is contained in:
Shahed Nasser
2025-08-29 12:51:55 +03:00
committed by GitHub
parent 899ac2f052
commit 7b1028e5ae
23 changed files with 308 additions and 1047 deletions

View File

@@ -3,7 +3,6 @@ description: The shipping option type's details.
x-schemaName: AdminCreateShippingOptionType
required:
- label
- description
- code
properties:
label:

View File

@@ -1,174 +0,0 @@
type: object
description: The properties to update in the shipping option.
properties:
name:
type: string
title: name
description: The shipping option's name.
data:
type: object
description: The shipping option's data that is useful for third-party providers.
externalDocs:
url: >-
https://docs.medusajs.com/v2/resources/commerce-modules/fulfillment/shipping-option#data-property
price_type:
type: string
description: >
The type of the shipping option's price. If `calculated`, its price is
retrieved by the associated fulfillment provider during checkout. If
`flat`, its price is set in the `prices` property.
enum:
- calculated
- flat
provider_id:
type: string
title: provider_id
description: >-
The ID of the associated fulfillment provider that is used to process the
option.
shipping_profile_id:
type: string
title: shipping_profile_id
description: The ID of the shipping profile this shipping option belongs to.
type:
type: object
description: The shipping option's type.
required:
- code
- description
- label
properties:
label:
type: string
title: label
description: The type's label.
description:
type: string
title: description
description: The type's description.
code:
type: string
title: code
description: The type's code.
prices:
type: array
description: >-
The shipping option's prices. If the `price_type` is `calculated`, pass an
empty array.
items:
oneOf:
- type: object
description: The shipping option's price for a currency code.
properties:
id:
type: string
title: id
description: The ID of an existing price.
currency_code:
type: string
title: currency_code
description: The price's currency code.
amount:
type: number
title: amount
description: The price's amount.
- type: object
description: The shipping option's price for a region.
properties:
id:
type: string
title: id
description: The ID of an existing price.
region_id:
type: string
title: region_id
description: The ID of the associated region.
amount:
type: number
title: amount
description: The price's amount.
rules:
type: array
description: The shipping option's rules.
items:
oneOf:
- type: object
description: The details of a new shipping option rule.
required:
- operator
- attribute
- value
properties:
operator:
type: string
description: The operator used to check whether a rule applies.
enum:
- in
- eq
- ne
- gt
- gte
- lt
- lte
- nin
attribute:
type: string
title: attribute
description: The name of a property or table that the rule applies to.
example: customer_group
value:
oneOf:
- type: string
title: value
description: A value of the attribute that enables this rule.
example: cusgroup_123
- type: array
description: Values of the attribute that enable this rule.
items:
type: string
title: value
description: A value of the attribute that enables this rule.
example: cusgroup_123
- type: object
description: Update the properties of an existing rule.
required:
- id
- operator
- attribute
- value
properties:
id:
type: string
title: id
description: The rule's ID.
operator:
type: string
description: The operator used to check whether a rule applies.
enum:
- in
- eq
- ne
- gt
- gte
- lt
- lte
- nin
attribute:
type: string
title: attribute
description: The name of a property or table that the rule applies to.
example: customer_group
value:
oneOf:
- type: string
title: value
description: A value of the attribute that enables this rule.
example: cusgroup_123
- type: array
description: Values of the attribute that enable this rule.
items:
type: string
title: value
description: A value of the attribute that enables this rule.
example: cusgroup_123
x-schemaName: AdminUpdateShippingOption

View File

@@ -0,0 +1,16 @@
type: object
description: The properties to update in the shipping option type.
properties:
code:
type: string
title: code
description: The shipping option type's code.
description:
type: string
title: description
description: The shipping option type's description.
label:
type: string
title: label
description: The shipping option type's label.
x-schemaName: AdminUpdateShippingOptionType

View File

@@ -18390,7 +18390,6 @@ paths:
summary: List Feature Flags
description: Retrieve a list of feature flags. The feature flags can be filtered by fields such as `id`. The feature flags can also be sorted or paginated.
x-authenticated: false
parameters: []
x-codeSamples:
- lang: Shell
label: cURL
@@ -45073,7 +45072,7 @@ paths:
content:
application/json:
schema:
$ref: '#/components/schemas/AdminUpdateShippingOption'
$ref: '#/components/schemas/AdminUpdateShippingOptionType'
x-codeSamples:
- lang: JavaScript
label: JS SDK
@@ -45994,7 +45993,7 @@ paths:
content:
application/json:
schema:
$ref: '#/components/schemas/AdminUpdateShippingOption'
$ref: '#/components/schemas/AdminUpdateShippingOptionType'
x-codeSamples:
- lang: JavaScript
label: JS SDK
@@ -57812,7 +57811,6 @@ components:
x-schemaName: AdminCreateShippingOptionType
required:
- label
- description
- code
properties:
label:
@@ -69085,174 +69083,6 @@ components:
externalDocs:
url: https://docs.medusajs.com/api/admin#manage-metadata
description: Learn how to manage metadata
AdminUpdateShippingOption:
type: object
description: The properties to update in the shipping option.
properties:
name:
type: string
title: name
description: The shipping option's name.
data:
type: object
description: The shipping option's data that is useful for third-party providers.
externalDocs:
url: https://docs.medusajs.com/v2/resources/commerce-modules/fulfillment/shipping-option#data-property
price_type:
type: string
description: |
The type of the shipping option's price. If `calculated`, its price is retrieved by the associated fulfillment provider during checkout. If `flat`, its price is set in the `prices` property.
enum:
- calculated
- flat
provider_id:
type: string
title: provider_id
description: The ID of the associated fulfillment provider that is used to process the option.
shipping_profile_id:
type: string
title: shipping_profile_id
description: The ID of the shipping profile this shipping option belongs to.
type:
type: object
description: The shipping option's type.
required:
- code
- description
- label
properties:
label:
type: string
title: label
description: The type's label.
description:
type: string
title: description
description: The type's description.
code:
type: string
title: code
description: The type's code.
prices:
type: array
description: The shipping option's prices. If the `price_type` is `calculated`, pass an empty array.
items:
oneOf:
- type: object
description: The shipping option's price for a currency code.
properties:
id:
type: string
title: id
description: The ID of an existing price.
currency_code:
type: string
title: currency_code
description: The price's currency code.
amount:
type: number
title: amount
description: The price's amount.
- type: object
description: The shipping option's price for a region.
properties:
id:
type: string
title: id
description: The ID of an existing price.
region_id:
type: string
title: region_id
description: The ID of the associated region.
amount:
type: number
title: amount
description: The price's amount.
rules:
type: array
description: The shipping option's rules.
items:
oneOf:
- type: object
description: The details of a new shipping option rule.
required:
- operator
- attribute
- value
properties:
operator:
type: string
description: The operator used to check whether a rule applies.
enum:
- in
- eq
- ne
- gt
- gte
- lt
- lte
- nin
attribute:
type: string
title: attribute
description: The name of a property or table that the rule applies to.
example: customer_group
value:
oneOf:
- type: string
title: value
description: A value of the attribute that enables this rule.
example: cusgroup_123
- type: array
description: Values of the attribute that enable this rule.
items:
type: string
title: value
description: A value of the attribute that enables this rule.
example: cusgroup_123
- type: object
description: Update the properties of an existing rule.
required:
- id
- operator
- attribute
- value
properties:
id:
type: string
title: id
description: The rule's ID.
operator:
type: string
description: The operator used to check whether a rule applies.
enum:
- in
- eq
- ne
- gt
- gte
- lt
- lte
- nin
attribute:
type: string
title: attribute
description: The name of a property or table that the rule applies to.
example: customer_group
value:
oneOf:
- type: string
title: value
description: A value of the attribute that enables this rule.
example: cusgroup_123
- type: array
description: Values of the attribute that enable this rule.
items:
type: string
title: value
description: A value of the attribute that enables this rule.
example: cusgroup_123
x-schemaName: AdminUpdateShippingOption
AdminUpdateShippingOptionRule:
type: object
description: The properties to update in the shipping option rule.
@@ -69297,6 +69127,23 @@ components:
description: A value of the attribute that enables this rule.
example: cusgroup_123
x-schemaName: AdminUpdateShippingOptionRule
AdminUpdateShippingOptionType:
type: object
description: The properties to update in the shipping option type.
properties:
code:
type: string
title: code
description: The shipping option type's code.
description:
type: string
title: description
description: The shipping option type's description.
label:
type: string
title: label
description: The shipping option type's label.
x-schemaName: AdminUpdateShippingOptionType
AdminUpdateShippingProfile:
type: object
description: The properties to update in the shipping profile.

View File

@@ -5,7 +5,6 @@ get:
Retrieve a list of feature flags. The feature flags can be filtered by
fields such as `id`. The feature flags can also be sorted or paginated.
x-authenticated: false
parameters: []
x-codeSamples:
- lang: Shell
label: cURL

View File

@@ -107,7 +107,7 @@ post:
content:
application/json:
schema:
$ref: ../components/schemas/AdminUpdateShippingOption.yaml
$ref: ../components/schemas/AdminUpdateShippingOptionType.yaml
x-codeSamples:
- lang: JavaScript
label: JS SDK

View File

@@ -104,7 +104,7 @@ post:
content:
application/json:
schema:
$ref: ../components/schemas/AdminUpdateShippingOption.yaml
$ref: ../components/schemas/AdminUpdateShippingOptionType.yaml
x-codeSamples:
- lang: JavaScript
label: JS SDK

View File

@@ -3,7 +3,6 @@ description: The shipping option type's details.
x-schemaName: AdminCreateShippingOptionType
required:
- label
- description
- code
properties:
label:

View File

@@ -1,174 +0,0 @@
type: object
description: The properties to update in the shipping option.
properties:
name:
type: string
title: name
description: The shipping option's name.
data:
type: object
description: The shipping option's data that is useful for third-party providers.
externalDocs:
url: >-
https://docs.medusajs.com/v2/resources/commerce-modules/fulfillment/shipping-option#data-property
price_type:
type: string
description: >
The type of the shipping option's price. If `calculated`, its price is
retrieved by the associated fulfillment provider during checkout. If
`flat`, its price is set in the `prices` property.
enum:
- calculated
- flat
provider_id:
type: string
title: provider_id
description: >-
The ID of the associated fulfillment provider that is used to process the
option.
shipping_profile_id:
type: string
title: shipping_profile_id
description: The ID of the shipping profile this shipping option belongs to.
type:
type: object
description: The shipping option's type.
required:
- code
- description
- label
properties:
label:
type: string
title: label
description: The type's label.
description:
type: string
title: description
description: The type's description.
code:
type: string
title: code
description: The type's code.
prices:
type: array
description: >-
The shipping option's prices. If the `price_type` is `calculated`, pass an
empty array.
items:
oneOf:
- type: object
description: The shipping option's price for a currency code.
properties:
id:
type: string
title: id
description: The ID of an existing price.
currency_code:
type: string
title: currency_code
description: The price's currency code.
amount:
type: number
title: amount
description: The price's amount.
- type: object
description: The shipping option's price for a region.
properties:
id:
type: string
title: id
description: The ID of an existing price.
region_id:
type: string
title: region_id
description: The ID of the associated region.
amount:
type: number
title: amount
description: The price's amount.
rules:
type: array
description: The shipping option's rules.
items:
oneOf:
- type: object
description: The details of a new shipping option rule.
required:
- operator
- attribute
- value
properties:
operator:
type: string
description: The operator used to check whether a rule applies.
enum:
- in
- eq
- ne
- gt
- gte
- lt
- lte
- nin
attribute:
type: string
title: attribute
description: The name of a property or table that the rule applies to.
example: customer_group
value:
oneOf:
- type: string
title: value
description: A value of the attribute that enables this rule.
example: cusgroup_123
- type: array
description: Values of the attribute that enable this rule.
items:
type: string
title: value
description: A value of the attribute that enables this rule.
example: cusgroup_123
- type: object
description: Update the properties of an existing rule.
required:
- id
- operator
- attribute
- value
properties:
id:
type: string
title: id
description: The rule's ID.
operator:
type: string
description: The operator used to check whether a rule applies.
enum:
- in
- eq
- ne
- gt
- gte
- lt
- lte
- nin
attribute:
type: string
title: attribute
description: The name of a property or table that the rule applies to.
example: customer_group
value:
oneOf:
- type: string
title: value
description: A value of the attribute that enables this rule.
example: cusgroup_123
- type: array
description: Values of the attribute that enable this rule.
items:
type: string
title: value
description: A value of the attribute that enables this rule.
example: cusgroup_123
x-schemaName: AdminUpdateShippingOption

View File

@@ -0,0 +1,16 @@
type: object
description: The properties to update in the shipping option type.
properties:
code:
type: string
title: code
description: The shipping option type's code.
description:
type: string
title: description
description: The shipping option type's description.
label:
type: string
title: label
description: The shipping option type's label.
x-schemaName: AdminUpdateShippingOptionType

View File

@@ -12173,7 +12173,6 @@ components:
x-schemaName: AdminCreateShippingOptionType
required:
- label
- description
- code
properties:
label:
@@ -23446,174 +23445,6 @@ components:
externalDocs:
url: https://docs.medusajs.com/api/admin#manage-metadata
description: Learn how to manage metadata
AdminUpdateShippingOption:
type: object
description: The properties to update in the shipping option.
properties:
name:
type: string
title: name
description: The shipping option's name.
data:
type: object
description: The shipping option's data that is useful for third-party providers.
externalDocs:
url: https://docs.medusajs.com/v2/resources/commerce-modules/fulfillment/shipping-option#data-property
price_type:
type: string
description: |
The type of the shipping option's price. If `calculated`, its price is retrieved by the associated fulfillment provider during checkout. If `flat`, its price is set in the `prices` property.
enum:
- calculated
- flat
provider_id:
type: string
title: provider_id
description: The ID of the associated fulfillment provider that is used to process the option.
shipping_profile_id:
type: string
title: shipping_profile_id
description: The ID of the shipping profile this shipping option belongs to.
type:
type: object
description: The shipping option's type.
required:
- code
- description
- label
properties:
label:
type: string
title: label
description: The type's label.
description:
type: string
title: description
description: The type's description.
code:
type: string
title: code
description: The type's code.
prices:
type: array
description: The shipping option's prices. If the `price_type` is `calculated`, pass an empty array.
items:
oneOf:
- type: object
description: The shipping option's price for a currency code.
properties:
id:
type: string
title: id
description: The ID of an existing price.
currency_code:
type: string
title: currency_code
description: The price's currency code.
amount:
type: number
title: amount
description: The price's amount.
- type: object
description: The shipping option's price for a region.
properties:
id:
type: string
title: id
description: The ID of an existing price.
region_id:
type: string
title: region_id
description: The ID of the associated region.
amount:
type: number
title: amount
description: The price's amount.
rules:
type: array
description: The shipping option's rules.
items:
oneOf:
- type: object
description: The details of a new shipping option rule.
required:
- operator
- attribute
- value
properties:
operator:
type: string
description: The operator used to check whether a rule applies.
enum:
- in
- eq
- ne
- gt
- gte
- lt
- lte
- nin
attribute:
type: string
title: attribute
description: The name of a property or table that the rule applies to.
example: customer_group
value:
oneOf:
- type: string
title: value
description: A value of the attribute that enables this rule.
example: cusgroup_123
- type: array
description: Values of the attribute that enable this rule.
items:
type: string
title: value
description: A value of the attribute that enables this rule.
example: cusgroup_123
- type: object
description: Update the properties of an existing rule.
required:
- id
- operator
- attribute
- value
properties:
id:
type: string
title: id
description: The rule's ID.
operator:
type: string
description: The operator used to check whether a rule applies.
enum:
- in
- eq
- ne
- gt
- gte
- lt
- lte
- nin
attribute:
type: string
title: attribute
description: The name of a property or table that the rule applies to.
example: customer_group
value:
oneOf:
- type: string
title: value
description: A value of the attribute that enables this rule.
example: cusgroup_123
- type: array
description: Values of the attribute that enable this rule.
items:
type: string
title: value
description: A value of the attribute that enables this rule.
example: cusgroup_123
x-schemaName: AdminUpdateShippingOption
AdminUpdateShippingOptionRule:
type: object
description: The properties to update in the shipping option rule.
@@ -23658,6 +23489,23 @@ components:
description: A value of the attribute that enables this rule.
example: cusgroup_123
x-schemaName: AdminUpdateShippingOptionRule
AdminUpdateShippingOptionType:
type: object
description: The properties to update in the shipping option type.
properties:
code:
type: string
title: code
description: The shipping option type's code.
description:
type: string
title: description
description: The shipping option type's description.
label:
type: string
title: label
description: The shipping option type's label.
x-schemaName: AdminUpdateShippingOptionType
AdminUpdateShippingProfile:
type: object
description: The properties to update in the shipping profile.

View File

@@ -4,7 +4,6 @@
* summary: List Feature Flags
* description: Retrieve a list of feature flags. The feature flags can be filtered by fields such as `id`. The feature flags can also be sorted or paginated.
* x-authenticated: false
* parameters: []
* x-codeSamples:
* - lang: Shell
* label: cURL

View File

@@ -33,7 +33,7 @@
* content:
* application/json:
* schema:
* $ref: "#/components/schemas/AdminUpdateShippingOption"
* $ref: "#/components/schemas/AdminUpdateShippingOptionType"
* x-codeSamples:
* - lang: JavaScript
* label: JS SDK

View File

@@ -31,7 +31,7 @@
* content:
* application/json:
* schema:
* $ref: "#/components/schemas/AdminUpdateShippingOption"
* $ref: "#/components/schemas/AdminUpdateShippingOptionType"
* x-codeSamples:
* - lang: JavaScript
* label: JS SDK

View File

@@ -5,7 +5,6 @@
* x-schemaName: AdminCreateShippingOptionType
* required:
* - label
* - description
* - code
* properties:
* label:

View File

@@ -1,172 +0,0 @@
/**
* @schema AdminUpdateShippingOption
* type: object
* description: The properties to update in the shipping option.
* properties:
* name:
* type: string
* title: name
* description: The shipping option's name.
* data:
* type: object
* description: The shipping option's data that is useful for third-party providers.
* externalDocs:
* url: https://docs.medusajs.com/v2/resources/commerce-modules/fulfillment/shipping-option#data-property
* price_type:
* type: string
* description: |
* The type of the shipping option's price. If `calculated`, its price is retrieved by the associated fulfillment provider during checkout. If `flat`, its price is set in the `prices` property.
* enum:
* - calculated
* - flat
* provider_id:
* type: string
* title: provider_id
* description: The ID of the associated fulfillment provider that is used to process the option.
* shipping_profile_id:
* type: string
* title: shipping_profile_id
* description: The ID of the shipping profile this shipping option belongs to.
* type:
* type: object
* description: The shipping option's type.
* required:
* - code
* - description
* - label
* properties:
* label:
* type: string
* title: label
* description: The type's label.
* description:
* type: string
* title: description
* description: The type's description.
* code:
* type: string
* title: code
* description: The type's code.
* prices:
* type: array
* description: The shipping option's prices. If the `price_type` is `calculated`, pass an empty array.
* items:
* oneOf:
* - type: object
* description: The shipping option's price for a currency code.
* properties:
* id:
* type: string
* title: id
* description: The ID of an existing price.
* currency_code:
* type: string
* title: currency_code
* description: The price's currency code.
* amount:
* type: number
* title: amount
* description: The price's amount.
* - type: object
* description: The shipping option's price for a region.
* properties:
* id:
* type: string
* title: id
* description: The ID of an existing price.
* region_id:
* type: string
* title: region_id
* description: The ID of the associated region.
* amount:
* type: number
* title: amount
* description: The price's amount.
* rules:
* type: array
* description: The shipping option's rules.
* items:
* oneOf:
* - type: object
* description: The details of a new shipping option rule.
* required:
* - operator
* - attribute
* - value
* properties:
* operator:
* type: string
* description: The operator used to check whether a rule applies.
* enum:
* - in
* - eq
* - ne
* - gt
* - gte
* - lt
* - lte
* - nin
* attribute:
* type: string
* title: attribute
* description: The name of a property or table that the rule applies to.
* example: customer_group
* value:
* oneOf:
* - type: string
* title: value
* description: A value of the attribute that enables this rule.
* example: cusgroup_123
* - type: array
* description: Values of the attribute that enable this rule.
* items:
* type: string
* title: value
* description: A value of the attribute that enables this rule.
* example: cusgroup_123
* - type: object
* description: Update the properties of an existing rule.
* required:
* - id
* - operator
* - attribute
* - value
* properties:
* id:
* type: string
* title: id
* description: The rule's ID.
* operator:
* type: string
* description: The operator used to check whether a rule applies.
* enum:
* - in
* - eq
* - ne
* - gt
* - gte
* - lt
* - lte
* - nin
* attribute:
* type: string
* title: attribute
* description: The name of a property or table that the rule applies to.
* example: customer_group
* value:
* oneOf:
* - type: string
* title: value
* description: A value of the attribute that enables this rule.
* example: cusgroup_123
* - type: array
* description: Values of the attribute that enable this rule.
* items:
* type: string
* title: value
* description: A value of the attribute that enables this rule.
* example: cusgroup_123
* x-schemaName: AdminUpdateShippingOption
*
*/

View File

@@ -0,0 +1,21 @@
/**
* @schema AdminUpdateShippingOptionType
* type: object
* description: The properties to update in the shipping option type.
* properties:
* code:
* type: string
* title: code
* description: The shipping option type's code.
* description:
* type: string
* title: description
* description: The shipping option type's description.
* label:
* type: string
* title: label
* description: The shipping option type's label.
* x-schemaName: AdminUpdateShippingOptionType
*
*/

View File

@@ -24,6 +24,7 @@
"commander": "^11.1.0",
"dotenv": "^16.3.1",
"eslint": "8.56.0",
"fdir": "^6.5.0",
"glob": "^11.0.2",
"minimatch": "^9.0.3",
"openai": "^4.29.1",

View File

@@ -364,7 +364,7 @@ class OasSchemaHelper {
.replace("DTO", "")
.replace(this.schemaRefPrefix, "")
.replace(
/(?<!(AdminProduct|CreateProduct|UpdateProduct|StoreShippingOption|AdminShippingOption|CreateShippingOption|BaseProduct|StoreProduct))Type$/,
/(?<!(AdminProduct|CreateProduct|UpdateProduct|StoreShippingOption|AdminShippingOption|CreateShippingOption|BaseProduct|StoreProduct|AdminCreateShippingOption|AdminUpdateShippingOption))Type$/,
""
)
}

View File

@@ -88,7 +88,7 @@ class DefaultKindGenerator<T extends ts.Node = ts.Node> {
* @returns {boolean} Whether this generator can be used with the specified node.
*/
isAllowed(node: ts.Node): node is T {
return this.allowedKinds.includes(node.kind)
return !this.isIgnored(node) && this.allowedKinds.includes(node.kind)
}
/**
@@ -638,6 +638,18 @@ class DefaultKindGenerator<T extends ts.Node = ts.Node> {
featureFlagTag,
}
}
/**
* Check if a node is ignored.
*
* @param node - The node to check.
* @returns Whether the node is ignored.
*/
isIgnored(node: ts.Node): boolean {
return ts
.getJSDocTags(node)
.some((tag) => tag.tagName.getText() === "ignore")
}
}
export default DefaultKindGenerator

View File

@@ -203,6 +203,10 @@ class OasKindGenerator extends FunctionKindGenerator {
return false
}
if (this.isIgnored(functionNode)) {
return false
}
const hasCorrectRequestType = this.REQUEST_TYPE_NAMES.some(
(name) => functionNode.parameters[0].type?.getText().startsWith(name)
)
@@ -2653,9 +2657,16 @@ class OasKindGenerator extends FunctionKindGenerator {
if (
fnText.includes(`${workflowName}(`) ||
fnText.includes(`${workflowName} (`) ||
fnText.includes(`${workflowName}.`)
fnText.includes(`${workflowName}.`) ||
fnText.includes(`we.run(${workflowName}`) ||
fnText.includes(`we.run (${workflowName}`) ||
fnText.includes(`we.run(
${workflowName}
)`)
) {
workflow = workflowName
// workaround for API routes that execute a workflow
// by its ID. Not very smart but will do for now.
workflow = workflowName.replace(/Id$/, "")
}
})
})

View File

@@ -1,10 +1,5 @@
import {
existsSync,
readFileSync,
readdirSync,
rmSync,
writeFileSync,
} from "fs"
import { existsSync, readFileSync, rmSync, writeFileSync } from "fs"
import { fdir } from "fdir"
import { OpenAPIV3 } from "openapi-types"
import path from "path"
import ts from "typescript"
@@ -78,175 +73,181 @@ export default async function () {
console.log("Cleaning OAS files...")
// read files under the operations/{area} directory
areas.forEach((area) => {
const areaPath = path.join(oasOperationsPath, area)
if (!existsSync(areaPath)) {
return
}
readdirSync(areaPath, {
recursive: true,
encoding: "utf-8",
}).forEach((oasFile) => {
const filePath = path.join(areaPath, oasFile)
const { oas, oasPrefix } = parseOas(readFileSync(filePath, "utf-8")) || {}
if (!oas || !oasPrefix) {
await Promise.all(
areas.map(async (area) => {
const areaPath = path.join(oasOperationsPath, area)
if (!existsSync(areaPath)) {
return
}
// decode oasPrefix
const matchOasPrefix = OAS_PREFIX_REGEX.exec(oasPrefix)
if (
!matchOasPrefix?.groups?.method ||
!matchOasPrefix.groups.path ||
matchOasPrefix.groups.path.startsWith("/auth/")
) {
return
}
const splitPath = matchOasPrefix.groups.path.substring(1).split("/")
const dirFiles = await new fdir()
.withFullPaths()
.crawl(areaPath)
.withPromise()
// normalize path by replacing {paramName} with [paramName]
const normalizedOasPrefix = splitPath
.map((item) => item.replace(/^\{(.+)\}$/, "[$1]"))
.join("/")
const sourceFilePath = path.join(
apiRoutesPath,
normalizedOasPrefix,
"route.ts"
)
dirFiles.forEach((oasFile) => {
const { oas, oasPrefix } =
parseOas(readFileSync(oasFile, "utf-8")) || {}
if (!oas["x-ignoreCleanup"]) {
// check if a route exists for the path
if (!existsSync(sourceFilePath)) {
// remove OAS file
rmSync(filePath, {
force: true,
})
if (!oas || !oasPrefix) {
return
}
// check if method exists in the file
let exists = false
const program = ts.createProgram([sourceFilePath], {})
// decode oasPrefix
const matchOasPrefix = OAS_PREFIX_REGEX.exec(oasPrefix)
if (
!matchOasPrefix?.groups?.method ||
!matchOasPrefix.groups.path ||
matchOasPrefix.groups.path.startsWith("/auth/")
) {
return
}
const splitPath = matchOasPrefix.groups.path.substring(1).split("/")
const oasKindGenerator = new OasKindGenerator({
checker: program.getTypeChecker(),
generatorEventManager: new GeneratorEventManager(),
additionalOptions: {},
// normalize path by replacing {paramName} with [paramName]
const normalizedOasPrefix = splitPath
.map((item) => item.replace(/^\{(.+)\}$/, "[$1]"))
.join("/")
const sourceFilePath = path.join(
apiRoutesPath,
normalizedOasPrefix,
"route.ts"
)
if (!oas["x-ignoreCleanup"]) {
// check if a route exists for the path
if (!existsSync(sourceFilePath)) {
// remove OAS file
rmSync(oasFile, {
force: true,
})
return
}
// check if method exists in the file
let exists = false
const program = ts.createProgram([sourceFilePath], {})
const oasKindGenerator = new OasKindGenerator({
checker: program.getTypeChecker(),
generatorEventManager: new GeneratorEventManager(),
additionalOptions: {},
})
const sourceFile = program.getSourceFile(sourceFilePath)
if (!sourceFile) {
// remove file
rmSync(oasFile, {
force: true,
})
return
}
const visitChildren = (node: ts.Node) => {
if (
!exists &&
oasKindGenerator.isAllowed(node) &&
oasKindGenerator.canDocumentNode(node) &&
oasKindGenerator.getHTTPMethodName(node) ===
matchOasPrefix.groups!.method
) {
exists = true
} else if (!exists) {
ts.forEachChild(node, visitChildren)
}
}
ts.forEachChild(sourceFile, visitChildren)
if (!exists) {
// remove OAS file
rmSync(oasFile, {
force: true,
})
return
}
}
// collect tags
oas.tags?.forEach((tag) => {
const areaTags = tags.get(area as OasArea)
areaTags?.add(tag)
})
const sourceFile = program.getSourceFile(sourceFilePath)
if (!sourceFile) {
// remove file
rmSync(filePath, {
force: true,
})
return
}
const visitChildren = (node: ts.Node) => {
if (
!exists &&
oasKindGenerator.isAllowed(node) &&
oasKindGenerator.canDocumentNode(node) &&
oasKindGenerator.getHTTPMethodName(node) ===
matchOasPrefix.groups!.method
) {
exists = true
} else if (!exists) {
ts.forEachChild(node, visitChildren)
}
}
ts.forEachChild(sourceFile, visitChildren)
if (!exists) {
// remove OAS file
rmSync(filePath, {
force: true,
})
return
}
}
// collect tags
oas.tags?.forEach((tag) => {
const areaTags = tags.get(area as OasArea)
areaTags?.add(tag)
})
// collect schemas
oas.parameters?.forEach((parameter) => {
if (oasSchemaHelper.isRefObject(parameter)) {
referencedSchemas.add(
oasSchemaHelper.normalizeSchemaName(parameter.$ref)
)
return
}
if (!parameter.schema) {
return
}
if (oasSchemaHelper.isRefObject(parameter.schema)) {
referencedSchemas.add(
oasSchemaHelper.normalizeSchemaName(parameter.schema.$ref)
)
return
}
testAndFindReferenceSchema(parameter.schema)
})
if (oas.requestBody) {
if (oasSchemaHelper.isRefObject(oas.requestBody)) {
referencedSchemas.add(
oasSchemaHelper.normalizeSchemaName(oas.requestBody.$ref)
)
} else {
const requestBodySchema =
oas.requestBody.content[Object.keys(oas.requestBody.content)[0]]
.schema
if (requestBodySchema) {
testAndFindReferenceSchema(requestBodySchema)
}
}
}
if (oas.responses) {
const successResponseKey = Object.keys(oas.responses)[0]
if (!Object.keys(DEFAULT_OAS_RESPONSES).includes(successResponseKey)) {
const responseObj = oas.responses[successResponseKey]
if (oasSchemaHelper.isRefObject(responseObj)) {
// collect schemas
oas.parameters?.forEach((parameter) => {
if (oasSchemaHelper.isRefObject(parameter)) {
referencedSchemas.add(
oasSchemaHelper.normalizeSchemaName(responseObj.$ref)
oasSchemaHelper.normalizeSchemaName(parameter.$ref)
)
} else if (responseObj.content) {
const responseBodySchema =
responseObj.content[Object.keys(responseObj.content)[0]].schema
if (responseBodySchema) {
testAndFindReferenceSchema(responseBodySchema)
return
}
if (!parameter.schema) {
return
}
if (oasSchemaHelper.isRefObject(parameter.schema)) {
referencedSchemas.add(
oasSchemaHelper.normalizeSchemaName(parameter.schema.$ref)
)
return
}
testAndFindReferenceSchema(parameter.schema)
})
if (oas.requestBody) {
if (oasSchemaHelper.isRefObject(oas.requestBody)) {
referencedSchemas.add(
oasSchemaHelper.normalizeSchemaName(oas.requestBody.$ref)
)
} else {
const requestBodySchema =
oas.requestBody.content[Object.keys(oas.requestBody.content)[0]]
.schema
if (requestBodySchema) {
testAndFindReferenceSchema(requestBodySchema)
}
}
}
}
if (oas.responses) {
const successResponseKey = Object.keys(oas.responses)[0]
if (
!Object.keys(DEFAULT_OAS_RESPONSES).includes(successResponseKey)
) {
const responseObj = oas.responses[successResponseKey]
if (oasSchemaHelper.isRefObject(responseObj)) {
referencedSchemas.add(
oasSchemaHelper.normalizeSchemaName(responseObj.$ref)
)
} else if (responseObj.content) {
const responseBodySchema =
responseObj.content[Object.keys(responseObj.content)[0]].schema
if (responseBodySchema) {
testAndFindReferenceSchema(responseBodySchema)
}
}
}
}
})
})
})
)
console.log("Clean tags...")
// check if any tags should be removed
const oasBasePath = path.join(oasOutputBasePath, "base")
readdirSync(oasBasePath, {
recursive: true,
encoding: "utf-8",
}).forEach((baseYaml) => {
const baseYamlPath = path.join(oasBasePath, baseYaml)
const baseFiles = await new fdir()
.withFullPaths()
.crawl(oasBasePath)
.withPromise()
baseFiles.forEach((baseYaml) => {
const parsedBaseYaml = parse(
readFileSync(baseYamlPath, "utf-8")
readFileSync(baseYaml, "utf-8")
) as OpenApiDocument
const area = path.basename(baseYaml).split(".")[0] as OasArea
@@ -266,7 +267,7 @@ export default async function () {
return tagA.name.localeCompare(tagB.name)
})
// write to the file
writeFileSync(baseYamlPath, stringify(parsedBaseYaml))
writeFileSync(baseYaml, stringify(parsedBaseYaml))
}
// collect referenced schemas
@@ -284,18 +285,18 @@ export default async function () {
// check if any schemas should be removed
// a schema is removed if no other schemas/operations reference it
const oasSchemasPath = path.join(oasOutputBasePath, "schemas")
readdirSync(oasSchemasPath, {
recursive: true,
encoding: "utf-8",
}).forEach((schemaYaml) => {
const schemaPath = path.join(oasSchemasPath, schemaYaml)
const oasSchemaFiles = await new fdir()
.withFullPaths()
.crawl(oasSchemasPath)
.withPromise()
oasSchemaFiles.forEach((schemaYaml) => {
const parsedSchema = oasSchemaHelper.parseSchema(
readFileSync(schemaPath, "utf-8")
readFileSync(schemaYaml, "utf-8")
)
if (!parsedSchema) {
// remove file
rmSync(schemaPath, {
rmSync(schemaYaml, {
force: true,
})
return
@@ -311,19 +312,19 @@ export default async function () {
})
// clean up schemas
allSchemas.forEach((schemaName) => {
if (
referencedSchemas.has(schemaName) ||
ignoreSchemas.includes(schemaName)
) {
return
}
// schema isn't referenced anywhere, so remove it
rmSync(path.join(oasSchemasPath, `${schemaName}.ts`), {
force: true,
Array.from(allSchemas)
.filter((schemaName) => {
return (
!referencedSchemas.has(schemaName) &&
!ignoreSchemas.includes(schemaName)
)
})
.forEach((schemaName) => {
// schema isn't referenced anywhere, so remove it
rmSync(path.join(oasSchemasPath, `${schemaName}.ts`), {
force: true,
})
})
})
console.log("Finished clean up")
}

View File

@@ -2646,6 +2646,7 @@ __metadata:
commander: ^11.1.0
dotenv: ^16.3.1
eslint: 8.56.0
fdir: ^6.5.0
glob: ^11.0.2
minimatch: ^9.0.3
openai: ^4.29.1
@@ -3279,6 +3280,18 @@ __metadata:
languageName: node
linkType: hard
"fdir@npm:^6.5.0":
version: 6.5.0
resolution: "fdir@npm:6.5.0"
peerDependencies:
picomatch: ^3 || ^4
peerDependenciesMeta:
picomatch:
optional: true
checksum: e345083c4306b3aed6cb8ec551e26c36bab5c511e99ea4576a16750ddc8d3240e63826cc624f5ae17ad4dc82e68a253213b60d556c11bfad064b7607847ed07f
languageName: node
linkType: hard
"file-entry-cache@npm:^6.0.1":
version: 6.0.1
resolution: "file-entry-cache@npm:6.0.1"