@uipath/integrationservice-tool 1.198.0 → 1.199.0-preview.105

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/tool.js +450 -73
  2. package/package.json +2 -2
package/dist/tool.js CHANGED
@@ -23588,7 +23588,7 @@ var require_adm_zip = __commonJS((exports, module) => {
23588
23588
  var package_default = {
23589
23589
  name: "@uipath/integrationservice-tool",
23590
23590
  license: "MIT",
23591
- version: "1.198.0",
23591
+ version: "1.199.0-preview.105",
23592
23592
  description: "Manage Integration Service connectors, connections, and triggers.",
23593
23593
  private: false,
23594
23594
  repository: {
@@ -23627,7 +23627,7 @@ var package_default = {
23627
23627
  "@uipath/filesystem": "workspace:*",
23628
23628
  "@uipath/integrationservice-sdk": "workspace:*",
23629
23629
  "@types/node": "^25.5.2",
23630
- "adm-zip": "^0.5.16",
23630
+ "adm-zip": "^0.6.0",
23631
23631
  commander: "^14.0.3",
23632
23632
  typescript: "^6.0.2"
23633
23633
  }
@@ -23668,6 +23668,7 @@ function settlePromiseLike(thenable) {
23668
23668
  var DEFAULT_401 = "Unauthorized (401). Run `uip login` to authenticate.";
23669
23669
  var DEFAULT_403 = "Forbidden (403). Ensure the account has the required permissions.";
23670
23670
  var DEFAULT_405 = "Method Not Allowed (405). The endpoint may not exist or the base URL may be incorrect.";
23671
+ var DEFAULT_413 = "Payload too large (413). The upload exceeded the server or CDN size limit. Reduce the package size — for example, exclude unused dependencies or remove large files from the project — and try again.";
23671
23672
  var HTML_RESPONSE_MESSAGE = "Received HTML instead of the expected JSON response.";
23672
23673
  var NETWORK_ERROR_CODES = new Set([
23673
23674
  "ECONNREFUSED",
@@ -23769,6 +23770,9 @@ function classifyError(status, error) {
23769
23770
  if (status === 405) {
23770
23771
  return { errorCode: "method_not_allowed", retry: "RetryWillNotFix" };
23771
23772
  }
23773
+ if (status === 413) {
23774
+ return { errorCode: "invalid_argument", retry: "RetryWillNotFix" };
23775
+ }
23772
23776
  if (status === 408) {
23773
23777
  return { errorCode: "timeout", retry: "RetryLater" };
23774
23778
  }
@@ -23846,6 +23850,8 @@ async function extractErrorDetails(error, options) {
23846
23850
  result = "AuthenticationError";
23847
23851
  } else if (status === 405) {
23848
23852
  message = DEFAULT_405;
23853
+ } else if (status === 413) {
23854
+ message = DEFAULT_413;
23849
23855
  } else if (status === 400 || status === 422) {
23850
23856
  message = formatHttpStatusMessage(status, rawMessage, extractedMessage, inferredStatus);
23851
23857
  result = "ValidationError";
@@ -30728,6 +30734,7 @@ var SKILL_ATTRIBUTION = attributionRecord([
30728
30734
  var KNOWN_SKILL_NAMES = new Set(Object.keys(SKILL_ATTRIBUTION));
30729
30735
  var COMMAND_ATTRIBUTION = commandAttribution([
30730
30736
  ["cli", "troubleshoot", ["uip.feedback"]],
30737
+ ["llm-gateway", "operate", ["uip.llm-gateway"]],
30731
30738
  ["llm-gateway", "operate", ["uip.llm-configuration", "uip.model-hub"]],
30732
30739
  ["context-grounding", "build", ["uip.context-grounding"]],
30733
30740
  ["api-workflow", "build", ["uip.api-workflow"]],
@@ -32099,7 +32106,7 @@ class TextApiResponse {
32099
32106
  var package_default2 = {
32100
32107
  name: "@uipath/integrationservice-sdk",
32101
32108
  license: "MIT",
32102
- version: "1.198.0",
32109
+ version: "1.199.0-preview.105",
32103
32110
  repository: {
32104
32111
  type: "git",
32105
32112
  url: "https://github.com/UiPath/cli.git",
@@ -37892,6 +37899,7 @@ var resolveConfigAsync = async ({
37892
37899
  customAuthority,
37893
37900
  customClientId,
37894
37901
  customClientSecret,
37902
+ customClientAssertion,
37895
37903
  customScopes
37896
37904
  } = {}) => {
37897
37905
  const fileAuth = getAuthFileConfig();
@@ -37917,7 +37925,7 @@ var resolveConfigAsync = async ({
37917
37925
  if (!clientSecret && fileAuth.clientSecret) {
37918
37926
  clientSecret = fileAuth.clientSecret;
37919
37927
  }
37920
- const isExternalAppAuth = clientId !== DEFAULT_CLIENT_ID && Boolean(clientSecret);
37928
+ const isExternalAppAuth = clientId !== DEFAULT_CLIENT_ID && (Boolean(clientSecret) || Boolean(customClientAssertion));
37921
37929
  const scopes = resolveScopes(isExternalAppAuth, customScopes, fileAuth.scopes);
37922
37930
  return {
37923
37931
  clientId,
@@ -39035,7 +39043,6 @@ var getAuthContext = async (options = {}) => {
39035
39043
  tenantName
39036
39044
  };
39037
39045
  };
39038
-
39039
39046
  // ../auth/src/index.ts
39040
39047
  init_constants();
39041
39048
 
@@ -40074,6 +40081,9 @@ function formatActivityList(activities) {
40074
40081
  function filterByTriggerMode(activities, isTrigger) {
40075
40082
  return activities.filter((a) => a.isTrigger === isTrigger);
40076
40083
  }
40084
+ function filterExcluded(activities, connectorKey) {
40085
+ return activities.filter((a) => connectorKey !== "uipath-uipath-dataservice" || !/_V3$/i.test(String(a.name ?? "")));
40086
+ }
40077
40087
 
40078
40088
  // src/store/cache.ts
40079
40089
  init_src();
@@ -40342,7 +40352,7 @@ var registerActivitiesCommand = (program2) => {
40342
40352
  if (data && data.length > 0)
40343
40353
  await writeActivities(connectorKey, data, options.tenant);
40344
40354
  }
40345
- const filtered = data ? filterByTriggerMode(data, isTriggerMode) : [];
40355
+ const filtered = filterExcluded(data ? filterByTriggerMode(data, isTriggerMode) : [], connectorKey);
40346
40356
  OutputFormatter.emitList(isTriggerMode ? "TriggerActivityList" : "ActivityList", formatActivityList(filtered), {
40347
40357
  emptyInstructions: !data || data.length === 0 ? `No activities found for connector '${connectorKey}'. Check that the connector key is correct.` : isTriggerMode ? `No trigger activities found for connector '${connectorKey}'. This connector has no trigger activities.` : `No non-trigger activities found for connector '${connectorKey}'. All activities are triggers — use --triggers to list them.`
40348
40358
  });
@@ -42441,6 +42451,13 @@ var CONTRACT_FIELDS = [
42441
42451
  "source"
42442
42452
  ];
42443
42453
  var SYNCED_FIELDS = [...CONTRACT_FIELDS, "displayName"];
42454
+ var MIRRORED_UI_FIELDS = [
42455
+ "reference",
42456
+ "design",
42457
+ "fieldActions",
42458
+ "enum",
42459
+ "enhancedEnum"
42460
+ ];
42444
42461
  var RUNTIME_ONLY_PARAM_TYPES = new Set([
42445
42462
  "value",
42446
42463
  "body"
@@ -42465,6 +42482,11 @@ function buildSrParamFromElement(elemParam) {
42465
42482
  srParam[field] = elemParam[field];
42466
42483
  }
42467
42484
  }
42485
+ for (const field of MIRRORED_UI_FIELDS) {
42486
+ if (field in elemParam) {
42487
+ srParam[field] = elemParam[field];
42488
+ }
42489
+ }
42468
42490
  if ("name" in srParam && !("displayName" in srParam)) {
42469
42491
  srParam.displayName = humanize2(String(srParam.name));
42470
42492
  }
@@ -42531,6 +42553,11 @@ function syncMethodParams(srMethodParams, elemResourceParams, options = {}) {
42531
42553
  merged[field] = elemParam[field];
42532
42554
  }
42533
42555
  }
42556
+ for (const field of MIRRORED_UI_FIELDS) {
42557
+ if (field in elemParam) {
42558
+ merged[field] = elemParam[field];
42559
+ }
42560
+ }
42534
42561
  if (!("displayName" in merged) && "name" in merged) {
42535
42562
  merged.displayName = humanize2(String(merged.name));
42536
42563
  }
@@ -42935,6 +42962,8 @@ function trailingPlaceholder(path3) {
42935
42962
  function deriveIdPath(vendorPath, primaryKey) {
42936
42963
  if (trailingPlaceholder(vendorPath) !== undefined)
42937
42964
  return vendorPath;
42965
+ if (vendorPath.includes(`{${primaryKey}}`))
42966
+ return vendorPath;
42938
42967
  const lastSlash = vendorPath.lastIndexOf("/");
42939
42968
  const lastSegment = vendorPath.slice(lastSlash + 1);
42940
42969
  const extMatch = /^(.+)(\.[A-Za-z][A-Za-z0-9]{0,4})$/.exec(lastSegment);
@@ -42987,6 +43016,9 @@ function methodNeedsIdSuffix(method, methods) {
42987
43016
  }
42988
43017
  return false;
42989
43018
  }
43019
+ function elementSideParamType(token, elementPath) {
43020
+ return elementPath.includes(`{${token}}`) ? "path" : "query";
43021
+ }
42990
43022
  function buildDefaultParameters(method, resourceName, resourcePath, vendorPath, hasCeql, paramNames = {}, queryValueParams = [], noBody = false) {
42991
43023
  const params = [];
42992
43024
  const pathParams = [];
@@ -43006,7 +43038,7 @@ function buildDefaultParameters(method, resourceName, resourcePath, vendorPath,
43006
43038
  vendorName: param,
43007
43039
  vendorType: "path",
43008
43040
  name: param,
43009
- type: "path",
43041
+ type: elementSideParamType(param, resourcePath),
43010
43042
  description: `The ${param} of the ${itemLabel}`,
43011
43043
  required: true,
43012
43044
  dataType: "string",
@@ -43080,12 +43112,12 @@ function buildDefaultParameters(method, resourceName, resourcePath, vendorPath,
43080
43112
  params.push(...queryValueParams);
43081
43113
  return params;
43082
43114
  }
43083
- function buildSrMethodParameters(method, vendorPath, resourceName) {
43115
+ function buildSrMethodParameters(method, vendorPath, resourceName, elementPath) {
43084
43116
  const params = [];
43085
43117
  const pathEntry = (paramName, description) => ({
43086
43118
  name: paramName,
43087
43119
  vendorName: paramName,
43088
- type: "path",
43120
+ type: elementSideParamType(paramName, elementPath),
43089
43121
  vendorType: "path",
43090
43122
  source: "request",
43091
43123
  dataType: "string",
@@ -43154,7 +43186,7 @@ function buildStandardResource(args) {
43154
43186
  method: "GET",
43155
43187
  path: internalBase,
43156
43188
  reference: internalBase,
43157
- parameters: buildSrMethodParameters("GET", vendorPath, name)
43189
+ parameters: buildSrMethodParameters("GET", vendorPath, name, internalBase)
43158
43190
  };
43159
43191
  if (hasCeql)
43160
43192
  cfg.hasCEQL = true;
@@ -43167,7 +43199,7 @@ function buildStandardResource(args) {
43167
43199
  description: `Retrieve ${anItem} by ID`,
43168
43200
  method: "GET",
43169
43201
  path: `${internalBase}/{${primaryKey}}`,
43170
- parameters: buildSrMethodParameters("GETBYID", idPath, name)
43202
+ parameters: buildSrMethodParameters("GETBYID", idPath, name, `${internalBase}/{${primaryKey}}`)
43171
43203
  };
43172
43204
  } else if (m === "POST") {
43173
43205
  methodMetadata.POST = {
@@ -43176,7 +43208,7 @@ function buildStandardResource(args) {
43176
43208
  description: `Create ${anItem}`,
43177
43209
  method: "POST",
43178
43210
  path: internalBase,
43179
- parameters: buildSrMethodParameters("POST", vendorPath, name)
43211
+ parameters: buildSrMethodParameters("POST", vendorPath, name, internalBase)
43180
43212
  };
43181
43213
  } else if (m === "PUT" || m === "PATCH") {
43182
43214
  const idSuffix = methodNeedsIdSuffix(m, methods);
@@ -43188,7 +43220,7 @@ function buildStandardResource(args) {
43188
43220
  description: idSuffix ? `Update ${anItem} by ID` : `Update ${displayName}`,
43189
43221
  method: m,
43190
43222
  path: methodPath,
43191
- parameters: buildSrMethodParameters(m, methodVendorPath, name)
43223
+ parameters: buildSrMethodParameters(m, methodVendorPath, name, methodPath)
43192
43224
  };
43193
43225
  } else if (m === "DELETE") {
43194
43226
  const idSuffix = methodNeedsIdSuffix("DELETE", methods);
@@ -43321,8 +43353,14 @@ function mergeStandardResource(existing, built, overwriteFields) {
43321
43353
  const methodsReplaced = [];
43322
43354
  for (const [m, cfg] of Object.entries(builtMethods)) {
43323
43355
  if (m in methodMap) {
43324
- if (JSON.stringify(methodMap[m]) !== JSON.stringify(cfg)) {
43325
- methodMap[m] = cfg;
43356
+ const existingCfg = methodMap[m];
43357
+ const existingCurated = existingCfg && typeof existingCfg === "object" ? existingCfg.curated : undefined;
43358
+ const nextCfg = { ...cfg };
43359
+ if (existingCurated !== undefined) {
43360
+ nextCfg.curated = existingCurated;
43361
+ }
43362
+ if (JSON.stringify(existingCfg) !== JSON.stringify(nextCfg)) {
43363
+ methodMap[m] = nextCfg;
43326
43364
  methodsReplaced.push(m);
43327
43365
  }
43328
43366
  } else {
@@ -43545,6 +43583,7 @@ async function runCreateResource(args, root, resolvedSrName) {
43545
43583
  hasCeql,
43546
43584
  queryValueParams: entryQueryValueParams,
43547
43585
  noBody: args.noBody,
43586
+ explicitVendorPath: method in methodVendorPaths,
43548
43587
  filterParam: method === "GET" ? args.filterParam : undefined,
43549
43588
  pageSizeParam: method === "GET" ? args.pageSizeParam : undefined,
43550
43589
  offsetParam: method === "GET" ? args.offsetParam : undefined
@@ -43553,6 +43592,8 @@ async function runCreateResource(args, root, resolvedSrName) {
43553
43592
  const label = actualVendorPath && actualVendorPath !== entryPath ? `${actualMethod} ${entryPath} (vendor ${actualVendorPath})` : `${actualMethod} ${entryPath}`;
43554
43593
  if (result.skipped) {
43555
43594
  entriesSkipped.push(label);
43595
+ } else if (result.updated) {
43596
+ entriesAdded.push(`${label} [vendor path updated]`);
43556
43597
  } else {
43557
43598
  entriesAdded.push(label);
43558
43599
  }
@@ -43582,9 +43623,6 @@ async function runCreateResource(args, root, resolvedSrName) {
43582
43623
  }
43583
43624
  function addElementResourceEntry(element, args) {
43584
43625
  const resourcePath = args.path || `/${args.resourceName}`;
43585
- if (findResourceEntry(element, resourcePath, args.method)) {
43586
- return { skipped: true };
43587
- }
43588
43626
  const isSystemType = SYSTEM_RESOURCE_TYPES.has(args.resourceType);
43589
43627
  const queryValueParams = args.queryValueParams ?? [];
43590
43628
  const parameters = isSystemType ? [...queryValueParams] : buildDefaultParameters(args.method, args.resourceName, resourcePath, args.vendorPath, args.hasCeql, {
@@ -43592,6 +43630,23 @@ function addElementResourceEntry(element, args) {
43592
43630
  pageSizeParam: args.pageSizeParam,
43593
43631
  offsetParam: args.offsetParam
43594
43632
  }, queryValueParams, args.noBody ?? false);
43633
+ const existing = findResourceEntry(element, resourcePath, args.method);
43634
+ if (existing) {
43635
+ if (args.explicitVendorPath && args.vendorPath && existing.vendorPath !== args.vendorPath) {
43636
+ existing.vendorPath = args.vendorPath;
43637
+ existing.vendorMethod = args.method;
43638
+ const existingParams = Array.isArray(existing.parameters) ? existing.parameters : [];
43639
+ const seen = new Set(existingParams.map((p) => typeof p.name === "string" ? p.name : ""));
43640
+ for (const p of parameters) {
43641
+ const pn = typeof p.name === "string" ? p.name : "";
43642
+ if (pn && !seen.has(pn))
43643
+ existingParams.push(p);
43644
+ }
43645
+ existing.parameters = existingParams;
43646
+ return { skipped: false, updated: true };
43647
+ }
43648
+ return { skipped: true };
43649
+ }
43595
43650
  const entry = {
43596
43651
  path: resourcePath,
43597
43652
  vendorPath: args.vendorPath,
@@ -43636,7 +43691,8 @@ async function syncSrParamsWithElement(root, srFileName, name, methods, primaryK
43636
43691
  const methodMap = metadata.method ?? {};
43637
43692
  metadata.method = methodMap;
43638
43693
  const base = resourcePath || `/${name}`;
43639
- let updates = 0;
43694
+ let changedMethods = 0;
43695
+ let syncedParams = 0;
43640
43696
  for (const m of methods) {
43641
43697
  const elemMethod = m === "GETBYID" ? "GET" : m;
43642
43698
  const elemPath = methodNeedsIdSuffix(m, methods) ? `${base}/{${primaryKey}}` : base;
@@ -43650,13 +43706,14 @@ async function syncSrParamsWithElement(root, srFileName, name, methods, primaryK
43650
43706
  const merged = syncMethodParams(existing, elemParams);
43651
43707
  if (JSON.stringify(merged) !== JSON.stringify(existing)) {
43652
43708
  methodCfg.parameters = merged;
43653
- updates += 1;
43709
+ changedMethods += 1;
43710
+ syncedParams += merged.length;
43654
43711
  }
43655
43712
  }
43656
- if (updates) {
43713
+ if (changedMethods) {
43657
43714
  await writeStandardResource(root, srFileName, sr);
43658
43715
  }
43659
- return updates;
43716
+ return syncedParams;
43660
43717
  }
43661
43718
  async function listResources(connectorRoot, filter = {}) {
43662
43719
  const found = await findElementDir(connectorRoot);
@@ -44097,13 +44154,22 @@ async function upsertParam(connectorRoot, resource, method, param) {
44097
44154
  if (!located.ok)
44098
44155
  return located;
44099
44156
  const { root, element, entry } = located;
44157
+ const warnings = [];
44158
+ const internalPath = String(entry.path ?? "");
44159
+ let inputParam = param;
44160
+ if (param.type === "path" && !internalPath.includes(`{${name}}`)) {
44161
+ inputParam = { ...param, type: "query" };
44162
+ if (inputParam.vendorType === undefined)
44163
+ inputParam.vendorType = "path";
44164
+ warnings.push(`Path variable '${name}' is not in the internal path '${internalPath}', so it was declared type:"query" with vendorType:"path" — element-service interpolates it into the vendor path. A literal type:"path" here would 400 at runtime.`);
44165
+ }
44100
44166
  const params = getEntryParams(entry);
44101
44167
  const idx = params.findIndex((p) => p.name === name);
44102
44168
  const outcome = idx >= 0 ? "replaced" : "added";
44103
44169
  if (idx >= 0) {
44104
- params[idx] = { ...params[idx], ...param };
44170
+ params[idx] = { ...params[idx], ...inputParam };
44105
44171
  } else {
44106
- params.push(withNewParamDefaults(param));
44172
+ params.push(withNewParamDefaults(inputParam));
44107
44173
  }
44108
44174
  entry.parameters = params;
44109
44175
  const effectiveParam = params[idx >= 0 ? idx : params.length - 1];
@@ -44118,7 +44184,8 @@ async function upsertParam(connectorRoot, resource, method, param) {
44118
44184
  method,
44119
44185
  param: effectiveParam,
44120
44186
  outcome,
44121
- srSynced
44187
+ srSynced,
44188
+ ...warnings.length > 0 ? { warnings } : {}
44122
44189
  }
44123
44190
  };
44124
44191
  } catch (e) {
@@ -44200,6 +44267,10 @@ async function locateEntry(connectorRoot, resource, method) {
44200
44267
  return { ok: true, root, element, entry: match };
44201
44268
  }
44202
44269
  }
44270
+ const byName = resources.find((r) => typeof r.standardResourceName === "string" && r.standardResourceName === resource && r.method === elemMethod);
44271
+ if (byName) {
44272
+ return { ok: true, root, element, entry: byName };
44273
+ }
44203
44274
  return {
44204
44275
  ok: false,
44205
44276
  error: {
@@ -44314,6 +44385,10 @@ var VISIBILITY_ALLOWED_KEYS = new Set([
44314
44385
  "name",
44315
44386
  "designOverrides"
44316
44387
  ]);
44388
+ var VISIBILITY_KEY_ALIASES = {
44389
+ "request-curated": "requestCurated",
44390
+ "response-curated": "responseCurated"
44391
+ };
44317
44392
  var ALLOWED_FIELD_SPEC_KEYS = new Set([
44318
44393
  "name",
44319
44394
  "type",
@@ -44413,8 +44488,46 @@ function validateReference(parsed, label, errors) {
44413
44488
  if (typeof parsed.path !== "string" || parsed.path.length === 0) {
44414
44489
  errors.push(`${label}: 'reference' requires a non-empty 'path' (e.g. '/system_countries').`);
44415
44490
  }
44491
+ if (typeof parsed.lookupValue !== "string" || parsed.lookupValue.length === 0) {
44492
+ errors.push(`${label}: 'reference' should set 'lookupValue' — the field sent as the value when a row is picked (e.g. 'id'). Without it the dropdown has no value to submit.`);
44493
+ }
44416
44494
  return parsed;
44417
44495
  }
44496
+ var FIELD_ACTION_TYPES = new Set([
44497
+ "show",
44498
+ "hide",
44499
+ "required",
44500
+ "optional",
44501
+ "showMessages",
44502
+ "api",
44503
+ "reset"
44504
+ ]);
44505
+ function validateFieldActions(parsed, label, warnings) {
44506
+ if (!Array.isArray(parsed)) {
44507
+ warnings.push(`${label}: 'design.fieldActions' is usually an array.`);
44508
+ return;
44509
+ }
44510
+ parsed.forEach((action, i) => {
44511
+ if (!isPlainObject(action)) {
44512
+ warnings.push(`${label}: fieldActions[${i}] should be an object.`);
44513
+ return;
44514
+ }
44515
+ const at = action.actionType;
44516
+ if (typeof at !== "string" || !FIELD_ACTION_TYPES.has(at)) {
44517
+ warnings.push(`${label}: fieldActions[${i}].actionType '${String(at)}' is uncommon (usual: ${[...FIELD_ACTION_TYPES].join(", ")}).`);
44518
+ }
44519
+ const rules = action.rules;
44520
+ if (!Array.isArray(rules) || rules.length === 0) {
44521
+ warnings.push(`${label}: fieldActions[${i}] needs a non-empty 'rules' array (each rule points at the field it reacts to).`);
44522
+ return;
44523
+ }
44524
+ rules.forEach((rule, j) => {
44525
+ if (!isPlainObject(rule) || typeof rule.refFieldName !== "string" || rule.refFieldName.length === 0) {
44526
+ warnings.push(`${label}: fieldActions[${i}].rules[${j}] needs a non-empty 'refFieldName' (the field it depends on).`);
44527
+ }
44528
+ });
44529
+ });
44530
+ }
44418
44531
  function validateVisibility(parsed, label, errors, warnings) {
44419
44532
  if (!isPlainObject(parsed)) {
44420
44533
  errors.push(`${label}: per-method visibility must be an object keyed by HTTP method (e.g. { "GET": { "response": true } }).`);
@@ -44430,22 +44543,26 @@ function validateVisibility(parsed, label, errors, warnings) {
44430
44543
  out[method] = entry;
44431
44544
  continue;
44432
44545
  }
44546
+ const normEntry = {};
44433
44547
  for (const [k, v] of Object.entries(entry)) {
44434
- if (!VISIBILITY_ALLOWED_KEYS.has(k)) {
44548
+ const nk = VISIBILITY_KEY_ALIASES[k] ?? k;
44549
+ if (!VISIBILITY_ALLOWED_KEYS.has(nk)) {
44435
44550
  warnings.push(`${label}: unknown visibility key '${k}' on method '${method}'.`);
44551
+ normEntry[k] = v;
44436
44552
  continue;
44437
44553
  }
44438
- if (VISIBILITY_BOOLEAN_KEYS.has(k) && !isBooleanish(v)) {
44439
- warnings.push(`${label}: visibility '${k}' on method '${method}' is usually true/false.`);
44554
+ if (VISIBILITY_BOOLEAN_KEYS.has(nk) && !isBooleanish(v)) {
44555
+ warnings.push(`${label}: visibility '${nk}' on method '${method}' is usually true/false.`);
44440
44556
  }
44441
- if (k === "designOverrides") {
44557
+ if (nk === "designOverrides") {
44442
44558
  const pos = isPlainObject(v) ? v.position : undefined;
44443
44559
  if (pos !== undefined && (typeof pos !== "string" || !DESIGN_POSITIONS.has(pos))) {
44444
44560
  warnings.push(`${label}: uncommon designOverrides.position on method '${method}'; passed through.`);
44445
44561
  }
44446
44562
  }
44563
+ normEntry[nk] = v;
44447
44564
  }
44448
- out[method] = entry;
44565
+ out[method] = normEntry;
44449
44566
  }
44450
44567
  return out;
44451
44568
  }
@@ -44504,15 +44621,19 @@ function normalizeOne(raw, index, errors, warnings) {
44504
44621
  warnings.push(`${label}: '${k}' is usually a number.`);
44505
44622
  }
44506
44623
  }
44507
- for (const k of [
44508
- "searchableOperators",
44509
- "searchableNames",
44510
- "fieldActions"
44511
- ]) {
44512
- if (raw[k] !== undefined && !Array.isArray(raw[k])) {
44624
+ for (const k of ["searchableOperators", "searchableNames"]) {
44625
+ const v = raw[k];
44626
+ if (v === undefined)
44627
+ continue;
44628
+ if (typeof v === "string") {
44629
+ spec[k] = v.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
44630
+ } else if (!Array.isArray(v)) {
44513
44631
  warnings.push(`${label}: '${k}' is usually an array.`);
44514
44632
  }
44515
44633
  }
44634
+ if (raw.fieldActions !== undefined && !Array.isArray(raw.fieldActions)) {
44635
+ warnings.push(`${label}: 'fieldActions' is usually an array.`);
44636
+ }
44516
44637
  if (raw.enum !== undefined) {
44517
44638
  const normalized = normalizeEnumValues(raw.enum, label, warnings);
44518
44639
  if (normalized)
@@ -44531,6 +44652,9 @@ function normalizeOne(raw, index, errors, warnings) {
44531
44652
  if (pos !== undefined && (typeof pos !== "string" || !DESIGN_POSITIONS.has(pos))) {
44532
44653
  warnings.push(`${label}: uncommon design.position '${String(pos)}' (usual: ${[...DESIGN_POSITIONS].join(", ")}). Passed through.`);
44533
44654
  }
44655
+ if (raw.design.fieldActions !== undefined) {
44656
+ validateFieldActions(raw.design.fieldActions, label, warnings);
44657
+ }
44534
44658
  }
44535
44659
  if (raw.method !== undefined && raw.methods !== undefined) {
44536
44660
  errors.push(`${label}: pass only one of 'method' or 'methods' (they are aliases; 'method' is canonical).`);
@@ -44611,6 +44735,9 @@ function checkStoredFieldShape(name, field) {
44611
44735
  if (pos !== undefined && (typeof pos !== "string" || !DESIGN_POSITIONS.has(pos))) {
44612
44736
  warnings.push(`${label}: uncommon design.position '${String(pos)}' (usual: primary | secondary | none).`);
44613
44737
  }
44738
+ if (field.design.fieldActions !== undefined) {
44739
+ validateFieldActions(field.design.fieldActions, label, warnings);
44740
+ }
44614
44741
  }
44615
44742
  if (field.reference !== undefined) {
44616
44743
  validateReference(field.reference, label, warnings);
@@ -44632,12 +44759,12 @@ var FIELD_KEY_DESCRIPTIONS = {
44632
44759
  sampleValue: "Example value shown in the designer.",
44633
44760
  format: "Format hint, e.g. date-time, int32.",
44634
44761
  mask: `Date/number FORMAT pattern string, e.g. "yyyy-MM-dd'T'HH:mm:ssZ" (not a boolean).`,
44635
- design: "Design metadata object: { position: primary|secondary|none, component, hidden, displayPattern, loadByDefault, isMultiSelect, ... }.",
44762
+ design: 'Design metadata: { position: primary|secondary|none, component, hidden, displayPattern, loadByDefault, isMultiSelect, enableUserOverride, isHidden, fieldActions }. For a dropdown set displayPattern (e.g. "{name} - {id}"); for a dependent dropdown set isHidden + fieldActions (see below).',
44636
44763
  method: "Per-method visibility map, e.g. { GET: { response: true }, POST: { request: true } }.",
44637
44764
  methods: "Alias for 'method' (accepted on input; not both).",
44638
44765
  enum: 'Allowed values. Bare ["a"] is normalized to [{ value: "a" }].',
44639
44766
  enhancedEnum: "Labelled options: [{ name, value }].",
44640
- reference: "Dynamic lookup: { objectName, path, lookupValue, lookupNames } (objectName+path required).",
44767
+ reference: "Dropdown lookup: { objectName (target List resource), path (its list path; use {parentField} for a dependent dropdown, e.g. /teams/{team_id}/channels), lookupValue (the ONE field sent), lookupNames (display-candidate fields), filterPattern (type-ahead with {filter}) }. objectName+path+lookupValue expected.",
44641
44768
  primaryKey: "true if this field is the primary key.",
44642
44769
  sortOrder: "Number controlling field order.",
44643
44770
  searchable: "true if usable in CEQL filters.",
@@ -44649,7 +44776,7 @@ var FIELD_KEY_DESCRIPTIONS = {
44649
44776
  isCuratedEventField: "true if this field is a curated event/trigger field.",
44650
44777
  isPriority: "true to mark the field as high-priority in the designer.",
44651
44778
  key: "Vendor-side key alias some connectors carry alongside name.",
44652
- fieldActions: "Conditional show/hide rules array (cascading field visibility)."
44779
+ fieldActions: "Show/hide/required rules array: [{ actionType: show|hide|required|optional, rules: [{ type: 'field', refFieldName: '<otherField>', refFieldValues: ['*'], isCleared: false }] }]. Drives dependent dropdowns (show a child once the parent is filled) and conditional fields. Prefer `--depends-on <parentField>` on `field create` to generate the standard pair."
44653
44780
  };
44654
44781
  function describeFieldSchema() {
44655
44782
  return {
@@ -44702,6 +44829,61 @@ function describeFieldSchema() {
44702
44829
  lookupNames: ["name"]
44703
44830
  },
44704
44831
  method: { GET: { response: true } }
44832
+ },
44833
+ {
44834
+ name: "team_id",
44835
+ type: "string",
44836
+ displayName: "Team",
44837
+ reference: {
44838
+ objectName: "teams",
44839
+ path: "/teams",
44840
+ lookupValue: "id",
44841
+ lookupNames: ["id", "displayName"]
44842
+ },
44843
+ design: {
44844
+ displayPattern: "{displayName}",
44845
+ loadByDefault: true
44846
+ },
44847
+ method: { POST: { request: true } }
44848
+ },
44849
+ {
44850
+ name: "channel_id",
44851
+ type: "string",
44852
+ displayName: "Channel",
44853
+ reference: {
44854
+ objectName: "teams::channels",
44855
+ path: "/teams/{team_id}/channels",
44856
+ lookupValue: "id",
44857
+ lookupNames: ["id", "displayName"]
44858
+ },
44859
+ design: {
44860
+ displayPattern: "{displayName}",
44861
+ isHidden: true,
44862
+ fieldActions: [
44863
+ {
44864
+ actionType: "show",
44865
+ rules: [
44866
+ {
44867
+ type: "field",
44868
+ refFieldName: "team_id",
44869
+ refFieldValues: ["*"],
44870
+ isCleared: false
44871
+ }
44872
+ ]
44873
+ },
44874
+ {
44875
+ actionType: "hide",
44876
+ rules: [
44877
+ {
44878
+ type: "field",
44879
+ refFieldName: "team_id",
44880
+ isCleared: true
44881
+ }
44882
+ ]
44883
+ }
44884
+ ]
44885
+ },
44886
+ method: { POST: { request: true } }
44705
44887
  }
44706
44888
  ]
44707
44889
  };
@@ -45481,6 +45663,74 @@ function normalizeVisibilityToken(token) {
45481
45663
  return null;
45482
45664
  }
45483
45665
  }
45666
+ function buildDependencyActions(parentField) {
45667
+ return [
45668
+ {
45669
+ actionType: "show",
45670
+ priorityOrder: 0,
45671
+ rules: [
45672
+ {
45673
+ type: "field",
45674
+ refFieldName: parentField,
45675
+ refFieldValues: ["*"],
45676
+ isCleared: false,
45677
+ isVariable: false
45678
+ }
45679
+ ]
45680
+ },
45681
+ {
45682
+ actionType: "hide",
45683
+ priorityOrder: 1,
45684
+ rules: [
45685
+ {
45686
+ type: "field",
45687
+ refFieldName: parentField,
45688
+ isCleared: true,
45689
+ isVariable: false
45690
+ }
45691
+ ]
45692
+ }
45693
+ ];
45694
+ }
45695
+ function buildReferenceAndDesign(o) {
45696
+ const ref = o.reference !== undefined ? parseFieldJson(o.reference, "reference") : {};
45697
+ if (o.referenceObject !== undefined)
45698
+ ref.objectName = o.referenceObject;
45699
+ if (o.referencePath !== undefined)
45700
+ ref.path = o.referencePath;
45701
+ if (o.lookupValue !== undefined)
45702
+ ref.lookupValue = o.lookupValue;
45703
+ const lookupNames = splitCsv(o.lookupNames);
45704
+ if (lookupNames !== undefined)
45705
+ ref.lookupNames = lookupNames;
45706
+ if (o.filterPattern !== undefined)
45707
+ ref.filterPattern = o.filterPattern;
45708
+ const design = {};
45709
+ if (o.designPosition !== undefined)
45710
+ design.position = o.designPosition;
45711
+ if (o.component !== undefined)
45712
+ design.component = o.component;
45713
+ if (o.hidden)
45714
+ design.isHidden = true;
45715
+ if (o.displayPattern !== undefined)
45716
+ design.displayPattern = o.displayPattern;
45717
+ if (o.loadByDefault)
45718
+ design.loadByDefault = true;
45719
+ if (o.multiSelect)
45720
+ design.isMultiSelect = true;
45721
+ if (o.enableUserOverride)
45722
+ design.enableUserOverride = true;
45723
+ if (o.dependsOn !== undefined) {
45724
+ design.isHidden = true;
45725
+ design.fieldActions = buildDependencyActions(o.dependsOn);
45726
+ }
45727
+ if (o.fieldActions !== undefined)
45728
+ design.fieldActions = parseFieldJson(o.fieldActions, "field-actions");
45729
+ return {
45730
+ reference: Object.keys(ref).length > 0 ? ref : undefined,
45731
+ design: Object.keys(design).length > 0 ? design : undefined
45732
+ };
45733
+ }
45484
45734
  function buildField(options) {
45485
45735
  const raw = { name: options.name };
45486
45736
  if (options.type !== undefined)
@@ -45499,8 +45749,9 @@ function buildField(options) {
45499
45749
  raw.enum = parseFieldJson(options.enum, "enum");
45500
45750
  if (options.enhancedEnum !== undefined)
45501
45751
  raw.enhancedEnum = parseFieldJson(options.enhancedEnum, "enhanced-enum");
45502
- if (options.reference !== undefined)
45503
- raw.reference = parseFieldJson(options.reference, "reference");
45752
+ const dropdown = buildReferenceAndDesign(options);
45753
+ if (dropdown.reference !== undefined)
45754
+ raw.reference = dropdown.reference;
45504
45755
  if (options.defaultValue !== undefined)
45505
45756
  raw.defaultValue = parseDefaultValue(options.defaultValue);
45506
45757
  if (options.mask !== undefined)
@@ -45553,16 +45804,8 @@ function buildField(options) {
45553
45804
  }
45554
45805
  raw.method = methodMap;
45555
45806
  }
45556
- if (options.designPosition !== undefined || options.component !== undefined || options.hidden) {
45557
- const design = {};
45558
- if (options.designPosition !== undefined)
45559
- design.position = options.designPosition;
45560
- if (options.component !== undefined)
45561
- design.component = options.component;
45562
- if (options.hidden)
45563
- design.hidden = true;
45564
- raw.design = design;
45565
- }
45807
+ if (dropdown.design !== undefined)
45808
+ raw.design = dropdown.design;
45566
45809
  const { specs } = validateAndNormalizeFieldSpecs([raw]);
45567
45810
  return specs?.[0];
45568
45811
  }
@@ -45589,11 +45832,33 @@ function buildParam(options) {
45589
45832
  param.displayName = options.displayName;
45590
45833
  if (options.sortOrder !== undefined)
45591
45834
  param.sortOrder = Number(options.sortOrder);
45835
+ const enumErrors = [];
45836
+ const enumLabel = `param '${options.name}'`;
45837
+ if (options.enum !== undefined) {
45838
+ const norm = normalizeEnumValues(parseFieldJson(options.enum, "enum"), enumLabel, enumErrors);
45839
+ if (norm !== undefined)
45840
+ param.enum = norm;
45841
+ }
45842
+ if (options.enhancedEnum !== undefined) {
45843
+ const norm = normalizeEnhancedEnum(parseFieldJson(options.enhancedEnum, "enhanced-enum"), enumLabel, enumErrors);
45844
+ if (norm !== undefined)
45845
+ param.enhancedEnum = norm;
45846
+ }
45847
+ if (enumErrors.length > 0)
45848
+ throw new Error(enumErrors.join("; "));
45849
+ const dropdown = buildReferenceAndDesign(options);
45850
+ if (dropdown.reference !== undefined)
45851
+ param.reference = dropdown.reference;
45852
+ if (dropdown.design !== undefined)
45853
+ param.design = dropdown.design;
45592
45854
  return param;
45593
45855
  }
45594
45856
  function collect(value, previous = []) {
45595
45857
  return [...previous, value];
45596
45858
  }
45859
+ function addDropdownOptions(cmd) {
45860
+ return cmd.option("--enum <json>", 'Allowed values as JSON — accepts bare ["a","b"] or [{"value":"a"}]').option("--enhanced-enum <json>", 'Labelled options as JSON [{"name":"Label","value":"V"}]').option("--reference <json>", 'Dynamic lookup as JSON {"objectName":"users","path":"/users","lookupValue":"id","lookupNames":["name"]}').option("--reference-object <name>", "Dropdown: the target List resource's object name (e.g. teams)").option("--reference-path <path>", "Dropdown: the List resource path (e.g. /teams). Use {parent} for a dependent dropdown, e.g. /teams/{team_id}/channels").option("--lookup-value <field>", "Dropdown: the field sent as the value (one field, e.g. id)").option("--lookup-names <csv>", "Dropdown: display-candidate fields the display pattern can use (e.g. id,displayName)").option("--display-pattern <pattern>", 'Dropdown: visible label template, e.g. "{displayName}" or "{name} - {id}"').option("--filter-pattern <pattern>", "Dropdown: server-side type-ahead filter template with {filter}").option("--load-by-default", "Dropdown: populate the list on open").option("--multi-select", "Dropdown: allow selecting multiple values").option("--enable-user-override", "Dropdown: let the user type a raw value instead of picking").option("--depends-on <parent>", "Dependent dropdown: hide until <parent> has a value (generates the show/hide rules). The reference path should contain {<parent>}").option("--field-actions <json>", "Show/hide/required rules as JSON — escape hatch for conditions beyond --depends-on");
45861
+ }
45597
45862
  function registerActivityCommands(builder) {
45598
45863
  const activity = builder.command("activity").description("Author connector activities (resources): API endpoints with their fields, methods, parameters, and hooks. `create` finds-or-appends by internal path.");
45599
45864
  registerResourceVerbs(activity);
@@ -45743,12 +46008,14 @@ function registerFieldCommands(resource) {
45743
46008
  })
45744
46009
  });
45745
46010
  });
45746
- field.command("create").description("Create or update a field on a resource's standard-resource. Re-running on an existing field MERGES: top-level keys you pass win, unspecified keys are kept, and per-method visibility is deep-merged (so adding a method never drops the existing ones).").addHelpText("after", helpBlock([
46011
+ const fieldCreate = field.command("create").description("Create or update a field on a resource's standard-resource. Re-running on an existing field MERGES: top-level keys you pass win, unspecified keys are kept, and per-method visibility is deep-merged (so adding a method never drops the existing ones).").addHelpText("after", helpBlock([
45747
46012
  "Adding or updating a UI field with per-method visibility and design metadata.",
45748
46013
  "Assembling per-method visibility incrementally — each call merges into the existing field."
45749
46014
  ], [
45750
46015
  "Adding a runtime request parameter — use 'activity param create'."
45751
- ])).requiredOption("--resource <name>", "Resource name").requiredOption("--name <name>", "Field name (becomes the fields map key)").option("--type <type>", "Field type (string, integer, ...) — required for a NEW field; optional when merging into an existing one").option("--native-type <type>", "Vendor-native type name (defaults to --type)").option("--display-name <name>", "UI display name").option("--description <text>", "Field description").option("--sample-value <value>", "Sample value").option("--format <format>", "Field format hint (e.g. date-time, int32)").option("--enum <json>", 'Allowed values as JSON — accepts bare ["a","b"] or [{"value":"a"}]').option("--enhanced-enum <json>", 'Labelled options as JSON [{"name":"Label","value":"V"}]').option("--reference <json>", 'Dynamic lookup as JSON {"objectName":"users","path":"/users","lookupValue":"id","lookupNames":["name"]}').option("--default-value <value>", "Default value (scalar or JSON)").option("--mask <pattern>", `Date/number format pattern, e.g. "yyyy-MM-dd'T'HH:mm:ssZ"`).option("--primary-key", "Mark the field as the primary key").option("--sort-order <n>", "Sort order").option("--searchable", "Mark the field as searchable").option("--searchable-operators <csv>", "Comma-separated searchable operators").option("--searchable-names <csv>", "Comma-separated alternate names to match in queries").option("--method <method>", "HTTP method the visibility flags below apply to (repeatable). Inline per-method flags override them: --method 'GET=response' --method 'POST=request,required'. Prefix a flag with '!' to unset it on a merge: --method 'GET=!request'", collect).option("--request", "Field is part of the request for each --method").option("--response", "Field is part of the response for each --method").option("--required", "Field is required for each --method").option("--request-curated", "Field is request-curated for each --method").option("--response-curated", "Field is response-curated for each --method").option("--design-position <position>", "Design position: primary | secondary | none").option("--component <component>", "Design component override").option("--hidden", "Hide the field in the designer").option("--connector-dir <path>", FOLDER_OPTION_DESC).examples(FIELD_CREATE_EXAMPLES).trackedAction(processContext, async (options) => {
46016
+ ])).requiredOption("--resource <name>", "Resource name").requiredOption("--name <name>", "Field name (becomes the fields map key)").option("--type <type>", "Field type (string, integer, ...) — required for a NEW field; optional when merging into an existing one").option("--native-type <type>", "Vendor-native type name (defaults to --type)").option("--display-name <name>", "UI display name").option("--description <text>", "Field description").option("--sample-value <value>", "Sample value").option("--format <format>", "Field format hint (e.g. date-time, int32)");
46017
+ addDropdownOptions(fieldCreate);
46018
+ fieldCreate.option("--default-value <value>", "Default value (scalar or JSON)").option("--mask <pattern>", `Date/number format pattern, e.g. "yyyy-MM-dd'T'HH:mm:ssZ"`).option("--primary-key", "Mark the field as the primary key").option("--sort-order <n>", "Sort order").option("--searchable", "Mark the field as searchable").option("--searchable-operators <csv>", "Comma-separated searchable operators").option("--searchable-names <csv>", "Comma-separated alternate names to match in queries").option("--method <method>", "HTTP method the visibility flags below apply to (repeatable). Inline per-method flags override them: --method 'GET=response' --method 'POST=request,required'. Prefix a flag with '!' to unset it on a merge: --method 'GET=!request'", collect).option("--request", "Field is part of the request for each --method").option("--response", "Field is part of the response for each --method").option("--required", "Field is required for each --method").option("--request-curated", "Field is request-curated for each --method").option("--response-curated", "Field is response-curated for each --method").option("--design-position <position>", "Design position: primary | secondary | none").option("--component <component>", "Design component override").option("--hidden", "Hide the field in the designer").option("--connector-dir <path>", FOLDER_OPTION_DESC).examples(FIELD_CREATE_EXAMPLES).trackedAction(processContext, async (options) => {
45752
46019
  const root = await resolveConnectorRoot(options.connectorDir);
45753
46020
  if (root === null)
45754
46021
  return;
@@ -45885,7 +46152,9 @@ function registerParamCommands(resource) {
45885
46152
  })
45886
46153
  });
45887
46154
  });
45888
- param.command("create").description("Create or replace a parameter on a resource method.").requiredOption("--resource <name>", "Resource name").requiredOption("--method <method>", "HTTP method (GET, POST, ...)").requiredOption("--name <name>", "Parameter name").option("--vendor-name <name>", "Vendor-side parameter name").requiredOption("--type <type>", `Parameter type — one of: ${PARAM_TYPE_NAMES.join(", ")} (see --help)`).option("--vendor-type <type>", "Vendor-side parameter type").option("--data-type <type>", "Data type (string, integer, ...)").option("--vendor-data-type <type>", "Vendor-side data type").option("--source <source>", "Parameter source (request, response)").option("--required", "Mark the parameter as required").option("--description <text>", "Parameter description").option("--display-name <name>", "UI display name").option("--sort-order <n>", "Sort order").option("--connector-dir <path>", FOLDER_OPTION_DESC).addHelpText("after", PARAM_TYPE_HELP).examples(PARAM_CREATE_EXAMPLES).trackedAction(processContext, async (options) => {
46155
+ const paramCreate = param.command("create").description("Create or replace a parameter on a resource method.").requiredOption("--resource <name>", "Resource name").requiredOption("--method <method>", "HTTP method (GET, POST, ...)").requiredOption("--name <name>", "Parameter name").option("--vendor-name <name>", "Vendor-side parameter name").requiredOption("--type <type>", `Parameter type — one of: ${PARAM_TYPE_NAMES.join(", ")} (see --help)`).option("--vendor-type <type>", "Vendor-side parameter type").option("--data-type <type>", "Data type (string, integer, ...)").option("--vendor-data-type <type>", "Vendor-side data type").option("--source <source>", "Parameter source (request, response)").option("--required", "Mark the parameter as required").option("--description <text>", "Parameter description").option("--display-name <name>", "UI display name").option("--sort-order <n>", "Sort order");
46156
+ addDropdownOptions(paramCreate);
46157
+ paramCreate.option("--design-position <position>", "Design position: primary | secondary | none").option("--hidden", "Hide the parameter in the designer").option("--connector-dir <path>", FOLDER_OPTION_DESC).addHelpText("after", PARAM_TYPE_HELP).examples(PARAM_CREATE_EXAMPLES).trackedAction(processContext, async (options) => {
45889
46158
  const root = await resolveConnectorRoot(options.connectorDir);
45890
46159
  if (root === null)
45891
46160
  return;
@@ -45898,7 +46167,8 @@ function registerParamCommands(resource) {
45898
46167
  ParamName: data.param.name ?? null,
45899
46168
  Param: data.param,
45900
46169
  Outcome: data.outcome,
45901
- SrSynced: data.srSynced
46170
+ SrSynced: data.srSynced,
46171
+ ...data.warnings ? { Warnings: data.warnings } : {}
45902
46172
  })
45903
46173
  });
45904
46174
  });
@@ -48305,22 +48575,7 @@ var VALID_LIFECYCLE_STAGES = [
48305
48575
  "PREVIEW",
48306
48576
  "DEPRECATED"
48307
48577
  ];
48308
- var KNOWN_PARAM_TYPES = new Set([
48309
- "configuration",
48310
- "header",
48311
- "path",
48312
- "query",
48313
- "form",
48314
- "multipart",
48315
- "body",
48316
- "bodyField",
48317
- "bodyToken",
48318
- "value",
48319
- "prevBody",
48320
- "prevBodyField",
48321
- "customValue",
48322
- "no-op"
48323
- ]);
48578
+ var KNOWN_PARAM_TYPES = new Set(VALID_PARAMETER_TYPES);
48324
48579
  var KNOWN_PARAM_SOURCES = new Set([
48325
48580
  "request",
48326
48581
  "response"
@@ -48672,6 +48927,35 @@ async function validateConnector(connectorRoot) {
48672
48927
  warnings.push(`Uncommon resource type '${rtype}': ${strOrQ2(r.method)} ${strOrQ2(r.path)}`);
48673
48928
  }
48674
48929
  }
48930
+ const globalPathVendorNames = new Set(asRecordArray2(elem.parameters).filter((p) => p.vendorType === "path").map((p) => stringOr3(p.vendorName)).filter((n) => n.length > 0));
48931
+ const pathTokens = (p) => [
48932
+ ...new Set([...p.matchAll(/\{([\w.]+)\}/g)].map((m) => m[1]))
48933
+ ];
48934
+ for (const r of resources) {
48935
+ const rPath = stringOr3(r.path);
48936
+ const rVendorPath = stringOr3(r.vendorPath);
48937
+ if (!rPath)
48938
+ continue;
48939
+ const params = asRecordArray2(r.parameters);
48940
+ for (const p of params) {
48941
+ const pName = stringOr3(p.name);
48942
+ const pVendorName = stringOr3(p.vendorName);
48943
+ if (p.type === "path" && pName && !rPath.includes(`{${pName}}`)) {
48944
+ errors.push(`Resource ${strOrQ2(r.method)} ${strOrQ2(r.path)}: path parameter '${pName}' is type:"path" but '{${pName}}' is not in the internal path '${rPath}'. ` + `element-service will 400 "required parameter '` + pName + `' not found" at request time. Declare it type:"query" with vendorType:"path" (a vendor-only path variable), or add the token to the resource path via --resource-path.`);
48945
+ }
48946
+ if (p.vendorType === "path" && pVendorName && rVendorPath && !rVendorPath.includes(`{${pVendorName}}`)) {
48947
+ warnings.push(`Resource ${strOrQ2(r.method)} ${strOrQ2(r.path)}: parameter '${pName}' has vendorType:"path" but '{${pVendorName}}' is not in the vendor path '${rVendorPath}' — the value has no vendor slot to fill.`);
48948
+ }
48949
+ }
48950
+ if (rVendorPath) {
48951
+ const boundVendorNames = new Set(params.filter((p) => p.vendorType === "path").map((p) => stringOr3(p.vendorName)));
48952
+ for (const token of pathTokens(rVendorPath)) {
48953
+ if (!boundVendorNames.has(token) && !globalPathVendorNames.has(token)) {
48954
+ errors.push(`Resource ${strOrQ2(r.method)} ${strOrQ2(r.path)}: vendor path '${rVendorPath}' has an unbound '{${token}}' — no path parameter sends it, so the request 404s. Add a parameter with vendorType:"path" and vendorName:"${token}".`);
48955
+ }
48956
+ }
48957
+ }
48958
+ }
48675
48959
  const srDir = fs8.path.join(root, ...SR_REL3);
48676
48960
  const seenSrNames = new Set;
48677
48961
  for (const r of resources) {
@@ -48687,6 +48971,7 @@ async function validateConnector(connectorRoot) {
48687
48971
  }
48688
48972
  warnings.push(...await checkSrLinkage(elem, root));
48689
48973
  warnings.push(...await checkFieldlessActivities(elem, root));
48974
+ warnings.push(...await checkDropdownTargets(elem, root));
48690
48975
  const hooksDir = fs8.path.join(root, "app", "element", "hooks");
48691
48976
  for (const r of resources) {
48692
48977
  for (const hook of asRecordArray2(r.hooks)) {
@@ -48765,6 +49050,40 @@ async function validateConnector(connectorRoot) {
48765
49050
  }
48766
49051
  }
48767
49052
  }
49053
+ const knownNames = new Set(Object.keys(fields));
49054
+ for (const mData of Object.values(methodMeta)) {
49055
+ for (const p of asRecordArray2(asRecord2(mData).parameters)) {
49056
+ const pn = stringOr3(p.name);
49057
+ if (pn)
49058
+ knownNames.add(pn);
49059
+ }
49060
+ }
49061
+ const checkDropdownWiring = (kind, carrier) => {
49062
+ const design = asRecord2(carrier.design);
49063
+ const refPath = stringOr3(asRecord2(carrier.reference).path);
49064
+ for (const m of refPath.matchAll(/\{([\w.]+)\}/g)) {
49065
+ if (!knownNames.has(m[1])) {
49066
+ warnings.push(`${srName}: ${kind} dropdown path '${refPath}' interpolates '{${m[1]}}' but no field/param '${m[1]}' exists on this resource — the dependent dropdown won't resolve.`);
49067
+ }
49068
+ }
49069
+ const actions = Array.isArray(design.fieldActions) ? design.fieldActions : [];
49070
+ for (const action of actions) {
49071
+ for (const rule of asRecordArray2(asRecord2(action).rules)) {
49072
+ const rfn = stringOr3(rule.refFieldName);
49073
+ if (rfn && !knownNames.has(rfn)) {
49074
+ warnings.push(`${srName}: ${kind} has a show/hide rule on '${rfn}', which isn't a field/param on this resource.`);
49075
+ }
49076
+ }
49077
+ }
49078
+ };
49079
+ for (const [fName, fVal] of Object.entries(fields)) {
49080
+ checkDropdownWiring(`field '${fName}'`, asRecord2(fVal));
49081
+ }
49082
+ for (const [mName, mData] of Object.entries(methodMeta)) {
49083
+ for (const p of asRecordArray2(asRecord2(mData).parameters)) {
49084
+ checkDropdownWiring(`${mName} param '${stringOr3(p.name)}'`, p);
49085
+ }
49086
+ }
48768
49087
  }
48769
49088
  } else {
48770
49089
  warnings.push("No standard-resources/ directory found");
@@ -48939,6 +49258,64 @@ async function checkSrLinkage(elem, root) {
48939
49258
  }
48940
49259
  return warnings;
48941
49260
  }
49261
+ async function checkDropdownTargets(elem, root) {
49262
+ const fs8 = getFileSystem();
49263
+ const warnings = [];
49264
+ const srDir = fs8.path.join(root, ...SR_REL3);
49265
+ if (!await fs8.exists(srDir)) {
49266
+ return warnings;
49267
+ }
49268
+ const objMethods = new Map;
49269
+ for (const r of asRecordArray2(elem.resources)) {
49270
+ if (SYSTEM_RESOURCE_TYPES.has(stringOr3(r.type))) {
49271
+ continue;
49272
+ }
49273
+ const obj = stringOr3(r.standardResourceName);
49274
+ if (!obj) {
49275
+ continue;
49276
+ }
49277
+ const method = stringOr3(r.method ?? r.vendorMethod).toUpperCase();
49278
+ const set2 = objMethods.get(obj) ?? new Set;
49279
+ if (method) {
49280
+ set2.add(method);
49281
+ }
49282
+ objMethods.set(obj, set2);
49283
+ }
49284
+ const isReadable = (obj) => {
49285
+ const set2 = objMethods.get(obj);
49286
+ return set2 !== undefined && (set2.has("GET") || set2.has("GETBYID"));
49287
+ };
49288
+ const srFiles = (await fs8.readdir(srDir)).filter((f) => f.endsWith(".json"));
49289
+ for (const srName of srFiles) {
49290
+ const sr = await readJsonFile2(fs8.path.join(srDir, srName));
49291
+ if (sr === null) {
49292
+ continue;
49293
+ }
49294
+ const flagged = new Set;
49295
+ const walk = (node2) => {
49296
+ if (Array.isArray(node2)) {
49297
+ for (const item of node2) {
49298
+ walk(item);
49299
+ }
49300
+ return;
49301
+ }
49302
+ if (node2 === null || typeof node2 !== "object") {
49303
+ return;
49304
+ }
49305
+ const rec = node2;
49306
+ const obj = stringOr3(asRecord2(rec.reference).objectName);
49307
+ if (obj && objMethods.has(obj) && !isReadable(obj) && !flagged.has(obj)) {
49308
+ flagged.add(obj);
49309
+ warnings.push(`${srName}: dropdown targets object '${obj}', which has no GET/List method — the dropdown will be empty at runtime. Add a GET (list) method to the '${obj}' resource.`);
49310
+ }
49311
+ for (const value of Object.values(rec)) {
49312
+ walk(value);
49313
+ }
49314
+ };
49315
+ walk(sr);
49316
+ }
49317
+ return warnings;
49318
+ }
48942
49319
  async function checkFieldlessActivities(elem, root) {
48943
49320
  const fs8 = getFileSystem();
48944
49321
  const warnings = [];
@@ -50607,7 +50984,7 @@ function parseResources(segments, filters) {
50607
50984
  });
50608
50985
  }
50609
50986
  if (segments.length === 3) {
50610
- throw new Error(`element.json/resources/${segments[2]} requires a URL-encoded resource path. ` + `Example: element.json/resources/${segments[2]}/%2Fcontacts`);
50987
+ throw new Error("element.json/resources/<METHOD>/<url-encoded-path> after 'resources' pass an " + "HTTP METHOD (GET, POST, …) then the URL-encoded resource path. " + `Example: element.json/resources/GET/%2Fcontacts (you passed '${segments[2]}').`);
50611
50988
  }
50612
50989
  const method = segments[2].toUpperCase();
50613
50990
  const resourcePath = unquote(segments[3]);
@@ -54402,4 +54779,4 @@ export {
54402
54779
  metadata
54403
54780
  };
54404
54781
 
54405
- //# debugId=6324C44904F8F68364756E2164756E21
54782
+ //# debugId=70F89176847F9D3164756E2164756E21
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@uipath/integrationservice-tool",
3
3
  "license": "MIT",
4
- "version": "1.198.0",
4
+ "version": "1.199.0-preview.105",
5
5
  "description": "Manage Integration Service connectors, connections, and triggers.",
6
6
  "private": false,
7
7
  "repository": {
@@ -26,5 +26,5 @@
26
26
  "files": [
27
27
  "dist"
28
28
  ],
29
- "gitHead": "1fadf03d7a8dd102742571dff569fdac11808afb"
29
+ "gitHead": "30a83200f41e8bb994929322e33176b4355f6707"
30
30
  }