V13-FE-011: finalize search list layout slice
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
import fs from 'node:fs'
|
||||
import path from 'node:path'
|
||||
import crypto from 'node:crypto'
|
||||
|
||||
const sourcePath = 'contracts/fields/kbx.fields.json'
|
||||
const source = JSON.parse(fs.readFileSync(sourcePath, 'utf8'))
|
||||
const fields = [...source.fields].sort((a, b) => a.key.localeCompare(b.key))
|
||||
const hash = crypto.createHash('sha256').update(JSON.stringify(source)).digest('hex')
|
||||
|
||||
const tsDir = 'packages/kbx-contracts/src/generated'
|
||||
const csDir = 'backend/Shared/Contracts/Generated'
|
||||
fs.mkdirSync(tsDir, { recursive: true })
|
||||
fs.mkdirSync(csDir, { recursive: true })
|
||||
fs.mkdirSync('generated', { recursive: true })
|
||||
|
||||
const q = value => JSON.stringify(value)
|
||||
const ts = [
|
||||
'// GENERATED FILE. DO NOT EDIT.',
|
||||
`// Source: ${sourcePath}`,
|
||||
`// Source SHA256: ${hash}`,
|
||||
'',
|
||||
`export const kbxFieldDictionaryVersion = ${q(source.version)} as const`,
|
||||
'',
|
||||
'export const kbxFieldCatalog = {',
|
||||
...fields.map(f => ` ${q(f.key)}: ${JSON.stringify(f)},`),
|
||||
'} as const',
|
||||
'',
|
||||
'export type KbxKnownFieldKey = keyof typeof kbxFieldCatalog',
|
||||
'export type KbxKnownFieldDefinition = (typeof kbxFieldCatalog)[KbxKnownFieldKey]',
|
||||
'',
|
||||
'export function getKbxField<K extends KbxKnownFieldKey>(key: K): (typeof kbxFieldCatalog)[K] {',
|
||||
' return kbxFieldCatalog[key]',
|
||||
'}',
|
||||
'',
|
||||
].join('\n')
|
||||
fs.writeFileSync(path.join(tsDir, 'fieldCatalog.ts'), ts)
|
||||
|
||||
const csString = value => value == null ? 'null' : `"${String(value).replaceAll('\\','\\\\').replaceAll('"','\\"')}"`
|
||||
const csBool = value => value ? 'true' : 'false'
|
||||
const pascal = s => s[0].toUpperCase() + s.slice(1)
|
||||
const cs = [
|
||||
'// <auto-generated />',
|
||||
`// Source: ${sourcePath}`,
|
||||
`// Source SHA256: ${hash}`,
|
||||
'namespace Kbx.Contracts.Generated;',
|
||||
'',
|
||||
'public sealed record KbxFieldMetadata(',
|
||||
' string Key, string Label, string DataType, IReadOnlyList<string> Aliases,',
|
||||
' bool Required, int? MaxLength, int? Precision, int? Scale, string? LookupEntity,',
|
||||
' bool Readonly, bool Importable, bool Exportable, bool Sensitive, string? Masking);',
|
||||
'',
|
||||
'public static class KbxFieldKeys',
|
||||
'{',
|
||||
...fields.map(f => ` public const string ${pascal(f.key)} = "${f.key}";`),
|
||||
'}',
|
||||
'',
|
||||
'public static class KbxFieldCatalog',
|
||||
'{',
|
||||
` public const string Version = "${source.version}";`,
|
||||
' private static readonly IReadOnlyDictionary<string, KbxFieldMetadata> Items =',
|
||||
' new Dictionary<string, KbxFieldMetadata>(StringComparer.Ordinal)',
|
||||
' {',
|
||||
...fields.map(f => {
|
||||
const aliases = (f.aliases ?? []).map(csString).join(', ')
|
||||
return ` ["${f.key}"] = new("${f.key}", ${csString(f.label)}, "${f.dataType}", new[] { ${aliases} }, ${csBool(Boolean(f.required))}, ${f.maxLength ?? 'null'}, ${f.precision ?? 'null'}, ${f.scale ?? 'null'}, ${csString(f.lookupEntity)}, ${csBool(Boolean(f.readonly))}, ${csBool(Boolean(f.importable))}, ${csBool(Boolean(f.exportable))}, ${csBool(Boolean(f.sensitive))}, ${csString(f.masking)}),`
|
||||
}),
|
||||
' };',
|
||||
'',
|
||||
' public static KbxFieldMetadata Get(string key) => Items.TryGetValue(key, out var value)',
|
||||
' ? value',
|
||||
' : throw new KeyNotFoundException($"Unknown KBX field key: {key}");',
|
||||
'',
|
||||
' public static bool TryGet(string key, out KbxFieldMetadata? value) => Items.TryGetValue(key, out value);',
|
||||
' public static IReadOnlyCollection<KbxFieldMetadata> All => Items.Values;',
|
||||
'}',
|
||||
'',
|
||||
].join('\n')
|
||||
fs.writeFileSync(path.join(csDir, 'KbxFieldCatalog.g.cs'), cs)
|
||||
|
||||
const manifest = {
|
||||
version: source.version,
|
||||
source: sourcePath,
|
||||
sourceSha256: hash,
|
||||
count: fields.length,
|
||||
fields,
|
||||
}
|
||||
fs.writeFileSync('generated/field-manifest.json', JSON.stringify(manifest, null, 2) + '\n')
|
||||
console.log(`field contracts generated: ${fields.length} fields, version ${source.version}`)
|
||||
Reference in New Issue
Block a user