@uipath/maestro-builder-sdk 6.8.0 → 6.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/check.js CHANGED
@@ -1250,7 +1250,7 @@ function checkConnectorLookups(step, spec, opts, diags) {
1250
1250
  const declared = specs?.[named];
1251
1251
  const by = value.__lookup.by;
1252
1252
  if (declared && typeof by === 'string' && !declared.by.includes(by)) {
1253
- const { target, call } = lookupPhrases(named, declared);
1253
+ const { target, call } = lookupPhrases(named, declared, spec);
1254
1254
  diags.push({
1255
1255
  level: 'error',
1256
1256
  code: 'LOOKUP_UNKNOWN_MATCH_KEY',
@@ -1302,7 +1302,7 @@ function checkConnectorLookups(step, spec, opts, diags) {
1302
1302
  const literal = value instanceof Expr ? value.value : value;
1303
1303
  if (typeof literal !== 'string')
1304
1304
  return;
1305
- const { target, call } = lookupPhrases(field, lookup);
1305
+ const { target, call } = lookupPhrases(field, lookup, spec);
1306
1306
  diags.push({
1307
1307
  level: 'warning',
1308
1308
  code: 'LOOKUP_LITERAL_ID',
@@ -1439,13 +1439,32 @@ function checkConnectorContract(step, spec, opts, diags) {
1439
1439
  }
1440
1440
  }
1441
1441
  }
1442
- /** The two phrases every lookup diagnostic needs: what the field sends, and how to resolve it. */
1443
- function lookupPhrases(field, lookup) {
1442
+ /**
1443
+ * The two phrases every lookup diagnostic needs: what the field sends, and how
1444
+ * to resolve it.
1445
+ *
1446
+ * The `call` names BOTH authoring forms, and names which one the alias belongs
1447
+ * to. Printing `lookup(<Descriptor>, 'entityName').byDisplayName('<value>')`
1448
+ * alone — the old text — was a remedy with an unstated precondition: aliases
1449
+ * are generated onto the descriptor, and `<Descriptor>` is a placeholder the
1450
+ * reader has to fill from somewhere. An author holding the connector key and
1451
+ * action instead (the form the library's Generic CRUD half is authored in, and
1452
+ * the majority of its lookup fields) substitutes those for the placeholder,
1453
+ * keeps the alias, and gets `lookup(...).byDisplayName is not a function`. Six
1454
+ * flow-eval tasks did precisely that, each losing a check-edit-check round to
1455
+ * a message that had told them to.
1456
+ */
1457
+ function lookupPhrases(field, lookup, spec) {
1444
1458
  const target = `${lookup.objectName ?? lookup.path}.${lookup.value}`;
1459
+ const by = lookup.by[0] ?? 'id';
1445
1460
  const alias = Object.keys(lookup.aliases)[0];
1461
+ // The key/action form first: it needs no import, so it is the one line that
1462
+ // is paste-ready from the message alone.
1463
+ const generic = `lookup('${spec.key}', '${spec.action}', '${field}').by('${by}', '<value>')`;
1446
1464
  const call = alias
1447
- ? `lookup(<Descriptor>, '${field}').${alias}('<value>')`
1448
- : `lookup(<Descriptor>, '${field}').by('${lookup.by[0] ?? 'id'}', '<value>')`;
1465
+ ? `${generic}\n or \`lookup(D, '${field}').${alias}('<value>')\`, where D is the `
1466
+ + `descriptor \`${prepareCommand(spec.key, spec.action)}\` generates — the aliases exist only there`
1467
+ : generic;
1449
1468
  return { target, call };
1450
1469
  }
1451
1470
  /**
@@ -1502,7 +1521,7 @@ function runtimeLookupDiagnostic(step, spec, field, lookup, value) {
1502
1521
  || leaf.toLowerCase() === valueLeaf.toLowerCase()
1503
1522
  || (valueIsEmail && EMAIL_LEAF.test(leaf))))
1504
1523
  return undefined;
1505
- const { target, call } = lookupPhrases(field, lookup);
1524
+ const { target, call } = lookupPhrases(field, lookup, spec);
1506
1525
  const searchesByEmail = lookup.by.some((b) => EMAIL_LEAF.test(b));
1507
1526
  const isEmail = !!leaf && EMAIL_LEAF.test(leaf) && !valueIsEmail && !searchesByEmail;
1508
1527
  const message = `Connector step "${step}": \`${field}\` is a lookup field bound to the runtime expression `
@@ -46,7 +46,53 @@ export function isLookupToken(v) {
46
46
  export function lookupKey(nodeType, field, by, value) {
47
47
  return JSON.stringify([nodeType, field, by, value]);
48
48
  }
49
- function makeBuilder(nodeType, field, spec) {
49
+ /**
50
+ * An alias-shaped property: `byEmail`, `byDisplayName`, `byAccountId`.
51
+ *
52
+ * Narrow on purpose. The builder is handed to whatever inspects it next —
53
+ * `util.inspect`, a `then` probe on an accidental `await`, a spread — and a
54
+ * trap that answered for EVERY absent name would turn those into throws. Only
55
+ * a name the author could have meant as an alias is intercepted.
56
+ */
57
+ const ALIAS_SHAPE = /^by[A-Z]/;
58
+ /**
59
+ * Why `.byDisplayName()` is absent, in the terms of the form that was used.
60
+ *
61
+ * Aliases are generated from the descriptor's own `lookups` table, so the
62
+ * string form — which has no table to read — offers only `.by(name, value)`.
63
+ * That is a deliberate trade (see the overload's `@remarks`), but the author
64
+ * who trips it learns it as `lookup(...).byDisplayName is not a function`: a
65
+ * bare `TypeError` naming neither the field, the form, nor the way out. Six
66
+ * flow-eval tasks lost turns to exactly that message, every one of them having
67
+ * copied an alias out of a diagnostic or a descriptor's doc comment and pasted
68
+ * it onto the key/action form they happened to be holding.
69
+ */
70
+ function missingAliasMessage(nodeType, field, alias, spec, generic) {
71
+ const head = `lookup(${nodeType}, '${field}'): \`.${alias}()\` does not exist. `;
72
+ if (!spec) {
73
+ // The remedy names the author's OWN key and action rather than a
74
+ // placeholder: a remedy with a hole in it is what produced this call.
75
+ const here = generic
76
+ ? `lookup('${generic.key}', '${generic.action}', '${field}')`
77
+ : `lookup(…, '${field}')`;
78
+ return head
79
+ + `Aliases are generated onto the descriptor, and this call has no descriptor `
80
+ + `to read them from, so only \`.by(name, value)\` exists here. Search by name:\n`
81
+ + ` ${here}.by('<searchable name>', <value>)\n`
82
+ + `\`check\` and \`${prepareCommand()}\` both print the names this field is `
83
+ + `searchable by. Or import the descriptor `
84
+ + (generic ? `\`${prepareCommand(generic.key, generic.action)}\` generates ` : '')
85
+ + `and call \`.${alias}(<value>)\` on that.`;
86
+ }
87
+ const aliases = Object.keys(spec.aliases);
88
+ return head
89
+ + (aliases.length
90
+ ? `Generated aliases for this field: ${aliases.map((a) => `\`.${a}()\``).join(', ')}. `
91
+ : `This field earns no alias — two of its names camelise to one, so both were dropped. `)
92
+ + `Every searchable name is reachable as `
93
+ + `\`.by(${spec.by.map((b) => `'${b}'`).join(' | ')}, <value>)\`.`;
94
+ }
95
+ function makeBuilder(nodeType, field, spec, generic) {
50
96
  const token = (by, value) => ({ __lookup: { nodeType, field, by, value } });
51
97
  const builder = {
52
98
  by(name, value) {
@@ -63,7 +109,19 @@ function makeBuilder(nodeType, field, spec) {
63
109
  for (const [alias, byName] of Object.entries(spec?.aliases ?? {})) {
64
110
  builder[alias] = (value) => token(byName, value);
65
111
  }
66
- return builder;
112
+ // The throw is deferred to the CALL rather than raised on the property read,
113
+ // so the stack points at `.byDisplayName('Inbox')` — the line the author
114
+ // wrote — instead of at the property access the engine desugared it into.
115
+ return new Proxy(builder, {
116
+ get(target, prop, receiver) {
117
+ if (typeof prop === 'string' && !(prop in target) && ALIAS_SHAPE.test(prop)) {
118
+ return () => {
119
+ throw new Error(missingAliasMessage(nodeType, field, prop, spec, generic));
120
+ };
121
+ }
122
+ return Reflect.get(target, prop, receiver);
123
+ },
124
+ });
67
125
  }
68
126
  export function lookup(a, b, c) {
69
127
  if (typeof a === 'string') {
@@ -71,7 +129,7 @@ export function lookup(a, b, c) {
71
129
  throw new Error("lookup(key, action, field) needs all three arguments; " +
72
130
  "did you mean lookup(descriptor, field)?");
73
131
  }
74
- return makeBuilder(`uipath.connector.${a}.${b}`, c);
132
+ return makeBuilder(`uipath.connector.${a}.${b}`, c, undefined, { key: a, action: b });
75
133
  }
76
134
  if (!('nodeType' in a) || a.nodeType === undefined) {
77
135
  const event = a;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uipath/maestro-builder-sdk",
3
- "version": "6.8.0",
3
+ "version": "6.8.1",
4
4
  "description": "Build UiPath Flow, Case, and BPMN artifacts by writing TypeScript.",
5
5
  "license": "MIT",
6
6
  "homepage": "https://docs.uipath.com/maestro",
@@ -87,5 +87,5 @@
87
87
  "@types/node": "^22.7.0",
88
88
  "esbuild": "^0.28.1"
89
89
  },
90
- "gitref": "de2812e18734552a112d97deec05fc9ae2244caa"
90
+ "gitref": "5ec4e9cb4aeac6a5297078cfd071d7c38784fed3"
91
91
  }