diff --git a/__tests__/Rest_openapi_test.res b/__tests__/Rest_openapi_test.res deleted file mode 100644 index 53d02d0..0000000 --- a/__tests__/Rest_openapi_test.res +++ /dev/null @@ -1,142 +0,0 @@ -open Ava -open RescriptSchema - -let postSchema = S.object(s => - { - "title": s.field("title", S.string), - "published": s.field("published", S.bool), - } -) - -test("findPosts route to OpenAPI", t => { - let findPosts = Rest.route(() => { - path: "/posts", - method: "GET", - variables: s => - { - "search": s.query("search", S.option(S.string)), - "sortBy": s.query( - "sortBy", - S.option(S.union([S.literal(#title), S.literal(#date)]))->S.Option.getOr(#date), - ), - "sort": s.query( - "sort", - S.option(S.union([S.literal(#asc), S.literal(#desc)]))->S.Option.getOr(#desc), - ), - "obj": s.query("obj", S.object(s => s.field("a", S.string))), - }, - responses: [ - s => { - s.status(#200) - s.data(S.array(postSchema)) - }, - ], - }) - - t->Assert.deepEqual( - Rest.routeToOpenAPI(findPosts), - %raw(`{ - operationId: 'findPosts', - parameters: [ - { - schema: { - type: 'string', - '$schema': 'http://json-schema.org/draft-07/schema#' - }, - name: 'search', - in: 'query' - }, - { - schema: { - anyOf: [ - { type: 'string', const: 'title' }, - { type: 'string', const: 'date' } - ], - '$schema': 'http://json-schema.org/draft-07/schema#' - }, - name: 'sortBy', - in: 'query' - }, - { - schema: { - anyOf: [ - { type: 'string', const: 'asc' }, - { type: 'string', const: 'desc' } - ], - '$schema': 'http://json-schema.org/draft-07/schema#' - }, - name: 'sort', - in: 'query' - }, - { - required: true, - style: 'deepObject', - schema: { - type: 'object', - properties: { a: { type: 'string' } }, - additionalProperties: true, - required: [ 'a' ], - '$schema': 'http://json-schema.org/draft-07/schema#' - }, - name: 'obj', - in: 'query' - } - ], - }`), - ) -}) - -test("createPost route to OpenAPI", t => { - let createPost = Rest.route(() => { - path: "/posts", - method: "POST", - deprecated: true, - variables: s => - { - "title": s.field("title", S.string), - "published": s.field("published", S.option(S.bool)), - }, - responses: [ - s => { - s.status(#200) - s.data(postSchema) - }, - ], - }) - - t->Assert.deepEqual( - Rest.routeToOpenAPI(createPost), - %raw(`{ - operationId: "createPost", - deprecated: true, - parameters: [], - }`), - ) -}) - -test("auth route to OpenAPI", t => { - let auth = Rest.route(() => { - path: "/auth", - method: "POST", - variables: s => - { - "clientId": s.header("x-client-id", S.string), - "apiKey": s.header("x-api-key", S.string), - "tenantId": s.header("x-tenant-id", S.option(S.string)), - }, - responses: [ - s => { - s.status(#200) - s.data(S.string) - }, - ], - }) - - t->Assert.deepEqual( - Rest.routeToOpenAPI(auth), - %raw(`{ - operationId: "auth", - parameters: [], - }`), - ) -}) diff --git a/package-lock.json b/package-lock.json index 45bec66..70139f4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,10 +8,6 @@ "name": "rescript-rest", "version": "0.4.2", "license": "MIT", - "dependencies": { - "rescript-json-schema": "6.x", - "rescript-openapi": "0.3.x" - }, "devDependencies": { "@dzakh/rescript-ava": "3.0.0", "ava": "5.2.x", @@ -1487,6 +1483,7 @@ "version": "11.1.2", "resolved": "https://registry.npmjs.org/rescript/-/rescript-11.1.2.tgz", "integrity": "sha512-sA4EgPoPbwGM/+R8xkZJzgr1gvnA1E/Gxjg6DXSG8csl8ttrSBMwHYK4FtGF0K9Ej5NRgsvIi7p/v/dtLB/cjg==", + "dev": true, "hasInstallScript": true, "bin": { "bsc": "bsc", @@ -1497,30 +1494,11 @@ "node": ">=10" } }, - "node_modules/rescript-json-schema": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/rescript-json-schema/-/rescript-json-schema-6.1.0.tgz", - "integrity": "sha512-rDddZI/t4Zax5GMuuS2tIy6JP/Zjw1Mxh1INwg44+j02pIxxg5paoP686z9pZ3tVM5YxGKrYchqNL9n5Z2DRzg==", - "peerDependencies": { - "rescript": "11.x", - "rescript-schema": "7.x || 8.x" - } - }, - "node_modules/rescript-openapi": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/rescript-openapi/-/rescript-openapi-0.3.0.tgz", - "integrity": "sha512-3FJUl2TXf4EEWw2gHV9SMAGvYxo9BhIpt3K1+Xv/2skfkgQFntk04bhUl6qiwUiUAeJdWeK/f8HBy/SiJBcS4A==", - "dependencies": { - "rescript-json-schema": "6.x" - }, - "peerDependencies": { - "rescript": "11.x" - } - }, "node_modules/rescript-schema": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/rescript-schema/-/rescript-schema-8.0.1.tgz", "integrity": "sha512-8mtoHl7pKE4wezI3FbEgCb4bZ2toKHY8hi7ZJ/WnfaBWr8Up5v1i6G20mSk5vfhJWV5mvEUzuSgADnmgeQKoqw==", + "dev": true, "peerDependencies": { "rescript": "11.x" } @@ -3001,26 +2979,14 @@ "rescript": { "version": "11.1.2", "resolved": "https://registry.npmjs.org/rescript/-/rescript-11.1.2.tgz", - "integrity": "sha512-sA4EgPoPbwGM/+R8xkZJzgr1gvnA1E/Gxjg6DXSG8csl8ttrSBMwHYK4FtGF0K9Ej5NRgsvIi7p/v/dtLB/cjg==" - }, - "rescript-json-schema": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/rescript-json-schema/-/rescript-json-schema-6.1.0.tgz", - "integrity": "sha512-rDddZI/t4Zax5GMuuS2tIy6JP/Zjw1Mxh1INwg44+j02pIxxg5paoP686z9pZ3tVM5YxGKrYchqNL9n5Z2DRzg==", - "requires": {} - }, - "rescript-openapi": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/rescript-openapi/-/rescript-openapi-0.3.0.tgz", - "integrity": "sha512-3FJUl2TXf4EEWw2gHV9SMAGvYxo9BhIpt3K1+Xv/2skfkgQFntk04bhUl6qiwUiUAeJdWeK/f8HBy/SiJBcS4A==", - "requires": { - "rescript-json-schema": "6.x" - } + "integrity": "sha512-sA4EgPoPbwGM/+R8xkZJzgr1gvnA1E/Gxjg6DXSG8csl8ttrSBMwHYK4FtGF0K9Ej5NRgsvIi7p/v/dtLB/cjg==", + "dev": true }, "rescript-schema": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/rescript-schema/-/rescript-schema-8.0.1.tgz", "integrity": "sha512-8mtoHl7pKE4wezI3FbEgCb4bZ2toKHY8hi7ZJ/WnfaBWr8Up5v1i6G20mSk5vfhJWV5mvEUzuSgADnmgeQKoqw==", + "dev": true, "requires": {} }, "resolve-cwd": { diff --git a/package.json b/package.json index 2213090..4a5fc70 100644 --- a/package.json +++ b/package.json @@ -27,10 +27,6 @@ "res:clean": "rescript clean", "test": "ava" }, - "dependencies": { - "rescript-openapi": "0.3.x", - "rescript-json-schema": "6.x" - }, "devDependencies": { "@dzakh/rescript-ava": "3.0.0", "ava": "5.2.x", diff --git a/rescript.json b/rescript.json index f8041b4..1d25872 100644 --- a/rescript.json +++ b/rescript.json @@ -17,9 +17,7 @@ }, "suffix": ".res.js", "bs-dependencies": [ - "rescript-schema", - "rescript-openapi", - "rescript-json-schema" + "rescript-schema" ], "bs-dev-dependencies": ["@dzakh/rescript-ava"] } diff --git a/src/Rest.res b/src/Rest.res index f03a097..27575e2 100644 --- a/src/Rest.res +++ b/src/Rest.res @@ -525,116 +525,3 @@ let client = (~baseUrl, ~fetcher=ApiFetcher.default, ~jsonQuery=false) => { jsonQuery, } } - -let routeToOpenAPI = (route: route<'variables, 'response>, ~jsonQuery=false): OpenAPI.operation => { - let params = route->params - let schemas = (params.variablesSchema->S.classify->Obj.magic)["fields"] - - let parameters = [] - - let paramsSchemaItems: dict = switch (schemas["params"]: option) { - | None => Js.Dict.empty() - | Some(paramsItem) => (paramsItem.schema->S.classify->Obj.magic)["fields"] - } - params.pathItems->Js.Array2.forEach(pathItem => { - switch pathItem { - | Static(_) => () - | Param({name}) => - switch paramsSchemaItems - ->Js.Dict.unsafeGet(name) - ->Option.unsafeSome { - | None => panic(`Path parameter "${name}" is not defined in variables`) - | Some(fieldItem) => - parameters - ->Js.Array2.push( - OpenAPI.Mutable.WithReference.object( - ( - { - name, - in_: Path, - required: true, - schema: switch JSONSchema.make(fieldItem.schema) { - | Ok(schema) => schema - | Error(message) => panic(message) - }, - }: OpenAPI.Mutable.parameter - ), - ), - ) - ->ignore - } - } - }) - - let querySchemaItems: array = switch (schemas["query"]: option) { - | None => [] - | Some(queryItem) => (queryItem.schema->S.classify->Obj.magic)["items"] - } - querySchemaItems->Js.Array2.forEach(item => { - let required = ref(Some(true)) - let schema = switch item.schema->S.classify { - | Option(s) => { - required := None - s - } - | _ => item.schema - } - - let jsonSchema = switch JSONSchema.make(schema) { - | Ok(schema) => schema - | Error(message) => panic(message) - } - - let parameter: OpenAPI.Mutable.parameter = { - name: item.location, - in_: Query, - } - switch required.contents { - | Some(required) => parameter.required = Some(required) - | None => () - } - switch item.schema->S.description { - | Some(description) => parameter.description = Some(description) - | None => () - } - switch jsonQuery { - | true => - parameter.content = Some( - Js.Dict.fromArray([ - ( - "application/json", - OpenAPI.Mutable.WithReference.object(({schema: jsonSchema}: OpenAPI.Mutable.mediaType)), - ), - ]), - ) - | false => - parameter.schema = Some(jsonSchema) - switch schema->S.classify { - | Object(_) => parameter.style = Some(#deepObject) - | _ => () - } - } - - parameters - ->Js.Array2.push(OpenAPI.Mutable.WithReference.object(parameter)) - ->ignore - }) - - let operation: OpenAPI.Mutable.operation = { - operationId: %raw(`route.name`), - parameters, - } - switch params.definition.summary { - | Some(summary) => operation.summary = Some(summary) - | None => () - } - switch params.definition.description { - | Some(description) => operation.description = Some(description) - | None => () - } - switch params.definition.deprecated { - | Some(deprecated) => operation.deprecated = Some(deprecated) - | None => () - } - operation->(Obj.magic: OpenAPI.Mutable.operation => OpenAPI.operation) -} diff --git a/src/Rest.res.js b/src/Rest.res.js index da9041c..390addb 100644 --- a/src/Rest.res.js +++ b/src/Rest.res.js @@ -1,8 +1,6 @@ // Generated by ReScript, PLEASE EDIT WITH CARE 'use strict'; -var Js_dict = require("rescript/lib/js/js_dict.js"); -var JSONSchema = require("rescript-json-schema/src/JSONSchema.res.js"); var S$RescriptSchema = require("rescript-schema/src/S.res.js"); async function $$default(args) { @@ -253,108 +251,9 @@ function client(baseUrl, fetcherOpt, jsonQueryOpt) { }; } -function routeToOpenAPI(route, jsonQueryOpt) { - var jsonQuery = jsonQueryOpt !== undefined ? jsonQueryOpt : false; - var params$1 = params(route); - var schemas = S$RescriptSchema.classify(params$1.variablesSchema).fields; - var parameters = []; - var paramsItem = schemas.params; - var paramsSchemaItems = paramsItem !== undefined ? S$RescriptSchema.classify(paramsItem.t).fields : ({}); - params$1.pathItems.forEach(function (pathItem) { - if (typeof pathItem === "string") { - return ; - } - var name = pathItem.name; - var fieldItem = paramsSchemaItems[name]; - if (fieldItem !== undefined) { - var schema = JSONSchema.make(fieldItem.t); - var tmp; - if (schema.TAG === "Ok") { - tmp = schema._0; - } else { - throw new Error("[rescript-rest] " + schema._0); - } - parameters.push({ - name: name, - in: "path", - required: true, - schema: tmp - }); - return ; - } - throw new Error("[rescript-rest] " + ("Path parameter \"" + name + "\" is not defined in variables")); - }); - var queryItem = schemas.query; - var querySchemaItems = queryItem !== undefined ? S$RescriptSchema.classify(queryItem.t).items : []; - querySchemaItems.forEach(function (item) { - var required = true; - var s = S$RescriptSchema.classify(item.t); - var schema; - if (typeof s !== "object" || s.TAG !== "Option") { - schema = item.t; - } else { - required = undefined; - schema = s._0; - } - var schema$1 = JSONSchema.make(schema); - var jsonSchema; - if (schema$1.TAG === "Ok") { - jsonSchema = schema$1._0; - } else { - throw new Error("[rescript-rest] " + schema$1._0); - } - var parameter = { - name: item.l, - in: "query" - }; - var required$1 = required; - if (required$1 !== undefined) { - parameter.required = required$1; - } - var description = S$RescriptSchema.description(item.t); - if (description !== undefined) { - parameter.description = description; - } - if (jsonQuery) { - parameter.content = Js_dict.fromArray([[ - "application/json", - { - schema: jsonSchema - } - ]]); - } else { - parameter.schema = jsonSchema; - var match = S$RescriptSchema.classify(schema); - if (typeof match === "object" && match.TAG === "Object") { - parameter.style = "deepObject"; - } - - } - parameters.push(parameter); - }); - var operation = { - operationId: route.name, - parameters: parameters - }; - var summary = params$1.definition.summary; - if (summary !== undefined) { - operation.summary = summary; - } - var description = params$1.definition.description; - if (description !== undefined) { - operation.description = description; - } - var deprecated = params$1.definition.deprecated; - if (deprecated !== undefined) { - operation.deprecated = deprecated; - } - return operation; -} - var $$Response = {}; exports.ApiFetcher = ApiFetcher; exports.$$Response = $$Response; exports.client = client; -exports.routeToOpenAPI = routeToOpenAPI; -/* JSONSchema Not a pure module */ +/* S-RescriptSchema Not a pure module */ diff --git a/src/Rest.resi b/src/Rest.resi index ae19d1f..011e1a8 100644 --- a/src/Rest.resi +++ b/src/Rest.resi @@ -123,5 +123,3 @@ type client = { } let client: (~baseUrl: string, ~fetcher: ApiFetcher.t=?, ~jsonQuery: bool=?) => client - -let routeToOpenAPI: (route<'variables, 'response>, ~jsonQuery: bool=?) => OpenAPI.operation