@ixo/editor 6.7.0 → 6.9.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.
@@ -439,6 +439,127 @@ function buildServicesFromHandlers(handlers) {
439
439
  };
440
440
  }
441
441
 
442
+ // src/core/lib/xeroWorkItems.ts
443
+ var XERO_WORK_ITEMS_MAP_NAME = "xeroWorkItems";
444
+ function getXeroWorkItemsMap(doc) {
445
+ return doc.getMap(XERO_WORK_ITEMS_MAP_NAME);
446
+ }
447
+ function getEditorXeroWorkItemsMap(editor) {
448
+ return editor?._yXeroWorkItems || null;
449
+ }
450
+ function readMapItems(map) {
451
+ if (!map) return [];
452
+ const items = [];
453
+ map.forEach((value) => {
454
+ if (value && typeof value === "object" && "id" in value) {
455
+ items.push({ ...value });
456
+ }
457
+ });
458
+ return items;
459
+ }
460
+ function mergeItem(existing, next) {
461
+ if (existing.status === "completed") {
462
+ return existing;
463
+ }
464
+ return {
465
+ ...existing,
466
+ ...next,
467
+ id: existing.id,
468
+ attempts: existing.attempts ?? [],
469
+ originalPayload: existing.originalPayload,
470
+ submittedPayload: existing.submittedPayload,
471
+ result: existing.result,
472
+ completedAt: existing.completedAt,
473
+ completedByDid: existing.completedByDid
474
+ };
475
+ }
476
+ function buildXeroInvoiceWorkKey(params) {
477
+ return ["xero", "invoice.create", params.flowId, params.evaluationBlockId, params.claimId].join(":");
478
+ }
479
+ function buildXeroPaymentWorkKey(params) {
480
+ return ["xero", "payment.create", params.flowId, params.evaluationBlockId, params.claimId, params.invoiceWorkItemId].join(":");
481
+ }
482
+ function findXeroWorkItems(map, filter = {}) {
483
+ return readMapItems(map).filter((item) => {
484
+ if (filter.kind && item.kind !== filter.kind) return false;
485
+ if (filter.assignedBlockId && item.assignedBlockId !== filter.assignedBlockId) return false;
486
+ if (filter.statuses && !filter.statuses.includes(item.status)) return false;
487
+ return true;
488
+ });
489
+ }
490
+ function upsertXeroWorkItem(map, next) {
491
+ if (!map) {
492
+ return next;
493
+ }
494
+ let existing;
495
+ map.forEach((item) => {
496
+ if (item?.idempotencyKey === next.idempotencyKey) existing = item;
497
+ });
498
+ const stored = existing ? mergeItem(existing, next) : next;
499
+ map.set(stored.id, stored);
500
+ return stored;
501
+ }
502
+ function updateXeroWorkReviewPayload(map, itemId, reviewPayload) {
503
+ if (!map) return null;
504
+ const item = map.get(itemId);
505
+ if (!item) return null;
506
+ if (item.status === "completed") return item;
507
+ const updatedItem = { ...item, reviewPayload };
508
+ map.set(itemId, updatedItem);
509
+ return updatedItem;
510
+ }
511
+ function markXeroWorkFailed(map, itemId, params) {
512
+ if (!map) return null;
513
+ const item = map.get(itemId);
514
+ if (!item) return null;
515
+ if (item.status === "completed") return item;
516
+ const at = params.at ?? Date.now();
517
+ const updatedItem = {
518
+ ...item,
519
+ status: "failed",
520
+ reviewPayload: params.payload,
521
+ error: { message: params.error, at },
522
+ attempts: [...item.attempts ?? [], { at, byDid: params.byDid, payload: params.payload, error: params.error }]
523
+ };
524
+ map.set(itemId, updatedItem);
525
+ return updatedItem;
526
+ }
527
+ function markXeroWorkCompleted(map, itemId, params) {
528
+ if (!map) return null;
529
+ const item = map.get(itemId);
530
+ if (!item) return null;
531
+ if (item.status === "completed") return item;
532
+ const at = params.at ?? Date.now();
533
+ const updatedItem = {
534
+ ...item,
535
+ status: "completed",
536
+ reviewPayload: params.payload,
537
+ submittedPayload: params.payload,
538
+ result: params.result,
539
+ error: void 0,
540
+ completedAt: at,
541
+ completedByDid: params.byDid,
542
+ attempts: [...item.attempts ?? [], { at, byDid: params.byDid, payload: params.payload, result: params.result }]
543
+ };
544
+ map.set(itemId, updatedItem);
545
+ return updatedItem;
546
+ }
547
+ function findXeroWorkItemsForEditor(editor, filter) {
548
+ return findXeroWorkItems(getEditorXeroWorkItemsMap(editor), filter);
549
+ }
550
+ function upsertXeroWorkItemForEditor(editor, next) {
551
+ return upsertXeroWorkItem(getEditorXeroWorkItemsMap(editor), next);
552
+ }
553
+ function updateXeroWorkReviewPayloadForEditor(editor, itemId, reviewPayload) {
554
+ return updateXeroWorkReviewPayload(getEditorXeroWorkItemsMap(editor), itemId, reviewPayload);
555
+ }
556
+ function markXeroWorkFailedForEditor(editor, itemId, params) {
557
+ return markXeroWorkFailed(getEditorXeroWorkItemsMap(editor), itemId, params);
558
+ }
559
+ function markXeroWorkCompletedForEditor(editor, itemId, params) {
560
+ return markXeroWorkCompleted(getEditorXeroWorkItemsMap(editor), itemId, params);
561
+ }
562
+
442
563
  // src/core/lib/matrixDm.ts
