@uipath/packager-tool-businessrules 1.202.0-preview.134
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/business-rules-tool-factory.d.ts +8 -0
- package/dist/business-rules-tool.d.ts +38 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +106 -0
- package/package.json +41 -0
- package/src/business-rules-tool-factory.ts +25 -0
- package/src/business-rules-tool.ts +198 -0
- package/src/index.ts +16 -0
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type IFileSystem, type IProjectToolFactory, type IToolLogger, type ProjectTool, type ProjectType } from "@uipath/solutionpackager-tool-core";
|
|
2
|
+
/**
|
|
3
|
+
* Factory for creating Business Rules project tools
|
|
4
|
+
*/
|
|
5
|
+
export declare class BusinessRulesToolFactory implements IProjectToolFactory {
|
|
6
|
+
readonly supportedTypes: readonly ProjectType[];
|
|
7
|
+
createAsync(logger: IToolLogger, fileSystem: IFileSystem): Promise<ProjectTool>;
|
|
8
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { IProjectBuildOptions, IProjectPackOptions, IProjectRestoreOptions, IProjectValidateOptions } from "@uipath/solutionpackager-tool-core";
|
|
2
|
+
import { ProjectTool, ToolResult } from "@uipath/solutionpackager-tool-core";
|
|
3
|
+
/**
|
|
4
|
+
* Business Rules project tool.
|
|
5
|
+
*
|
|
6
|
+
* Only `packAsync` does anything. A rule ships as the `.dmn` itself, not wrapped
|
|
7
|
+
* in a nupkg: `options.outputPath` is already `files/{projectId}` in the archive,
|
|
8
|
+
* so copying the file there is the whole job. The solution's `businessRule`
|
|
9
|
+
* resource points at it by file name.
|
|
10
|
+
*/
|
|
11
|
+
export declare class BusinessRulesTool extends ProjectTool {
|
|
12
|
+
restoreAsync(_options: IProjectRestoreOptions, _cancellationToken?: AbortSignal): Promise<ToolResult>;
|
|
13
|
+
validateAsync(_options: IProjectValidateOptions, _cancellationToken?: AbortSignal): Promise<ToolResult>;
|
|
14
|
+
buildAsync(_options: IProjectBuildOptions, _cancellationToken?: AbortSignal): Promise<ToolResult>;
|
|
15
|
+
packAsync(options: IProjectPackOptions, _cancellationToken?: AbortSignal): Promise<ToolResult>;
|
|
16
|
+
/**
|
|
17
|
+
* `{ruleName}-{version}.dmn`, which is what Orchestrator's export handler
|
|
18
|
+
* builds for the same rule. Publish and export have to agree on this or a
|
|
19
|
+
* rule stops round-tripping between solutions.
|
|
20
|
+
*
|
|
21
|
+
* `ruleName` is the name of the `businessRule` resource, never the `.dmn`
|
|
22
|
+
* file's own basename — a project folder named "Business Rules" holding
|
|
23
|
+
* "Business rule.dmn" is what Studio Web produces today. Orchestrator takes
|
|
24
|
+
* the rule's name from the resource (`Spec.Name`) and rebuilds the file name
|
|
25
|
+
* from it on export, and the service reads a rule's version back out of this
|
|
26
|
+
* name by stripping the resource name off the front. Deriving the name from
|
|
27
|
+
* the `.dmn` would break both.
|
|
28
|
+
*
|
|
29
|
+
* So resolve it the way `solution projects add` does when it registers the
|
|
30
|
+
* resource: `project.uiproj`'s `Name`, falling back to the folder. Blank also
|
|
31
|
+
* falls back — `projects add` passes an empty `Name` through, but here it
|
|
32
|
+
* would produce a file called "-1.0.0.dmn".
|
|
33
|
+
*
|
|
34
|
+
* Returns `undefined` when the declared name cannot be used in a file name.
|
|
35
|
+
*/
|
|
36
|
+
private resolveRuleName;
|
|
37
|
+
private findRuleFiles;
|
|
38
|
+
}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import { toolsFactoryRepository } from "@uipath/solutionpackager-tool-core";
|
|
3
|
+
|
|
4
|
+
// src/business-rules-tool-factory.ts
|
|
5
|
+
import {
|
|
6
|
+
ProjectTypes
|
|
7
|
+
} from "@uipath/solutionpackager-tool-core";
|
|
8
|
+
|
|
9
|
+
// src/business-rules-tool.ts
|
|
10
|
+
import {
|
|
11
|
+
Path,
|
|
12
|
+
ProjectTool,
|
|
13
|
+
ToolErrorCodes,
|
|
14
|
+
ToolResult
|
|
15
|
+
} from "@uipath/solutionpackager-tool-core";
|
|
16
|
+
var DmnExtension = ".dmn";
|
|
17
|
+
var ReservedInFileName = /[<>:"/\\|?*]/;
|
|
18
|
+
function isUsableInFileName(name) {
|
|
19
|
+
return !ReservedInFileName.test(name) && ![...name].some((character) => character.charCodeAt(0) < 32);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
class BusinessRulesTool extends ProjectTool {
|
|
23
|
+
async restoreAsync(_options, _cancellationToken) {
|
|
24
|
+
this.logger.info("Restore operation is not required for Business Rules projects");
|
|
25
|
+
return ToolResult.success();
|
|
26
|
+
}
|
|
27
|
+
async validateAsync(_options, _cancellationToken) {
|
|
28
|
+
this.logger.info("Validate operation is not required for Business Rules projects");
|
|
29
|
+
return ToolResult.success();
|
|
30
|
+
}
|
|
31
|
+
async buildAsync(_options, _cancellationToken) {
|
|
32
|
+
this.logger.info("Build operation is not required for Business Rules projects");
|
|
33
|
+
return ToolResult.success();
|
|
34
|
+
}
|
|
35
|
+
async packAsync(options, _cancellationToken) {
|
|
36
|
+
try {
|
|
37
|
+
const ruleFiles = await this.findRuleFiles(options.projectPath);
|
|
38
|
+
if (ruleFiles.length === 0) {
|
|
39
|
+
return ToolResult.error(ToolErrorCodes.InternalError, `No ${DmnExtension} file found in ${options.projectPath}.`, "Add a decision to the project, then pack again.");
|
|
40
|
+
}
|
|
41
|
+
if (ruleFiles.length > 1) {
|
|
42
|
+
return ToolResult.error(ToolErrorCodes.InternalError, `Found ${ruleFiles.length} ${DmnExtension} files in ${options.projectPath}, expected one.`, `Keep one decision per project and move the rest to their own projects.`);
|
|
43
|
+
}
|
|
44
|
+
const sourceFile = ruleFiles[0];
|
|
45
|
+
const ruleName = await this.resolveRuleName(options);
|
|
46
|
+
if (ruleName === undefined) {
|
|
47
|
+
return ToolResult.error(ToolErrorCodes.InternalError, `The project name in project.uiproj cannot be used in a file name.`, `Rename the project so its name has no path separators and none of < > : " | ? * characters.`);
|
|
48
|
+
}
|
|
49
|
+
const targetName = `${ruleName}-${options.package.version}${DmnExtension}`;
|
|
50
|
+
const targetFile = Path.join(options.outputPath, targetName);
|
|
51
|
+
this.logger.progress(`Copying ${targetName}...`);
|
|
52
|
+
const content = await this.fileSystem.readFile(sourceFile);
|
|
53
|
+
if (!content) {
|
|
54
|
+
return ToolResult.error(ToolErrorCodes.InternalError, `Could not read ${sourceFile}.`);
|
|
55
|
+
}
|
|
56
|
+
await this.fileSystem.writeFile(targetFile, content);
|
|
57
|
+
return new ToolResult(ToolErrorCodes.Success, "done", []);
|
|
58
|
+
} catch (error) {
|
|
59
|
+
const message = error instanceof Error ? error.toString() : String(error);
|
|
60
|
+
this.logger.error(message);
|
|
61
|
+
return ToolResult.error(ToolErrorCodes.InternalError, "An error occurred while packing the Business Rules project");
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
async resolveRuleName(options) {
|
|
65
|
+
const uiProject = await this.getUiProjectAsync(options.projectPath);
|
|
66
|
+
const declared = uiProject?.Name?.trim();
|
|
67
|
+
if (!declared) {
|
|
68
|
+
return Path.basename(options.projectPath);
|
|
69
|
+
}
|
|
70
|
+
return isUsableInFileName(declared) ? declared : undefined;
|
|
71
|
+
}
|
|
72
|
+
async findRuleFiles(projectPath) {
|
|
73
|
+
const entries = await this.fileSystem.readdir(projectPath);
|
|
74
|
+
const ruleFiles = [];
|
|
75
|
+
for (const entry of entries) {
|
|
76
|
+
if (!entry.toLowerCase().endsWith(DmnExtension)) {
|
|
77
|
+
continue;
|
|
78
|
+
}
|
|
79
|
+
const fullPath = Path.join(projectPath, entry);
|
|
80
|
+
const stat = await this.fileSystem.stat(fullPath);
|
|
81
|
+
if (stat?.isFile()) {
|
|
82
|
+
ruleFiles.push(fullPath);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return ruleFiles;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// src/business-rules-tool-factory.ts
|
|
90
|
+
class BusinessRulesToolFactory {
|
|
91
|
+
supportedTypes = [
|
|
92
|
+
ProjectTypes.BusinessRules
|
|
93
|
+
];
|
|
94
|
+
async createAsync(logger, fileSystem) {
|
|
95
|
+
return new BusinessRulesTool(fileSystem, logger);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// src/index.ts
|
|
100
|
+
toolsFactoryRepository.registerProjectToolFactory(new BusinessRulesToolFactory);
|
|
101
|
+
export {
|
|
102
|
+
BusinessRulesTool,
|
|
103
|
+
BusinessRulesToolFactory
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
//# debugId=4D84B4901B7D0E3264756E2164756E21
|
package/package.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@uipath/packager-tool-businessrules",
|
|
3
|
+
"version": "1.202.0-preview.134",
|
|
4
|
+
"description": "UiPath Business Rules tool implementation",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"exports": {
|
|
7
|
+
".": {
|
|
8
|
+
"source": "./src/index.ts",
|
|
9
|
+
"default": "./dist/index.js"
|
|
10
|
+
}
|
|
11
|
+
},
|
|
12
|
+
"repository": {
|
|
13
|
+
"type": "git",
|
|
14
|
+
"url": "https://github.com/UiPath/cli.git",
|
|
15
|
+
"directory": "packages/packager/packager-tool-businessrules"
|
|
16
|
+
},
|
|
17
|
+
"publishConfig": {
|
|
18
|
+
"registry": "https://registry.npmjs.org/"
|
|
19
|
+
},
|
|
20
|
+
"types": "./dist/index.d.ts",
|
|
21
|
+
"files": [
|
|
22
|
+
"dist",
|
|
23
|
+
"src"
|
|
24
|
+
],
|
|
25
|
+
"author": "",
|
|
26
|
+
"license": "ISC",
|
|
27
|
+
"peerDependencies": {
|
|
28
|
+
"@uipath/solutionpackager-tool-core": "1.202.0"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@types/node": "^25.5.2",
|
|
32
|
+
"@uipath/solutionpackager-tool-core": "1.202.0",
|
|
33
|
+
"@vitest/browser": "^4.1.6",
|
|
34
|
+
"@vitest/browser-playwright": "^4.1.6",
|
|
35
|
+
"@vitest/coverage-v8": "^4.1.6",
|
|
36
|
+
"playwright": "^1.57.0",
|
|
37
|
+
"typescript": "^7.0.2",
|
|
38
|
+
"vitest": "^4.1.6"
|
|
39
|
+
},
|
|
40
|
+
"gitHead": "a335728adbdb02f28308e4f55d8936d0b150444b"
|
|
41
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type IFileSystem,
|
|
3
|
+
type IProjectToolFactory,
|
|
4
|
+
type IToolLogger,
|
|
5
|
+
type ProjectTool,
|
|
6
|
+
type ProjectType,
|
|
7
|
+
ProjectTypes,
|
|
8
|
+
} from "@uipath/solutionpackager-tool-core";
|
|
9
|
+
import { BusinessRulesTool } from "./business-rules-tool.js";
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Factory for creating Business Rules project tools
|
|
13
|
+
*/
|
|
14
|
+
export class BusinessRulesToolFactory implements IProjectToolFactory {
|
|
15
|
+
readonly supportedTypes: readonly ProjectType[] = [
|
|
16
|
+
ProjectTypes.BusinessRules,
|
|
17
|
+
];
|
|
18
|
+
|
|
19
|
+
async createAsync(
|
|
20
|
+
logger: IToolLogger,
|
|
21
|
+
fileSystem: IFileSystem,
|
|
22
|
+
): Promise<ProjectTool> {
|
|
23
|
+
return new BusinessRulesTool(fileSystem, logger);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
IProjectBuildOptions,
|
|
3
|
+
IProjectPackOptions,
|
|
4
|
+
IProjectRestoreOptions,
|
|
5
|
+
IProjectValidateOptions,
|
|
6
|
+
} from "@uipath/solutionpackager-tool-core";
|
|
7
|
+
import {
|
|
8
|
+
Path,
|
|
9
|
+
ProjectTool,
|
|
10
|
+
ToolErrorCodes,
|
|
11
|
+
ToolResult,
|
|
12
|
+
} from "@uipath/solutionpackager-tool-core";
|
|
13
|
+
|
|
14
|
+
const DmnExtension = ".dmn";
|
|
15
|
+
|
|
16
|
+
// Path separators and the characters no mainstream filesystem accepts in a name.
|
|
17
|
+
// `.`/`..` are not listed: the name always gains a "-{version}.dmn" suffix, so the
|
|
18
|
+
// final path segment can never be either of them.
|
|
19
|
+
const ReservedInFileName = /[<>:"/\\|?*]/;
|
|
20
|
+
|
|
21
|
+
/** Whether `name` can stand as one segment of a file path. */
|
|
22
|
+
function isUsableInFileName(name: string): boolean {
|
|
23
|
+
// Control characters are matched by code point rather than folded into the regex
|
|
24
|
+
// above: a control character inside a regex literal is itself a lint error.
|
|
25
|
+
return (
|
|
26
|
+
!ReservedInFileName.test(name) &&
|
|
27
|
+
![...name].some((character) => character.charCodeAt(0) < 0x20)
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Business Rules project tool.
|
|
33
|
+
*
|
|
34
|
+
* Only `packAsync` does anything. A rule ships as the `.dmn` itself, not wrapped
|
|
35
|
+
* in a nupkg: `options.outputPath` is already `files/{projectId}` in the archive,
|
|
36
|
+
* so copying the file there is the whole job. The solution's `businessRule`
|
|
37
|
+
* resource points at it by file name.
|
|
38
|
+
*/
|
|
39
|
+
export class BusinessRulesTool extends ProjectTool {
|
|
40
|
+
override async restoreAsync(
|
|
41
|
+
_options: IProjectRestoreOptions,
|
|
42
|
+
_cancellationToken?: AbortSignal,
|
|
43
|
+
): Promise<ToolResult> {
|
|
44
|
+
this.logger.info(
|
|
45
|
+
"Restore operation is not required for Business Rules projects",
|
|
46
|
+
);
|
|
47
|
+
return ToolResult.success();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
override async validateAsync(
|
|
51
|
+
_options: IProjectValidateOptions,
|
|
52
|
+
_cancellationToken?: AbortSignal,
|
|
53
|
+
): Promise<ToolResult> {
|
|
54
|
+
this.logger.info(
|
|
55
|
+
"Validate operation is not required for Business Rules projects",
|
|
56
|
+
);
|
|
57
|
+
return ToolResult.success();
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
override async buildAsync(
|
|
61
|
+
_options: IProjectBuildOptions,
|
|
62
|
+
_cancellationToken?: AbortSignal,
|
|
63
|
+
): Promise<ToolResult> {
|
|
64
|
+
this.logger.info(
|
|
65
|
+
"Build operation is not required for Business Rules projects",
|
|
66
|
+
);
|
|
67
|
+
return ToolResult.success();
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
override async packAsync(
|
|
71
|
+
options: IProjectPackOptions,
|
|
72
|
+
_cancellationToken?: AbortSignal,
|
|
73
|
+
): Promise<ToolResult> {
|
|
74
|
+
try {
|
|
75
|
+
const ruleFiles = await this.findRuleFiles(options.projectPath);
|
|
76
|
+
|
|
77
|
+
if (ruleFiles.length === 0) {
|
|
78
|
+
return ToolResult.error(
|
|
79
|
+
ToolErrorCodes.InternalError,
|
|
80
|
+
`No ${DmnExtension} file found in ${options.projectPath}.`,
|
|
81
|
+
"Add a decision to the project, then pack again.",
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// One rule per project today. Copying several would leave the extra
|
|
86
|
+
// files unreferenced, since the project has a single businessRule
|
|
87
|
+
// resource — so say so instead of packing something deploy can't place.
|
|
88
|
+
if (ruleFiles.length > 1) {
|
|
89
|
+
return ToolResult.error(
|
|
90
|
+
ToolErrorCodes.InternalError,
|
|
91
|
+
`Found ${ruleFiles.length} ${DmnExtension} files in ${options.projectPath}, expected one.`,
|
|
92
|
+
`Keep one decision per project and move the rest to their own projects.`,
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const sourceFile = ruleFiles[0];
|
|
97
|
+
const ruleName = await this.resolveRuleName(options);
|
|
98
|
+
|
|
99
|
+
if (ruleName === undefined) {
|
|
100
|
+
return ToolResult.error(
|
|
101
|
+
ToolErrorCodes.InternalError,
|
|
102
|
+
`The project name in project.uiproj cannot be used in a file name.`,
|
|
103
|
+
`Rename the project so its name has no path separators and none of < > : " | ? * characters.`,
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const targetName = `${ruleName}-${options.package.version}${DmnExtension}`;
|
|
108
|
+
const targetFile = Path.join(options.outputPath, targetName);
|
|
109
|
+
|
|
110
|
+
this.logger.progress(`Copying ${targetName}...`);
|
|
111
|
+
|
|
112
|
+
const content = await this.fileSystem.readFile(sourceFile);
|
|
113
|
+
if (!content) {
|
|
114
|
+
return ToolResult.error(
|
|
115
|
+
ToolErrorCodes.InternalError,
|
|
116
|
+
`Could not read ${sourceFile}.`,
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
await this.fileSystem.writeFile(targetFile, content);
|
|
120
|
+
|
|
121
|
+
// Empty on purpose. A non-.nupkg path here breaks solution signing:
|
|
122
|
+
// the resolver finds nothing for it and the sign step fails hard.
|
|
123
|
+
// Nothing to resolve is safe.
|
|
124
|
+
return new ToolResult(ToolErrorCodes.Success, "done", []);
|
|
125
|
+
} catch (error: unknown) {
|
|
126
|
+
const message =
|
|
127
|
+
error instanceof Error ? error.toString() : String(error);
|
|
128
|
+
this.logger.error(message);
|
|
129
|
+
return ToolResult.error(
|
|
130
|
+
ToolErrorCodes.InternalError,
|
|
131
|
+
"An error occurred while packing the Business Rules project",
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* `{ruleName}-{version}.dmn`, which is what Orchestrator's export handler
|
|
138
|
+
* builds for the same rule. Publish and export have to agree on this or a
|
|
139
|
+
* rule stops round-tripping between solutions.
|
|
140
|
+
*
|
|
141
|
+
* `ruleName` is the name of the `businessRule` resource, never the `.dmn`
|
|
142
|
+
* file's own basename — a project folder named "Business Rules" holding
|
|
143
|
+
* "Business rule.dmn" is what Studio Web produces today. Orchestrator takes
|
|
144
|
+
* the rule's name from the resource (`Spec.Name`) and rebuilds the file name
|
|
145
|
+
* from it on export, and the service reads a rule's version back out of this
|
|
146
|
+
* name by stripping the resource name off the front. Deriving the name from
|
|
147
|
+
* the `.dmn` would break both.
|
|
148
|
+
*
|
|
149
|
+
* So resolve it the way `solution projects add` does when it registers the
|
|
150
|
+
* resource: `project.uiproj`'s `Name`, falling back to the folder. Blank also
|
|
151
|
+
* falls back — `projects add` passes an empty `Name` through, but here it
|
|
152
|
+
* would produce a file called "-1.0.0.dmn".
|
|
153
|
+
*
|
|
154
|
+
* Returns `undefined` when the declared name cannot be used in a file name.
|
|
155
|
+
*/
|
|
156
|
+
private async resolveRuleName(
|
|
157
|
+
options: IProjectPackOptions,
|
|
158
|
+
): Promise<string | undefined> {
|
|
159
|
+
const uiProject = await this.getUiProjectAsync(options.projectPath);
|
|
160
|
+
const declared = uiProject?.Name?.trim();
|
|
161
|
+
|
|
162
|
+
// Absent or blank: `projects add` names the resource after the folder too,
|
|
163
|
+
// so the two still agree.
|
|
164
|
+
if (!declared) {
|
|
165
|
+
return Path.basename(options.projectPath);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// `project.uiproj` travels inside the solution, so `Name` is untrusted input
|
|
169
|
+
// that reaches a file path. `Path.join` only normalizes separators — it does
|
|
170
|
+
// not resolve `..` — so "../../x" would write outside `options.outputPath`.
|
|
171
|
+
// Falling back to the folder is not the answer either: the artefact name has
|
|
172
|
+
// to match the resource name or the service cannot read the version back off
|
|
173
|
+
// it, so an unusable name is reported rather than quietly replaced.
|
|
174
|
+
return isUsableInFileName(declared) ? declared : undefined;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
private async findRuleFiles(projectPath: string): Promise<string[]> {
|
|
178
|
+
const entries = await this.fileSystem.readdir(projectPath);
|
|
179
|
+
const ruleFiles: string[] = [];
|
|
180
|
+
|
|
181
|
+
for (const entry of entries) {
|
|
182
|
+
if (!entry.toLowerCase().endsWith(DmnExtension)) {
|
|
183
|
+
continue;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
const fullPath = Path.join(projectPath, entry);
|
|
187
|
+
const stat = await this.fileSystem.stat(fullPath);
|
|
188
|
+
if (stat?.isFile()) {
|
|
189
|
+
ruleFiles.push(fullPath);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// Deliberately unordered: packAsync only reads element 0 when there is exactly
|
|
194
|
+
// one, and the "more than one" error reports the count rather than a file, so
|
|
195
|
+
// nothing downstream can observe the order.
|
|
196
|
+
return ruleFiles;
|
|
197
|
+
}
|
|
198
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// Business Rules tool factory.
|
|
2
|
+
//
|
|
3
|
+
// Self-registers on import so micro-frontend consumers (whose MFEs UiPath does
|
|
4
|
+
// not control) that load this package via a side-effect import get the factory
|
|
5
|
+
// registered automatically — StudioWeb does not reference this package, so it
|
|
6
|
+
// relies on self-registration. Also exported for consumers that register
|
|
7
|
+
// explicitly; re-registering the same factory class is an idempotent no-op.
|
|
8
|
+
import { toolsFactoryRepository } from "@uipath/solutionpackager-tool-core";
|
|
9
|
+
import { BusinessRulesToolFactory } from "./business-rules-tool-factory.js";
|
|
10
|
+
|
|
11
|
+
toolsFactoryRepository.registerProjectToolFactory(
|
|
12
|
+
new BusinessRulesToolFactory(),
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
export { BusinessRulesTool } from "./business-rules-tool.js";
|
|
16
|
+
export { BusinessRulesToolFactory };
|