/
gsam
/
ui-kit-ce
Обзор
Документация
Войти
/
gsam
/
ui-kit-ce
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
develop
scripts/sbom-generator.js
131 строка
3 KB
Denis Svyatovets
build: добавлен скрипт для генерации sbom
02 апр 2026, 16:11
02 апр 2026, 16:11
a680442
Код
Авторство
О чём код?
const { exec } = require('child_process') const fs = require('fs') const rawSbomName = 'raw-bom.json' const finalSbomName = 'bom-with-license.json' generateSbom() async function generateSbom() { fs.rmSync(`./${finalSbomName}`, { force: true }) const filterString = await getSbomFilter() await runCmdAsync( `yarn cdxgen -o ${rawSbomName} --install-deps false --exclude **/package/package-lock.json --exclude **/package/yarn.lock --exclude **/next-js14/package-lock.json ${filterString}` ) fixLicense() fs.rmSync(`./${rawSbomName}`, { force: true }) } async function getSbomFilter() { const rawProdList = await runCmdAsync('NODE_ENV=production yarn list --json') let productionList = JSON.parse(rawProdList).data.trees.slice() const productionMap = getDepsMap(productionList) const rawAllList = await runCmdAsync('NODE_ENV=development yarn list --json') let allList = JSON.parse(rawAllList).data.trees.slice() const allMap = getDepsMap(allList) const devDeps = [] allMap.forEach((pkgSet, pkgName) => { const prodSet = productionMap.get(pkgName) if (!prodSet) { devDeps.push(`${pkgName}@`) } else if (!areSetsEqual(pkgSet, prodSet)) { pkgSet.forEach((ver) => { if (!prodSet.has(ver)) { devDeps.push(`${pkgName}@${ver}`) } }) } }) return devDeps.map((x) => `--filter ${x}`).join(' ') || '' } function fixLicense() { const rawData = fs.readFileSync(`./${rawSbomName}`, 'utf8') const jsonData = JSON.parse(rawData) const components = jsonData.components.map((c) => { const { group, name } = c const path = group ? `/${group}/${name}` : `/${name}` const rawComponentPkgJson = fs.readFileSync( `./node_modules/${path}/package.json`, 'utf-8' ) const componentPkgJson = JSON.parse(rawComponentPkgJson) const componenLicense = componentPkgJson.license return { ...c, licenses: [ { license: { id: componenLicense, }, }, ], } }) fs.writeFileSync( `./${finalSbomName}`, JSON.stringify({ ...jsonData, components }) ) } function getDepsMap(rootList) { const productionMap = new Map() const listCopy = rootList.slice() while (listCopy.length) { const node = listCopy.pop() if ( !node.name.includes('@v-uik') && !node.name.includes('@^') && !node.name.includes('@~') ) { const [pkgName, pkgVersion] = node.name.split('@').filter(Boolean) let mapValue = productionMap.get(pkgName) || new Set() productionMap.set(pkgName, mapValue) mapValue.add(pkgVersion) } listCopy.push(...(node.children ?? [])) } return productionMap } function areSetsEqual(setA, setB) { if (setA.size !== setB.size) { return false } for (let item of setA) { if (!setB.has(item)) { return false } } return true } function runCmdAsync(cmd) { return new Promise((res, rej) => { console.log(cmd) exec(cmd, (error, stdout, stderr) => { if (error) { console.error(`Ошибка: ${error.message}`) rej(`Ошибка: ${error.message}`) return } if (stderr) { console.error(`STDERR: ${stderr}`) } res(stdout) }) }) }