// SPDX-License-Identifier: AGPL-3.0-only 'use strict'; const fs = require('node:fs'); const path = require('node:path'); const crypto = require('node:crypto'); const root = path.join(__dirname, '..'); const lock = JSON.parse(fs.readFileSync(path.join(root, 'package-lock.json'), 'utf8')); const components = Object.entries(lock.packages || {}).filter(([name]) => name.startsWith('node_modules/')).map(([name, value]) => ({ type: 'library', name: name.slice('node_modules/'.length), version: value.version, licenses: value.license ? [{license: {id: value.license}}] : undefined, hashes: value.integrity ? [{alg: 'SHA-512', content: value.integrity.replace(/^sha512-/, '')}] : undefined, })).sort((a, b) => a.name.localeCompare(b.name)); const lockDigest = crypto.createHash('sha256').update(JSON.stringify(lock)).digest('hex'); const uuid = `${lockDigest.slice(0, 8)}-${lockDigest.slice(8, 12)}-5${lockDigest.slice(13, 16)}-a${lockDigest.slice(17, 20)}-${lockDigest.slice(20, 32)}`; const document = {bomFormat: 'CycloneDX', specVersion: '1.5', serialNumber: `urn:uuid:${uuid}`, version: 1, metadata: {component: {type: 'application', name: 'gamertan.sandwich-hime', version: '0.1.0-preview.1'}}, components}; process.stdout.write(`${JSON.stringify(document, null, 2)}\n`);