443
564
  function getHomeserver(matrixClient) {
444
565
  const userId = matrixClient.getUserId();
@@ -2939,606 +3060,89 @@ registerAction({
2939
3060
  throw new Error("surveyAnswers must be valid JSON");
2940
3061
  }
2941
3062
  }
2942
- if (!surveyAnswers || typeof surveyAnswers !== "object" || Array.isArray(surveyAnswers)) {
2943
- throw new Error("surveyAnswers must be an object");
2944
- }
2945
- let pin = String(inputs.pin || "").trim();
2946
- if (!pin) {
2947
- pin = await service.requestPin({
2948
- title: "Verify Identity",
2949
- description: "Enter your PIN to submit the claim",
2950
- submitText: "Verify"
2951
- });
2952
- }
2953
- if (!pin) {
2954
- throw new Error("PIN is required to submit claim");
2955
- }
2956
- if (isGroupExecution(inputs)) {
2957
- const { coreAddress, title, description } = requireGroupExecutionParams(inputs);
2958
- const handlers = ctx.handlers;
2959
- if (typeof handlers?.prepareGroupClaimSubmission !== "function") {
2960
- throw new Error("Acting as a POD is not available: the host does not implement prepareGroupClaimSubmission");
2961
- }
2962
- const prepared = await handlers.prepareGroupClaimSubmission({
2963
- surveyData: surveyAnswers,
2964
- deedDid,
2965
- entityDid: deedDid,
2966
- collectionId,
2967
- adminAddress,
2968
- pin,
2969
- groupAddress: coreAddress
2970
- });
2971
- const claimId2 = String(prepared?.claimId || "").trim();
2972
- if (!claimId2) throw new Error("prepareGroupClaimSubmission returned no claim identifier");
2973
- return proposeGroupExecution(ctx, {
2974
- coreAddress,
2975
- title,
2976
- description,
2977
- msgs: prepared.msgs || [],
2978
- expectedOutput: {
2979
- claimId: claimId2,
2980
- transactionHash: "",
2981
- collectionId,
2982
- deedDid,
2983
- submittedByDid: coreAddress,
2984
- submittedAt: (/* @__PURE__ */ new Date()).toISOString(),
2985
- surveyAnswers
2986
- },
2987
- completionEvent: "submitted"
2988
- });
2989
- }
2990
- const result = await service.submitClaim({
2991
- surveyData: surveyAnswers,
2992
- deedDid,
2993
- entityDid: deedDid,
2994
- collectionId,
2995
- adminAddress,
2996
- pin
2997
- });
2998
- const claimId = String(result?.claimId || result?.id || "");
2999
- if (!claimId) {
3000
- throw new Error("submitClaim returned no claim identifier");
3001
- }
3002
- const transactionHash = String(result?.transactionHash || "");
3003
- const submittedByDid = ctx.actorDid || "";
3004
- const submittedAt = (/* @__PURE__ */ new Date()).toISOString();
3005
- const output = {
3006
- claimId,
3007
- transactionHash,
3008
- collectionId,
3009
- deedDid,
3010
- submittedByDid,
3011
- submittedAt,
3012
- surveyAnswers
3013
- };
3014
- return {
3015
- output,
3016
- events: [
3017
- {
3018
- name: "submitted",
3019
- payload: output
3020
- }
3021
- ]
3022
- };
3023
- }
3024
- });
3025
-
3026
- // src/core/lib/xeroWorkItems.ts
3027
- function getXeroWorkItemsMap(editor) {
3028
- return editor?._yXeroWorkItems || null;
3029
- }
3030
- function readMapItems(map) {
3031
- if (!map) return [];
3032
- const items = [];
3033
- map.forEach((value) => {
3034
- if (value && typeof value === "object" && "id" in value) {
3035
- items.push({ ...value });
3036
- }
3037
- });
3038
- return items;
3039
- }
3040
- function mergeItem(existing, next) {
3041
- if (existing.status === "completed") {
3042
- return existing;
3043
- }
3044
- return {
3045
- ...existing,
3046
- ...next,
3047
- id: existing.id,
3048
- attempts: existing.attempts ?? [],
3049
- originalPayload: existing.originalPayload,
3050
- submittedPayload: existing.submittedPayload,
3051
- result: existing.result,
3052
- completedAt: existing.completedAt,
3053
- completedByDid: existing.completedByDid
3054
- };
3055
- }
3056
- function buildXeroInvoiceWorkKey(params) {
3057
- return ["xero", "invoice.create", params.flowId, params.evaluationBlockId, params.claimId, params.invoiceBlockId].join(":");
3058
- }
3059
- function buildXeroPaymentWorkKey(params) {
3060
- return ["xero", "payment.create", params.flowId, params.evaluationBlockId, params.claimId, params.paymentBlockId, params.invoiceWorkItemId].join(":");
3061
- }
3062
- function findXeroWorkItemsForEditor(editor, filter) {
3063
- return readMapItems(getXeroWorkItemsMap(editor)).filter((item) => {
3064
- if (filter.kind && item.kind !== filter.kind) return false;
3065
- if (filter.assignedBlockId && item.assignedBlockId !== filter.assignedBlockId) return false;
3066
- if (filter.statuses && !filter.statuses.includes(item.status)) return false;
3067
- return true;
3068
- });
3069
- }
3070
- function upsertXeroWorkItemForEditor(editor, next) {
3071
- const map = getXeroWorkItemsMap(editor);
3072
- if (!map) {
3073
- return next;
3074
- }
3075
- let existing;
3076
- map.forEach((item) => {
3077
- if (item?.idempotencyKey === next.idempotencyKey) existing = item;
3078
- });
3079
- const stored = existing ? mergeItem(existing, next) : next;
3080
- map.set(stored.id, stored);
3081
- return stored;
3082
- }
3083
- function updateXeroWorkReviewPayloadForEditor(editor, itemId, reviewPayload) {
3084
- const map = getXeroWorkItemsMap(editor);
3085
- if (!map) return null;
3086
- const item = map.get(itemId);
3087
- if (!item) return null;
3088
- const updatedItem = { ...item, reviewPayload };
3089
- map.set(itemId, updatedItem);
3090
- return updatedItem;
3091
- }
3092
- function markXeroWorkFailedForEditor(editor, itemId, params) {
3093
- const map = getXeroWorkItemsMap(editor);
3094
- if (!map) return null;
3095
- const item = map.get(itemId);
3096
- if (!item) return null;
3097
- const at = params.at ?? Date.now();
3098
- const updatedItem = {
3099
- ...item,
3100
- status: "failed",
3101
- reviewPayload: params.payload,
3102
- error: { message: params.error, at },
3103
- attempts: [...item.attempts ?? [], { at, byDid: params.byDid, payload: params.payload, error: params.error }]
3104
- };
3105
- map.set(itemId, updatedItem);
3106
- return updatedItem;
3107
- }
3108
- function markXeroWorkCompletedForEditor(editor, itemId, params) {
3109
- const map = getXeroWorkItemsMap(editor);
3110
- if (!map) return null;
3111
- const item = map.get(itemId);
3112
- if (!item) return null;
3113
- const at = params.at ?? Date.now();
3114
- const updatedItem = {
3115
- ...item,
3116
- status: "completed",
3117
- reviewPayload: params.payload,
3118
- submittedPayload: params.payload,
3119
- result: params.result,
3120
- error: void 0,
3121
- completedAt: at,
3122
- completedByDid: params.byDid,
3123
- attempts: [...item.attempts ?? [], { at, byDid: params.byDid, payload: params.payload, result: params.result }]
3124
- };
3125
- map.set(itemId, updatedItem);
3126
- return updatedItem;
3127
- }
3128
-
3129
- // src/core/lib/actionRegistry/actions/xero/invoiceCreate.types.ts
3130
- var LINE_ITEM_FIELD_KEYS = ["Description", "Quantity", "UnitAmount", "AccountCode", "TaxType", "ItemCode", "DiscountRate"];
3131
- function emptyLineItemCells() {
3132
- return {
3133
- Description: "",
3134
- Quantity: "1",
3135
- UnitAmount: "",
3136
- AccountCode: "",
3137
- TaxType: "",
3138
- ItemCode: "",
3139
- DiscountRate: ""
3140
- };
3141
- }
3142
- function emptyLineItems() {
3143
- return { mode: "manual", rows: [emptyLineItemCells()] };
3144
- }
3145
- function coerceCells(raw) {
3146
- const base = emptyLineItemCells();
3147
- if (!raw || typeof raw !== "object") return base;
3148
- for (const key of LINE_ITEM_FIELD_KEYS) {
3149
- const v = raw[key];
3150
- if (typeof v === "string") base[key] = v;
3151
- else if (typeof v === "number") base[key] = String(v);
3152
- else if (typeof v === "boolean") base[key] = v ? "true" : "false";
3153
- }
3154
- return base;
3155
- }
3156
- function normaliseLineItems(raw) {
3157
- if (raw && typeof raw === "object") {
3158
- const candidate = raw;
3159
- if (candidate.mode === "iterative") {
3160
- return {
3161
- mode: "iterative",
3162
- source: typeof candidate.source === "string" ? candidate.source : "",
3163
- map: coerceCells(candidate.map)
3164
- };
3165
- }
3166
- if (candidate.mode === "manual") {
3167
- const rows = Array.isArray(candidate.rows) ? candidate.rows.map(coerceCells) : [];
3168
- return { mode: "manual", rows: rows.length > 0 ? rows : [emptyLineItemCells()] };
3169
- }
3170
- }
3171
- if (typeof raw === "string") {
3172
- const trimmed = raw.trim();
3173
- if (!trimmed) return emptyLineItems();
3174
- try {
3175
- const parsed = JSON.parse(trimmed);
3176
- if (Array.isArray(parsed) && parsed.length > 0) {
3177
- return { mode: "manual", rows: parsed.map(coerceCells) };
3178
- }
3179
- } catch {
3180
- }
3181
- }
3182
- return emptyLineItems();
3183
- }
3184
- function parseXeroInvoiceCreateInputs(raw) {
3185
- try {
3186
- const parsed = typeof raw === "string" ? JSON.parse(raw || "{}") : raw || {};
3187
- const conn = parsed.connection;
3188
- const connection = conn && typeof conn === "object" && typeof conn.connectedAccountId === "string" && typeof conn.entityDid === "string" ? { connectedAccountId: conn.connectedAccountId, entityDid: conn.entityDid } : null;
3189
- return {
3190
- connection,
3191
- tenant_id: typeof parsed.tenant_id === "string" ? parsed.tenant_id : "",
3192
- Type: typeof parsed.Type === "string" && parsed.Type ? parsed.Type : "ACCREC",
3193
- Status: typeof parsed.Status === "string" ? parsed.Status : "DRAFT",
3194
- Date: typeof parsed.Date === "string" ? parsed.Date : "",
3195
- DueDate: typeof parsed.DueDate === "string" ? parsed.DueDate : "",
3196
- ContactID: typeof parsed.ContactID === "string" ? parsed.ContactID : "",
3197
- ContactName: typeof parsed.ContactName === "string" ? parsed.ContactName : "",
3198
- Reference: typeof parsed.Reference === "string" ? parsed.Reference : "",
3199
- InvoiceNumber: typeof parsed.InvoiceNumber === "string" ? parsed.InvoiceNumber : "",
3200
- CurrencyCode: typeof parsed.CurrencyCode === "string" ? parsed.CurrencyCode : "",
3201
- LineItems: normaliseLineItems(parsed.LineItems)
3202
- };
3203
- } catch {
3204
- return {
3205
- connection: null,
3206
- tenant_id: "",
3207
- Type: "ACCREC",
3208
- Status: "DRAFT",
3209
- Date: "",
3210
- DueDate: "",
3211
- ContactID: "",
3212
- ContactName: "",
3213
- Reference: "",
3214
- InvoiceNumber: "",
3215
- CurrencyCode: "",
3216
- LineItems: emptyLineItems()
3217
- };
3218
- }
3219
- }
3220
- function serializeXeroInvoiceCreateInputs(inputs) {
3221
- return JSON.stringify(inputs);
3222
- }
3223
- var NUMERIC_LINE_ITEM_FIELDS = ["Quantity", "UnitAmount", "DiscountRate"];
3224
- function finaliseLineItem(cells) {
3225
- const out = {};
3226
- for (const key of LINE_ITEM_FIELD_KEYS) {
3227
- const raw = (cells[key] ?? "").trim();
3228
- if (!raw) continue;
3229
- if (NUMERIC_LINE_ITEM_FIELDS.includes(key)) {
3230
- const n = Number(raw);
3231
- if (!Number.isFinite(n)) {
3232
- throw new Error(`Line item field ${key} must be a number; got "${raw}"`);
3233
- }
3234
- out[key] = n;
3235
- } else {
3236
- out[key] = raw;
3237
- }
3238
- }
3239
- if (!out.Description) {
3240
- out.Description = "payment";
3241
- }
3242
- return out;
3243
- }
3244
-
3245
- // src/core/lib/actionRegistry/actions/xero/paymentCreate.types.ts
3246
- function parseXeroPaymentCreateInputs(raw) {
3247
- try {
3248
- const parsed = typeof raw === "string" ? JSON.parse(raw || "{}") : raw || {};
3249
- const conn = parsed.connection;
3250
- const connection = conn && typeof conn === "object" && typeof conn.connectedAccountId === "string" && typeof conn.entityDid === "string" ? { connectedAccountId: conn.connectedAccountId, entityDid: conn.entityDid } : null;
3251
- return {
3252
- connection,
3253
- tenant_id: typeof parsed.tenant_id === "string" ? parsed.tenant_id : "",
3254
- InvoiceID: typeof parsed.InvoiceID === "string" ? parsed.InvoiceID : "",
3255
- AccountID: typeof parsed.AccountID === "string" ? parsed.AccountID : "",
3256
- Date: typeof parsed.Date === "string" ? parsed.Date : "",
3257
- Amount: typeof parsed.Amount === "string" ? parsed.Amount : typeof parsed.Amount === "number" ? String(parsed.Amount) : "",
3258
- Reference: typeof parsed.Reference === "string" ? parsed.Reference : "",
3259
- CurrencyRate: typeof parsed.CurrencyRate === "string" ? parsed.CurrencyRate : ""
3260
- };
3261
- } catch {
3262
- return {
3263
- connection: null,
3264
- tenant_id: "",
3265
- InvoiceID: "",
3266
- AccountID: "",
3267
- Date: "",
3268
- Amount: "",
3269
- Reference: "",
3270
- CurrencyRate: ""
3271
- };
3272
- }
3273
- }
3274
- function serializeXeroPaymentCreateInputs(inputs) {
3275
- return JSON.stringify(inputs);
3276
- }
3277
-
3278
- // src/core/lib/flowEngine/referenceResolver.ts
3279
- var REFERENCE_REGEX = /\{\{([a-zA-Z0-9_-]+)\.([a-zA-Z0-9_.:]+)\}\}/g;
3280
- function parseReferences(input) {
3281
- const references = [];
3282
- const regex = new RegExp(REFERENCE_REGEX);
3283
- let match;
3284
- while ((match = regex.exec(input)) !== null) {
3285
- references.push({
3286
- fullMatch: match[0],
3287
- blockId: match[1],
3288
- propPath: match[2],
3289
- startIndex: match.index,
3290
- endIndex: match.index + match[0].length
3291
- });
3292
- }
3293
- return references;
3294
- }
3295
- function getNestedValue(obj, path) {
3296
- return path.split(".").reduce((current, key) => {
3297
- return current?.[key];
3298
- }, obj);
3299
- }
3300
- function resolveSingleReferenceDetailed(blockId, propPath, editorDocument, yRuntime, scope) {
3301
- if (scope && Object.prototype.hasOwnProperty.call(scope, blockId)) {
3302
- const root = scope[blockId];
3303
- if (root == null) return { value: void 0, reason: "missing-value" };
3304
- const value2 = getNestedValue(root, propPath);
3305
- return { value: value2, reason: value2 === void 0 ? "missing-value" : void 0 };
3306
- }
3307
- if (!editorDocument || !Array.isArray(editorDocument)) {
3308
- return { value: void 0, reason: "unknown-block" };
3309
- }
3310
- const block = editorDocument.find((b) => b.id === blockId);
3311
- if (!block) {
3312
- return { value: void 0, reason: "unknown-block" };
3313
- }
3314
- if (propPath.startsWith("output.")) {
3315
- if (!yRuntime) return { value: void 0, reason: "missing-value" };
3316
- const runtimeState = yRuntime.get(blockId);
3317
- if (!runtimeState?.output) return { value: void 0, reason: "missing-value" };
3318
- const innerPath = propPath.substring("output.".length);
3319
- const direct = getNestedValue(runtimeState.output, innerPath);
3320
- if (direct !== void 0) return { value: direct };
3321
- if (runtimeState.output.data !== void 0) {
3322
- const value2 = getNestedValue(runtimeState.output.data, innerPath);
3323
- return { value: value2, reason: value2 === void 0 ? "missing-value" : void 0 };
3324
- }
3325
- if (runtimeState.output.http?.data !== void 0) {
3326
- const value2 = getNestedValue(runtimeState.output.http.data, innerPath);
3327
- return { value: value2, reason: value2 === void 0 ? "missing-value" : void 0 };
3328
- }
3329
- return { value: void 0, reason: "missing-value" };
3330
- }
3331
- if (propPath.startsWith("response.")) {
3332
- const responseData = block.props.response;
3333
- if (!responseData) {
3334
- return { value: void 0, reason: "missing-value" };
3335
- }
3336
- try {
3337
- const parsedResponse = typeof responseData === "string" ? JSON.parse(responseData) : responseData;
3338
- const innerPath = propPath.substring("response.".length);
3339
- const value2 = getNestedValue(parsedResponse, innerPath);
3340
- return { value: value2, reason: value2 === void 0 ? "missing-value" : void 0 };
3341
- } catch {
3342
- warnOnce(`ref-response-parse:${blockId}`, `[flow-config] block ${blockId}: props.response is not valid JSON; {{${blockId}.${propPath}}} cannot resolve`);
3343
- return { value: void 0, reason: "response-parse-error" };
3344
- }
3345
- }
3346
- const value = getNestedValue(block.props, propPath);
3347
- return { value, reason: value === void 0 ? "missing-value" : void 0 };
3348
- }
3349
- function resolveSingleReference(blockId, propPath, editorDocument, yRuntime, scope) {
3350
- return resolveSingleReferenceDetailed(blockId, propPath, editorDocument, yRuntime, scope).value;
3351
- }
3352
- function resolveReferencesDetailed(input, editorDocument, options = {}) {
3353
- const { fallback = "", stringifyObjects = true, yRuntime, scope, warnContext } = options;
3354
- const unresolved = [];
3355
- if (input == null) {
3356
- return { value: "", unresolved };
3357
- }
3358
- const inputStr = String(input);
3359
- const references = parseReferences(inputStr);
3360
- if (references.length === 0) {
3361
- return { value: inputStr, unresolved };
3362
- }
3363
- let result = inputStr;
3364
- for (let i = references.length - 1; i >= 0; i--) {
3365
- const ref = references[i];
3366
- const resolution = resolveSingleReferenceDetailed(ref.blockId, ref.propPath, editorDocument, yRuntime, scope);
3367
- const resolvedValue = resolution.value;
3368
- let replacementStr;
3369
- if (resolvedValue === void 0 || resolvedValue === null) {
3370
- replacementStr = fallback;
3371
- unresolved.push({ ref: ref.fullMatch, blockId: ref.blockId, propPath: ref.propPath, reason: resolution.reason || "missing-value" });
3372
- } else if (typeof resolvedValue === "object") {
3373
- replacementStr = stringifyObjects ? JSON.stringify(resolvedValue) : fallback;
3374
- } else {
3375
- replacementStr = String(resolvedValue);
3376
- }
3377
- result = result.substring(0, ref.startIndex) + replacementStr + result.substring(ref.endIndex);
3378
- }
3379
- if (warnContext && unresolved.length > 0) {
3380
- for (const entry of unresolved) {
3381
- warnOnce(`ref-unresolved:${warnContext}:${entry.ref}`, `[flow-config] ${warnContext}: reference ${entry.ref} did not resolve (${entry.reason}); using fallback '${fallback}'`);
3382
- }
3383
- }
3384
- return { value: result, unresolved };
3385
- }
3386
- function resolveReferences(input, editorDocument, options = {}) {
3387
- return resolveReferencesDetailed(input, editorDocument, options).value;
3388
- }
3389
- function hasReferences(input) {
3390
- if (input == null) return false;
3391
- return parseReferences(String(input)).length > 0;
3392
- }
3393
- function createReference(blockId, propPath) {
3394
- return `{{${blockId}.${propPath}}}`;
3395
- }
3396
-
3397
- // src/core/lib/xeroWorkItemPayloads.ts
3398
- function resolveXeroBindings(editorDocument, invoiceBlockId, paymentBlockId) {
3399
- if (!Array.isArray(editorDocument)) return { invoiceCreateBlock: null, paymentCreateBlock: null, evaluateBlockId: null };
3400
- const findById = (id, expectedActionType) => {
3401
- const trimmed = String(id || "").trim();
3402
- if (!trimmed) return null;
3403
- const block = editorDocument.find((b) => b?.id === trimmed);
3404
- if (!block || block.type !== "action" || block.props?.actionType !== expectedActionType) return null;
3405
- return block;
3406
- };
3407
- return {
3408
- invoiceCreateBlock: findById(invoiceBlockId, "qi/xero.invoice.create"),
3409
- paymentCreateBlock: findById(paymentBlockId, "qi/xero.payment.create"),
3410
- evaluateBlockId: null
3411
- };
3412
- }
3413
- function buildClaimScope(claim, claimData, evaluateBlockId, evaluateContext) {
3414
- const surveyAnswers = claimData && typeof claimData === "object" ? claimData.credentialSubject ?? claimData.surveyAnswers ?? claimData : {};
3415
- const evaluationOutput = evaluateContext?.evaluationOutput ?? {};
3416
- const scope = {
3417
- claim: {
3418
- claimId: claim?.claimId || evaluationOutput.claimId || "",
3419
- agentDid: claim?.agentDid || "",
3420
- agentAddress: claim?.agentAddress || "",
3421
- submissionDate: claim?.submissionDate || "",
3422
- surveyAnswers,
3423
- ...surveyAnswers
3424
- },
3425
- evaluation: {
3426
- transactionHash: evaluationOutput.transactionHash || "",
3427
- amount: evaluationOutput.amount || "",
3428
- date: (/* @__PURE__ */ new Date()).toISOString().slice(0, 10)
3429
- }
3430
- };
3431
- const trimmedId = String(evaluateBlockId || "").trim();
3432
- if (trimmedId) {
3433
- scope[trimmedId] = {
3434
- output: {
3435
- claimId: claim?.claimId || evaluationOutput.claimId || "",
3436
- collectionId: evaluateContext?.collectionId || "",
3437
- deedDid: evaluateContext?.deedDid || "",
3438
- surveyAnswers,
3439
- ...evaluationOutput
3440
- }
3441
- };
3442
- }
3443
- return scope;
3444
- }
3445
- function resolveIterativeSource(source, editorDocument, opts) {
3446
- const refs = parseReferences(source || "");
3447
- if (refs.length === 0) return [];
3448
- const ref = refs[0];
3449
- const value = resolveSingleReference(ref.blockId, ref.propPath, editorDocument, opts.yRuntime, opts.scope);
3450
- return Array.isArray(value) ? value : [];
3451
- }
3452
- function resolveCells(cells, editorDocument, opts) {
3453
- const out = {};
3454
- for (const key of LINE_ITEM_FIELD_KEYS) {
3455
- out[key] = resolveReferences(cells[key] || "", editorDocument, opts);
3456
- }
3457
- return out;
3458
- }
3459
- function buildLineItemsArray(config, editorDocument, opts) {
3460
- if (config.mode === "manual") {
3461
- if (config.rows.length === 0) throw new Error("At least one line item is required.");
3462
- return config.rows.map((row) => finaliseLineItem(resolveCells(row, editorDocument, opts)));
3463
- }
3464
- const elements = resolveIterativeSource(config.source, editorDocument, opts);
3465
- if (elements.length === 0) throw new Error("The bound source list is empty or could not be resolved.");
3466
- return elements.map((element) => {
3467
- const perItemOpts = { ...opts, scope: { ...opts.scope || {}, item: element } };
3468
- return finaliseLineItem(resolveCells(config.map, editorDocument, perItemOpts));
3469
- });
3470
- }
3471
- async function resolveInvoiceWorkPayload(block, editorDocument, scope) {
3472
- const parsed = parseXeroInvoiceCreateInputs(block?.props?.inputs);
3473
- const opts = { scope };
3474
- const resolveStr = (v) => resolveReferences(v || "", editorDocument, opts);
3475
- const payload = {
3476
- connection: parsed.connection,
3477
- tenant_id: resolveStr(parsed.tenant_id),
3478
- Type: resolveStr(parsed.Type) || "ACCREC",
3479
- Status: resolveStr(parsed.Status) || "DRAFT",
3480
- Date: resolveStr(parsed.Date),
3481
- DueDate: resolveStr(parsed.DueDate),
3482
- ContactID: resolveStr(parsed.ContactID),
3483
- ContactName: resolveStr(parsed.ContactName),
3484
- Reference: resolveStr(parsed.Reference),
3485
- InvoiceNumber: resolveStr(parsed.InvoiceNumber),
3486
- CurrencyCode: resolveStr(parsed.CurrencyCode),
3487
- LineItems: buildLineItemsArray(parsed.LineItems, editorDocument, opts)
3488
- };
3489
- let preview = [];
3490
- const resolver = getDiffResolver("qi/xero.invoice.create");
3491
- if (resolver) {
3492
- try {
3493
- preview = await resolver.resolver({ ...payload, LineItems: parsed.LineItems }, {});
3494
- } catch {
3495
- preview = [];
3496
- }
3497
- }
3498
- return { payload, preview };
3499
- }
3500
- async function resolvePaymentWorkPayload(block, editorDocument, baseScope, settlement) {
3501
- const parsed = parseXeroPaymentCreateInputs(block?.props?.inputs);
3502
- const scope = {
3503
- ...baseScope,
3504
- invoice: { invoiceId: settlement.invoiceId, InvoiceID: settlement.invoiceId },
3505
- evaluation: {
3506
- transactionHash: settlement.transactionHash,
3507
- amount: settlement.amount,
3508
- date: settlement.date || (/* @__PURE__ */ new Date()).toISOString().slice(0, 10)
3063
+ if (!surveyAnswers || typeof surveyAnswers !== "object" || Array.isArray(surveyAnswers)) {
3064
+ throw new Error("surveyAnswers must be an object");
3509
3065
  }
3510
- };
3511
- const opts = { scope };
3512
- const resolveStr = (v) => resolveReferences(v || "", editorDocument, opts);
3513
- const currencyRateRaw = resolveStr(parsed.CurrencyRate);
3514
- const currencyRate = currencyRateRaw ? Number(currencyRateRaw) : void 0;
3515
- const amountRaw = resolveStr(parsed.Amount);
3516
- const amount = Number.isFinite(Number(amountRaw)) && Number(amountRaw) > 0 ? Number(amountRaw) : settlement.amount;
3517
- const payload = {
3518
- connection: parsed.connection,
3519
- tenant_id: resolveStr(parsed.tenant_id),
3520
- InvoiceID: resolveStr(parsed.InvoiceID) || settlement.invoiceId,
3521
- AccountID: resolveStr(parsed.AccountID),
3522
- Date: resolveStr(parsed.Date) || settlement.date || (/* @__PURE__ */ new Date()).toISOString().slice(0, 10),
3523
- Amount: amount,
3524
- Reference: resolveStr(parsed.Reference) || settlement.transactionHash,
3525
- CurrencyRate: typeof currencyRate === "number" && Number.isFinite(currencyRate) ? currencyRate : void 0
3526
- };
3527
- let preview = [];
3528
- const resolver = getDiffResolver("qi/xero.payment.create");
3529
- if (resolver) {
3530
- try {
3531
- preview = await resolver.resolver({ ...payload, Amount: String(payload.Amount) }, {});
3532
- } catch {
3533
- preview = [];
3066
+ let pin = String(inputs.pin || "").trim();
3067
+ if (!pin) {
3068
+ pin = await service.requestPin({
3069
+ title: "Verify Identity",
3070
+ description: "Enter your PIN to submit the claim",
3071
+ submitText: "Verify"
3072
+ });
3073
+ }
3074
+ if (!pin) {
3075
+ throw new Error("PIN is required to submit claim");
3076
+ }
3077
+ if (isGroupExecution(inputs)) {
3078
+ const { coreAddress, title, description } = requireGroupExecutionParams(inputs);
3079
+ const handlers = ctx.handlers;
3080
+ if (typeof handlers?.prepareGroupClaimSubmission !== "function") {
3081
+ throw new Error("Acting as a POD is not available: the host does not implement prepareGroupClaimSubmission");
3082
+ }
3083
+ const prepared = await handlers.prepareGroupClaimSubmission({
3084
+ surveyData: surveyAnswers,
3085
+ deedDid,
3086
+ entityDid: deedDid,
3087
+ collectionId,
3088
+ adminAddress,
3089
+ pin,
3090
+ groupAddress: coreAddress
3091
+ });
3092
+ const claimId2 = String(prepared?.claimId || "").trim();
3093
+ if (!claimId2) throw new Error("prepareGroupClaimSubmission returned no claim identifier");
3094
+ return proposeGroupExecution(ctx, {
3095
+ coreAddress,
3096
+ title,
3097
+ description,
3098
+ msgs: prepared.msgs || [],
3099
+ expectedOutput: {
3100
+ claimId: claimId2,
3101
+ transactionHash: "",
3102
+ collectionId,
3103
+ deedDid,
3104
+ submittedByDid: coreAddress,
3105
+ submittedAt: (/* @__PURE__ */ new Date()).toISOString(),
3106
+ surveyAnswers
3107
+ },
3108
+ completionEvent: "submitted"
3109
+ });
3110
+ }
3111
+ const result = await service.submitClaim({
3112
+ surveyData: surveyAnswers,
3113
+ deedDid,
3114
+ entityDid: deedDid,
3115
+ collectionId,
3116
+ adminAddress,
3117
+ pin
3118
+ });
3119
+ const claimId = String(result?.claimId || result?.id || "");
3120
+ if (!claimId) {
3121
+ throw new Error("submitClaim returned no claim identifier");
3534
3122
  }
3123
+ const transactionHash = String(result?.transactionHash || "");
3124
+ const submittedByDid = ctx.actorDid || "";
3125
+ const submittedAt = (/* @__PURE__ */ new Date()).toISOString();
3126
+ const output = {
3127
+ claimId,
3128
+ transactionHash,
3129
+ collectionId,
3130
+ deedDid,
3131
+ submittedByDid,
3132
+ submittedAt,
3133
+ surveyAnswers
3134
+ };
3135
+ return {
3136
+ output,
3137
+ events: [
3138
+ {
3139
+ name: "submitted",
3140
+ payload: output
3141
+ }
3142
+ ]
3143
+ };
3535
3144
  }
3536
- return { payload, preview };
3537
- }
3538
- function getInvoiceTotal(output) {
3539
- const total = typeof output.total === "number" ? output.total : Number(output.total);
3540
- return Number.isFinite(total) && total > 0 ? total : 0;
3541
- }
3145
+ });
3542
3146
 
