import { type FileSystem, type Logger, path as pathModule, Plugin, type ObjectShape, Shape, NowConfig, type Package, } from '@servicenow/sdk-build-core' import { RepackService } from './repack' import { JsonFileShape } from './json-plugin' export const PackageJsonPlugin = Plugin.create({ name: 'PackageJsonPlugin', noTelemetry: true, shapes: [ { shape: JsonFileShape, async toRecord(file, { config, packageJson, project, factory, fs, logger }) { if (file.getBaseName() !== 'package.json' || config.type === 'configuration') { return { success: false } } const relativePath = pathModule.relative(project.getRootDir(), file.getPath()) const sysModulePath = NowConfig.moduleResolutionPath(config, packageJson, false, relativePath) const sbomRecord = await factory.createRecord({ source: file, table: 'sys_module', explicitId: 'bom_json', properties: { path: NowConfig.moduleResolutionPath(config, packageJson, false, 'bom.json'), external_source: false, }, }) return { success: true, value: ( await factory.createRecord({ source: file, table: 'sys_module', explicitId: relativePath.replaceAll(/[./\\]/g, '_'), properties: { // Module resolution at runtime requires this format path: sysModulePath, content: Shape.from( file, await fixDependencyVersion(file.getJson().asObject(), { fs, logger, rootDir: project.getRootDir(), packageJson, }) ) .asString() .withContentType('cdata'), external_source: false, sys_name: sysModulePath, }, }) ).with(sbomRecord), } }, }, ], }) async function fixDependencyVersion( json: ObjectShape, context: { fs: FileSystem; logger: Logger; rootDir: string; packageJson: Package } ) { const deps = json.get('dependencies').ifObject() if (!deps) { return JSON.stringify({ ...json.getValue(), version: context.packageJson.version }, null, 2) } const repack = await RepackService.create(context.logger, context.fs, context.rootDir) const resolvedDeps: { [key: string]: string } = {} for (const dep of deps.keys()) { const { name, version } = await repack.getResolvedDepDetails(dep) resolvedDeps[name] = version } return JSON.stringify( { ...json.getValue(), dependencies: resolvedDeps, version: context.packageJson.version, }, null, 2 ) }