From 9a412f5ee0f0a2e5ef9fef87460e196a2c22c7b5 Mon Sep 17 00:00:00 2001
From: Dan Jones <danjon@noc.ac.uk>
Date: Fri, 30 Aug 2024 11:05:22 +0100
Subject: [PATCH] feat: downgrade geojson to 3.0.x compatible schema

This allows us to include Feature and FeatureCollection
We probably don't need FeatureCollection for now at least
We do need Feature since the primitive list will
contain a list of features of varied geometries
---
 generate_schema_config.py |   39 +-
 project/soar/swagger.json | 1020 +++++++++++++++++++++++++++++++++++++
 2 files changed, 1053 insertions(+), 6 deletions(-)

diff --git a/generate_schema_config.py b/generate_schema_config.py
index aca7647..cb3b238 100644
--- a/generate_schema_config.py
+++ b/generate_schema_config.py
@@ -162,6 +162,35 @@ def nested_replace(source, key, value, replace_with):
             nested_replace(v, key, value, replace_with)
 
 
+def downgrade_schema_30x_compatible(schema):
+    """
+    The published GeoJSON schemas are OpenAPI v3.1
+
+    Moving to v3.1 is not trivial
+    There isn't a CommonJS validator for v3.1
+    There isn't a python source of the v3.0.x defs
+
+    Remove $id and $schema
+    Remove oneOf: [{type:null}]
+    Iterate over oneOf and items child schemas
+    """
+    if "$id" in schema:
+        del schema["$id"]
+    if "$schema" in schema:
+        del schema["$schema"]
+    if "properties" in schema:
+        for propConfig in schema["properties"].values():
+            if "oneOf" in propConfig:
+                try:
+                    propConfig["oneOf"].remove({"type": "null"})
+                except ValueError:
+                    pass
+                for child_schema in propConfig["oneOf"]:
+                    downgrade_schema_30x_compatible(child_schema)
+            if "items" in propConfig:
+                downgrade_schema_30x_compatible(propConfig["items"])
+
+
 def inject_schema(schema, remote_ref):
     """
     Given a parent schema and a remote ref
@@ -171,14 +200,12 @@ def inject_schema(schema, remote_ref):
     3. insert into components.schemas
     4. replace remote references with local references
 
-
     returns True if resolved and injected
     """
     local_name = rename_ref(remote_ref)
     local_ref = f"#/components/schemas/{local_name}"
     ref_schema = resolve_ref(remote_ref)
-    del ref_schema["$id"]
-    del ref_schema["$schema"]
+    downgrade_schema_30x_compatible(ref_schema)
     if ref_schema is not None:
         nested_replace(schema, "$ref", remote_ref, local_ref)
         schema["components"]["schemas"][local_name] = ref_schema
@@ -198,8 +225,8 @@ def import_remote_refs(swagger_config):
     # makes the schema fail to validate
 
     ref_imports = [
-        # "https://geojson.org/schema/Feature.json",
-        # "https://geojson.org/schema/FeatureCollection.json",
+        "https://geojson.org/schema/FeatureCollection.json",
+        "https://geojson.org/schema/Feature.json",
         "https://geojson.org/schema/LineString.json",
         "https://geojson.org/schema/MultiLineString.json",
         "https://geojson.org/schema/MultiPoint.json",
@@ -316,7 +343,7 @@ def get_options():
     args = parser.parse_args()
     config = vars(args)
     # If no flag is specified default to running the flask server
-    if not (config['run_flask'] or config['output_file']):
+    if not (config["run_flask"] or config["output_file"]):
         config["run_flask"] = True
     return config
 
diff --git a/project/soar/swagger.json b/project/soar/swagger.json
index e89b24f..e73d62e 100644
--- a/project/soar/swagger.json
+++ b/project/soar/swagger.json
@@ -111,6 +111,1026 @@
         ],
         "type": "object"
       },
