54 lines
1.6 KiB
TypeScript
54 lines
1.6 KiB
TypeScript
export const ORCHESTRATION_TASK_TITLE_MAX_LENGTH = 80
|
|
export const ORCHESTRATION_DISPLAY_NAME_MAX_LENGTH = 160
|
|
|
|
export type OrchestrationTaskDisplayMetadata = {
|
|
taskTitle: string
|
|
displayName: string
|
|
}
|
|
|
|
export function buildOrchestrationTaskDisplayMetadata(input: {
|
|
spec: string
|
|
taskTitle?: string | null
|
|
displayName?: string | null
|
|
}): OrchestrationTaskDisplayMetadata {
|
|
const taskTitle =
|
|
normalizeSingleLine(input.taskTitle, ORCHESTRATION_TASK_TITLE_MAX_LENGTH) ||
|
|
deriveTaskTitleFromSpec(input.spec)
|
|
const displayName =
|
|
normalizeSingleLine(input.displayName, ORCHESTRATION_DISPLAY_NAME_MAX_LENGTH) || taskTitle
|
|
return { taskTitle, displayName }
|
|
}
|
|
|
|
function deriveTaskTitleFromSpec(spec: string): string {
|
|
for (const line of spec.split(/\r?\n/)) {
|
|
const title = normalizeSingleLine(line, ORCHESTRATION_TASK_TITLE_MAX_LENGTH)
|
|
if (title) {
|
|
return title
|
|
}
|
|
}
|
|
return normalizeSingleLine(spec, ORCHESTRATION_TASK_TITLE_MAX_LENGTH)
|
|
}
|
|
|
|
function normalizeSingleLine(value: string | null | undefined, maxLength: number): string {
|
|
if (!value) {
|
|
return ''
|
|
}
|
|
const normalized = value.trim().replace(/\s+/g, ' ')
|
|
if (!normalized) {
|
|
return ''
|
|
}
|
|
if (normalized.length <= maxLength) {
|
|
return normalized
|
|
}
|
|
const body = trimDanglingHighSurrogate(normalized.slice(0, maxLength - 3)).trimEnd()
|
|
return `${body}...`
|
|
}
|
|
|
|
function trimDanglingHighSurrogate(value: string): string {
|
|
if (value.length === 0) {
|
|
return value
|
|
}
|
|
const lastCode = value.charCodeAt(value.length - 1)
|
|
return lastCode >= 0xd800 && lastCode <= 0xdbff ? value.slice(0, -1) : value
|
|
}
|