@uipath/packager-tool-case 1.201.0 → 1.202.0-preview.136

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/index.d.ts CHANGED
@@ -1,2 +1,3 @@
1
1
  import { CaseToolFactory } from "./case-tool-factory.js";
2
+ export { type CaseBpmnCompiler, registerCaseBpmnCompiler, } from "./case-bpmn-compiler.js";
2
3
  export { CaseToolFactory };
package/dist/index.js CHANGED
@@ -18,9 +18,23 @@ import {
18
18
  ToolErrorCodes,
19
19
  ToolResult
20
20
  } from "@uipath/solutionpackager-tool-core";
21
+
22
+ // src/case-bpmn-compiler.ts
23
+ var COMPILER_KEY = Symbol.for("@uipath/packager-tool-case/caseBpmnCompiler");
24
+ var _global = globalThis;
25
+ function registerCaseBpmnCompiler(caseBpmnCompiler) {
26
+ _global[COMPILER_KEY] = caseBpmnCompiler;
27
+ }
28
+ function getCaseBpmnCompiler() {
29
+ return _global[COMPILER_KEY];
30
+ }
31
+
32
+ // src/case-tool.ts
21
33
  var CaseConstants = {
22
34
  EntryPointsFileName: "entry-points.json",
23
- BindingsV2FileName: "bindings_v2.json"
35
+ BindingsV2FileName: "bindings_v2.json",
36
+ CasePlanFileName: "caseplan.json",
37
+ CompiledBpmnFileName: "caseplan.json.bpmn"
24
38
  };
25
39
 
