From 3d1cabbd49d527271d3444d17b10022daa9578d1 Mon Sep 17 00:00:00 2001 From: Adam Bergman Date: Mon, 20 Jan 2025 15:42:35 +0100 Subject: [PATCH 1/8] add DateTime type to navi --- src/navi/transform.clj | 4 ++++ test/navi/impl_test.clj | 12 +++++++++++- test/navi/transform_test.clj | 3 +++ 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/navi/transform.clj b/src/navi/transform.clj index 7cef333..b525b11 100644 --- a/src/navi/transform.clj +++ b/src/navi/transform.clj @@ -22,6 +22,7 @@ ObjectSchema Schema StringSchema + DateTimeSchema UUIDSchema] [io.swagger.v3.oas.models.parameters CookieParameter @@ -57,6 +58,9 @@ :else content-fn))) + DateTimeSchema + (p/transform [_] inst?) + UUIDSchema (p/transform [_] uuid?) diff --git a/test/navi/impl_test.clj b/test/navi/impl_test.clj index abdf8c2..289ed01 100644 --- a/test/navi/impl_test.clj +++ b/test/navi/impl_test.clj @@ -29,6 +29,8 @@ (is (= {:query [:map [:x string?]]} (i/wrap-map :path {:query [:map [:x string?]]}))))) + + (deftest openapi-properties-to-malli-spec (testing "convert a required OpenAPI Map entry" (let [property (Map/entry "id" (StringSchema.))] @@ -37,7 +39,11 @@ (testing "convert an optional OpenAPI Map entry" (let [property (Map/entry "id" (StringSchema.))] (is (= [:id {:optional true} string?] - (i/->prop-schema #{"x"} property)))))) + (i/->prop-schema #{"x"} property))))) + (testing "convert a DateTime OpenAPI Map entry" + (let [property (Map/entry "timestamp" (io.swagger.v3.oas.models.media.DateTimeSchema.))] + (is (= [:timestamp inst?] + (i/->prop-schema #{"timestamp"} property)))))) (deftest openapi-parameters-to-malli-spec (testing "convert a required OpenAPI Parameter" @@ -54,6 +60,8 @@ (is (= [:x {:optional true} string?] (i/->param-schema param)))))) + + (deftest responses-to-malli-spec (testing "empty response" (let [response (ApiResponse.)] @@ -142,3 +150,5 @@ (is (= {:get {:handler "a handler" :parameters {:path [:map [:x int?]]}}} (i/path-item->data path-item handlers)))))) + + diff --git a/test/navi/transform_test.clj b/test/navi/transform_test.clj index d6aaf42..185d1e8 100644 --- a/test/navi/transform_test.clj +++ b/test/navi/transform_test.clj @@ -17,6 +17,7 @@ ByteArraySchema ComposedSchema Content + DateTimeSchema IntegerSchema JsonSchema MediaType @@ -34,6 +35,8 @@ [java.util LinkedHashMap])) (deftest primitives + (testing "datetime" + (is (= inst? (p/transform (DateTimeSchema.))))) (testing "string" (is (= string? (p/transform (StringSchema.))))) (testing "integer" From b15a2dde7e20bf8f62d59e89d9101418e2bba573 Mon Sep 17 00:00:00 2001 From: Adam Bergman Date: Mon, 20 Jan 2025 15:47:52 +0100 Subject: [PATCH 2/8] namespace --- test/navi/impl_test.clj | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/test/navi/impl_test.clj b/test/navi/impl_test.clj index 289ed01..561a7c4 100644 --- a/test/navi/impl_test.clj +++ b/test/navi/impl_test.clj @@ -41,7 +41,7 @@ (is (= [:id {:optional true} string?] (i/->prop-schema #{"x"} property))))) (testing "convert a DateTime OpenAPI Map entry" - (let [property (Map/entry "timestamp" (io.swagger.v3.oas.models.media.DateTimeSchema.))] + (let [property (Map/entry "timestamp" (.DateTimeSchema.))] (is (= [:timestamp inst?] (i/->prop-schema #{"timestamp"} property)))))) @@ -149,6 +149,4 @@ (.setGet operation))] (is (= {:get {:handler "a handler" :parameters {:path [:map [:x int?]]}}} - (i/path-item->data path-item handlers)))))) - - + (i/path-item->data path-item handlers)))))) \ No newline at end of file From 25d4ace92f50c3a30bd2564977c24926ee924638 Mon Sep 17 00:00:00 2001 From: Adam Bergman Date: Thu, 23 Jan 2025 16:02:11 +0100 Subject: [PATCH 3/8] remove whitespace --- newopenapispec.yaml | 420 ++++++++++++++++++++++++++++++++++++++++ test/navi/impl_test.clj | 4 - 2 files changed, 420 insertions(+), 4 deletions(-) create mode 100644 newopenapispec.yaml diff --git a/newopenapispec.yaml b/newopenapispec.yaml new file mode 100644 index 0000000..5c2e974 --- /dev/null +++ b/newopenapispec.yaml @@ -0,0 +1,420 @@ +openapi: "3.0.0" + +info: + title: My calculator + version: "0.1.0" + description: My awesome calc! + +paths: + /v1/taxonomy/graphql: + get: + operationId: getGraphQL + parameters: + - in: query + name: query + required: true + schema: + type: string + description: query string + - in: query + name: variables + required: false + schema: + type: string + description: json string with query variables + - in: query + name: operationName + required: false + schema: + type: string + description: optional query name that is used when there are multiple query definitions in a single query string + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/GraphQLResult' + application/transit+msgpack: + schema: + $ref: '#/components/schemas/GraphQLResult' + application/transit+json: + schema: + $ref: '#/components/schemas/GraphQLResult' + application/edn: + schema: + $ref: '#/components/schemas/GraphQLResult' + "400": + $ref: '#/components/responses/BadRequest' + "401": + $ref: '#/components/responses/Unauthorized' + "500": + $ref: '#/components/responses/InternalServerError' + tags: + - GraphQL + summary: GraphQL endpoint for powerful graph queries + description: You should explore this API in [this GraphQL-specific explorer](/v1/taxonomy/graphiql) + + post: + operationId: postGraphQL + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/GraphQLInput' + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/GraphQLResult' + application/transit+msgpack: + schema: + $ref: '#/components/schemas/GraphQLResult' + application/transit+json: + schema: + $ref: '#/components/schemas/GraphQLResult' + application/edn: + schema: + $ref: '#/components/schemas/GraphQLResult' + "400": + $ref: '#/components/responses/BadRequest' + "401": + $ref: '#/components/responses/Unauthorized' + "500": + $ref: '#/components/responses/InternalServerError' + tags: + - GraphQL + summary: GraphQL endpoint for powerful graph queries + description: You should explore this API in [this GraphQL-specific explorer](/v1/taxonomy/graphiql) + + /v1/taxonomy/main/versions: + get: + operationId: getVersions + tags: + - Main + summary: Show the available versions. + responses: + "200": + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/VersionsList' + application/transit+msgpack: + schema: + $ref: '#/components/schemas/VersionsList' + application/transit+json: + schema: + $ref: '#/components/schemas/VersionsList' + application/edn: + schema: + $ref: '#/components/schemas/VersionsList' + "400": + $ref: '#/components/responses/BadRequest' + "401": + $ref: '#/components/responses/Unauthorized' + "500": + $ref: '#/components/responses/InternalServerError' + + + + /v1/taxonomy/main/concepts: + get: + operationId: getConcepts + tags: + - Main + summary: Get concepts. Supply at least one search parameter. + parameters: + - in: query + name: offset + description: Return list offset (from 0) + schema: + type: integer + format: int64 + minimum: 0 + - in: query + name: preferred-label + description: Textual name of concept + schema: + type: string + - in: query + name: id + description: ID of concept + schema: + type: string + - in: query + name: limit + description: Return list limit + schema: + type: integer + format: int64 + minimum: 1 + - in: query + name: include-legacy-information + description: This parameter will be removed. Include information related to Arbetsförmedlingen's old internal taxonomy + schema: + type: boolean + deprecated: true + - in: query + name: related-ids + description: OR-restrict to these relation IDs (white space separated list). If specified, relation is required + schema: + type: string + - in: query + name: include-deprecated + description: Include deprecated values + schema: + type: boolean + - in: query + name: deprecated + description: Restrict to deprecation state + schema: + type: boolean + deprecated: true + - in: query + name: type + description: Restrict to concept type + schema: + type: string + - in: query + name: version + description: Taxonomy version, either number that indicates the version, "latest" for latest release, or "next" for unpublished changes (requires admin rights) + schema: + anyOf: + - type: integer + format: int64 + - type: string + enum: + - latest + - next + - in: query + name: relation + description: Relation type. If specified, related-ids is required. "substitutability-to" and "substitutability-from" are deprecated, please use "substitutability" and "substituted-by" respectively + schema: + type: string + enum: + - close-match + - substitutability-from + - exact-match + - narrower + - broad-match + - related + - possible-combination + - narrow-match + - substitutability-to + - substitutability + - broader + - unlikely-combination + - substituted-by + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/concepts' + '400': + $ref: '#/components/responses/BadRequest' + '401': + $ref: '#/components/responses/Unauthorized' + '500': + $ref: '#/components/responses/InternalServerError' + +components: + responses: + Unauthorized: + description: Unauthorized - API key is missing or invalid + content: + application/json: + schema: + type: object + properties: + taxonomy/error: + type: string + required: + - taxonomy/error + title: taxonomy/unauthorized + application/transit+msgpack: + schema: + type: object + properties: + taxonomy/error: + type: string + required: + - taxonomy/error + title: taxonomy/unauthorized + application/transit+json: + schema: + type: object + properties: + taxonomy/error: + type: string + required: + - taxonomy/error + title: taxonomy/unauthorized + application/edn: + schema: + type: object + properties: + taxonomy/error: + type: string + required: + - taxonomy/error + title: taxonomy/unauthorized + BadRequest: + description: Bad request + content: + application/json: + schema: + $ref: '#/components/schemas/Error' + application/transit+msgpack: + schema: + $ref: '#/components/schemas/Error' + application/transit+json: + schema: + $ref: '#/components/schemas/Error' + application/edn: + schema: + $ref: '#/components/schemas/Error' + InternalServerError: + description: Internal Server Error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorWithInfo' + application/transit+msgpack: + schema: + $ref: '#/components/schemas/ErrorWithInfo' + application/transit+json: + schema: + $ref: '#/components/schemas/ErrorWithInfo' + application/edn: + schema: + $ref: '#/components/schemas/ErrorWithInfo' + schemas: + VersionInfo: + type: object + oneOf: + - required: + - taxonomy/version + - required: + - taxonomy/timestamp + properties: + taxonomy/version: + type: integer + format: int64 + taxonomy/timestamp: + type: string + format: date-time + description: ISO 8601 formatted timestamp with timezone (YYYY-MM-DDThh:mm:ss(Z|±hh:mm)) + # pattern: '^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?Z$' + examples: + - "2024-01-17T15:30:00Z" + - "2024-01-17T15:30:00+01:00" + - "2024-01-17T15:30:00-05:00" + externalDocs: + description: "ISO 8601 date validation regex explanation" + url: "https://stackoverflow.com/a/28022901" + title: taxonomy/version-object + + VersionInfo0: + type: object + properties: + taxonomy/version: + type: integer + format: int64 + taxonomy/timestamp: + type: string + format: date-time + required: + - taxonomy/version + - taxonomy/timestamp + title: taxonomy/version-object + + VersionsList: + type: array + items: + $ref: '#/components/schemas/VersionInfo' + title: taxonomy/versions + + Error: + type: object + properties: + taxonomy/error: + type: string + description: Error message + required: + - taxonomy/error + title: taxonomy/err + ErrorWithInfo: + type: object + properties: + taxonomy/error: + type: string + description: Error message describing what went wrong + taxonomy/info: + type: object + description: Additional error context information + required: + - taxonomy/error + title: taxonomy/err + NumbersMap: + type: object + required: + - n1 + - n2 + properties: + n1: + type: integer + description: The first number + n2: + type: integer + description: The second number + concept: + type: object + properties: + taxonomy/id: + type: string + taxonomy/type: + type: string + taxonomy/preferred-label: + type: string + required: + - taxonomy/id + - taxonomy/type + - taxonomy/preferred-label + concepts: + type: array + items: + $ref: '#/components/schemas/concept' + + GraphQLResult: + type: object + properties: + data: + type: object + errors: + type: array + items: + type: object + properties: + message: + type: string + GraphQLInput: + type: object + properties: + query: + type: string + description: query string + variables: + type: string + description: json string with query variables + operationName: + type: string + description: optional query name that is used when there are multiple query definitions in a single query string + required: + - query + \ No newline at end of file diff --git a/test/navi/impl_test.clj b/test/navi/impl_test.clj index 561a7c4..a497635 100644 --- a/test/navi/impl_test.clj +++ b/test/navi/impl_test.clj @@ -29,8 +29,6 @@ (is (= {:query [:map [:x string?]]} (i/wrap-map :path {:query [:map [:x string?]]}))))) - - (deftest openapi-properties-to-malli-spec (testing "convert a required OpenAPI Map entry" (let [property (Map/entry "id" (StringSchema.))] @@ -60,8 +58,6 @@ (is (= [:x {:optional true} string?] (i/->param-schema param)))))) - - (deftest responses-to-malli-spec (testing "empty response" (let [response (ApiResponse.)] From 4c741c5a30e22dddea0f89ef5d15cc7d9ecf7de5 Mon Sep 17 00:00:00 2001 From: Adam Bergman Date: Thu, 23 Jan 2025 16:09:17 +0100 Subject: [PATCH 4/8] add DateTime support --- src/navi/core.clj | 44 +++++++++++++++++++++++++++++++++++++---- src/navi/transform.clj | 4 ++++ test/navi/impl_test.clj | 6 ++++++ 3 files changed, 50 insertions(+), 4 deletions(-) diff --git a/src/navi/core.clj b/src/navi/core.clj index 1f1402f..2f74d40 100644 --- a/src/navi/core.clj +++ b/src/navi/core.clj @@ -39,7 +39,43 @@ "HealthCheck" (fn [_] {:status 200 :body "Ok"})}) - (-> "api.yaml" - slurp - (routes-from handlers) - pp/pprint)) + (def routes (-> "newopenapispec.yaml" + slurp + (routes-from handlers) + ))) + + + +(defn function->symbol [x] + (if (fn? x) + (case x + clojure.core/string? 'string? + clojure.core/int? 'int? + clojure.core/boolean? 'boolean? + clojure.core/inst? 'inst? + (-> x + .getClass + .getName + clojure.lang.Compiler/demunge + symbol)) + x)) + +(defn routes->serializable + "Convert routes data structure to serializable form" + [routes] + (clojure.walk/postwalk function->symbol routes)) + +(defn save-routes! [routes filename] + (spit filename + (with-out-str + (clojure.pprint/pprint + (routes->serializable routes))))) + +;; Usage in REPL: +(save-routes! routes "routes2.edn") + +(defn read-routes [filename] + (clojure.edn/read-string + (slurp filename))) + +(def ole (read-routes "routes.edn")) \ No newline at end of file diff --git a/src/navi/transform.clj b/src/navi/transform.clj index b525b11..7dba541 100644 --- a/src/navi/transform.clj +++ b/src/navi/transform.clj @@ -23,6 +23,7 @@ Schema StringSchema DateTimeSchema + DateSchema UUIDSchema] [io.swagger.v3.oas.models.parameters CookieParameter @@ -57,6 +58,9 @@ :else content-fn))) + + DateSchema + (p/transform [_] inst?) DateTimeSchema (p/transform [_] inst?) diff --git a/test/navi/impl_test.clj b/test/navi/impl_test.clj index a497635..7f73904 100644 --- a/test/navi/impl_test.clj +++ b/test/navi/impl_test.clj @@ -13,6 +13,7 @@ [io.swagger.v3.oas.models Operation PathItem] [io.swagger.v3.oas.models.media Content + DateSchema IntegerSchema MediaType ObjectSchema @@ -38,6 +39,11 @@ (let [property (Map/entry "id" (StringSchema.))] (is (= [:id {:optional true} string?] (i/->prop-schema #{"x"} property))))) + (testing "convert a Date OpenAPI Map entry" + (let [property (Map/entry "date" (DateSchema.))] + (is (= [:date inst?] + (i/->prop-schema #{"date"} property))))) + (testing "convert a DateTime OpenAPI Map entry" (testing "convert a DateTime OpenAPI Map entry" (let [property (Map/entry "timestamp" (.DateTimeSchema.))] (is (= [:timestamp inst?] From 62bd4fa8b77d96b07657f382afa813b3a60c48b8 Mon Sep 17 00:00:00 2001 From: Adam Bergman Date: Fri, 24 Jan 2025 10:36:03 +0100 Subject: [PATCH 5/8] add tests --- test/navi/impl_test.clj | 16 +++++++++------- test/navi/transform_test.clj | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 7 deletions(-) diff --git a/test/navi/impl_test.clj b/test/navi/impl_test.clj index 7f73904..f545e22 100644 --- a/test/navi/impl_test.clj +++ b/test/navi/impl_test.clj @@ -14,6 +14,7 @@ [io.swagger.v3.oas.models.media Content DateSchema + DateTimeSchema IntegerSchema MediaType ObjectSchema @@ -39,15 +40,16 @@ (let [property (Map/entry "id" (StringSchema.))] (is (= [:id {:optional true} string?] (i/->prop-schema #{"x"} property))))) - (testing "convert a Date OpenAPI Map entry" - (let [property (Map/entry "date" (DateSchema.))] - (is (= [:date inst?] - (i/->prop-schema #{"date"} property))))) - (testing "convert a DateTime OpenAPI Map entry" + (testing "convert a DateTime OpenAPI Map entry" - (let [property (Map/entry "timestamp" (.DateTimeSchema.))] + (let [property (Map/entry "timestamp" (DateTimeSchema.))] (is (= [:timestamp inst?] - (i/->prop-schema #{"timestamp"} property)))))) + (i/->prop-schema #{"timestamp"} property))))) + + (testing "convert a Date OpenAPI Map entry" + (let [property (Map/entry "date" (DateSchema.))] + (is (= [:date inst?] + (i/->prop-schema #{"date"} property)))))) (deftest openapi-parameters-to-malli-spec (testing "convert a required OpenAPI Parameter" diff --git a/test/navi/transform_test.clj b/test/navi/transform_test.clj index 185d1e8..7b2edc0 100644 --- a/test/navi/transform_test.clj +++ b/test/navi/transform_test.clj @@ -17,6 +17,7 @@ ByteArraySchema ComposedSchema Content + DateSchema DateTimeSchema IntegerSchema JsonSchema @@ -37,6 +38,8 @@ (deftest primitives (testing "datetime" (is (= inst? (p/transform (DateTimeSchema.))))) + (testing "date" + (is (= inst? (p/transform (DateSchema.))))) (testing "string" (is (= string? (p/transform (StringSchema.))))) (testing "integer" @@ -84,6 +87,37 @@ (testing "nil" (is (= any? (p/transform nil))))) +(deftest date-schema-transformations + (testing "DateSchema transforms to inst? predicate" + (let [schema (DateSchema.)] + (is (= inst? (p/transform schema))))) + + (testing "DateTimeSchema transforms to inst? predicate" + (let [schema (DateTimeSchema.)] + (is (= inst? (p/transform schema))))) + + (testing "inst? validates different date types" + (let [schema (DateTimeSchema.) + pred (p/transform schema)] + (testing "java.util.Date" + (is (pred (java.util.Date.)))) + (testing "java.time.Instant" + (is (pred (java.time.Instant/now)))) + (testing "java.time.LocalDateTime converted to Instant" + (is (pred (-> (java.time.LocalDateTime/now) + (.atZone (java.time.ZoneId/systemDefault)) + .toInstant)))) + (testing "java.time.ZonedDateTime converted to Instant" + (is (pred (-> (java.time.ZonedDateTime/now) + .toInstant)))))) + + (testing "inst? rejects invalid inputs" + (let [schema (DateTimeSchema.) + pred (p/transform schema)] + (is (not (pred "2024-01-01"))) + (is (not (pred nil))) + (is (not (pred 123)))))) + (deftest string-formats (testing "uuid" (is (= uuid? (p/transform (UUIDSchema.))))) From acf39a9514143088144266e84124b217f8bca248 Mon Sep 17 00:00:00 2001 From: Adam Bergman Date: Fri, 24 Jan 2025 10:36:57 +0100 Subject: [PATCH 6/8] remove file --- newopenapispec.yaml | 420 -------------------------------------------- 1 file changed, 420 deletions(-) delete mode 100644 newopenapispec.yaml diff --git a/newopenapispec.yaml b/newopenapispec.yaml deleted file mode 100644 index 5c2e974..0000000 --- a/newopenapispec.yaml +++ /dev/null @@ -1,420 +0,0 @@ -openapi: "3.0.0" - -info: - title: My calculator - version: "0.1.0" - description: My awesome calc! - -paths: - /v1/taxonomy/graphql: - get: - operationId: getGraphQL - parameters: - - in: query - name: query - required: true - schema: - type: string - description: query string - - in: query - name: variables - required: false - schema: - type: string - description: json string with query variables - - in: query - name: operationName - required: false - schema: - type: string - description: optional query name that is used when there are multiple query definitions in a single query string - responses: - "200": - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/GraphQLResult' - application/transit+msgpack: - schema: - $ref: '#/components/schemas/GraphQLResult' - application/transit+json: - schema: - $ref: '#/components/schemas/GraphQLResult' - application/edn: - schema: - $ref: '#/components/schemas/GraphQLResult' - "400": - $ref: '#/components/responses/BadRequest' - "401": - $ref: '#/components/responses/Unauthorized' - "500": - $ref: '#/components/responses/InternalServerError' - tags: - - GraphQL - summary: GraphQL endpoint for powerful graph queries - description: You should explore this API in [this GraphQL-specific explorer](/v1/taxonomy/graphiql) - - post: - operationId: postGraphQL - requestBody: - required: true - content: - application/json: - schema: - $ref: '#/components/schemas/GraphQLInput' - responses: - "200": - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/GraphQLResult' - application/transit+msgpack: - schema: - $ref: '#/components/schemas/GraphQLResult' - application/transit+json: - schema: - $ref: '#/components/schemas/GraphQLResult' - application/edn: - schema: - $ref: '#/components/schemas/GraphQLResult' - "400": - $ref: '#/components/responses/BadRequest' - "401": - $ref: '#/components/responses/Unauthorized' - "500": - $ref: '#/components/responses/InternalServerError' - tags: - - GraphQL - summary: GraphQL endpoint for powerful graph queries - description: You should explore this API in [this GraphQL-specific explorer](/v1/taxonomy/graphiql) - - /v1/taxonomy/main/versions: - get: - operationId: getVersions - tags: - - Main - summary: Show the available versions. - responses: - "200": - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/VersionsList' - application/transit+msgpack: - schema: - $ref: '#/components/schemas/VersionsList' - application/transit+json: - schema: - $ref: '#/components/schemas/VersionsList' - application/edn: - schema: - $ref: '#/components/schemas/VersionsList' - "400": - $ref: '#/components/responses/BadRequest' - "401": - $ref: '#/components/responses/Unauthorized' - "500": - $ref: '#/components/responses/InternalServerError' - - - - /v1/taxonomy/main/concepts: - get: - operationId: getConcepts - tags: - - Main - summary: Get concepts. Supply at least one search parameter. - parameters: - - in: query - name: offset - description: Return list offset (from 0) - schema: - type: integer - format: int64 - minimum: 0 - - in: query - name: preferred-label - description: Textual name of concept - schema: - type: string - - in: query - name: id - description: ID of concept - schema: - type: string - - in: query - name: limit - description: Return list limit - schema: - type: integer - format: int64 - minimum: 1 - - in: query - name: include-legacy-information - description: This parameter will be removed. Include information related to Arbetsförmedlingen's old internal taxonomy - schema: - type: boolean - deprecated: true - - in: query - name: related-ids - description: OR-restrict to these relation IDs (white space separated list). If specified, relation is required - schema: - type: string - - in: query - name: include-deprecated - description: Include deprecated values - schema: - type: boolean - - in: query - name: deprecated - description: Restrict to deprecation state - schema: - type: boolean - deprecated: true - - in: query - name: type - description: Restrict to concept type - schema: - type: string - - in: query - name: version - description: Taxonomy version, either number that indicates the version, "latest" for latest release, or "next" for unpublished changes (requires admin rights) - schema: - anyOf: - - type: integer - format: int64 - - type: string - enum: - - latest - - next - - in: query - name: relation - description: Relation type. If specified, related-ids is required. "substitutability-to" and "substitutability-from" are deprecated, please use "substitutability" and "substituted-by" respectively - schema: - type: string - enum: - - close-match - - substitutability-from - - exact-match - - narrower - - broad-match - - related - - possible-combination - - narrow-match - - substitutability-to - - substitutability - - broader - - unlikely-combination - - substituted-by - responses: - '200': - description: OK - content: - application/json: - schema: - $ref: '#/components/schemas/concepts' - '400': - $ref: '#/components/responses/BadRequest' - '401': - $ref: '#/components/responses/Unauthorized' - '500': - $ref: '#/components/responses/InternalServerError' - -components: - responses: - Unauthorized: - description: Unauthorized - API key is missing or invalid - content: - application/json: - schema: - type: object - properties: - taxonomy/error: - type: string - required: - - taxonomy/error - title: taxonomy/unauthorized - application/transit+msgpack: - schema: - type: object - properties: - taxonomy/error: - type: string - required: - - taxonomy/error - title: taxonomy/unauthorized - application/transit+json: - schema: - type: object - properties: - taxonomy/error: - type: string - required: - - taxonomy/error - title: taxonomy/unauthorized - application/edn: - schema: - type: object - properties: - taxonomy/error: - type: string - required: - - taxonomy/error - title: taxonomy/unauthorized - BadRequest: - description: Bad request - content: - application/json: - schema: - $ref: '#/components/schemas/Error' - application/transit+msgpack: - schema: - $ref: '#/components/schemas/Error' - application/transit+json: - schema: - $ref: '#/components/schemas/Error' - application/edn: - schema: - $ref: '#/components/schemas/Error' - InternalServerError: - description: Internal Server Error - content: - application/json: - schema: - $ref: '#/components/schemas/ErrorWithInfo' - application/transit+msgpack: - schema: - $ref: '#/components/schemas/ErrorWithInfo' - application/transit+json: - schema: - $ref: '#/components/schemas/ErrorWithInfo' - application/edn: - schema: - $ref: '#/components/schemas/ErrorWithInfo' - schemas: - VersionInfo: - type: object - oneOf: - - required: - - taxonomy/version - - required: - - taxonomy/timestamp - properties: - taxonomy/version: - type: integer - format: int64 - taxonomy/timestamp: - type: string - format: date-time - description: ISO 8601 formatted timestamp with timezone (YYYY-MM-DDThh:mm:ss(Z|±hh:mm)) - # pattern: '^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?Z$' - examples: - - "2024-01-17T15:30:00Z" - - "2024-01-17T15:30:00+01:00" - - "2024-01-17T15:30:00-05:00" - externalDocs: - description: "ISO 8601 date validation regex explanation" - url: "https://stackoverflow.com/a/28022901" - title: taxonomy/version-object - - VersionInfo0: - type: object - properties: - taxonomy/version: - type: integer - format: int64 - taxonomy/timestamp: - type: string - format: date-time - required: - - taxonomy/version - - taxonomy/timestamp - title: taxonomy/version-object - - VersionsList: - type: array - items: - $ref: '#/components/schemas/VersionInfo' - title: taxonomy/versions - - Error: - type: object - properties: - taxonomy/error: - type: string - description: Error message - required: - - taxonomy/error - title: taxonomy/err - ErrorWithInfo: - type: object - properties: - taxonomy/error: - type: string - description: Error message describing what went wrong - taxonomy/info: - type: object - description: Additional error context information - required: - - taxonomy/error - title: taxonomy/err - NumbersMap: - type: object - required: - - n1 - - n2 - properties: - n1: - type: integer - description: The first number - n2: - type: integer - description: The second number - concept: - type: object - properties: - taxonomy/id: - type: string - taxonomy/type: - type: string - taxonomy/preferred-label: - type: string - required: - - taxonomy/id - - taxonomy/type - - taxonomy/preferred-label - concepts: - type: array - items: - $ref: '#/components/schemas/concept' - - GraphQLResult: - type: object - properties: - data: - type: object - errors: - type: array - items: - type: object - properties: - message: - type: string - GraphQLInput: - type: object - properties: - query: - type: string - description: query string - variables: - type: string - description: json string with query variables - operationName: - type: string - description: optional query name that is used when there are multiple query definitions in a single query string - required: - - query - \ No newline at end of file From 8225236d319e51e55163295331f469e656f76e7c Mon Sep 17 00:00:00 2001 From: Adam Bergman Date: Fri, 24 Jan 2025 10:40:33 +0100 Subject: [PATCH 7/8] not include my stuff here --- src/navi/core.clj | 44 ++++---------------------------------------- 1 file changed, 4 insertions(+), 40 deletions(-) diff --git a/src/navi/core.clj b/src/navi/core.clj index 2f74d40..1f1402f 100644 --- a/src/navi/core.clj +++ b/src/navi/core.clj @@ -39,43 +39,7 @@ "HealthCheck" (fn [_] {:status 200 :body "Ok"})}) - (def routes (-> "newopenapispec.yaml" - slurp - (routes-from handlers) - ))) - - - -(defn function->symbol [x] - (if (fn? x) - (case x - clojure.core/string? 'string? - clojure.core/int? 'int? - clojure.core/boolean? 'boolean? - clojure.core/inst? 'inst? - (-> x - .getClass - .getName - clojure.lang.Compiler/demunge - symbol)) - x)) - -(defn routes->serializable - "Convert routes data structure to serializable form" - [routes] - (clojure.walk/postwalk function->symbol routes)) - -(defn save-routes! [routes filename] - (spit filename - (with-out-str - (clojure.pprint/pprint - (routes->serializable routes))))) - -;; Usage in REPL: -(save-routes! routes "routes2.edn") - -(defn read-routes [filename] - (clojure.edn/read-string - (slurp filename))) - -(def ole (read-routes "routes.edn")) \ No newline at end of file + (-> "api.yaml" + slurp + (routes-from handlers) + pp/pprint)) From 69ed5bce79373af71d6cecd9e6de28ed26bfffc0 Mon Sep 17 00:00:00 2001 From: Adam Bergman Date: Fri, 24 Jan 2025 11:03:14 +0100 Subject: [PATCH 8/8] add misisng test --- test/navi/transform_test.clj | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/navi/transform_test.clj b/test/navi/transform_test.clj index 7b2edc0..7ab00ec 100644 --- a/test/navi/transform_test.clj +++ b/test/navi/transform_test.clj @@ -109,6 +109,9 @@ .toInstant)))) (testing "java.time.ZonedDateTime converted to Instant" (is (pred (-> (java.time.ZonedDateTime/now) + .toInstant)))) + (testing "java.time.OffsetDateTime converted to Instant" + (is (pred (-> (java.time.OffsetDateTime/now) .toInstant)))))) (testing "inst? rejects invalid inputs"