@uipath/flow-tool 1.204.0 → 1.205.0-preview.258

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.
Files changed (178) hide show
  1. package/README.md +9 -9
  2. package/dist/THIRD-PARTY-NOTICES.md +39 -15
  3. package/dist/{authoring-bppe07p0.js → authoring-e1k40hyw.js} +6 -5
  4. package/dist/{binding-service-xwgsn35p.js → binding-service-pdtxvvt8.js} +38 -30
  5. package/dist/{connector-service-r0w8ztas.js → connector-service-pm9hfmsv.js} +224 -47
  6. package/dist/de-UZI7FJDO-awjpqfz0.js +200 -0
  7. package/dist/{de-MUJPA4EB-dpg7t2rw.js → de-UZI7FJDO-mwvc4cxe.js} +29 -2
  8. package/dist/{de-FGHEJRCI-rv513mfh.js → de-WLW6KWOJ-2qnsqdtw.js} +238 -31
  9. package/dist/debug-conversation-trigger-xsm3ycqx.js +30 -0
  10. package/dist/{debug-http-client-p4kf38yt.js → debug-http-client-yqjzsnhw.js} +5 -4
  11. package/dist/{debug-service-893erynq.js → debug-service-nra3n02y.js} +6 -5
  12. package/dist/{edge-service-yzsfw4bs.js → edge-service-mddnjwb0.js} +16 -12
  13. package/dist/{embedded-file-reader-v8c2yj2a.js → embedded-file-reader-r66242ey.js} +2 -2
  14. package/dist/en-EJCBA3LK-0wb3b1xy.js +146 -0
  15. package/dist/{en-FBPVNKFN-dqt573xn.js → en-EJCBA3LK-dtpdghgj.js} +12 -4
  16. package/dist/{en-BWGKA5OE-1qkvb9rn.js → en-M7GQYBV2-5nfmpnfz.js} +88 -6
  17. package/dist/{es-7SE7HX2X-8yh1aj2y.js → es-4UBUTCQA-m1ytpyx2.js} +29 -2
  18. package/dist/es-4UBUTCQA-t7hsackg.js +200 -0
  19. package/dist/{es-KR3ZSNMP-84zphx0x.js → es-5THCNRFN-tqwyrdgy.js} +235 -28
  20. package/dist/{es-MX-2MYFZU7X-3rek4r73.js → es-MX-5RELIXKI-9jhqtddc.js} +29 -2
  21. package/dist/es-MX-5RELIXKI-jtjbcxbb.js +200 -0
  22. package/dist/{es-MX-XXZJGC4R-2mr8jtgm.js → es-MX-TWZBRAXK-gqd9swzw.js} +237 -30
  23. package/dist/filter-engine-7ep90g7f.js +11 -0
  24. package/dist/{flow-api-kjvpsxhw.js → flow-api-sat010z1.js} +16 -10
  25. package/dist/{flow-debug-service-dd10rg08.js → flow-debug-service-dw0d9cv7.js} +96 -58
  26. package/dist/{flow-eval-node-target-2ekp77s6.js → flow-eval-node-target-wttmdm4v.js} +17 -17
  27. package/dist/flow-eval-run-api-xdygjzfv.js +13 -0
  28. package/dist/{flow-eval-run-service-twzbmeq6.js → flow-eval-run-service-g09w4m9m.js} +73 -80
  29. package/dist/{flow-eval-service-ckwx7d5z.js → flow-eval-service-jfkz0tae.js} +167 -415
  30. package/dist/{flow-init-sdk-source-z9qx1zkt.js → flow-init-sdk-source-xvdvkq7d.js} +6 -5
  31. package/dist/{flow-init-service-m6swzk43.js → flow-init-service-5v6zwhas.js} +19 -15
  32. package/dist/{flow-io-tnrc53z6.js → flow-io-64tmj8n7.js} +15 -11
  33. package/dist/{flow-migrate-service-625gppk0.js → flow-migrate-service-bjxs35ac.js} +16 -12
  34. package/dist/{flow-pack-service-qdpvrmme.js → flow-pack-service-s75qhtn5.js} +47 -38
  35. package/dist/flow-validate-service-rbvgesrb.js +70 -0
  36. package/dist/{fr-Y6NPVODW-8vr1ja4b.js → fr-CERONSRC-edpxhbmb.js} +237 -30
  37. package/dist/{fr-MDFKNZ4C-h4a122k9.js → fr-VBM5WRC2-63z7w4mh.js} +29 -2
  38. package/dist/fr-VBM5WRC2-707ha692.js +200 -0
  39. package/dist/{governance-fetcher-zq8zmfjb.js → governance-fetcher-tw83p74c.js} +7 -6
  40. package/dist/{hitl-service-r19zvqsz.js → hitl-service-hgg9tr5j.js} +15 -11
  41. package/dist/{index-b8n7hv68.js → index-09mfatmh.js} +6 -5
  42. package/dist/{index-aaq9rwfv.js → index-1b2je9n2.js} +1088 -233
  43. package/dist/index-d090f35d.js +66 -0
  44. package/dist/{index-yj4xk2aw.js → index-dgdnbb2g.js} +7 -5
  45. package/dist/{index-ng2f77my.js → index-fyc0k5dd.js} +985 -617
  46. package/dist/{index-vrhcbxnk.js → index-nsn889vf.js} +6 -5
  47. package/dist/{index-2s8rmmw6.js → index-sqhbn7ew.js} +4 -4
  48. package/dist/{index-tnz5ks4t.js → index-wycgq0ff.js} +65 -2230
  49. package/dist/index.js +17 -14
  50. package/dist/init.js +19 -15
  51. package/dist/inline-entity-resolver-2qqf1635.js +45 -0
  52. package/dist/input-reader-n7kzdrev.js +12 -0
  53. package/dist/{ja-UTQEAP34-8e0q6swp.js → ja-43QL7CGO-c3q8gre9.js} +29 -2
  54. package/dist/ja-43QL7CGO-h6qfxfay.js +200 -0
  55. package/dist/{ja-Q5PXKJ2V-p4msxzjd.js → ja-U2MCNHGT-gz0ap1jk.js} +235 -28
  56. package/dist/{known-types-q6fcyq2e.js → known-types-3025scz1.js} +5 -5
  57. package/dist/ko-TLL6Z6CD-ag6gjynr.js +200 -0
  58. package/dist/{ko-AXCHW2OK-askct7f6.js → ko-TLL6Z6CD-wrt3n8a9.js} +29 -2
  59. package/dist/{ko-AYBDSRZG-41mdmsg1.js → ko-XAUYQWDR-zp81gjp4.js} +237 -30
  60. package/dist/{maestro-automate-entry-qak46eg0.js → maestro-automate-entry-6f9act3w.js} +2 -2
  61. package/dist/{node-ccwecksf.js → node-1wzjq3jb.js} +29 -15
  62. package/dist/{node-service-w8gsy23p.js → node-service-0hxtt2x6.js} +41 -30
  63. package/dist/{node-strategy-fdnkvq4a.js → node-strategy-1dmmhvf3.js} +1 -1
  64. package/dist/node-sync-service-n7r4ma3a.js +61 -0
  65. package/dist/{packager-tool-s4etvs59.js → packager-tool-0j8v36qh.js} +1 -1
  66. package/dist/packager-tool-10vc8pq4.js +2 -0
  67. package/dist/{packager-tool-pw6j69m5.js → packager-tool-445qgxdk.js} +1802 -378
  68. package/dist/packager-tool-4kr6g0zw.js +16 -0
  69. package/dist/packager-tool-4x7tzvv0.js +1176 -0
  70. package/dist/{packager-tool-86rhxbf1.js → packager-tool-5regytfc.js} +6 -4
  71. package/dist/{packager-tool-d88rqwk8.js → packager-tool-6z1hsm2h.js} +13 -5
  72. package/dist/{packager-tool-jaa5gcbv.js → packager-tool-71gqkgg6.js} +6 -6
  73. package/dist/packager-tool-7hw344bt.js +107 -0
  74. package/dist/{packager-tool-m8xtf5ej.js → packager-tool-8g5931fz.js} +7 -4
  75. package/dist/{packager-tool-h9tzz0qd.js → packager-tool-961vsbsc.js} +15 -10
  76. package/dist/{packager-tool-zzc2yp2h.js → packager-tool-99gban46.js} +172 -71
  77. package/dist/packager-tool-9era57c0.js +28 -0
  78. package/dist/packager-tool-9jxzgsxc.js +14 -0
  79. package/dist/{packager-tool-zxp4hya4.js → packager-tool-a5afh1dc.js} +34 -13
  80. package/dist/{packager-tool-02f63a08.js → packager-tool-apawc11t.js} +88 -762
  81. package/dist/{packager-tool-tf3d2y8z.js → packager-tool-aw9v0raw.js} +2 -2
  82. package/dist/{packager-tool-6y0f9qg5.js → packager-tool-b3k0mkke.js} +463 -327
  83. package/dist/packager-tool-cqtsj6yh.js +2 -0
  84. package/dist/{packager-tool-5nqhxb9e.js → packager-tool-dwd6cc01.js} +16110 -13031
  85. package/dist/{packager-tool-t605qewm.js → packager-tool-dxgrhfq5.js} +2 -2
  86. package/dist/{packager-tool-awkq26v0.js → packager-tool-e7kvq8hf.js} +5 -3
  87. package/dist/packager-tool-fc1xdt3y.js +35 -0
  88. package/dist/{packager-tool-3dc9gz35.js → packager-tool-frjt46rb.js} +1 -1
  89. package/dist/{packager-tool-cn7e7cx2.js → packager-tool-gcap41av.js} +668 -57
  90. package/dist/packager-tool-hj5x3p8g.js +23 -0
  91. package/dist/{packager-tool-k91rd9nx.js → packager-tool-hvgn6t66.js} +6 -24
  92. package/dist/{packager-tool-w5a1hhyj.js → packager-tool-hxyjn885.js} +13 -2
  93. package/dist/{packager-tool-hhy1gr2k.js → packager-tool-jgfzfqjm.js} +1 -1
  94. package/dist/{packager-tool-6h69pd2a.js → packager-tool-kn86394c.js} +127 -61
  95. package/dist/packager-tool-mgcz986r.js +143 -0
  96. package/dist/{packager-tool-3h2ktz6q.js → packager-tool-myhbp761.js} +11 -1
  97. package/dist/{packager-tool-hp5vnk8p.js → packager-tool-ndev7vbj.js} +13 -13
  98. package/dist/{packager-tool-dynm8fz9.js → packager-tool-nj4vcnq9.js} +20 -8
  99. package/dist/{packager-tool-ayc9nhpa.js → packager-tool-nk16zaz3.js} +519 -437
  100. package/dist/{packager-tool-vzbttaje.js → packager-tool-nts5rrch.js} +5 -6
  101. package/dist/{packager-tool-vbfz8k7w.js → packager-tool-p8gab24q.js} +52 -32
  102. package/dist/{packager-tool-stq8800d.js → packager-tool-pacrqxv2.js} +17 -4
  103. package/dist/{packager-tool-7q6z6npd.js → packager-tool-pcvhcn2k.js} +93 -11
  104. package/dist/packager-tool-phw8ydjx.js +331 -0
  105. package/dist/packager-tool-qcqb9hf8.js +26 -0
  106. package/dist/{packager-tool-n89vrpex.js → packager-tool-skcjythd.js} +10907 -25608
  107. package/dist/{packager-tool-1ca047de.js → packager-tool-sqpesv2e.js} +12 -56
  108. package/dist/packager-tool-t7ahhaer.js +877 -0
  109. package/dist/{packager-tool-peawy22c.js → packager-tool-tqjfdpda.js} +53 -8
  110. package/dist/{packager-tool-y8egb0fa.js → packager-tool-wds3myef.js} +2573 -535
  111. package/dist/{packager-tool-5tjzg56t.js → packager-tool-wh660fny.js} +1 -1
  112. package/dist/{packager-tool-tyg399d6.js → packager-tool-wze74wyk.js} +74 -47
  113. package/dist/packager-tool-xj0agqpk.js +11 -0
  114. package/dist/packager-tool-xk78j7dz.js +1256 -0
  115. package/dist/{packager-tool-py93409h.js → packager-tool-ymma2s85.js} +2 -2
  116. package/dist/packager-tool-z0yxfhdj.js +40 -0
  117. package/dist/packager-tool.js +13 -10
  118. package/dist/{pt-BR-TKHNHMET-sn91xyq0.js → pt-BR-GNQNAAZ2-xadharv4.js} +237 -30
  119. package/dist/{pt-BR-Y6K6XHXK-mp3hwhw1.js → pt-BR-USP2T7GD-pedn77m1.js} +29 -2
  120. package/dist/pt-BR-USP2T7GD-rppy42ym.js +200 -0
  121. package/dist/{pt-3DIO5QWG-59b3f4bc.js → pt-RMIAKZB4-67enhx3m.js} +29 -2
  122. package/dist/pt-RMIAKZB4-t80exmp7.js +200 -0
  123. package/dist/{pt-ROXU257Y-2f6bxev4.js → pt-TO2DARY2-ftcce1bv.js} +237 -30
  124. package/dist/ro-GHOBYW2S-4zevc9dy.js +200 -0
  125. package/dist/{ro-BWR3ONRR-vzx3hy8a.js → ro-GHOBYW2S-mhnqsgaa.js} +29 -2
  126. package/dist/{ro-AVAWPKOO-b89pw79r.js → ro-WUYJV6OW-a8d9qy1n.js} +235 -28
  127. package/dist/ru-WBLQ5B2U-dpqvtfwr.js +10 -0
  128. package/dist/services/connector-request-buckets.d.ts +1 -0
  129. package/dist/services/flow-eval-file-store.d.ts +1 -11
  130. package/dist/services/flow-eval-utils.d.ts +1 -32
  131. package/dist/services/flow-validate-service.d.ts +51 -0
  132. package/dist/services/inline-entity-resolver.d.ts +22 -0
  133. package/dist/services/node-service.d.ts +21 -1
  134. package/dist/services/packaging-utils.d.ts +15 -2
  135. package/dist/{shared-utils-pnbvyyb2.js → shared-utils-tqnx96mg.js} +4 -3
  136. package/dist/solution-auth-8qz5pw7z.js +14 -0
  137. package/dist/solution-discovery-vqravtkh.js +44 -0
  138. package/dist/{tidy-service-4fd4mjpb.js → tidy-service-fdctmeww.js} +143 -39
  139. package/dist/tool.js +17 -14
  140. package/dist/{tr-5IIHSFW5-hw4cewew.js → tr-GDTLECMM-k5fhmq13.js} +29 -2
  141. package/dist/tr-GDTLECMM-kngksm3r.js +200 -0
  142. package/dist/{tr-JMIP7ZSL-c39b6pe4.js → tr-M3F5A6AU-bb0tg39m.js} +235 -28
  143. package/dist/utils/flow-io.d.ts +2 -1
  144. package/dist/validation.js +39 -33
  145. package/dist/{variable-service-xgyaf3xy.js → variable-service-9xfk31pm.js} +16 -12
  146. package/dist/{wait-for-flow-job-d8m6mqb4.js → wait-for-flow-job-b0vj8828.js} +15 -12
  147. package/dist/{zh-CN-IFFXSEJS-9wm9gmrv.js → zh-CN-C5G4PC7C-ds9gkptg.js} +235 -28
  148. package/dist/zh-CN-I5D7WHBD-ge92tbx9.js +200 -0
  149. package/dist/{zh-CN-R2KU4U5L-tc1hat59.js → zh-CN-I5D7WHBD-sr5h0a98.js} +29 -2
  150. package/dist/{zh-TW-GNKMELBF-j674515r.js → zh-TW-2AVLM723-288pkc1z.js} +29 -2
  151. package/dist/zh-TW-2AVLM723-xsmap3gk.js +200 -0
  152. package/dist/{zh-TW-IYBNYAMG-8727c7v2.js → zh-TW-62HZIG6O-787kdwex.js} +234 -27
  153. package/package.json +2 -2
  154. package/dist/debug-conversation-trigger-8fgas95p.js +0 -44
  155. package/dist/flow-eval-run-api-byx3cacw.js +0 -13
  156. package/dist/flow-validate-service-ss9nt15j.js +0 -64
  157. package/dist/input-reader-vhar4g0k.js +0 -11
  158. package/dist/node-sync-service-42dpmp60.js +0 -40
  159. package/dist/packager-tool-a5xfcqqr.js +0 -15
  160. package/dist/packager-tool-epkg5s7f.js +0 -454
  161. package/dist/packager-tool-pz5nqg0s.js +0 -64
  162. package/dist/packager-tool-t3ysatjd.js +0 -521
  163. package/dist/packager-tool-vd6jt4n8.js +0 -208
  164. package/dist/packager-tool-wv3qf487.js +0 -265
  165. package/dist/services/flow-debug-service.d.ts +0 -320
  166. package/dist/services/flow-eval-schema/deterministic-evaluators.d.ts +0 -110
  167. package/dist/services/flow-eval-schema/evaluator-fields.d.ts +0 -66
  168. package/dist/services/flow-eval-schema/helpers.d.ts +0 -9
  169. package/dist/services/flow-eval-schema/index.d.ts +0 -4
  170. package/dist/services/flow-eval-schema/llm-judge-evaluators.d.ts +0 -174
  171. package/dist/services/flow-eval-schema/prompts.d.ts +0 -2
  172. package/dist/services/flow-eval-schema/registry.d.ts +0 -375
  173. package/dist/services/flow-eval-schema/tool-call-evaluators.d.ts +0 -93
  174. package/dist/services/flow-eval-schema/types.d.ts +0 -95
  175. package/dist/services/flow-eval-types.d.ts +0 -6
  176. package/dist/utils/write-resolved-flow.d.ts +0 -7
  177. /package/dist/{headless-45dypanh.js → headless-fw8pwyzm.js} +0 -0
  178. /package/dist/{localization-xecwjpe2.js → localization-d6gjmrsw.js} +0 -0
