@uipath/integrationservice-tool 1.198.0-preview.90 → 1.199.0-preview.91

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-preview.90",
23591
+ version: "1.199.0-preview.91",
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";
@@ -30500,6 +30506,7 @@ var SKILL_ATTRIBUTION = attributionRecord([
30500
30506
  var KNOWN_SKILL_NAMES = new Set(Object.keys(SKILL_ATTRIBUTION));
30501
30507
  var COMMAND_ATTRIBUTION = commandAttribution([
30502
30508
  ["cli", "troubleshoot", ["uip.feedback"]],
30509
+ ["llm-gateway", "operate", ["uip.llm-gateway"]],
30503
30510
  ["llm-gateway", "operate", ["uip.llm-configuration", "uip.model-hub"]],
30504
30511
  ["context-grounding", "build", ["uip.context-grounding"]],
30505
30512
  ["api-workflow", "build", ["uip.api-workflow"]],
@@ -31992,7 +31999,7 @@ class TextApiResponse {
31992
31999
  var package_default2 = {
31993
32000
  name: "@uipath/integrationservice-sdk",
31994
32001
  license: "MIT",
31995
- version: "1.198.0-preview.90",
32002
+ version: "1.199.0-preview.91",
31996
32003
  repository: {
31997
32004
  type: "git",
31998
32005
  url: "https://github.com/UiPath/cli.git",
@@ -37785,6 +37792,7 @@ var resolveConfigAsync = async ({
37785
37792
  customAuthority,
37786
37793
  customClientId,
37787
37794
  customClientSecret,
37795
+ customClientAssertion,
37788
37796
  customScopes
37789
37797
  } = {}) => {
37790
37798
  const fileAuth = getAuthFileConfig();
@@ -37810,7 +37818,7 @@ var resolveConfigAsync = async ({
37810
37818
  if (!clientSecret && fileAuth.clientSecret) {
37811
37819
  clientSecret = fileAuth.clientSecret;
37812
37820
  }
37813
- const isExternalAppAuth = clientId !== DEFAULT_CLIENT_ID && Boolean(clientSecret);
37821
+ const isExternalAppAuth = clientId !== DEFAULT_CLIENT_ID && (Boolean(clientSecret) || Boolean(customClientAssertion));
37814
37822
  const scopes = resolveScopes(isExternalAppAuth, customScopes, fileAuth.scopes);
37815
37823
  return {
37816
37824
  clientId,
@@ -38928,7 +38936,6 @@ var getAuthContext = async (options = {}) => {
38928
38936
  tenantName
38929
38937
  };
38930
38938
  };
38931
-
38932
38939
  // ../auth/src/index.ts
38933
38940
  init_constants();
38934
38941
 
@@ -39967,6 +39974,9 @@ function formatActivityList(activities) {
39967
39974
  function filterByTriggerMode(activities, isTrigger) {
39968
39975
  return activities.filter((a) => a.isTrigger === isTrigger);
39969
39976
  }
39977
+ function filterExcluded(activities, connectorKey) {
39978
+ return activities.filter((a) => connectorKey !== "uipath-uipath-dataservice" || !/_V3$/i.test(String(a.name ?? "")));
39979
+ }
39970
39980
 
39971
39981
  // src/store/cache.ts
39972
39982
  init_src();
@@ -40235,7 +40245,7 @@ var registerActivitiesCommand = (program2) => {
40235
40245
  if (data && data.length > 0)
40236
40246
  await writeActivities(connectorKey, data, options.tenant);
40237
40247
  }
40238
- const filtered = data ? filterByTriggerMode(data, isTriggerMode) : [];
40248
+ const filtered = filterExcluded(data ? filterByTriggerMode(data, isTriggerMode) : [], connectorKey);
40239
40249
  OutputFormatter.emitList(isTriggerMode ? "TriggerActivityList" : "ActivityList", formatActivityList(filtered), {
40240
40250
  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.`
40241
40251
  });
@@ -42334,6 +42344,13 @@ var CONTRACT_FIELDS = [
42334
42344
  "source"
42335
42345
  ];
42336
42346
  var SYNCED_FIELDS = [...CONTRACT_FIELDS, "displayName"];
42347
+ var MIRRORED_UI_FIELDS = [
42348
+ "reference",
42349
+ "design",
42350
+ "fieldActions",
42351
+ "enum",
42352
+ "enhancedEnum"
42353
+ ];
42337
42354
  var RUNTIME_ONLY_PARAM_TYPES = new Set([
42338
42355
  "value",
42339
42356
  "body"
@@ -42358,6 +42375,11 @@ function buildSrParamFromElement(elemParam) {
42358
42375
  srParam[field] = elemParam[field];
42359
42376
  }
42360
42377
  }
42378
+ for (const field of MIRRORED_UI_FIELDS) {
42379
+ if (field in elemParam) {
42380
+ srParam[field] = elemParam[field];
42381
+ }
42382
+ }
42361
42383
  if ("name" in srParam && !("displayName" in srParam)) {
42362
42384
  srParam.displayName = humanize2(String(srParam.name));
42363
42385
  }
@@ -42424,6 +42446,11 @@ function syncMethodParams(srMethodParams, elemResourceParams, options = {}) {
42424
42446
  merged[field] = elemParam[field];
42425
42447
  }
42426
42448
  }
42449
+ for (const field of MIRRORED_UI_FIELDS) {
42450
+ if (field in elemParam) {
42451
+ merged[field] = elemParam[field];
42452
+ }
42453
+ }
42427
42454
  if (!("displayName" in merged) && "name" in merged) {
42428
42455
  merged.displayName = humanize2(String(merged.name));
42429
42456
  }
@@ -42828,6 +42855,8 @@ function trailingPlaceholder(path3) {
42828
42855
  function deriveIdPath(vendorPath, primaryKey) {
42829
42856
  if (trailingPlaceholder(vendorPath) !== undefined)
42830
42857
  return vendorPath;
42858
+ if (vendorPath.includes(`{${primaryKey}}`))
42859
+ return vendorPath;
42831
42860
  const lastSlash = vendorPath.lastIndexOf("/");
42832
42861
  const lastSegment = vendorPath.slice(lastSlash + 1);
42833
42862
  const extMatch = /^(.+)(\.[A-Za-z][A-Za-z0-9]{0,4})$/.exec(lastSegment);
@@ -42880,6 +42909,9 @@ function methodNeedsIdSuffix(method, methods) {
42880
42909
  }
42881
42910
  return false;
42882
42911
  }
42912
+ function elementSideParamType(token, elementPath) {
42913
+ return elementPath.includes(`{${token}}`) ? "path" : "query";
42914
+ }
42883
42915
  function buildDefaultParameters(method, resourceName, resourcePath, vendorPath, hasCeql, paramNames = {}, queryValueParams = [], noBody = false) {
42884
42916
  const params = [];
42885
42917
  const pathParams = [];
@@ -42899,7 +42931,7 @@ function buildDefaultParameters(method, resourceName, resourcePath, vendorPath,
42899
42931
  vendorName: param,
42900
42932
  vendorType: "path",
42901
42933
  name: param,
42902
- type: "path",
42934
+ type: elementSideParamType(param, resourcePath),
42903
42935
  description: `The ${param} of the ${itemLabel}`,
42904
42936
  required: true,
42905
42937
  dataType: "string",
@@ -42973,12 +43005,12 @@ function buildDefaultParameters(method, resourceName, resourcePath, vendorPath,
42973
43005
  params.push(...queryValueParams);
42974
43006
  return params;
42975
43007
  }
42976
- function buildSrMethodParameters(method, vendorPath, resourceName) {
43008
+ function buildSrMethodParameters(method, vendorPath, resourceName, elementPath) {
42977
43009
  const params = [];
42978
43010
  const pathEntry = (paramName, description) => ({
42979
43011
  name: paramName,
42980
43012
  vendorName: paramName,
42981
- type: "path",
43013
+ type: elementSideParamType(paramName, elementPath),
42982
43014
  vendorType: "path",
42983
43015
  source: "request",
42984
43016
  dataType: "string",
@@ -43047,7 +43079,7 @@ function buildStandardResource(args) {
43047
43079
  method: "GET",
43048
43080
  path: internalBase,
43049
43081
  reference: internalBase,
43050
- parameters: buildSrMethodParameters("GET", vendorPath, name)
43082
+ parameters: buildSrMethodParameters("GET", vendorPath, name, internalBase)
43051
43083
  };
43052
43084
  if (hasCeql)
43053
43085
  cfg.hasCEQL = true;
@@ -43060,7 +43092,7 @@ function buildStandardResource(args) {
43060
43092
  description: `Retrieve ${anItem} by ID`,
43061
43093
  method: "GET",
43062
43094
  path: `${internalBase}/{${primaryKey}}`,
43063
- parameters: buildSrMethodParameters("GETBYID", idPath, name)
43095
+ parameters: buildSrMethodParameters("GETBYID", idPath, name, `${internalBase}/{${primaryKey}}`)
43064
43096
  };
43065
43097
  } else if (m === "POST") {
43066
43098
  methodMetadata.POST = {
@@ -43069,7 +43101,7 @@ function buildStandardResource(args) {
43069
43101
  description: `Create ${anItem}`,
43070
43102
  method: "POST",
43071
43103
  path: internalBase,
43072
- parameters: buildSrMethodParameters("POST", vendorPath, name)
43104
+ parameters: buildSrMethodParameters("POST", vendorPath, name, internalBase)
43073
43105
  };
43074
43106
  } else if (m === "PUT" || m === "PATCH") {
43075
43107
  const idSuffix = methodNeedsIdSuffix(m, methods);
@@ -43081,7 +43113,7 @@ function buildStandardResource(args) {
43081
43113
  description: idSuffix ? `Update ${anItem} by ID` : `Update ${displayName}`,
43082
43114
  method: m,
43083
43115
  path: methodPath,
43084
- parameters: buildSrMethodParameters(m, methodVendorPath, name)
43116
+ parameters: buildSrMethodParameters(m, methodVendorPath, name, methodPath)
43085
43117
  };
43086
43118
  } else if (m === "DELETE") {
43087
43119
  const idSuffix = methodNeedsIdSuffix("DELETE", methods);
@@ -43214,8 +43246,14 @@ function mergeStandardResource(existing, built, overwriteFields) {
43214
43246
  const methodsReplaced = [];
43215
43247
  for (const [m, cfg] of Object.entries(builtMethods)) {
43216
43248
  if (m in methodMap) {
43217
- if (JSON.stringify(methodMap[m]) !== JSON.stringify(cfg)) {
43218
- methodMap[m] = cfg;
43249
+ const existingCfg = methodMap[m];
43250
+ const existingCurated = existingCfg && typeof existingCfg === "object" ? existingCfg.curated : undefined;
43251
+ const nextCfg = { ...cfg };
43252
+ if (existingCurated !== undefined) {
43253
+ nextCfg.curated = existingCurated;
43254
+ }
43255
+ if (JSON.stringify(existingCfg) !== JSON.stringify(nextCfg)) {
43256
+ methodMap[m] = nextCfg;
43219
43257
  methodsReplaced.push(m);
43220
43258
  }
43221
43259
  } else {
@@ -43438,6 +43476,7 @@ async function runCreateResource(args, root, resolvedSrName) {
43438
43476
  hasCeql,
43439
43477
  queryValueParams: entryQueryValueParams,
43440
43478
  noBody: args.noBody,
43479
+ explicitVendorPath: method in methodVendorPaths,
43441
43480
  filterParam: method === "GET" ? args.filterParam : undefined,
43442
43481
  pageSizeParam: method === "GET" ? args.pageSizeParam : undefined,
43443
43482
  offsetParam: method === "GET" ? args.offsetParam : undefined
@@ -43446,6 +43485,8 @@ async function runCreateResource(args, root, resolvedSrName) {
43446
43485
  const label = actualVendorPath && actualVendorPath !== entryPath ? `${actualMethod} ${entryPath} (vendor ${actualVendorPath})` : `${actualMethod} ${entryPath}`;
43447
43486
  if (result.skipped) {
43448
43487
  entriesSkipped.push(label);
43488
+ } else if (result.updated) {
43489
+ entriesAdded.push(`${label} [vendor path updated]`);
43449
43490
  } else {
43450
43491
  entriesAdded.push(label);
43451
43492
  }
@@ -43475,9 +43516,6 @@ async function runCreateResource(args, root, resolvedSrName) {
43475
43516
  }
43476
43517
  function addElementResourceEntry(element, args) {
43477
43518
  const resourcePath = args.path || `/${args.resourceName}`;
43478
- if (findResourceEntry(element, resourcePath, args.method)) {
43479
- return { skipped: true };
43480
- }
43481
43519
  const isSystemType = SYSTEM_RESOURCE_TYPES.has(args.resourceType);
43482
43520
  const queryValueParams = args.queryValueParams ?? [];
43483
43521
  const parameters = isSystemType ? [...queryValueParams] : buildDefaultParameters(args.method, args.resourceName, resourcePath, args.vendorPath, args.hasCeql, {
@@ -43485,6 +43523,23 @@ function addElementResourceEntry(element, args) {
43485
43523
  pageSizeParam: args.pageSizeParam,
43486
43524
  offsetParam: args.offsetParam
43487
43525
  }, queryValueParams, args.noBody ?? false);
43526
+ const existing = findResourceEntry(element, resourcePath, args.method);
43527
+ if (existing) {
43528
+ if (args.explicitVendorPath && args.vendorPath && existing.vendorPath !== args.vendorPath) {
43529
+ existing.vendorPath = args.vendorPath;
43530
+ existing.vendorMethod = args.method;
43531
+ const existingParams = Array.isArray(existing.parameters) ? existing.parameters : [];
43532
+ const seen = new Set(existingParams.map((p) => typeof p.name === "string" ? p.name : ""));
43533
+ for (const p of parameters) {
43534
+ const pn = typeof p.name === "string" ? p.name : "";
43535
+ if (pn && !seen.has(pn))
43536
+ existingParams.push(p);
43537
+ }
43538
+ existing.parameters = existingParams;
43539
+ return { skipped: false, updated: true };
43540
+ }
43541
+ return { skipped: true };
43542
+ }
43488
43543
  const entry = {
43489
43544
  path: resourcePath,
43490
43545
  vendorPath: args.vendorPath,
@@ -43529,7 +43584,8 @@ async function syncSrParamsWithElement(root, srFileName, name, methods, primaryK
43529
43584
  const methodMap = metadata.method ?? {};
43530
43585
  metadata.method = methodMap;
43531
43586
  const base = resourcePath || `/${name}`;
43532
- let updates = 0;
43587
+ let changedMethods = 0;
43588
+ let syncedParams = 0;
43533
43589
  for (const m of methods) {
43534
43590
  const elemMethod = m === "GETBYID" ? "GET" : m;
43535
43591
  const elemPath = methodNeedsIdSuffix(m, methods) ? `${base}/{${primaryKey}}` : base;
@@ -43543,13 +43599,14 @@ async function syncSrParamsWithElement(root, srFileName, name, methods, primaryK
43543
43599
  const merged = syncMethodParams(existing, elemParams);
43544
43600
  if (JSON.stringify(merged) !== JSON.stringify(existing)) {
43545
43601
  methodCfg.parameters = merged;
43546
- updates += 1;
43602
+ changedMethods += 1;
43603
+ syncedParams += merged.length;
43547
43604
  }
43548
43605
  }
43549
- if (updates) {
43606
+ if (changedMethods) {
43550
43607
  await writeStandardResource(root, srFileName, sr);
43551
43608
  }
43552
- return updates;
43609
+ return syncedParams;
43553
43610
  }
43554
43611
  async function listResources(connectorRoot, filter = {}) {
43555
43612
  const found = await findElementDir(connectorRoot);
@@ -43990,13 +44047,22 @@ async function upsertParam(connectorRoot, resource, method, param) {
43990
44047
  if (!located.ok)
43991
44048
  return located;
43992
44049
  const { root, element, entry } = located;
44050
+ const warnings = [];
44051
+ const internalPath = String(entry.path ?? "");
44052
+ let inputParam = param;
44053
+ if (param.type === "path" && !internalPath.includes(`{${name}}`)) {
44054
+ inputParam = { ...param, type: "query" };
44055
+ if (inputParam.vendorType === undefined)
44056
+ inputParam.vendorType = "path";
44057
+ 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.`);
44058
+ }
43993
44059
  const params = getEntryParams(entry);
43994
44060
  const idx = params.findIndex((p) => p.name === name);
43995
44061
  const outcome = idx >= 0 ? "replaced" : "added";
43996
44062
  if (idx >= 0) {
43997
- params[idx] = { ...params[idx], ...param };
44063
+ params[idx] = { ...params[idx], ...inputParam };
43998
44064
  } else {
43999
- params.push(withNewParamDefaults(param));
44065
+ params.push(withNewParamDefaults(inputParam));
44000
44066
  }
44001
44067
  entry.parameters = params;
44002
44068
  const effectiveParam = params[idx >= 0 ? idx : params.length - 1];
@@ -44011,7 +44077,8 @@ async function upsertParam(connectorRoot, resource, method, param) {
44011
44077
  method,
44012
44078
  param: effectiveParam,
44013
44079
  outcome,
44014
- srSynced
44080
+ srSynced,
44081
+ ...warnings.length > 0 ? { warnings } : {}
44015
44082
  }
44016
44083
  };
44017
44084
  } catch (e) {
@@ -44093,6 +44160,10 @@ async function locateEntry(connectorRoot, resource, method) {
44093
44160
  return { ok: true, root, element, entry: match };
44094
44161
  }
44095
44162
  }
44163
+ const byName = resources.find((r) => typeof r.standardResourceName === "string" && r.standardResourceName === resource && r.method === elemMethod);
44164
+ if (byName) {
44165
+ return { ok: true, root, element, entry: byName };
44166
+ }
44096
44167
  return {
44097
44168
  ok: false,
44098
44169
  error: {
@@ -44207,6 +44278,10 @@ var VISIBILITY_ALLOWED_KEYS = new Set([
44207
44278
  "name",
44208
44279
  "designOverrides"
44209
44280
  ]);
44281
+ var VISIBILITY_KEY_ALIASES = {
44282
+ "request-curated": "requestCurated",
44283
+ "response-curated": "responseCurated"
44284
+ };
44210
44285
  var ALLOWED_FIELD_SPEC_KEYS = new Set([
44211
44286
  "name",
44212
44287
  "type",
@@ -44306,8 +44381,46 @@ function validateReference(parsed, label, errors) {
44306
44381
  if (typeof parsed.path !== "string" || parsed.path.length === 0) {
44307
44382
  errors.push(`${label}: 'reference' requires a non-empty 'path' (e.g. '/system_countries').`);
44308
44383
  }
44384
+ if (typeof parsed.lookupValue !== "string" || parsed.lookupValue.length === 0) {
44385
+ 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.`);
44386
+ }
44309
44387
  return parsed;
44310
44388
  }
44389
+ var FIELD_ACTION_TYPES = new Set([
44390
+ "show",
44391
+ "hide",
44392
+ "required",
44393
+ "optional",
44394
+ "showMessages",
44395
+ "api",
44396
+ "reset"
44397
+ ]);
44398
+ function validateFieldActions(parsed, label, warnings) {
44399
+ if (!Array.isArray(parsed)) {
44400
+ warnings.push(`${label}: 'design.fieldActions' is usually an array.`);
44401
+ return;
44402
+ }
44403
+ parsed.forEach((action, i) => {
44404
+ if (!isPlainObject(action)) {
44405
+ warnings.push(`${label}: fieldActions[${i}] should be an object.`);
44406
+ return;
44407
+ }
44408
+ const at = action.actionType;
44409
+ if (typeof at !== "string" || !FIELD_ACTION_TYPES.has(at)) {
44410
+ warnings.push(`${label}: fieldActions[${i}].actionType '${String(at)}' is uncommon (usual: ${[...FIELD_ACTION_TYPES].join(", ")}).`);
44411
+ }
44412
+ const rules = action.rules;
44413
+ if (!Array.isArray(rules) || rules.length === 0) {
44414
+ warnings.push(`${label}: fieldActions[${i}] needs a non-empty 'rules' array (each rule points at the field it reacts to).`);
44415
+ return;
44416
+ }
44417
+ rules.forEach((rule, j) => {
44418
+ if (!isPlainObject(rule) || typeof rule.refFieldName !== "string" || rule.refFieldName.length === 0) {
44419
+ warnings.push(`${label}: fieldActions[${i}].rules[${j}] needs a non-empty 'refFieldName' (the field it depends on).`);
44420
+ }
44421
+ });
44422
+ });
44423
+ }
44311
44424
  function validateVisibility(parsed, label, errors, warnings) {
44312
44425
  if (!isPlainObject(parsed)) {
44313
44426
  errors.push(`${label}: per-method visibility must be an object keyed by HTTP method (e.g. { "GET": { "response": true } }).`);
@@ -44323,22 +44436,26 @@ function validateVisibility(parsed, label, errors, warnings) {
44323
44436
  out[method] = entry;
44324
44437
  continue;
44325
44438
  }
44439
+ const normEntry = {};
44326
44440
  for (const [k, v] of Object.entries(entry)) {
44327
- if (!VISIBILITY_ALLOWED_KEYS.has(k)) {
44441
+ const nk = VISIBILITY_KEY_ALIASES[k] ?? k;
44442
+ if (!VISIBILITY_ALLOWED_KEYS.has(nk)) {
44328
44443
  warnings.push(`${label}: unknown visibility key '${k}' on method '${method}'.`);
44444
+ normEntry[k] = v;
44329
44445
  continue;
44330
44446
  }
44331
- if (VISIBILITY_BOOLEAN_KEYS.has(k) && !isBooleanish(v)) {
44332
- warnings.push(`${label}: visibility '${k}' on method '${method}' is usually true/false.`);
44447
+ if (VISIBILITY_BOOLEAN_KEYS.has(nk) && !isBooleanish(v)) {
44448
+ warnings.push(`${label}: visibility '${nk}' on method '${method}' is usually true/false.`);
44333
44449
  }
44334
- if (k === "designOverrides") {
44450
+ if (nk === "designOverrides") {
44335
44451
  const pos = isPlainObject(v) ? v.position : undefined;
44336
44452
  if (pos !== undefined && (typeof pos !== "string" || !DESIGN_POSITIONS.has(pos))) {
44337
44453
  warnings.push(`${label}: uncommon designOverrides.position on method '${method}'; passed through.`);
44338
44454
  }
44339
44455
  }
44456
+ normEntry[nk] = v;
44340
44457
  }
44341
- out[method] = entry;
44458
+ out[method] = normEntry;
44342
44459
  }
44343
44460
  return out;
44344
44461
  }
@@ -44397,15 +44514,19 @@ function normalizeOne(raw, index, errors, warnings) {
44397
44514
  warnings.push(`${label}: '${k}' is usually a number.`);
44398
44515
  }
44399
44516
  }
44400
- for (const k of [
44401
- "searchableOperators",
44402
- "searchableNames",
44403
- "fieldActions"
44404
- ]) {
44405
- if (raw[k] !== undefined && !Array.isArray(raw[k])) {
44517
+ for (const k of ["searchableOperators", "searchableNames"]) {
44518
+ const v = raw[k];
44519
+ if (v === undefined)
44520
+ continue;
44521
+ if (typeof v === "string") {
44522
+ spec[k] = v.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
44523
+ } else if (!Array.isArray(v)) {
44406
44524
  warnings.push(`${label}: '${k}' is usually an array.`);
44407
44525
  }
44408
44526
  }
44527
+ if (raw.fieldActions !== undefined && !Array.isArray(raw.fieldActions)) {
44528
+ warnings.push(`${label}: 'fieldActions' is usually an array.`);
44529
+ }
44409
44530
  if (raw.enum !== undefined) {
44410
44531
  const normalized = normalizeEnumValues(raw.enum, label, warnings);
44411
44532
  if (normalized)
@@ -44424,6 +44545,9 @@ function normalizeOne(raw, index, errors, warnings) {
44424
44545
  if (pos !== undefined && (typeof pos !== "string" || !DESIGN_POSITIONS.has(pos))) {
44425
44546
  warnings.push(`${label}: uncommon design.position '${String(pos)}' (usual: ${[...DESIGN_POSITIONS].join(", ")}). Passed through.`);
44426
44547
  }
44548
+ if (raw.design.fieldActions !== undefined) {
44549
+ validateFieldActions(raw.design.fieldActions, label, warnings);
44550
+ }
44427
44551
  }
44428
44552
  if (raw.method !== undefined && raw.methods !== undefined) {
44429
44553
  errors.push(`${label}: pass only one of 'method' or 'methods' (they are aliases; 'method' is canonical).`);
@@ -44504,6 +44628,9 @@ function checkStoredFieldShape(name, field) {
44504
44628
  if (pos !== undefined && (typeof pos !== "string" || !DESIGN_POSITIONS.has(pos))) {
44505
44629
  warnings.push(`${label}: uncommon design.position '${String(pos)}' (usual: primary | secondary | none).`);
44506
44630
  }
44631
+ if (field.design.fieldActions !== undefined) {
44632
+ validateFieldActions(field.design.fieldActions, label, warnings);
44633
+ }
44507
44634
  }
44508
44635
  if (field.reference !== undefined) {
44509
44636
  validateReference(field.reference, label, warnings);
@@ -44525,12 +44652,12 @@ var FIELD_KEY_DESCRIPTIONS = {
44525
44652
  sampleValue: "Example value shown in the designer.",
44526
44653
  format: "Format hint, e.g. date-time, int32.",
44527
44654
  mask: `Date/number FORMAT pattern string, e.g. "yyyy-MM-dd'T'HH:mm:ssZ" (not a boolean).`,
44528
- design: "Design metadata object: { position: primary|secondary|none, component, hidden, displayPattern, loadByDefault, isMultiSelect, ... }.",
44655
+ 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).',
44529
44656
  method: "Per-method visibility map, e.g. { GET: { response: true }, POST: { request: true } }.",
44530
44657
  methods: "Alias for 'method' (accepted on input; not both).",
44531
44658
  enum: 'Allowed values. Bare ["a"] is normalized to [{ value: "a" }].',
44532
44659
  enhancedEnum: "Labelled options: [{ name, value }].",
44533
- reference: "Dynamic lookup: { objectName, path, lookupValue, lookupNames } (objectName+path required).",
44660
+ 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.",
44534
44661
  primaryKey: "true if this field is the primary key.",
44535
44662
  sortOrder: "Number controlling field order.",
44536
44663
  searchable: "true if usable in CEQL filters.",
@@ -44542,7 +44669,7 @@ var FIELD_KEY_DESCRIPTIONS = {
44542
44669
  isCuratedEventField: "true if this field is a curated event/trigger field.",
44543
44670
  isPriority: "true to mark the field as high-priority in the designer.",
44544
44671
  key: "Vendor-side key alias some connectors carry alongside name.",
44545
- fieldActions: "Conditional show/hide rules array (cascading field visibility)."
44672
+ 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."
44546
44673
  };
44547
44674
  function describeFieldSchema() {
44548
44675
  return {
@@ -44595,6 +44722,61 @@ function describeFieldSchema() {
44595
44722
  lookupNames: ["name"]
44596
44723
  },
44597
44724
  method: { GET: { response: true } }
44725
+ },
44726
+ {
44727
+ name: "team_id",
44728
+ type: "string",
44729
+ displayName: "Team",
44730
+ reference: {
44731
+ objectName: "teams",
44732
+ path: "/teams",
44733
+ lookupValue: "id",
44734
+ lookupNames: ["id", "displayName"]
44735
+ },
44736
+ design: {
44737
+ displayPattern: "{displayName}",
44738
+ loadByDefault: true
44739
+ },
44740
+ method: { POST: { request: true } }
44741
+ },
44742
+ {
44743
+ name: "channel_id",
44744
+ type: "string",
44745
+ displayName: "Channel",
44746
+ reference: {
44747
+ objectName: "teams::channels",
44748
+ path: "/teams/{team_id}/channels",
44749
+ lookupValue: "id",
44750
+ lookupNames: ["id", "displayName"]
44751
+ },
44752
+ design: {
44753
+ displayPattern: "{displayName}",
44754
+ isHidden: true,
44755
+ fieldActions: [
44756
+ {
44757
+ actionType: "show",
44758
+ rules: [
44759
+ {
44760
+ type: "field",
44761
+ refFieldName: "team_id",
44762
+ refFieldValues: ["*"],
44763
+ isCleared: false
44764
+ }
44765
+ ]
44766
+ },
44767
+ {
44768
+ actionType: "hide",
44769
+ rules: [
44770
+ {
44771
+ type: "field",
44772
+ refFieldName: "team_id",
44773
+ isCleared: true
44774
+ }
44775
+ ]
44776
+ }
44777
+ ]
44778
+ },
44779
+ method: { POST: { request: true } }
44598
44780
  }
44599
44781
  ]
44600
44782
  };
@@ -45374,6 +45556,74 @@ function normalizeVisibilityToken(token) {
45374
45556
  return null;
45375
45557
  }
45376
45558
  }
45559
+ function buildDependencyActions(parentField) {
45560
+ return [
45561
+ {
45562
+ actionType: "show",
45563
+ priorityOrder: 0,
45564
+ rules: [
45565
+ {
45566
+ type: "field",
45567
+ refFieldName: parentField,
45568
+ refFieldValues: ["*"],
45569
+ isCleared: false,
45570
+ isVariable: false
45571
+ }
45572
+ ]
45573
+ },
45574
+ {
45575
+ actionType: "hide",
45576
+ priorityOrder: 1,
45577
+ rules: [
45578
+ {
45579
+ type: "field",
45580
+ refFieldName: parentField,
45581
+ isCleared: true,
45582
+ isVariable: false
45583
+ }
45584
+ ]
45585
+ }
45586
+ ];
45587
+ }
45588
+ function buildReferenceAndDesign(o) {
45589
+ const ref = o.reference !== undefined ? parseFieldJson(o.reference, "reference") : {};
45590
+ if (o.referenceObject !== undefined)
45591
+ ref.objectName = o.referenceObject;
45592
+ if (o.referencePath !== undefined)
45593
+ ref.path = o.referencePath;
45594
+ if (o.lookupValue !== undefined)
45595
+ ref.lookupValue = o.lookupValue;
45596
+ const lookupNames = splitCsv(o.lookupNames);
45597
+ if (lookupNames !== undefined)
45598
+ ref.lookupNames = lookupNames;
45599
+ if (o.filterPattern !== undefined)
45600
+ ref.filterPattern = o.filterPattern;
45601
+ const design = {};
45602
+ if (o.designPosition !== undefined)
45603
+ design.position = o.designPosition;
45604
+ if (o.component !== undefined)
45605
+ design.component = o.component;
45606
+ if (o.hidden)
45607
+ design.isHidden = true;
45608
+ if (o.displayPattern !== undefined)
45609
+ design.displayPattern = o.displayPattern;
45610
+ if (o.loadByDefault)
45611
+ design.loadByDefault = true;
45612
+ if (o.multiSelect)
45613
+ design.isMultiSelect = true;
45614
+ if (o.enableUserOverride)
45615
+ design.enableUserOverride = true;
45616
+ if (o.dependsOn !== undefined) {
45617
+ design.isHidden = true;
45618
+ design.fieldActions = buildDependencyActions(o.dependsOn);
45619
+ }
45620
+ if (o.fieldActions !== undefined)
45621
+ design.fieldActions = parseFieldJson(o.fieldActions, "field-actions");
45622
+ return {
45623
+ reference: Object.keys(ref).length > 0 ? ref : undefined,
45624
+ design: Object.keys(design).length > 0 ? design : undefined
45625
+ };
45626
+ }
45377
45627
  function buildField(options) {
45378
45628
  const raw = { name: options.name };
45379
45629
  if (options.type !== undefined)
@@ -45392,8 +45642,9 @@ function buildField(options) {
45392
45642
  raw.enum = parseFieldJson(options.enum, "enum");
45393
45643
  if (options.enhancedEnum !== undefined)
45394
45644
  raw.enhancedEnum = parseFieldJson(options.enhancedEnum, "enhanced-enum");
45395
- if (options.reference !== undefined)
45396
- raw.reference = parseFieldJson(options.reference, "reference");
45645
+ const dropdown = buildReferenceAndDesign(options);
45646
+ if (dropdown.reference !== undefined)
45647
+ raw.reference = dropdown.reference;
45397
45648
  if (options.defaultValue !== undefined)
45398
45649
  raw.defaultValue = parseDefaultValue(options.defaultValue);
45399
45650
  if (options.mask !== undefined)
@@ -45446,16 +45697,8 @@ function buildField(options) {
45446
45697
  }
45447
45698
  raw.method = methodMap;
45448
45699
  }
45449
- if (options.designPosition !== undefined || options.component !== undefined || options.hidden) {
45450
- const design = {};
45451
- if (options.designPosition !== undefined)
45452
- design.position = options.designPosition;
45453
- if (options.component !== undefined)
45454
- design.component = options.component;
45455
- if (options.hidden)
45456
- design.hidden = true;
45457
- raw.design = design;
45458
- }
45700
+ if (dropdown.design !== undefined)
45701
+ raw.design = dropdown.design;
45459
45702
  const { specs } = validateAndNormalizeFieldSpecs([raw]);
45460
45703
  return specs?.[0];
45461
45704
  }
@@ -45482,11 +45725,33 @@ function buildParam(options) {
45482
45725
  param.displayName = options.displayName;
45483
45726
  if (options.sortOrder !== undefined)
45484
45727
  param.sortOrder = Number(options.sortOrder);
45728
+ const enumErrors = [];
45729
+ const enumLabel = `param '${options.name}'`;
45730
+ if (options.enum !== undefined) {
45731
+ const norm = normalizeEnumValues(parseFieldJson(options.enum, "enum"), enumLabel, enumErrors);
45732
+ if (norm !== undefined)
45733
+ param.enum = norm;
45734
+ }
45735
+ if (options.enhancedEnum !== undefined) {
45736
+ const norm = normalizeEnhancedEnum(parseFieldJson(options.enhancedEnum, "enhanced-enum"), enumLabel, enumErrors);
45737
+ if (norm !== undefined)
45738
+ param.enhancedEnum = norm;
45739
+ }
45740
+ if (enumErrors.length > 0)
45741
+ throw new Error(enumErrors.join("; "));
45742
+ const dropdown = buildReferenceAndDesign(options);
45743
+ if (dropdown.reference !== undefined)
45744
+ param.reference = dropdown.reference;
45745
+ if (dropdown.design !== undefined)
45746
+ param.design = dropdown.design;
45485
45747
  return param;
45486
45748
  }
45487
45749
  function collect(value, previous = []) {
45488
45750
  return [...previous, value];
45489
45751
  }
45752
+ function addDropdownOptions(cmd) {
45753
+ 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");
45754
+ }
45490
45755
  function registerActivityCommands(builder) {
45491
45756
  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.");
45492
45757
  registerResourceVerbs(activity);
@@ -45636,12 +45901,14 @@ function registerFieldCommands(resource) {
45636
45901
  })
45637
45902
  });
45638
45903
  });
45639
- 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([
45904
+ 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([
45640
45905
  "Adding or updating a UI field with per-method visibility and design metadata.",
45641
45906
  "Assembling per-method visibility incrementally — each call merges into the existing field."
45642
45907
  ], [
45643
45908
  "Adding a runtime request parameter — use 'activity param create'."
45644
- ])).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) => {
45909
+ ])).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)");
45910
+ addDropdownOptions(fieldCreate);
45911
+ 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) => {
45645
45912
  const root = await resolveConnectorRoot(options.connectorDir);
45646
45913
  if (root === null)
45647
45914
  return;
@@ -45778,7 +46045,9 @@ function registerParamCommands(resource) {
45778
46045
  })
45779
46046
  });
45780
46047
  });
45781
- 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) => {
46048
+ 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");
46049
+ addDropdownOptions(paramCreate);
46050
+ 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) => {
45782
46051
  const root = await resolveConnectorRoot(options.connectorDir);
45783
46052
  if (root === null)
45784
46053
  return;
@@ -45791,7 +46060,8 @@ function registerParamCommands(resource) {
45791
46060
  ParamName: data.param.name ?? null,
45792
46061
  Param: data.param,
45793
46062
  Outcome: data.outcome,
45794
- SrSynced: data.srSynced
46063
+ SrSynced: data.srSynced,
46064
+ ...data.warnings ? { Warnings: data.warnings } : {}
45795
46065
  })
45796
46066
  });
45797
46067
  });
@@ -48198,22 +48468,7 @@ var VALID_LIFECYCLE_STAGES = [
48198
48468
  "PREVIEW",
48199
48469
  "DEPRECATED"
48200
48470
  ];
48201
- var KNOWN_PARAM_TYPES = new Set([
48202
- "configuration",
48203
- "header",
48204
- "path",
48205
- "query",
48206
- "form",
48207
- "multipart",
48208
- "body",
48209
- "bodyField",
48210
- "bodyToken",
48211
- "value",
48212
- "prevBody",
48213
- "prevBodyField",
48214
- "customValue",
48215
- "no-op"
48216
- ]);
48471
+ var KNOWN_PARAM_TYPES = new Set(VALID_PARAMETER_TYPES);
48217
48472
  var KNOWN_PARAM_SOURCES = new Set([
48218
48473
  "request",
48219
48474
  "response"
@@ -48565,6 +48820,35 @@ async function validateConnector(connectorRoot) {
48565
48820
  warnings.push(`Uncommon resource type '${rtype}': ${strOrQ2(r.method)} ${strOrQ2(r.path)}`);
48566
48821
  }
48567
48822
  }
48823
+ const globalPathVendorNames = new Set(asRecordArray2(elem.parameters).filter((p) => p.vendorType === "path").map((p) => stringOr3(p.vendorName)).filter((n) => n.length > 0));
48824
+ const pathTokens = (p) => [
48825
+ ...new Set([...p.matchAll(/\{([\w.]+)\}/g)].map((m) => m[1]))
48826
+ ];
48827
+ for (const r of resources) {
48828
+ const rPath = stringOr3(r.path);
48829
+ const rVendorPath = stringOr3(r.vendorPath);
48830
+ if (!rPath)
48831
+ continue;
48832
+ const params = asRecordArray2(r.parameters);
48833
+ for (const p of params) {
48834
+ const pName = stringOr3(p.name);
48835
+ const pVendorName = stringOr3(p.vendorName);
48836
+ if (p.type === "path" && pName && !rPath.includes(`{${pName}}`)) {
48837
+ 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.`);
48838
+ }
48839
+ if (p.vendorType === "path" && pVendorName && rVendorPath && !rVendorPath.includes(`{${pVendorName}}`)) {
48840
+ 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.`);
48841
+ }
48842
+ }
48843
+ if (rVendorPath) {
48844
+ const boundVendorNames = new Set(params.filter((p) => p.vendorType === "path").map((p) => stringOr3(p.vendorName)));
48845
+ for (const token of pathTokens(rVendorPath)) {
48846
+ if (!boundVendorNames.has(token) && !globalPathVendorNames.has(token)) {
48847
+ 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}".`);
48848
+ }
48849
+ }
48850
+ }
48851
+ }
48568
48852
  const srDir = fs8.path.join(root, ...SR_REL3);
48569
48853
  const seenSrNames = new Set;
48570
48854
  for (const r of resources) {
@@ -48580,6 +48864,7 @@ async function validateConnector(connectorRoot) {
48580
48864
  }
48581
48865
  warnings.push(...await checkSrLinkage(elem, root));
48582
48866
  warnings.push(...await checkFieldlessActivities(elem, root));
48867
+ warnings.push(...await checkDropdownTargets(elem, root));
48583
48868
  const hooksDir = fs8.path.join(root, "app", "element", "hooks");
48584
48869
  for (const r of resources) {
48585
48870
  for (const hook of asRecordArray2(r.hooks)) {
@@ -48658,6 +48943,40 @@ async function validateConnector(connectorRoot) {
48658
48943
  }
48659
48944
  }
48660
48945
  }
48946
+ const knownNames = new Set(Object.keys(fields));
48947
+ for (const mData of Object.values(methodMeta)) {
48948
+ for (const p of asRecordArray2(asRecord2(mData).parameters)) {
48949
+ const pn = stringOr3(p.name);
48950
+ if (pn)
48951
+ knownNames.add(pn);
48952
+ }
48953
+ }
48954
+ const checkDropdownWiring = (kind, carrier) => {
48955
+ const design = asRecord2(carrier.design);
48956
+ const refPath = stringOr3(asRecord2(carrier.reference).path);
48957
+ for (const m of refPath.matchAll(/\{([\w.]+)\}/g)) {
48958
+ if (!knownNames.has(m[1])) {
48959
+ 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.`);
48960
+ }
48961
+ }
48962
+ const actions = Array.isArray(design.fieldActions) ? design.fieldActions : [];
48963
+ for (const action of actions) {
48964
+ for (const rule of asRecordArray2(asRecord2(action).rules)) {
48965
+ const rfn = stringOr3(rule.refFieldName);
48966
+ if (rfn && !knownNames.has(rfn)) {
48967
+ warnings.push(`${srName}: ${kind} has a show/hide rule on '${rfn}', which isn't a field/param on this resource.`);
48968
+ }
48969
+ }
48970
+ }
48971
+ };
48972
+ for (const [fName, fVal] of Object.entries(fields)) {
48973
+ checkDropdownWiring(`field '${fName}'`, asRecord2(fVal));
48974
+ }
48975
+ for (const [mName, mData] of Object.entries(methodMeta)) {
48976
+ for (const p of asRecordArray2(asRecord2(mData).parameters)) {
48977
+ checkDropdownWiring(`${mName} param '${stringOr3(p.name)}'`, p);
48978
+ }
48979
+ }
48661
48980
  }
48662
48981
  } else {
48663
48982
  warnings.push("No standard-resources/ directory found");
@@ -48832,6 +49151,64 @@ async function checkSrLinkage(elem, root) {
48832
49151
  }
48833
49152
  return warnings;
48834
49153
  }
49154
+ async function checkDropdownTargets(elem, root) {
49155
+ const fs8 = getFileSystem();
49156
+ const warnings = [];
49157
+ const srDir = fs8.path.join(root, ...SR_REL3);
49158
+ if (!await fs8.exists(srDir)) {
49159
+ return warnings;
49160
+ }
49161
+ const objMethods = new Map;
49162
+ for (const r of asRecordArray2(elem.resources)) {
49163
+ if (SYSTEM_RESOURCE_TYPES.has(stringOr3(r.type))) {
49164
+ continue;
49165
+ }
49166
+ const obj = stringOr3(r.standardResourceName);
49167
+ if (!obj) {
49168
+ continue;
49169
+ }
49170
+ const method = stringOr3(r.method ?? r.vendorMethod).toUpperCase();
49171
+ const set2 = objMethods.get(obj) ?? new Set;
49172
+ if (method) {
49173
+ set2.add(method);
49174
+ }
49175
+ objMethods.set(obj, set2);
49176
+ }
49177
+ const isReadable = (obj) => {
49178
+ const set2 = objMethods.get(obj);
49179
+ return set2 !== undefined && (set2.has("GET") || set2.has("GETBYID"));
49180
+ };
49181
+ const srFiles = (await fs8.readdir(srDir)).filter((f) => f.endsWith(".json"));
49182
+ for (const srName of srFiles) {
49183
+ const sr = await readJsonFile2(fs8.path.join(srDir, srName));
49184
+ if (sr === null) {
49185
+ continue;
49186
+ }
49187
+ const flagged = new Set;
49188
+ const walk = (node2) => {
49189
+ if (Array.isArray(node2)) {
49190
+ for (const item of node2) {
49191
+ walk(item);
49192
+ }
49193
+ return;
49194
+ }
49195
+ if (node2 === null || typeof node2 !== "object") {
49196
+ return;
49197
+ }
49198
+ const rec = node2;
49199
+ const obj = stringOr3(asRecord2(rec.reference).objectName);
49200
+ if (obj && objMethods.has(obj) && !isReadable(obj) && !flagged.has(obj)) {
49201
+ flagged.add(obj);
49202
+ 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.`);
49203
+ }
49204
+ for (const value of Object.values(rec)) {
49205
+ walk(value);
49206
+ }
49207
+ };
49208
+ walk(sr);
49209
+ }
49210
+ return warnings;
49211
+ }
48835
49212
  async function checkFieldlessActivities(elem, root) {
48836
49213
  const fs8 = getFileSystem();
48837
49214
  const warnings = [];
@@ -50500,7 +50877,7 @@ function parseResources(segments, filters) {
50500
50877
  });
50501
50878
  }
50502
50879
  if (segments.length === 3) {
50503
- throw new Error(`element.json/resources/${segments[2]} requires a URL-encoded resource path. ` + `Example: element.json/resources/${segments[2]}/%2Fcontacts`);
50880
+ 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]}').`);
50504
50881
  }
50505
50882
  const method = segments[2].toUpperCase();
50506
50883
  const resourcePath = unquote(segments[3]);
@@ -54295,4 +54672,4 @@ export {
54295
54672
  metadata
54296
54673
  };
54297
54674
 
54298
- //# debugId=E629FCACA204A19164756E2164756E21
54675
+ //# debugId=83EE43E85080E9AF64756E2164756E21
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-preview.90",
4
+ "version": "1.199.0-preview.91",
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": "7fa615fb10f91f98f796a038ea70569336611f42"
29
+ "gitHead": "f428cb1e61ba89ad18394b0c6106784055699f02"
30
30
  }