3543
3147
  // src/core/lib/actionRegistry/actions/evaluateClaim/evaluateClaim.ts
3544
3148
  var BASELINE_OUTPUT2 = [
@@ -3583,6 +3187,27 @@ function isEvaluatorRole(role) {
3583
3187
  const normalized = String(role || "").trim().toLowerCase();
3584
3188
  return normalized === "ea" || normalized === "evaluation_agent";
3585
3189
  }
3190
+ function isTruthyFlag(value) {
3191
+ if (value === true) return true;
3192
+ if (typeof value === "number") return value === 1;
3193
+ if (typeof value === "string") {
3194
+ const normalized = value.trim().toLowerCase();
3195
+ return normalized === "true" || normalized === "1" || normalized === "yes" || normalized === "on";
3196
+ }
3197
+ return false;
3198
+ }
3199
+ var XERO_INVOICE_DEFAULT_KEYS = ["Type", "Status", "CurrencyCode", "tenant_id", "ContactID", "ContactName"];
3200
+ function buildXeroInvoiceDefaults(raw) {
3201
+ const source = raw && typeof raw === "object" && !Array.isArray(raw) ? raw : {};
3202
+ const defaults = {};
3203
+ for (const key of XERO_INVOICE_DEFAULT_KEYS) {
3204
+ const value = String(source[key] ?? "").trim();
3205
+ if (value) defaults[key] = value;
3206
+ }
3207
+ if (!defaults.Type) defaults.Type = "ACCREC";
3208
+ if (!defaults.Status) defaults.Status = "DRAFT";
3209
+ return defaults;
3210
+ }
3586
3211
  registerAction({
3587
3212
  type: "qi/claim.evaluate",
3588
3213
  can: "claim/evaluate",
@@ -3671,9 +3296,12 @@ registerAction({
3671
3296
  traceCid: { type: "string", description: "Trace CID passed through to the UDID." },
3672
3297
  items: { type: "array", description: "Evaluation items passed through to the UDID." },
3673
3298
  patch: { type: "object", description: "Patch object passed through to the UDID." },
3674
- xeroInvoiceBlockId: { type: "string", description: "Bound Xero invoice block id to queue invoice work on approval." },
3675
- xeroPaymentBlockId: { type: "string", description: "Bound Xero payment block id used when resolving Xero bindings." },
3676
- claimSnapshot: { type: "object", description: "Claim snapshot used to build the Xero invoice scope." }
3299
+ xeroOracleInvoiceOnApprove: { type: "boolean", description: "Create a Xero draft invoice via the contracted xero-oracle when a claim is approved." },
3300
+ xeroInvoiceDefaults: {
3301
+ type: "object",
3302
+ description: "Optional template-level Xero invoice defaults (Type, Status, CurrencyCode, tenant_id, ContactID, ContactName) pinned into the invoice work payload."
3303
+ },
3304
+ claimSnapshot: { type: "object", description: "Claim snapshot used to build the Xero invoice work payload." }
3677
3305
  }
3678
3306
  },
3679
3307
  run: async (inputs, ctx) => {
@@ -3855,36 +3483,30 @@ registerAction({
3855
3483
  evaluatedAt,
3856
3484
  surveyAnswers
3857
3485
  };
3858
- const xeroInvoiceBlockId = String(inputs.xeroInvoiceBlockId || "").trim();
3859
- if (decision === "approve" && xeroInvoiceBlockId) {
3860
- const editorDoc = ctx.editor?.document || [];
3861
- const runtime = ctx.runtime;
3862
- if (!runtime) {
3863
- throw new Error("Cannot queue Xero invoice work: runtime state manager is unavailable");
3864
- }
3865
- const bindings = resolveXeroBindings(editorDoc, xeroInvoiceBlockId, String(inputs.xeroPaymentBlockId || ""));
3866
- const invoiceBlock = bindings.invoiceCreateBlock;
3867
- if (!invoiceBlock) {
3868
- throw new Error("Cannot queue Xero invoice work: bound invoice block was not found");
3869
- }
3486
+ if (decision === "approve" && isTruthyFlag(inputs.xeroOracleInvoiceOnApprove)) {
3870
3487
  const flowId = String(ctx.flowId || ctx.flowUri || "flow");
3871
- const scope = buildClaimScope(inputs.claimSnapshot || { claimId }, claimData || surveyAnswers, ctx.nodeId, {
3872
- deedDid,
3873
- collectionId,
3874
- evaluationOutput: output
3875
- });
3876
- const { payload } = await resolveInvoiceWorkPayload(invoiceBlock, editorDoc, scope);
3877
- const idempotencyKey = buildXeroInvoiceWorkKey({
3878
- flowId,
3879
- evaluationBlockId: ctx.nodeId,
3880
- claimId,
3881
- invoiceBlockId: invoiceBlock.id
3882
- });
3488
+ const claimSnapshot = inputs.claimSnapshot && typeof inputs.claimSnapshot === "object" && !Array.isArray(inputs.claimSnapshot) ? inputs.claimSnapshot : void 0;
3489
+ const surveyQuestions = Array.isArray(claimSnapshot?.surveyQuestions) ? claimSnapshot.surveyQuestions : Array.isArray(inputs?.surveyAnswersSchema) ? inputs.surveyAnswersSchema : [];
3490
+ const idempotencyKey = buildXeroInvoiceWorkKey({ flowId, evaluationBlockId: ctx.nodeId, claimId });
3491
+ const originalPayload = {
3492
+ claim: { claimId, collectionId, deedDid },
3493
+ surveyQuestions,
3494
+ surveyAnswers,
3495
+ evaluation: {
3496
+ decision,
3497
+ amount: normalizedCoin,
3498
+ evaluatedByDid,
3499
+ evaluatedAt,
3500
+ verificationProof,
3501
+ transactionHash
3502
+ },
3503
+ invoiceDefaults: buildXeroInvoiceDefaults(inputs.xeroInvoiceDefaults)
3504
+ };
3883
3505
  upsertXeroWorkItemForEditor(ctx.editor, {
3884
3506
  id: idempotencyKey,
3885
3507
  kind: "invoice.create",
3886
3508
  status: "pending",
3887
- assignedBlockId: invoiceBlock.id,
3509
+ assignedBlockId: ctx.nodeId,
3888
3510
  idempotencyKey,
3889
3511
  source: {
3890
3512
  claimId,
@@ -3892,15 +3514,14 @@ registerAction({
3892
3514
  deedDid,
3893
3515
  collectionId
3894
3516
  },
3895
- originalPayload: payload,
3896
- reviewPayload: payload,
3517
+ originalPayload,
3518
+ reviewPayload: originalPayload,
3897
3519
  provenance: {
3898
3520
  createdAt: Date.now(),
3899
3521
  createdByDid: ctx.actorDid,
3900
- templateBlockId: invoiceBlock.id,
3901
- templateInputsSnapshot: invoiceBlock.props?.inputs,
3522
+ templateBlockId: ctx.nodeId,
3902
3523
  evaluationOutput: output,
3903
- claimSnapshot: inputs.claimSnapshot
3524
+ claimSnapshot
3904
3525
  },
3905
3526
  attempts: []
3906
3527
  });
@@ -10614,6 +10235,127 @@ function isRuntimeRef(value) {
10614
10235
 
10615
10236
  // src/core/lib/flowEngine/triggers.ts
10616
10237
  import * as Y from "yjs";
10238
+
10239
+ // src/core/lib/flowEngine/referenceResolver.ts
10240
+ var REFERENCE_REGEX = /\{\{([a-zA-Z0-9_-]+)\.([a-zA-Z0-9_.:]+)\}\}/g;
10241
+ function parseReferences(input) {
10242
+ const references = [];
10243
+ const regex = new RegExp(REFERENCE_REGEX);
10244
+ let match;
10245
+ while ((match = regex.exec(input)) !== null) {
10246
+ references.push({
10247
+ fullMatch: match[0],
10248
+ blockId: match[1],
10249
+ propPath: match[2],
10250
+ startIndex: match.index,
10251
+ endIndex: match.index + match[0].length
10252
+ });
10253
+ }
10254
+ return references;
10255
+ }
10256
+ function getNestedValue(obj, path) {
10257
+ return path.split(".").reduce((current, key) => {
10258
+ return current?.[key];
10259
+ }, obj);
10260
+ }
10261
+ function resolveSingleReferenceDetailed(blockId, propPath, editorDocument, yRuntime, scope) {
10262
+ if (scope && Object.prototype.hasOwnProperty.call(scope, blockId)) {
10263
+ const root = scope[blockId];
10264
+ if (root == null) return { value: void 0, reason: "missing-value" };
10265
+ const value2 = getNestedValue(root, propPath);
10266
+ return { value: value2, reason: value2 === void 0 ? "missing-value" : void 0 };
10267
+ }
10268
+ if (!editorDocument || !Array.isArray(editorDocument)) {
10269
+ return { value: void 0, reason: "unknown-block" };
10270
+ }
10271
+ const block = editorDocument.find((b) => b.id === blockId);
10272
+ if (!block) {
10273
+ return { value: void 0, reason: "unknown-block" };
10274
+ }
10275
+ if (propPath.startsWith("output.")) {
10276
+ if (!yRuntime) return { value: void 0, reason: "missing-value" };
10277
+ const runtimeState = yRuntime.get(blockId);
10278
+ if (!runtimeState?.output) return { value: void 0, reason: "missing-value" };
10279
+ const innerPath = propPath.substring("output.".length);
10280
+ const direct = getNestedValue(runtimeState.output, innerPath);
10281
+ if (direct !== void 0) return { value: direct };
10282
+ if (runtimeState.output.data !== void 0) {
10283
+ const value2 = getNestedValue(runtimeState.output.data, innerPath);
10284
+ return { value: value2, reason: value2 === void 0 ? "missing-value" : void 0 };
10285
+ }
10286
+ if (runtimeState.output.http?.data !== void 0) {
10287
+ const value2 = getNestedValue(runtimeState.output.http.data, innerPath);
10288
+ return { value: value2, reason: value2 === void 0 ? "missing-value" : void 0 };
10289
+ }
10290
+ return { value: void 0, reason: "missing-value" };
10291
+ }
10292
+ if (propPath.startsWith("response.")) {
10293
+ const responseData = block.props.response;
10294
+ if (!responseData) {
10295
+ return { value: void 0, reason: "missing-value" };
10296
+ }
10297
+ try {
10298
+ const parsedResponse = typeof responseData === "string" ? JSON.parse(responseData) : responseData;
10299
+ const innerPath = propPath.substring("response.".length);
10300
+ const value2 = getNestedValue(parsedResponse, innerPath);
10301
+ return { value: value2, reason: value2 === void 0 ? "missing-value" : void 0 };
10302
+ } catch {
10303
+ warnOnce(`ref-response-parse:${blockId}`, `[flow-config] block ${blockId}: props.response is not valid JSON; {{${blockId}.${propPath}}} cannot resolve`);
10304
+ return { value: void 0, reason: "response-parse-error" };
10305
+ }
10306
+ }
10307
+ const value = getNestedValue(block.props, propPath);
10308
+ return { value, reason: value === void 0 ? "missing-value" : void 0 };
10309
+ }
10310
+ function resolveSingleReference(blockId, propPath, editorDocument, yRuntime, scope) {
10311
+ return resolveSingleReferenceDetailed(blockId, propPath, editorDocument, yRuntime, scope).value;
10312
+ }
10313
+ function resolveReferencesDetailed(input, editorDocument, options = {}) {
10314
+ const { fallback = "", stringifyObjects = true, yRuntime, scope, warnContext } = options;
10315
+ const unresolved = [];
10316
+ if (input == null) {
10317
+ return { value: "", unresolved };
10318
+ }
10319
+ const inputStr = String(input);
10320
+ const references = parseReferences(inputStr);
10321
+ if (references.length === 0) {
10322
+ return { value: inputStr, unresolved };
10323
+ }
10324
+ let result = inputStr;
10325
+ for (let i = references.length - 1; i >= 0; i--) {
10326
+ const ref = references[i];
10327
+ const resolution = resolveSingleReferenceDetailed(ref.blockId, ref.propPath, editorDocument, yRuntime, scope);
10328
+ const resolvedValue = resolution.value;
10329
+ let replacementStr;
10330
+ if (resolvedValue === void 0 || resolvedValue === null) {
10331
+ replacementStr = fallback;
10332
+ unresolved.push({ ref: ref.fullMatch, blockId: ref.blockId, propPath: ref.propPath, reason: resolution.reason || "missing-value" });
10333
+ } else if (typeof resolvedValue === "object") {
10334
+ replacementStr = stringifyObjects ? JSON.stringify(resolvedValue) : fallback;
10335
+ } else {
10336
+ replacementStr = String(resolvedValue);
10337
+ }
10338
+ result = result.substring(0, ref.startIndex) + replacementStr + result.substring(ref.endIndex);
10339
+ }
10340
+ if (warnContext && unresolved.length > 0) {
10341
+ for (const entry of unresolved) {
10342
+ warnOnce(`ref-unresolved:${warnContext}:${entry.ref}`, `[flow-config] ${warnContext}: reference ${entry.ref} did not resolve (${entry.reason}); using fallback '${fallback}'`);
10343
+ }
10344
+ }
10345
+ return { value: result, unresolved };
10346
+ }
10347
+ function resolveReferences(input, editorDocument, options = {}) {
10348
+ return resolveReferencesDetailed(input, editorDocument, options).value;
10349
+ }
10350
+ function hasReferences(input) {
10351
+ if (input == null) return false;
10352
+ return parseReferences(String(input)).length > 0;
10353
+ }
10354
+ function createReference(blockId, propPath) {
10355
+ return `{{${blockId}.${propPath}}}`;
10356
+ }
10357
+
10358
+ // src/core/lib/flowEngine/triggers.ts
10617
10359
  var RUN_RECORD_AUDIT_TYPE = "block.run";
10618
10360
  function computePendingInvocationId(args) {
10619
10361
  const { sourceBlockId, sourceRunId, listenerBlockId, eventName, eventIndex } = args;
@@ -11239,7 +10981,7 @@ var buildFlowNodeFromBlock = (block) => {
11239
10981
  };
11240
10982
 
11241
10983
  // src/core/lib/flowEngine/runtime.ts
11242
- var XERO_WORK_ITEMS_MAP_NAME = "xeroWorkItems";
10984
+ var XERO_WORK_ITEMS_MAP_NAME2 = "xeroWorkItems";
11243
10985
  var XERO_CONNECTION_MAP_NAME = "xeroConnection";
11244
10986
  var ensureStateObject = (value) => {
11245
10987
  if (!value || typeof value !== "object") {
@@ -11285,7 +11027,7 @@ function clearRuntimeForTemplateClone(yDoc) {
11285
11027
  const agentOutbox = yDoc.getMap("agentOutbox");
11286
11028
  const agentLeases = yDoc.getMap("agentLeases");
11287
11029
  const auditTrail = yDoc.getMap("auditTrail");
11288
- const xeroWorkItems = yDoc.getMap(XERO_WORK_ITEMS_MAP_NAME);
11030
+ const xeroWorkItems = yDoc.getMap(XERO_WORK_ITEMS_MAP_NAME2);
11289
11031
  const xeroConnection = yDoc.getMap(XERO_CONNECTION_MAP_NAME);
11290
11032
  yDoc.transact(() => {
11291
11033
  runtime.forEach((_, key) => runtime.delete(key));
@@ -15071,29 +14813,20 @@ export {
15071
14813
  hasDiffResolver,
15072
14814
  extractDid,
15073
14815
  extractSurveyAnswerSchema,
14816
+ XERO_WORK_ITEMS_MAP_NAME,
14817
+ getXeroWorkItemsMap,
14818
+ buildXeroInvoiceWorkKey,
15074
14819
  buildXeroPaymentWorkKey,
14820
+ findXeroWorkItems,
14821
+ upsertXeroWorkItem,
14822
+ updateXeroWorkReviewPayload,
14823
+ markXeroWorkFailed,
14824
+ markXeroWorkCompleted,
15075
14825
  findXeroWorkItemsForEditor,
15076
14826
  upsertXeroWorkItemForEditor,
15077
14827
  updateXeroWorkReviewPayloadForEditor,
15078
14828
  markXeroWorkFailedForEditor,
15079
14829
  markXeroWorkCompletedForEditor,
15080
- LINE_ITEM_FIELD_KEYS,
15081
- emptyLineItemCells,
15082
- parseXeroInvoiceCreateInputs,
15083
- serializeXeroInvoiceCreateInputs,
15084
- finaliseLineItem,
15085
- parseXeroPaymentCreateInputs,
15086
- serializeXeroPaymentCreateInputs,
15087
- parseReferences,
15088
- resolveSingleReference,
15089
- resolveReferencesDetailed,
15090
- resolveReferences,
15091
- hasReferences,
15092
- createReference,
15093
- resolveXeroBindings,
15094
- buildClaimScope,
15095
- resolvePaymentWorkPayload,
15096
- getInvoiceTotal,
15097
14830
  transformSurveyToCredentialSubject,
15098
14831
  buildVerifiableCredential,
15099
14832
  buildDomainCardLinkedResource,
@@ -15124,6 +14857,12 @@ export {
15124
14857
  formatCoinAmount,
15125
14858
  createUcanService,
15126
14859
  isRuntimeRef,
14860
+ parseReferences,
14861
+ resolveSingleReference,
14862
+ resolveReferencesDetailed,
14863
+ resolveReferences,
14864
+ hasReferences,
14865
+ createReference,
15127
14866
  RUN_RECORD_AUDIT_TYPE,
15128
14867
  computePendingInvocationId,
15129
14868
  snapshotInputRefs,
@@ -15218,4 +14957,4 @@ export {
15218
14957
  executeQueuedFlowAgentCoreCommands,
15219
14958
  FlowAgentService
15220
14959
  };
15221
- //# sourceMappingURL=chunk-JS7P4DUX.js.map
14960
+ //# sourceMappingURL=chunk-ABM3ZZIX.js.map