Skip to content

Commit

Permalink
Create file + tests for parsing the type body
Browse files Browse the repository at this point in the history
  • Loading branch information
vocksel committed Feb 4, 2024
1 parent 7a66544 commit 2c5e769
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 69 deletions.
65 changes: 8 additions & 57 deletions server/src/openapi/createLuauTypeFromOpenAPIObject.luau
Original file line number Diff line number Diff line change
@@ -1,76 +1,27 @@
local types = require("@server/openapi/types")
local parseTypeBody = require("@server/openapi/parseTypeBody")
local createLuauComment = require("@server/openapi/createLuauComment")

type Object<T> = types.Object<T>

local function createTypePropertiesFromObject(object: Object<any>): Object<string | Object<any>>
local inner = {}

if object.type and object.type == "object" and object.properties then
for key, value in object.properties do
local valueType = typeof(value)

if valueType == "table" then
value = createTypePropertiesFromObject(value)
end

if object.required then
local isRequired = table.find(object.required, key)
-- TODO: Determine if properties in OpenAPI objects are required
-- by default
if isRequired == false then
valueType ..= "?"
end
end

inner[key] = valueType
end
end

return inner
end

local function createLuauTypeFromOpenAPIObject(object: Object<any>): types.LuauType
local comment = createLuauComment(object)

print(object)
local function createLuauTypeFromOpenAPIObject(name: string, object: Object<any>): types.LuauType
local body
if object.type == "object" then
local properties = {}
body = {}

if object.properties then
for key, value in object.properties do
print(key, value)
if typeof(value) == "table" then
value = createTypePropertiesFromObject(value)
else
value = typeof(value)
end
properties[key] = value
body[key] = parseTypeBody(value)
end
end
local inner = table.concat(properties, "\n")

print("properties", properties)

return properties

-- local typeString = `export type {name} = \{{inner}\}`
-- if comment then
-- return `{comment}\n{typeString}`
-- else
-- return typeString
-- end
elseif object.type == "integer" then
return "number"
body = "number"
else
return {
comment = comment,
source = typeof(object),
}
body = object.type
end

return {
name = name,
body = body,
comment = createLuauComment(object),
}
end
Expand Down
19 changes: 7 additions & 12 deletions server/src/openapi/createLuauTypeFromOpenAPIObject.spec.luau
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,21 @@ assert(petstore.components.schemas, "no schemas found in mock API")

-- print("schemas", petstore.components.schemas)

local Pet = createLuauTypeFromOpenAPIObject(petstore.components.schemas.Pet)
local Pet = createLuauTypeFromOpenAPIObject("Pet", petstore.components.schemas.Pet)
assert(Pet ~= nil, `missing "Pet" schema`)
assert(Pet.id == "number", `bad Pet.id (expected number, got {Pet.id})`)
assert(Pet.name == "string", `bad Pet.name (expected string, got {Pet.name})`)
assert(Pet.tag == "string?", `bad Pet.tag (expected string?, got {Pet.tag})`)
assert(Pet.body ~= nil, `bad Pet.body (expected table, got {Pet.body})`)
assert(Pet.body.id == "number", `bad Pet.body.id (expected number, got {Pet.body.id})`)
assert(Pet.body.name == "string", `bad Pet.body.name (expected string, got {Pet.body.name})`)
assert(Pet.body.tag == "string?", `bad Pet.body.tag (expected string?, got {Pet.body.tag})`)

local Pets = createLuauTypeFromOpenAPIObject(petstore.components.schemas.Pets)
local Pets = createLuauTypeFromOpenAPIObject("Pets", petstore.components.schemas.Pets)
assert(Pets ~= nil, `missing "Pets" schema`)
assert(Pets.id == "number", `bad Pets.id (expected number, got {Pets.id})`)
assert(Pets.name == "string", `bad Pets.name (expected string, got {Pets.name})`)
assert(Pets.tag == "string?", `bad Pets.tag (expected string?, got {Pets.tag})`)

local Error = createLuauTypeFromOpenAPIObject(petstore.components.schemas.Error)
local Error = createLuauTypeFromOpenAPIObject("Error", petstore.components.schemas.Error)
assert(Error, `missing "Error" schema`)

-- assert(nil, "summary is not included in type comment")
-- assert(nil, "description is not included in type comment")

assert(petstore.components.responses, "no responses found in mock API")

local responses = createLuauTypeFromOpenAPIObject(petstore.components.responses)

print(responses)
46 changes: 46 additions & 0 deletions server/src/openapi/parseTypeBody.luau
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
local types = require("@server/openapi/types")

type Object<T> = types.Object<T>

local function parseTypeBody(object: Object<any>): Object<string | Object<any>>
local body = {}

if object.type then
if object.type == "object" then
if object.properties then
for key, value in object.properties do
local valueType = typeof(value)

if valueType == "table" then
valueType = parseTypeBody(value)
end

-- TODO: Handle refs

if object.required then
local isRequired = table.find(object.required, key)
-- TODO: Check if properties in OpenAPI objects are required by
-- default. Right now the assumption is that they are
if not isRequired then
valueType ..= "?"
end
end

body[key] = valueType
end
else
body = "{ [string]: any }"
end
else
if object.type == "integer" then
body = "number"
else
body = object.type
end
end
end

return body
end

return parseTypeBody
17 changes: 17 additions & 0 deletions server/src/openapi/parseTypeBody.spec.luau
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
local fs = require("@lune/fs")
local serde = require("@lune/serde")
local openapiTypes = require("@server/openapi/openapi31")
local parseTypeBody = require("./parseTypeBody")

type OpenAPIObject = openapiTypes.OpenAPIObject

local petstore: OpenAPIObject = serde.decode("yaml", fs.readFile("server/src/openapi/mocks/petstore.yml"))

local body = parseTypeBody(petstore.components.schemas.Pet)
assert(body ~= nil, `bad body (expected table, got {body})`)
assert(body.id == "number", `bad body.id (expected number, got {body.id})`)
assert(body.name == "string", `bad body.name (expected string, got {body.name})`)
assert(body.tag == "string?", `bad body.tag (expected string?, got {body.tag})`)

body = parseTypeBody(petstore.components.schemas.Pets)
assert(body ~= nil, `bad body (expected table, got {body})`)
2 changes: 2 additions & 0 deletions server/src/openapi/types.luau
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
export type Object<T> = { [string]: T }

type Primitive = string | number | boolean

export type LuauType = {
name: string,
body: Primitive | { [string]: Primitive },
Expand Down

0 comments on commit 2c5e769

Please sign in to comment.