1+ using JSON3
2+ function process_components_meta (metafile)
3+ metadata = JSON3. read (
4+ read (metafile, String)
5+ )
6+ result = []
7+ for (file, props) in metadata
8+ name = split (split (string (file), " /" )[end ], " ." )[1 ]
9+ push! (result, make_component_meta (name, props))
10+ end
11+ return result
12+ end
13+
14+ function make_component_meta (name, props)
15+ args = filter (filter_arg, props[" props" ])
16+ regular_args = filter (collect (keys (args))) do name
17+ ! endswith (string (name), " -*" )
18+ end
19+ wild_args =
20+ filter (collect (keys (args))) do name
21+ endswith (string (name), " -*" )
22+ end
23+ return OrderedDict (
24+ :name => Symbol (name),
25+ :args => regular_args,
26+ :wild_args => [Symbol (replace (string (a), " -*" => " " )) for a in wild_args],
27+ :docstr => docstring (name, args, props[" description" ]),
28+ )
29+ end
30+
31+
32+ const _reserved_words = Set (
33+ [" baremodule" ,
34+ " begin" ,
35+ " break" ,
36+ " catch" ,
37+ " const" ,
38+ " continue" ,
39+ " do" ,
40+ " else" ,
41+ " elseif" ,
42+ " end" ,
43+ " export" ,
44+ " false" ,
45+ " finally" ,
46+ " for" ,
47+ " function" ,
48+ " global" ,
49+ " if" ,
50+ " import" ,
51+ " let" ,
52+ " local" ,
53+ " macro" ,
54+ " module" ,
55+ " quote" ,
56+ " return" ,
57+ " struct" ,
58+ " true" ,
59+ " try" ,
60+ " using" ,
61+ " while" ]
62+ )
63+ function is_reserved_world (w)
64+ return w in _reserved_words
65+ end
66+
67+ function filter_arg (argpair)
68+ name, props = argpair
69+ is_reserved_world (name) && return false
70+ if haskey (props, " type" )
71+ arg_type = props[" type" ][" name" ]
72+ return ! in (arg_type, [" func" , " symbol" , " instanceOf" ])
73+ end
74+ if " flowType" in props
75+ arg_type_name = props[" flowType" ][" name" ]
76+ if arg_type_name == " signature"
77+ # This does the same as the PropTypes filter above, but "func"
78+ # is under "type" if "name" is "signature" vs just in "name"
79+ if ! in (" type" , props[" FlowType" ]) || props[" FlowType" ][" type" ] != " object"
80+ return false
81+ end
82+ end
83+ return true
84+ end
85+ return false
86+ end
87+
88+ function docstring (name, props, description)
89+ article = lowercase (first (name)) in [' a' , ' e' , ' i' , ' o' , ' u' ] ? " An " : " A "
90+ result = string (
91+ article, name, " component" , " \n " ,
92+ description, " \n\n "
93+ )
94+ if haskey (props, :children )
95+ result *= arg_docstring (" children" , props[:children ]) * " \n "
96+ end
97+ if haskey (props, :id )
98+ result *= arg_docstring (" id" , props[:id ]) * " \n "
99+ end
100+ other_props = sort (
101+ collect (filter (v-> ! in (v. first, [:children , :id ]), props)),
102+ lt = (a, b) -> a[1 ] < b[1 ]
103+ )
104+ result *= join (arg_docstring .(other_props), " \n " )
105+ return result
106+
107+ end
108+
109+ _jl_type (:: Val{:array} , type_object) = " Array"
110+ _jl_type (:: Val{:bool} , type_object) = " Bool"
111+ _jl_type (:: Val{:string} , type_object) = " String"
112+ _jl_type (:: Val{:object} , type_object) = " Dict"
113+ _jl_type (:: Val{:any} , type_object) = " Bool | Real | String | Dict | Array"
114+ _jl_type (:: Val{:element} , type_object) = " dash component"
115+ _jl_type (:: Val{:node} , type_object) = " a list of or a singular dash component, string or number"
116+
117+ _jl_type (:: Val{:enum} , type_object) = join (
118+ string .(
119+ getindex .(type_object[" value" ], :value )
120+ ), " , "
121+ )
122+
123+ function _jl_type (:: Val{:union} , type_object)
124+ join (
125+ filter (a-> ! isempty (a), jl_type .(type_object[" value" ])),
126+ " | "
127+ )
128+ end
129+
130+ function _jl_type (:: Val{:arrayOf} , type_object)
131+ result = " Array"
132+ if type_object[" value" ] != " "
133+ result *= string (" of " , jl_type (type_object[" value" ]), " s" )
134+ end
135+ return result
136+ end
137+
138+ _jl_type (:: Val{:objectOf} , type_object) =
139+ string (" Dict with Strings as keys and values of type " , jl_type (type_object[" value" ]))
140+
141+ function _jl_type (:: Val{:shape} , type_object)
142+ child_names = join (string .(keys (type_object[" value" ])), " , " )
143+ result = " lists containing elements $(child_names) "
144+ result *= join (
145+ [
146+ arg_docstring (name, prop, prop[" required" ], get (prop, " description" , " " ), 1 )
147+ for (name, prop) in type_object[" value" ]
148+ ]
149+ )
150+ return result
151+ end
152+ _jl_type (:: Val{:exact} , type_object) = _jl_type (Val (:shape ), type_object)
153+ _jl_type (val, type_object) = " "
154+
155+
156+ jl_type (type_object) = _jl_type (Val (Symbol (type_object[" name" ])), type_object)
157+
158+ arg_docstring (name_prop:: Pair , indent_num = 0 ) = arg_docstring (name_prop[1 ], name_prop[2 ], indent_num)
159+ arg_docstring (name, prop, indent_num = 0 ) =
160+ arg_docstring (
161+ string (name),
162+ haskey (prop, " type" ) ? prop[" type" ] : prop[" flowType" ],
163+ prop[" required" ],
164+ prop[" description" ],
165+ indent_num
166+ )
167+
168+ function arg_docstring (prop_name, type_object, required, description, indent_num)
169+ typename = jl_type (type_object)
170+ indent_spacing = repeat (" " , indent_num)
171+ if occursin (" \n " , typename)
172+ return string (
173+ indent_spacing, " - `" , prop_name, " ` " ,
174+ " (" , required ? " required" : " optional" , " ):" ,
175+ description, " . " ,
176+ prop_name, " has the following type: " , typename
177+ )
178+ end
179+
180+ return string (
181+ indent_spacing, " - `" , prop_name, " ` " ,
182+ " (" ,
183+ isempty (typename) ? " " : string (typename, " ; " ),
184+ required ? " required" : " optional" ,
185+ " )" ,
186+ isempty (description) ? " " : string (" : " , description)
187+ )
188+ end
0 commit comments