26
40
  class CaseTool extends ProjectTool {
@@ -44,6 +58,11 @@ class CaseTool extends ProjectTool {
44
58
  try {
45
59
  this.logger.progress("Copying files...");
46
60
  await this.copyFiles(options.projectPath, contentFolder);
61
+ this.logger.progress("Compiling case plan to BPMN...");
62
+ const compileResult = await this.compileCasePlan(options.projectPath, contentFolder);
63
+ if (!compileResult.isSuccess) {
64
+ return compileResult;
65
+ }
47
66
  this.logger.progress("Creating operate.json file...");
48
67
  await this.createOperateFile(options, contentFolder);
49
68
  this.logger.progress("Creating package-descriptor.json file...");
@@ -100,6 +119,59 @@ class CaseTool extends ProjectTool {
100
119
  }
101
120
  }
102
121
  }
122
+ async compileCasePlan(projectPath, contentFolder) {
123
+ const compile = getCaseBpmnCompiler();
124
+ const casePlanPath = Path.join(projectPath, CaseConstants.CasePlanFileName);
125
+ if (!compile || !await this.fileSystem.exists(casePlanPath)) {
126
+ return this.checkEntryPointBpmnPresent(contentFolder);
127
+ }
128
+ const casePlan = await this.fileSystem.readFile(casePlanPath);
129
+ if (!casePlan || casePlan.length === 0) {
130
+ return ToolResult.error(ToolErrorCodes.InternalError, `'${CaseConstants.CasePlanFileName}' in ${projectPath} is empty, so there is nothing to compile into '${CaseConstants.CompiledBpmnFileName}'. Author the case plan, or re-scaffold the project with 'uip maestro case init'.`);
131
+ }
132
+ try {
133
+ const bpmnXml = await compile(new TextDecoder().decode(casePlan));
134
+ await this.fileSystem.writeFile(Path.join(contentFolder, CaseConstants.CompiledBpmnFileName), bpmnXml);
135
+ return await this.checkEntryPointBpmnPresent(contentFolder);
136
+ } catch (error) {
137
+ const message = error instanceof Error ? error.message : String(error);
138
+ this.logger.error(message);
139
+ return ToolResult.error(ToolErrorCodes.InternalError, `Failed to compile '${CaseConstants.CasePlanFileName}' into '${CaseConstants.CompiledBpmnFileName}': ${message}. Run 'uip maestro case validate ${projectPath}' to find the problem in the case plan, then pack again.`);
140
+ }
141
+ }
142
+ async checkEntryPointBpmnPresent(contentFolder) {
143
+ const referenced = await this.readEntryPointBpmnFiles(contentFolder);
144
+ if (referenced === null) {
145
+ return ToolResult.error(ToolErrorCodes.InternalError, `'${CaseConstants.EntryPointsFileName}' could not be read as JSON, so pack cannot check that the BPMN it declares is in the package. Fix or re-scaffold '${CaseConstants.EntryPointsFileName}', then pack again.`);
146
+ }
147
+ if (referenced.length === 0) {
148
+ return ToolResult.success();
149
+ }
150
+ const contentFiles = await this.fileSystem.readdir(contentFolder);
151
+ const missing = referenced.filter((file) => !contentFiles.includes(file));
152
+ if (missing.length === 0) {
153
+ return ToolResult.success();
154
+ }
155
+ const fix = missing.includes(CaseConstants.CompiledBpmnFileName) ? `Author '${CaseConstants.CasePlanFileName}' so pack can compile it (see 'uip maestro case init'), then pack again.` : `Add the missing file to the project, or point '${CaseConstants.EntryPointsFileName}' at the BPMN the project does ship, then pack again.`;
156
+ return ToolResult.error(ToolErrorCodes.InternalError, `'${CaseConstants.EntryPointsFileName}' points at ${missing.map((f) => `'content/${f}'`).join(", ")}, which the package does not contain, so it would deploy and activate and then fault every job. ${fix}`);
157
+ }
158
+ async readEntryPointBpmnFiles(contentFolder) {
159
+ const entryPointsPath = Path.join(contentFolder, CaseConstants.EntryPointsFileName);
160
+ if (!await this.fileSystem.exists(entryPointsPath)) {
161
+ return [];
162
+ }
163
+ const raw = await this.fileSystem.readFile(entryPointsPath);
164
+ if (!raw || raw.length === 0) {
165
+ return null;
166
+ }
167
+ try {
168
+ const parsed = JSON.parse(new TextDecoder().decode(raw));
169
+ const names = (parsed.entryPoints ?? []).map((entry) => entry.filePath ?? "").map((filePath) => filePath.split("#")[0]).map((filePath) => filePath.split("/").pop() ?? "").filter((name) => name.endsWith(".bpmn"));
170
+ return [...new Set(names)];
171
+ } catch {
172
+ return null;
173
+ }
174
+ }
103
175
  async createOperateFile(options, contentFolder) {
104
176
  await ensureContentOperateFile(this.fileSystem, {
105
177
  contentFolder,
@@ -141,7 +213,8 @@ class CaseToolFactory {
141
213
  // src/index.ts
142
214
  toolsFactoryRepository.registerProjectToolFactory(new CaseToolFactory);
143
215
  export {
144
- CaseToolFactory
216
+ CaseToolFactory,
217
+ registerCaseBpmnCompiler
145
218
  };
146
219
 
147
- //# debugId=C4347E7455C1904D64756E2164756E21
220
+ //# debugId=0879235A557F09E364756E2164756E21
@@ -0,0 +1,39 @@
1
+ import { createRequire } from "node:module";
2
+ var __create = Object.create;
3
+ var __getProtoOf = Object.getPrototypeOf;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ function __accessProp(key) {
8
+ return this[key];
9
+ }
10
+ var __toESMCache_node;
11
+ var __toESMCache_esm;
12
+ var __toESM = (mod, isNodeMode, target) => {
13
+ var canCache = mod != null && typeof mod === "object";
14
+ if (canCache) {
15
+ var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
16
+ var cached = cache.get(mod);
17
+ if (cached)
18
+ return cached;
19
+ }
20
+ target = mod != null ? __create(__getProtoOf(mod)) : {};
21
+ const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
22
+ if (mod && typeof mod === "object" || typeof mod === "function") {
23
+ for (let key of __getOwnPropNames(mod))
24
+ if (!__hasOwnProp.call(to, key))
25
+ __defProp(to, key, {
26
+ get: __accessProp.bind(mod, key),
27
+ enumerable: true
28
+ });
29
+ }
30
+ if (canCache)
31
+ cache.set(mod, to);
32
+ return to;
33
+ };
34
+ var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
35
+ var __require = /* @__PURE__ */ createRequire(import.meta.url);
36
+
37
+ export { __toESM, __commonJS, __require };
38
+
39
+ //# debugId=4A15A0D6FCDB684764756E2164756E21
package/dist/node.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Register the Node `caseplan.json` -> BPMN compiler. Call it wherever the
3
+ * Case project tool factory is registered on Node — without it a Case project
4
+ * can only be packed from an already-compiled `.bpmn`.
5
+ */
6
+ export declare function registerNodeCaseBpmnCompiler(): void;
package/dist/node.js ADDED
@@ -0,0 +1,26 @@
1
+ import {
2
+ __require,
3
+ __toESM
4
+ } from "./node-1de529jm.js";
5
+
6
+ // src/case-bpmn-compiler.ts
7
+ var COMPILER_KEY = Symbol.for("@uipath/packager-tool-case/caseBpmnCompiler");
8
+ var _global = globalThis;
9
+ function registerCaseBpmnCompiler(caseBpmnCompiler) {
10
+ _global[COMPILER_KEY] = caseBpmnCompiler;
11
+ }
12
+
13
+ // src/node.ts
14
+ var compileCasePlan = async (casePlanJson) => {
15
+ const { serializeCaseDiskJsonToBpmnAndRulesJson } = await import("./index-x6xpvwgg.js").then((m)=>__toESM(m.default,1));
16
+ const { bpmnXml } = await serializeCaseDiskJsonToBpmnAndRulesJson(casePlanJson);
17
+ return bpmnXml;
18
+ };
19
+ function registerNodeCaseBpmnCompiler() {
20
+ registerCaseBpmnCompiler(compileCasePlan);
21
+ }
22
+ export {
23
+ registerNodeCaseBpmnCompiler
24
+ };
25
+
26
+ //# debugId=0A08F635657DD68164756E2164756E21
package/package.json CHANGED
@@ -1,12 +1,17 @@
1
1
  {
2
2
  "name": "@uipath/packager-tool-case",
3
- "version": "1.201.0",
3
+ "version": "1.202.0-preview.136",
4
4
  "description": "UiPath Case Management tool implementation",
5
5
  "type": "module",
6
6
  "exports": {
7
7
  ".": {
8
8
  "source": "./src/index.ts",
9
9
  "default": "./dist/index.js"
10
+ },
11
+ "./node": {
12
+ "source": "./src/node.ts",
13
+ "types": "./dist/node.d.ts",
14
+ "default": "./dist/node.js"
10
15
  }
11
16
  },
12
17
  "repository": {
@@ -25,7 +30,7 @@
25
30
  "author": "",
26
31
  "license": "ISC",
27
32
  "peerDependencies": {
28
- "@uipath/solutionpackager-tool-core": "1.201.0"
33
+ "@uipath/solutionpackager-tool-core": "1.202.0"
29
34
  },
30
- "gitHead": "7933378ad5276ac369900293a1447474dcec6826"
35
+ "gitHead": "f6270de2c7c04f4c43b2f5187b0c3d3c314c2610"
31
36
  }
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Registry for the `caseplan.json` -> BPMN compiler.
3
+ *
4
+ * The compiler lives in `@uipath/case-schema`, a 2.5 MB CommonJS bundle that
5
+ * `require`s `child_process`, `tls` and `http2`. This package builds for the
6
+ * browser (StudioWeb loads it as a micro-frontend), so it cannot import that
7
+ * dependency directly. Instead it declares the interface and whoever runs on
8
+ * Node registers the real thing — `@uipath/packager-tool-case/node` provides
9
+ * that implementation, and the CLI tools that register the Case factory call
10
+ * it alongside.
11
+ *
12
+ * Nothing registered means no compile: `CaseTool` then requires the project to
13
+ * carry an already-compiled `.bpmn` and fails the build with an actionable
14
+ * message if it does not. It never packs a case silently missing its BPMN.
15
+ */
16
+
17
+ /** Compiles the contents of `caseplan.json` into BPMN XML. */
18
+ export type CaseBpmnCompiler = (casePlanJson: string) => Promise<string>;
19
+
20
+ /**
21
+ * Global singleton key, keyed with `Symbol.for()` so every copy of this module
22
+ * resolves to the same slot. There are always several: `maestro-tool` and
23
+ * `case-tool` each bundle their own copy of this package, and the Node entry
24
+ * that registers the compiler is a separate build output from the browser one
25
+ * that reads it. A module-local `let` would leave the registration in one copy
26
+ * and the lookup in another — which is silently the old bug, a package packed
27
+ * without its BPMN. Mirrors `toolsFactoryRepository` in
28
+ * `@uipath/solutionpackager-tool-core`.
29
+ */
30
+ const COMPILER_KEY = Symbol.for("@uipath/packager-tool-case/caseBpmnCompiler");
31
+
32
+ const _global = globalThis as Record<symbol, CaseBpmnCompiler | undefined>;
33
+
34
+ /**
35
+ * Register the compiler used by `CaseTool.buildAsync`. Last call wins. Pass
36
+ * `undefined` to clear it — how a test reproduces a host that never
37
+ * registered one.
38
+ */
39
+ export function registerCaseBpmnCompiler(
40
+ caseBpmnCompiler: CaseBpmnCompiler | undefined,
41
+ ): void {
42
+ _global[COMPILER_KEY] = caseBpmnCompiler;
43
+ }
44
+
45
+ /** The registered compiler, or `undefined` when none was registered. */
46
+ export function getCaseBpmnCompiler(): CaseBpmnCompiler | undefined {
47
+ return _global[COMPILER_KEY];
48
+ }
package/src/case-tool.ts CHANGED
@@ -17,6 +17,7 @@ import {
17
17
  ToolErrorCodes,
18
18
  ToolResult,
19
19
  } from "@uipath/solutionpackager-tool-core";
20
+ import { getCaseBpmnCompiler } from "./case-bpmn-compiler.js";
20
21
 
21
22
  /**
22
23
  * Case Management-specific file names
@@ -24,14 +25,18 @@ import {
24
25
  const CaseConstants = {
25
26
  EntryPointsFileName: "entry-points.json",
26
27
  BindingsV2FileName: "bindings_v2.json",
28
+ CasePlanFileName: "caseplan.json",
29
+ CompiledBpmnFileName: "caseplan.json.bpmn",
27
30
  } as const;
28
31
 
29
32
  /**
30
33
  * Case Management project tool implementation.
31
34
  *
32
- * Case Management projects use .stage.json source files that are converted
33
- * to .bpmn format. All files are placed in the content/ folder (no separate
34
- * source folder like flow_files/).
35
+ * The authored source is `caseplan.json`; the runtime reads the BPMN compiled
36
+ * from it. `entry-points.json` points at `/content/caseplan.json.bpmn`, so the
37
+ * build compiles that file into content/ — a package without it deploys and
38
+ * activates fine and then faults every job it starts (UV-15809). All files are
39
+ * placed in the content/ folder (no separate source folder like flow_files/).
35
40
  */
36
41
  export class CaseTool extends ProjectTool {
37
42
  private readonly _temporaryStorage: TemporaryStorageService;
@@ -79,6 +84,15 @@ export class CaseTool extends ProjectTool {
79
84
  this.logger.progress("Copying files...");
80
85
  await this.copyFiles(options.projectPath, contentFolder);
81
86
 
87
+ this.logger.progress("Compiling case plan to BPMN...");
88
+ const compileResult = await this.compileCasePlan(
89
+ options.projectPath,
90
+ contentFolder,
91
+ );
92
+ if (!compileResult.isSuccess) {
93
+ return compileResult;
94
+ }
95
+
82
96
  this.logger.progress("Creating operate.json file...");
83
97
  await this.createOperateFile(options, contentFolder);
84
98
 
@@ -175,6 +189,153 @@ export class CaseTool extends ProjectTool {
175
189
  }
176
190
  }
177
191
 
192
+ /**
193
+ * Compile `caseplan.json` into `content/caseplan.json.bpmn`.
194
+ *
195
+ * Runs after copyFiles on purpose: a stale `caseplan.json.bpmn` left in the
196
+ * project directory by an earlier `uip maestro case pack` is copied in
197
+ * first and then overwritten here, so an edited case plan can never ship
198
+ * against an old BPMN. Nothing is written back into the project directory —
199
+ * packing a solution does not mutate the user's source tree.
200
+ *
201
+ * The compiler is injected (see `case-bpmn-compiler.ts`). With none
202
+ * registered — a browser host, where `@uipath/case-schema` cannot run — the
203
+ * project has to bring its own compiled `.bpmn`.
204
+ */
205
+ private async compileCasePlan(
206
+ projectPath: string,
207
+ contentFolder: string,
208
+ ): Promise<ToolResult> {
209
+ const compile = getCaseBpmnCompiler();
210
+ const casePlanPath = Path.join(
211
+ projectPath,
212
+ CaseConstants.CasePlanFileName,
213
+ );
214
+
215
+ if (!compile || !(await this.fileSystem.exists(casePlanPath))) {
216
+ return this.checkEntryPointBpmnPresent(contentFolder);
217
+ }
218
+
219
+ const casePlan = await this.fileSystem.readFile(casePlanPath);
220
+ if (!casePlan || casePlan.length === 0) {
221
+ return ToolResult.error(
222
+ ToolErrorCodes.InternalError,
223
+ `'${CaseConstants.CasePlanFileName}' in ${projectPath} is empty, so there is nothing to compile into '${CaseConstants.CompiledBpmnFileName}'. Author the case plan, or re-scaffold the project with 'uip maestro case init'.`,
224
+ );
225
+ }
226
+
227
+ try {
228
+ const bpmnXml = await compile(new TextDecoder().decode(casePlan));
229
+ await this.fileSystem.writeFile(
230
+ Path.join(contentFolder, CaseConstants.CompiledBpmnFileName),
231
+ bpmnXml,
232
+ );
233
+ // A compile alone does not prove the package is coherent: the
234
+ // entry point could name a different file. Check what was declared.
235
+ return await this.checkEntryPointBpmnPresent(contentFolder);
236
+ } catch (error) {
237
+ const message =
238
+ error instanceof Error ? error.message : String(error);
239
+ this.logger.error(message);
240
+ return ToolResult.error(
241
+ ToolErrorCodes.InternalError,
242
+ `Failed to compile '${CaseConstants.CasePlanFileName}' into '${CaseConstants.CompiledBpmnFileName}': ${message}. Run 'uip maestro case validate ${projectPath}' to find the problem in the case plan, then pack again.`,
243
+ );
244
+ }
245
+ }
246
+
247
+ /**
248
+ * Verify every `.bpmn` `entry-points.json` names is actually in content/.
249
+ *
250
+ * This is the defect UV-15809 reported, checked mechanically: the entry
251
+ * point resolved to a file the package did not contain, so it deployed and
252
+ * activated cleanly and then faulted every job. Checking the declaration
253
+ * rather than a fixed filename covers both project shapes — a CLI project
254
+ * (`caseplan.json` -> `caseplan.json.bpmn`) and a Studio Web one
255
+ * (`<name>.stage.json` shipped with its compiled `<name>.stage.json.bpmn`)
256
+ * — and a stray `.bpmn` left behind by `uip case debug` cannot stand in for
257
+ * the one that is missing.
258
+ *
259
+ * No `entry-points.json` means nothing declares an entry point, so there is
260
+ * nothing to resolve and nothing to fail on.
261
+ */
262
+ private async checkEntryPointBpmnPresent(
263
+ contentFolder: string,
264
+ ): Promise<ToolResult> {
265
+ const referenced = await this.readEntryPointBpmnFiles(contentFolder);
266
+ if (referenced === null) {
267
+ return ToolResult.error(
268
+ ToolErrorCodes.InternalError,
269
+ `'${CaseConstants.EntryPointsFileName}' could not be read as JSON, so pack cannot check that the BPMN it declares is in the package. Fix or re-scaffold '${CaseConstants.EntryPointsFileName}', then pack again.`,
270
+ );
271
+ }
272
+ if (referenced.length === 0) {
273
+ return ToolResult.success();
274
+ }
275
+
276
+ const contentFiles = await this.fileSystem.readdir(contentFolder);
277
+ const missing = referenced.filter(
278
+ (file) => !contentFiles.includes(file),
279
+ );
280
+ if (missing.length === 0) {
281
+ return ToolResult.success();
282
+ }
283
+
284
+ // Only the CLI shape can be produced by packing: the missing file is
285
+ // compiled from `caseplan.json`. A Studio Web project ships its own
286
+ // `<name>.stage.json.bpmn`, and telling that user to author a
287
+ // `caseplan.json` their project type does not use is wrong.
288
+ const fix = missing.includes(CaseConstants.CompiledBpmnFileName)
289
+ ? `Author '${CaseConstants.CasePlanFileName}' so pack can compile it (see 'uip maestro case init'), then pack again.`
290
+ : `Add the missing file to the project, or point '${CaseConstants.EntryPointsFileName}' at the BPMN the project does ship, then pack again.`;
291
+
292
+ return ToolResult.error(
293
+ ToolErrorCodes.InternalError,
294
+ `'${CaseConstants.EntryPointsFileName}' points at ${missing.map((f) => `'content/${f}'`).join(", ")}, which the package does not contain, so it would deploy and activate and then fault every job. ${fix}`,
295
+ );
296
+ }
297
+
298
+ /**
299
+ * The `.bpmn` file names `entry-points.json` refers to. Entries look like
300
+ * `/content/caseplan.json.bpmn#<triggerId>`; `uip case debug` writes them
301
+ * without the `content/` prefix, so both forms are accepted.
302
+ *
303
+ * No file at all means nothing is declared, so the caller has nothing to
304
+ * check. A file that is there but cannot be read as JSON returns `null`:
305
+ * treating that as "nothing declared" would wave through the very package
306
+ * this check exists to stop, since the entry point it names is unknown.
307
+ */
308
+ private async readEntryPointBpmnFiles(
309
+ contentFolder: string,
310
+ ): Promise<string[] | null> {
311
+ const entryPointsPath = Path.join(
312
+ contentFolder,
313
+ CaseConstants.EntryPointsFileName,
314
+ );
315
+ if (!(await this.fileSystem.exists(entryPointsPath))) {
316
+ return [];
317
+ }
318
+
319
+ const raw = await this.fileSystem.readFile(entryPointsPath);
320
+ if (!raw || raw.length === 0) {
321
+ return null;
322
+ }
323
+
324
+ try {
325
+ const parsed = JSON.parse(new TextDecoder().decode(raw)) as {
326
+ entryPoints?: { filePath?: string }[];
327
+ };
328
+ const names = (parsed.entryPoints ?? [])
329
+ .map((entry) => entry.filePath ?? "")
330
+ .map((filePath) => filePath.split("#")[0])
331
+ .map((filePath) => filePath.split("/").pop() ?? "")
332
+ .filter((name) => name.endsWith(".bpmn"));
333
+ return [...new Set(names)];
334
+ } catch {
335
+ return null;
336
+ }
337
+ }
338
+
178
339
  /**
179
340
  * Create operate.json file if it doesn't already exist
180
341
  */
package/src/index.ts CHANGED
@@ -10,4 +10,8 @@ import { CaseToolFactory } from "./case-tool-factory.js";
10
10
 
11
11
  toolsFactoryRepository.registerProjectToolFactory(new CaseToolFactory());
12
12
 
13
+ export {
14
+ type CaseBpmnCompiler,
15
+ registerCaseBpmnCompiler,
16
+ } from "./case-bpmn-compiler.js";
13
17
  export { CaseToolFactory };
package/src/node.ts ADDED
@@ -0,0 +1,35 @@
1
+ // Node-only entry point: wires the real `caseplan.json` -> BPMN compiler into
2
+ // the Case packager. Kept out of `index.ts` because `@uipath/case-schema`
3
+ // requires Node built-ins and would break the browser build — see
4
+ // `case-bpmn-compiler.ts`.
5
+
6
+ import {
7
+ type CaseBpmnCompiler,
8
+ registerCaseBpmnCompiler,
9
+ } from "./case-bpmn-compiler.js";
10
+
11
+ /**
12
+ * `@uipath/case-schema` ships as a single 2.5 MB CommonJS bundle with no
13
+ * `exports` map, so nothing in it can be tree-shaken — importing one function
14
+ * costs the whole file. Behind `await import` it becomes its own lazy chunk,
15
+ * parsed only when a Case project is actually built, instead of loading with
16
+ * every `uip maestro -h`. `case-tool` keeps the same shape for its own
17
+ * `uip maestro case pack` path (`services/case-schema-loader.ts`).
18
+ */
19
+ const compileCasePlan: CaseBpmnCompiler = async (casePlanJson) => {
20
+ const { serializeCaseDiskJsonToBpmnAndRulesJson } = await import(
21
+ "@uipath/case-schema"
22
+ );
23
+ const { bpmnXml } =
24
+ await serializeCaseDiskJsonToBpmnAndRulesJson(casePlanJson);
25
+ return bpmnXml;
26
+ };
27
+
28
+ /**
29
+ * Register the Node `caseplan.json` -> BPMN compiler. Call it wherever the
30
+ * Case project tool factory is registered on Node — without it a Case project
31
+ * can only be packed from an already-compiled `.bpmn`.
32
+ */
33
+ export function registerNodeCaseBpmnCompiler(): void {
34
+ registerCaseBpmnCompiler(compileCasePlan);
35
+ }