@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.
- package/README.md +9 -9
- package/dist/THIRD-PARTY-NOTICES.md +39 -15
- package/dist/{authoring-bppe07p0.js → authoring-e1k40hyw.js} +6 -5
- package/dist/{binding-service-xwgsn35p.js → binding-service-pdtxvvt8.js} +38 -30
- package/dist/{connector-service-r0w8ztas.js → connector-service-pm9hfmsv.js} +224 -47
- package/dist/de-UZI7FJDO-awjpqfz0.js +200 -0
- package/dist/{de-MUJPA4EB-dpg7t2rw.js → de-UZI7FJDO-mwvc4cxe.js} +29 -2
- package/dist/{de-FGHEJRCI-rv513mfh.js → de-WLW6KWOJ-2qnsqdtw.js} +238 -31
- package/dist/debug-conversation-trigger-xsm3ycqx.js +30 -0
- package/dist/{debug-http-client-p4kf38yt.js → debug-http-client-yqjzsnhw.js} +5 -4
- package/dist/{debug-service-893erynq.js → debug-service-nra3n02y.js} +6 -5
- package/dist/{edge-service-yzsfw4bs.js → edge-service-mddnjwb0.js} +16 -12
- package/dist/{embedded-file-reader-v8c2yj2a.js → embedded-file-reader-r66242ey.js} +2 -2
- package/dist/en-EJCBA3LK-0wb3b1xy.js +146 -0
- package/dist/{en-FBPVNKFN-dqt573xn.js → en-EJCBA3LK-dtpdghgj.js} +12 -4
- package/dist/{en-BWGKA5OE-1qkvb9rn.js → en-M7GQYBV2-5nfmpnfz.js} +88 -6
- package/dist/{es-7SE7HX2X-8yh1aj2y.js → es-4UBUTCQA-m1ytpyx2.js} +29 -2
- package/dist/es-4UBUTCQA-t7hsackg.js +200 -0
- package/dist/{es-KR3ZSNMP-84zphx0x.js → es-5THCNRFN-tqwyrdgy.js} +235 -28
- package/dist/{es-MX-2MYFZU7X-3rek4r73.js → es-MX-5RELIXKI-9jhqtddc.js} +29 -2
- package/dist/es-MX-5RELIXKI-jtjbcxbb.js +200 -0
- package/dist/{es-MX-XXZJGC4R-2mr8jtgm.js → es-MX-TWZBRAXK-gqd9swzw.js} +237 -30
- package/dist/filter-engine-7ep90g7f.js +11 -0
- package/dist/{flow-api-kjvpsxhw.js → flow-api-sat010z1.js} +16 -10
- package/dist/{flow-debug-service-dd10rg08.js → flow-debug-service-dw0d9cv7.js} +96 -58
- package/dist/{flow-eval-node-target-2ekp77s6.js → flow-eval-node-target-wttmdm4v.js} +17 -17
- package/dist/flow-eval-run-api-xdygjzfv.js +13 -0
- package/dist/{flow-eval-run-service-twzbmeq6.js → flow-eval-run-service-g09w4m9m.js} +73 -80
- package/dist/{flow-eval-service-ckwx7d5z.js → flow-eval-service-jfkz0tae.js} +167 -415
- package/dist/{flow-init-sdk-source-z9qx1zkt.js → flow-init-sdk-source-xvdvkq7d.js} +6 -5
- package/dist/{flow-init-service-m6swzk43.js → flow-init-service-5v6zwhas.js} +19 -15
- package/dist/{flow-io-tnrc53z6.js → flow-io-64tmj8n7.js} +15 -11
- package/dist/{flow-migrate-service-625gppk0.js → flow-migrate-service-bjxs35ac.js} +16 -12
- package/dist/{flow-pack-service-qdpvrmme.js → flow-pack-service-s75qhtn5.js} +47 -38
- package/dist/flow-validate-service-rbvgesrb.js +70 -0
- package/dist/{fr-Y6NPVODW-8vr1ja4b.js → fr-CERONSRC-edpxhbmb.js} +237 -30
- package/dist/{fr-MDFKNZ4C-h4a122k9.js → fr-VBM5WRC2-63z7w4mh.js} +29 -2
- package/dist/fr-VBM5WRC2-707ha692.js +200 -0
- package/dist/{governance-fetcher-zq8zmfjb.js → governance-fetcher-tw83p74c.js} +7 -6
- package/dist/{hitl-service-r19zvqsz.js → hitl-service-hgg9tr5j.js} +15 -11
- package/dist/{index-b8n7hv68.js → index-09mfatmh.js} +6 -5
- package/dist/{index-aaq9rwfv.js → index-1b2je9n2.js} +1088 -233
- package/dist/index-d090f35d.js +66 -0
- package/dist/{index-yj4xk2aw.js → index-dgdnbb2g.js} +7 -5
- package/dist/{index-ng2f77my.js → index-fyc0k5dd.js} +985 -617
- package/dist/{index-vrhcbxnk.js → index-nsn889vf.js} +6 -5
- package/dist/{index-2s8rmmw6.js → index-sqhbn7ew.js} +4 -4
- package/dist/{index-tnz5ks4t.js → index-wycgq0ff.js} +65 -2230
- package/dist/index.js +17 -14
- package/dist/init.js +19 -15
- package/dist/inline-entity-resolver-2qqf1635.js +45 -0
- package/dist/input-reader-n7kzdrev.js +12 -0
- package/dist/{ja-UTQEAP34-8e0q6swp.js → ja-43QL7CGO-c3q8gre9.js} +29 -2
- package/dist/ja-43QL7CGO-h6qfxfay.js +200 -0
- package/dist/{ja-Q5PXKJ2V-p4msxzjd.js → ja-U2MCNHGT-gz0ap1jk.js} +235 -28
- package/dist/{known-types-q6fcyq2e.js → known-types-3025scz1.js} +5 -5
- package/dist/ko-TLL6Z6CD-ag6gjynr.js +200 -0
- package/dist/{ko-AXCHW2OK-askct7f6.js → ko-TLL6Z6CD-wrt3n8a9.js} +29 -2
- package/dist/{ko-AYBDSRZG-41mdmsg1.js → ko-XAUYQWDR-zp81gjp4.js} +237 -30
- package/dist/{maestro-automate-entry-qak46eg0.js → maestro-automate-entry-6f9act3w.js} +2 -2
- package/dist/{node-ccwecksf.js → node-1wzjq3jb.js} +29 -15
- package/dist/{node-service-w8gsy23p.js → node-service-0hxtt2x6.js} +41 -30
- package/dist/{node-strategy-fdnkvq4a.js → node-strategy-1dmmhvf3.js} +1 -1
- package/dist/node-sync-service-n7r4ma3a.js +61 -0
- package/dist/{packager-tool-s4etvs59.js → packager-tool-0j8v36qh.js} +1 -1
- package/dist/packager-tool-10vc8pq4.js +2 -0
- package/dist/{packager-tool-pw6j69m5.js → packager-tool-445qgxdk.js} +1802 -378
- package/dist/packager-tool-4kr6g0zw.js +16 -0
- package/dist/packager-tool-4x7tzvv0.js +1176 -0
- package/dist/{packager-tool-86rhxbf1.js → packager-tool-5regytfc.js} +6 -4
- package/dist/{packager-tool-d88rqwk8.js → packager-tool-6z1hsm2h.js} +13 -5
- package/dist/{packager-tool-jaa5gcbv.js → packager-tool-71gqkgg6.js} +6 -6
- package/dist/packager-tool-7hw344bt.js +107 -0
- package/dist/{packager-tool-m8xtf5ej.js → packager-tool-8g5931fz.js} +7 -4
- package/dist/{packager-tool-h9tzz0qd.js → packager-tool-961vsbsc.js} +15 -10
- package/dist/{packager-tool-zzc2yp2h.js → packager-tool-99gban46.js} +172 -71
- package/dist/packager-tool-9era57c0.js +28 -0
- package/dist/packager-tool-9jxzgsxc.js +14 -0
- package/dist/{packager-tool-zxp4hya4.js → packager-tool-a5afh1dc.js} +34 -13
- package/dist/{packager-tool-02f63a08.js → packager-tool-apawc11t.js} +88 -762
- package/dist/{packager-tool-tf3d2y8z.js → packager-tool-aw9v0raw.js} +2 -2
- package/dist/{packager-tool-6y0f9qg5.js → packager-tool-b3k0mkke.js} +463 -327
- package/dist/packager-tool-cqtsj6yh.js +2 -0
- package/dist/{packager-tool-5nqhxb9e.js → packager-tool-dwd6cc01.js} +16110 -13031
- package/dist/{packager-tool-t605qewm.js → packager-tool-dxgrhfq5.js} +2 -2
- package/dist/{packager-tool-awkq26v0.js → packager-tool-e7kvq8hf.js} +5 -3
- package/dist/packager-tool-fc1xdt3y.js +35 -0
- package/dist/{packager-tool-3dc9gz35.js → packager-tool-frjt46rb.js} +1 -1
- package/dist/{packager-tool-cn7e7cx2.js → packager-tool-gcap41av.js} +668 -57
- package/dist/packager-tool-hj5x3p8g.js +23 -0
- package/dist/{packager-tool-k91rd9nx.js → packager-tool-hvgn6t66.js} +6 -24
- package/dist/{packager-tool-w5a1hhyj.js → packager-tool-hxyjn885.js} +13 -2
- package/dist/{packager-tool-hhy1gr2k.js → packager-tool-jgfzfqjm.js} +1 -1
- package/dist/{packager-tool-6h69pd2a.js → packager-tool-kn86394c.js} +127 -61
- package/dist/packager-tool-mgcz986r.js +143 -0
- package/dist/{packager-tool-3h2ktz6q.js → packager-tool-myhbp761.js} +11 -1
- package/dist/{packager-tool-hp5vnk8p.js → packager-tool-ndev7vbj.js} +13 -13
- package/dist/{packager-tool-dynm8fz9.js → packager-tool-nj4vcnq9.js} +20 -8
- package/dist/{packager-tool-ayc9nhpa.js → packager-tool-nk16zaz3.js} +519 -437
- package/dist/{packager-tool-vzbttaje.js → packager-tool-nts5rrch.js} +5 -6
- package/dist/{packager-tool-vbfz8k7w.js → packager-tool-p8gab24q.js} +52 -32
- package/dist/{packager-tool-stq8800d.js → packager-tool-pacrqxv2.js} +17 -4
- package/dist/{packager-tool-7q6z6npd.js → packager-tool-pcvhcn2k.js} +93 -11
- package/dist/packager-tool-phw8ydjx.js +331 -0
- package/dist/packager-tool-qcqb9hf8.js +26 -0
- package/dist/{packager-tool-n89vrpex.js → packager-tool-skcjythd.js} +10907 -25608
- package/dist/{packager-tool-1ca047de.js → packager-tool-sqpesv2e.js} +12 -56
- package/dist/packager-tool-t7ahhaer.js +877 -0
- package/dist/{packager-tool-peawy22c.js → packager-tool-tqjfdpda.js} +53 -8
- package/dist/{packager-tool-y8egb0fa.js → packager-tool-wds3myef.js} +2573 -535
- package/dist/{packager-tool-5tjzg56t.js → packager-tool-wh660fny.js} +1 -1
- package/dist/{packager-tool-tyg399d6.js → packager-tool-wze74wyk.js} +74 -47
- package/dist/packager-tool-xj0agqpk.js +11 -0
- package/dist/packager-tool-xk78j7dz.js +1256 -0
- package/dist/{packager-tool-py93409h.js → packager-tool-ymma2s85.js} +2 -2
- package/dist/packager-tool-z0yxfhdj.js +40 -0
- package/dist/packager-tool.js +13 -10
- package/dist/{pt-BR-TKHNHMET-sn91xyq0.js → pt-BR-GNQNAAZ2-xadharv4.js} +237 -30
- package/dist/{pt-BR-Y6K6XHXK-mp3hwhw1.js → pt-BR-USP2T7GD-pedn77m1.js} +29 -2
- package/dist/pt-BR-USP2T7GD-rppy42ym.js +200 -0
- package/dist/{pt-3DIO5QWG-59b3f4bc.js → pt-RMIAKZB4-67enhx3m.js} +29 -2
- package/dist/pt-RMIAKZB4-t80exmp7.js +200 -0
- package/dist/{pt-ROXU257Y-2f6bxev4.js → pt-TO2DARY2-ftcce1bv.js} +237 -30
- package/dist/ro-GHOBYW2S-4zevc9dy.js +200 -0
- package/dist/{ro-BWR3ONRR-vzx3hy8a.js → ro-GHOBYW2S-mhnqsgaa.js} +29 -2
- package/dist/{ro-AVAWPKOO-b89pw79r.js → ro-WUYJV6OW-a8d9qy1n.js} +235 -28
- package/dist/ru-WBLQ5B2U-dpqvtfwr.js +10 -0
- package/dist/services/connector-request-buckets.d.ts +1 -0
- package/dist/services/flow-eval-file-store.d.ts +1 -11
- package/dist/services/flow-eval-utils.d.ts +1 -32
- package/dist/services/flow-validate-service.d.ts +51 -0
- package/dist/services/inline-entity-resolver.d.ts +22 -0
- package/dist/services/node-service.d.ts +21 -1
- package/dist/services/packaging-utils.d.ts +15 -2
- package/dist/{shared-utils-pnbvyyb2.js → shared-utils-tqnx96mg.js} +4 -3
- package/dist/solution-auth-8qz5pw7z.js +14 -0
- package/dist/solution-discovery-vqravtkh.js +44 -0
- package/dist/{tidy-service-4fd4mjpb.js → tidy-service-fdctmeww.js} +143 -39
- package/dist/tool.js +17 -14
- package/dist/{tr-5IIHSFW5-hw4cewew.js → tr-GDTLECMM-k5fhmq13.js} +29 -2
- package/dist/tr-GDTLECMM-kngksm3r.js +200 -0
- package/dist/{tr-JMIP7ZSL-c39b6pe4.js → tr-M3F5A6AU-bb0tg39m.js} +235 -28
- package/dist/utils/flow-io.d.ts +2 -1
- package/dist/validation.js +39 -33
- package/dist/{variable-service-xgyaf3xy.js → variable-service-9xfk31pm.js} +16 -12
- package/dist/{wait-for-flow-job-d8m6mqb4.js → wait-for-flow-job-b0vj8828.js} +15 -12
- package/dist/{zh-CN-IFFXSEJS-9wm9gmrv.js → zh-CN-C5G4PC7C-ds9gkptg.js} +235 -28
- package/dist/zh-CN-I5D7WHBD-ge92tbx9.js +200 -0
- package/dist/{zh-CN-R2KU4U5L-tc1hat59.js → zh-CN-I5D7WHBD-sr5h0a98.js} +29 -2
- package/dist/{zh-TW-GNKMELBF-j674515r.js → zh-TW-2AVLM723-288pkc1z.js} +29 -2
- package/dist/zh-TW-2AVLM723-xsmap3gk.js +200 -0
- package/dist/{zh-TW-IYBNYAMG-8727c7v2.js → zh-TW-62HZIG6O-787kdwex.js} +234 -27
- package/package.json +2 -2
- package/dist/debug-conversation-trigger-8fgas95p.js +0 -44
- package/dist/flow-eval-run-api-byx3cacw.js +0 -13
- package/dist/flow-validate-service-ss9nt15j.js +0 -64
- package/dist/input-reader-vhar4g0k.js +0 -11
- package/dist/node-sync-service-42dpmp60.js +0 -40
- package/dist/packager-tool-a5xfcqqr.js +0 -15
- package/dist/packager-tool-epkg5s7f.js +0 -454
- package/dist/packager-tool-pz5nqg0s.js +0 -64
- package/dist/packager-tool-t3ysatjd.js +0 -521
- package/dist/packager-tool-vd6jt4n8.js +0 -208
- package/dist/packager-tool-wv3qf487.js +0 -265
- package/dist/services/flow-debug-service.d.ts +0 -320
- package/dist/services/flow-eval-schema/deterministic-evaluators.d.ts +0 -110
- package/dist/services/flow-eval-schema/evaluator-fields.d.ts +0 -66
- package/dist/services/flow-eval-schema/helpers.d.ts +0 -9
- package/dist/services/flow-eval-schema/index.d.ts +0 -4
- package/dist/services/flow-eval-schema/llm-judge-evaluators.d.ts +0 -174
- package/dist/services/flow-eval-schema/prompts.d.ts +0 -2
- package/dist/services/flow-eval-schema/registry.d.ts +0 -375
- package/dist/services/flow-eval-schema/tool-call-evaluators.d.ts +0 -93
- package/dist/services/flow-eval-schema/types.d.ts +0 -95
- package/dist/services/flow-eval-types.d.ts +0 -6
- package/dist/utils/write-resolved-flow.d.ts +0 -7
- /package/dist/{headless-45dypanh.js → headless-fw8pwyzm.js} +0 -0
- /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-
|
|
16
|
+
} from "./packager-tool-skcjythd.js";
|
|
14
17
|
import {
|
|
15
|
-
getAuthContext,
|
|
16
18
|
getLoginStatusAsync
|
|
17
|
-
} from "./packager-tool-
|
|
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-
|
|
26
|
-
import"./packager-tool-
|
|
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-
|
|
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-
|
|
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
|
|
3457
|
-
|
|
3458
|
-
|
|
3459
|
-
|
|
3460
|
-
let
|
|
3461
|
-
let
|
|
3462
|
-
|
|
3463
|
-
let
|
|
3464
|
-
|
|
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
|
-
|
|
3469
|
-
|
|
3470
|
-
|
|
3471
|
-
|
|
3472
|
-
|
|
3473
|
-
|
|
3474
|
-
|
|
3475
|
-
|
|
3476
|
-
|
|
3477
|
-
|
|
3478
|
-
|
|
3479
|
-
|
|
3480
|
-
|
|
3481
|
-
|
|
3482
|
-
|
|
3483
|
-
|
|
3484
|
-
|
|
3485
|
-
|
|
3486
|
-
|
|
3487
|
-
|
|
3488
|
-
|
|
3489
|
-
|
|
3490
|
-
|
|
3491
|
-
|
|
3492
|
-
|
|
3493
|
-
|
|
3494
|
-
|
|
3495
|
-
|
|
3496
|
-
|
|
3497
|
-
|
|
3498
|
-
|
|
3499
|
-
|
|
3500
|
-
|
|
3501
|
-
|
|
3502
|
-
|
|
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
|
-
|
|
3507
|
-
|
|
3508
|
-
|
|
3509
|
-
|
|
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
|
-
|
|
3513
|
-
|
|
3514
|
-
|
|
3515
|
-
|
|
3516
|
-
|
|
3517
|
-
|
|
3518
|
-
|
|
3519
|
-
|
|
3520
|
-
|
|
3521
|
-
|
|
3522
|
-
|
|
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
|
-
|
|
3548
|
-
|
|
3549
|
-
|
|
3550
|
-
|
|
3551
|
-
|
|
3552
|
-
|
|
3553
|
-
|
|
3554
|
-
|
|
3555
|
-
|
|
3556
|
-
|
|
3557
|
-
|
|
3558
|
-
|
|
3559
|
-
|
|
3560
|
-
|
|
3561
|
-
|
|
3562
|
-
|
|
3563
|
-
|
|
3564
|
-
|
|
3565
|
-
|
|
3566
|
-
|
|
3567
|
-
|
|
3568
|
-
|
|
3569
|
-
|
|
3570
|
-
|
|
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
|
-
|
|
3582
|
-
|
|
3583
|
-
|
|
3584
|
-
|
|
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
|
-
|
|
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-
|
|
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
|
|
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 (
|
|
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
|
-
|
|
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
|
|
4284
|
-
|
|
4285
|
-
|
|
4286
|
-
|
|
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
|
|
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(
|
|
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
|
-
|
|
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 (
|
|
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:
|
|
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
|
-
|
|
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
|
|
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,
|
|
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]
|
|
16560
|
+
if (sameIgnoringCase(target[kindIndex], kind)) {
|
|
15979
16561
|
target[kindIndex] = lowerFirstChar(kind);
|
|
15980
|
-
|
|
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
|
-
|
|
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,
|
|
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
|
|
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
|
|
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
|
-
}
|
|
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
|
-
|
|
16341
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
16727
|
-
|
|
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
|
|
16747
|
-
|
|
16748
|
-
|
|
16749
|
-
|
|
16750
|
-
|
|
16751
|
-
|
|
16752
|
-
|
|
16753
|
-
|
|
16754
|
-
|
|
16755
|
-
|
|
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
|
-
|
|
16759
|
-
|
|
16760
|
-
|
|
16761
|
-
|
|
16762
|
-
|
|
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
|
-
|
|
16766
|
-
}
|
|
16767
|
-
if (!metadata?.resources?.length) {
|
|
16768
|
-
continue;
|
|
16769
|
-
}
|
|
16770
|
-
allBindings.push(...metadata.resources);
|
|
17606
|
+
}
|
|
17607
|
+
};
|
|
16771
17608
|
}
|
|
16772
|
-
return {
|
|
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 [
|
|
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=
|
|
17926
|
+
//# debugId=EF208697C79EBB8D64756E2164756E21
|