Module: Opencdd::Codegen::Ts
- Defined in:
- lib/opencdd/codegen/ts.rb
Overview
Serializes the Ruby registries (Opencdd::PropertyIds::REGISTRY and Opencdd::MetaClasses) to TypeScript files that the OpenCDD Editor imports at build time. The editor has no runtime dependency on Ruby.
Constant Summary collapse
- PROPERTY_HELPERS =
<<~TS.freeze export function entry(id: string): PropertyEntry | undefined { return REGISTRY[id]; } export function multilingual(id: string): boolean { return REGISTRY[id]?.multilingual ?? false; } export function appliesTo(id: string): AppliesTo | undefined { return REGISTRY[id]?.appliesTo; } export function valueKind(id: string): ValueKind | undefined { return REGISTRY[id]?.valueKind; } export const ALL_IDS: readonly string[] = Object.keys(REGISTRY); export function canonicalId(name: string): string | undefined { if (name in REGISTRY) return name; return ALIAS_MAP[name]; } export function normalize(rawId: string | null | undefined): string | null { if (!rawId) return null; const s = rawId.trim(); if (!s) return null; const match = s.match(/\\.([A-Za-z0-9-]+)$/); if (!match) return canonicalId(s) ?? s; const base = s.slice(0, s.length - match[0].length); const lang = match[1]; const canonical = canonicalId(base) ?? base; return `${canonical}.${lang}`; } TS
- META_HELPERS =
<<~TS.freeze export function entry(irdi: string): MetaClassEntry | undefined { return REGISTRY[irdi]; } export function entityTypeFor(irdi: string): EntityType | undefined { return REGISTRY[irdi]?.entityType; } export function codePropertyIdFor(irdi: string): string | undefined { return REGISTRY[irdi]?.codePropertyId; } export function metaClassForType(type: EntityType): string | undefined { for (const [irdi, e] of Object.entries(REGISTRY)) { if (e.entityType === type) return irdi; } return undefined; } export const ALL_CODES: readonly string[] = Object.keys(REGISTRY); TS
Class Method Summary collapse
- .alias_map_literal(registry) ⇒ Object
- .entry_literal(entry) ⇒ Object
- .generate_all(editor_dir) ⇒ Object
- .generate_meta_classes(path) ⇒ Object
- .generate_property_ids(path) ⇒ Object
- .render_meta_classes ⇒ Object
-
.render_property_ids ⇒ Object
Returns the generated TS source as a string (no filesystem access).
- .union_type(name, values) ⇒ Object
- .write_file(path, content) ⇒ Object
Class Method Details
.alias_map_literal(registry) ⇒ Object
110 111 112 113 114 115 116 |
# File 'lib/opencdd/codegen/ts.rb', line 110 def alias_map_literal(registry) pairs = [] registry.each_value do |e| e.aliases.each { |a| pairs << " \"#{a}\": \"#{e.id}\"," } end "const ALIAS_MAP: Readonly<Record<string, string>> = {\n#{pairs.join("\n")}\n};" end |
.entry_literal(entry) ⇒ Object
104 105 106 107 108 |
# File 'lib/opencdd/codegen/ts.rb', line 104 def entry_literal(entry) aliases = entry.aliases.map { |a| "\"#{a}\"" }.join(", ") "{ id: \"#{entry.id}\", aliases: [#{aliases}], appliesTo: \"#{entry.applies_to}\", " \ "multilingual: #{entry.multilingual}, valueKind: \"#{entry.value_kind}\" }" end |
.generate_all(editor_dir) ⇒ Object
13 14 15 16 |
# File 'lib/opencdd/codegen/ts.rb', line 13 def generate_all(editor_dir) generate_property_ids(File.join(editor_dir, "src", "models", "PropertyIds.generated.ts")) (File.join(editor_dir, "src", "models", "MetaClasses.generated.ts")) end |
.generate_meta_classes(path) ⇒ Object
54 55 56 |
# File 'lib/opencdd/codegen/ts.rb', line 54 def (path) write_file(path, ) end |
.generate_property_ids(path) ⇒ Object
18 19 20 |
# File 'lib/opencdd/codegen/ts.rb', line 18 def generate_property_ids(path) write_file(path, render_property_ids) end |
.render_meta_classes ⇒ Object
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 |
# File 'lib/opencdd/codegen/ts.rb', line 58 def Opencdd::MetaClasses.reset! = Opencdd::MetaClasses.all type_map = Opencdd::MetaClasses::TYPE_BY_META_CLASS code_map = Opencdd::MetaClasses::CODE_PROPERTY_IDS entity_types = type_map.values.map(&:to_s).uniq.sort out = [] out << "// AUTO-GENERATED by `rake generate_ts`. Do not edit by hand." out << "// Source: Opencdd::MetaClasses in lib/opencdd/meta_class.rb" out << "" out << union_type("EntityType", entity_types) out << "" out << "export interface MetaClassEntry {" out << " readonly irdi: string;" out << " readonly name: string;" out << " readonly entityType: EntityType;" out << " readonly codePropertyId: string;" out << " readonly allowedPropertyIds: readonly string[];" out << "}" out << "" out << "export const REGISTRY: Readonly<Record<string, MetaClassEntry>> = {" .each do |mc| out << " \"#{mc.irdi}\": {" out << " irdi: \"#{mc.irdi}\"," out << " name: \"#{mc.name}\"," out << " entityType: \"#{type_map[mc.irdi]}\"," out << " codePropertyId: \"#{code_map[mc.irdi]}\"," ids = mc.allowed_property_ids.map { |id| "\"#{id}\"" }.join(", ") out << " allowedPropertyIds: [#{ids}]," out << " }," end out << "};" out << "" .each { |mc| out << "export const #{mc.irdi} = \"#{mc.irdi}\";" } out << "" out << META_HELPERS out.join("\n") + "\n" end |
.render_property_ids ⇒ Object
Returns the generated TS source as a string (no filesystem access). Testable in-memory. See TODO.impl/31.
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 |
# File 'lib/opencdd/codegen/ts.rb', line 24 def render_property_ids registry = Opencdd::PropertyIds::REGISTRY out = [] out << "// AUTO-GENERATED by `rake generate_ts`. Do not edit by hand." out << "// Source: Opencdd::PropertyIds::REGISTRY in lib/opencdd/property_ids.rb" out << "" out << union_type("AppliesTo", registry.values.map { |e| e.applies_to.to_s }.uniq.sort) out << union_type("ValueKind", registry.values.map { |e| e.value_kind.to_s }.uniq.sort) out << "" out << "export interface PropertyEntry {" out << " readonly id: string;" out << " readonly aliases: readonly string[];" out << " readonly appliesTo: AppliesTo;" out << " readonly multilingual: boolean;" out << " readonly valueKind: ValueKind;" out << "}" out << "" out << "export const REGISTRY: Readonly<Record<string, PropertyEntry>> = {" registry.each_value { |e| out << " \"#{e.id}\": #{entry_literal(e)}," } out << "};" out << "" registry.each_key { |id| out << "export const #{id} = \"#{id}\";" } out << "" out << PROPERTY_HELPERS out << "" out << alias_map_literal(registry) out.join("\n") + "\n" end |
.union_type(name, values) ⇒ Object
99 100 101 102 |
# File 'lib/opencdd/codegen/ts.rb', line 99 def union_type(name, values) body = values.map { |v| " | \"#{v}\"" }.join("\n") "export type #{name} =\n#{body};" end |
.write_file(path, content) ⇒ Object
118 119 120 121 122 |
# File 'lib/opencdd/codegen/ts.rb', line 118 def write_file(path, content) FileUtils.mkdir_p(File.dirname(path)) File.write(path, content + "\n") puts "Generated #{path}" end |