Skip to content

Commit

Permalink
fix small issues
Browse files Browse the repository at this point in the history
  • Loading branch information
mattoni committed Nov 5, 2024
1 parent c9a4611 commit 36c86e8
Show file tree
Hide file tree
Showing 11 changed files with 96 additions and 35 deletions.
2 changes: 1 addition & 1 deletion components/schemas/environments/EnvironmentFeatures.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@ properties:
type: string
enum:
- limited
- standard
- basic
- premium
- enterprise
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ required:
- enable
- container_id
- high_availability
- config
properties:
enable:
type: boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ required:
- enable
- container_id
- high_availability
- config
properties:
enable:
type: boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ required:
- enable
- container_id
- high_availablity
# - config
properties:
enable:
type: boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ required:
- enable
- container_id
- high_availability
- config
properties:
enable:
type: boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ properties:
type: string
custom_resolvers:
description: "A list of custom DNS resolver strings. Can specifify domains or ips."
type: array
items:
type: string
oneOf:
- type: array
items:
type: string
- type: "null"
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ properties:
enum:
- "v1"
details:
$ref: V1LbConfig.yml
anyOf:
- $ref: V1LbConfig.yml
- type: "null"
bind_host:
description: |
Binds the load balancer to the host server IP address.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ properties:
enum:
- any
- all
# legacy value TODO remove
- ""
conditions:
description: An array of the specific conditions for the rule.
type: array
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,9 @@ properties:
description: Replacement value.
type: string
url:
type: string
type:
- string
- "null"
description: |
The URL to forward the request to.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,4 @@ properties:
oneOf:
- $ref: ./haproxy/StackSpecHaProxyConfig.yml
- $ref: ./v1/StackSpecV1LbConfig.yml

- type: "null"
106 changes: 82 additions & 24 deletions util/downconvert.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,8 @@ class Schema {
adjust(schemaMap: Record<string, Schema>) {
this.removeUnsupportedProperties();
this.handleConstAsEnum();
this.flattenAnyOfOrOneOfWithRefAndNull(schemaMap);
this.handleAnyOfWithNull();
this.handleOneOfWithNull();
this.flattenIdenticalReferences(schemaMap);
this.adjustNestedSchemas(schemaMap);
}
Expand All @@ -141,40 +142,94 @@ class Schema {
}
}

// Handle the specific case where `anyOf` or `oneOf` contains a `$ref` and `null`
flattenAnyOfOrOneOfWithRefAndNull(schemaMap: Record<string, Schema>) {
const keywords = ["oneOf", "anyOf"] as const;
// Handle `anyOf` containing `null` and a reference or another type
handleAnyOfWithNull() {
if (this.anyOf) {
let hasNullType = false;
let nonNullEntry: Schema | null = null;

// Check for `null` type in `anyOf`
this.anyOf.forEach((entry) => {
if (entry.type === "null") {
hasNullType = true;
} else {
nonNullEntry = entry;
}
});

keywords.forEach((keyword) => {
if (this[keyword]) {
let hasNullType = false;
let refEntry: Schema | null = null;
// If both `null` and another type are present, make the schema nullable and use `allOf` for reference
if (hasNullType && nonNullEntry) {
this.nullable = true;

// Check for `$ref` and `null` type in `oneOf` or `anyOf`
this[keyword]!.forEach((entry) => {
if (entry.type === "null") {
hasNullType = true;
} else if (entry.$ref) {
refEntry = entry;
if (nonNullEntry.$ref) {
// Convert `anyOf` to `allOf` with the reference
this.allOf = [{ $ref: nonNullEntry.$ref }];
} else {
// Otherwise, retain all properties of the non-null entry
Object.assign(this, nonNullEntry);
}

delete this.anyOf;
}
}
}

// Handle `oneOf` containing `null` and another type
handleOneOfWithNull() {
// Do not modify `oneOf` if a discriminator is present
if (this.discriminator) {
return;
}

if (this.oneOf) {
let hasNullType = false;
let nonNullEntry: Schema | null = null;

// Iterate through the `oneOf` entries
this.oneOf.forEach((entry) => {
if (entry.type === "null") {
hasNullType = true;
} else {
nonNullEntry = entry;
}
});

// If both `null` and another type are present
if (hasNullType && nonNullEntry) {
// Set nullable to true
this.nullable = true;

// Retain all properties of the non-null entry (type, enum, description, etc.)
for (const key in nonNullEntry) {
if (key !== "type" && key !== "nullable") {
(this as any)[key] = nonNullEntry[key];
}
});
}

// If both `$ref` and `null` are present, convert to `allOf` with `nullable: true`
if (refEntry && hasNullType) {
this.nullable = true;
this.allOf = [refEntry];
delete this[keyword];
// Assign the type of the non-null entry
this.type = nonNullEntry.type;

// If there's an enum, retain it
if (nonNullEntry.enum) {
this.enum = nonNullEntry.enum;
}

delete this.oneOf;
}
});
}
}

// Flatten `oneOf` or `anyOf` if all `$ref` point to the same primitive type
flattenIdenticalReferences(schemaMap: Record<string, Schema>) {
// Do not modify `oneOf` or `anyOf` if a discriminator is present
if (this.discriminator) {
return;
}

const keywords = ["oneOf", "anyOf"] as const;

keywords.forEach((keyword) => {
if (this[keyword] && !this.discriminator) {
if (this[keyword]) {
const entries = this[keyword]!;
let primitiveType: string | null = null;
let hasNullType = false;
Expand Down Expand Up @@ -238,8 +293,11 @@ class Schema {
keywords.forEach((keyword) => {
if (this[keyword]) {
this[keyword] = this[keyword]!.map((entry) => {
entry.adjust(schemaMap);
return entry;
// Ensure entry is converted to a Schema instance before adjustment
const schemaEntry =
entry instanceof Schema ? entry : new Schema(entry);
schemaEntry.adjust(schemaMap);
return schemaEntry;
});
}
});
Expand Down

0 comments on commit 36c86e8

Please sign in to comment.