Some checks failed
Deploy skills-market-server / deploy (push) Has been cancelled
- Integrated a new utility function `parseFrontmatterScalarKey` to streamline the extraction of the description from skill files. - Improved the logic for handling frontmatter, ensuring more robust parsing and trimming of description values.
78 lines
2.1 KiB
JavaScript
78 lines
2.1 KiB
JavaScript
/**
|
||
* 从 frontmatter 文本里读一个顶层标量(整块 metadata 已由调用方从 --- … --- 切好)。
|
||
* 多行块(description: > / |):从下一行起收到「下一个顶层键」或 metadata 结束为止。
|
||
*/
|
||
|
||
function escapeRegExp(s) {
|
||
return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
|
||
}
|
||
|
||
/** 下一行若是顶层键 `foo:`(行首无缩进),则当前块结束。 */
|
||
function isTopLevelKeyLine(line) {
|
||
const t = line.trimStart()
|
||
if (!t || t.startsWith('#')) return false
|
||
return /^[A-Za-z_][\w-]*\s*:\s/.test(t)
|
||
}
|
||
|
||
function minIndentOfNonEmpty(lines) {
|
||
let min = Infinity
|
||
for (const l of lines) {
|
||
if (!l.trim()) continue
|
||
const n = l.match(/^(\s*)/)[1].length
|
||
if (n < min) min = n
|
||
}
|
||
return min === Infinity ? 0 : min
|
||
}
|
||
|
||
function dedent(lines) {
|
||
const min = minIndentOfNonEmpty(lines)
|
||
return lines.map((l) => (l.length === 0 ? '' : l.slice(min)))
|
||
}
|
||
|
||
function parseFrontmatterScalarKey(fmBlock, key) {
|
||
if (!fmBlock || !key) return null
|
||
const lines = fmBlock.split(/\r?\n/)
|
||
const keyRe = new RegExp(`^${escapeRegExp(key)}:\\s*(.*)$`)
|
||
|
||
for (let i = 0; i < lines.length; i++) {
|
||
const m = lines[i].match(keyRe)
|
||
if (!m) continue
|
||
|
||
let after = m[1].replace(/\s+$/, '')
|
||
const blockHead = after.match(/^([>|])([-+]?)\s*(.*)$/)
|
||
|
||
if (blockHead) {
|
||
const mode = blockHead[1]
|
||
const sameLine = (blockHead[3] || '').trimEnd()
|
||
const raw = []
|
||
if (sameLine) raw.push(sameLine)
|
||
|
||
for (let j = i + 1; j < lines.length; j++) {
|
||
const line = lines[j]
|
||
if (line.length > 0 && !/^\s/.test(line) && isTopLevelKeyLine(line)) break
|
||
raw.push(line)
|
||
}
|
||
|
||
const body = dedent(raw)
|
||
if (mode === '>') {
|
||
return body
|
||
.map((l) => l.trim())
|
||
.filter(Boolean)
|
||
.join(' ')
|
||
.trim()
|
||
}
|
||
return body.join('\n').trim()
|
||
}
|
||
|
||
const t = after.trim()
|
||
if ((t.startsWith('"') && t.endsWith('"')) || (t.startsWith("'") && t.endsWith("'"))) {
|
||
return t.slice(1, -1)
|
||
}
|
||
if (t) return t.replace(/^["']|["']$/g, '')
|
||
return ''
|
||
}
|
||
return null
|
||
}
|
||
|
||
module.exports = { parseFrontmatterScalarKey }
|