147 lines
3.8 KiB
Ruby
Executable file
147 lines
3.8 KiB
Ruby
Executable file
WARNING_HEADER =
|
|
"" "
|
|
// THIS INTERFACE WAS AUTO GENERATED ON #{Date.today}
|
|
// DO NOT EDIT THIS FILE.
|
|
// IT WILL BE OVERWRITTEN ON EVERY CELERYSCRIPT UPGRADE.
|
|
|
|
" ""
|
|
HASH = Sequence::Corpus.as_json({})
|
|
OUTPUT = [WARNING_HEADER]
|
|
FILE_PATH = "latest_corpus.ts"
|
|
VALUES = HASH.fetch(:values)
|
|
VALUE_PREFIX = "CS"
|
|
VALUES_TPL = "export type %{name} = %{type};\n"
|
|
VALUES_OVERRIDE = HashWithIndifferentAccess.new(float: "number", integer: "number")
|
|
# There are some rule exceptions when generating the Typescript corpus.
|
|
FUNNY_NAMES = { "Example" => "CSExample" }
|
|
ENUMS = HASH.fetch(:enums)
|
|
ENUM_TPL = "export type %{name} = %{type};\n"
|
|
ARGS = HASH
|
|
.fetch(:args)
|
|
.reduce(HashWithIndifferentAccess.new) do |acc, arg|
|
|
acc[arg.fetch("name").to_s] = arg
|
|
acc
|
|
end
|
|
NODES = HASH.fetch(:nodes)
|
|
NODE_START = ["export type %{camel_case}BodyItem = %{body_types};",
|
|
"/** %{snake_case}\n%{docs}\n %{tag_docs} */",
|
|
"export interface %{camel_case} {",
|
|
" comment?: string | undefined;",
|
|
' kind: "%{snake_case}";',
|
|
" args: {"].join("\n")
|
|
MIDDLE_CENTER = " %{arg_name}: %{arg_values};"
|
|
BOTTOM_END = [" }",
|
|
" body?: %{camel_case}BodyItem[] | undefined;",
|
|
"}\n"].join("\n")
|
|
CONSTANT_DECLR_HACK = {
|
|
LATEST_VERSION: Sequence::LATEST_VERSION,
|
|
DIGITAL: CeleryScriptSettingsBag::DIGITAL,
|
|
ANALOG: CeleryScriptSettingsBag::ANALOG,
|
|
}
|
|
CONSTANT_DECLR_HACK_TPL = "export const %{name} = %{value};\n"
|
|
PUBLIC_NODES = [] # Filled at runtime
|
|
PIPE = " |\n"
|
|
|
|
def emit_constants()
|
|
CONSTANT_DECLR_HACK.map do |(name, value)|
|
|
konst = CONSTANT_DECLR_HACK_TPL % { name: name, value: value }
|
|
add_to_output(konst)
|
|
end
|
|
end
|
|
|
|
def add_to_output(string)
|
|
OUTPUT.push(string)
|
|
end
|
|
|
|
def save!
|
|
File.open(FILE_PATH, "w") { |f| f.write(OUTPUT.join("")) }
|
|
puts "Saved to #{FILE_PATH}"
|
|
end
|
|
|
|
def name_of(thing)
|
|
thing.fetch("name").to_s
|
|
end
|
|
|
|
def emit_values
|
|
output = VALUES.map do |val|
|
|
real_name = name_of(val)
|
|
capitalized = real_name.capitalize
|
|
celerized = VALUE_PREFIX + capitalized
|
|
FUNNY_NAMES[capitalized] = celerized
|
|
type = VALUES_OVERRIDE.fetch(real_name, real_name)
|
|
VALUES_TPL % { name: celerized, type: type }
|
|
end
|
|
.uniq
|
|
.sort
|
|
add_to_output(output)
|
|
end
|
|
|
|
def emit_enums
|
|
output = ENUMS.map do |enum|
|
|
name = name_of(enum)
|
|
type = enum.fetch("allowed_values").sort.map(&:inspect).uniq.join(PIPE)
|
|
FUNNY_NAMES[name] = name
|
|
ENUM_TPL % { name: name, type: type }
|
|
end
|
|
.uniq
|
|
.sort
|
|
|
|
add_to_output(output)
|
|
end
|
|
|
|
def emit_nodes()
|
|
nodes = NODES.map do |node|
|
|
tags = node.fetch("tags").sort.uniq
|
|
# Don't publish internal CeleryScript nodes:
|
|
next if tags.include?(:private)
|
|
tag_list = tags.join(", ")
|
|
name = name_of(node).to_s
|
|
bodies = node
|
|
.fetch("allowed_body_types")
|
|
.sort
|
|
.uniq
|
|
.map(&:to_s)
|
|
.map(&:camelize)
|
|
bt = bodies.any? ? "(#{bodies.join(PIPE)})" : "never"
|
|
PUBLIC_NODES.push(name.camelize)
|
|
tpl_binding = {
|
|
body_types: bt,
|
|
camel_case: name.camelize,
|
|
docs: node.fetch("docs"),
|
|
snake_case: name,
|
|
tag_docs: "Tag properties: #{tag_list}.",
|
|
}
|
|
|
|
one = NODE_START % tpl_binding
|
|
two = node.fetch("allowed_args").sort.map do |arg|
|
|
MIDDLE_CENTER % {
|
|
arg_name: arg.to_s,
|
|
arg_values: ARGS.fetch(arg)
|
|
.fetch("allowed_values")
|
|
.map(&:name)
|
|
.map { |x| FUNNY_NAMES[x] || x.camelize }
|
|
.join(PIPE),
|
|
}
|
|
end
|
|
three = BOTTOM_END % tpl_binding
|
|
[one, two, three].flatten.join("\n")
|
|
end
|
|
.compact
|
|
.uniq
|
|
.join("\n")
|
|
add_to_output(nodes)
|
|
end
|
|
|
|
def emit_misc()
|
|
types = PUBLIC_NODES.sort.uniq.join(PIPE)
|
|
tpl = "export type CeleryNode = #{types};\n"
|
|
add_to_output(tpl)
|
|
end
|
|
|
|
emit_constants()
|
|
emit_values()
|
|
emit_enums()
|
|
emit_nodes()
|
|
emit_misc()
|
|
save!
|