@ixo/editor 5.20.1 → 5.24.0

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.
@@ -897,7 +897,8 @@ registerAction({
897
897
  const submission = await service.submitBid({
898
898
  collectionId,
899
899
  role: chainRole,
900
- surveyAnswers
900
+ surveyAnswers,
901
+ entityDid: deedDid || void 0
901
902
  });
902
903
  const bidId = String(submission?.claimId || submission?.bidId || submission?.id || "");
903
904
  if (!bidId) {
@@ -1004,7 +1005,8 @@ registerAction({
1004
1005
  await service.approveBid({
1005
1006
  bidId,
1006
1007
  collectionId,
1007
- did: applicantDid
1008
+ did: applicantDid,
1009
+ entityDid: deedDid
1008
1010
  });
1009
1011
  } else {
1010
1012
  const reason = String(inputs.reason || "").trim();
@@ -1015,7 +1017,8 @@ registerAction({
1015
1017
  bidId,
1016
1018
  collectionId,
1017
1019
  did: deedDid,
1018
- reason
1020
+ reason,
1021
+ entityDid: deedDid
1019
1022
  });
1020
1023
  }
1021
1024
  return {
@@ -1219,6 +1222,7 @@ registerAction({
1219
1222
  const result = await service.submitClaim({
1220
1223
  surveyData: surveyAnswers,
1221
1224
  deedDid,
1225
+ entityDid: deedDid,
1222
1226
  collectionId,
1223
1227
  adminAddress,
1224
1228
  pin
@@ -1251,6 +1255,505 @@ registerAction({
1251
1255
  }
1252
1256
  });
1253
1257
 
1258
+ // src/core/lib/xeroWorkItems.ts
1259
+ function getXeroWorkItemsMap(editor) {
1260
+ return editor?._yXeroWorkItems || null;
1261
+ }
1262
+ function readMapItems(map) {
1263
+ if (!map) return [];
1264
+ const items = [];
1265
+ map.forEach((value) => {
1266
+ if (value && typeof value === "object" && "id" in value) {
1267
+ items.push({ ...value });
1268
+ }
1269
+ });
1270
+ return items;
1271
+ }
1272
+ function mergeItem(existing, next) {
1273
+ if (existing.status === "completed") {
1274
+ return existing;
1275
+ }
1276
+ return {
1277
+ ...existing,
1278
+ ...next,
1279
+ id: existing.id,
1280
+ attempts: existing.attempts ?? [],
1281
+ originalPayload: existing.originalPayload,
1282
+ submittedPayload: existing.submittedPayload,
1283
+ result: existing.result,
1284
+ completedAt: existing.completedAt,
1285
+ completedByDid: existing.completedByDid
1286
+ };
1287
+ }
1288
+ function buildXeroInvoiceWorkKey(params) {
1289
+ return ["xero", "invoice.create", params.flowId, params.evaluationBlockId, params.claimId, params.invoiceBlockId].join(":");
1290
+ }
1291
+ function buildXeroPaymentWorkKey(params) {
1292
+ return ["xero", "payment.create", params.flowId, params.evaluationBlockId, params.claimId, params.paymentBlockId, params.invoiceWorkItemId].join(":");
1293
+ }
1294
+ function findXeroWorkItemsForEditor(editor, filter) {
1295
+ return readMapItems(getXeroWorkItemsMap(editor)).filter((item) => {
1296
+ if (filter.kind && item.kind !== filter.kind) return false;
1297
+ if (filter.assignedBlockId && item.assignedBlockId !== filter.assignedBlockId) return false;
1298
+ if (filter.statuses && !filter.statuses.includes(item.status)) return false;
1299
+ return true;
1300
+ });
1301
+ }
1302
+ function upsertXeroWorkItemForEditor(editor, next) {
1303
+ const map = getXeroWorkItemsMap(editor);
1304
+ if (!map) {
1305
+ return next;
1306
+ }
1307
+ let existing;
1308
+ map.forEach((item) => {
1309
+ if (item?.idempotencyKey === next.idempotencyKey) existing = item;
1310
+ });
1311
+ const stored = existing ? mergeItem(existing, next) : next;
1312
+ map.set(stored.id, stored);
1313
+ return stored;
1314
+ }
1315
+ function updateXeroWorkReviewPayloadForEditor(editor, itemId, reviewPayload) {
1316
+ const map = getXeroWorkItemsMap(editor);
1317
+ if (!map) return null;
1318
+ const item = map.get(itemId);
1319
+ if (!item) return null;
1320
+ const updatedItem = { ...item, reviewPayload };
1321
+ map.set(itemId, updatedItem);
1322
+ return updatedItem;
1323
+ }
1324
+ function markXeroWorkFailedForEditor(editor, itemId, params) {
1325
+ const map = getXeroWorkItemsMap(editor);
1326
+ if (!map) return null;
1327
+ const item = map.get(itemId);
1328
+ if (!item) return null;
1329
+ const at = params.at ?? Date.now();
1330
+ const updatedItem = {
1331
+ ...item,
1332
+ status: "failed",
1333
+ reviewPayload: params.payload,
1334
+ error: { message: params.error, at },
1335
+ attempts: [...item.attempts ?? [], { at, byDid: params.byDid, payload: params.payload, error: params.error }]
1336
+ };
1337
+ map.set(itemId, updatedItem);
1338
+ return updatedItem;
1339
+ }
1340
+ function markXeroWorkCompletedForEditor(editor, itemId, params) {
1341
+ const map = getXeroWorkItemsMap(editor);
1342
+ if (!map) return null;
1343
+ const item = map.get(itemId);
1344
+ if (!item) return null;
1345
+ const at = params.at ?? Date.now();
1346
+ const updatedItem = {
1347
+ ...item,
1348
+ status: "completed",
1349
+ reviewPayload: params.payload,
1350
+ submittedPayload: params.payload,
1351
+ result: params.result,
1352
+ error: void 0,
1353
+ completedAt: at,
1354
+ completedByDid: params.byDid,
1355
+ attempts: [...item.attempts ?? [], { at, byDid: params.byDid, payload: params.payload, result: params.result }]
1356
+ };
1357
+ map.set(itemId, updatedItem);
1358
+ return updatedItem;
1359
+ }
1360
+
1361
+ // src/core/lib/actionRegistry/actions/xero/invoiceCreate.types.ts
1362
+ var LINE_ITEM_FIELD_KEYS = ["Description", "Quantity", "UnitAmount", "AccountCode", "TaxType", "ItemCode", "DiscountRate"];
1363
+ function emptyLineItemCells() {
1364
+ return {
1365
+ Description: "",
1366
+ Quantity: "1",
1367
+ UnitAmount: "",
1368
+ AccountCode: "",
1369
+ TaxType: "",
1370
+ ItemCode: "",
1371
+ DiscountRate: ""
1372
+ };
1373
+ }
1374
+ function emptyLineItems() {
1375
+ return { mode: "manual", rows: [emptyLineItemCells()] };
1376
+ }
1377
+ function coerceCells(raw) {
1378
+ const base = emptyLineItemCells();
1379
+ if (!raw || typeof raw !== "object") return base;
1380
+ for (const key of LINE_ITEM_FIELD_KEYS) {
1381
+ const v = raw[key];
1382
+ if (typeof v === "string") base[key] = v;
1383
+ else if (typeof v === "number") base[key] = String(v);
1384
+ else if (typeof v === "boolean") base[key] = v ? "true" : "false";
1385
+ }
1386
+ return base;
1387
+ }
1388
+ function normaliseLineItems(raw) {
1389
+ if (raw && typeof raw === "object") {
1390
+ const candidate = raw;
1391
+ if (candidate.mode === "iterative") {
1392
+ return {
1393
+ mode: "iterative",
1394
+ source: typeof candidate.source === "string" ? candidate.source : "",
1395
+ map: coerceCells(candidate.map)
1396
+ };
1397
+ }
1398
+ if (candidate.mode === "manual") {
1399
+ const rows = Array.isArray(candidate.rows) ? candidate.rows.map(coerceCells) : [];
1400
+ return { mode: "manual", rows: rows.length > 0 ? rows : [emptyLineItemCells()] };
1401
+ }
1402
+ }
1403
+ if (typeof raw === "string") {
1404
+ const trimmed = raw.trim();
1405
+ if (!trimmed) return emptyLineItems();
1406
+ try {
1407
+ const parsed = JSON.parse(trimmed);
1408
+ if (Array.isArray(parsed) && parsed.length > 0) {
1409
+ return { mode: "manual", rows: parsed.map(coerceCells) };
1410
+ }
1411
+ } catch {
1412
+ }
1413
+ }
1414
+ return emptyLineItems();
1415
+ }
1416
+ function parseXeroInvoiceCreateInputs(raw) {
1417
+ try {
1418
+ const parsed = typeof raw === "string" ? JSON.parse(raw || "{}") : raw || {};
1419
+ const conn = parsed.connection;
1420
+ const connection = conn && typeof conn === "object" && typeof conn.connectedAccountId === "string" && typeof conn.entityDid === "string" ? { connectedAccountId: conn.connectedAccountId, entityDid: conn.entityDid } : null;
1421
+ return {
1422
+ connection,
1423
+ tenant_id: typeof parsed.tenant_id === "string" ? parsed.tenant_id : "",
1424
+ Type: typeof parsed.Type === "string" && parsed.Type ? parsed.Type : "ACCREC",
1425
+ Status: typeof parsed.Status === "string" ? parsed.Status : "DRAFT",
1426
+ Date: typeof parsed.Date === "string" ? parsed.Date : "",
1427
+ DueDate: typeof parsed.DueDate === "string" ? parsed.DueDate : "",
1428
+ ContactID: typeof parsed.ContactID === "string" ? parsed.ContactID : "",
1429
+ ContactName: typeof parsed.ContactName === "string" ? parsed.ContactName : "",
1430
+ Reference: typeof parsed.Reference === "string" ? parsed.Reference : "",
1431
+ InvoiceNumber: typeof parsed.InvoiceNumber === "string" ? parsed.InvoiceNumber : "",
1432
+ CurrencyCode: typeof parsed.CurrencyCode === "string" ? parsed.CurrencyCode : "",
1433
+ LineItems: normaliseLineItems(parsed.LineItems)
1434
+ };
1435
+ } catch {
1436
+ return {
1437
+ connection: null,
1438
+ tenant_id: "",
1439
+ Type: "ACCREC",
1440
+ Status: "DRAFT",
1441
+ Date: "",
1442
+ DueDate: "",
1443
+ ContactID: "",
1444
+ ContactName: "",
1445
+ Reference: "",
1446
+ InvoiceNumber: "",
1447
+ CurrencyCode: "",
1448
+ LineItems: emptyLineItems()
1449
+ };
1450
+ }
1451
+ }
1452
+ function serializeXeroInvoiceCreateInputs(inputs) {
1453
+ return JSON.stringify(inputs);
1454
+ }
1455
+ var NUMERIC_LINE_ITEM_FIELDS = ["Quantity", "UnitAmount", "DiscountRate"];
1456
+ function finaliseLineItem(cells) {
1457
+ const out = {};
1458
+ for (const key of LINE_ITEM_FIELD_KEYS) {
1459
+ const raw = (cells[key] ?? "").trim();
1460
+ if (!raw) continue;
1461
+ if (NUMERIC_LINE_ITEM_FIELDS.includes(key)) {
1462
+ const n = Number(raw);
1463
+ if (!Number.isFinite(n)) {
1464
+ throw new Error(`Line item field ${key} must be a number; got "${raw}"`);
1465
+ }
1466
+ out[key] = n;
1467
+ } else {
1468
+ out[key] = raw;
1469
+ }
1470
+ }
1471
+ if (!out.Description) {
1472
+ out.Description = "payment";
1473
+ }
1474
+ return out;
1475
+ }
1476
+
1477
+ // src/core/lib/actionRegistry/actions/xero/paymentCreate.types.ts
1478
+ function parseXeroPaymentCreateInputs(raw) {
1479
+ try {
1480
+ const parsed = typeof raw === "string" ? JSON.parse(raw || "{}") : raw || {};
1481
+ const conn = parsed.connection;
1482
+ const connection = conn && typeof conn === "object" && typeof conn.connectedAccountId === "string" && typeof conn.entityDid === "string" ? { connectedAccountId: conn.connectedAccountId, entityDid: conn.entityDid } : null;
1483
+ return {
1484
+ connection,
1485
+ tenant_id: typeof parsed.tenant_id === "string" ? parsed.tenant_id : "",
1486
+ InvoiceID: typeof parsed.InvoiceID === "string" ? parsed.InvoiceID : "",
1487
+ AccountID: typeof parsed.AccountID === "string" ? parsed.AccountID : "",
1488
+ Date: typeof parsed.Date === "string" ? parsed.Date : "",
1489
+ Amount: typeof parsed.Amount === "string" ? parsed.Amount : typeof parsed.Amount === "number" ? String(parsed.Amount) : "",
1490
+ Reference: typeof parsed.Reference === "string" ? parsed.Reference : "",
1491
+ CurrencyRate: typeof parsed.CurrencyRate === "string" ? parsed.CurrencyRate : ""
1492
+ };
1493
+ } catch {
1494
+ return {
1495
+ connection: null,
1496
+ tenant_id: "",
1497
+ InvoiceID: "",
1498
+ AccountID: "",
1499
+ Date: "",
1500
+ Amount: "",
1501
+ Reference: "",
1502
+ CurrencyRate: ""
1503
+ };
1504
+ }
1505
+ }
1506
+ function serializeXeroPaymentCreateInputs(inputs) {
1507
+ return JSON.stringify(inputs);
1508
+ }
1509
+
1510
+ // src/mantine/utils/referenceResolver.ts
1511
+ var REFERENCE_REGEX = /\{\{([a-zA-Z0-9_-]+)\.([a-zA-Z0-9_.:]+)\}\}/g;
1512
+ function parseReferences(input) {
1513
+ const references = [];
1514
+ const regex = new RegExp(REFERENCE_REGEX);
1515
+ let match;
1516
+ while ((match = regex.exec(input)) !== null) {
1517
+ references.push({
1518
+ fullMatch: match[0],
1519
+ blockId: match[1],
1520
+ propPath: match[2],
1521
+ startIndex: match.index,
1522
+ endIndex: match.index + match[0].length
1523
+ });
1524
+ }
1525
+ return references;
1526
+ }
1527
+ function getNestedValue(obj, path) {
1528
+ return path.split(".").reduce((current, key) => {
1529
+ return current?.[key];
1530
+ }, obj);
1531
+ }
1532
+ function resolveSingleReference(blockId, propPath, editorDocument, yRuntime, scope) {
1533
+ if (scope && Object.prototype.hasOwnProperty.call(scope, blockId)) {
1534
+ const root = scope[blockId];
1535
+ if (root == null) return void 0;
1536
+ return getNestedValue(root, propPath);
1537
+ }
1538
+ if (!editorDocument || !Array.isArray(editorDocument)) {
1539
+ return void 0;
1540
+ }
1541
+ const block = editorDocument.find((b) => b.id === blockId);
1542
+ if (!block) {
1543
+ return void 0;
1544
+ }
1545
+ if (propPath.startsWith("output.")) {
1546
+ if (!yRuntime) return void 0;
1547
+ const runtimeState = yRuntime.get(blockId);
1548
+ if (!runtimeState?.output) return void 0;
1549
+ const innerPath = propPath.substring("output.".length);
1550
+ const direct = getNestedValue(runtimeState.output, innerPath);
1551
+ if (direct !== void 0) return direct;
1552
+ if (runtimeState.output.data !== void 0) {
1553
+ return getNestedValue(runtimeState.output.data, innerPath);
1554
+ }
1555
+ if (runtimeState.output.http?.data !== void 0) {
1556
+ return getNestedValue(runtimeState.output.http.data, innerPath);
1557
+ }
1558
+ return void 0;
1559
+ }
1560
+ if (propPath.startsWith("response.")) {
1561
+ const responseData = block.props.response;
1562
+ if (!responseData) {
1563
+ return void 0;
1564
+ }
1565
+ try {
1566
+ const parsedResponse = typeof responseData === "string" ? JSON.parse(responseData) : responseData;
1567
+ const innerPath = propPath.substring("response.".length);
1568
+ const value2 = getNestedValue(parsedResponse, innerPath);
1569
+ return value2;
1570
+ } catch (error) {
1571
+ return void 0;
1572
+ }
1573
+ }
1574
+ const value = getNestedValue(block.props, propPath);
1575
+ return value;
1576
+ }
1577
+ function resolveReferences(input, editorDocument, options = {}) {
1578
+ const { fallback = "", stringifyObjects = true, yRuntime, scope } = options;
1579
+ if (input == null) {
1580
+ return "";
1581
+ }
1582
+ const inputStr = String(input);
1583
+ const references = parseReferences(inputStr);
1584
+ if (references.length === 0) {
1585
+ return inputStr;
1586
+ }
1587
+ let result = inputStr;
1588
+ for (let i = references.length - 1; i >= 0; i--) {
1589
+ const ref = references[i];
1590
+ const resolvedValue = resolveSingleReference(ref.blockId, ref.propPath, editorDocument, yRuntime, scope);
1591
+ let replacementStr;
1592
+ if (resolvedValue === void 0 || resolvedValue === null) {
1593
+ replacementStr = fallback;
1594
+ } else if (typeof resolvedValue === "object") {
1595
+ replacementStr = stringifyObjects ? JSON.stringify(resolvedValue) : fallback;
1596
+ } else {
1597
+ replacementStr = String(resolvedValue);
1598
+ }
1599
+ result = result.substring(0, ref.startIndex) + replacementStr + result.substring(ref.endIndex);
1600
+ }
1601
+ return result;
1602
+ }
1603
+ function hasReferences(input) {
1604
+ if (input == null) return false;
1605
+ return parseReferences(String(input)).length > 0;
1606
+ }
1607
+ function createReference(blockId, propPath) {
1608
+ return `{{${blockId}.${propPath}}}`;
1609
+ }
1610
+
1611
+ // src/core/lib/xeroWorkItemPayloads.ts
1612
+ function resolveXeroBindings(editorDocument, invoiceBlockId, paymentBlockId) {
1613
+ if (!Array.isArray(editorDocument)) return { invoiceCreateBlock: null, paymentCreateBlock: null, evaluateBlockId: null };
1614
+ const findById = (id, expectedActionType) => {
1615
+ const trimmed = String(id || "").trim();
1616
+ if (!trimmed) return null;
1617
+ const block = editorDocument.find((b) => b?.id === trimmed);
1618
+ if (!block || block.type !== "action" || block.props?.actionType !== expectedActionType) return null;
1619
+ return block;
1620
+ };
1621
+ return {
1622
+ invoiceCreateBlock: findById(invoiceBlockId, "qi/xero.invoice.create"),
1623
+ paymentCreateBlock: findById(paymentBlockId, "qi/xero.payment.create"),
1624
+ evaluateBlockId: null
1625
+ };
1626
+ }
1627
+ function buildClaimScope(claim, claimData, evaluateBlockId, evaluateContext) {
1628
+ const surveyAnswers = claimData && typeof claimData === "object" ? claimData.credentialSubject ?? claimData.surveyAnswers ?? claimData : {};
1629
+ const evaluationOutput = evaluateContext?.evaluationOutput ?? {};
1630
+ const scope = {
1631
+ claim: {
1632
+ claimId: claim?.claimId || evaluationOutput.claimId || "",
1633
+ agentDid: claim?.agentDid || "",
1634
+ agentAddress: claim?.agentAddress || "",
1635
+ submissionDate: claim?.submissionDate || "",
1636
+ surveyAnswers,
1637
+ ...surveyAnswers
1638
+ },
1639
+ evaluation: {
1640
+ transactionHash: evaluationOutput.transactionHash || "",
1641
+ amount: evaluationOutput.amount || "",
1642
+ date: (/* @__PURE__ */ new Date()).toISOString().slice(0, 10)
1643
+ }
1644
+ };
1645
+ const trimmedId = String(evaluateBlockId || "").trim();
1646
+ if (trimmedId) {
1647
+ scope[trimmedId] = {
1648
+ output: {
1649
+ claimId: claim?.claimId || evaluationOutput.claimId || "",
1650
+ collectionId: evaluateContext?.collectionId || "",
1651
+ deedDid: evaluateContext?.deedDid || "",
1652
+ surveyAnswers,
1653
+ ...evaluationOutput
1654
+ }
1655
+ };
1656
+ }
1657
+ return scope;
1658
+ }
1659
+ function resolveIterativeSource(source, editorDocument, opts) {
1660
+ const refs = parseReferences(source || "");
1661
+ if (refs.length === 0) return [];
1662
+ const ref = refs[0];
1663
+ const value = resolveSingleReference(ref.blockId, ref.propPath, editorDocument, opts.yRuntime, opts.scope);
1664
+ return Array.isArray(value) ? value : [];
1665
+ }
1666
+ function resolveCells(cells, editorDocument, opts) {
1667
+ const out = {};
1668
+ for (const key of LINE_ITEM_FIELD_KEYS) {
1669
+ out[key] = resolveReferences(cells[key] || "", editorDocument, opts);
1670
+ }
1671
+ return out;
1672
+ }
1673
+ function buildLineItemsArray(config, editorDocument, opts) {
1674
+ if (config.mode === "manual") {
1675
+ if (config.rows.length === 0) throw new Error("At least one line item is required.");
1676
+ return config.rows.map((row) => finaliseLineItem(resolveCells(row, editorDocument, opts)));
1677
+ }
1678
+ const elements = resolveIterativeSource(config.source, editorDocument, opts);
1679
+ if (elements.length === 0) throw new Error("The bound source list is empty or could not be resolved.");
1680
+ return elements.map((element) => {
1681
+ const perItemOpts = { ...opts, scope: { ...opts.scope || {}, item: element } };
1682
+ return finaliseLineItem(resolveCells(config.map, editorDocument, perItemOpts));
1683
+ });
1684
+ }
1685
+ async function resolveInvoiceWorkPayload(block, editorDocument, scope) {
1686
+ const parsed = parseXeroInvoiceCreateInputs(block?.props?.inputs);
1687
+ const opts = { scope };
1688
+ const resolveStr = (v) => resolveReferences(v || "", editorDocument, opts);
1689
+ const payload = {
1690
+ connection: parsed.connection,
1691
+ tenant_id: resolveStr(parsed.tenant_id),
1692
+ Type: resolveStr(parsed.Type) || "ACCREC",
1693
+ Status: resolveStr(parsed.Status) || "DRAFT",
1694
+ Date: resolveStr(parsed.Date),
1695
+ DueDate: resolveStr(parsed.DueDate),
1696
+ ContactID: resolveStr(parsed.ContactID),
1697
+ ContactName: resolveStr(parsed.ContactName),
1698
+ Reference: resolveStr(parsed.Reference),
1699
+ InvoiceNumber: resolveStr(parsed.InvoiceNumber),
1700
+ CurrencyCode: resolveStr(parsed.CurrencyCode),
1701
+ LineItems: buildLineItemsArray(parsed.LineItems, editorDocument, opts)
1702
+ };
1703
+ let preview = [];
1704
+ const resolver = getDiffResolver("qi/xero.invoice.create");
1705
+ if (resolver) {
1706
+ try {
1707
+ preview = await resolver.resolver({ ...payload, LineItems: parsed.LineItems }, {});
1708
+ } catch {
1709
+ preview = [];
1710
+ }
1711
+ }
1712
+ return { payload, preview };
1713
+ }
1714
+ async function resolvePaymentWorkPayload(block, editorDocument, baseScope, settlement) {
1715
+ const parsed = parseXeroPaymentCreateInputs(block?.props?.inputs);
1716
+ const scope = {
1717
+ ...baseScope,
1718
+ invoice: { invoiceId: settlement.invoiceId, InvoiceID: settlement.invoiceId },
1719
+ evaluation: {
1720
+ transactionHash: settlement.transactionHash,
1721
+ amount: settlement.amount,
1722
+ date: settlement.date || (/* @__PURE__ */ new Date()).toISOString().slice(0, 10)
1723
+ }
1724
+ };
1725
+ const opts = { scope };
1726
+ const resolveStr = (v) => resolveReferences(v || "", editorDocument, opts);
1727
+ const currencyRateRaw = resolveStr(parsed.CurrencyRate);
1728
+ const currencyRate = currencyRateRaw ? Number(currencyRateRaw) : void 0;
1729
+ const amountRaw = resolveStr(parsed.Amount);
1730
+ const amount = Number.isFinite(Number(amountRaw)) && Number(amountRaw) > 0 ? Number(amountRaw) : settlement.amount;
1731
+ const payload = {
1732
+ connection: parsed.connection,
1733
+ tenant_id: resolveStr(parsed.tenant_id),
1734
+ InvoiceID: resolveStr(parsed.InvoiceID) || settlement.invoiceId,
1735
+ AccountID: resolveStr(parsed.AccountID),
1736
+ Date: resolveStr(parsed.Date) || settlement.date || (/* @__PURE__ */ new Date()).toISOString().slice(0, 10),
1737
+ Amount: amount,
1738
+ Reference: resolveStr(parsed.Reference) || settlement.transactionHash,
1739
+ CurrencyRate: typeof currencyRate === "number" && Number.isFinite(currencyRate) ? currencyRate : void 0
1740
+ };
1741
+ let preview = [];
1742
+ const resolver = getDiffResolver("qi/xero.payment.create");
1743
+ if (resolver) {
1744
+ try {
1745
+ preview = await resolver.resolver({ ...payload, Amount: String(payload.Amount) }, {});
1746
+ } catch {
1747
+ preview = [];
1748
+ }
1749
+ }
1750
+ return { payload, preview };
1751
+ }
1752
+ function getInvoiceTotal(output) {
1753
+ const total = typeof output.total === "number" ? output.total : Number(output.total);
1754
+ return Number.isFinite(total) && total > 0 ? total : 0;
1755
+ }
1756
+
1254
1757
  // src/core/lib/actionRegistry/actions/evaluateClaim/evaluateClaim.ts
1255
1758
  var BASELINE_OUTPUT2 = [
1256
1759
  { path: "claimId", displayName: "Claim ID", type: "string", description: "Evaluated claim identifier" },
@@ -1459,11 +1962,12 @@ registerAction({
1459
1962
  amount: normalizedCoin
1460
1963
  });
1461
1964
  const transactionHash = String(broadcastResult?.transactionHash || "");
1965
+ let claimData = null;
1462
1966
  let surveyAnswers = {};
1463
1967
  try {
1464
1968
  const getClaimData = handlers?.getClaimData;
1465
1969
  if (typeof getClaimData === "function") {
1466
- const claimData = await getClaimData(collectionId, claimId);
1970
+ claimData = await getClaimData(collectionId, claimId, { entityDid: deedDid });
1467
1971
  const candidate = claimData?.credentialSubject ?? claimData?.surveyAnswers ?? claimData;
1468
1972
  if (candidate && typeof candidate === "object" && !Array.isArray(candidate)) {
1469
1973
  surveyAnswers = candidate;
@@ -1485,6 +1989,56 @@ registerAction({
1485
1989
  evaluatedAt,
1486
1990
  surveyAnswers
1487
1991
  };
1992
+ const xeroInvoiceBlockId = String(inputs.xeroInvoiceBlockId || "").trim();
1993
+ if (decision === "approve" && xeroInvoiceBlockId) {
1994
+ const editorDoc = ctx.editor?.document || [];
1995
+ const runtime = ctx.runtime;
1996
+ if (!runtime) {
1997
+ throw new Error("Cannot queue Xero invoice work: runtime state manager is unavailable");
1998
+ }
1999
+ const bindings = resolveXeroBindings(editorDoc, xeroInvoiceBlockId, String(inputs.xeroPaymentBlockId || ""));
2000
+ const invoiceBlock = bindings.invoiceCreateBlock;
2001
+ if (!invoiceBlock) {
2002
+ throw new Error("Cannot queue Xero invoice work: bound invoice block was not found");
2003
+ }
2004
+ const flowId = String(ctx.flowId || ctx.flowUri || "flow");
2005
+ const scope = buildClaimScope(inputs.claimSnapshot || { claimId }, claimData || surveyAnswers, ctx.nodeId, {
2006
+ deedDid,
2007
+ collectionId,
2008
+ evaluationOutput: output
2009
+ });
2010
+ const { payload } = await resolveInvoiceWorkPayload(invoiceBlock, editorDoc, scope);
2011
+ const idempotencyKey = buildXeroInvoiceWorkKey({
2012
+ flowId,
2013
+ evaluationBlockId: ctx.nodeId,
2014
+ claimId,
2015
+ invoiceBlockId: invoiceBlock.id
2016
+ });
2017
+ upsertXeroWorkItemForEditor(ctx.editor, {
2018
+ id: idempotencyKey,
2019
+ kind: "invoice.create",
2020
+ status: "pending",
2021
+ assignedBlockId: invoiceBlock.id,
2022
+ idempotencyKey,
2023
+ source: {
2024
+ claimId,
2025
+ evaluationBlockId: ctx.nodeId,
2026
+ deedDid,
2027
+ collectionId
2028
+ },
2029
+ originalPayload: payload,
2030
+ reviewPayload: payload,
2031
+ provenance: {
2032
+ createdAt: Date.now(),
2033
+ createdByDid: ctx.actorDid,
2034
+ templateBlockId: invoiceBlock.id,
2035
+ templateInputsSnapshot: invoiceBlock.props?.inputs,
2036
+ evaluationOutput: output,
2037
+ claimSnapshot: inputs.claimSnapshot
2038
+ },
2039
+ attempts: []
2040
+ });
2041
+ }
1488
2042
  const eventName = decision === "approve" ? "approved" : "rejected";
1489
2043
  const eventPayload = decision === "approve" ? {
1490
2044
  claimId,
@@ -4885,7 +5439,7 @@ registerAction({
4885
5439
  }
4886
5440
  const invoiceId = String(inputs.InvoiceID || "").trim();
4887
5441
  if (!invoiceId) {
4888
- throw new Error("InvoiceID is required \u2014 usually wired from the upstream Capture Bill step.");
5442
+ throw new Error("InvoiceID is required; work items usually supply it from invoice.create completion.");
4889
5443
  }
4890
5444
  const accountId = String(inputs.AccountID || "").trim();
4891
5445
  if (!accountId) {
@@ -6418,6 +6972,8 @@ var buildFlowNodeFromBlock = (block) => {
6418
6972
  };
6419
6973
 
6420
6974
  // src/core/lib/flowEngine/runtime.ts
6975
+ var XERO_WORK_ITEMS_MAP_NAME = "xeroWorkItems";
6976
+ var XERO_CONNECTION_MAP_NAME = "xeroConnection";
6421
6977
  var ensureStateObject = (value) => {
6422
6978
  if (!value || typeof value !== "object") {
6423
6979
  return {};
@@ -6462,6 +7018,8 @@ function clearRuntimeForTemplateClone(yDoc) {
6462
7018
  const agentOutbox = yDoc.getMap("agentOutbox");
6463
7019
  const agentLeases = yDoc.getMap("agentLeases");
6464
7020
  const auditTrail = yDoc.getMap("auditTrail");
7021
+ const xeroWorkItems = yDoc.getMap(XERO_WORK_ITEMS_MAP_NAME);
7022
+ const xeroConnection = yDoc.getMap(XERO_CONNECTION_MAP_NAME);
6465
7023
  yDoc.transact(() => {
6466
7024
  runtime.forEach((_, key) => runtime.delete(key));
6467
7025
  invocations.forEach((_, key) => invocations.delete(key));
@@ -6469,6 +7027,8 @@ function clearRuntimeForTemplateClone(yDoc) {
6469
7027
  agentOutbox.forEach((_, key) => agentOutbox.delete(key));
6470
7028
  agentLeases.forEach((_, key) => agentLeases.delete(key));
6471
7029
  auditTrail.forEach((_, key) => auditTrail.delete(key));
7030
+ xeroWorkItems.forEach((_, key) => xeroWorkItems.delete(key));
7031
+ xeroConnection.forEach((_, key) => xeroConnection.delete(key));
6472
7032
  });
6473
7033
  }
6474
7034
 
@@ -6503,7 +7063,7 @@ function resolveRef(ref, getNodeOutput2, triggerContext) {
6503
7063
  throw new Error(`Trigger ref "${ref}" used outside of a listener invocation context. trigger.payload.* refs are only valid on block.event-triggered blocks.`);
6504
7064
  }
6505
7065
  const fieldPath2 = ref.slice("trigger.payload.".length);
6506
- return getNestedValue(triggerContext.payload, fieldPath2);
7066
+ return getNestedValue2(triggerContext.payload, fieldPath2);
6507
7067
  }
6508
7068
  if (triggerContext && Object.prototype.hasOwnProperty.call(triggerContext.refSnapshots, ref)) {
6509
7069
  return triggerContext.refSnapshots[ref];
@@ -6518,9 +7078,9 @@ function resolveRef(ref, getNodeOutput2, triggerContext) {
6518
7078
  if (!output) {
6519
7079
  return void 0;
6520
7080
  }
6521
- return getNestedValue(output, fieldPath);
7081
+ return getNestedValue2(output, fieldPath);
6522
7082
  }
6523
- function getNestedValue(obj, path) {
7083
+ function getNestedValue2(obj, path) {
6524
7084
  const parts = path.split(".");
6525
7085
  let current = obj;
6526
7086
  for (const part of parts) {
@@ -6758,7 +7318,7 @@ function snapshotInputRefs(inputs, getNodeOutput2) {
6758
7318
  if (!parsed) return;
6759
7319
  const output = getNodeOutput2(parsed.nodeId);
6760
7320
  if (!output) return;
6761
- snapshots[ref.$ref] = getNestedValue2(output, parsed.fieldPath);
7321
+ snapshots[ref.$ref] = getNestedValue3(output, parsed.fieldPath);
6762
7322
  });
6763
7323
  return snapshots;
6764
7324
  }
@@ -6783,7 +7343,7 @@ function parseOutputRef(ref) {
6783
7343
  fieldPath: ref.slice(outputIndex + ".output.".length)
6784
7344
  };
6785
7345
  }
6786
- function getNestedValue2(obj, path) {
7346
+ function getNestedValue3(obj, path) {
6787
7347
  const parts = path.split(".");
6788
7348
  let current = obj;
6789
7349
  for (const part of parts) {
@@ -10123,6 +10683,28 @@ export {
10123
10683
  hasDiffResolver,
10124
10684
  extractDid,
10125
10685
  extractSurveyAnswerSchema,
10686
+ buildXeroPaymentWorkKey,
10687
+ findXeroWorkItemsForEditor,
10688
+ upsertXeroWorkItemForEditor,
10689
+ updateXeroWorkReviewPayloadForEditor,
10690
+ markXeroWorkFailedForEditor,
10691
+ markXeroWorkCompletedForEditor,
10692
+ LINE_ITEM_FIELD_KEYS,
10693
+ emptyLineItemCells,
10694
+ parseXeroInvoiceCreateInputs,
10695
+ serializeXeroInvoiceCreateInputs,
10696
+ finaliseLineItem,
10697
+ parseXeroPaymentCreateInputs,
10698
+ serializeXeroPaymentCreateInputs,
10699
+ parseReferences,
10700
+ resolveSingleReference,
10701
+ resolveReferences,
10702
+ hasReferences,
10703
+ createReference,
10704
+ resolveXeroBindings,
10705
+ buildClaimScope,
10706
+ resolvePaymentWorkPayload,
10707
+ getInvoiceTotal,
10126
10708
  transformSurveyToCredentialSubject,
10127
10709
  buildVerifiableCredential,
10128
10710
  buildDomainCardLinkedResource,
@@ -10215,4 +10797,4 @@ export {
10215
10797
  executeQueuedFlowAgentCoreCommands,
10216
10798
  FlowAgentService
10217
10799
  };
10218
- //# sourceMappingURL=chunk-6N5JNDZ3.mjs.map
10800
+ //# sourceMappingURL=chunk-UWRUVSMP.mjs.map