Packages
oaspec
0.28.0
0.68.0
0.67.0
0.66.0
0.65.0
0.64.0
0.63.0
0.62.0
0.61.0
0.60.0
0.59.0
0.58.1
0.58.0
0.57.0
0.56.0
0.55.0
0.54.0
0.53.0
0.52.0
0.51.0
0.50.0
0.49.0
0.48.0
0.47.0
0.46.0
0.45.0
0.44.0
0.43.0
0.42.0
0.41.0
0.40.0
0.39.0
0.38.0
0.37.0
0.36.0
0.35.0
0.34.0
0.33.0
0.32.0
0.31.0
0.30.0
0.29.0
0.28.0
0.27.0
0.26.0
0.25.0
0.24.0
0.23.0
0.22.0
0.21.0
0.20.0
0.19.0
0.18.0
0.17.0
0.16.0
0.15.0
0.14.0
0.13.0
0.12.0
0.11.0
0.10.0
0.9.0
0.8.0
0.7.0
0.6.3
0.6.1
0.6.0
0.5.0
0.4.0
0.3.0
0.1.3
Generate Gleam code from OpenAPI 3.x specifications
Current section
Files
Jump to
Current section
Files
src/oaspec/internal/openapi/provenance.gleam
//// Summarise the provenance of component schemas after the hoist pass has
//// run. Distinguishing user-authored schemas from synthetic ones created
//// during hoisting lets tooling explain where each generated type came from.
import gleam/dict
import gleam/list
import gleam/option.{None, Some}
import oaspec/internal/openapi/schema.{
HoistedAdditionalProperties, HoistedAllOfPart, HoistedAnyOfVariant,
HoistedArrayItem, HoistedOneOfVariant, HoistedParameter, HoistedProperty,
HoistedRequestBody, HoistedResponse, Inline, UserAuthored,
}
import oaspec/internal/openapi/spec.{type OpenApiSpec}
/// Breakdown of component schemas by origin after hoisting.
pub type HoistedSummary {
HoistedSummary(
user_authored: List(String),
hoisted_properties: List(#(String, String, String)),
hoisted_array_items: List(#(String, String)),
hoisted_oneof_variants: List(#(String, String, Int)),
hoisted_anyof_variants: List(#(String, String, Int)),
hoisted_allof_parts: List(#(String, String, Int)),
hoisted_request_bodies: List(#(String, String)),
hoisted_responses: List(#(String, String, String)),
hoisted_parameters: List(#(String, String, String)),
hoisted_additional_properties: List(#(String, String)),
)
}
/// Total number of synthetic schemas that were created during hoisting.
pub fn total_hoisted(summary: HoistedSummary) -> Int {
list.length(summary.hoisted_properties)
+ list.length(summary.hoisted_array_items)
+ list.length(summary.hoisted_oneof_variants)
+ list.length(summary.hoisted_anyof_variants)
+ list.length(summary.hoisted_allof_parts)
+ list.length(summary.hoisted_request_bodies)
+ list.length(summary.hoisted_responses)
+ list.length(summary.hoisted_parameters)
+ list.length(summary.hoisted_additional_properties)
}
/// Walk component schemas and group them by provenance. Reference-only
/// entries (rare after resolve) are ignored because they carry no
/// metadata of their own.
pub fn hoisted_schema_summary(spec: OpenApiSpec(stage)) -> HoistedSummary {
let empty =
HoistedSummary(
user_authored: [],
hoisted_properties: [],
hoisted_array_items: [],
hoisted_oneof_variants: [],
hoisted_anyof_variants: [],
hoisted_allof_parts: [],
hoisted_request_bodies: [],
hoisted_responses: [],
hoisted_parameters: [],
hoisted_additional_properties: [],
)
let schemas = case spec.components {
Some(components) -> components.schemas
None -> dict.new()
}
dict.to_list(schemas)
|> list.fold(empty, fn(acc, entry) {
let #(name, schema_ref) = entry
case schema_ref {
Inline(obj) ->
case schema.get_provenance(obj) {
UserAuthored ->
HoistedSummary(..acc, user_authored: [name, ..acc.user_authored])
HoistedProperty(parent:, property:) ->
HoistedSummary(..acc, hoisted_properties: [
#(name, parent, property),
..acc.hoisted_properties
])
HoistedArrayItem(parent:) ->
HoistedSummary(..acc, hoisted_array_items: [
#(name, parent),
..acc.hoisted_array_items
])
HoistedOneOfVariant(parent:, index:) ->
HoistedSummary(..acc, hoisted_oneof_variants: [
#(name, parent, index),
..acc.hoisted_oneof_variants
])
HoistedAnyOfVariant(parent:, index:) ->
HoistedSummary(..acc, hoisted_anyof_variants: [
#(name, parent, index),
..acc.hoisted_anyof_variants
])
HoistedAllOfPart(parent:, index:) ->
HoistedSummary(..acc, hoisted_allof_parts: [
#(name, parent, index),
..acc.hoisted_allof_parts
])
HoistedRequestBody(operation_id:) ->
HoistedSummary(..acc, hoisted_request_bodies: [
#(name, operation_id),
..acc.hoisted_request_bodies
])
HoistedResponse(operation_id:, status:) ->
HoistedSummary(..acc, hoisted_responses: [
#(name, operation_id, status),
..acc.hoisted_responses
])
HoistedParameter(operation_id:, name: param_name) ->
HoistedSummary(..acc, hoisted_parameters: [
#(name, operation_id, param_name),
..acc.hoisted_parameters
])
HoistedAdditionalProperties(parent:) ->
HoistedSummary(..acc, hoisted_additional_properties: [
#(name, parent),
..acc.hoisted_additional_properties
])
}
_ -> acc
}
})
}