24 lines
2.7 KiB
JavaScript
24 lines
2.7 KiB
JavaScript
import fs from 'node:fs'
|
|
import crypto from 'node:crypto'
|
|
const sourcePath='contracts/telemetry/kbx.telemetry.json'
|
|
const source=fs.readFileSync(sourcePath,'utf8')
|
|
const data=JSON.parse(source)
|
|
const sha=crypto.createHash('sha256').update(source).digest('hex')
|
|
const names=new Set(), allowedName=/^[a-z][a-z0-9_.-]+$/
|
|
for(const event of data.events){
|
|
if(!allowedName.test(event.name)) throw new Error(`invalid telemetry event name: ${event.name}`)
|
|
if(names.has(event.name)) throw new Error(`duplicate telemetry event: ${event.name}`)
|
|
names.add(event.name)
|
|
const attrs=new Set()
|
|
for(const key of event.allowedAttributes??[]){if(attrs.has(key))throw new Error(`duplicate attribute ${event.name}.${key}`);attrs.add(key)}
|
|
}
|
|
const manifest={schemaVersion:data.schemaVersion,telemetryVersion:data.telemetryVersion,sourceSha256:sha,principles:data.principles,events:data.events,metrics:data.metrics}
|
|
fs.mkdirSync('generated',{recursive:true});fs.writeFileSync('generated/telemetry-manifest.json',JSON.stringify(manifest,null,2)+'\n')
|
|
const ts=`// generated from ${sourcePath}; do not edit.\nexport const kbxTelemetryCatalog = ${JSON.stringify(Object.fromEntries(data.events.map(e=>[e.name,e])),null,2)} as const\nexport type KbxTelemetryEventName = keyof typeof kbxTelemetryCatalog\nexport const kbxUxMetricCatalog = ${JSON.stringify(Object.fromEntries(data.metrics.map(m=>[m.key,m])),null,2)} as const\nexport type KbxUxMetricKey = keyof typeof kbxUxMetricCatalog\nexport const kbxTelemetrySourceSha256 = '${sha}' as const\n`
|
|
fs.mkdirSync('packages/kbx-contracts/src/generated',{recursive:true});fs.writeFileSync('packages/kbx-contracts/src/generated/telemetryCatalog.ts',ts)
|
|
const esc=s=>s.replaceAll('"','\\"')
|
|
const csEvents=data.events.map(e=>` ["${e.name}"] = new("${e.name}", "${e.category}", new[] { ${(e.allowedAttributes??[]).map(x=>`"${x}"`).join(', ')} }, ${e.requiresDuration?'true':'false'})`).join(',\n')
|
|
const cs=`// generated from ${sourcePath}; do not edit.\nnamespace Kbx.Shared.Telemetry.Generated;\n\npublic sealed record KbxTelemetryEventDefinition(string Name,string Category,IReadOnlyList<string> AllowedAttributes,bool RequiresDuration);\n\npublic static class KbxTelemetryCatalog\n{\n public const string SourceSha256 = "${sha}";\n public static readonly IReadOnlyDictionary<string,KbxTelemetryEventDefinition> Events = new Dictionary<string,KbxTelemetryEventDefinition>(StringComparer.Ordinal)\n {\n${csEvents}\n };\n}\n`
|
|
fs.mkdirSync('backend/Shared/Telemetry/Generated',{recursive:true});fs.writeFileSync('backend/Shared/Telemetry/Generated/KbxTelemetryCatalog.g.cs',cs)
|
|
console.log(`generated telemetry contracts: ${data.events.length} events, ${data.metrics.length} metrics`)
|