-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinit.luau
179 lines (169 loc) · 4.98 KB
/
init.luau
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
--!strict
local argparse = require("./submodules/argparse")
local process = require("@lune/process")
local serde = require("@lune/serde")
local fs = require("@lune/fs")
local roblox = require("@lune/roblox")
local TYPED_REACT_PACKAGE = "jiwonz/react-lua-plus"
local TYPED_REACT_VERSION = "0.1.3"
local function stringStarts(str, start)
return string.sub(str, 1, string.len(start)) == start
end
local function toHashTable(array: { any })
local tbl = {}
for _, v in array do
tbl[v] = true
end
return tbl
end
local function generate(args: {
output: string?,
classes: string?
})
local output = args.output or "GeneratedReactTypes"
local db = roblox.getReflectionDatabase()
--local classes = args.classes and args.classes:split(",") or db:GetClassNames()
-- {
-- -- "Frame",
-- -- "TextLabel",
-- -- "TextBox",
-- -- "TextButton",
-- -- "ImageButton",
-- -- "ImageLabel",
-- -- "ViewportFrame",
-- -- "ScrollingFrame",
-- -- "CanvasGroup",
-- -- }
-- local freepassClasses = {}
-- for _, name in db:GetClassNames() do
-- if name:sub(1, 2) == "UI" then
-- freepassClasses[name] = true
-- end
-- end
local allowedSuperClasses = {
BasePart = true,
GuiBase2d = true,
GuiBase3d = true,
GuiObject = true,
}
local base = "local r=require(script.Parent.react);export type e=(<T>((T)->())->((T)->(r.ReactElement<(T)->(),T>)))&%s;return nil"
local elementsType = {}
local datatypeMap = {
String = "string",
Bool = "boolean",
Float32 = "number",
Float64 = "number",
Content = "string",
Int64 = "number",
Int32 = "number",
Int16 = "number",
Ref = "Instance"
}
for _, name in db:GetClassNames() :: { string } do
local function processClass(className, ptbl: {}?): boolean?
local class = db:FindClass(className)
if class and not table.find(class.Tags, "Deprecated") then
if not ptbl then
local allowed = false
do
local currentClass = class.Superclass
while currentClass ~= nil do
if allowedSuperClasses[currentClass] then
allowed = true
break
else
local nex = db:FindClass(currentClass)
if nex then
currentClass = nex.Superclass
end
end
end
end
if not allowed then
return true
end
local tags = toHashTable(class.Tags)
if tags.Deprecated or tags.NotCreatable or tags.NotBrowsable or tags.Settings or tags.UserSettings or tags.Service then
return true
end
end
local props = ptbl or {}
for _, v in class.Properties do
if v.Datatype ~= "RBXScriptSignal" and v.Scriptability ~= "Write" and v.Scriptability ~= "ReadWrite" then
continue
end
local typeName = datatypeMap[v.Datatype] or v.Datatype
table.insert(props, v.Name..":"..typeName.."?,")
end
local superclass = class.Superclass
if superclass then
processClass(superclass, props)
end
if not ptbl then
local propsType = "{"..table.concat(props).."}"
table.insert(elementsType, `(("{className}")->({propsType})->r.ReactElement<"{className}",{propsType}>)`)
end
end
return
end
if processClass(name) then
continue
end
end
fs.writeDir(output)
fs.writeFile(output.."/init.luau", base:format(table.concat(elementsType, "&")))
end
local function applyReactPlus()
if fs.isDir("Packages") then
local indexDir
for _, name in fs.readDir("Packages/_Index") do
local indexName = TYPED_REACT_PACKAGE:gsub("/", "_")
--print(name, indexName)
if stringStarts(name, indexName) then
indexDir = "Packages/_Index/" .. name
end
end
if indexDir and fs.isDir(indexDir) then
generate({
output = indexDir.."/GeneratedReactTypes"
})
else
error(`Package(typed-react) index not found: {indexDir}`)
end
else
error("Failed to find Packages folder")
end
end
-- only supports wally for now.. sorry pesde
local parser = argparse("react-lua-plus")
local setupCommand = parser:command("setup", "Setups react-lua-setup")
setupCommand:action(function(_)
process.spawn("wally", {"init"})
if fs.isFile("wally.toml") then
local wally = serde.decode("toml", fs.readFile("wally.toml"))
local dependencies = wally.dependencies
if not dependencies then
dependencies = {}
wally.dependencies = dependencies
end
dependencies["react"] = TYPED_REACT_PACKAGE.."@"..TYPED_REACT_VERSION
dependencies["react-roblox"] = "jsdotlua/react-roblox@17.1.0"
fs.writeFile("wally.toml", serde.encode("toml", wally))
local result = process.spawn("wally", {"install"})
if result.ok then
applyReactPlus()
else
print(result.stderr)
error("Failed to install packages from wally")
end
else
error("wally.toml not found")
end
end)
local generateCommand = parser:command("generate", "Generate react types")
generateCommand:option("--output", "Generated react types module path")
generateCommand:option("--classes", "CSV list of roblox class names to generate")
generateCommand:action(generate)
local applyCommand = parser:command("apply", "Applies react-lua-plus features")
applyCommand:action(applyReactPlus)
parser:parse()