@uipath/packager-tool-webapp 1.0.4

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.
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Constants used throughout the WebApp tool implementation
3
+ */
4
+ /**
5
+ * File names
6
+ */
7
+ export declare const PROJECT_JSON_FILE = "project.json";
8
+ /**
9
+ * Default bundle path if not specified in manifest
10
+ */
11
+ export declare const DEFAULT_BUNDLE_PATH = "source/dist";
12
+ /**
13
+ * Target runtime for operate.json
14
+ */
15
+ export declare const TARGET_RUNTIME = "Coded";
16
+ /**
17
+ * Default entry point type
18
+ */
19
+ export declare const DEFAULT_ENTRY_POINT_TYPE = "api";
20
+ /**
21
+ * Error messages
22
+ */
23
+ export declare const ERROR_MESSAGES: {
24
+ readonly MANIFEST_NOT_FOUND: (file: string) => string;
25
+ readonly PROJECT_JSON_FOUND: "project.json found in WebApp project. The WebApp tool only supports Coded web apps without project.json.";
26
+ readonly MANIFEST_LOAD_FAILED: (file: string) => string;
27
+ readonly BUNDLE_NOT_FOUND: (path: string) => string;
28
+ readonly BUNDLE_NOT_DIRECTORY: (path: string) => string;
29
+ readonly BUILD_NOT_SUPPORTED: "Build execution (isCompiled=false) is not yet supported. Please build the project manually and set isCompiled=true.";
30
+ readonly VALIDATION_FAILED: (context: string) => string;
31
+ readonly PACKING_FAILED: (context: string) => string;
32
+ readonly PACKAGE_NAME_REQUIRED: "Package name is required";
33
+ readonly PACKAGE_VERSION_REQUIRED: "Package version is required";
34
+ readonly PROJECT_PATH_REQUIRED: "Project path is required";
35
+ readonly OUTPUT_PATH_REQUIRED: "Output path is required";
36
+ };
@@ -0,0 +1,2 @@
1
+ export { WebAppTool } from "./webapp-tool.js";
2
+ export { WebAppToolFactory } from "./webapp-tool-factory.js";
package/dist/index.js ADDED
@@ -0,0 +1,466 @@
1
+ // src/index.ts
2
+ import { toolsFactoryRepository } from "@uipath/solutionpackager-tool-core";
3
+
4
+ // src/webapp-tool-factory.ts
5
+ import {
6
+ ProjectTypes as ProjectTypes2
7
+ } from "@uipath/solutionpackager-tool-core";
8
+
9
+ // src/webapp-tool.ts
10
+ import {
11
+ Path as Path4,
12
+ ProjectTool,
13
+ TemporaryStorageService,
14
+ ToolErrorCodes,
15
+ ToolResult
16
+ } from "@uipath/solutionpackager-tool-core";
17
+
18
+ // src/constants.ts
19
+ var PROJECT_JSON_FILE = "project.json";
20
+ var DEFAULT_BUNDLE_PATH = "source/dist";
21
+ var TARGET_RUNTIME = "Coded";
22
+ var DEFAULT_ENTRY_POINT_TYPE = "api";
23
+ var ERROR_MESSAGES = {
24
+ MANIFEST_NOT_FOUND: (file) => `WebApp manifest not found: ${file}. This file is required for WebApp projects.`,
25
+ PROJECT_JSON_FOUND: "project.json found in WebApp project. The WebApp tool only supports Coded web apps without project.json.",
26
+ MANIFEST_LOAD_FAILED: (file) => `Failed to load or parse ${file}`,
27
+ BUNDLE_NOT_FOUND: (path) => `Compiled bundle not found at ${path}. Ensure the project is built before packing.`,
28
+ BUNDLE_NOT_DIRECTORY: (path) => `Bundle path ${path} exists but is not a directory.`,
29
+ BUILD_NOT_SUPPORTED: "Build execution (isCompiled=false) is not yet supported. Please build the project manually and set isCompiled=true.",
30
+ VALIDATION_FAILED: (context) => `Validation failed: ${context}`,
31
+ PACKING_FAILED: (context) => `An error occurred while packing WebApp project: ${context}`,
32
+ PACKAGE_NAME_REQUIRED: "Package name is required",
33
+ PACKAGE_VERSION_REQUIRED: "Package version is required",
34
+ PROJECT_PATH_REQUIRED: "Project path is required",
35
+ OUTPUT_PATH_REQUIRED: "Output path is required"
36
+ };
37
+
38
+ // src/models/webapp-manifest.ts
39
+ var WebAppVariantType;
40
+ ((WebAppVariantType2) => {
41
+ WebAppVariantType2["Coded"] = "Coded";
42
+ WebAppVariantType2["JS"] = "JS";
43
+ })(WebAppVariantType ||= {});
44
+ var WEBAPP_MANIFEST_FILE_NAME = "webAppManifest.json";
45
+
46
+ // src/strategies/coded-app-strategy.ts
47
+ import {
48
+ NugetConstants,
49
+ NugetPackager,
50
+ Path as Path2,
51
+ ProjectTypes,
52
+ TargetFramework
53
+ } from "@uipath/solutionpackager-tool-core";
54
+
55
+ // src/utils/fs-helpers.ts
56
+ import { Path } from "@uipath/solutionpackager-tool-core";
57
+ async function copyDirectoryAsync(fileSystem, sourcePath, destinationPath) {
58
+ await fileSystem.mkdir(destinationPath);
59
+ const entries = await fileSystem.readdir(sourcePath);
60
+ for (const entry of entries) {
61
+ const sourceEntry = Path.join(sourcePath, entry);
62
+ const destEntry = Path.join(destinationPath, entry);
63
+ const stat = await fileSystem.stat(sourceEntry);
64
+ if (stat?.isDirectory()) {
65
+ await copyDirectoryAsync(fileSystem, sourceEntry, destEntry);
66
+ } else if (stat?.isFile()) {
67
+ const content = await fileSystem.readFile(sourceEntry);
68
+ if (content) {
69
+ await fileSystem.writeFile(destEntry, content);
70
+ }
71
+ }
72
+ }
73
+ }
74
+
75
+ // src/strategies/coded-app-strategy.ts
76
+ class CodedAppStrategy {
77
+ fileSystem;
78
+ constructor(fileSystem) {
79
+ this.fileSystem = fileSystem;
80
+ }
81
+ async validateAsync(args) {
82
+ const { projectPath, manifest, logger } = args;
83
+ const typed = manifest;
84
+ let bundlePath = typed.config?.bundlePath;
85
+ if (typeof bundlePath !== "string" || bundlePath.length === 0) {
86
+ bundlePath = DEFAULT_BUNDLE_PATH;
87
+ }
88
+ const isCompiled = typed.config?.isCompiled ?? true;
89
+ if (isCompiled) {
90
+ const fullBundlePath = Path2.join(projectPath, bundlePath);
91
+ const exists = await this.fileSystem.exists(fullBundlePath);
92
+ if (!exists) {
93
+ const message = ERROR_MESSAGES.BUNDLE_NOT_FOUND(fullBundlePath);
94
+ if (logger?.warn) {
95
+ logger.warn(message);
96
+ } else {
97
+ logger?.info(`Warning: ${message}`);
98
+ }
99
+ }
100
+ }
101
+ }
102
+ async packageAsync(args) {
103
+ const { projectPath, manifest, outputPath, packageInfo, logger } = args;
104
+ logger?.info(`Packaging Coded variant: ${packageInfo.id}@${packageInfo.version}`);
105
+ let bundlePath = manifest.config?.bundlePath;
106
+ if (typeof bundlePath !== "string" || bundlePath.length === 0) {
107
+ bundlePath = DEFAULT_BUNDLE_PATH;
108
+ }
109
+ const isCompiled = manifest.config?.isCompiled ?? true;
110
+ const fullBundlePath = Path2.join(projectPath, bundlePath);
111
+ if (isCompiled) {
112
+ logger?.progress("Validating compiled bundle...");
113
+ const bundleExists = await this.fileSystem.exists(fullBundlePath);
114
+ if (!bundleExists) {
115
+ throw new Error(ERROR_MESSAGES.BUNDLE_NOT_FOUND(fullBundlePath));
116
+ }
117
+ const bundleStat = await this.fileSystem.stat(fullBundlePath);
118
+ if (!bundleStat?.isDirectory()) {
119
+ throw new Error(ERROR_MESSAGES.BUNDLE_NOT_DIRECTORY(fullBundlePath));
120
+ }
121
+ } else {
122
+ logger?.info("Build mode (isCompiled=false) is not yet implemented in v1.");
123
+ throw new Error(ERROR_MESSAGES.BUILD_NOT_SUPPORTED);
124
+ }
125
+ const localBuildFolder = Path2.join(outputPath, NugetConstants.OutputFolderName);
126
+ const contentFolder = Path2.join(localBuildFolder, NugetConstants.ContentFolderName);
127
+ await this.fileSystem.mkdir(contentFolder);
128
+ try {
129
+ logger?.progress("Copying bundle to content folder...");
130
+ await copyDirectoryAsync(this.fileSystem, fullBundlePath, contentFolder);
131
+ logger?.progress("Preparing metadata files...");
132
+ await this.prepareMetadataFiles(localBuildFolder, contentFolder, packageInfo, manifest, projectPath);
133
+ logger?.progress("Creating NuGet package...");
134
+ const nupkgFileName = `${packageInfo.id}.${packageInfo.version}.nupkg`;
135
+ const nupkgPath = Path2.join(outputPath, nupkgFileName);
136
+ const packager = new NugetPackager(this.fileSystem);
137
+ const result = await packager.packAsync(localBuildFolder, packageInfo, nupkgPath);
138
+ logger?.info(`Package created successfully: ${result.outputPath}`);
139
+ return result.outputPath;
140
+ } finally {
141
+ try {
142
+ await this.fileSystem.rm(localBuildFolder);
143
+ } catch (cleanupError) {
144
+ logger?.error(`Failed to cleanup build folder: ${cleanupError instanceof Error ? cleanupError.message : String(cleanupError)}`);
145
+ }
146
+ }
147
+ }
148
+ async prepareMetadataFiles(_localBuildFolder, contentFolder, packageInfo, _manifest, projectPath) {
149
+ let mainFile = "index.html";
150
+ const indexHtmlPath = Path2.join(contentFolder, "index.html");
151
+ const indexHtmlExists = await this.fileSystem.exists(indexHtmlPath);
152
+ if (!indexHtmlExists) {
153
+ const possibleEntries = ["index.html", "main.html", "app.html"];
154
+ for (const entry of possibleEntries) {
155
+ const entryPath = Path2.join(contentFolder, entry);
156
+ if (await this.fileSystem.exists(entryPath)) {
157
+ mainFile = entry;
158
+ break;
159
+ }
160
+ }
161
+ }
162
+ const operatePath = Path2.join(contentFolder, NugetConstants.OperateFileName);
163
+ const operateModel = {
164
+ projectId: packageInfo.id,
165
+ main: mainFile,
166
+ contentType: ProjectTypes.WebApp,
167
+ targetFramework: TargetFramework.Portable,
168
+ targetRuntime: TARGET_RUNTIME,
169
+ runtimeOptions: {
170
+ requiresUserInteraction: false,
171
+ isAttended: false
172
+ }
173
+ };
174
+ const operateJson = JSON.stringify(operateModel, null, 2);
175
+ await this.fileSystem.writeFile(operatePath, operateJson);
176
+ const manifestSourcePath = Path2.join(projectPath, WEBAPP_MANIFEST_FILE_NAME);
177
+ const manifestDestPath = Path2.join(contentFolder, WEBAPP_MANIFEST_FILE_NAME);
178
+ const manifestExists = await this.fileSystem.exists(manifestSourcePath);
179
+ if (manifestExists) {
180
+ const manifestContent = await this.fileSystem.readFile(manifestSourcePath);
181
+ if (manifestContent) {
182
+ await this.fileSystem.writeFile(manifestDestPath, manifestContent);
183
+ }
184
+ }
185
+ const uipathJsonSourcePath = Path2.join(projectPath, "uipath.json");
186
+ const uipathJsonDestPath = Path2.join(contentFolder, "uipath.json");
187
+ const uipathJsonExists = await this.fileSystem.exists(uipathJsonSourcePath);
188
+ if (uipathJsonExists) {
189
+ const uipathJsonContent = await this.fileSystem.readFile(uipathJsonSourcePath);
190
+ if (uipathJsonContent) {
191
+ await this.fileSystem.writeFile(uipathJsonDestPath, uipathJsonContent);
192
+ }
193
+ }
194
+ const bindingsPath = Path2.join(contentFolder, "bindings.json");
195
+ const bindingsExists = await this.fileSystem.exists(bindingsPath);
196
+ if (!bindingsExists) {
197
+ const bindingsJson = JSON.stringify({
198
+ version: "1.0",
199
+ resources: []
200
+ }, null, 2);
201
+ await this.fileSystem.writeFile(bindingsPath, bindingsJson);
202
+ }
203
+ const bindingsV2Path = Path2.join(contentFolder, "bindings_v2.json");
204
+ const bindingsV2Exists = await this.fileSystem.exists(bindingsV2Path);
205
+ if (!bindingsV2Exists) {
206
+ const bindingsV2Json = JSON.stringify({
207
+ version: "2.0",
208
+ resources: []
209
+ }, null, 2);
210
+ await this.fileSystem.writeFile(bindingsV2Path, bindingsV2Json);
211
+ }
212
+ const entryPointsPath = Path2.join(contentFolder, "entry-points.json");
213
+ const projectEntryPointsPath = Path2.join(projectPath, "entry-points.json");
214
+ let entryPointsContent;
215
+ const projectEntryPointsExists = await this.fileSystem.exists(projectEntryPointsPath);
216
+ if (projectEntryPointsExists) {
217
+ const entryPointsData = await this.fileSystem.readFile(projectEntryPointsPath);
218
+ if (entryPointsData) {
219
+ entryPointsContent = new TextDecoder().decode(entryPointsData);
220
+ } else {
221
+ entryPointsContent = this.createDefaultEntryPoints(mainFile);
222
+ }
223
+ } else {
224
+ entryPointsContent = this.createDefaultEntryPoints(mainFile);
225
+ }
226
+ await this.fileSystem.writeFile(entryPointsPath, entryPointsContent);
227
+ const packageDescriptorPath = Path2.join(contentFolder, NugetConstants.PackageDescriptorFileName);
228
+ const packageDescriptor = {
229
+ files: {
230
+ [NugetConstants.OperateFileName]: Path2.join(NugetConstants.ContentFolderName, NugetConstants.OperateFileName),
231
+ "entry-points.json": Path2.join(NugetConstants.ContentFolderName, "entry-points.json"),
232
+ "bindings.json": Path2.join(NugetConstants.ContentFolderName, "bindings_v2.json")
233
+ }
234
+ };
235
+ const packageDescriptorJson = JSON.stringify(packageDescriptor, null, 2);
236
+ await this.fileSystem.writeFile(packageDescriptorPath, packageDescriptorJson);
237
+ }
238
+ createDefaultEntryPoints(mainFile) {
239
+ const uniqueId = this.generateUniqueId();
240
+ const entryPoints = {
241
+ $schema: "https://cloud.uipath.com/draft/2024-12/entry-point",
242
+ $id: "entry-points-doc-001",
243
+ entryPoints: [
244
+ {
245
+ filePath: mainFile,
246
+ uniqueId,
247
+ type: DEFAULT_ENTRY_POINT_TYPE,
248
+ input: {
249
+ amount: { type: "integer" },
250
+ id: { type: "string" }
251
+ },
252
+ output: {
253
+ status: { type: "string" }
254
+ }
255
+ }
256
+ ]
257
+ };
258
+ return JSON.stringify(entryPoints, null, 2);
259
+ }
260
+ generateUniqueId() {
261
+ const randomBytes = new Uint8Array(16);
262
+ if (typeof crypto !== "undefined" && crypto.getRandomValues) {
263
+ crypto.getRandomValues(randomBytes);
264
+ } else {
265
+ throw new Error("crypto.getRandomValues is not available");
266
+ }
267
+ randomBytes[6] = randomBytes[6] & 15 | 64;
268
+ randomBytes[8] = randomBytes[8] & 63 | 128;
269
+ const hex = Array.from(randomBytes).map((b) => b.toString(16).padStart(2, "0")).join("");
270
+ return [
271
+ hex.substring(0, 8),
272
+ hex.substring(8, 12),
273
+ hex.substring(12, 16),
274
+ hex.substring(16, 20),
275
+ hex.substring(20, 32)
276
+ ].join("-");
277
+ }
278
+ }
279
+
280
+ // src/strategies/variant-strategy-factory.ts
281
+ class VariantStrategyFactory {
282
+ static createStrategy(manifest, fileSystem) {
283
+ const variant = manifest.type;
284
+ switch (variant) {
285
+ case "Coded" /* Coded */:
286
+ return new CodedAppStrategy(fileSystem);
287
+ case "JS" /* JS */:
288
+ throw new Error("JS variant is not yet implemented. Only Coded is supported in v1.");
289
+ default:
290
+ throw new Error(`Unknown WebApp variant: ${manifest.type}. Supported variants: ${Object.values(WebAppVariantType).join(", ")}`);
291
+ }
292
+ }
293
+ }
294
+
295
+ // src/utils/manifest-loader.ts
296
+ import { Path as Path3 } from "@uipath/solutionpackager-tool-core";
297
+ async function loadWebAppManifest(fileSystem, projectPath) {
298
+ const manifestPath = Path3.join(projectPath, WEBAPP_MANIFEST_FILE_NAME);
299
+ const exists = await fileSystem.exists(manifestPath);
300
+ if (!exists) {
301
+ return null;
302
+ }
303
+ const content = await fileSystem.readFile(manifestPath);
304
+ if (!content) {
305
+ return null;
306
+ }
307
+ try {
308
+ const text = new TextDecoder().decode(content);
309
+ const manifest = JSON.parse(text);
310
+ return manifest;
311
+ } catch (error) {
312
+ throw new Error(`Failed to parse ${WEBAPP_MANIFEST_FILE_NAME}: ${error instanceof Error ? error.message : String(error)}`);
313
+ }
314
+ }
315
+
316
+ // src/webapp-tool.ts
317
+ class WebAppTool extends ProjectTool {
318
+ _temporaryStorage;
319
+ _tempBuildFolder = null;
320
+ constructor(fileSystem, logger) {
321
+ super(fileSystem, logger);
322
+ this._temporaryStorage = new TemporaryStorageService(fileSystem);
323
+ }
324
+ async restoreAsync(_options, _cancellationToken) {
325
+ this.logger.info("Restore operation is not required for WebApp projects");
326
+ return ToolResult.success();
327
+ }
328
+ async validateAsync(options, _cancellationToken) {
329
+ if (!options.projectPath) {
330
+ return this.handleError(new Error(ERROR_MESSAGES.PROJECT_PATH_REQUIRED), "Validation");
331
+ }
332
+ try {
333
+ this.logger.info("Validating WebApp project...");
334
+ let manifest;
335
+ let strategy;
336
+ try {
337
+ const prepared = await this.getManifestAndStrategy(options.projectPath);
338
+ manifest = prepared.manifest;
339
+ strategy = prepared.strategy;
340
+ } catch (error) {
341
+ return this.handleError(error, "Validation");
342
+ }
343
+ try {
344
+ if (strategy.validateAsync) {
345
+ await strategy.validateAsync({
346
+ fileSystem: this.fileSystem,
347
+ projectPath: options.projectPath,
348
+ manifest,
349
+ logger: this.createStrategyLogger()
350
+ });
351
+ }
352
+ } catch (error) {
353
+ return this.handleError(error, "Validation");
354
+ }
355
+ this.logger.info("WebApp project validation completed");
356
+ return ToolResult.success();
357
+ } catch (error) {
358
+ return this.handleError(error, "Validation");
359
+ }
360
+ }
361
+ async buildAsync(_options, _cancellationToken) {
362
+ this.logger.info("Build operation for WebApp is lightweight (metadata preparation only)");
363
+ return ToolResult.success();
364
+ }
365
+ async packAsync(options, _cancellationToken) {
366
+ if (!options.projectPath) {
367
+ return this.handleError(new Error(ERROR_MESSAGES.PROJECT_PATH_REQUIRED), "Packing");
368
+ }
369
+ if (!options.outputPath) {
370
+ return this.handleError(new Error(ERROR_MESSAGES.OUTPUT_PATH_REQUIRED), "Packing");
371
+ }
372
+ if (!options.package?.id) {
373
+ return this.handleError(new Error(ERROR_MESSAGES.PACKAGE_NAME_REQUIRED), "Packing");
374
+ }
375
+ if (!options.package?.version) {
376
+ return this.handleError(new Error(ERROR_MESSAGES.PACKAGE_VERSION_REQUIRED), "Packing");
377
+ }
378
+ try {
379
+ this.logger.info(`Packing WebApp project: ${options.package.id}@${options.package.version}`);
380
+ let manifest;
381
+ let strategy;
382
+ try {
383
+ const prepared = await this.getManifestAndStrategy(options.projectPath);
384
+ manifest = prepared.manifest;
385
+ strategy = prepared.strategy;
386
+ } catch (error) {
387
+ return this.handleError(error, `Packing WebApp project '${options.package.id}'`);
388
+ }
389
+ const nupkgPath = await strategy.packageAsync({
390
+ fileSystem: this.fileSystem,
391
+ projectPath: options.projectPath,
392
+ manifest,
393
+ outputPath: options.outputPath,
394
+ packageInfo: options.package,
395
+ logger: this.createStrategyLogger()
396
+ });
397
+ this.logger.info(`WebApp package created successfully: ${nupkgPath}`);
398
+ return new ToolResult(ToolErrorCodes.Success, "done", [nupkgPath]);
399
+ } catch (error) {
400
+ return this.handleError(error, `Packing WebApp project '${options.package.id}'`);
401
+ }
402
+ }
403
+ async dispose() {
404
+ this.logger.info("Disposing WebApp Tool");
405
+ try {
406
+ if (this._tempBuildFolder) {
407
+ await this.fileSystem.rm(this._tempBuildFolder);
408
+ this._tempBuildFolder = null;
409
+ }
410
+ await this._temporaryStorage.cleanup();
411
+ } catch {}
412
+ }
413
+ async getManifestAndStrategy(projectPath) {
414
+ const manifestPath = Path4.join(projectPath, WEBAPP_MANIFEST_FILE_NAME);
415
+ const manifestExists = await this.fileSystem.exists(manifestPath);
416
+ if (!manifestExists) {
417
+ throw new Error(ERROR_MESSAGES.MANIFEST_NOT_FOUND(WEBAPP_MANIFEST_FILE_NAME));
418
+ }
419
+ const projectJsonPath = Path4.join(projectPath, PROJECT_JSON_FILE);
420
+ if (await this.fileSystem.exists(projectJsonPath)) {
421
+ throw new Error(ERROR_MESSAGES.PROJECT_JSON_FOUND);
422
+ }
423
+ const manifest = await loadWebAppManifest(this.fileSystem, projectPath);
424
+ if (!manifest) {
425
+ throw new Error(ERROR_MESSAGES.MANIFEST_LOAD_FAILED(WEBAPP_MANIFEST_FILE_NAME));
426
+ }
427
+ const strategy = VariantStrategyFactory.createStrategy(manifest, this.fileSystem);
428
+ return { manifest, strategy };
429
+ }
430
+ handleError(error, context) {
431
+ const errorMessage = error instanceof Error ? error.message : String(error);
432
+ this.logger.error(`${context}: ${errorMessage}`);
433
+ let userMessage;
434
+ if (context === "Validation") {
435
+ userMessage = ERROR_MESSAGES.VALIDATION_FAILED(errorMessage);
436
+ } else if (context.startsWith("Packing")) {
437
+ userMessage = ERROR_MESSAGES.PACKING_FAILED(errorMessage);
438
+ } else {
439
+ userMessage = errorMessage;
440
+ }
441
+ return ToolResult.error(ToolErrorCodes.InternalError, userMessage);
442
+ }
443
+ createStrategyLogger() {
444
+ return {
445
+ info: (msg) => this.logger.info(msg),
446
+ error: (msg) => this.logger.error(msg),
447
+ progress: (msg) => this.logger.progress(msg),
448
+ warn: (msg) => this.logger.warn(msg)
449
+ };
450
+ }
451
+ }
452
+
453
+ // src/webapp-tool-factory.ts
454
+ class WebAppToolFactory {
455
+ supportedTypes = [ProjectTypes2.AppV2];
456
+ async createAsync(logger, fileSystem) {
457
+ return new WebAppTool(fileSystem, logger);
458
+ }
459
+ }
460
+
461
+ // src/index.ts
462
+ toolsFactoryRepository.registerProjectToolFactory(new WebAppToolFactory);
463
+ export {
464
+ WebAppToolFactory,
465
+ WebAppTool
466
+ };
@@ -0,0 +1,39 @@
1
+ export declare enum WebAppVariantType {
2
+ Coded = "Coded",
3
+ JS = "JS"
4
+ }
5
+ /** @public */
6
+ export declare enum AppSubType {
7
+ /** Coded app subtype that is registered with Solutions */
8
+ Coded = "Coded",
9
+ /** CodedAction app subtype that is registered with Solutions */
10
+ CodedAction = "CodedAction"
11
+ }
12
+ /**
13
+ * Variant-specific configurations
14
+ */
15
+ export interface CodedAppConfig {
16
+ /** If true: pack only; If false: build → pack (future) */
17
+ isCompiled?: boolean;
18
+ /** Compiled bundle folder location (default: dist/) */
19
+ bundlePath?: string;
20
+ /** Optional build command for future scenarios */
21
+ buildCommand?: string;
22
+ isActionApp?: boolean;
23
+ }
24
+ export interface JsConfig {
25
+ [key: string]: unknown;
26
+ }
27
+ /** Map each variant to its specific config type */
28
+ type ManifestConfigMap = {
29
+ [WebAppVariantType.Coded]: CodedAppConfig;
30
+ [WebAppVariantType.JS]: JsConfig;
31
+ };
32
+ /** WebApp manifest type parameterized by variant */
33
+ export type WebAppManifest<T extends WebAppVariantType = WebAppVariantType> = {
34
+ type: T;
35
+ solutionResourceSubType: string;
36
+ config?: ManifestConfigMap[T];
37
+ };
38
+ export declare const WEBAPP_MANIFEST_FILE_NAME = "webAppManifest.json";
39
+ export {};
@@ -0,0 +1,37 @@
1
+ import type { IFileSystem } from "@uipath/solutionpackager-tool-core";
2
+ import type { WebAppManifest } from "../models/webapp-manifest.js";
3
+ import type { PackageArgs, VariantStrategy } from "./variant-strategy.js";
4
+ /**
5
+ * Coded app strategy for Coded variant
6
+ * Supports isCompiled=true (v1) and isCompiled=false (future)
7
+ */
8
+ export declare class CodedAppStrategy implements VariantStrategy {
9
+ private readonly fileSystem;
10
+ constructor(fileSystem: IFileSystem);
11
+ /**
12
+ * Variant-specific validation: warn if compiled bundle is expected but missing
13
+ */
14
+ validateAsync(args: {
15
+ fileSystem: IFileSystem;
16
+ projectPath: string;
17
+ manifest: WebAppManifest;
18
+ logger?: {
19
+ info: (message: string) => void;
20
+ error: (message: string) => void;
21
+ progress: (message: string) => void;
22
+ };
23
+ }): Promise<void>;
24
+ packageAsync(args: PackageArgs): Promise<string>;
25
+ /**
26
+ * Prepare metadata files (operate.json, package-descriptor.json, bindings.json, bindings_v2.json, entry-points.json)
27
+ */
28
+ private prepareMetadataFiles;
29
+ /**
30
+ * Create default entry-points.json structure
31
+ */
32
+ private createDefaultEntryPoints;
33
+ /**
34
+ * Generate a cryptographically secure unique ID (UUID v4-like format)
35
+ */
36
+ private generateUniqueId;
37
+ }
@@ -0,0 +1,16 @@
1
+ import type { IFileSystem } from "@uipath/solutionpackager-tool-core";
2
+ import type { WebAppManifest } from "../models/webapp-manifest.js";
3
+ import type { VariantStrategy } from "./variant-strategy.js";
4
+ /**
5
+ * Factory for creating variant-specific packaging strategies
6
+ */
7
+ export declare class VariantStrategyFactory {
8
+ /**
9
+ * Create a strategy instance based on manifest type
10
+ * @param manifest - WebApp manifest
11
+ * @param fileSystem - File system instance
12
+ * @returns Strategy instance
13
+ * @throws Error if variant is not supported
14
+ */
15
+ static createStrategy(manifest: WebAppManifest, fileSystem: IFileSystem): VariantStrategy;
16
+ }
@@ -0,0 +1,57 @@
1
+ import type { IFileSystem, NugetPackageInfo } from "@uipath/solutionpackager-tool-core";
2
+ import type { WebAppManifest } from "../models/webapp-manifest.js";
3
+ /**
4
+ * Arguments for packaging operation
5
+ */
6
+ export interface PackageArgs {
7
+ /**
8
+ * File system instance
9
+ */
10
+ fileSystem: IFileSystem;
11
+ /**
12
+ * Project root path
13
+ */
14
+ projectPath: string;
15
+ /**
16
+ * Parsed webApp manifest
17
+ */
18
+ manifest: WebAppManifest;
19
+ /**
20
+ * Output directory path
21
+ */
22
+ outputPath: string;
23
+ /**
24
+ * NuGet package information
25
+ */
26
+ packageInfo: NugetPackageInfo;
27
+ /**
28
+ * Logger instance (optional, for strategy-specific logging)
29
+ */
30
+ logger?: {
31
+ info: (message: string) => void;
32
+ error: (message: string) => void;
33
+ progress: (message: string) => void;
34
+ warn?: (message: string) => void;
35
+ };
36
+ }
37
+ /**
38
+ * Strategy interface for different WebApp variant packaging
39
+ */
40
+ export interface VariantStrategy {
41
+ /**
42
+ * Package the WebApp according to variant-specific logic
43
+ * @param args - Packaging arguments
44
+ * @returns Path to the created .nupkg file
45
+ */
46
+ packageAsync(args: PackageArgs): Promise<string>;
47
+ /**
48
+ * Optional variant-specific validation step invoked during tool validation.
49
+ * Implementations may warn or throw on invalid configuration.
50
+ */
51
+ validateAsync?(args: {
52
+ fileSystem: PackageArgs["fileSystem"];
53
+ projectPath: string;
54
+ manifest: PackageArgs["manifest"];
55
+ logger?: PackageArgs["logger"];
56
+ }): Promise<void>;
57
+ }
@@ -0,0 +1,9 @@
1
+ import type { IFileSystem } from "@uipath/solutionpackager-tool-core";
2
+ /**
3
+ * Copy directory recursively from source to destination
4
+ */
5
+ export declare function copyDirectoryAsync(fileSystem: IFileSystem, sourcePath: string, destinationPath: string): Promise<void>;
6
+ /**
7
+ * Find .nupkg file in a directory
8
+ */
9
+ export declare function findNupkgInFolder(fileSystem: IFileSystem, directoryPath: string): Promise<string | null>;
@@ -0,0 +1,6 @@
1
+ import type { IFileSystem } from "@uipath/solutionpackager-tool-core";
2
+ import type { WebAppManifest } from "../models/webapp-manifest.js";
3
+ /**
4
+ * Load and parse webAppManifest.json from project path
5
+ */
6
+ export declare function loadWebAppManifest(fileSystem: IFileSystem, projectPath: string): Promise<WebAppManifest | null>;
@@ -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 WebApp project tools
4
+ */
5
+ export declare class WebAppToolFactory implements IProjectToolFactory {
6
+ readonly supportedTypes: readonly ProjectType[];
7
+ createAsync(logger: IToolLogger, fileSystem: IFileSystem): Promise<ProjectTool>;
8
+ }