Files
video-gen/video-gen-admin/src/utils/videoPromptSchema.ts
T

153 lines
5.0 KiB
TypeScript

export type JsonValue = any;
export type JsonRecord = Record<string, JsonValue>;
export interface VideoPromptSchemaFieldConfig {
key: string;
label: string;
type?: string;
enabled: boolean;
editable: boolean;
maxLength?: number;
}
export interface VideoPromptSchemaSectionConfig extends VideoPromptSchemaFieldConfig {
contentKey?: string;
itemFields: VideoPromptSchemaFieldConfig[];
children: VideoPromptSchemaFieldConfig[];
}
function isRecord(value: unknown): value is JsonRecord {
return !!value && typeof value === 'object' && !Array.isArray(value);
}
function readString(source: JsonRecord, ...keys: string[]): string {
for (const key of keys) {
const value = source[key];
if (value !== undefined && value !== null && String(value).trim() !== '') return String(value);
}
return '';
}
function readBool(source: JsonRecord, defaultValue: boolean, ...keys: string[]): boolean {
for (const key of keys) {
const value = source[key];
if (value === true || value === false) return value;
if (value === 'true') return true;
if (value === 'false') return false;
}
return defaultValue;
}
function readNumber(source: JsonRecord, ...keys: string[]): number | undefined {
for (const key of keys) {
const value = source[key];
if (typeof value === 'number' && Number.isFinite(value) && value > 0) return value;
if (typeof value === 'string' && value.trim()) {
const parsed = Number(value);
if (Number.isFinite(parsed) && parsed > 0) return parsed;
}
}
return undefined;
}
function normalizeField(raw: unknown): VideoPromptSchemaFieldConfig | null {
if (!isRecord(raw)) return null;
const key = readString(raw, 'key');
if (!key) return null;
return {
key,
label: readString(raw, 'label') || key,
type: readString(raw, 'type') || undefined,
enabled: readBool(raw, true, 'enabled'),
editable: readBool(raw, true, 'editable'),
maxLength: readNumber(raw, 'maxLength', 'max_length'),
};
}
export function getSchemaConfigData(snapshot: unknown): JsonRecord | null {
if (!isRecord(snapshot)) return null;
const data = snapshot.data;
if (isRecord(data)) return data;
if (Array.isArray(snapshot.sections)) return snapshot;
return null;
}
export function hasSchemaConfigSnapshot(snapshot: unknown): boolean {
return !!getSchemaConfigData(snapshot);
}
export function normalizeSchemaSections(snapshot: unknown): VideoPromptSchemaSectionConfig[] {
const data = getSchemaConfigData(snapshot);
const rawSections = Array.isArray(data?.sections) ? data.sections : [];
return rawSections
.map((raw): VideoPromptSchemaSectionConfig | null => {
const base = normalizeField(raw);
if (!base || !isRecord(raw)) return null;
const children = Array.isArray(raw.children) ? raw.children.map(normalizeField).filter(Boolean) as VideoPromptSchemaFieldConfig[] : [];
const itemFields = Array.isArray(raw.itemFields)
? raw.itemFields.map(normalizeField).filter(Boolean) as VideoPromptSchemaFieldConfig[]
: Array.isArray(raw.item_fields)
? raw.item_fields.map(normalizeField).filter(Boolean) as VideoPromptSchemaFieldConfig[]
: [];
return {
...base,
contentKey: readString(raw, 'contentKey', 'content_key') || undefined,
children,
itemFields,
};
})
.filter((section): section is VideoPromptSchemaSectionConfig => !!section && section.enabled);
}
export function inferSchemaSections(schema: unknown): VideoPromptSchemaSectionConfig[] {
if (!isRecord(schema)) return [];
return Object.entries(schema)
.filter(([key]) => !['schemaVersion', 'schemaUsage', 'schema_version', 'schema_usage'].includes(key))
.map(([key, value]) => {
if (Array.isArray(value) && value.every(isRecord)) {
const fields = Array.from(new Set(value.flatMap((item) => Object.keys(item))));
return {
key,
label: key,
type: 'flow',
enabled: true,
editable: false,
itemFields: fields.filter((field) => field !== '时间段').map((field) => ({ key: field, label: field, enabled: true, editable: false })),
children: [],
} as VideoPromptSchemaSectionConfig;
}
if (isRecord(value)) {
return {
key,
label: key,
type: 'object',
enabled: true,
editable: false,
children: Object.keys(value).map((field) => ({ key: field, label: field, enabled: true, editable: false })),
itemFields: [],
} as VideoPromptSchemaSectionConfig;
}
return {
key,
label: key,
type: 'text',
enabled: true,
editable: false,
children: [],
itemFields: [],
} as VideoPromptSchemaSectionConfig;
});
}
export function stringifySchemaValue(value: JsonValue): string {
if (value === null || value === undefined) return '';
if (typeof value === 'object') {
try {
return JSON.stringify(value, null, 2);
} catch {
return String(value);
}
}
return String(value);
}