+      "geojson.org.schema.Feature.json": {
+        "properties": {
+          "bbox": {
+            "items": {
+              "type": "number"
+            },
+            "minItems": 4,
+            "type": "array"
+          },
+          "geometry": {
+            "oneOf": [
+              {
+                "properties": {
+                  "bbox": {
+                    "items": {
+                      "type": "number"
+                    },
+                    "minItems": 4,
+                    "type": "array"
+                  },
+                  "coordinates": {
+                    "items": {
+                      "type": "number"
+                    },
+                    "minItems": 2,
+                    "type": "array"
+                  },
+                  "type": {
+                    "enum": [
+                      "Point"
+                    ],
+                    "type": "string"
+                  }
+                },
+                "required": [
+                  "type",
+                  "coordinates"
+                ],
+                "title": "GeoJSON Point",
+                "type": "object"
+              },
+              {
+                "properties": {
+                  "bbox": {
+                    "items": {
+                      "type": "number"
+                    },
+                    "minItems": 4,
+                    "type": "array"
+                  },
+                  "coordinates": {
+                    "items": {
+                      "items": {
+                        "type": "number"
+                      },
+                      "minItems": 2,
+                      "type": "array"
+                    },
+                    "minItems": 2,
+                    "type": "array"
+                  },
+                  "type": {
+                    "enum": [
+                      "LineString"
+                    ],
+                    "type": "string"
+                  }
+                },
+                "required": [
+                  "type",
+                  "coordinates"
+                ],
+                "title": "GeoJSON LineString",
+                "type": "object"
+              },
+              {
+                "properties": {
+                  "bbox": {
+                    "items": {
+                      "type": "number"
+                    },
+                    "minItems": 4,
+                    "type": "array"
+                  },
+                  "coordinates": {
+                    "items": {
+                      "items": {
+                        "items": {
+                          "type": "number"
+                        },
+                        "minItems": 2,
+                        "type": "array"
+                      },
+                      "minItems": 4,
+                      "type": "array"
+                    },
+                    "type": "array"
+                  },
+                  "type": {
+                    "enum": [
+                      "Polygon"
+                    ],
+                    "type": "string"
+                  }
+                },
+                "required": [
+                  "type",
+                  "coordinates"
+                ],
+                "title": "GeoJSON Polygon",
+                "type": "object"
+              },
+              {
+                "properties": {
+                  "bbox": {
+                    "items": {
+                      "type": "number"
+                    },
+                    "minItems": 4,
+                    "type": "array"
+                  },
+                  "coordinates": {
+                    "items": {
+                      "items": {
+                        "type": "number"
+                      },
+                      "minItems": 2,
+                      "type": "array"
+                    },
+                    "type": "array"
+                  },
+                  "type": {
+                    "enum": [
+                      "MultiPoint"
+                    ],
+                    "type": "string"
+                  }
+                },
+                "required": [
+                  "type",
+                  "coordinates"
+                ],
+                "title": "GeoJSON MultiPoint",
+                "type": "object"
+              },
+              {
+                "properties": {
+                  "bbox": {
+                    "items": {
+                      "type": "number"
+                    },
+                    "minItems": 4,
+                    "type": "array"
+                  },
+                  "coordinates": {
+                    "items": {
+                      "items": {
+                        "items": {
+                          "type": "number"
+                        },
+                        "minItems": 2,
+                        "type": "array"
+                      },
+                      "minItems": 2,
+                      "type": "array"
+                    },
+                    "type": "array"
+                  },
+                  "type": {
+                    "enum": [
+                      "MultiLineString"
+                    ],
+                    "type": "string"
+                  }
+                },
+                "required": [
+                  "type",
+                  "coordinates"
+                ],
+                "title": "GeoJSON MultiLineString",
+                "type": "object"
+              },
+              {
+                "properties": {
+                  "bbox": {
+                    "items": {
+                      "type": "number"
+                    },
+                    "minItems": 4,
+                    "type": "array"
+                  },
+                  "coordinates": {
+                    "items": {
+                      "items": {
+                        "items": {
+                          "items": {
+                            "type": "number"
+                          },
+                          "minItems": 2,
+                          "type": "array"
+                        },
+                        "minItems": 4,
+                        "type": "array"
+                      },
+                      "type": "array"
+                    },
+                    "type": "array"
+                  },
+                  "type": {
+                    "enum": [
+                      "MultiPolygon"
+                    ],
+                    "type": "string"
+                  }
+                },
+                "required": [
+                  "type",
+                  "coordinates"
+                ],
+                "title": "GeoJSON MultiPolygon",
+                "type": "object"
+              },
+              {
+                "properties": {
+                  "bbox": {
+                    "items": {
+                      "type": "number"
+                    },
+                    "minItems": 4,
+                    "type": "array"
+                  },
+                  "geometries": {
+                    "items": {
+                      "oneOf": [
+                        {
+                          "properties": {
+                            "bbox": {
+                              "items": {
+                                "type": "number"
+                              },
+                              "minItems": 4,
+                              "type": "array"
+                            },
+                            "coordinates": {
+                              "items": {
+                                "type": "number"
+                              },
+                              "minItems": 2,
+                              "type": "array"
+                            },
+                            "type": {
+                              "enum": [
+                                "Point"
+                              ],
+                              "type": "string"
+                            }
+                          },
+                          "required": [
+                            "type",
+                            "coordinates"
+                          ],
+                          "title": "GeoJSON Point",
+                          "type": "object"
+                        },
+                        {
+                          "properties": {
+                            "bbox": {
+                              "items": {
+                                "type": "number"
+                              },
+                              "minItems": 4,
+                              "type": "array"
+                            },
+                            "coordinates": {
+                              "items": {
+                                "items": {
+                                  "type": "number"
+                                },
+                                "minItems": 2,
+                                "type": "array"
+                              },
+                              "minItems": 2,
+                              "type": "array"
+                            },
+                            "type": {
+                              "enum": [
+                                "LineString"
+                              ],
+                              "type": "string"
+                            }
+                          },
+                          "required": [
+                            "type",
+                            "coordinates"
+                          ],
+                          "title": "GeoJSON LineString",
+                          "type": "object"
+                        },
+                        {
+                          "properties": {
+                            "bbox": {
+                              "items": {
+                                "type": "number"
+                              },
+                              "minItems": 4,
+                              "type": "array"
+                            },
+                            "coordinates": {
+                              "items": {
+                                "items": {
+                                  "items": {
+                                    "type": "number"
+                                  },
+                                  "minItems": 2,
+                                  "type": "array"
+                                },
+                                "minItems": 4,
+                                "type": "array"
+                              },
+                              "type": "array"
+                            },
+                            "type": {
+                              "enum": [
+                                "Polygon"
+                              ],
+                              "type": "string"
+                            }
+                          },
+                          "required": [
+                            "type",
+                            "coordinates"
+                          ],
+                          "title": "GeoJSON Polygon",
+                          "type": "object"
+                        },
+                        {
+                          "properties": {
+                            "bbox": {
+                              "items": {
+                                "type": "number"
+                              },
+                              "minItems": 4,
+                              "type": "array"
+                            },
+                            "coordinates": {
+                              "items": {
+                                "items": {
+                                  "type": "number"
+                                },
+                                "minItems": 2,
+                                "type": "array"
+                              },
+                              "type": "array"
+                            },
+                            "type": {
+                              "enum": [
+                                "MultiPoint"
+                              ],
+                              "type": "string"
+                            }
+                          },
+                          "required": [
+                            "type",
+                            "coordinates"
+                          ],
+                          "title": "GeoJSON MultiPoint",
+                          "type": "object"
+                        },
+                        {
+                          "properties": {
+                            "bbox": {
+                              "items": {
+                                "type": "number"
+                              },
+                              "minItems": 4,
+                              "type": "array"
+                            },
+                            "coordinates": {
+                              "items": {
+                                "items": {
+                                  "items": {
+                                    "type": "number"
+                                  },
+                                  "minItems": 2,
+                                  "type": "array"
+                                },
+                                "minItems": 2,
+                                "type": "array"
+                              },
+                              "type": "array"
+                            },
+                            "type": {
+                              "enum": [
+                                "MultiLineString"
+                              ],
+                              "type": "string"
+                            }
+                          },
+                          "required": [
+                            "type",
+                            "coordinates"
+                          ],
+                          "title": "GeoJSON MultiLineString",
+                          "type": "object"
+                        },
+                        {
+                          "properties": {
+                            "bbox": {
+                              "items": {
+                                "type": "number"
+                              },
+                              "minItems": 4,
+                              "type": "array"
+                            },
+                            "coordinates": {
+                              "items": {
+                                "items": {
+                                  "items": {
+                                    "items": {
+                                      "type": "number"
+                                    },
+                                    "minItems": 2,
+                                    "type": "array"
+                                  },
+                                  "minItems": 4,
+                                  "type": "array"
+                                },
+                                "type": "array"
+                              },
+                              "type": "array"
+                            },
+                            "type": {
+                              "enum": [
+                                "MultiPolygon"
+                              ],
+                              "type": "string"
+                            }
+                          },
+                          "required": [
+                            "type",
+                            "coordinates"
+                          ],
+                          "title": "GeoJSON MultiPolygon",
+                          "type": "object"
+                        }
+                      ]
+                    },
+                    "type": "array"
+                  },
+                  "type": {
+                    "enum": [
+                      "GeometryCollection"
+                    ],
+                    "type": "string"
+                  }
+                },
+                "required": [
+                  "type",
+                  "geometries"
+                ],
+                "title": "GeoJSON GeometryCollection",
+                "type": "object"
+              }
+            ]
+          },
+          "id": {
+            "oneOf": [
+              {
+                "type": "number"
+              },
+              {
+                "type": "string"
+              }
+            ]
+          },
+          "properties": {
+            "oneOf": [
+              {
+                "type": "object"
+              }
+            ]
+          },
+          "type": {
+            "enum": [
+              "Feature"
+            ],
+            "type": "string"
+          }
+        },
+        "required": [
+          "type",
+          "properties",
+          "geometry"
+        ],
+        "title": "GeoJSON Feature",
+        "type": "object"
+      },
+      "geojson.org.schema.FeatureCollection.json": {
+        "properties": {
+          "bbox": {
+            "items": {
+              "type": "number"
+            },
+            "minItems": 4,
+            "type": "array"
+          },
+          "features": {
+            "items": {
+              "properties": {
+                "bbox": {
+                  "items": {
+                    "type": "number"
+                  },
+                  "minItems": 4,
+                  "type": "array"
+                },
+                "geometry": {
+                  "oneOf": [
+                    {
+                      "properties": {
+                        "bbox": {
+                          "items": {
+                            "type": "number"
+                          },
+                          "minItems": 4,
+                          "type": "array"
+                        },
+                        "coordinates": {
+                          "items": {
+                            "type": "number"
+                          },
+                          "minItems": 2,
+                          "type": "array"
+                        },
+                        "type": {
+                          "enum": [
+                            "Point"
+                          ],
+                          "type": "string"
+                        }
+                      },
+                      "required": [
+                        "type",
+                        "coordinates"
+                      ],
+                      "title": "GeoJSON Point",
+                      "type": "object"
+                    },
+                    {
+                      "properties": {
+                        "bbox": {
+                          "items": {
+                            "type": "number"
+                          },
+                          "minItems": 4,
+                          "type": "array"
+                        },
+                        "coordinates": {
+                          "items": {
+                            "items": {
+                              "type": "number"
+                            },
+                            "minItems": 2,
+                            "type": "array"
+                          },
+                          "minItems": 2,
+                          "type": "array"
+                        },
+                        "type": {
+                          "enum": [
+                            "LineString"
+                          ],
+                          "type": "string"
+                        }
+                      },
+                      "required": [
+                        "type",
+                        "coordinates"
+                      ],
+                      "title": "GeoJSON LineString",
+                      "type": "object"
+                    },
+                    {
+                      "properties": {
+                        "bbox": {
+                          "items": {
+                            "type": "number"
+                          },
+                          "minItems": 4,
+                          "type": "array"
+                        },
+                        "coordinates": {
+                          "items": {
+                            "items": {
+                              "items": {
+                                "type": "number"
+                              },
+                              "minItems": 2,
+                              "type": "array"
+                            },
+                            "minItems": 4,
+                            "type": "array"
+                          },
+                          "type": "array"
+                        },
+                        "type": {
+                          "enum": [
+                            "Polygon"
+                          ],
+                          "type": "string"
+                        }
+                      },
+                      "required": [
+                        "type",
+                        "coordinates"
+                      ],
+                      "title": "GeoJSON Polygon",
+                      "type": "object"
+                    },
+                    {
+                      "properties": {
+                        "bbox": {
+                          "items": {
+                            "type": "number"
+                          },
+                          "minItems": 4,
+                          "type": "array"
+                        },
+                        "coordinates": {
+                          "items": {
+                            "items": {
+                              "type": "number"
+                            },
+                            "minItems": 2,
+                            "type": "array"
+                          },
+                          "type": "array"
+                        },
+                        "type": {
+                          "enum": [
+                            "MultiPoint"
+                          ],
+                          "type": "string"
+                        }
+                      },
+                      "required": [
+                        "type",
+                        "coordinates"
+                      ],
+                      "title": "GeoJSON MultiPoint",
+                      "type": "object"
+                    },
+                    {
+                      "properties": {
+                        "bbox": {
+                          "items": {
+                            "type": "number"
+                          },
+                          "minItems": 4,
+                          "type": "array"
+                        },
+                        "coordinates": {
+                          "items": {
+                            "items": {
+                              "items": {
+                                "type": "number"
+                              },
+                              "minItems": 2,
+                              "type": "array"
+                            },
+                            "minItems": 2,
+                            "type": "array"
+                          },
+                          "type": "array"
+                        },
+                        "type": {
+                          "enum": [
+                            "MultiLineString"
+                          ],
+                          "type": "string"
+                        }
+                      },
+                      "required": [
+                        "type",
+                        "coordinates"
+                      ],
+                      "title": "GeoJSON MultiLineString",
+                      "type": "object"
+                    },
+                    {
+                      "properties": {
+                        "bbox": {
+                          "items": {
+                            "type": "number"
+                          },
+                          "minItems": 4,
+                          "type": "array"
+                        },
+                        "coordinates": {
+                          "items": {
+                            "items": {
+                              "items": {
+                                "items": {
+                                  "type": "number"
+                                },
+                                "minItems": 2,
+                                "type": "array"
+                              },
+                              "minItems": 4,
+                              "type": "array"
+                            },
+                            "type": "array"
+                          },
+                          "type": "array"
+                        },
+                        "type": {
+                          "enum": [
+                            "MultiPolygon"
+                          ],
+                          "type": "string"
+                        }
+                      },
+                      "required": [
+                        "type",
+                        "coordinates"
+                      ],
+                      "title": "GeoJSON MultiPolygon",
+                      "type": "object"
+                    },
+                    {
+                      "properties": {
+                        "bbox": {
+                          "items": {
+                            "type": "number"
+                          },
+                          "minItems": 4,
+                          "type": "array"
+                        },
+                        "geometries": {
+                          "items": {
+                            "oneOf": [
+                              {
+                                "properties": {
+                                  "bbox": {
+                                    "items": {
+                                      "type": "number"
+                                    },
+                                    "minItems": 4,
+                                    "type": "array"
+                                  },
+                                  "coordinates": {
+                                    "items": {
+                                      "type": "number"
+                                    },
+                                    "minItems": 2,
+                                    "type": "array"
+                                  },
+                                  "type": {
+                                    "enum": [
+                                      "Point"
+                                    ],
+                                    "type": "string"
+                                  }
+                                },
+                                "required": [
+                                  "type",
+                                  "coordinates"
+                                ],
+                                "title": "GeoJSON Point",
+                                "type": "object"
+                              },
+                              {
+                                "properties": {
+                                  "bbox": {
+                                    "items": {
+                                      "type": "number"
+                                    },
+                                    "minItems": 4,
+                                    "type": "array"
+                                  },
+                                  "coordinates": {
+                                    "items": {
+                                      "items": {
+                                        "type": "number"
+                                      },
+                                      "minItems": 2,
+                                      "type": "array"
+                                    },
+                                    "minItems": 2,
+                                    "type": "array"
+                                  },
+                                  "type": {
+                                    "enum": [
+                                      "LineString"
+                                    ],
+                                    "type": "string"
+                                  }
+                                },
+                                "required": [
+                                  "type",
+                                  "coordinates"
+                                ],
+                                "title": "GeoJSON LineString",
+                                "type": "object"
+                              },
+                              {
+                                "properties": {
+                                  "bbox": {
+                                    "items": {
+                                      "type": "number"
+                                    },
+                                    "minItems": 4,
+                                    "type": "array"
+                                  },
+                                  "coordinates": {
+                                    "items": {
+                                      "items": {
+                                        "items": {
+                                          "type": "number"
+                                        },
+                                        "minItems": 2,
+                                        "type": "array"
+                                      },
+                                      "minItems": 4,
+                                      "type": "array"
+                                    },
+                                    "type": "array"
+                                  },
+                                  "type": {
+                                    "enum": [
+                                      "Polygon"
+                                    ],
+                                    "type": "string"
+                                  }
+                                },
+                                "required": [
+                                  "type",
+                                  "coordinates"
+                                ],
+                                "title": "GeoJSON Polygon",
+                                "type": "object"
+                              },
+                              {
+                                "properties": {
+                                  "bbox": {
+                                    "items": {
+                                      "type": "number"
+                                    },
+                                    "minItems": 4,
+                                    "type": "array"
+                                  },
+                                  "coordinates": {
+                                    "items": {
+                                      "items": {
+                                        "type": "number"
+                                      },
+                                      "minItems": 2,
+                                      "type": "array"
+                                    },
+                                    "type": "array"
+                                  },
+                                  "type": {
+                                    "enum": [
+                                      "MultiPoint"
+                                    ],
+                                    "type": "string"
+                                  }
+                                },
+                                "required": [
+                                  "type",
+                                  "coordinates"
+                                ],
+                                "title": "GeoJSON MultiPoint",
+                                "type": "object"
+                              },
+                              {
+                                "properties": {
+                                  "bbox": {
+                                    "items": {
+                                      "type": "number"
+                                    },
+                                    "minItems": 4,
+                                    "type": "array"
+                                  },
+                                  "coordinates": {
+                                    "items": {
+                                      "items": {
+                                        "items": {
+                                          "type": "number"
+                                        },
+                                        "minItems": 2,
+                                        "type": "array"
+                                      },
+                                      "minItems": 2,
+                                      "type": "array"
+                                    },
+                                    "type": "array"
+                                  },
+                                  "type": {
+                                    "enum": [
+                                      "MultiLineString"
+                                    ],
+                                    "type": "string"
+                                  }
+                                },
+                                "required": [
+                                  "type",
+                                  "coordinates"
+                                ],
+                                "title": "GeoJSON MultiLineString",
+                                "type": "object"
+                              },
+                              {
+                                "properties": {
+                                  "bbox": {
+                                    "items": {
+                                      "type": "number"
+                                    },
+                                    "minItems": 4,
+                                    "type": "array"
+                                  },
+                                  "coordinates": {
+                                    "items": {
+                                      "items": {
+                                        "items": {
+                                          "items": {
+                                            "type": "number"
+                                          },
+                                          "minItems": 2,
+                                          "type": "array"
+                                        },
+                                        "minItems": 4,
+                                        "type": "array"
+                                      },
+                                      "type": "array"
+                                    },
+                                    "type": "array"
+                                  },
+                                  "type": {
+                                    "enum": [
+                                      "MultiPolygon"
+                                    ],
+                                    "type": "string"
+                                  }
+                                },
+                                "required": [
+                                  "type",
+                                  "coordinates"
+                                ],
+                                "title": "GeoJSON MultiPolygon",
+                                "type": "object"
+                              }
+                            ]
+                          },
+                          "type": "array"
+                        },
+                        "type": {
+                          "enum": [
+                            "GeometryCollection"
+                          ],
+                          "type": "string"
+                        }
+                      },
+                      "required": [
+                        "type",
+                        "geometries"
+                      ],
+                      "title": "GeoJSON GeometryCollection",
+                      "type": "object"
+                    }
+                  ]
+                },
+                "id": {
+                  "oneOf": [
+                    {
+                      "type": "number"
+                    },
+                    {
+                      "type": "string"
+                    }
+                  ]
+                },
+                "properties": {
+                  "oneOf": [
+                    {
+                      "type": "object"
+                    }
+                  ]
+                },
+                "type": {
+                  "enum": [
+                    "Feature"
+                  ],
+                  "type": "string"
+                }
+              },
+              "required": [
+                "type",
+                "properties",
+                "geometry"
+              ],
+              "title": "GeoJSON Feature",
+              "type": "object"
+            },
+            "type": "array"
+          },
+          "type": {
+            "enum": [
+              "FeatureCollection"
+            ],
+            "type": "string"
+          }
+        },
+        "required": [
+          "type",
+          "features"
+        ],
+        "title": "GeoJSON FeatureCollection",
+        "type": "object"
+      },
       "geojson.org.schema.LineString.json": {
         "properties": {
           "bbox": {
-- 
GitLab