@@ -1,3 +1,6 @@
1
+ import {
2
+ getSolutionAuthContext
3
+ } from "./packager-tool-9era57c0.js";
1
4
  import {
2
5
  JsonSerializerFactory,
3
6
  JsonSerializerNames,
@@ -10,30 +13,31 @@ import {
10
13
  import {
11
14
  UsersApi,
12
15
  createApiClient
13
- } from "./packager-tool-n89vrpex.js";
16
+ } from "./packager-tool-skcjythd.js";
14
17
  import {
15
- getAuthContext,
16
18
  getLoginStatusAsync
17
- } from "./packager-tool-6h69pd2a.js";
18
- import"./packager-tool-qa9gftnj.js";
19
+ } from "./packager-tool-kn86394c.js";
19
20
  import"./packager-tool-0gctz400.js";
21
+ import"./packager-tool-qa9gftnj.js";
20
22
  import"./packager-tool-yc4kw997.js";
21
23
  import {
22
24
  findSolutionFileUpward,
23
25
  normalizeProjectType,
24
26
  toPortableRelativePath
25
- } from "./packager-tool-m8xtf5ej.js";
26
- import"./packager-tool-stq8800d.js";
27
+ } from "./packager-tool-8g5931fz.js";
28
+ import"./packager-tool-pacrqxv2.js";
27
29
  import"./packager-tool-nkrmjr3a.js";
28
30
  import {
29
- catchError,
30
31
  extractErrorMessage,
31
32
  isGuid,
32
33
  logger
33
- } from "./packager-tool-02f63a08.js";
34
+ } from "./packager-tool-apawc11t.js";
35
+ import {
36
+ catchError
37
+ } from "./packager-tool-t7ahhaer.js";
34
38
  import {
35
39
  getFileSystem
36
- } from "./packager-tool-3h2ktz6q.js";
40
+ } from "./packager-tool-myhbp761.js";
37
41
  import {
38
42
  __commonJS,
39
43
  __require,
@@ -2472,6 +2476,19 @@ class NullSecretsProvider {
2472
2476
  }
2473
2477
  }
2474
2478
 
2479
+ // ../../node_modules/@uipath/resource-builder-sdk/dist/providers/feature-flag-provider.js
2480
+ class NullFeatureFlagProvider {
2481
+ getBool(_featureFlagName, defaultValue) {
2482
+ return defaultValue ?? false;
2483
+ }
2484
+ getInt(_featureFlagName, defaultValue) {
2485
+ return defaultValue ?? 0;
2486
+ }
2487
+ getString(_featureFlagName, defaultValue) {
2488
+ return defaultValue ?? "";
2489
+ }
2490
+ }
2491
+
2475
2492
  // ../../node_modules/@uipath/resource-builder-sdk/dist/exceptions/timeout-exception.js
