
Security News
Happy Birthday, Shai-Hulud
It has been one year since Shai-Hulud made its first appearance on npm.
@uipath/solutionpackager-tool-core
Advanced tools
Affected versions:
Core contracts and interfaces for building UiPath Solution Packager tools. This package provides the type definitions and base classes for creating tools that restore, validate, build, and pack UiPath projects and solutions.
Create a GitHub Personal Access Token with read:packages permission:
read:packages scopeWindows (PowerShell):
$env:GH_NPM_REGISTRY_TOKEN = "your-token-here"
Linux/macOS:
export GH_NPM_REGISTRY_TOKEN="your-token-here"
Create .npmrc in your project root:
@uipath:registry=https://npm.pkg.github.com/
//npm.pkg.github.com/:_authToken=${GH_NPM_REGISTRY_TOKEN}
Then install:
npm install @uipath/solutionpackager-tool-core
Extend ProjectTool and override the operations you need:
import {
ProjectTool,
type IProjectBuildOptions,
type IProjectRestoreOptions,
ToolResult,
type IToolLogger,
type IFileSystem,
Path,
} from "@uipath/solutionpackager-tool-core";
export class ApiWorkflowsTool extends ProjectTool {
constructor(fileSystem: IFileSystem, logger: IToolLogger) {
super(fileSystem, logger);
}
override async restoreAsync(
options: IProjectRestoreOptions,
cancellationToken?: AbortSignal
): Promise<ToolResult> {
this.logger.info("Restoring dependencies...");
return ToolResult.success();
}
override async buildAsync(
options: IProjectBuildOptions,
cancellationToken?: AbortSignal
): Promise<ToolResult> {
this.logger.info("Building project...");
const outputFolder = Path.join(options.outputPath, "output");
await this.fileSystem.mkdir(outputFolder);
await this.fileSystem.writeFile(
Path.join(outputFolder, "artifact.txt"),
"Build Artifact"
);
return new ToolResult(ToolErrorCodes.Success, "Build completed", [outputFolder]);
}
override async dispose(): Promise<void> {
// Cleanup resources
}
}
Implement IProjectToolFactory:
import {
type IProjectToolFactory,
type ProjectTool,
ProjectTypes,
type ProjectType,
type IToolLogger,
type IFileSystem,
} from "@uipath/solutionpackager-tool-core";
export class ApiWorkflowToolFactory implements IProjectToolFactory {
readonly supportedTypes: readonly ProjectType[] = [ProjectTypes.Api];
constructor(private readonly fileSystem: IFileSystem) {}
async createAsync(logger: IToolLogger): Promise<ProjectTool> {
return new ApiWorkflowsTool(this.fileSystem, logger);
}
}
Register with the SolutionPackager instance:
import type { IToolsFactoryRepositoryConfigurator } from "@uipath/solutionpackager-tool-core";
export function registerProjectToolFactory(
configurator: IToolsFactoryRepositoryConfigurator,
fileSystem: IFileSystem
): void {
configurator.registerProjectToolFactory(
new ApiWorkflowToolFactory(fileSystem)
);
}
// Usage:
// const solutionPackager = await createBrowserSolutionPackager();
// registerApiWorkflowTool(solutionPackager, solutionPackager.fileSystem);
ProjectTool - Override operations your tool supports:
restoreAsync() - Restore dependenciesvalidateAsync() - Validate projectbuildAsync() - Build/compilepackAsync() - Package projectdispose() - CleanupSolutionTool - Similar to ProjectTool but operates at solution level.
Access logger via this.logger:
this.logger.info("Starting build");
this.logger.progress("Building", 50);
this.logger.warn("Deprecated API");
this.logger.error("Build failed", { code: "BUILD_001" });
Access via this.fileSystem with consistent API across Node.js and Browser:
// Read file
const content = await this.fileSystem.readFile("path/to/file.json");
// Write file
await this.fileSystem.writeFile("output/config.xml", "<config></config>");
// Create directory (recursive)
await this.fileSystem.mkdir("dist/assets/images");
// Check existence
if (await this.fileSystem.exists("entrypoints.json")) { }
// List directory
const files = await this.fileSystem.readdir("src/components");
// Delete (recursive for directories)
await this.fileSystem.rm("temp_build");
// Success
return ToolResult.success();
// Error with code and message
return ToolResult.error(ToolErrorCodes.InternalError, "Syntax error");
// With package paths
return new ToolResult(ToolErrorCodes.Success, "done", [packagePath]);
ProjectTypes.AgentProjectTypes.ApiProjectTypes.ConnectorProjectTypes.ProcessProjectTypes.LibraryProjectTypes.WebAppProjectTypes.TestsToolErrorCodes.SuccessToolErrorCodes.InternalErrorExtend with custom codes:
type MyToolErrorCode = ToolErrorCode | "COMPILATION_FAILED" | "VALIDATION_ERROR";
import { Path } from "@uipath/solutionpackager-tool-core";
const fullPath = Path.join(basePath, "subfolder", "file.json");
import { NugetConstants } from "@uipath/solutionpackager-tool-core";
NugetConstants.OutputFolderName; // "bundle"
NugetConstants.ContentFolderName; // "content"
NugetConstants.OperateFileName; // "operate.json"
NugetConstants.EntryPointsFileName; // "entrypoints.json"
NugetConstants.PackageDescriptorFileName; // "package-descriptor.json"
┌─────────────────────────────────────────────────────────────┐
│ tool.core (contracts) │
│ IToolLogger IFileSystem ProjectTool SolutionTool │
└─────────────────────────────────────────────────────────────┘
▲
implements/uses │
┌─────────────────────────┼───────────────────────────────────┐
│ solutionpackager │
│ ToolLogger FileSystem ToolsFactory │
└─────────────────────────────────────────────────────────────┘
tool.core provides interfaces and base classes# Build
npm run build
# Run tests
npm test
# Pack
npm pack
# Publish
npm publish
404 Not Found:
GH_NPM_REGISTRY_TOKEN environment variable is setread:packages permission401 Unauthorized:
echo $env:GH_NPM_REGISTRY_TOKEN (Windows) or echo $GH_NPM_REGISTRY_TOKEN (Linux/macOS)See @uipath/tool-apiworkflow for a complete reference implementation.
@uipath/solutionpackager-tool-coreFAQs
UiPath contracts for solution packager tools
The npm package @uipath/solutionpackager-tool-core receives a total of 1,560 weekly downloads. As such, @uipath/solutionpackager-tool-core popularity was classified as popular.
We found that @uipath/solutionpackager-tool-core demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 25 open source maintainers collaborating on the project.

Security News
It has been one year since Shai-Hulud made its first appearance on npm.

Research
/Security News
Operators behind PolinRider used a compromised GitHub account to plant malware in four development versions of a Packagist package with 700,000+ downloads.

Security News
GitHub Actions now supports cache-mode, a least-privilege control on the Actions cache aimed at the cache poisoning technique behind recent compromises.