diff --git a/cli.odin b/cli.odin index 39f18ca..ae98dea 100644 --- a/cli.odin +++ b/cli.odin @@ -6,7 +6,7 @@ import "core:mem" import "core:strings" import gql "./graphql_parser" -write_string :: strings.write_string +write :: strings.write_string when ODIN_OS == .Windows { is_terminal :: proc(fd: os.Handle) -> bool { @@ -61,6 +61,8 @@ main :: proc() { fmt.panicf("Error parsing schema: %v", schema_err) } + // gql.schema_topological_sort(&schema) + os.write(os.stdout, runtime) b := strings.builder_make_len_cap(0, 2048) @@ -68,58 +70,36 @@ main :: proc() { /* Types typedef jsdoc */ - for type, _i in schema.types[gql.USER_TYPES_START:] { - i := _i + gql.USER_TYPES_START + write(&b, "\n/*\n\n") + write(&b, "TYPES:\n\n") + write(&b, "*/\n") + + types_done := make([]bool, len(schema.types), context.temp_allocator) + #unroll for i in 0.. 0 { - write_string(b, "(") + write(b, "(") for arg, i in field.args { - write_string(b, arg.name) - write_string(b, ":'+JSON.stringify(vars.") - write_string(b, arg.name) - write_string(b, ")+'") + write(b, arg.name) + write(b, ":'+JSON.stringify(vars.") + write(b, arg.name) + write(b, ")+'") if i < len(field.args)-1 { - write_string(b, " ") + write(b, " ") } } - write_string(b, ")") + write(b, ")") } write_type_fields(b, schema, field.value) - write_string(b, "}'\n}\n\n") + write(b, "}'\n}\n\n") } { // query_data - write_string(b, "/**\n * ") - write_string(b, operation_type) - write_string(b, ": `") - write_string(b, field.name) - write_string(b, "`\\\n * vars : {@link Vars_") - write_string(b, field.name) - write_string(b, " }\\\n * value: {@link Value_") - write_string(b, field.name) - write_string(b, "}\n * @type {Query_Data}\n */\nexport const ") - write_string(b, operation_type) - write_string(b, "_") - write_string(b, field.name) - write_string(b, " = /** @type {*} */({\n") - write_string(b, "\tname : \"") - write_string(b, field.name) - write_string(b, "\",\n") - write_string(b, "\tget_body : query_get_body_") - write_string(b, field.name) - write_string(b, ",\n") - write_string(b, "\tinitial_value: ") - if field.value.lists > 0 { - write_string(b, "[]") - } else { - write_string(b, "undefined") - } - write_string(b, ",\n})\n") + write(b, "/**\n * ") + write(b, operation_type) + write(b, ": `") + write(b, field.name) + write(b, "`\\\n * vars : {@link Vars_") + write(b, field.name) + write(b, " }\\\n * value: {@link Value_") + write(b, field.name) + write(b, "}\n * @type {Query_Data}\n */\nexport const ") + write(b, operation_type) + write(b, "_") + write(b, field.name) + write(b, " = /** @type {*} */({\n") + write(b, "\tname : \"") + write(b, field.name) + write(b, "\",\n") + write(b, "\tget_body : query_get_body_") + write(b, field.name) + write(b, ",\n") + write(b, "\tinitial_value: ") + write_initial_value(b, schema, field.value) + write(b, ",\n})\n") } } @@ -245,18 +309,56 @@ write_type_fields :: proc(b: ^strings.Builder, schema: gql.Schema, value: gql.Ty type := schema.types[value.index] if (type.kind != .Object) do return false - write_string(b, "{") + write(b, "{") for field, i in type.fields { - write_string(b, field.name) + write(b, field.name) if !write_type_fields(b, schema, field.value) && i < len(type.fields)-1 { - write_string(b, " ") + write(b, " ") } } - write_string(b, "}") + write(b, "}") return true } +write_initial_value :: proc(b: ^strings.Builder, schema: gql.Schema, value: gql.Type_Value) { + if gql.type_value_is_non_null(value) { + if value.lists > 0 { + write(b, "[]") + } else { + type := schema.types[value.index] + write_initial_type(b, schema, type) + } + } else { + write(b, "null") + } +} + +write_initial_type :: proc(b: ^strings.Builder, schema: gql.Schema, type: gql.Type) { + switch type.kind { + case .Enum: + write(b, type.name) + write(b, ".") + write(b, type.enum_values[0]) + case .Union: + write_initial_type(b, schema, schema.types[type.members[0]]) + case .Object, .Input_Object, .Interface: + write(b, "initial_") + write(b, type.name) + case .Scalar, .Unknown: + switch type.name { + case "String": + write(b, "\"\"") + case "Int", "Float": + write(b, "0") + case "Boolean": + write(b, "false") + case: + write(b, "null") + } + } +} + /* String -> Maybe String! -> String @@ -272,23 +374,24 @@ write_type_value :: proc(b: ^strings.Builder, schema: gql.Schema, value: gql.Typ to_close := 0 for i in 0..") + write(b, "Maybe<") + write(b, type.name) + write(b, ">") } for _ in 0..") + write(b, ">") } } + diff --git a/readme.md b/readme.md index e543622..4eb33b3 100644 --- a/readme.md +++ b/readme.md @@ -1 +1,35 @@ # graphstate + +A reactive GraphQL client generator. + +Work in progress. + +Initial values for types: + +```gql +# Type | Initial value +String # null +String! # "" +Int! # 0 +Float! # 0 +Boolean! # false +ID! # "" ????? +[String!]! # [] + +type Link { # { + title: String! # title: "", + url: String! # url: "", +} # } + +enum LinkState { # "None" (always the first member) + None + Bookmark + InProgress + Completed +} + +union LinkUnion = LinkState | Link + +LinkUnion # null +LinkUnion! # "None" (LinkState is the first member of the union) +``` \ No newline at end of file diff --git a/runtime.js b/runtime.js index 285213a..e1e1296 100644 --- a/runtime.js +++ b/runtime.js @@ -22,7 +22,7 @@ * @typedef {object } Query_Data * @property {string } name * @property {Query_Get_Body} get_body - * @property {TValue | undefined } initial_value + * @property {TValue } initial_value * @property {TVars } _type_vars * @property {TValue } _type_value */