2476
2493
  class TimeoutException extends Error {
2477
2494
  constructor(message, timeoutMs) {
@@ -2626,10 +2643,12 @@ function withFileOperationTimeout2(provider, timeoutMs) {
2626
2643
  // ../../node_modules/@uipath/resource-builder-sdk/dist/solution/solution-context-options.js
2627
2644
  var DEFAULT_SOLUTION_CONTEXT_OPTIONS = {
2628
2645
  lockTimeoutMs: 30000,
2629
- fileOperationTimeoutMs: 30000
2646
+ fileOperationTimeoutMs: 30000,
2647
+ maxDegreeOfParallelism: 1
2630
2648
  };
2631
2649
  var SOLUTION_CONTEXT_TIMEOUT_STORAGE_KEY = "SOL_RB_SOLUTION_CONTEXT_TIMEOUT_MS";
2632
2650
  var FILE_OPERATION_TIMEOUT_STORAGE_KEY = "SOL_RB_FILE_OPERATION_TIMEOUT_MS";
2651
+ var MAX_DEGREE_OF_PARALLELISM_STORAGE_KEY = "SOL_RB_MAX_DEGREE_OF_PARALLELISM";
2633
2652
  function resolveTimeoutMs(storageKey, configured, fallback) {
2634
2653
  const override = readTimeoutOverrideMs(storageKey);
2635
2654
  if (override !== undefined)
@@ -2642,10 +2661,33 @@ function resolveLockTimeoutMs(options) {
2642
2661
  function resolveFileOperationTimeoutMs(options) {
2643
2662
  return resolveTimeoutMs(FILE_OPERATION_TIMEOUT_STORAGE_KEY, options?.fileOperationTimeoutMs, DEFAULT_SOLUTION_CONTEXT_OPTIONS.fileOperationTimeoutMs);
2644
2663
  }
2664
+ function isValidDegreeOfParallelism(value) {
2665
+ return typeof value == "number" && Number.isInteger(value) && value > 0;
2666
+ }
2667
+ function resolveMaxDegreeOfParallelism(options) {
2668
+ const override = readDegreeOfParallelismOverride(MAX_DEGREE_OF_PARALLELISM_STORAGE_KEY);
2669
+ if (override !== undefined)
2670
+ return override;
2671
+ return isValidDegreeOfParallelism(options?.maxDegreeOfParallelism) ? options.maxDegreeOfParallelism : DEFAULT_SOLUTION_CONTEXT_OPTIONS.maxDegreeOfParallelism;
2672
+ }
2673
+ function readDegreeOfParallelismOverride(storageKey) {
2674
+ try {
2675
+ if ("u" < typeof localStorage)
2676
+ return;
2677
+ const raw = localStorage.getItem(storageKey);
2678
+ if (raw === null || raw.trim() === "")
2679
+ return;
2680
+ const parsed = Number(raw);
2681
+ return isValidDegreeOfParallelism(parsed) ? parsed : undefined;
2682
+ } catch {
2683
+ return;
2684
+ }
2685
+ }
2645
2686
  function mergeSolutionContextOptions(options) {
2646
2687
  return {
2647
2688
  lockTimeoutMs: isValidTimeoutMs(options?.lockTimeoutMs) ? options.lockTimeoutMs : DEFAULT_SOLUTION_CONTEXT_OPTIONS.lockTimeoutMs,
2648
- fileOperationTimeoutMs: isValidTimeoutMs(options?.fileOperationTimeoutMs) ? options.fileOperationTimeoutMs : DEFAULT_SOLUTION_CONTEXT_OPTIONS.fileOperationTimeoutMs
2689
+ fileOperationTimeoutMs: isValidTimeoutMs(options?.fileOperationTimeoutMs) ? options.fileOperationTimeoutMs : DEFAULT_SOLUTION_CONTEXT_OPTIONS.fileOperationTimeoutMs,
2690
+ maxDegreeOfParallelism: isValidDegreeOfParallelism(options?.maxDegreeOfParallelism) ? options.maxDegreeOfParallelism : DEFAULT_SOLUTION_CONTEXT_OPTIONS.maxDegreeOfParallelism
2649
2691
  };
2650
2692
  }
2651
2693
 
@@ -3436,6 +3478,16 @@ function getRootFolder(solution) {
3436
3478
  }
3437
3479
 
3438
3480
  // ../../node_modules/@uipath/resource-builder-sdk/dist/solution/multi-file-solution-definition-provider.js
3481
+ function nowMs() {
3482
+ return globalThis.performance?.now?.() ?? Date.now();
3483
+ }
3484
+ function round1(ms) {
3485
+ return Math.round(10 * ms) / 10;
3486
+ }
3487
+ function cancellationError(signal) {
3488
+ return signal?.reason instanceof OperationCancelledException ? signal.reason : new OperationCancelledException;
3489
+ }
3490
+
3439
3491
  class MultiFileSolutionDefinitionProvider {
3440
3492
  get caseInsensitiveSerializer() {
3441
3493
  if (!this._caseInsensitiveSerializer)
@@ -3453,137 +3505,344 @@ class MultiFileSolutionDefinitionProvider {
3453
3505
  }
3454
3506
  async readAsync(context, cancellationToken) {
3455
3507
  this.logger.info("Reading multi-file solution definition for solution %s", context.path);
3456
- const solutionKey = this.getSolutionKey(context);
3457
- const fileStorageProvider = await this.getFileStorageProviderAsync(context, cancellationToken);
3458
- const resources = [];
3459
- const solutionFiles = [];
3460
- let hashes;
3461
- let paths;
3462
- const pathsByKind = this.getPathsByKind(context);
3463
- let tree;
3464
- pathsByKind.clear();
3508
+ const loadStarted = nowMs();
3509
+ let fileCount = 0;
3510
+ let listMs = 0;
3511
+ let readStarted = loadStarted;
3512
+ let readWallMs = 0;
3513
+ let readCompleted = false;
3514
+ let ioMs = 0;
3515
+ let maxFileIoMs = 0;
3516
+ let parseMs = 0;
3517
+ let hashMs = 0;
3518
+ let chars = 0;
3519
+ let loadedCount = 0;
3465
3520
  const parseErrors = [];
3466
3521
  const missingFiles = [];
3467
3522
  const invalidFiles = [];
3468
- context.items[SolutionContextKeys.PARSE_ERRORS_ITEM_KEY] = parseErrors;
3469
- if (!context.isReadOnly) {
3470
- hashes = this.getHashes(context);
3471
- paths = this.getPaths(context);
3472
- tree = this.getTree(context);
3473
- hashes.clear();
3474
- paths.clear();
3475
- tree.length = 0;
3476
- }
3477
- const resourceFiles = await fileStorageProvider.getFilesAsync(SolutionConstants.RESOURCE_FILES_FOLDER_NAME, "*.json", cancellationToken);
3478
- for (const resourceFile of resourceFiles)
3479
- try {
3480
- const stream = await fileStorageProvider.openFileAsync(resourceFile, cancellationToken);
3481
- const content = await this.streamToString(stream);
3482
- const wrapper = this.caseInsensitiveSerializer.deserialize(content);
3483
- if (wrapper?.resource) {
3484
- const rd = this.fromSerializable(wrapper.resource, solutionFiles);
3485
- const relPath = resourceFile.replace(/\\/g, "/");
3486
- const segments = relPath.split("/").filter((s) => s.length > 0);
3487
- const firstSegment = segments[0];
3488
- if (segments.length >= 3 && firstSegment && firstSegment.toLowerCase() === SolutionConstants.RESOURCE_FILES_FOLDER_NAME.toLowerCase()) {
3489
- const hasType = !!rd.type;
3490
- const folderSegmentCount = hasType ? segments.length - 3 : segments.length - 2;
3491
- if (folderSegmentCount < 1)
3492
- rd.folders = [
3493
- {
3494
- fullyQualifiedName: SolutionConstants.ROOT_FOLDER_NAME
3495
- }
3496
- ];
3497
- else {
3498
- const segmentsToUse = segments.slice(1, folderSegmentCount);
3499
- const folderFqn = segmentsToUse.join("/");
3500
- rd.folders = [
3501
- {
3502
- fullyQualifiedName: folderFqn
3503
- }
3504
- ];
3523
+ let metricsLogged = false;
3524
+ const logReadMetrics = (outcome) => {
3525
+ metricsLogged = true;
3526
+ const totalMs = nowMs() - loadStarted;
3527
+ const mergeMs = readCompleted ? nowMs() - readStarted - readWallMs : 0;
3528
+ const metrics = {
3529
+ outcome,
3530
+ path: context.path,
3531
+ fileCount,
3532
+ totalMs: round1(totalMs),
3533
+ listMs: round1(listMs),
3534
+ readWallMs: round1(readWallMs),
3535
+ ioMs: round1(ioMs),
3536
+ maxFileIoMs: round1(maxFileIoMs),
3537
+ parseMs: round1(parseMs),
3538
+ hashMs: round1(hashMs),
3539
+ mergeMs: round1(mergeMs),
3540
+ chars,
3541
+ degreeOfParallelism: resolveMaxDegreeOfParallelism(this.options),
3542
+ isReadOnly: context.isReadOnly,
3543
+ loaded: loadedCount,
3544
+ missing: missingFiles.length,
3545
+ invalid: invalidFiles.length,
3546
+ parseErrors: parseErrors.length
3547
+ };
3548
+ const message = `Solution read ${outcome} for solution ${context.path}: ${metrics.fileCount} files in ${metrics.totalMs} ms (list ${metrics.listMs} ms, read ${metrics.readWallMs} ms wall, io ${metrics.ioMs} ms summed, max file io ${metrics.maxFileIoMs} ms, parse ${metrics.parseMs} ms, hash ${metrics.hashMs} ms, merge ${metrics.mergeMs} ms); ${metrics.chars} chars; parallelism ${metrics.degreeOfParallelism}; readOnly ${metrics.isReadOnly}; loaded ${metrics.loaded}, missing ${metrics.missing}, invalid ${metrics.invalid}, parseErrors ${metrics.parseErrors}`;
3549
+ if (outcome === "Success")
3550
+ this.logger.info(message, metrics);
3551
+ else
3552
+ this.logger.warn(message, metrics);
3553
+ };
3554
+ const readCore = async () => {
3555
+ const solutionKey = this.getSolutionKey(context);
3556
+ const fileStorageProvider = await this.getFileStorageProviderAsync(context, cancellationToken);
3557
+ const resources = [];
3558
+ const solutionFiles = [];
3559
+ let hashes;
3560
+ let paths;
3561
+ const pathsByKind = this.getPathsByKind(context);
3562
+ let tree;
3563
+ pathsByKind.clear();
3564
+ context.items[SolutionContextKeys.PARSE_ERRORS_ITEM_KEY] = parseErrors;
3565
+ if (!context.isReadOnly) {
3566
+ hashes = this.getHashes(context);
3567
+ paths = this.getPaths(context);
3568
+ tree = this.getTree(context);
3569
+ hashes.clear();
3570
+ paths.clear();
3571
+ tree.length = 0;
3572
+ }
3573
+ const listStarted = nowMs();
3574
+ const resourceFiles = await fileStorageProvider.getFilesAsync(SolutionConstants.RESOURCE_FILES_FOLDER_NAME, "*.json", cancellationToken);
3575
+ listMs = nowMs() - listStarted;
3576
+ fileCount = resourceFiles.length;
3577
+ readStarted = nowMs();
3578
+ const readResults = await this.readResourceFilesAsync(context, fileStorageProvider, resourceFiles, cancellationToken);
3579
+ readWallMs = nowMs() - readStarted;
3580
+ readCompleted = true;
3581
+ let fatal;
3582
+ let hasFatal = false;
3583
+ for (const result of readResults)
3584
+ if (result !== undefined) {
3585
+ if (result.timings) {
3586
+ ioMs += result.timings.ioMs;
3587
+ maxFileIoMs = Math.max(maxFileIoMs, result.timings.ioMs);
3588
+ parseMs += result.timings.parseMs;
3589
+ hashMs += result.timings.hashMs;
3590
+ chars += result.timings.chars;
3591
+ }
3592
+ if (result.fatal !== undefined) {
3593
+ if (!hasFatal) {
3594
+ fatal = result.fatal;
3595
+ hasFatal = true;
3505
3596
  }
3506
- } else
3507
- rd.folders = [
3508
- {
3509
- fullyQualifiedName: SolutionConstants.ROOT_FOLDER_NAME
3597
+ continue;
3598
+ }
3599
+ if (!hasFatal)
3600
+ switch (result.outcome) {
3601
+ case "loaded": {
3602
+ loadedCount++;
3603
+ const rd = result.resource;
3604
+ for (const file of result.files)
3605
+ if (!solutionFiles.some((sf) => sf.name === file.name && sf.kind === file.kind))
3606
+ solutionFiles.push(file);
3607
+ resources.push(rd);
3608
+ const resourceKey = rd.key;
3609
+ const normalizedFullPath = result.normalizedPath;
3610
+ if (!pathsByKind.has(rd.kind))
3611
+ pathsByKind.set(rd.kind, []);
3612
+ const kindPaths = pathsByKind.get(rd.kind);
3613
+ if (kindPaths)
3614
+ kindPaths.push({
3615
+ name: rd.name,
3616
+ key: rd.key,
3617
+ path: normalizedFullPath
3618
+ });
3619
+ if (!context.isReadOnly && hashes && paths) {
3620
+ paths.set(resourceKey, normalizedFullPath);
3621
+ hashes.set(resourceKey, result.hash);
3622
+ }
3623
+ break;
3510
3624
  }
3511
- ];
3512
- resources.push(rd);
3513
- const resourceKey = rd.key;
3514
- const normalizedFullPath = this.getNormalizedPath(resourceFile);
3515
- if (!pathsByKind.has(rd.kind))
3516
- pathsByKind.set(rd.kind, []);
3517
- const kindPaths = pathsByKind.get(rd.kind);
3518
- if (kindPaths)
3519
- kindPaths.push({
3520
- name: rd.name,
3521
- key: rd.key,
3522
- path: normalizedFullPath
3625
+ case "missing":
3626
+ missingFiles.push(result.file);
3627
+ break;
3628
+ case "invalid":
3629
+ invalidFiles.push(result.file);
3630
+ break;
3631
+ case "parseError":
3632
+ parseErrors.push(result.file);
3633
+ break;
3634
+ }
3635
+ }
3636
+ if (hasFatal) {
3637
+ logReadMetrics("Fatal");
3638
+ throw fatal;
3639
+ }
3640
+ if (missingFiles.length > 0) {
3641
+ logReadMetrics("MissingFiles");
3642
+ throw new BadRequestException(ErrorCodes.Resources.MissingFileDependencies, `Solution has missing files: ${missingFiles.join(", ")}`);
3643
+ }
3644
+ if (invalidFiles.length > 0) {
3645
+ logReadMetrics("InvalidFiles");
3646
+ throw new BadRequestException(ErrorCodes.Resources.InvalidResourceFile, `Solution has resource files with invalid content: ${invalidFiles.join(", ")}`);
3647
+ }
3648
+ if (parseErrors.length > 0) {
3649
+ logReadMetrics("ParseErrors");
3650
+ throw new Error(`Failed to read resource files for solution ${context.path}: ${parseErrors.join(", ")}`);
3651
+ }
3652
+ const folderMap = new Map;
3653
+ const rootFolder = this.buildRootFolder(solutionKey, SolutionConstants.ROOT_FOLDER_NAME);
3654
+ folderMap.set(rootFolder.fullyQualifiedName.toLowerCase(), rootFolder);
3655
+ for (const res of resources)
3656
+ for (const fdep of res.folders ?? []) {
3657
+ const fqnLower = fdep.fullyQualifiedName.toLowerCase();
3658
+ if (!folderMap.has(fqnLower)) {
3659
+ const folderKey = this.generateGuidFromString(fdep.fullyQualifiedName);
3660
+ const pathSegments = fdep.fullyQualifiedName.split("/").filter((s) => s.length > 0).map((p) => {
3661
+ if (p.toLowerCase() !== SolutionConstants.ROOT_FOLDER_NAME.toLowerCase())
3662
+ return this.generateGuidFromString(SolutionConstants.ROOT_FOLDER_NAME);
3663
+ return rootFolder.key;
3664
+ });
3665
+ const folderPath = pathSegments.join(".");
3666
+ folderMap.set(fqnLower, {
3667
+ key: folderKey,
3668
+ fullyQualifiedName: fdep.fullyQualifiedName,
3669
+ path: folderPath
3523
3670
  });
3524
- if (!context.isReadOnly && hashes && paths) {
3525
- paths.set(resourceKey, normalizedFullPath);
3526
- hashes.set(resourceKey, await this.computeHash(content));
3527
3671
  }
3528
- } else {
3529
- this.logger.error("Failed to read resource file %s for solution %s: invalid content", undefined, resourceFile, context.path);
3530
- invalidFiles.push(resourceFile);
3531
- }
3532
- } catch (ex) {
3533
- if (ex instanceof OperationCancelledException || cancellationToken?.aborted) {
3534
- this.logger.warn("Operation cancelled while reading file %s for solution %s", resourceFile, context.path);
3535
- throw ex instanceof OperationCancelledException ? ex : new OperationCancelledException;
3536
- }
3537
- if (ex instanceof TimeoutException)
3538
- throw new TimeoutException(`Reading resource file ${resourceFile} for solution ${context.path} timed out: ${ex.message}`, ex.timeoutMs);
3539
- if (isFileNotFoundError(ex)) {
3540
- this.logger.warn("Resource file listed but missing in storage for solution %s: %s", resourceFile, context.path);
3541
- missingFiles.push(resourceFile);
3542
- } else {
3543
- this.logger.error("Failed to read resource file %s for solution %s", ex, resourceFile, context.path);
3544
- parseErrors.push(resourceFile);
3545
3672
  }
3673
+ const solution = {
3674
+ key: solutionKey,
3675
+ docVersion: SolutionConstants.CURRENT_DOC_VERSION,
3676
+ folders: Array.from(folderMap.values()),
3677
+ resources,
3678
+ files: solutionFiles
3679
+ };
3680
+ await this.replaceDuplicateKeysAsync(solution, cancellationToken);
3681
+ if (!context.isReadOnly && tree) {
3682
+ const orderedResourceKeys = getTopologicalIdsOrdering(buildDependencyGraph(solution.resources));
3683
+ tree.push(...orderedResourceKeys);
3546
3684
  }
3547
- if (missingFiles.length > 0)
3548
- throw new BadRequestException(ErrorCodes.Resources.MissingFileDependencies, `Solution has missing files: ${missingFiles.join(", ")}`);
3549
- if (invalidFiles.length > 0)
3550
- throw new BadRequestException(ErrorCodes.Resources.InvalidResourceFile, `Solution has resource files with invalid content: ${invalidFiles.join(", ")}`);
3551
- if (parseErrors.length > 0)
3552
- throw new Error(`Failed to read resource files for solution ${context.path}: ${parseErrors.join(", ")}`);
3553
- const folderMap = new Map;
3554
- const rootFolder = this.buildRootFolder(solutionKey, SolutionConstants.ROOT_FOLDER_NAME);
3555
- folderMap.set(rootFolder.fullyQualifiedName.toLowerCase(), rootFolder);
3556
- for (const res of resources)
3557
- for (const fdep of res.folders ?? []) {
3558
- const fqnLower = fdep.fullyQualifiedName.toLowerCase();
3559
- if (!folderMap.has(fqnLower)) {
3560
- const folderKey = this.generateGuidFromString(fdep.fullyQualifiedName);
3561
- const pathSegments = fdep.fullyQualifiedName.split("/").filter((s) => s.length > 0).map((p) => {
3562
- if (p.toLowerCase() !== SolutionConstants.ROOT_FOLDER_NAME.toLowerCase())
3563
- return this.generateGuidFromString(SolutionConstants.ROOT_FOLDER_NAME);
3564
- return rootFolder.key;
3565
- });
3566
- const folderPath = pathSegments.join(".");
3567
- folderMap.set(fqnLower, {
3568
- key: folderKey,
3569
- fullyQualifiedName: fdep.fullyQualifiedName,
3570
- path: folderPath
3571
- });
3572
- }
3685
+ logReadMetrics("Success");
3686
+ return solution;
3687
+ };
3688
+ try {
3689
+ return await readCore();
3690
+ } catch (ex) {
3691
+ if (!metricsLogged)
3692
+ logReadMetrics("Fatal");
3693
+ throw ex;
3694
+ }
3695
+ }
3696
+ async readResourceFilesAsync(context, fileStorageProvider, resourceFiles, cancellationToken) {
3697
+ const results = Array.from({
3698
+ length: resourceFiles.length
3699
+ }, () => {
3700
+ return;
3701
+ });
3702
+ if (resourceFiles.length === 0)
3703
+ return results;
3704
+ const computeHash = !context.isReadOnly;
3705
+ const degreeOfParallelism = Math.min(resolveMaxDegreeOfParallelism(this.options), resourceFiles.length);
3706
+ let nextIndex = 0;
3707
+ let stopRequested = false;
3708
+ const runWorkerAsync = async () => {
3709
+ while (!stopRequested && nextIndex < resourceFiles.length) {
3710
+ const index = nextIndex++;
3711
+ const resourceFile = resourceFiles[index];
3712
+ const result = await this.readResourceFileAsync(context, fileStorageProvider, resourceFile, computeHash, cancellationToken);
3713
+ results[index] = result;
3714
+ if (result.fatal !== undefined)
3715
+ stopRequested = true;
3573
3716
  }
3574
- const solution = {
3575
- key: solutionKey,
3576
- docVersion: SolutionConstants.CURRENT_DOC_VERSION,
3577
- folders: Array.from(folderMap.values()),
3578
- resources,
3579
- files: solutionFiles
3580
3717
  };
3581
- await this.replaceDuplicateKeysAsync(solution, cancellationToken);
3582
- if (!context.isReadOnly && tree) {
3583
- const orderedResourceKeys = getTopologicalIdsOrdering(buildDependencyGraph(solution.resources));
3584
- tree.push(...orderedResourceKeys);
3718
+ const workers = [];
3719
+ for (let i = 0;i < degreeOfParallelism; i++)
3720
+ workers.push(runWorkerAsync());
3721
+ await Promise.all(workers);
3722
+ if (cancellationToken?.aborted && !results.some((result) => result?.fatal !== undefined))
3723
+ throw cancellationError(cancellationToken);
3724
+ return results;
3725
+ }
3726
+ async readResourceFileAsync(context, fileStorageProvider, resourceFile, computeHash, cancellationToken) {
3727
+ const started = nowMs();
3728
+ let ioMs;
3729
+ let content;
3730
+ const failureTimings = () => {
3731
+ const elapsed = nowMs() - started;
3732
+ return ioMs === undefined ? {
3733
+ ioMs: elapsed,
3734
+ parseMs: 0,
3735
+ hashMs: 0,
3736
+ chars: 0
3737
+ } : {
3738
+ ioMs,
3739
+ parseMs: elapsed - ioMs,
3740
+ hashMs: 0,
3741
+ chars: content?.length ?? 0
3742
+ };
3743
+ };
3744
+ try {
3745
+ if (cancellationToken?.aborted)
3746
+ throw cancellationError(cancellationToken);
3747
+ const stream = await fileStorageProvider.openFileAsync(resourceFile, cancellationToken);
3748
+ content = await this.streamToString(stream);
3749
+ ioMs = nowMs() - started;
3750
+ const parseStarted = nowMs();
3751
+ const wrapper = this.caseInsensitiveSerializer.deserialize(content);
3752
+ if (!wrapper?.resource) {
3753
+ this.logger.error("Failed to read resource file %s for solution %s: invalid content", undefined, resourceFile, context.path);
3754
+ return {
3755
+ file: resourceFile,
3756
+ outcome: "invalid",
3757
+ timings: failureTimings()
3758
+ };
3759
+ }
3760
+ const files = [];
3761
+ const rd = this.fromSerializable(wrapper.resource, files);
3762
+ this.applyFolders(rd, resourceFile);
3763
+ const parseMs = nowMs() - parseStarted;
3764
+ let hash;
3765
+ let hashMs = 0;
3766
+ if (computeHash) {
3767
+ const hashStarted = nowMs();
3768
+ hash = await this.computeHash(content);
3769
+ hashMs = nowMs() - hashStarted;
3770
+ }
3771
+ return {
3772
+ file: resourceFile,
3773
+ outcome: "loaded",
3774
+ resource: rd,
3775
+ files,
3776
+ normalizedPath: this.getNormalizedPath(resourceFile),
3777
+ hash,
3778
+ timings: {
3779
+ ioMs,
3780
+ parseMs,
3781
+ hashMs,
3782
+ chars: content.length
3783
+ }
3784
+ };
3785
+ } catch (ex) {
3786
+ if (ex instanceof OperationCancelledException || cancellationToken?.aborted) {
3787
+ this.logger.warn("Operation cancelled while reading file %s for solution %s", resourceFile, context.path);
3788
+ return {
3789
+ file: resourceFile,
3790
+ outcome: "fatal",
3791
+ fatal: ex instanceof OperationCancelledException ? ex : cancellationError(cancellationToken),
3792
+ timings: failureTimings()
3793
+ };
3794
+ }
3795
+ if (ex instanceof TimeoutException)
3796
+ return {
3797
+ file: resourceFile,
3798
+ outcome: "fatal",
3799
+ fatal: new TimeoutException(`Reading resource file ${resourceFile} for solution ${context.path} timed out: ${ex.message}`, ex.timeoutMs),
3800
+ timings: failureTimings()
3801
+ };
3802
+ if (isFileNotFoundError(ex)) {
3803
+ this.logger.warn("Resource file listed but missing in storage for solution %s: %s", resourceFile, context.path);
3804
+ return {
3805
+ file: resourceFile,
3806
+ outcome: "missing",
3807
+ timings: failureTimings()
3808
+ };
3809
+ }
3810
+ this.logger.error("Failed to read resource file %s for solution %s", ex, resourceFile, context.path);
3811
+ return {
3812
+ file: resourceFile,
3813
+ outcome: "parseError",
3814
+ timings: failureTimings()
3815
+ };
3585
3816
  }
3586
- return solution;
3817
+ }
3818
+ applyFolders(resource, resourceFile) {
3819
+ const relPath = resourceFile.replace(/\\/g, "/");
3820
+ const segments = relPath.split("/").filter((s) => s.length > 0);
3821
+ const firstSegment = segments[0];
3822
+ if (segments.length >= 3 && firstSegment && firstSegment.toLowerCase() === SolutionConstants.RESOURCE_FILES_FOLDER_NAME.toLowerCase()) {
3823
+ const hasType = !!resource.type;
3824
+ const folderSegmentCount = hasType ? segments.length - 3 : segments.length - 2;
3825
+ if (folderSegmentCount < 1)
3826
+ resource.folders = [
3827
+ {
3828
+ fullyQualifiedName: SolutionConstants.ROOT_FOLDER_NAME
3829
+ }
3830
+ ];
3831
+ else {
3832
+ const segmentsToUse = segments.slice(1, folderSegmentCount);
3833
+ const folderFqn = segmentsToUse.join("/");
3834
+ resource.folders = [
3835
+ {
3836
+ fullyQualifiedName: folderFqn
3837
+ }
3838
+ ];
3839
+ }
3840
+ } else
3841
+ resource.folders = [
3842
+ {
3843
+ fullyQualifiedName: SolutionConstants.ROOT_FOLDER_NAME
3844
+ }
3845
+ ];
3587
3846
  }
3588
3847
  async writeAsync(context, solution, cancellationToken) {
3589
3848
  if (context.isReadOnly)
@@ -3888,7 +4147,7 @@ class MultiFileSolutionDefinitionFactory {
3888
4147
  // ../../node_modules/@uipath/resource-builder-sdk/dist/embedded-files-default.js
3889
4148
  async function createDefaultEmbeddedFileReaderAsync() {
3890
4149
  const [{ EmbeddedFileReader }, { JsonSerializerFactory: JsonSerializerFactory2 }] = await Promise.all([
3891
- import("./embedded-file-reader-v8c2yj2a.js"),
4150
+ import("./embedded-file-reader-r66242ey.js"),
3892
4151
  import("./index-kmp9fmhb.js")
3893
4152
  ]);
3894
4153
  return new EmbeddedFileReader(new JsonSerializerFactory2);
@@ -3906,6 +4165,7 @@ var ServiceTokens = {
3906
4165
  SecretsProvider: "ISecretsProvider",
3907
4166
  FileStorageProviderFactory: "IFileStorageProviderFactory",
3908
4167
  IpRangeBypassSecretProvider: "IIpRangeBypassSecretProvider",
4168
+ FeatureFlagProvider: "IFeatureFlagProvider",
3909
4169
  SolutionDefinitionProvider: "ISolutionDefinitionProvider",
3910
4170
  SolutionDefinitionFactory: "ISolutionDefinitionFactory",
3911
4171
  ArtifactResourceSpecEnhancer: "IArtifactResourceSpecEnhancer",
@@ -4256,6 +4516,9 @@ function getBindingType(resourceKind, resourceType) {
4256
4516
  }
4257
4517
 
4258
4518
  // ../../node_modules/@uipath/resource-builder-sdk/dist/bindings/bindings-metadata-serializer.js
4519
+ var SUPPORTED_SCHEMA_MAJOR_VERSION = 2;
4520
+ var INT32_MAX_VALUE = 2147483647;
4521
+
4259
4522
  class BindingsMetadataSerializer {
4260
4523
  tryDeserialize(input) {
4261
4524
  if (!input)
@@ -4266,30 +4529,52 @@ class BindingsMetadataSerializer {
4266
4529
  let cleanInput = input.charCodeAt(0) === 65279 ? input.slice(1) : input;
4267
4530
  if (cleanInput.charCodeAt(cleanInput.length - 1) === 26)
4268
4531
  cleanInput = cleanInput.slice(0, -1);
4269
- const jsonObject = JSON.parse(cleanInput);
4532
+ const root = JSON.parse(cleanInput);
4533
+ if (root === null || typeof root != "object" || Array.isArray(root)) {
4534
+ this.logger.warn("Invalid bindings: content is not a JSON object");
4535
+ return {
4536
+ success: false
4537
+ };
4538
+ }
4539
+ const jsonObject = root;
4270
4540
  const versionValue = jsonObject[BindingsKnownKeys.Version];
4271
- if (!versionValue)
4541
+ if (typeof versionValue != "string") {
4542
+ this.logger.warn(`Invalid bindings: '${BindingsKnownKeys.Version}' is missing or not a string`);
4543
+ return {
4544
+ success: false
4545
+ };
4546
+ }
4547
+ const majorVersion = BindingsMetadataSerializer.tryParseMajorVersion(versionValue);
4548
+ if (majorVersion === undefined) {
4549
+ this.logger.warn(`Invalid bindings: '${BindingsKnownKeys.Version}' is not a valid version`);
4550
+ return {
4551
+ success: false
4552
+ };
4553
+ }
4554
+ if (majorVersion !== SUPPORTED_SCHEMA_MAJOR_VERSION) {
4555
+ this.logger.warn(`Invalid bindings: unsupported schema major version ${majorVersion}`);
4556
+ return {
4557
+ success: false
4558
+ };
4559
+ }
4560
+ const resources = jsonObject[BindingsKnownKeys.Resources];
4561
+ if (!Array.isArray(resources)) {
4562
+ this.logger.warn(`Invalid bindings: '${BindingsKnownKeys.Resources}' is missing or not an array`);
4272
4563
  return {
4273
4564
  success: false
4274
4565
  };
4275
- const versionParts = versionValue.split(".").map(Number);
4276
- const majorVersion = versionParts[0];
4277
- if (majorVersion !== 2)
4278
- throw new Error("Unsupported bindings schema");
4566
+ }
4279
4567
  const metadata = {
4280
4568
  version: versionValue,
4281
4569
  resources: []
4282
4570
  };
4283
- const resources = jsonObject[BindingsKnownKeys.Resources];
4284
- if (Array.isArray(resources))
4285
- for (const resourceElement of resources) {
4286
- if (resourceElement == null) {
4287
- this.logger.warn("Skipping null bindings resource element");
4288
- continue;
4289
- }
4290
- const resource = this.getBindingsResourceV2(resourceElement);
4291
- metadata.resources.push(resource);
4571
+ for (const resourceElement of resources) {
4572
+ if (resourceElement == null) {
4573
+ this.logger.warn("Skipping null bindings resource element");
4574
+ continue;
4292
4575
  }
4576
+ metadata.resources.push(this.getBindingsResourceV2(resourceElement));
4577
+ }
4293
4578
  this.linkDependencies(metadata.resources);
4294
4579
  return {
4295
4580
  success: true,
@@ -4302,6 +4587,22 @@ class BindingsMetadataSerializer {
4302
4587
  };
4303
4588
  }
4304
4589
  }
4590
+ static tryParseMajorVersion(value) {
4591
+ const parts = value.split(".");
4592
+ if (parts.length < 2 || parts.length > 4)
4593
+ return;
4594
+ let major;
4595
+ for (const [index, part] of parts.entries()) {
4596
+ if (!/^\s*[+-]?\d+\s*$/.test(part))
4597
+ return;
4598
+ const component = Number(part);
4599
+ if (component < 0 || component > INT32_MAX_VALUE)
4600
+ return;
4601
+ if (index === 0)
4602
+ major = component === 0 ? 0 : component;
4603
+ }
4604
+ return major;
4605
+ }
4305
4606
  linkDependencies(resources) {
4306
4607
  for (const resource of resources) {
4307
4608
  const propertyMeta = resource.metadata;
@@ -4488,8 +4789,7 @@ class BindingOverwritesHandler {
4488
4789
  [BindingsKnownKeys.FolderKeyPropertyName]: resourceOverwrite.folderKey ?? ""
4489
4790
  };
4490
4791
  else {
4491
- const isBusinessRule = bindingResource.binding.resourceType === models_BindingsResourceType.BusinessRule;
4492
- const folderPath = bindingResource.isArtefactResource && !isBusinessRule ? "" : resourceOverwrite.folderFullyQualifiedName ?? "";
4792
+ const folderPath = bindingResource.isArtefactResource && !bindingResource.isCodedApp ? "" : resourceOverwrite.folderFullyQualifiedName ?? "";
4493
4793
  overwrite = {
4494
4794
  [BindingsKnownKeys.FolderPathPropertyName]: folderPath,
4495
4795
  [BindingsKnownKeys.NamePropertyName]: resourceOverwrite.resourceName
@@ -4522,6 +4822,11 @@ function removeTimeTriggerBindings(bindings) {
4522
4822
  }
4523
4823
 
4524
4824
  // ../../node_modules/@uipath/resource-builder-sdk/dist/bindings/binding-overwrites-mapping-handler.js
4825
+ function isCodedAppType(type) {
4826
+ const normalized = type?.toLowerCase();
4827
+ return normalized === "coded" || normalized === "codedaction";
4828
+ }
4829
+
4525
4830
  class BindingOverwritesMappingRequestHandler {
4526
4831
  async handleAsync(request, cancellationToken) {
4527
4832
  const solutionBindings = request.bindings.resources.filter((x) => isSolutionResource(x.metadata));
@@ -4547,7 +4852,8 @@ class BindingOverwritesMappingRequestHandler {
4547
4852
  result.push({
4548
4853
  binding: bindingsResource,
4549
4854
  resourceKey: resource.key,
4550
- isArtefactResource: resource.projectKey != null
4855
+ isArtefactResource: resource.projectKey != null,
4856
+ isCodedApp: bindingsResource.resourceType === models_BindingsResourceType.App && isCodedAppType(resource.type)
4551
4857
  });
4552
4858
  } else {
4553
4859
  this.logger.error(`Solution does not contain binding resource of type ${models_BindingsResourceType[bindingsResource.resourceType]}.`);
@@ -5552,6 +5858,9 @@ class SolutionPublishLocationRequest {
5552
5858
  }
5553
5859
 
5554
5860
  class SolutionPublishLocationRequestV2 {
5861
+ constructor(permissionType) {
5862
+ this.permissionType = permissionType;
5863
+ }
5555
5864
  }
5556
5865
 
5557
5866
  class SettingsRequest {
@@ -5716,12 +6025,13 @@ function _ts_param3(paramIndex, decorator) {
5716
6025
  }
5717
6026
 
5718
6027
  class SolutionPublishLocationRequestV2Handler {
5719
- async handleAsync(_request, cancellationToken) {
6028
+ async handleAsync(request, cancellationToken) {
5720
6029
  try {
5721
6030
  const orchestratorClient = await this.orchestratorClientFactory.getClientAsync(cancellationToken);
5722
6031
  if (!orchestratorClient)
5723
6032
  throw new InvalidOperationException("Failed to create Orchestrator client");
5724
- return await orchestratorClient.getPublishLocationsAsync(cancellationToken);
6033
+ const { permissionType } = request;
6034
+ return permissionType == null ? await orchestratorClient.getPublishLocationsAsync(cancellationToken) : await orchestratorClient.getAccessiblePublishLocationsAsync(permissionType, cancellationToken);
5725
6035
  } catch (error) {
5726
6036
  this.logger.error("An unexpected error occurred while retrieving publish locations from Automation Solutions service.", error);
5727
6037
  throw error;
@@ -7751,7 +8061,7 @@ class GetResourceKeyForProjectRequestHandler {
7751
8061
  projectKey: request.projectKey,
7752
8062
  solution: request.context.path
7753
8063
  });
7754
- const cacheKey = `prk:${request.projectKey}`;
8064
+ const cacheKey = `prk:${request.context.path}:${request.projectKey}`;
7755
8065
  const cached = await this.cacheProvider.getAsync(cacheKey, cancellationToken);
7756
8066
  if (cached && typeof cached == "object" && "resourceKey" in cached) {
7757
8067
  this.logger.info("Cache hit for project {projectKey} resource key.", {
@@ -8579,7 +8889,11 @@ class UpdateResourceConfigurationCommandHandler {
8579
8889
  for (const prop of command.properties) {
8580
8890
  const propKey = prop.property.toLowerCase();
8581
8891
  const metadata = propertiesMetadata.get(propKey);
8582
- if (!(!metadata || isAnyReferenceProperty(metadata)) && metadata.readOnly !== true) {
8892
+ if (metadata && metadata.readOnly !== true) {
8893
+ if (isAnyReferenceProperty(metadata)) {
8894
+ updated = this.setSolutionReference(solution, resource, currentConfiguration, propertiesMetadata, metadata, prop.configuredValue) || updated;
8895
+ continue;
8896
+ }
8583
8897
  if (isSecretProperty(metadata)) {
8584
8898
  const secretValue = prop.configuredValue?.toString() || "";
8585
8899
  const existingKey = currentConfiguration[metadata.property]?.toString();
@@ -8623,6 +8937,38 @@ class UpdateResourceConfigurationCommandHandler {
8623
8937
  await command.context.saveChangesAsync(cancellationToken);
8624
8938
  return resourceConfiguration;
8625
8939
  }
8940
+ setSolutionReference(solution, resource, currentConfiguration, propertiesMetadata, metadata, configuredValue) {
8941
+ const referenceKind = metadata["referenceKind"];
8942
+ if (!isSingleReferenceProperty(metadata) || isFileReferenceProperty(metadata) || typeof referenceKind != "string" || !referenceKind)
8943
+ return false;
8944
+ const requested = asReference(configuredValue);
8945
+ const target = requested?.key ? solution.resources.find((r) => invariantEquals(r.key, requested.key) && invariantEquals(r.kind, referenceKind)) : undefined;
8946
+ if (!requested || !target || invariantEquals(target.key, resource.key))
8947
+ return false;
8948
+ const dependencies = resource.dependencies ??= [];
8949
+ const previous = asReference(currentConfiguration[metadata.property]);
8950
+ const previousKey = previous?.key;
8951
+ const isReferencedElsewhere = (key) => [
8952
+ ...propertiesMetadata.values()
8953
+ ].some((p) => isAnyReferenceProperty(p) && !isFileReferenceProperty(p) && typeof p["referenceKind"] == "string" && invariantEquals(p["referenceKind"], target.kind) && !invariantEquals(p.property, metadata.property) && asReferences(currentConfiguration[p.property]).some((r) => r.key !== undefined && invariantEquals(r.key, key)));
8954
+ if (previousKey && !invariantEquals(previousKey, target.key) && !isReferencedElsewhere(previousKey)) {
8955
+ const previousName = solution.resources.find((r) => invariantEquals(r.key, previousKey) && invariantEquals(r.kind, target.kind))?.name ?? previous?.name ?? "";
8956
+ resource.dependencies = dependencies.filter((d) => !(invariantEquals(d.kind, target.kind) && invariantEquals(d.name, previousName)));
8957
+ }
8958
+ if (!resource.dependencies.some((d) => invariantEquals(d.kind, target.kind) && invariantEquals(d.name, target.name)))
8959
+ resource.dependencies.push({
8960
+ kind: target.kind,
8961
+ name: target.name
8962
+ });
8963
+ currentConfiguration[metadata.property] = {
8964
+ name: target.name,
8965
+ key: target.key,
8966
+ folderKey: requested.folderKey ?? null,
8967
+ lookupStrategy: null,
8968
+ info: null
8969
+ };
8970
+ return true;
8971
+ }
8626
8972
  async updateReferencesName(solutionDefinition, resource, oldName, cancellationToken) {
8627
8973
  const resourcesToBeChanged = solutionDefinition.resources.filter((r) => r.key !== resource.key && (r.dependencies ?? []).some((d) => invariantEquals(d.kind, resource.kind) && invariantEquals(d.name, oldName)));
8628
8974
  if (resourcesToBeChanged.length === 0)
@@ -8909,6 +9255,28 @@ class UpsertResourceSecretCommandHandler {
8909
9255
  this.secretsProvider = secretsProvider;
8910
9256
  }
8911
9257
  }
9258
+ function asReference(value) {
9259
+ if (!value || typeof value != "object" || Array.isArray(value))
9260
+ return;
9261
+ const record = value;
9262
+ const pick = (name) => {
9263
+ const entry = Object.entries(record).find(([k]) => k.toLowerCase() === name.toLowerCase());
9264
+ return typeof entry?.[1] == "string" ? entry[1] : undefined;
9265
+ };
9266
+ return {
9267
+ key: pick("key"),
9268
+ name: pick("name"),
9269
+ folderKey: pick("folderKey")
9270
+ };
9271
+ }
9272
+ function asReferences(value) {
9273
+ if (Array.isArray(value))
9274
+ return value.map(asReference).filter((r) => r !== undefined);
9275
+ const single = asReference(value);
9276
+ return single ? [
9277
+ single
9278
+ ] : [];
9279
+ }
8912
9280
 
8913
9281
  // ../../node_modules/@uipath/resource-builder-sdk/dist/handlers/solution-handlers.js
8914
9282
  var DUPLICATE_NAMES_SUPPORTED_KINDS = new Set([
@@ -9880,6 +10248,9 @@ class ResourceCatalogApi extends HttpClient {
9880
10248
  // ../../node_modules/@uipath/resource-builder-sdk/dist/clients/resource-catalog/resource-catalog-client.factory.js
9881
10249
  var RESOURCE_CATALOG_SCOPE = "RCS.FolderAuthorization";
9882
10250
  var RESOURCE_CATALOG_SERVICE_NAME = "resourcecatalog";
10251
+ function trimTrailingSlashes(url) {
10252
+ return url.replace(/\/+$/, "");
10253
+ }
9883
10254
 
9884
10255
  class ResourceCatalogClientFactory {
9885
10256
  async getClientAsync(cancellationToken) {
@@ -9893,9 +10264,8 @@ class ResourceCatalogClientFactory {
9893
10264
  ], true, cancellationToken);
9894
10265
  const ipRangeBypassSecret = await this.ipRangeBypassSecretProvider?.getIpRangeBypassSecretAsync(cancellationToken);
9895
10266
  const gatewayIntegrationEnabled = this.resourceBuilderAccessProvider.isGatewayIntegrationEnabled();
9896
- const normalizedBaseUrl = baseUrl.endsWith("/") ? baseUrl : baseUrl + "/";
9897
10267
  const client = new ResourceCatalogApi({
9898
- baseUrl: normalizedBaseUrl,
10268
+ baseUrl: trimTrailingSlashes(baseUrl),
9899
10269
  securityWorker: (securityData) => {
9900
10270
  if (!securityData)
9901
10271
  return {};
@@ -9938,7 +10308,7 @@ class ResourceCatalogClientFactory {
9938
10308
  if (!accountKey)
9939
10309
  throw new Error("Unable to obtain account key");
9940
10310
  const client = new ResourceCatalogApi({
9941
- baseUrl,
10311
+ baseUrl: trimTrailingSlashes(baseUrl),
9942
10312
  securityWorker: (securityData) => {
9943
10313
  if (!securityData)
9944
10314
  return {};
@@ -12157,7 +12527,16 @@ class AutomationSolutionsClientProxy2 {
12157
12527
  // ../../node_modules/@uipath/resource-builder-sdk/dist/clients/orchestrator/orchestrator-client.js
12158
12528
  class OrchestratorClient {
12159
12529
  async getPublishLocationsAsync(cancellationToken) {
12160
- const url = `${this.options.baseUrl}api/v2/AutomationSolutions/publish_locations`;
12530
+ return this.getPublishLocationsFromAsync(this.publishLocationsUrl(), cancellationToken);
12531
+ }
12532
+ async getAccessiblePublishLocationsAsync(permissionType, cancellationToken) {
12533
+ const url = `${this.publishLocationsUrl()}?permissionType=${encodeURIComponent(permissionType)}`;
12534
+ return this.getPublishLocationsFromAsync(url, cancellationToken);
12535
+ }
12536
+ publishLocationsUrl() {
12537
+ return `${this.options.baseUrl}api/v2/AutomationSolutions/publish_locations`;
12538
+ }
12539
+ async getPublishLocationsFromAsync(url, cancellationToken) {
12161
12540
  const headers = OrchestratorClientFactory.buildHeaders(this.options.securityData);
12162
12541
  const response = await fetch(url, {
12163
12542
  method: "GET",
@@ -12847,7 +13226,7 @@ class ReconcileProjectsCommandHandler {
12847
13226
  } : {
12848
13227
  resourceKey: undefined
12849
13228
  };
12850
- await this.cacheProvider.setAsync(`prk:${projectKey}`, result, cancellationToken);
13229
+ await this.cacheProvider.setAsync(`prk:${context.path}:${projectKey}`, result, cancellationToken);
12851
13230
  }
12852
13231
  groupByProjectKey(artefactResources) {
12853
13232
  const map = new Map;
@@ -13721,6 +14100,11 @@ class ResourceBuilder {
13721
14100
  const request = new SolutionPublishLocationRequestV2;
13722
14101
  return this._mediator.sendAsync(request, cancellationToken);
13723
14102
  }
14103
+ async getAccessiblePublishLocationsAsync(permissionType, cancellationToken) {
14104
+ this.throwIfCancelled(cancellationToken);
14105
+ const request = new SolutionPublishLocationRequestV2(permissionType);
14106
+ return this._mediator.sendAsync(request, cancellationToken);
14107
+ }
13724
14108
  async getSettingsAsync(cancellationToken) {
13725
14109
  this.throwIfCancelled(cancellationToken);
13726
14110
  const request = new SettingsRequest;
@@ -14280,9 +14664,9 @@ class UnconfiguredEmbeddedFileReader {
14280
14664
  }
14281
14665
 
14282
14666
  // ../../node_modules/@uipath/resource-builder-sdk/dist/container.js
14283
- function createContainer(accessProvider, cacheProvider, secretsProvider, fileStorageProviderFactory, ipRangeBypassSecretProvider, solutionDefinitionProvider, solutionDefinitionFactory, artifactResourceSpecEnhancer, httpReaderOptions, loggerFactory, embeddedFileReader, solutionContextOptions) {
14667
+ function createContainer(accessProvider, cacheProvider, secretsProvider, fileStorageProviderFactory, ipRangeBypassSecretProvider, solutionDefinitionProvider, solutionDefinitionFactory, artifactResourceSpecEnhancer, httpReaderOptions, loggerFactory, embeddedFileReader, solutionContextOptions, featureFlagProvider) {
14284
14668
  const childContainer = import_tsyringe6.container.createChildContainer();
14285
- registerProviders(childContainer, accessProvider, cacheProvider, secretsProvider, fileStorageProviderFactory, ipRangeBypassSecretProvider, solutionDefinitionProvider, solutionDefinitionFactory, artifactResourceSpecEnhancer, httpReaderOptions, loggerFactory, solutionContextOptions);
14669
+ registerProviders(childContainer, accessProvider, cacheProvider, secretsProvider, fileStorageProviderFactory, ipRangeBypassSecretProvider, solutionDefinitionProvider, solutionDefinitionFactory, artifactResourceSpecEnhancer, httpReaderOptions, loggerFactory, solutionContextOptions, featureFlagProvider);
14286
14670
  registerServices(childContainer, embeddedFileReader);
14287
14671
  registerHandlers(childContainer);
14288
14672
  childContainer.register(ServiceTokens.Mediator, {
@@ -14306,11 +14690,15 @@ function registerProvider(diContainer, token, provider) {
14306
14690
  break;
14307
14691
  }
14308
14692
  }
14309
- function registerProviders(diContainer, accessProvider, cacheProvider, secretsProvider, fileStorageProviderFactory, ipRangeBypassSecretProvider, solutionDefinitionProvider, solutionDefinitionFactory, artifactResourceSpecEnhancer, httpReaderOptions, loggerFactory, solutionContextOptions) {
14693
+ function registerProviders(diContainer, accessProvider, cacheProvider, secretsProvider, fileStorageProviderFactory, ipRangeBypassSecretProvider, solutionDefinitionProvider, solutionDefinitionFactory, artifactResourceSpecEnhancer, httpReaderOptions, loggerFactory, solutionContextOptions, featureFlagProvider) {
14310
14694
  registerProvider(diContainer, ServiceTokens.AccessProvider, accessProvider);
14311
14695
  registerProvider(diContainer, ServiceTokens.CacheProvider, cacheProvider);
14312
14696
  registerProvider(diContainer, ServiceTokens.SecretsProvider, secretsProvider);
14313
14697
  registerProvider(diContainer, ServiceTokens.IpRangeBypassSecretProvider, ipRangeBypassSecretProvider);
14698
+ registerProvider(diContainer, ServiceTokens.FeatureFlagProvider, featureFlagProvider ?? {
14699
+ instance: new NullFeatureFlagProvider,
14700
+ lifetime: service_tokens_ServiceLifetime.Singleton
14701
+ });
14314
14702
  registerProvider(diContainer, ServiceTokens.FileStorageProviderFactory, fileStorageProviderFactory);
14315
14703
  registerProvider(diContainer, ServiceTokens.SolutionDefinitionProvider, solutionDefinitionProvider);
14316
14704
  registerProvider(diContainer, ServiceTokens.SolutionDefinitionFactory, solutionDefinitionFactory);
@@ -15037,6 +15425,11 @@ class ResourceBuilderConfiguration {
15037
15425
  this._ipRangeBypassSecretProviderLifetime = lifetime;
15038
15426
  return this;
15039
15427
  }
15428
+ addFeatureFlagProvider(provider, lifetime = service_tokens_ServiceLifetime.Scoped) {
15429
+ this._featureFlagProviderProvider = provider;
15430
+ this._featureFlagProviderLifetime = lifetime;
15431
+ return this;
15432
+ }
15040
15433
  addSolutionDefinitionProvider(provider, lifetime = service_tokens_ServiceLifetime.Scoped) {
15041
15434
  this._solutionDefinitionProviderProvider = provider;
15042
15435
  this._solutionDefinitionProviderLifetime = lifetime;
@@ -15090,6 +15483,11 @@ class ResourceBuilderConfiguration {
15090
15483
  instance: ipRangeBypassSecretProviderInstance,
15091
15484
  lifetime: this._ipRangeBypassSecretProviderLifetime
15092
15485
  };
15486
+ const featureFlagProviderInstance = this._featureFlagProviderProvider ? await resolveProvider(this._featureFlagProviderProvider) : new NullFeatureFlagProvider;
15487
+ const featureFlagProvider = {
15488
+ instance: featureFlagProviderInstance,
15489
+ lifetime: this._featureFlagProviderLifetime
15490
+ };
15093
15491
  const secretsProviderInstance = this._secretsProviderProvider ? await resolveProvider(this._secretsProviderProvider) : new NullSecretsProvider;
15094
15492
  const secretsProvider = {
15095
15493
  instance: secretsProviderInstance,
@@ -15133,7 +15531,7 @@ class ResourceBuilderConfiguration {
15133
15531
  lifetime: this._artifactResourceSpecEnhancerLifetime
15134
15532
  };
15135
15533
  const embeddedFileReader = await createDefaultEmbeddedFileReaderAsync();
15136
- const container3 = createContainer(accessProvider, cacheProvider, secretsProvider, fileStorageProviderFactory, ipRangeBypassSecretProvider, solutionDefinitionProvider, solutionDefinitionFactory, artifactResourceSpecEnhancer, this._httpReaderOptions, loggerFactory, embeddedFileReader, this._solutionContextOptions);
15534
+ const container3 = createContainer(accessProvider, cacheProvider, secretsProvider, fileStorageProviderFactory, ipRangeBypassSecretProvider, solutionDefinitionProvider, solutionDefinitionFactory, artifactResourceSpecEnhancer, this._httpReaderOptions, loggerFactory, embeddedFileReader, this._solutionContextOptions, featureFlagProvider);
15137
15535
  return new ResourceBuilderServices(container3);
15138
15536
  }
15139
15537
  async buildServices() {
@@ -15145,6 +15543,7 @@ class ResourceBuilderConfiguration {
15145
15543
  this._secretsProviderLifetime = service_tokens_ServiceLifetime.Scoped;
15146
15544
  this._fileStorageProviderFactoryLifetime = service_tokens_ServiceLifetime.Singleton;
15147
15545
  this._ipRangeBypassSecretProviderLifetime = service_tokens_ServiceLifetime.Scoped;
15546
+ this._featureFlagProviderLifetime = service_tokens_ServiceLifetime.Scoped;
15148
15547
  this._solutionDefinitionProviderLifetime = service_tokens_ServiceLifetime.Scoped;
15149
15548
  this._solutionDefinitionFactoryLifetime = service_tokens_ServiceLifetime.Scoped;
15150
15549
  this._artifactResourceSpecEnhancerLifetime = service_tokens_ServiceLifetime.Scoped;
@@ -15256,8 +15655,59 @@ var ARTEFACT_KIND_APP = "app";
15256
15655
  var ARTEFACT_KIND_APP_VERSION = "appversion";
15257
15656
  var ARTEFACT_KIND_PACKAGE = "package";
15258
15657
  var SPEC_KEY_PACKAGE = "package";
15658
+ var RESOURCE_FILES_FOLDER_NAME = "resources";
15659
+ var RESOURCE_FILE_PATTERN = "*.json";
15660
+ var FIX_SHARED_KEY = "Delete all but one file for each key, then retry.";
15661
+ var FIX_KEYLESS = 'Give each file without a key its own unique "key", then retry.';
15662
+
15663
+ class DuplicateKeysError extends Error {
15664
+ keys;
15665
+ constructor(keys) {
15666
+ super(`Duplicate resource keys: ${keys.map(describeKey).join(", ")}`);
15667
+ this.keys = keys;
15668
+ }
15669
+ }
15259
15670
 
15260
15671
  class ArtefactPairBindingProvider extends MultiFileSolutionDefinitionProvider {
15672
+ async readAsync(context, cancellationToken) {
15673
+ const [readError, solution] = await catchError(super.readAsync(context, cancellationToken));
15674
+ if (!readError)
15675
+ return solution;
15676
+ if (!(readError instanceof DuplicateKeysError))
15677
+ throw readError;
15678
+ const [describeError, message] = await catchError(this.describeDuplicateKeys(context, readError.keys, cancellationToken));
15679
+ throw describeError ? readError : new Error(message);
15680
+ }
15681
+ async replaceDuplicateKeysAsync(solution) {
15682
+ const keys = findDuplicateKeys(solution);
15683
+ if (keys.length > 0)
15684
+ throw new DuplicateKeysError(keys);
15685
+ }
15686
+ async describeDuplicateKeys(context, keys, cancellationToken) {
15687
+ const storage = await this.getFileStorageProviderAsync(context, cancellationToken);
15688
+ const files = await storage.getFilesAsync(RESOURCE_FILES_FOLDER_NAME, RESOURCE_FILE_PATTERN, cancellationToken);
15689
+ const pathsByKey = new Map(keys.map((key) => [key, []]));
15690
+ for (const file of [...files].sort()) {
15691
+ const [readError, key] = await catchError(this.readResourceKey(storage, file, cancellationToken));
15692
+ if (readError)
15693
+ continue;
15694
+ pathsByKey.get(key)?.push(toPortableRelativePath(file));
15695
+ }
15696
+ const lines = [...pathsByKey].map(([key, paths]) => `Resource key ${describeKey(key)} is used by: ${paths.join(", ")}`);
15697
+ const fixes = [
15698
+ keys.some((key) => !isKeyless(key)) && FIX_SHARED_KEY,
15699
+ keys.some(isKeyless) && FIX_KEYLESS
15700
+ ].filter(Boolean);
15701
+ return [...lines, ...fixes].join(`
15702
+ `);
15703
+ }
15704
+ async readResourceKey(storage, file, cancellationToken) {
15705
+ const content = await storage.readFileToEndAsync(file, cancellationToken);
15706
+ const wrapper = this.caseInsensitiveSerializer.deserialize(content);
15707
+ if (!wrapper?.resource)
15708
+ throw new Error(`No resource in ${file}`);
15709
+ return wrapper.resource.key;
15710
+ }
15261
15711
  async writeAsync(context, solution, cancellationToken) {
15262
15712
  patchAppPackageLinkage(solution);
15263
15713
  return super.writeAsync(context, solution, cancellationToken);
@@ -15269,6 +15719,22 @@ class ArtefactPairBindingSolutionDefinitionFactory extends MultiFileSolutionDefi
15269
15719
  return new ArtefactPairBindingProvider(this.fileStorageProviderFactory, this.jsonSerializerFactory, this.loggerFactory);
15270
15720
  }
15271
15721
  }
15722
+ function findDuplicateKeys(solution) {
15723
+ const counts = new Map;
15724
+ for (const resource of solution.resources ?? []) {
15725
+ const key = resource.key;
15726
+ counts.set(key, (counts.get(key) ?? 0) + 1);
15727
+ }
15728
+ return [...counts].filter(([, count]) => count > 1).map(([key]) => key);
15729
+ }
15730
+ function isKeyless(key) {
15731
+ return typeof key !== "string" || !key;
15732
+ }
15733
+ function describeKey(key) {
15734
+ if (typeof key === "string" && key)
15735
+ return key;
15736
+ return key === undefined ? "(missing)" : JSON.stringify(key);
15737
+ }
15272
15738
  function patchAppPackageLinkage(solution) {
15273
15739
  const resources = solution.resources ?? [];
15274
15740
  const projectKeys = new Set;
@@ -15740,6 +16206,108 @@ async function createProjectInSolutionBuilder(solutionDir, projectId, projectNam
15740
16206
  await catchError(solutionBuilder.disposeAsync());
15741
16207
  return createError;
15742
16208
  }
16209
+ // ../solution-sdk/src/resources/services/catalog-lookup-failure.ts
16210
+ var NO_CLIENT_MESSAGE = "Unable to create Resource Catalog client";
16211
+ function classifyCatalogFailure(error) {
16212
+ const message = error instanceof Error ? error.message : String(error);
16213
+ if (message.includes(NO_CLIENT_MESSAGE)) {
16214
+ return { message, kind: "no_session" };
16215
+ }
16216
+ const match = /\bHTTP (\d{3})\b/.exec(message);
16217
+ const status = match ? Number(match[1]) : undefined;
16218
+ if (status === 401 || status === 403) {
16219
+ return { message, kind: "refused", status };
16220
+ }
16221
+ return { message, kind: "failed", ...status ? { status } : {} };
16222
+ }
16223
+ function stopsCatalogLookups(failure) {
16224
+ return failure.kind !== "failed";
16225
+ }
16226
+ function describeBindings(bindings) {
16227
+ return bindings.map((b) => `${b.kind} "${b.name}"`).join(", ");
16228
+ }
16229
+ function describeCause(failure) {
16230
+ switch (failure.kind) {
16231
+ case "no_session":
16232
+ return "There is no login, so the Resource Catalog could not be searched";
16233
+ case "refused":
16234
+ return `The Resource Catalog refused this login (${failure.message})`;
16235
+ default:
16236
+ return `A Resource Catalog call failed (${failure.message})`;
16237
+ }
16238
+ }
16239
+ function classify(failure) {
16240
+ const refreshAndCommit = "or run 'uip solution resources refresh' under a login the Resource Catalog accepts and commit the solution's resources. The resources already in the solution are used as they are.";
16241
+ if (failure.kind === "no_session") {
16242
+ return {
16243
+ errorCode: "authentication_required",
16244
+ retry: "RetryWillNotFix",
16245
+ instructions: `Run 'uip login', then re-run; ${refreshAndCommit}`
16246
+ };
16247
+ }
16248
+ if (failure.kind === "refused") {
16249
+ return {
16250
+ errorCode: "permission_denied",
16251
+ retry: "RetryWillNotFix",
16252
+ instructions: `Use a login the Resource Catalog accepts (a user login: 'uip login'), ${refreshAndCommit}`
16253
+ };
16254
+ }
16255
+ const status = failure.status;
16256
+ if (status === 429) {
16257
+ return {
16258
+ errorCode: "rate_limited",
16259
+ retry: "RetryLater",
16260
+ instructions: `Wait, then re-run; ${refreshAndCommit}`
16261
+ };
16262
+ }
16263
+ if (status !== undefined && status >= 500) {
16264
+ return {
16265
+ errorCode: "server_error",
16266
+ retry: "RetryLater",
16267
+ instructions: `Retry once the Resource Catalog is back; ${refreshAndCommit}`
16268
+ };
16269
+ }
16270
+ if (status !== undefined && status >= 400) {
16271
+ return {
16272
+ errorCode: "unknown_error",
16273
+ retry: "RetryWillNotFix",
16274
+ instructions: `The Resource Catalog rejected the lookup for these bindings, so a retry gets the same answer. Check them in the project's bindings, ${refreshAndCommit}`
16275
+ };
16276
+ }
16277
+ return {
16278
+ errorCode: "unknown_error",
16279
+ retry: "RetryLater",
16280
+ instructions: `Retry; if it keeps failing, ${refreshAndCommit}`
16281
+ };
16282
+ }
16283
+ function catalogLookupWarning(failure, kept, unresolved) {
16284
+ const parts = [
16285
+ `${describeCause(failure)}, so ${kept + unresolved.length} binding(s) were not checked against the cloud.`
16286
+ ];
16287
+ if (kept > 0) {
16288
+ parts.push(`${kept} already in the solution were kept as they are.`);
16289
+ }
16290
+ if (unresolved.length > 0) {
16291
+ parts.push(`Not added to the solution: ${describeBindings(unresolved)}.`);
16292
+ }
16293
+ return parts.join(" ");
16294
+ }
16295
+
16296
+ class CatalogLookupError extends Error {
16297
+ errorCode;
16298
+ retry;
16299
+ instructions;
16300
+ unresolved;
16301
+ constructor(failure, unresolved) {
16302
+ super(`${describeCause(failure)}, so these bindings could not be resolved and are not in the solution: ${describeBindings(unresolved)}.`);
16303
+ this.name = "CatalogLookupError";
16304
+ const { errorCode, retry, instructions } = classify(failure);
16305
+ this.errorCode = errorCode;
16306
+ this.retry = retry;
16307
+ this.instructions = instructions;
16308
+ this.unresolved = unresolved;
16309
+ }
16310
+ }
15743
16311
  // ../solution-sdk/src/resources/services/local-resource-matcher.ts
15744
16312
  function normalizeFolderPath(path) {
15745
16313
  if (!path)
@@ -15845,6 +16413,20 @@ async function findCatalogEntityAsync(catalog, query, match) {
15845
16413
  } while (pageCursor);
15846
16414
  return;
15847
16415
  }
16416
+ async function findCatalogEntitiesAsync(catalog, query, match) {
16417
+ const found = [];
16418
+ let pageCursor;
16419
+ do {
16420
+ const page = await catalog.searchFolderEntities({
16421
+ ...query,
16422
+ pageSize: 100,
16423
+ pageCursor
16424
+ });
16425
+ found.push(...(page.items ?? []).filter(match));
16426
+ pageCursor = page.nextPage ?? undefined;
16427
+ } while (pageCursor);
16428
+ return found;
16429
+ }
15848
16430
  function toResourceReference(entity) {
15849
16431
  return toCatalogReference({
15850
16432
  kind: entity.entityType ?? "",
@@ -15898,7 +16480,7 @@ function parseJsonString(raw) {
15898
16480
  return error ? undefined : parsed;
15899
16481
  }
15900
16482
  // ../solution-sdk/src/resources/services/resource-casing.ts
15901
- var RESOURCE_FILES_FOLDER_NAME = "resources";
16483
+ var RESOURCE_FILES_FOLDER_NAME2 = "resources";
15902
16484
  function lowerFirstChar(value) {
15903
16485
  return value ? value.charAt(0).toLowerCase() + value.slice(1) : value;
15904
16486
  }
@@ -15927,7 +16509,7 @@ async function saveCasingNormalized(builder) {
15927
16509
  }
15928
16510
  async function normalizeResourceFileCasing(solutionDir) {
15929
16511
  const fs = getFileSystem();
15930
- const root = fs.path.join(solutionDir, RESOURCE_FILES_FOLDER_NAME);
16512
+ const root = fs.path.join(solutionDir, RESOURCE_FILES_FOLDER_NAME2);
15931
16513
  if (!await fs.exists(root))
15932
16514
  return [];
15933
16515
  const byTarget = new Map;
@@ -15975,13 +16557,17 @@ function targetSegments(segments, kind, type) {
15975
16557
  const kindIndex = type ? target.length - 3 : target.length - 2;
15976
16558
  if (kindIndex < 0)
15977
16559
  return target;
15978
- if (target[kindIndex] === kind)
16560
+ if (sameIgnoringCase(target[kindIndex], kind)) {
15979
16561
  target[kindIndex] = lowerFirstChar(kind);
15980
- if (type && target[kindIndex + 1] === type) {
16562
+ }
16563
+ if (type && sameIgnoringCase(target[kindIndex + 1], type)) {
15981
16564
  target[kindIndex + 1] = lowerFirstChar(type);
15982
16565
  }
15983
16566
  return target;
15984
16567
  }
16568
+ function sameIgnoringCase(a, b) {
16569
+ return a.toLowerCase() === b.toLowerCase();
16570
+ }
15985
16571
  async function collectResourceFiles(root, segments) {
15986
16572
  const fs = getFileSystem();
15987
16573
  const [readError, names] = await catchError(fs.readdir(fs.path.join(root, ...segments)));
@@ -16054,6 +16640,118 @@ function parseResourceHeader(content) {
16054
16640
  return null;
16055
16641
  }
16056
16642
  }
16643
+ // ../solution-sdk/src/resources/services/resource-configurations.ts
16644
+ var ROOT_RESOURCE_TYPES = new Set(["resource", "solutionresource"]);
16645
+ var KEY_NOT_FOUND = /^(?:Solution)?Resource with key '([^']+)' was not found$/i;
16646
+ function isResourceKeyNotFound(error, resourceKey) {
16647
+ if (!(error instanceof Error))
16648
+ return false;
16649
+ const typed = error;
16650
+ const sameKey = (key) => key !== undefined && key.toLowerCase() === resourceKey.toLowerCase();
16651
+ if (typeof typed.resourceType === "string" && typeof typed.resourceKey === "string") {
16652
+ return ROOT_RESOURCE_TYPES.has(typed.resourceType.toLowerCase()) && sameKey(typed.resourceKey);
16653
+ }
16654
+ return sameKey(KEY_NOT_FOUND.exec(error.message.trim())?.[1]);
16655
+ }
16656
+ async function refreshArtefactSpecsAsync(builder, configurations) {
16657
+ const resources = new Map;
16658
+ const [loadError, solution] = await catchError(builder.context.loadAsync());
16659
+ if (loadError || !solution)
16660
+ return resources;
16661
+ for (const configuration of configurations) {
16662
+ const resource = solution.resources.find((r) => r.key === configuration?.key);
16663
+ if (!resource)
16664
+ continue;
16665
+ resources.set(resource.key, resource);
16666
+ if (!resource.projectKey)
16667
+ continue;
16668
+ configuration.spec = await applyEntryPointEnhancementAsync(builder.context, resource, configuration.spec ?? {});
16669
+ }
16670
+ return resources;
16671
+ }
16672
+ async function exportResourceConfigurationsAsync(services, resourceKey, hint = {}) {
16673
+ const { catalog, importer } = getRemoteResourceClients(services);
16674
+ const byKey = (item) => item.entityKey === resourceKey;
16675
+ const entity = (hint.name ? await findCatalogEntityAsync(catalog, { name: hint.name }, byKey) : undefined) ?? await findCatalogEntityAsync(catalog, {}, byKey);
16676
+ if (!entity) {
16677
+ throw new Error(`Resource '${resourceKey}' was not found in the solution or in the resource catalog`);
16678
+ }
16679
+ const payload = await importer.exportResourceAsync(toResourceReference(entity));
16680
+ const definitions = payload.resourceDefinitions ?? [];
16681
+ if (definitions.length === 0) {
16682
+ throw new Error(`FPS export for '${resourceKey}' returned no resource definitions`);
16683
+ }
16684
+ return {
16685
+ resources: definitions.map((d) => ({
16686
+ key: d.key ?? "",
16687
+ spec: d.spec ?? {},
16688
+ locks: d.locks ?? [],
16689
+ apiVersion: d.apiVersion,
16690
+ isOverridable: d.isOverridable,
16691
+ name: d.name ?? "",
16692
+ kind: d.kind ?? "",
16693
+ dependencies: (d.dependencies ?? []).map((dep) => ({
16694
+ kind: dep.kind ?? "",
16695
+ name: dep.name ?? ""
16696
+ }))
16697
+ }))
16698
+ };
16699
+ }
16700
+ async function readLocalAsync(builder, resourceKey, read) {
16701
+ if (!builder)
16702
+ return;
16703
+ const [error, value] = await catchError(read(builder));
16704
+ if (!error)
16705
+ return { builder, value };
16706
+ if (isResourceKeyNotFound(error, resourceKey))
16707
+ return;
16708
+ throw error;
16709
+ }
16710
+ async function readResourceConfigurationsAsync(services, builder, resourceKey, hint = {}) {
16711
+ const local = await readLocalAsync(builder, resourceKey, (b) => b.getAllConfigurationsAsync(resourceKey));
16712
+ if (!local) {
16713
+ return exportResourceConfigurationsAsync(services, resourceKey, hint);
16714
+ }
16715
+ await refreshArtefactSpecsAsync(local.builder, local.value?.resources ?? []);
16716
+ return local.value;
16717
+ }
16718
+ async function readResourceConfigurationAsync(services, builder, resourceKey) {
16719
+ const local = await readLocalAsync(builder, resourceKey, (b) => b.getConfigurationAsync(resourceKey));
16720
+ if (local) {
16721
+ const configuration = local.value;
16722
+ const resources2 = await refreshArtefactSpecsAsync(local.builder, [
16723
+ configuration
16724
+ ]);
16725
+ return { configuration, resource: resources2.get(configuration.key) };
16726
+ }
16727
+ const { resources } = await exportResourceConfigurationsAsync(services, resourceKey);
16728
+ const primary = resources.find((r) => r.key === resourceKey) ?? resources[0];
16729
+ const { key, spec, locks, apiVersion, isOverridable } = primary;
16730
+ return { configuration: { key, spec, locks, apiVersion, isOverridable } };
16731
+ }
16732
+ // ../solution-sdk/src/resources/services/resource-lookup.ts
16733
+ async function findResourcesByNameAsync(services, builder, { kind, name, subTypes, folderKey }) {
16734
+ const same = (a, b) => (a ?? "").toLowerCase() === b.toLowerCase();
16735
+ const ofSubType = (type) => subTypes === undefined || subTypes.some((t) => same(type, t));
16736
+ if (builder) {
16737
+ const solution = await builder.context.loadAsync();
16738
+ const local = solution.resources.filter((r) => same(r.kind, kind) && same(r.name, name) && ofSubType(r.type)).map((r) => ({
16739
+ key: r.key,
16740
+ local: true,
16741
+ folderPath: r.folders?.[0]?.fullyQualifiedName
16742
+ }));
16743
+ if (local.length > 0)
16744
+ return local;
16745
+ }
16746
+ const { catalog } = getRemoteResourceClients(services);
16747
+ const rows = await findCatalogEntitiesAsync(catalog, { name, entityTypes: [kind] }, (row) => same(row.entityType, kind) && same(row.entityName, name) && ofSubType(row.entitySubType) && (folderKey === undefined || same(row.folderKey, folderKey)));
16748
+ return rows.map((row) => ({
16749
+ key: row.entityKey ?? "",
16750
+ local: false,
16751
+ folderPath: row.fullyQualifiedName ?? undefined,
16752
+ folderKey: row.folderKey ?? undefined
16753
+ }));
16754
+ }
16057
16755
  // ../solution-sdk/src/resources/services/resource-name.ts
16058
16756
  var MAX_RESOURCE_NAME_LENGTH = 256;
16059
16757
  var UNSAFE_NAME_CHARS = /[\\/:*?"<>|]/;
@@ -16095,32 +16793,15 @@ function assertValidResourceName(name, options = {}) {
16095
16793
  throw new Error(`${result.message}. ${result.instructions}`);
16096
16794
  }
16097
16795
  }
16098
- // ../solution-sdk/src/solution-auth.ts
16099
- async function getSolutionAuthContext(options) {
16100
- const ctx = await getAuthContext({
16101
- tenant: options.tenant,
16102
- ensureTokenValidityMinutes: options.loginValidity ?? 10,
16103
- envFilePath: options.envFilePath,
16104
- requireOrganizationId: true,
16105
- requireTenantName: true
16106
- });
16107
- const organizationId = ctx.organizationId;
16108
- const tenantName = ctx.tenantName;
16109
- const basePath = `${ctx.baseUrl}/${organizationId}/${tenantName}/automationsolutions_`;
16110
- return {
16111
- accessToken: ctx.accessToken,
16112
- basePath,
16113
- organizationId,
16114
- tenantName,
16115
- identity: ctx.identity
16116
- };
16117
- }
16118
16796
  // ../solution-sdk/src/resources/services/sync-resources-from-bindings.ts
16119
16797
  var TYPE_IS_IDENTITY_REPLACE_OPTIONS = new Set([
16120
16798
  "SameType",
16121
16799
  "SameNameAndType"
16122
16800
  ]);
16123
16801
  var BINDINGS_JSON_FALLBACK_TYPES = new Set(["agent", "function"]);
16802
+
16803
+ class OverwriteRefreshError extends Error {
16804
+ }
16124
16805
  function placeholderForType(type) {
16125
16806
  switch ((type ?? "string").toLowerCase()) {
16126
16807
  case "boolean":
@@ -16221,13 +16902,15 @@ function resolveBindingResourceIdentity(binding) {
16221
16902
  };
16222
16903
  }
16223
16904
  }
16224
- async function syncResourcesFromBindings(solutionDir, projectPaths, projectSubTypes) {
16905
+ async function syncResourcesFromBindings(solutionDir, projectPaths, projectSubTypes, projectBindings) {
16225
16906
  const result = {
16226
16907
  created: 0,
16227
16908
  imported: 0,
16228
16909
  skipped: 0,
16229
16910
  pruned: 0,
16230
- warnings: []
16911
+ projectResourcesCreated: 0,
16912
+ warnings: [],
16913
+ unresolved: []
16231
16914
  };
16232
16915
  const uipxProjects = await readUipxProjects(solutionDir);
16233
16916
  const paths = projectPaths ?? uipxProjects.map((p) => p.path);
@@ -16241,7 +16924,7 @@ async function syncResourcesFromBindings(solutionDir, projectPaths, projectSubTy
16241
16924
  return result;
16242
16925
  }
16243
16926
  const serializer = services.container.resolve(Tokens.IBindingsMetadataSerializer);
16244
- const { bindings: allBindings, parseErrors } = await collectBindings(solutionDir, paths, bindingsJsonFallbackDirs, serializer);
16927
+ const { bindings: allBindings, parseErrors } = await collectBindings(bindingsJsonFallbackDirs, serializer, bindingSources(solutionDir, paths, uipxProjects, projectBindings));
16245
16928
  if (parseErrors.length > 0) {
16246
16929
  const detail = parseErrors.map((e) => `${e.path}: ${e.reason}`).join("; ");
16247
16930
  throw new Error(`Invalid bindings file — ${detail}`);
@@ -16255,7 +16938,8 @@ async function syncResourcesFromBindings(solutionDir, projectPaths, projectSubTy
16255
16938
  logger.warn(`Failed to get solution builder: ${builderError.message}`);
16256
16939
  return result;
16257
16940
  }
16258
- await reconcileSolutionProjects(builder, solutionDir, projectSubTypes);
16941
+ const reconcileOutcome = await reconcileSolutionProjects(builder, solutionDir, projectSubTypes);
16942
+ result.projectResourcesCreated = reconcileOutcome.resourcesAdded;
16259
16943
  const memberProjectKeys = new Set(uipxProjects.map((project) => project.id.toLowerCase()));
16260
16944
  await pruneMemberClones(builder, memberProjectKeys, result);
16261
16945
  if (allBindings.length === 0) {
@@ -16270,6 +16954,28 @@ async function syncResourcesFromBindings(solutionDir, projectPaths, projectSubTy
16270
16954
  const resolveKindMetadata = await buildKindResolver(metadataReader);
16271
16955
  const solution = await builder.context.loadAsync();
16272
16956
  const knownResourceKeys = new Set((solution.resources ?? []).map((r) => r.key?.toLowerCase()).filter((k) => !!k));
16957
+ let keptUnchecked = 0;
16958
+ const resolvedKeys = new Set;
16959
+ const overwrittenKeys = new Set;
16960
+ const bindingKey = (kind, name) => `${kind}:${name ?? ""}`.toLowerCase();
16961
+ const recordUnchecked = async (error, kind, name, directCloudKey) => {
16962
+ if (error) {
16963
+ const failure = classifyCatalogFailure(error);
16964
+ if (!result.catalogLookupFailure || stopsCatalogLookups(failure) && !stopsCatalogLookups(result.catalogLookupFailure)) {
16965
+ result.catalogLookupFailure = failure;
16966
+ }
16967
+ }
16968
+ const covered = await isUncheckedBindingCovered(builder, knownResourceKeys, kind, name, directCloudKey);
16969
+ if (covered) {
16970
+ keptUnchecked++;
16971
+ result.skipped++;
16972
+ return;
16973
+ }
16974
+ result.unresolved.push({
16975
+ kind,
16976
+ name: directCloudKey ?? name
16977
+ });
16978
+ };
16273
16979
  const virtualCandidates = [];
16274
16980
  for (const binding of allBindings) {
16275
16981
  const identity = resolveBindingResourceIdentity(binding);
@@ -16299,7 +17005,12 @@ async function syncResourcesFromBindings(solutionDir, projectPaths, projectSubTy
16299
17005
  logger.info(`Skipping ${kind} "${name}" — the solution provisions this project itself; its member declaration covers the binding`);
16300
17006
  continue;
16301
17007
  }
16302
- const rcsMatch = directCloudKey ? await findResourceByKeyInRcs(builder, kind, directCloudKey, folderPath) : await findResourceInRcs(builder, kind, name, folderPath);
17008
+ const lookupsStopped = !!result.catalogLookupFailure && stopsCatalogLookups(result.catalogLookupFailure);
17009
+ const [lookupError, rcsMatch] = lookupsStopped ? [undefined, undefined] : await catchError(directCloudKey ? findResourceByKeyInRcs(builder, kind, directCloudKey, folderPath, true) : findResourceInRcs(builder, kind, name, folderPath, true));
17010
+ if (lookupsStopped || lookupError) {
17011
+ await recordUnchecked(lookupError, kind, name, directCloudKey);
17012
+ continue;
17013
+ }
16303
17014
  const resolvedType = identity.type ?? rcsMatch?.type ?? metadata?.type;
16304
17015
  if (!rcsMatch) {
16305
17016
  if (isConnection) {
@@ -16318,30 +17029,48 @@ async function syncResourcesFromBindings(solutionDir, projectPaths, projectSubTy
16318
17029
  }
16319
17030
  if (!isConnection && rcsMatch.key && knownResourceKeys.has(rcsMatch.key.toLowerCase())) {
16320
17031
  result.skipped++;
17032
+ resolvedKeys.add(bindingKey(kind, name));
16321
17033
  continue;
16322
17034
  }
16323
17035
  const callType = isConnection ? binding.metadata?.connector : resolvedType;
16324
- const [importError] = await catchError(builder.addOrUpdateResourceToSolutionAsync({
17036
+ const wasKnown = !!rcsMatch.key && knownResourceKeys.has(rcsMatch.key.toLowerCase());
17037
+ const reference = {
16325
17038
  kind,
16326
17039
  type: callType,
16327
17040
  key: rcsMatch.key,
16328
17041
  name: rcsMatch.name,
16329
17042
  folder: rcsMatch.folder
16330
- }, true));
17043
+ };
17044
+ const [importError] = await catchError(wasKnown ? refreshKnownResource(services, builder, reference, overwrittenKeys) : builder.addOrUpdateResourceToSolutionAsync(reference, true));
16331
17045
  if (!importError) {
17046
+ resolvedKeys.add(bindingKey(kind, directCloudKey ?? name));
17047
+ if (wasKnown) {
17048
+ result.skipped++;
17049
+ logger.info(`Refreshed ${kind} "${rcsMatch.name}" (key: ${rcsMatch.key}), already in solution`);
17050
+ continue;
17051
+ }
16332
17052
  if (rcsMatch.key) {
16333
17053
  knownResourceKeys.add(rcsMatch.key.toLowerCase());
17054
+ overwrittenKeys.add(rcsMatch.key.toLowerCase());
16334
17055
  }
16335
17056
  result.imported++;
16336
17057
  logger.info(`Imported ${kind} "${rcsMatch.name}" (key: ${rcsMatch.key}) into solution`);
16337
17058
  continue;
16338
17059
  }
17060
+ if (stopsCatalogLookups(classifyCatalogFailure(importError))) {
17061
+ await recordUnchecked(importError, kind, name, directCloudKey);
17062
+ continue;
17063
+ }
16339
17064
  if (isConnection) {
16340
- result.warnings.push(`Failed to import connection ${directCloudKey}: ${importError.message}`);
16341
- logger.warn(`Failed to import connection ${directCloudKey}: ${importError.message}`);
17065
+ const failedStep = importError instanceof OverwriteRefreshError ? "refresh the debug overwrite for" : "import";
17066
+ const warning = `Failed to ${failedStep} connection ${directCloudKey}: ${importError.message}`;
17067
+ result.warnings.push(warning);
17068
+ logger.warn(warning);
16342
17069
  continue;
16343
17070
  }
16344
- logger.warn(`Failed to import ${kind} "${name}" from Orchestrator: ${importError.message}. Will create locally instead.`);
17071
+ const importWarning = `Failed to import ${kind} "${name}" from Orchestrator: ${importError.message}. Created it locally instead; link it before deploy if it must point at the cloud resource.`;
17072
+ result.warnings.push(importWarning);
17073
+ logger.warn(importWarning);
16345
17074
  virtualCandidates.push({
16346
17075
  binding,
16347
17076
  kind,
@@ -16360,11 +17089,29 @@ async function syncResourcesFromBindings(solutionDir, projectPaths, projectSubTy
16360
17089
  return true;
16361
17090
  });
16362
17091
  for (const candidate of dedupedVirtuals) {
16363
- const [syncError] = await catchError(createVirtualForBinding(builder, candidate.binding, candidate.kind, candidate.type, candidate.metadata, candidate.name, candidate.folderPath, result));
17092
+ const [syncError, created] = await catchError(createVirtualForBinding(builder, candidate.binding, candidate.kind, candidate.type, candidate.metadata, candidate.name, candidate.folderPath, result));
16364
17093
  if (syncError) {
16365
17094
  logger.warn(`Failed to create virtual ${candidate.kind}/${candidate.name}: ${syncError.message}`);
17095
+ } else if (created) {
17096
+ resolvedKeys.add(bindingKey(candidate.kind, candidate.name));
16366
17097
  }
16367
17098
  }
17099
+ if (result.catalogLookupFailure) {
17100
+ const seen = new Set;
17101
+ result.unresolved = result.unresolved.filter((b) => {
17102
+ const key = bindingKey(b.kind, b.name);
17103
+ if (resolvedKeys.has(key)) {
17104
+ keptUnchecked++;
17105
+ result.skipped++;
17106
+ return false;
17107
+ }
17108
+ if (seen.has(key))
17109
+ return false;
17110
+ seen.add(key);
17111
+ return true;
17112
+ });
17113
+ result.warnings.push(catalogLookupWarning(result.catalogLookupFailure, keptUnchecked, result.unresolved));
17114
+ }
16368
17115
  const saveError = await saveAndDisposeBuilder(builder, solutionDir);
16369
17116
  if (saveError) {
16370
17117
  throw new Error(`Failed to save solution changes: ${saveError.message}`);
@@ -16392,6 +17139,43 @@ async function pruneMemberClones(builder, memberProjectKeys, result) {
16392
17139
  logger.info(`Removed duplicate ${clone.kind} "${clone.name}" (key: ${clone.key}) — the solution provisions this project itself`);
16393
17140
  }
16394
17141
  }
17142
+ async function isUncheckedBindingCovered(builder, knownResourceKeys, kind, name, directCloudKey) {
17143
+ if (directCloudKey) {
17144
+ return knownResourceKeys.has(directCloudKey.toLowerCase());
17145
+ }
17146
+ const solution = await builder.context.loadAsync();
17147
+ return !!findMatchingLocalResource(solution.resources ?? [], kind, name, undefined);
17148
+ }
17149
+ async function refreshKnownResource(services, builder, reference, overwrittenKeys) {
17150
+ const solution = await builder.context.loadAsync();
17151
+ const referenceKey = reference.key.toLowerCase();
17152
+ const existing = (solution.resources ?? []).find((resource) => resource.key?.toLowerCase() === referenceKey);
17153
+ const mediator = services.container.resolve(Tokens.IMediator);
17154
+ const response = await mediator.sendCommandAsync(new AddOrUpdateResourceToSolutionCommand(builder.context, reference, true, existing?.key));
17155
+ const sdkWroteOverwrite = response.saved && existing?.key === reference.key;
17156
+ if (!existing || sdkWroteOverwrite || overwrittenKeys.has(referenceKey)) {
17157
+ overwrittenKeys.add(referenceKey);
17158
+ return response;
17159
+ }
17160
+ const [overwriteError] = await catchError(refreshOverwrite(services, builder, reference, existing.key));
17161
+ if (overwriteError)
17162
+ throw new OverwriteRefreshError(overwriteError.message);
17163
+ overwrittenKeys.add(referenceKey);
17164
+ return response;
17165
+ }
17166
+ async function refreshOverwrite(services, builder, reference, solutionResourceKey) {
17167
+ const importer = services.container.resolve(Tokens.IImportResourceHelper);
17168
+ const payload = await importer.exportResourceAsync(reference);
17169
+ const referenceKey = reference.key.toLowerCase();
17170
+ const overwrite = [...payload.overwrites].find(([key]) => key.toLowerCase() === referenceKey)?.[1];
17171
+ if (!overwrite) {
17172
+ throw new Error(`Overwrite not found for resource key '${reference.key}' in exported payload`);
17173
+ }
17174
+ const overwrites = services.container.resolve(Tokens.IResourceOverwritesService);
17175
+ await overwrites.manageSolutionOverwritesAsync(builder.context, [
17176
+ { solutionResourceKey, overwrite }
17177
+ ]);
17178
+ }
16395
17179
  async function saveAndDisposeBuilder(builder, solutionDir) {
16396
17180
  const context = builder.context;
16397
17181
  if (!context?.forceSaveChangesAsync) {
@@ -16461,11 +17245,11 @@ async function createVirtualForBinding(builder, _binding, kind, type, metadata,
16461
17245
  if (alreadyVirtualized) {
16462
17246
  result.skipped++;
16463
17247
  logger.info(`Skipping virtual ${kind} "${name}" — existing resource "${alreadyVirtualized.name}" in solution_folder already covers this binding (requested folder "${folderPath}")`);
16464
- return;
17248
+ return true;
16465
17249
  }
16466
17250
  const minted = await mintVirtualResource(builder, kind, type, name, metadata);
16467
17251
  if (!minted)
16468
- return;
17252
+ return false;
16469
17253
  result.created++;
16470
17254
  logger.info(`Created ${kind} "${name}" in solution`);
16471
17255
  if (!virtualizable) {
@@ -16473,6 +17257,7 @@ async function createVirtualForBinding(builder, _binding, kind, type, metadata,
16473
17257
  result.warnings.push(warning);
16474
17258
  logger.warn(warning);
16475
17259
  }
17260
+ return true;
16476
17261
  }
16477
17262
  async function findResourceByKeyInRcs(builder, kind, expectedKey, folderPath, propagateErrors = false) {
16478
17263
  const expectedLower = expectedKey.toLowerCase();
@@ -16550,8 +17335,8 @@ async function searchRcsResourcesStrict(builder, kind, name) {
16550
17335
  } while (pageCursor);
16551
17336
  return allMatches;
16552
17337
  }
16553
- async function findResourceInRcs(builder, kind, name, folderPath) {
16554
- const allMatches = await searchRcsResources(builder, kind, name);
17338
+ async function findResourceInRcs(builder, kind, name, folderPath, propagateErrors = false) {
17339
+ const allMatches = propagateErrors ? await searchRcsResourcesStrict(builder, kind, name) : await searchRcsResources(builder, kind, name);
16555
17340
  if (allMatches.length === 0) {
16556
17341
  return;
16557
17342
  }
@@ -16649,9 +17434,15 @@ async function readUiprojName(uiprojPath) {
16649
17434
  return;
16650
17435
  }
16651
17436
  }
17437
+ async function snapshotResourceIdentities(builder) {
17438
+ const [loadError, solution] = await catchError(builder.context.loadAsync());
17439
+ if (loadError || !solution)
17440
+ return;
17441
+ return new Set((solution.resources ?? []).map((resource) => resource.key ? resource.key.toLowerCase() : `${resource.kind}:${resource.name}`.toLowerCase()));
17442
+ }
16652
17443
  async function reconcileSolutionProjects(builder, solutionDir, projectSubTypes) {
16653
17444
  const fs = getFileSystem();
16654
- const outcome = { projectsCount: 0 };
17445
+ const outcome = { projectsCount: 0, resourcesAdded: 0 };
16655
17446
  const uipxProjects = await readUipxProjects(solutionDir);
16656
17447
  const projectDetails = uipxProjects.flatMap((project) => {
16657
17448
  const reconcileType = mapUipxTypeToReconcileType(project.type);
@@ -16669,6 +17460,7 @@ async function reconcileSolutionProjects(builder, solutionDir, projectSubTypes)
16669
17460
  if (projectDetails.length === 0)
16670
17461
  return outcome;
16671
17462
  const solutionName = fs.path.basename(solutionDir);
17463
+ const before = await snapshotResourceIdentities(builder);
16672
17464
  const [reconcileError] = await catchError(builder.reconcileProjectsAsync({
16673
17465
  solutionName,
16674
17466
  projects: projectDetails
@@ -16678,6 +17470,10 @@ async function reconcileSolutionProjects(builder, solutionDir, projectSubTypes)
16678
17470
  return outcome;
16679
17471
  }
16680
17472
  outcome.projectsCount = projectDetails.length;
17473
+ const after = before && await snapshotResourceIdentities(builder);
17474
+ if (before && after) {
17475
+ outcome.resourcesAdded = [...after].filter((identity) => !before.has(identity)).length;
17476
+ }
16681
17477
  logger.info(`Reconciled ${projectDetails.length} .uipx project(s) in solution ${solutionName}`);
16682
17478
  return outcome;
16683
17479
  }
@@ -16719,12 +17515,48 @@ function findBindingsSchemaError(content) {
16719
17515
  }
16720
17516
  return null;
16721
17517
  }
16722
- async function collectBindings(solutionDir, projectPaths, bindingsJsonFallbackDirs, serializer) {
17518
+ function bindingSources(solutionDir, projectPaths, projects, projectBindings) {
17519
+ const sources = [{ directory: solutionDir }];
17520
+ const fileDirectories = new Set([solutionDir]);
17521
+ const contributedIds = new Set;
17522
+ for (const directory of new Set(projectPaths)) {
17523
+ const owners = projects.filter((project) => project.path === directory);
17524
+ for (const project of owners) {
17525
+ const bindings = projectBindings?.get(project.id);
17526
+ if (bindings === undefined || contributedIds.has(project.id))
17527
+ continue;
17528
+ contributedIds.add(project.id);
17529
+ sources.push({
17530
+ directory,
17531
+ contribution: { projectId: project.id, bindings }
17532
+ });
17533
+ }
17534
+ const needsFile = owners.length === 0 || owners.some((project) => !projectBindings?.has(project.id));
17535
+ if (needsFile && !fileDirectories.has(directory)) {
17536
+ fileDirectories.add(directory);
17537
+ sources.push({ directory });
17538
+ }
17539
+ }
17540
+ return sources;
17541
+ }
17542
+ async function collectBindings(bindingsJsonFallbackDirs, serializer, sources) {
16723
17543
  const fs = getFileSystem();
16724
17544
  const allBindings = [];
16725
17545
  const parseErrors = [];
16726
- const candidateDirs = [solutionDir, ...projectPaths];
16727
- for (const dir of candidateDirs) {
17546
+ for (const { directory: dir, contribution } of sources) {
17547
+ if (contribution) {
17548
+ if (contribution.bindings.length === 0)
17549
+ continue;
17550
+ const parsed2 = deserializeBindings(JSON.stringify({
17551
+ version: "2.0",
17552
+ resources: contribution.bindings
17553
+ }), `${dir} (bindings contributed by the project's tool; project ${contribution.projectId})`, serializer);
17554
+ if ("error" in parsed2)
17555
+ parseErrors.push(parsed2.error);
17556
+ else
17557
+ allBindings.push(...parsed2.resources);
17558
+ continue;
17559
+ }
16728
17560
  const v2Path = fs.path.join(dir, "bindings_v2.json");
16729
17561
  let bindingsPath = v2Path;
16730
17562
  let exists = await fs.exists(v2Path);
@@ -16743,37 +17575,44 @@ async function collectBindings(solutionDir, projectPaths, bindingsJsonFallbackDi
16743
17575
  });
16744
17576
  continue;
16745
17577
  }
16746
- const decoded = new TextDecoder().decode(content);
16747
- let success;
16748
- let metadata;
16749
- try {
16750
- const result = serializer.tryDeserialize(decoded);
16751
- success = result.success;
16752
- metadata = result.metadata;
16753
- } catch (err) {
16754
- parseErrors.push({
16755
- path: bindingsPath,
17578
+ const parsed = deserializeBindings(new TextDecoder().decode(content), bindingsPath, serializer);
17579
+ if ("error" in parsed)
17580
+ parseErrors.push(parsed.error);
17581
+ else
17582
+ allBindings.push(...parsed.resources);
17583
+ }
17584
+ return { bindings: allBindings, parseErrors };
17585
+ }
17586
+ function deserializeBindings(decoded, source, serializer) {
17587
+ let success;
17588
+ let metadata;
17589
+ try {
17590
+ const result = serializer.tryDeserialize(decoded);
17591
+ success = result.success;
17592
+ metadata = result.metadata;
17593
+ } catch (err) {
17594
+ return {
17595
+ error: {
17596
+ path: source,
16756
17597
  reason: findBindingsSchemaError(decoded) ?? `does not match the expected v2 bindings schema — check each resource's 'kind' and required fields${err instanceof Error ? ` (${err.message})` : ""}`
16757
- });
16758
- continue;
16759
- }
16760
- if (!success) {
16761
- parseErrors.push({
16762
- path: bindingsPath,
17598
+ }
17599
+ };
17600
+ }
17601
+ if (!success) {
17602
+ return {
17603
+ error: {
17604
+ path: source,
16763
17605
  reason: findBindingsSchemaError(decoded) ?? "does not match the expected v2 bindings schema (the serializer rejected it)"
16764
- });
16765
- continue;
16766
- }
16767
- if (!metadata?.resources?.length) {
16768
- continue;
16769
- }
16770
- allBindings.push(...metadata.resources);
17606
+ }
17607
+ };
16771
17608
  }
16772
- return { bindings: allBindings, parseErrors };
17609
+ return { resources: metadata?.resources ?? [] };
16773
17610
  }
16774
- async function syncAndLog(solutionDir, projectSubTypes) {
16775
- const [syncError, syncResult] = await catchError(syncResourcesFromBindings(solutionDir, undefined, projectSubTypes));
17611
+ async function syncAndLog(solutionDir, projectSubTypes, options) {
17612
+ const [syncError, syncResult] = await catchError(syncResourcesFromBindings(solutionDir, undefined, projectSubTypes, options?.projectBindings));
16776
17613
  if (syncError) {
17614
+ if (options?.failOnUnresolved)
17615
+ throw syncError;
16777
17616
  logger.warn(`Resource sync failed: ${syncError.message}. Continuing.`);
16778
17617
  return;
16779
17618
  }
@@ -16783,6 +17622,9 @@ async function syncAndLog(solutionDir, projectSubTypes) {
16783
17622
  for (const warning of syncResult.warnings) {
16784
17623
  logger.warn(warning);
16785
17624
  }
17625
+ if (options?.failOnUnresolved && syncResult.catalogLookupFailure && syncResult.unresolved.length > 0) {
17626
+ throw new CatalogLookupError(syncResult.catalogLookupFailure, syncResult.unresolved);
17627
+ }
16786
17628
  }
16787
17629
 
16788
17630
  // ../solution-sdk/src/resources/services/resource-refresh-service.ts
@@ -16819,7 +17661,11 @@ async function resourceRefreshAsync(solutionPath = ".", options = {}) {
16819
17661
  const resolverWarnings = subTypesError ? [
16820
17662
  `Could not resolve project subTypes: ${subTypesError.message}. Project artefacts for types that need a variant were left as they are; fix the tool install and re-run 'uip solution resources refresh'.`
16821
17663
  ] : [];
16822
- const [syncError, result] = await catchError(syncResourcesFromBindings(resolvedPath, undefined, projectSubTypes ?? new Map));
17664
+ const [bindingsError, projectBindings] = await catchError(options.resolveProjectBindingsAsync?.() ?? Promise.resolve(new Map));
17665
+ if (bindingsError) {
17666
+ resolverWarnings.push(`Could not read the bindings projects contribute: ${bindingsError.message}. Those projects were synced from any bindings_v2.json on disk instead; fix the tool install and re-run 'uip solution resources refresh'.`);
17667
+ }
17668
+ const [syncError, result] = await catchError(syncResourcesFromBindings(resolvedPath, undefined, projectSubTypes ?? new Map, projectBindings ?? new Map));
16823
17669
  if (syncError) {
16824
17670
  return {
16825
17671
  ok: false,
@@ -16833,6 +17679,7 @@ async function resourceRefreshAsync(solutionPath = ".", options = {}) {
16833
17679
  imported: result.imported,
16834
17680
  skipped: result.skipped,
16835
17681
  pruned: result.pruned,
17682
+ projectResourcesCreated: result.projectResourcesCreated,
16836
17683
  warnings: [...resolverWarnings, ...result.warnings]
16837
17684
  };
16838
17685
  }
@@ -17014,6 +17861,7 @@ function sortKeysDeep(value) {
17014
17861
  return sorted;
17015
17862
  }
17016
17863
  export {
17864
+ CatalogLookupError,
17017
17865
  EntryPointSpecEnhancer,
17018
17866
  MAX_RESOURCE_NAME_LENGTH,
17019
17867
  ProjectManifestError,
@@ -17026,7 +17874,9 @@ export {
17026
17874
  createProjectInSolutionBuilder,
17027
17875
  createResourceBuilderServices,
17028
17876
  createResourceKindMetadataResolver,
17877
+ exportResourceConfigurationsAsync,
17029
17878
  exportResourceDefinitionAsync,
17879
+ findCatalogEntitiesAsync,
17030
17880
  findCatalogEntityAsync,
17031
17881
  findMatchingLocalResource,
17032
17882
  findMatchingMemberResource,
@@ -17034,21 +17884,26 @@ export {
17034
17884
  findProjectFile,
17035
17885
  findResourceByKeyInRcs,
17036
17886
  findResourceInRcs,
17887
+ findResourcesByNameAsync,
17037
17888
  formatResourceSubtypes,
17038
17889
  getRemoteResourceClients,
17039
17890
  hasAnyTemplateRow,
17040
17891
  hasBareTemplateRow,
17041
17892
  isMissingProjectTypeError,
17042
17893
  isProjectManifestError,
17894
+ isResourceKeyNotFound,
17043
17895
  normalizeFolderPath,
17044
17896
  normalizeResourceCasing,
17045
17897
  normalizeResourceFileCasing,
17046
17898
  readProjectFile,
17899
+ readResourceConfigurationAsync,
17900
+ readResourceConfigurationsAsync,
17047
17901
  readSolutionFile,
17048
17902
  readSolutionManifest,
17049
17903
  readSpecEntryPoints,
17050
17904
  readSpecProperty,
17051
17905
  readUipxProjects,
17906
+ refreshArtefactSpecsAsync,
17052
17907
  resolveProjectDirFromManifest,
17053
17908
  resolveResourceKindMetadata,
17054
17909
  resolveSolutionFilePath,
@@ -17068,4 +17923,4 @@ export {
17068
17923
  writeSolutionFile
17069
17924
  };
17070
17925
 
17071
- //# debugId=DD659B11A166BFC064756E2164756E21
17926
+ //# debugId=EF208697C79EBB8D64756E2164756E21