@exponential_app/engine 0.0.0-stage → 0.1.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.
Files changed (85) hide show
  1. package/LICENSE +201 -0
  2. package/NOTICE +54 -0
  3. package/README.md +35 -2
  4. package/dist/capabilities.js +29 -0
  5. package/dist/capabilities.js.map +9 -0
  6. package/dist/chunks/index-3nf9f7pv.js +315 -0
  7. package/dist/chunks/index-3nf9f7pv.js.map +10 -0
  8. package/dist/chunks/index-3rgr16n2.js +443 -0
  9. package/dist/chunks/index-3rgr16n2.js.map +9 -0
  10. package/dist/chunks/index-79swfbsm.js +366 -0
  11. package/dist/chunks/index-79swfbsm.js.map +10 -0
  12. package/dist/chunks/index-knntt4cb.js +259 -0
  13. package/dist/chunks/index-knntt4cb.js.map +10 -0
  14. package/dist/chunks/index-m2845dn6.js +72 -0
  15. package/dist/chunks/index-m2845dn6.js.map +10 -0
  16. package/dist/chunks/index-pqpnz4ns.js +2213 -0
  17. package/dist/chunks/index-pqpnz4ns.js.map +9 -0
  18. package/dist/chunks/index-q4zws02e.js +2301 -0
  19. package/dist/chunks/index-q4zws02e.js.map +10 -0
  20. package/dist/chunks/index-s3xjr701.js +170 -0
  21. package/dist/chunks/index-s3xjr701.js.map +10 -0
  22. package/dist/chunks/index-sk8b0dh4.js +126 -0
  23. package/dist/chunks/index-sk8b0dh4.js.map +10 -0
  24. package/dist/chunks/index-tvsykgcv.js +3015 -0
  25. package/dist/chunks/index-tvsykgcv.js.map +19 -0
  26. package/dist/chunks/index-v0m7r4y3.js +6869 -0
  27. package/dist/chunks/index-v0m7r4y3.js.map +13 -0
  28. package/dist/consent.js +24 -0
  29. package/dist/consent.js.map +9 -0
  30. package/dist/index.js +654 -0
  31. package/dist/index.js.map +12 -0
  32. package/dist/lifecycle.js +11 -0
  33. package/dist/lifecycle.js.map +9 -0
  34. package/dist/outbox.js +27 -0
  35. package/dist/outbox.js.map +9 -0
  36. package/dist/pdf.js +15 -0
  37. package/dist/pdf.js.map +9 -0
  38. package/dist/providers.js +26 -0
  39. package/dist/providers.js.map +9 -0
  40. package/dist/runner.js +24 -0
  41. package/dist/runner.js.map +9 -0
  42. package/dist/tools.js +38 -0
  43. package/dist/tools.js.map +9 -0
  44. package/dist/types/domain-contract/src/app-records.d.ts +3148 -0
  45. package/dist/types/domain-contract/src/app-share.d.ts +222 -0
  46. package/dist/types/domain-contract/src/apps.d.ts +612 -0
  47. package/dist/types/eengine/fixtures/providers.json +55 -0
  48. package/dist/types/eengine/src/broker.d.ts +80 -0
  49. package/dist/types/eengine/src/capabilities.d.ts +88 -0
  50. package/dist/types/eengine/src/consent.d.ts +50 -0
  51. package/dist/types/eengine/src/index.d.ts +12 -0
  52. package/dist/types/eengine/src/instance.d.ts +131 -0
  53. package/dist/types/eengine/src/lifecycle.d.ts +64 -0
  54. package/dist/types/eengine/src/outbox.d.ts +3 -0
  55. package/dist/types/eengine/src/pdf.d.ts +36 -0
  56. package/dist/types/eengine/src/providers.d.ts +38 -0
  57. package/dist/types/eengine/src/runner.d.ts +82 -0
  58. package/dist/types/eengine/src/stores.d.ts +125 -0
  59. package/dist/types/eengine/src/synced.d.ts +59 -0
  60. package/dist/types/eengine/src/tools.d.ts +79 -0
  61. package/dist/types/eengine/src/web/index.d.ts +20 -0
  62. package/dist/types/eengine/src/web/mcp.d.ts +27 -0
  63. package/dist/types/eengine/src/web/platform.d.ts +91 -0
  64. package/dist/types/eengine/src/web/stores.d.ts +125 -0
  65. package/dist/types/emcp/fixtures/automations.json +521 -0
  66. package/dist/types/emcp/fixtures/hub.json +498 -0
  67. package/dist/types/emcp/src/access.d.ts +55 -0
  68. package/dist/types/emcp/src/audit.d.ts +22 -0
  69. package/dist/types/emcp/src/automations.d.ts +111 -0
  70. package/dist/types/emcp/src/exposes.d.ts +242 -0
  71. package/dist/types/emcp/src/hub.d.ts +63 -0
  72. package/dist/types/emcp/src/index.d.ts +7 -0
  73. package/dist/types/emcp/src/pure.d.ts +11 -0
  74. package/dist/types/emcp/src/upstream.d.ts +288 -0
  75. package/dist/types/emcp/src/vault.d.ts +34 -0
  76. package/dist/web/index.js +791 -0
  77. package/dist/web/index.js.map +13 -0
  78. package/fixtures/bundle.json +1165 -0
  79. package/fixtures/capabilities.json +434 -0
  80. package/fixtures/consent.json +146 -0
  81. package/fixtures/lifecycle.json +125 -0
  82. package/fixtures/outbox.json +22 -0
  83. package/fixtures/providers.json +55 -0
  84. package/fixtures/runner.json +2167 -0
  85. package/package.json +92 -4
@@ -0,0 +1,3148 @@
1
+ /** The keys every record row carries; a kind's schema may not declare them. */
2
+ export declare const APP_RECORD_ROW_KEYS: readonly string[];
3
+ /** One synced `app_records` row as the host reads it. */
4
+ export interface AppRecordRow {
5
+ id: string;
6
+ kind: string;
7
+ data: Record<string, unknown>;
8
+ createdBy: string | null;
9
+ /** VAPP-187: whose record it is (null/missing on a legacy row = `createdBy`). */
10
+ authorId?: string | null;
11
+ createdAt: string;
12
+ updatedAt: string;
13
+ }
14
+ /** VAPP-187: a record's AUTHOR (`authorId ?? createdBy`): whose record it
15
+ * is, what `mine`/`user=` and the per-member views read. */
16
+ export declare function recordAuthor(row: {
17
+ authorId?: string | null;
18
+ createdBy: string | null;
19
+ }): string | null;
20
+ /** VAPP-187 OWNERSHIP (fixture `ownership`): the default per-kind policy and
21
+ * the server's refusal. */
22
+ export declare const APP_RECORDS_OWNERSHIP: {
23
+ policy: Record<`update` | `delete`, `author` | `member`>;
24
+ refusal: string;
25
+ };
26
+ /** May `viewer` (with team `role`; null = not a member) `op` the record?
27
+ * Policy `author` = the author or a team owner (`canChangeCases`). */
28
+ export declare function canChangeRecord(row: {
29
+ authorId?: string | null;
30
+ createdBy: string | null;
31
+ }, viewer: string | null, role: string | null, op?: `update` | `delete`): boolean;
32
+ /** VAPP-188 ON-BEHALF (fixture `onBehalf`): who may name another member as
33
+ * a write's author, and the server's refusals. */
34
+ export declare const APP_RECORDS_ON_BEHALF: {
35
+ refusal: string;
36
+ notMember: string;
37
+ };
38
+ export type WriteAsVerdict = `ok` | `forbidden` | `notMember`;
39
+ /** May `viewer` (team `role`; null = not a member) write a record as
40
+ * `author` (null = as themself)? Another member = owners only, and the
41
+ * author must be one of `members` (`writeAsCases`). */
42
+ export declare function writeAsVerdict(viewer: string | null, role: string | null, author: string | null | undefined, members: readonly string[]): WriteAsVerdict;
43
+ /** An imported record's author (`importCases`): absent, the importer or a
44
+ * stranger to the team = the importer; another member = them when the
45
+ * importer is an owner, else the importer too (VAPP-192: a member
46
+ * importing a teammate's export keeps the rows as their own). */
47
+ export declare function importAuthor(importer: string, role: string | null, author: string | null | undefined, members: readonly string[]): string;
48
+ /** Settings → Apps → the app: "1,240 records", "1,240 of 25,000 records"
49
+ * (max = the team's quota, null = unlimited), "No records". */
50
+ export declare function recordsCountLabel(count: number, max: number | null): string;
51
+ /** VAPP-159 PURGE: how long a deleted record (or a trashed app's record)
52
+ * stays before the server hard-deletes it, and the rows per sweep. */
53
+ export declare const APP_RECORDS_PURGE: {
54
+ retentionDays: number;
55
+ batch: number;
56
+ };
57
+ /** A record is due for the purge once its own `deleted_at` or its app's
58
+ * trash stamp (`app_deleted_at`) is older than the retention. */
59
+ export declare function appRecordPurgeDue(deletedAt: Date | null, appDeletedAt: Date | null, now: Date): boolean;
60
+ export declare const APP_DATA_TAB: {
61
+ $comment: string;
62
+ copy: {
63
+ kindOption: string;
64
+ addRecord: string;
65
+ edit: string;
66
+ delete: string;
67
+ deleteTitle: string;
68
+ deleteBody: string;
69
+ by: string;
70
+ updated: string;
71
+ empty: string;
72
+ noKinds: string;
73
+ emptyTitle: string;
74
+ newTitle: string;
75
+ editTitle: string;
76
+ save: string;
77
+ cancel: string;
78
+ yes: string;
79
+ no: string;
80
+ none: string;
81
+ optional: string;
82
+ listHint: string;
83
+ author: string;
84
+ byFor: string;
85
+ file: string;
86
+ files: string;
87
+ };
88
+ columns: {
89
+ byWidth: number;
90
+ updatedWidth: number;
91
+ menuWidth: number;
92
+ minWidth: number;
93
+ typeWidths: {
94
+ date: number;
95
+ time: number;
96
+ "date-time": number;
97
+ number: number;
98
+ integer: number;
99
+ boolean: number;
100
+ };
101
+ gap: number;
102
+ };
103
+ placeholders: {
104
+ date: string;
105
+ time: string;
106
+ "date-time": string;
107
+ };
108
+ testIds: {
109
+ kind: string;
110
+ add: string;
111
+ row: string;
112
+ menu: string;
113
+ form: string;
114
+ save: string;
115
+ error: string;
116
+ history: string;
117
+ historyRow: string;
118
+ restore: string;
119
+ };
120
+ kindCases: ({
121
+ $why: string;
122
+ manifest: {
123
+ records: {
124
+ target: {
125
+ schema: {
126
+ type: string;
127
+ properties: {};
128
+ };
129
+ };
130
+ entry: {
131
+ schema: {
132
+ type: string;
133
+ properties: {
134
+ tags: {
135
+ type: string;
136
+ items: {
137
+ type: string;
138
+ };
139
+ };
140
+ note: {
141
+ type: string;
142
+ maxLength: number;
143
+ };
144
+ hours: {
145
+ type: string;
146
+ minimum: number;
147
+ maximum: number;
148
+ };
149
+ date: {
150
+ type: string;
151
+ format: string;
152
+ };
153
+ billable: {
154
+ type: string;
155
+ };
156
+ kind: {
157
+ type: string;
158
+ enum: string[];
159
+ };
160
+ count: {
161
+ type: string;
162
+ };
163
+ };
164
+ required: string[];
165
+ };
166
+ };
167
+ };
168
+ };
169
+ rows: {
170
+ kind: string;
171
+ }[];
172
+ kinds: {
173
+ kind: string;
174
+ count: number;
175
+ }[];
176
+ } | {
177
+ $why: string;
178
+ manifest: {
179
+ records: {
180
+ entry: {
181
+ schema: {
182
+ type: string;
183
+ properties: {
184
+ tags: {
185
+ type: string;
186
+ items: {
187
+ type: string;
188
+ };
189
+ };
190
+ note: {
191
+ type: string;
192
+ maxLength: number;
193
+ };
194
+ hours: {
195
+ type: string;
196
+ minimum: number;
197
+ maximum: number;
198
+ };
199
+ date: {
200
+ type: string;
201
+ format: string;
202
+ };
203
+ billable: {
204
+ type: string;
205
+ };
206
+ kind: {
207
+ type: string;
208
+ enum: string[];
209
+ };
210
+ count: {
211
+ type: string;
212
+ };
213
+ };
214
+ required: string[];
215
+ };
216
+ };
217
+ target?: undefined;
218
+ };
219
+ };
220
+ rows: never[];
221
+ kinds: {
222
+ kind: string;
223
+ count: number;
224
+ }[];
225
+ } | {
226
+ $why: string;
227
+ manifest: {
228
+ records?: undefined;
229
+ };
230
+ rows: {
231
+ kind: string;
232
+ }[];
233
+ kinds: never[];
234
+ } | {
235
+ $why: string;
236
+ manifest: null;
237
+ rows: never[];
238
+ kinds: never[];
239
+ })[];
240
+ columnCases: ({
241
+ schema: {
242
+ type: string;
243
+ properties: {
244
+ tags: {
245
+ type: string;
246
+ items: {
247
+ type: string;
248
+ };
249
+ };
250
+ note: {
251
+ type: string;
252
+ maxLength: number;
253
+ };
254
+ hours: {
255
+ type: string;
256
+ minimum: number;
257
+ maximum: number;
258
+ };
259
+ date: {
260
+ type: string;
261
+ format: string;
262
+ };
263
+ billable: {
264
+ type: string;
265
+ };
266
+ kind: {
267
+ type: string;
268
+ enum: string[];
269
+ };
270
+ count: {
271
+ type: string;
272
+ };
273
+ b?: undefined;
274
+ a?: undefined;
275
+ };
276
+ required: string[];
277
+ };
278
+ columns: string[];
279
+ $why?: undefined;
280
+ } | {
281
+ $why: string;
282
+ schema: {
283
+ type: string;
284
+ properties: {
285
+ b: {
286
+ type: string;
287
+ };
288
+ a: {
289
+ type: string;
290
+ };
291
+ tags?: undefined;
292
+ note?: undefined;
293
+ hours?: undefined;
294
+ date?: undefined;
295
+ billable?: undefined;
296
+ kind?: undefined;
297
+ count?: undefined;
298
+ };
299
+ required: string[];
300
+ };
301
+ columns: string[];
302
+ } | {
303
+ schema: {
304
+ type: string;
305
+ properties: {
306
+ tags?: undefined;
307
+ note?: undefined;
308
+ hours?: undefined;
309
+ date?: undefined;
310
+ billable?: undefined;
311
+ kind?: undefined;
312
+ count?: undefined;
313
+ b?: undefined;
314
+ a?: undefined;
315
+ };
316
+ required?: undefined;
317
+ };
318
+ columns: never[];
319
+ $why?: undefined;
320
+ })[];
321
+ rowsCases: {
322
+ $why: string;
323
+ kind: string;
324
+ rows: {
325
+ id: string;
326
+ kind: string;
327
+ updatedAt: string;
328
+ }[];
329
+ order: string[];
330
+ }[];
331
+ cellCases: ({
332
+ value: null;
333
+ text: string;
334
+ $why?: undefined;
335
+ } | {
336
+ $why: string;
337
+ text: string;
338
+ value?: undefined;
339
+ } | {
340
+ value: string;
341
+ text: string;
342
+ $why?: undefined;
343
+ } | {
344
+ value: number;
345
+ text: string;
346
+ $why?: undefined;
347
+ } | {
348
+ value: boolean;
349
+ text: string;
350
+ $why?: undefined;
351
+ } | {
352
+ value: string[];
353
+ text: string;
354
+ $why?: undefined;
355
+ } | {
356
+ value: (number | boolean)[];
357
+ text: string;
358
+ $why?: undefined;
359
+ } | {
360
+ value: {
361
+ a: number;
362
+ };
363
+ text: string;
364
+ $why?: undefined;
365
+ } | {
366
+ $why: string;
367
+ value: string;
368
+ text: string;
369
+ } | {
370
+ $why: string;
371
+ value: string[];
372
+ text: string;
373
+ })[];
374
+ formCases: ({
375
+ schema: {
376
+ type: string;
377
+ properties: {
378
+ tags: {
379
+ type: string;
380
+ items: {
381
+ type: string;
382
+ };
383
+ };
384
+ note: {
385
+ type: string;
386
+ maxLength: number;
387
+ };
388
+ hours: {
389
+ type: string;
390
+ minimum: number;
391
+ maximum: number;
392
+ };
393
+ date: {
394
+ type: string;
395
+ format: string;
396
+ };
397
+ billable: {
398
+ type: string;
399
+ };
400
+ kind: {
401
+ type: string;
402
+ enum: string[];
403
+ };
404
+ count: {
405
+ type: string;
406
+ };
407
+ at?: undefined;
408
+ when?: undefined;
409
+ nums?: undefined;
410
+ amount?: undefined;
411
+ receipt?: undefined;
412
+ photos?: undefined;
413
+ };
414
+ required: string[];
415
+ };
416
+ fields: ({
417
+ name: string;
418
+ control: string;
419
+ required: boolean;
420
+ placeholder: string;
421
+ options?: undefined;
422
+ itemType?: undefined;
423
+ } | {
424
+ name: string;
425
+ control: string;
426
+ required: boolean;
427
+ placeholder?: undefined;
428
+ options?: undefined;
429
+ itemType?: undefined;
430
+ } | {
431
+ name: string;
432
+ control: string;
433
+ required: boolean;
434
+ options: string[];
435
+ placeholder?: undefined;
436
+ itemType?: undefined;
437
+ } | {
438
+ name: string;
439
+ control: string;
440
+ required: boolean;
441
+ itemType: string;
442
+ placeholder?: undefined;
443
+ options?: undefined;
444
+ })[];
445
+ $why?: undefined;
446
+ } | {
447
+ schema: {
448
+ type: string;
449
+ properties: {
450
+ at: {
451
+ type: string;
452
+ format: string;
453
+ };
454
+ when: {
455
+ type: string;
456
+ format: string;
457
+ };
458
+ nums: {
459
+ type: string;
460
+ items: {
461
+ type: string;
462
+ };
463
+ };
464
+ tags?: undefined;
465
+ note?: undefined;
466
+ hours?: undefined;
467
+ date?: undefined;
468
+ billable?: undefined;
469
+ kind?: undefined;
470
+ count?: undefined;
471
+ amount?: undefined;
472
+ receipt?: undefined;
473
+ photos?: undefined;
474
+ };
475
+ required?: undefined;
476
+ };
477
+ fields: ({
478
+ name: string;
479
+ control: string;
480
+ required: boolean;
481
+ placeholder: string;
482
+ itemType?: undefined;
483
+ } | {
484
+ name: string;
485
+ control: string;
486
+ required: boolean;
487
+ itemType: string;
488
+ placeholder?: undefined;
489
+ })[];
490
+ $why?: undefined;
491
+ } | {
492
+ $why: string;
493
+ schema: {
494
+ type: string;
495
+ properties: {
496
+ amount: {
497
+ type: string;
498
+ };
499
+ receipt: {
500
+ type: string;
501
+ format: string;
502
+ };
503
+ photos: {
504
+ type: string;
505
+ items: {
506
+ type: string;
507
+ format: string;
508
+ };
509
+ };
510
+ tags: {
511
+ type: string;
512
+ items: {
513
+ type: string;
514
+ };
515
+ };
516
+ note?: undefined;
517
+ hours?: undefined;
518
+ date?: undefined;
519
+ billable?: undefined;
520
+ kind?: undefined;
521
+ count?: undefined;
522
+ at?: undefined;
523
+ when?: undefined;
524
+ nums?: undefined;
525
+ };
526
+ required: string[];
527
+ };
528
+ fields: ({
529
+ name: string;
530
+ control: string;
531
+ required: boolean;
532
+ itemType?: undefined;
533
+ } | {
534
+ name: string;
535
+ control: string;
536
+ required: boolean;
537
+ itemType: string;
538
+ })[];
539
+ })[];
540
+ inputCases: ({
541
+ control: string;
542
+ value: string;
543
+ input: string;
544
+ } | {
545
+ control: string;
546
+ value: null;
547
+ input: string;
548
+ } | {
549
+ control: string;
550
+ value: number;
551
+ input: string;
552
+ } | {
553
+ control: string;
554
+ value: string[];
555
+ input: string;
556
+ } | {
557
+ control: string;
558
+ value: number[];
559
+ input: string;
560
+ } | {
561
+ control: string;
562
+ value: boolean;
563
+ input: boolean;
564
+ } | {
565
+ control: string;
566
+ value: null;
567
+ input: boolean;
568
+ })[];
569
+ parseCases: ({
570
+ $why: string;
571
+ schema: {
572
+ type: string;
573
+ properties: {
574
+ tags: {
575
+ type: string;
576
+ items: {
577
+ type: string;
578
+ };
579
+ };
580
+ note: {
581
+ type: string;
582
+ maxLength: number;
583
+ };
584
+ hours: {
585
+ type: string;
586
+ minimum: number;
587
+ maximum: number;
588
+ };
589
+ date: {
590
+ type: string;
591
+ format: string;
592
+ };
593
+ billable: {
594
+ type: string;
595
+ };
596
+ kind: {
597
+ type: string;
598
+ enum: string[];
599
+ };
600
+ count: {
601
+ type: string;
602
+ };
603
+ nums?: undefined;
604
+ flags?: undefined;
605
+ };
606
+ required: string[];
607
+ };
608
+ editing: boolean;
609
+ inputs: {
610
+ date: string;
611
+ hours: string;
612
+ billable: boolean;
613
+ count: string;
614
+ kind: string;
615
+ note: string;
616
+ tags: string;
617
+ nums?: undefined;
618
+ flags?: undefined;
619
+ };
620
+ data: {
621
+ date: string;
622
+ hours: number;
623
+ billable: boolean;
624
+ note: string;
625
+ tags: string[];
626
+ count?: undefined;
627
+ kind?: undefined;
628
+ nums?: undefined;
629
+ flags?: undefined;
630
+ };
631
+ } | {
632
+ $why: string;
633
+ schema: {
634
+ type: string;
635
+ properties: {
636
+ tags: {
637
+ type: string;
638
+ items: {
639
+ type: string;
640
+ };
641
+ };
642
+ note: {
643
+ type: string;
644
+ maxLength: number;
645
+ };
646
+ hours: {
647
+ type: string;
648
+ minimum: number;
649
+ maximum: number;
650
+ };
651
+ date: {
652
+ type: string;
653
+ format: string;
654
+ };
655
+ billable: {
656
+ type: string;
657
+ };
658
+ kind: {
659
+ type: string;
660
+ enum: string[];
661
+ };
662
+ count: {
663
+ type: string;
664
+ };
665
+ nums?: undefined;
666
+ flags?: undefined;
667
+ };
668
+ required: string[];
669
+ };
670
+ editing: boolean;
671
+ inputs: {
672
+ date: string;
673
+ hours: string;
674
+ billable: boolean;
675
+ count: string;
676
+ kind: string;
677
+ note: string;
678
+ tags: string;
679
+ nums?: undefined;
680
+ flags?: undefined;
681
+ };
682
+ data: {
683
+ date: string;
684
+ hours: number;
685
+ billable: boolean;
686
+ count: null;
687
+ kind: string;
688
+ note: null;
689
+ tags: null;
690
+ nums?: undefined;
691
+ flags?: undefined;
692
+ };
693
+ } | {
694
+ $why: string;
695
+ schema: {
696
+ type: string;
697
+ properties: {
698
+ tags: {
699
+ type: string;
700
+ items: {
701
+ type: string;
702
+ };
703
+ };
704
+ note: {
705
+ type: string;
706
+ maxLength: number;
707
+ };
708
+ hours: {
709
+ type: string;
710
+ minimum: number;
711
+ maximum: number;
712
+ };
713
+ date: {
714
+ type: string;
715
+ format: string;
716
+ };
717
+ billable: {
718
+ type: string;
719
+ };
720
+ kind: {
721
+ type: string;
722
+ enum: string[];
723
+ };
724
+ count: {
725
+ type: string;
726
+ };
727
+ nums?: undefined;
728
+ flags?: undefined;
729
+ };
730
+ required: string[];
731
+ };
732
+ editing: boolean;
733
+ inputs: {
734
+ date: string;
735
+ hours: string;
736
+ billable: boolean;
737
+ count?: undefined;
738
+ kind?: undefined;
739
+ note?: undefined;
740
+ tags?: undefined;
741
+ nums?: undefined;
742
+ flags?: undefined;
743
+ };
744
+ data: {
745
+ hours: string;
746
+ billable: boolean;
747
+ date?: undefined;
748
+ note?: undefined;
749
+ tags?: undefined;
750
+ count?: undefined;
751
+ kind?: undefined;
752
+ nums?: undefined;
753
+ flags?: undefined;
754
+ };
755
+ } | {
756
+ $why: string;
757
+ schema: {
758
+ type: string;
759
+ properties: {
760
+ nums: {
761
+ type: string;
762
+ items: {
763
+ type: string;
764
+ };
765
+ };
766
+ flags: {
767
+ type: string;
768
+ items: {
769
+ type: string;
770
+ };
771
+ };
772
+ tags?: undefined;
773
+ note?: undefined;
774
+ hours?: undefined;
775
+ date?: undefined;
776
+ billable?: undefined;
777
+ kind?: undefined;
778
+ count?: undefined;
779
+ };
780
+ required?: undefined;
781
+ };
782
+ editing: boolean;
783
+ inputs: {
784
+ nums: string;
785
+ flags: string;
786
+ date?: undefined;
787
+ hours?: undefined;
788
+ billable?: undefined;
789
+ count?: undefined;
790
+ kind?: undefined;
791
+ note?: undefined;
792
+ tags?: undefined;
793
+ };
794
+ data: {
795
+ nums: (string | number)[];
796
+ flags: boolean[];
797
+ date?: undefined;
798
+ hours?: undefined;
799
+ billable?: undefined;
800
+ note?: undefined;
801
+ tags?: undefined;
802
+ count?: undefined;
803
+ kind?: undefined;
804
+ };
805
+ })[];
806
+ bylineCases: ({
807
+ name: string;
808
+ createdBy: string;
809
+ authorId: string;
810
+ names: {
811
+ u1: string;
812
+ u2: string;
813
+ };
814
+ fallback: string;
815
+ text: string;
816
+ } | {
817
+ name: string;
818
+ createdBy: string;
819
+ authorId: null;
820
+ names: {
821
+ u1: string;
822
+ u2: string;
823
+ };
824
+ fallback: string;
825
+ text: string;
826
+ } | {
827
+ name: string;
828
+ createdBy: null;
829
+ authorId: null;
830
+ names: {
831
+ u1: string;
832
+ u2: string;
833
+ };
834
+ fallback: string;
835
+ text: string;
836
+ })[];
837
+ authorOptionCases: {
838
+ users: {
839
+ id: string;
840
+ name: string;
841
+ }[];
842
+ order: string[];
843
+ }[];
844
+ formAuthorCases: ({
845
+ name: string;
846
+ viewer: string;
847
+ record: null;
848
+ picked: string;
849
+ default: string;
850
+ send: null;
851
+ } | {
852
+ name: string;
853
+ viewer: string;
854
+ record: null;
855
+ picked: string;
856
+ default: string;
857
+ send: string;
858
+ } | {
859
+ name: string;
860
+ viewer: string;
861
+ record: {
862
+ authorId: string;
863
+ createdBy: string;
864
+ };
865
+ picked: string;
866
+ default: string;
867
+ send: null;
868
+ } | {
869
+ name: string;
870
+ viewer: string;
871
+ record: {
872
+ authorId: string;
873
+ createdBy: string;
874
+ };
875
+ picked: string;
876
+ default: string;
877
+ send: string;
878
+ } | {
879
+ name: string;
880
+ viewer: string;
881
+ record: {
882
+ authorId: null;
883
+ createdBy: string;
884
+ };
885
+ picked: string;
886
+ default: string;
887
+ send: null;
888
+ } | {
889
+ name: string;
890
+ viewer: string;
891
+ record: {
892
+ authorId: null;
893
+ createdBy: null;
894
+ };
895
+ picked: string;
896
+ default: string;
897
+ send: string;
898
+ })[];
899
+ };
900
+ export declare const APP_DATA_COPY: {
901
+ kindOption: string;
902
+ addRecord: string;
903
+ edit: string;
904
+ delete: string;
905
+ deleteTitle: string;
906
+ deleteBody: string;
907
+ by: string;
908
+ updated: string;
909
+ empty: string;
910
+ noKinds: string;
911
+ emptyTitle: string;
912
+ newTitle: string;
913
+ editTitle: string;
914
+ save: string;
915
+ cancel: string;
916
+ yes: string;
917
+ no: string;
918
+ none: string;
919
+ optional: string;
920
+ listHint: string;
921
+ author: string;
922
+ byFor: string;
923
+ file: string;
924
+ files: string;
925
+ };
926
+ /** A kind's schema field (the SDK's JSON Schema subset, host/records.ts). */
927
+ export interface DataField {
928
+ type: `string` | `number` | `integer` | `boolean` | `array`;
929
+ enum?: string[];
930
+ items?: {
931
+ type: `string` | `number` | `integer` | `boolean`;
932
+ format?: string;
933
+ };
934
+ format?: `date` | `date-time` | `time` | `attachment`;
935
+ }
936
+ /** VAPP-221: a field holding files (`format: "attachment"` on a string or
937
+ * a list's string items): no form field, the app's FileUpload writes it. */
938
+ export declare function isAttachmentField(field: DataField): boolean;
939
+ export interface DataSchema {
940
+ type?: `object`;
941
+ properties: Record<string, DataField>;
942
+ required?: string[];
943
+ }
944
+ /** The head manifest's kinds, sorted by name, each with its live count
945
+ * (`kindCases`); a row of an undeclared kind is ignored. */
946
+ export declare function dataKinds(manifest: {
947
+ records?: Record<string, {
948
+ schema: DataSchema;
949
+ }>;
950
+ } | null | undefined, rows: readonly {
951
+ kind: string;
952
+ }[]): {
953
+ kind: string;
954
+ count: number;
955
+ }[];
956
+ /** The columns (`columnCases`): the `required` names in their order, then
957
+ * every other property sorted by name (never the declaration order: a
958
+ * host's JSON layer may lose it). */
959
+ export declare function dataColumns(schema: DataSchema): string[];
960
+ /** A kind's rows, `updatedAt` desc, ties by id (`rowsCases`). */
961
+ export declare function dataRows<T extends {
962
+ id: string;
963
+ kind: string;
964
+ updatedAt: string;
965
+ }>(rows: readonly T[], kind: string): T[];
966
+ /** One cell's text (`cellCases`). */
967
+ export declare function cellText(value: unknown): string;
968
+ export type DataControl = `text` | `number` | `switch` | `select` | `list`;
969
+ export interface DataFormField {
970
+ name: string;
971
+ control: DataControl;
972
+ required: boolean;
973
+ placeholder?: string;
974
+ options?: string[];
975
+ itemType?: `string` | `number` | `integer` | `boolean`;
976
+ }
977
+ /** The form's fields, in column order (`formCases`). */
978
+ export declare function formFields(schema: DataSchema): DataFormField[];
979
+ /** A stored value → the control's initial input (`inputCases`): a switch
980
+ * takes a boolean, every other control text. */
981
+ export declare function formInput(control: DataControl, value: unknown): string | boolean;
982
+ /** The inputs → the record's data (`parseCases`): an empty field = null,
983
+ * numbers and list items parse (unparsable stays the raw text, so the
984
+ * server names it); CREATE omits the nulls, EDIT keeps them (null clears). */
985
+ export declare function formData(schema: DataSchema, inputs: Record<string, string | boolean | undefined>, editing: boolean): Record<string, unknown>;
986
+ /** A column's fixed width in px (`columns.typeWidths`), or null = it shares
987
+ * the rest of the row. */
988
+ export declare function columnWidth(field: DataField): number | null;
989
+ /** VAPP-188: the `by` cell (`bylineCases`): the author's name (else
990
+ * `fallback`, apps.json `copy.byAgent`), `{writer} for {author}` when
991
+ * someone else with a name wrote it. */
992
+ export declare function recordByline(row: {
993
+ authorId?: string | null;
994
+ createdBy: string | null;
995
+ }, names: Readonly<Record<string, string>>, fallback: string): string;
996
+ /** VAPP-188: the owner's Author picker, members by name (case-insensitive,
997
+ * ties by id: `authorOptionCases`). */
998
+ export declare function authorOptions<T extends {
999
+ id: string;
1000
+ name: string;
1001
+ }>(users: readonly T[]): T[];
1002
+ /** VAPP-188: the picker's default (the record's author on edit, the viewer
1003
+ * on create) and what Save sends (`send`: the pick when it differs from
1004
+ * the record's author / the viewer, else null = omit; `formAuthorCases`). */
1005
+ export declare function formAuthor(viewer: string | null, record: {
1006
+ authorId?: string | null;
1007
+ createdBy: string | null;
1008
+ } | null, picked: string | null): {
1009
+ default: string | null;
1010
+ send: string | null;
1011
+ };
1012
+ export declare const APP_RECORD_HISTORY: {
1013
+ $comment: string;
1014
+ undoSeconds: number;
1015
+ retentionDays: number;
1016
+ batch: number;
1017
+ historyLimit: number;
1018
+ maxFields: number;
1019
+ ops: string[];
1020
+ vias: string[];
1021
+ copy: {
1022
+ history: string;
1023
+ restore: string;
1024
+ undo: string;
1025
+ created: string;
1026
+ deleted: string;
1027
+ restored: string;
1028
+ changed: string;
1029
+ more: string;
1030
+ saved: string;
1031
+ empty: string;
1032
+ undoCreate: string;
1033
+ undoUpdate: string;
1034
+ undoDelete: string;
1035
+ undoBatch: string;
1036
+ undoVerb: string;
1037
+ undoThing: string;
1038
+ };
1039
+ stateCases: ({
1040
+ name: string;
1041
+ event: {
1042
+ op: string;
1043
+ before: null;
1044
+ patch: {
1045
+ hours: number;
1046
+ };
1047
+ };
1048
+ state: {
1049
+ hours: number;
1050
+ note?: undefined;
1051
+ };
1052
+ } | {
1053
+ name: string;
1054
+ event: {
1055
+ op: string;
1056
+ before: {
1057
+ hours: number;
1058
+ note: string;
1059
+ };
1060
+ patch: {
1061
+ hours: number;
1062
+ };
1063
+ };
1064
+ state: {
1065
+ hours: number;
1066
+ note: string;
1067
+ };
1068
+ } | {
1069
+ name: string;
1070
+ event: {
1071
+ op: string;
1072
+ before: {
1073
+ hours: number;
1074
+ note?: undefined;
1075
+ };
1076
+ patch: null;
1077
+ };
1078
+ state: null;
1079
+ })[];
1080
+ inverseCases: ({
1081
+ name: string;
1082
+ event: {
1083
+ op: string;
1084
+ before: null;
1085
+ patch: {
1086
+ hours: number;
1087
+ };
1088
+ };
1089
+ inverse: {
1090
+ op: string;
1091
+ data?: undefined;
1092
+ };
1093
+ } | {
1094
+ name: string;
1095
+ event: {
1096
+ op: string;
1097
+ before: {
1098
+ hours: number;
1099
+ note: string;
1100
+ };
1101
+ patch: {
1102
+ hours: number;
1103
+ };
1104
+ };
1105
+ inverse: {
1106
+ op: string;
1107
+ data: {
1108
+ hours: number;
1109
+ note: string;
1110
+ };
1111
+ };
1112
+ } | {
1113
+ name: string;
1114
+ event: {
1115
+ op: string;
1116
+ before: {
1117
+ hours: number;
1118
+ note?: undefined;
1119
+ };
1120
+ patch: null;
1121
+ };
1122
+ inverse: {
1123
+ op: string;
1124
+ data: {
1125
+ hours: number;
1126
+ note?: undefined;
1127
+ };
1128
+ };
1129
+ } | {
1130
+ name: string;
1131
+ event: {
1132
+ op: string;
1133
+ before: {
1134
+ hours: number;
1135
+ note?: undefined;
1136
+ };
1137
+ patch: {
1138
+ hours: number;
1139
+ };
1140
+ };
1141
+ inverse: {
1142
+ op: string;
1143
+ data: {
1144
+ hours: number;
1145
+ note?: undefined;
1146
+ };
1147
+ };
1148
+ })[];
1149
+ labelCases: ({
1150
+ name: string;
1151
+ event: {
1152
+ op: string;
1153
+ before: null;
1154
+ patch: {
1155
+ hours: number;
1156
+ note?: undefined;
1157
+ day?: undefined;
1158
+ tags?: undefined;
1159
+ e?: undefined;
1160
+ d?: undefined;
1161
+ c?: undefined;
1162
+ b?: undefined;
1163
+ a?: undefined;
1164
+ };
1165
+ };
1166
+ label: string;
1167
+ } | {
1168
+ name: string;
1169
+ event: {
1170
+ op: string;
1171
+ before: {
1172
+ hours: number;
1173
+ note?: undefined;
1174
+ day?: undefined;
1175
+ tags?: undefined;
1176
+ a?: undefined;
1177
+ b?: undefined;
1178
+ c?: undefined;
1179
+ d?: undefined;
1180
+ e?: undefined;
1181
+ };
1182
+ patch: null;
1183
+ };
1184
+ label: string;
1185
+ } | {
1186
+ name: string;
1187
+ event: {
1188
+ op: string;
1189
+ before: {
1190
+ note: string;
1191
+ hours: number;
1192
+ day: string;
1193
+ tags?: undefined;
1194
+ a?: undefined;
1195
+ b?: undefined;
1196
+ c?: undefined;
1197
+ d?: undefined;
1198
+ e?: undefined;
1199
+ };
1200
+ patch: {
1201
+ note: string;
1202
+ hours: number;
1203
+ day: string;
1204
+ tags?: undefined;
1205
+ e?: undefined;
1206
+ d?: undefined;
1207
+ c?: undefined;
1208
+ b?: undefined;
1209
+ a?: undefined;
1210
+ };
1211
+ };
1212
+ label: string;
1213
+ } | {
1214
+ name: string;
1215
+ event: {
1216
+ op: string;
1217
+ before: {
1218
+ hours: number;
1219
+ note?: undefined;
1220
+ day?: undefined;
1221
+ tags?: undefined;
1222
+ a?: undefined;
1223
+ b?: undefined;
1224
+ c?: undefined;
1225
+ d?: undefined;
1226
+ e?: undefined;
1227
+ };
1228
+ patch: {
1229
+ note: string;
1230
+ hours?: undefined;
1231
+ day?: undefined;
1232
+ tags?: undefined;
1233
+ e?: undefined;
1234
+ d?: undefined;
1235
+ c?: undefined;
1236
+ b?: undefined;
1237
+ a?: undefined;
1238
+ };
1239
+ };
1240
+ label: string;
1241
+ } | {
1242
+ name: string;
1243
+ event: {
1244
+ op: string;
1245
+ before: {
1246
+ tags: string[];
1247
+ hours?: undefined;
1248
+ note?: undefined;
1249
+ day?: undefined;
1250
+ a?: undefined;
1251
+ b?: undefined;
1252
+ c?: undefined;
1253
+ d?: undefined;
1254
+ e?: undefined;
1255
+ };
1256
+ patch: {
1257
+ tags: string[];
1258
+ hours?: undefined;
1259
+ note?: undefined;
1260
+ day?: undefined;
1261
+ e?: undefined;
1262
+ d?: undefined;
1263
+ c?: undefined;
1264
+ b?: undefined;
1265
+ a?: undefined;
1266
+ };
1267
+ };
1268
+ label: string;
1269
+ } | {
1270
+ name: string;
1271
+ event: {
1272
+ op: string;
1273
+ before: {
1274
+ a: number;
1275
+ b: number;
1276
+ c: number;
1277
+ d: number;
1278
+ e: number;
1279
+ hours?: undefined;
1280
+ note?: undefined;
1281
+ day?: undefined;
1282
+ tags?: undefined;
1283
+ };
1284
+ patch: {
1285
+ e: number;
1286
+ d: number;
1287
+ c: number;
1288
+ b: number;
1289
+ a: number;
1290
+ hours?: undefined;
1291
+ note?: undefined;
1292
+ day?: undefined;
1293
+ tags?: undefined;
1294
+ };
1295
+ };
1296
+ label: string;
1297
+ } | {
1298
+ name: string;
1299
+ event: {
1300
+ op: string;
1301
+ before: {
1302
+ hours: number;
1303
+ note?: undefined;
1304
+ day?: undefined;
1305
+ tags?: undefined;
1306
+ a?: undefined;
1307
+ b?: undefined;
1308
+ c?: undefined;
1309
+ d?: undefined;
1310
+ e?: undefined;
1311
+ };
1312
+ patch: {
1313
+ hours: number;
1314
+ note?: undefined;
1315
+ day?: undefined;
1316
+ tags?: undefined;
1317
+ e?: undefined;
1318
+ d?: undefined;
1319
+ c?: undefined;
1320
+ b?: undefined;
1321
+ a?: undefined;
1322
+ };
1323
+ };
1324
+ label: string;
1325
+ })[];
1326
+ rowsCases: ({
1327
+ name: string;
1328
+ names: {
1329
+ u1: string;
1330
+ u2: string;
1331
+ };
1332
+ fallback: string;
1333
+ events: ({
1334
+ id: string;
1335
+ op: string;
1336
+ actor: string;
1337
+ before: null;
1338
+ patch: {
1339
+ hours: number;
1340
+ };
1341
+ createdAt: string;
1342
+ } | {
1343
+ id: string;
1344
+ op: string;
1345
+ actor: string;
1346
+ before: {
1347
+ hours: number;
1348
+ };
1349
+ patch: null;
1350
+ createdAt: string;
1351
+ } | {
1352
+ id: string;
1353
+ op: string;
1354
+ actor: string;
1355
+ before: {
1356
+ hours: number;
1357
+ };
1358
+ patch: {
1359
+ hours: number;
1360
+ };
1361
+ createdAt: string;
1362
+ })[];
1363
+ rows: {
1364
+ id: string;
1365
+ label: string;
1366
+ who: string;
1367
+ at: string;
1368
+ restorable: boolean;
1369
+ }[];
1370
+ } | {
1371
+ name: string;
1372
+ names: {
1373
+ u1?: undefined;
1374
+ u2?: undefined;
1375
+ };
1376
+ fallback: string;
1377
+ events: never[];
1378
+ rows: never[];
1379
+ })[];
1380
+ };
1381
+ export declare const APP_HISTORY_COPY: {
1382
+ history: string;
1383
+ restore: string;
1384
+ undo: string;
1385
+ created: string;
1386
+ deleted: string;
1387
+ restored: string;
1388
+ changed: string;
1389
+ more: string;
1390
+ saved: string;
1391
+ empty: string;
1392
+ undoCreate: string;
1393
+ undoUpdate: string;
1394
+ undoDelete: string;
1395
+ undoBatch: string;
1396
+ undoVerb: string;
1397
+ undoThing: string;
1398
+ };
1399
+ export type RecordEventOp = `create` | `update` | `delete` | `restore`;
1400
+ export type RecordEventVia = `editor` | `app` | `mcp` | `action` | `import` | `migration` | `share:${string}`;
1401
+ /** The part of an event the pure rules read. */
1402
+ export interface RecordEventCore {
1403
+ op: RecordEventOp;
1404
+ before: Record<string, unknown> | null;
1405
+ patch: Record<string, unknown> | null;
1406
+ }
1407
+ /** One event as `apps.records.history` returns it (newest first). */
1408
+ export interface RecordEvent extends RecordEventCore {
1409
+ id: string;
1410
+ actor: string | null;
1411
+ createdAt: string;
1412
+ /** VAPP-241: `share:<name>` = a guest's submission (app-share.json). */
1413
+ via?: string;
1414
+ }
1415
+ /** The write that undoes an event: a delete, or a restore of `data`. */
1416
+ export type InverseWrite = {
1417
+ op: `delete`;
1418
+ } | {
1419
+ op: `restore`;
1420
+ data: Record<string, unknown>;
1421
+ };
1422
+ /** The record an event left (`stateCases`): null = gone. */
1423
+ export declare function eventState(event: RecordEventCore): Record<string, unknown> | null;
1424
+ /** Undo = a new write of the event's `before` (`inverseCases`). */
1425
+ export declare function inverseWrite(event: RecordEventCore): InverseWrite;
1426
+ /** Deep JSON equality (objects by key, numbers by value). */
1427
+ export declare function jsonEqual(a: unknown, b: unknown): boolean;
1428
+ /** A History row's title (`labelCases`). */
1429
+ export declare function eventLabel(event: RecordEventCore): string;
1430
+ export interface HistoryRow {
1431
+ id: string;
1432
+ label: string;
1433
+ who: string;
1434
+ at: string;
1435
+ restorable: boolean;
1436
+ }
1437
+ /** The History list (`rowsCases`): the events in the server's order (newest
1438
+ * first); Restore on every row but the newest, never on a delete. */
1439
+ export declare function historyRows(events: readonly RecordEvent[], names: Readonly<Record<string, string>>, fallback: string): HistoryRow[];
1440
+ /** The Undo toast's title for a UI write. */
1441
+ export declare function undoTitle(write: `create` | `update` | `delete` | `batch`): string;
1442
+ export declare const APP_RECORDS_OUTBOX: {
1443
+ $comment: string;
1444
+ ackGraceSeconds: number;
1445
+ retryCodes: string[];
1446
+ copy: {
1447
+ pendingOne: string;
1448
+ pending: string;
1449
+ };
1450
+ writesCases: ({
1451
+ name: string;
1452
+ call: string;
1453
+ args: {
1454
+ kind: string;
1455
+ data: {
1456
+ hours: number;
1457
+ };
1458
+ id?: undefined;
1459
+ writes?: undefined;
1460
+ };
1461
+ newIds: string[];
1462
+ writes: {
1463
+ op: string;
1464
+ id: string;
1465
+ kind: string;
1466
+ data: {
1467
+ hours: number;
1468
+ };
1469
+ }[];
1470
+ } | {
1471
+ name: string;
1472
+ call: string;
1473
+ args: {
1474
+ kind: string;
1475
+ data: {
1476
+ hours: number;
1477
+ };
1478
+ id: string;
1479
+ writes?: undefined;
1480
+ };
1481
+ newIds: never[];
1482
+ writes: {
1483
+ op: string;
1484
+ id: string;
1485
+ kind: string;
1486
+ data: {
1487
+ hours: number;
1488
+ };
1489
+ }[];
1490
+ } | {
1491
+ name: string;
1492
+ call: string;
1493
+ args: {
1494
+ id: string;
1495
+ kind?: undefined;
1496
+ data?: undefined;
1497
+ writes?: undefined;
1498
+ };
1499
+ newIds: never[];
1500
+ writes: {
1501
+ op: string;
1502
+ id: string;
1503
+ }[];
1504
+ } | {
1505
+ name: string;
1506
+ call: string;
1507
+ args: {
1508
+ writes: ({
1509
+ op: string;
1510
+ kind: string;
1511
+ data: {
1512
+ hours: number;
1513
+ note?: undefined;
1514
+ };
1515
+ id?: undefined;
1516
+ } | {
1517
+ op: string;
1518
+ kind: string;
1519
+ data: {
1520
+ note: string;
1521
+ hours?: undefined;
1522
+ };
1523
+ id: string;
1524
+ } | {
1525
+ op: string;
1526
+ id: string;
1527
+ kind?: undefined;
1528
+ data?: undefined;
1529
+ })[];
1530
+ kind?: undefined;
1531
+ data?: undefined;
1532
+ id?: undefined;
1533
+ };
1534
+ newIds: string[];
1535
+ writes: ({
1536
+ op: string;
1537
+ id: string;
1538
+ kind: string;
1539
+ data: {
1540
+ hours: number;
1541
+ note?: undefined;
1542
+ };
1543
+ } | {
1544
+ op: string;
1545
+ id: string;
1546
+ kind: string;
1547
+ data: {
1548
+ note: string;
1549
+ hours?: undefined;
1550
+ };
1551
+ } | {
1552
+ op: string;
1553
+ id: string;
1554
+ kind?: undefined;
1555
+ data?: undefined;
1556
+ })[];
1557
+ } | {
1558
+ name: string;
1559
+ call: string;
1560
+ args: {
1561
+ kind: string;
1562
+ data?: undefined;
1563
+ id?: undefined;
1564
+ writes?: undefined;
1565
+ };
1566
+ newIds: string[];
1567
+ writes: {
1568
+ op: string;
1569
+ id: string;
1570
+ kind: string;
1571
+ data: {};
1572
+ }[];
1573
+ })[];
1574
+ requestCases: ({
1575
+ name: string;
1576
+ entry: {
1577
+ writeId: string;
1578
+ appId: string;
1579
+ call: string;
1580
+ writes: {
1581
+ op: string;
1582
+ id: string;
1583
+ kind: string;
1584
+ data: {
1585
+ hours: number;
1586
+ };
1587
+ }[];
1588
+ at: string;
1589
+ state: string;
1590
+ };
1591
+ request: {
1592
+ call: string;
1593
+ input: {
1594
+ kind: string;
1595
+ data: {
1596
+ hours: number;
1597
+ };
1598
+ newId: string;
1599
+ writeId: string;
1600
+ recordId?: undefined;
1601
+ writes?: undefined;
1602
+ };
1603
+ };
1604
+ } | {
1605
+ name: string;
1606
+ entry: {
1607
+ writeId: string;
1608
+ appId: string;
1609
+ call: string;
1610
+ writes: {
1611
+ op: string;
1612
+ id: string;
1613
+ kind: string;
1614
+ data: {
1615
+ hours: number;
1616
+ };
1617
+ }[];
1618
+ at: string;
1619
+ state: string;
1620
+ };
1621
+ request: {
1622
+ call: string;
1623
+ input: {
1624
+ kind: string;
1625
+ data: {
1626
+ hours: number;
1627
+ };
1628
+ recordId: string;
1629
+ writeId: string;
1630
+ newId?: undefined;
1631
+ writes?: undefined;
1632
+ };
1633
+ };
1634
+ } | {
1635
+ name: string;
1636
+ entry: {
1637
+ writeId: string;
1638
+ appId: string;
1639
+ call: string;
1640
+ writes: {
1641
+ op: string;
1642
+ id: string;
1643
+ }[];
1644
+ at: string;
1645
+ state: string;
1646
+ };
1647
+ request: {
1648
+ call: string;
1649
+ input: {
1650
+ recordId: string;
1651
+ writeId: string;
1652
+ kind?: undefined;
1653
+ data?: undefined;
1654
+ newId?: undefined;
1655
+ writes?: undefined;
1656
+ };
1657
+ };
1658
+ } | {
1659
+ name: string;
1660
+ entry: {
1661
+ writeId: string;
1662
+ appId: string;
1663
+ call: string;
1664
+ writes: ({
1665
+ op: string;
1666
+ id: string;
1667
+ kind: string;
1668
+ data: {
1669
+ hours: number;
1670
+ note?: undefined;
1671
+ };
1672
+ } | {
1673
+ op: string;
1674
+ id: string;
1675
+ kind: string;
1676
+ data: {
1677
+ note: string;
1678
+ hours?: undefined;
1679
+ };
1680
+ } | {
1681
+ op: string;
1682
+ id: string;
1683
+ kind?: undefined;
1684
+ data?: undefined;
1685
+ })[];
1686
+ at: string;
1687
+ state: string;
1688
+ };
1689
+ request: {
1690
+ call: string;
1691
+ input: {
1692
+ writes: ({
1693
+ op: string;
1694
+ kind: string;
1695
+ data: {
1696
+ hours: number;
1697
+ note?: undefined;
1698
+ };
1699
+ newId: string;
1700
+ id?: undefined;
1701
+ } | {
1702
+ op: string;
1703
+ kind: string;
1704
+ data: {
1705
+ note: string;
1706
+ hours?: undefined;
1707
+ };
1708
+ id: string;
1709
+ newId?: undefined;
1710
+ } | {
1711
+ op: string;
1712
+ id: string;
1713
+ kind?: undefined;
1714
+ data?: undefined;
1715
+ newId?: undefined;
1716
+ })[];
1717
+ writeId: string;
1718
+ kind?: undefined;
1719
+ data?: undefined;
1720
+ newId?: undefined;
1721
+ recordId?: undefined;
1722
+ };
1723
+ };
1724
+ })[];
1725
+ rowsCases: ({
1726
+ name: string;
1727
+ me: string;
1728
+ rows: {
1729
+ id: string;
1730
+ kind: string;
1731
+ data: {
1732
+ hours: number;
1733
+ };
1734
+ createdBy: string;
1735
+ authorId: string;
1736
+ createdAt: string;
1737
+ updatedAt: string;
1738
+ }[];
1739
+ entries: {
1740
+ writeId: string;
1741
+ appId: string;
1742
+ call: string;
1743
+ writes: {
1744
+ op: string;
1745
+ id: string;
1746
+ kind: string;
1747
+ data: {
1748
+ hours: number;
1749
+ };
1750
+ }[];
1751
+ at: string;
1752
+ state: string;
1753
+ }[];
1754
+ expected: {
1755
+ id: string;
1756
+ kind: string;
1757
+ data: {
1758
+ hours: number;
1759
+ };
1760
+ createdBy: string;
1761
+ authorId: string;
1762
+ createdAt: string;
1763
+ updatedAt: string;
1764
+ }[];
1765
+ } | {
1766
+ name: string;
1767
+ me: string;
1768
+ rows: {
1769
+ id: string;
1770
+ kind: string;
1771
+ data: {
1772
+ hours: number;
1773
+ note: string;
1774
+ };
1775
+ createdBy: string;
1776
+ authorId: string;
1777
+ createdAt: string;
1778
+ updatedAt: string;
1779
+ }[];
1780
+ entries: {
1781
+ writeId: string;
1782
+ appId: string;
1783
+ call: string;
1784
+ writes: {
1785
+ op: string;
1786
+ id: string;
1787
+ kind: string;
1788
+ data: {
1789
+ hours: number;
1790
+ };
1791
+ }[];
1792
+ at: string;
1793
+ state: string;
1794
+ }[];
1795
+ expected: {
1796
+ id: string;
1797
+ kind: string;
1798
+ data: {
1799
+ hours: number;
1800
+ note: string;
1801
+ };
1802
+ createdBy: string;
1803
+ authorId: string;
1804
+ createdAt: string;
1805
+ updatedAt: string;
1806
+ }[];
1807
+ } | {
1808
+ name: string;
1809
+ me: string;
1810
+ rows: {
1811
+ id: string;
1812
+ kind: string;
1813
+ data: {
1814
+ hours: number;
1815
+ };
1816
+ createdBy: string;
1817
+ authorId: string;
1818
+ createdAt: string;
1819
+ updatedAt: string;
1820
+ }[];
1821
+ entries: {
1822
+ writeId: string;
1823
+ appId: string;
1824
+ call: string;
1825
+ writes: {
1826
+ op: string;
1827
+ id: string;
1828
+ }[];
1829
+ at: string;
1830
+ state: string;
1831
+ }[];
1832
+ expected: {
1833
+ id: string;
1834
+ kind: string;
1835
+ data: {
1836
+ hours: number;
1837
+ };
1838
+ createdBy: string;
1839
+ authorId: string;
1840
+ createdAt: string;
1841
+ updatedAt: string;
1842
+ }[];
1843
+ } | {
1844
+ name: string;
1845
+ me: string;
1846
+ rows: never[];
1847
+ entries: ({
1848
+ writeId: string;
1849
+ appId: string;
1850
+ call: string;
1851
+ writes: {
1852
+ op: string;
1853
+ id: string;
1854
+ kind: string;
1855
+ data: {
1856
+ hours: number;
1857
+ };
1858
+ }[];
1859
+ at: string;
1860
+ state: string;
1861
+ } | {
1862
+ writeId: string;
1863
+ appId: string;
1864
+ call: string;
1865
+ writes: {
1866
+ op: string;
1867
+ id: string;
1868
+ kind: string;
1869
+ data: {
1870
+ note: string;
1871
+ };
1872
+ }[];
1873
+ at: string;
1874
+ state: string;
1875
+ })[];
1876
+ expected: ({
1877
+ id: string;
1878
+ kind: string;
1879
+ data: {
1880
+ hours: number;
1881
+ note: string;
1882
+ };
1883
+ createdBy: string;
1884
+ authorId: string;
1885
+ createdAt: string;
1886
+ updatedAt: string;
1887
+ } | {
1888
+ id: string;
1889
+ kind: string;
1890
+ data: {
1891
+ hours: number;
1892
+ note?: undefined;
1893
+ };
1894
+ createdBy: string;
1895
+ authorId: string;
1896
+ createdAt: string;
1897
+ updatedAt: string;
1898
+ })[];
1899
+ } | {
1900
+ name: string;
1901
+ me: string;
1902
+ rows: never[];
1903
+ entries: {
1904
+ writeId: string;
1905
+ appId: string;
1906
+ call: string;
1907
+ writes: ({
1908
+ op: string;
1909
+ id: string;
1910
+ kind: string;
1911
+ data: {
1912
+ hours: number;
1913
+ };
1914
+ } | {
1915
+ op: string;
1916
+ id: string;
1917
+ kind?: undefined;
1918
+ data?: undefined;
1919
+ })[];
1920
+ at: string;
1921
+ state: string;
1922
+ }[];
1923
+ expected: never[];
1924
+ } | {
1925
+ name: string;
1926
+ me: string;
1927
+ rows: {
1928
+ id: string;
1929
+ kind: string;
1930
+ data: {
1931
+ hours: number;
1932
+ };
1933
+ createdBy: string;
1934
+ authorId: string;
1935
+ createdAt: string;
1936
+ updatedAt: string;
1937
+ }[];
1938
+ entries: {
1939
+ writeId: string;
1940
+ appId: string;
1941
+ call: string;
1942
+ writes: {
1943
+ op: string;
1944
+ id: string;
1945
+ kind: string;
1946
+ data: {
1947
+ hours: number;
1948
+ };
1949
+ }[];
1950
+ at: string;
1951
+ state: string;
1952
+ ackedAt: string;
1953
+ }[];
1954
+ expected: {
1955
+ id: string;
1956
+ kind: string;
1957
+ data: {
1958
+ hours: number;
1959
+ };
1960
+ createdBy: string;
1961
+ authorId: string;
1962
+ createdAt: string;
1963
+ updatedAt: string;
1964
+ }[];
1965
+ })[];
1966
+ outcomeCases: ({
1967
+ name: string;
1968
+ entry: {
1969
+ writeId: string;
1970
+ appId: string;
1971
+ call: string;
1972
+ writes: {
1973
+ op: string;
1974
+ id: string;
1975
+ kind: string;
1976
+ data: {
1977
+ hours: number;
1978
+ };
1979
+ }[];
1980
+ at: string;
1981
+ state: string;
1982
+ };
1983
+ result: {
1984
+ ok: boolean;
1985
+ transport?: undefined;
1986
+ code?: undefined;
1987
+ };
1988
+ outcome: string;
1989
+ } | {
1990
+ name: string;
1991
+ entry: {
1992
+ writeId: string;
1993
+ appId: string;
1994
+ call: string;
1995
+ writes: {
1996
+ op: string;
1997
+ id: string;
1998
+ kind: string;
1999
+ data: {
2000
+ hours: number;
2001
+ };
2002
+ }[];
2003
+ at: string;
2004
+ state: string;
2005
+ };
2006
+ result: {
2007
+ transport: boolean;
2008
+ ok?: undefined;
2009
+ code?: undefined;
2010
+ };
2011
+ outcome: string;
2012
+ } | {
2013
+ name: string;
2014
+ entry: {
2015
+ writeId: string;
2016
+ appId: string;
2017
+ call: string;
2018
+ writes: {
2019
+ op: string;
2020
+ id: string;
2021
+ kind: string;
2022
+ data: {
2023
+ hours: number;
2024
+ };
2025
+ }[];
2026
+ at: string;
2027
+ state: string;
2028
+ };
2029
+ result: {
2030
+ code: string;
2031
+ ok?: undefined;
2032
+ transport?: undefined;
2033
+ };
2034
+ outcome: string;
2035
+ } | {
2036
+ name: string;
2037
+ entry: {
2038
+ writeId: string;
2039
+ appId: string;
2040
+ call: string;
2041
+ writes: {
2042
+ op: string;
2043
+ id: string;
2044
+ }[];
2045
+ at: string;
2046
+ state: string;
2047
+ };
2048
+ result: {
2049
+ code: string;
2050
+ ok?: undefined;
2051
+ transport?: undefined;
2052
+ };
2053
+ outcome: string;
2054
+ } | {
2055
+ name: string;
2056
+ entry: {
2057
+ writeId: string;
2058
+ appId: string;
2059
+ call: string;
2060
+ writes: {
2061
+ op: string;
2062
+ id: string;
2063
+ kind: string;
2064
+ data: {
2065
+ hours: string;
2066
+ };
2067
+ }[];
2068
+ at: string;
2069
+ state: string;
2070
+ };
2071
+ result: {
2072
+ code: string;
2073
+ ok?: undefined;
2074
+ transport?: undefined;
2075
+ };
2076
+ outcome: string;
2077
+ })[];
2078
+ flushCases: ({
2079
+ name: string;
2080
+ now: string;
2081
+ entries: {
2082
+ writeId: string;
2083
+ appId: string;
2084
+ call: string;
2085
+ writes: {
2086
+ op: string;
2087
+ id: string;
2088
+ kind: string;
2089
+ data: {
2090
+ hours: number;
2091
+ };
2092
+ }[];
2093
+ at: string;
2094
+ state: string;
2095
+ }[];
2096
+ results: {
2097
+ w1: {
2098
+ ok: boolean;
2099
+ transport?: undefined;
2100
+ code?: undefined;
2101
+ };
2102
+ w2: {
2103
+ ok: boolean;
2104
+ code?: undefined;
2105
+ };
2106
+ w3?: undefined;
2107
+ };
2108
+ sent: string[];
2109
+ refused: never[];
2110
+ after: {
2111
+ writeId: string;
2112
+ appId: string;
2113
+ call: string;
2114
+ writes: {
2115
+ op: string;
2116
+ id: string;
2117
+ kind: string;
2118
+ data: {
2119
+ hours: number;
2120
+ };
2121
+ }[];
2122
+ at: string;
2123
+ state: string;
2124
+ ackedAt: string;
2125
+ }[];
2126
+ } | {
2127
+ name: string;
2128
+ now: string;
2129
+ entries: {
2130
+ writeId: string;
2131
+ appId: string;
2132
+ call: string;
2133
+ writes: {
2134
+ op: string;
2135
+ id: string;
2136
+ kind: string;
2137
+ data: {
2138
+ hours: number;
2139
+ };
2140
+ }[];
2141
+ at: string;
2142
+ state: string;
2143
+ }[];
2144
+ results: {
2145
+ w1: {
2146
+ transport: boolean;
2147
+ ok?: undefined;
2148
+ code?: undefined;
2149
+ };
2150
+ w2: {
2151
+ ok: boolean;
2152
+ code?: undefined;
2153
+ };
2154
+ w3?: undefined;
2155
+ };
2156
+ sent: string[];
2157
+ refused: never[];
2158
+ after: {
2159
+ writeId: string;
2160
+ appId: string;
2161
+ call: string;
2162
+ writes: {
2163
+ op: string;
2164
+ id: string;
2165
+ kind: string;
2166
+ data: {
2167
+ hours: number;
2168
+ };
2169
+ }[];
2170
+ at: string;
2171
+ state: string;
2172
+ }[];
2173
+ } | {
2174
+ name: string;
2175
+ now: string;
2176
+ entries: ({
2177
+ writeId: string;
2178
+ appId: string;
2179
+ call: string;
2180
+ writes: {
2181
+ op: string;
2182
+ id: string;
2183
+ kind: string;
2184
+ data: {
2185
+ hours: string;
2186
+ };
2187
+ }[];
2188
+ at: string;
2189
+ state: string;
2190
+ } | {
2191
+ writeId: string;
2192
+ appId: string;
2193
+ call: string;
2194
+ writes: {
2195
+ op: string;
2196
+ id: string;
2197
+ }[];
2198
+ at: string;
2199
+ state: string;
2200
+ } | {
2201
+ writeId: string;
2202
+ appId: string;
2203
+ call: string;
2204
+ writes: {
2205
+ op: string;
2206
+ id: string;
2207
+ kind: string;
2208
+ data: {
2209
+ hours: number;
2210
+ };
2211
+ }[];
2212
+ at: string;
2213
+ state: string;
2214
+ })[];
2215
+ results: {
2216
+ w1: {
2217
+ code: string;
2218
+ ok?: undefined;
2219
+ transport?: undefined;
2220
+ };
2221
+ w2: {
2222
+ code: string;
2223
+ ok?: undefined;
2224
+ };
2225
+ w3: {
2226
+ ok: boolean;
2227
+ };
2228
+ };
2229
+ sent: string[];
2230
+ refused: {
2231
+ writeId: string;
2232
+ verb: string;
2233
+ }[];
2234
+ after: {
2235
+ writeId: string;
2236
+ appId: string;
2237
+ call: string;
2238
+ writes: {
2239
+ op: string;
2240
+ id: string;
2241
+ kind: string;
2242
+ data: {
2243
+ hours: number;
2244
+ };
2245
+ }[];
2246
+ at: string;
2247
+ state: string;
2248
+ ackedAt: string;
2249
+ }[];
2250
+ } | {
2251
+ name: string;
2252
+ now: string;
2253
+ entries: {
2254
+ writeId: string;
2255
+ appId: string;
2256
+ call: string;
2257
+ writes: {
2258
+ op: string;
2259
+ id: string;
2260
+ kind: string;
2261
+ data: {
2262
+ hours: number;
2263
+ };
2264
+ }[];
2265
+ at: string;
2266
+ state: string;
2267
+ }[];
2268
+ results: {
2269
+ w1: {
2270
+ code: string;
2271
+ ok?: undefined;
2272
+ transport?: undefined;
2273
+ };
2274
+ w2?: undefined;
2275
+ w3?: undefined;
2276
+ };
2277
+ sent: string[];
2278
+ refused: never[];
2279
+ after: never[];
2280
+ } | {
2281
+ name: string;
2282
+ now: string;
2283
+ entries: ({
2284
+ writeId: string;
2285
+ appId: string;
2286
+ call: string;
2287
+ writes: {
2288
+ op: string;
2289
+ id: string;
2290
+ kind: string;
2291
+ data: {
2292
+ hours: number;
2293
+ };
2294
+ }[];
2295
+ at: string;
2296
+ state: string;
2297
+ ackedAt: string;
2298
+ } | {
2299
+ writeId: string;
2300
+ appId: string;
2301
+ call: string;
2302
+ writes: {
2303
+ op: string;
2304
+ id: string;
2305
+ }[];
2306
+ at: string;
2307
+ state: string;
2308
+ ackedAt?: undefined;
2309
+ })[];
2310
+ results: {
2311
+ w2: {
2312
+ ok: boolean;
2313
+ code?: undefined;
2314
+ };
2315
+ w1?: undefined;
2316
+ w3?: undefined;
2317
+ };
2318
+ sent: string[];
2319
+ refused: never[];
2320
+ after: ({
2321
+ writeId: string;
2322
+ appId: string;
2323
+ call: string;
2324
+ writes: {
2325
+ op: string;
2326
+ id: string;
2327
+ kind: string;
2328
+ data: {
2329
+ hours: number;
2330
+ };
2331
+ }[];
2332
+ at: string;
2333
+ state: string;
2334
+ ackedAt: string;
2335
+ } | {
2336
+ writeId: string;
2337
+ appId: string;
2338
+ call: string;
2339
+ writes: {
2340
+ op: string;
2341
+ id: string;
2342
+ }[];
2343
+ at: string;
2344
+ state: string;
2345
+ ackedAt: string;
2346
+ })[];
2347
+ })[];
2348
+ pruneCases: ({
2349
+ name: string;
2350
+ now: string;
2351
+ rows: never[];
2352
+ entries: {
2353
+ writeId: string;
2354
+ appId: string;
2355
+ call: string;
2356
+ writes: {
2357
+ op: string;
2358
+ id: string;
2359
+ kind: string;
2360
+ data: {
2361
+ hours: number;
2362
+ };
2363
+ }[];
2364
+ at: string;
2365
+ state: string;
2366
+ }[];
2367
+ kept: string[];
2368
+ } | {
2369
+ name: string;
2370
+ now: string;
2371
+ rows: {
2372
+ id: string;
2373
+ kind: string;
2374
+ data: {
2375
+ hours: number;
2376
+ note: null;
2377
+ };
2378
+ createdBy: string;
2379
+ authorId: string;
2380
+ createdAt: string;
2381
+ updatedAt: string;
2382
+ }[];
2383
+ entries: {
2384
+ writeId: string;
2385
+ appId: string;
2386
+ call: string;
2387
+ writes: {
2388
+ op: string;
2389
+ id: string;
2390
+ kind: string;
2391
+ data: {
2392
+ hours: number;
2393
+ };
2394
+ }[];
2395
+ at: string;
2396
+ state: string;
2397
+ ackedAt: string;
2398
+ }[];
2399
+ kept: never[];
2400
+ } | {
2401
+ name: string;
2402
+ now: string;
2403
+ rows: {
2404
+ id: string;
2405
+ kind: string;
2406
+ data: {
2407
+ hours: number;
2408
+ };
2409
+ createdBy: string;
2410
+ authorId: string;
2411
+ createdAt: string;
2412
+ updatedAt: string;
2413
+ }[];
2414
+ entries: {
2415
+ writeId: string;
2416
+ appId: string;
2417
+ call: string;
2418
+ writes: {
2419
+ op: string;
2420
+ id: string;
2421
+ kind: string;
2422
+ data: {
2423
+ hours: number;
2424
+ };
2425
+ }[];
2426
+ at: string;
2427
+ state: string;
2428
+ ackedAt: string;
2429
+ }[];
2430
+ kept: string[];
2431
+ } | {
2432
+ name: string;
2433
+ now: string;
2434
+ rows: never[];
2435
+ entries: {
2436
+ writeId: string;
2437
+ appId: string;
2438
+ call: string;
2439
+ writes: {
2440
+ op: string;
2441
+ id: string;
2442
+ }[];
2443
+ at: string;
2444
+ state: string;
2445
+ ackedAt: string;
2446
+ }[];
2447
+ kept: never[];
2448
+ })[];
2449
+ pendingCases: ({
2450
+ name: string;
2451
+ entries: {
2452
+ writeId: string;
2453
+ appId: string;
2454
+ call: string;
2455
+ writes: {
2456
+ op: string;
2457
+ id: string;
2458
+ kind: string;
2459
+ data: {
2460
+ hours: number;
2461
+ };
2462
+ }[];
2463
+ at: string;
2464
+ state: string;
2465
+ ackedAt: string;
2466
+ }[];
2467
+ appId: string;
2468
+ label: null;
2469
+ } | {
2470
+ name: string;
2471
+ entries: ({
2472
+ writeId: string;
2473
+ appId: string;
2474
+ call: string;
2475
+ writes: {
2476
+ op: string;
2477
+ id: string;
2478
+ kind: string;
2479
+ data: {
2480
+ hours: number;
2481
+ };
2482
+ }[];
2483
+ at: string;
2484
+ state: string;
2485
+ } | {
2486
+ writeId: string;
2487
+ appId: string;
2488
+ call: string;
2489
+ writes: {
2490
+ op: string;
2491
+ id: string;
2492
+ }[];
2493
+ at: string;
2494
+ state: string;
2495
+ })[];
2496
+ appId: string;
2497
+ label: string;
2498
+ })[];
2499
+ };
2500
+ export declare const APP_OUTBOX_COPY: {
2501
+ pendingOne: string;
2502
+ pending: string;
2503
+ };
2504
+ export type OutboxCall = `upsert` | `delete` | `batch`;
2505
+ export type OutboxWrite = {
2506
+ op: `create` | `update`;
2507
+ id: string;
2508
+ kind: string;
2509
+ data: Record<string, unknown>;
2510
+ } | {
2511
+ op: `delete`;
2512
+ id: string;
2513
+ };
2514
+ export interface OutboxEntry {
2515
+ writeId: string;
2516
+ appId: string;
2517
+ call: OutboxCall;
2518
+ writes: OutboxWrite[];
2519
+ /** ISO time the write was made. */
2520
+ at: string;
2521
+ state: `pending` | `acked`;
2522
+ ackedAt?: string | null;
2523
+ }
2524
+ /** A replay's answer: ok, no network, or the server's tRPC code. */
2525
+ export type OutboxResult = {
2526
+ ok: true;
2527
+ } | {
2528
+ transport: true;
2529
+ } | {
2530
+ code: string;
2531
+ };
2532
+ export type OutboxOutcome = `done` | `retry` | `dropped` | `refused`;
2533
+ type Obj = Record<string, unknown>;
2534
+ /** A host call's writes (`writesCases`): a create takes the next client id. */
2535
+ export declare function outboxWrites(call: OutboxCall, args: Obj, newIds: readonly string[]): OutboxWrite[];
2536
+ /** The replay request of an entry (`requestCases`); the host adds the app. */
2537
+ export declare function outboxRequest(entry: OutboxEntry): {
2538
+ call: OutboxCall;
2539
+ input: Obj;
2540
+ };
2541
+ /** The visible rows: the synced rows with every entry laid over them, oldest
2542
+ * first (`rowsCases`). */
2543
+ export declare function outboxRows(rows: readonly AppRecordRow[], entries: readonly OutboxEntry[], me: string | null): AppRecordRow[];
2544
+ /** What a replay's answer does to its entry (`outcomeCases`). */
2545
+ export declare function outboxOutcome(entry: OutboxEntry, result: OutboxResult): OutboxOutcome;
2546
+ /** The failed-action toast's verb for a refused entry. */
2547
+ export declare function outboxVerb(entry: OutboxEntry): `save` | `delete`;
2548
+ /** One flush (`flushCases`): pending entries oldest first, one at a time;
2549
+ * a retry stops it; `results` = each write id's answer. */
2550
+ export declare function outboxFlush(entries: readonly OutboxEntry[], results: Record<string, OutboxResult>, now: string): {
2551
+ sent: string[];
2552
+ refused: {
2553
+ writeId: string;
2554
+ verb: `save` | `delete`;
2555
+ }[];
2556
+ after: OutboxEntry[];
2557
+ };
2558
+ /** Do the synced rows reflect an entry? */
2559
+ export declare function outboxReflected(entry: OutboxEntry, rows: readonly AppRecordRow[]): boolean;
2560
+ /** The entries that stay (`pruneCases`): pending ones, and acked ones the
2561
+ * rows don't reflect yet within the grace. */
2562
+ export declare function outboxPrune(entries: readonly OutboxEntry[], rows: readonly AppRecordRow[], now: string): OutboxEntry[];
2563
+ /** The header glyph's label for an app's pending entries (`pendingCases`);
2564
+ * null = no glyph. */
2565
+ export declare function outboxPendingLabel(entries: readonly OutboxEntry[], appId: string): string | null;
2566
+ export declare const APP_CSV_IMPORT: {
2567
+ $comment: string;
2568
+ maxRows: number;
2569
+ previewRows: number;
2570
+ issuesShown: number;
2571
+ trueWords: string[];
2572
+ falseWords: string[];
2573
+ authorKeys: string[];
2574
+ copy: {
2575
+ importButton: string;
2576
+ title: string;
2577
+ placeholder: string;
2578
+ chooseFile: string;
2579
+ skip: string;
2580
+ me: string;
2581
+ column: string;
2582
+ issue: string;
2583
+ rowIssue: string;
2584
+ moreIssues: string;
2585
+ ready: string;
2586
+ tooMany: string;
2587
+ noRows: string;
2588
+ importAction: string;
2589
+ imported: string;
2590
+ };
2591
+ issues: {
2592
+ notNumber: string;
2593
+ notInteger: string;
2594
+ notBoolean: string;
2595
+ notDate: string;
2596
+ slashDate: string;
2597
+ notTime: string;
2598
+ notDateTime: string;
2599
+ notEnum: string;
2600
+ notMember: string;
2601
+ extraCells: string;
2602
+ };
2603
+ testIds: {
2604
+ button: string;
2605
+ dialog: string;
2606
+ text: string;
2607
+ file: string;
2608
+ map: string;
2609
+ author: string;
2610
+ preview: string;
2611
+ error: string;
2612
+ confirm: string;
2613
+ };
2614
+ parseCases: {
2615
+ name: string;
2616
+ text: string;
2617
+ header: string[];
2618
+ rows: {
2619
+ row: number;
2620
+ cells: string[];
2621
+ }[];
2622
+ }[];
2623
+ mapCases: ({
2624
+ name: string;
2625
+ fields: string[];
2626
+ header: string[];
2627
+ mapping: {
2628
+ date: number;
2629
+ hours: number;
2630
+ note: number;
2631
+ hoursbilled?: undefined;
2632
+ issueRef?: undefined;
2633
+ billable?: undefined;
2634
+ stunden?: undefined;
2635
+ groesse?: undefined;
2636
+ };
2637
+ } | {
2638
+ name: string;
2639
+ fields: string[];
2640
+ header: string[];
2641
+ mapping: {
2642
+ date: number;
2643
+ hours: number;
2644
+ note?: undefined;
2645
+ hoursbilled?: undefined;
2646
+ issueRef?: undefined;
2647
+ billable?: undefined;
2648
+ stunden?: undefined;
2649
+ groesse?: undefined;
2650
+ };
2651
+ } | {
2652
+ name: string;
2653
+ fields: string[];
2654
+ header: string[];
2655
+ mapping: {
2656
+ hours: null;
2657
+ date?: undefined;
2658
+ note?: undefined;
2659
+ hoursbilled?: undefined;
2660
+ issueRef?: undefined;
2661
+ billable?: undefined;
2662
+ stunden?: undefined;
2663
+ groesse?: undefined;
2664
+ };
2665
+ } | {
2666
+ name: string;
2667
+ fields: string[];
2668
+ header: string[];
2669
+ mapping: {
2670
+ hours: number;
2671
+ hoursbilled: number;
2672
+ date?: undefined;
2673
+ note?: undefined;
2674
+ issueRef?: undefined;
2675
+ billable?: undefined;
2676
+ stunden?: undefined;
2677
+ groesse?: undefined;
2678
+ };
2679
+ } | {
2680
+ name: string;
2681
+ fields: string[];
2682
+ header: string[];
2683
+ mapping: {
2684
+ issueRef: number;
2685
+ billable: number;
2686
+ date?: undefined;
2687
+ hours?: undefined;
2688
+ note?: undefined;
2689
+ hoursbilled?: undefined;
2690
+ stunden?: undefined;
2691
+ groesse?: undefined;
2692
+ };
2693
+ } | {
2694
+ name: string;
2695
+ fields: string[];
2696
+ header: string[];
2697
+ mapping: {
2698
+ stunden: number;
2699
+ groesse: null;
2700
+ date?: undefined;
2701
+ hours?: undefined;
2702
+ note?: undefined;
2703
+ hoursbilled?: undefined;
2704
+ issueRef?: undefined;
2705
+ billable?: undefined;
2706
+ };
2707
+ } | {
2708
+ name: string;
2709
+ fields: string[];
2710
+ header: never[];
2711
+ mapping: {
2712
+ date: null;
2713
+ hours?: undefined;
2714
+ note?: undefined;
2715
+ hoursbilled?: undefined;
2716
+ issueRef?: undefined;
2717
+ billable?: undefined;
2718
+ stunden?: undefined;
2719
+ groesse?: undefined;
2720
+ };
2721
+ })[];
2722
+ authorColumnCases: ({
2723
+ header: string[];
2724
+ column: number;
2725
+ } | {
2726
+ header: string[];
2727
+ column: null;
2728
+ })[];
2729
+ cellCases: ({
2730
+ name: string;
2731
+ field: {
2732
+ type: string;
2733
+ enum?: undefined;
2734
+ format?: undefined;
2735
+ items?: undefined;
2736
+ };
2737
+ cell: string;
2738
+ value: null;
2739
+ issue?: undefined;
2740
+ } | {
2741
+ name: string;
2742
+ field: {
2743
+ type: string;
2744
+ enum?: undefined;
2745
+ format?: undefined;
2746
+ items?: undefined;
2747
+ };
2748
+ cell: string;
2749
+ value: string;
2750
+ issue?: undefined;
2751
+ } | {
2752
+ name: string;
2753
+ field: {
2754
+ type: string;
2755
+ enum?: undefined;
2756
+ format?: undefined;
2757
+ items?: undefined;
2758
+ };
2759
+ cell: string;
2760
+ value: number;
2761
+ issue?: undefined;
2762
+ } | {
2763
+ name: string;
2764
+ field: {
2765
+ type: string;
2766
+ enum?: undefined;
2767
+ format?: undefined;
2768
+ items?: undefined;
2769
+ };
2770
+ cell: string;
2771
+ issue: string;
2772
+ value?: undefined;
2773
+ } | {
2774
+ name: string;
2775
+ field: {
2776
+ type: string;
2777
+ enum?: undefined;
2778
+ format?: undefined;
2779
+ items?: undefined;
2780
+ };
2781
+ cell: string;
2782
+ value: boolean;
2783
+ issue?: undefined;
2784
+ } | {
2785
+ name: string;
2786
+ field: {
2787
+ type: string;
2788
+ enum: string[];
2789
+ format?: undefined;
2790
+ items?: undefined;
2791
+ };
2792
+ cell: string;
2793
+ value: string;
2794
+ issue?: undefined;
2795
+ } | {
2796
+ name: string;
2797
+ field: {
2798
+ type: string;
2799
+ enum: string[];
2800
+ format?: undefined;
2801
+ items?: undefined;
2802
+ };
2803
+ cell: string;
2804
+ issue: string;
2805
+ value?: undefined;
2806
+ } | {
2807
+ name: string;
2808
+ field: {
2809
+ type: string;
2810
+ format: string;
2811
+ enum?: undefined;
2812
+ items?: undefined;
2813
+ };
2814
+ cell: string;
2815
+ value: string;
2816
+ issue?: undefined;
2817
+ } | {
2818
+ name: string;
2819
+ field: {
2820
+ type: string;
2821
+ format: string;
2822
+ enum?: undefined;
2823
+ items?: undefined;
2824
+ };
2825
+ cell: string;
2826
+ issue: string;
2827
+ value?: undefined;
2828
+ } | {
2829
+ name: string;
2830
+ field: {
2831
+ type: string;
2832
+ items: {
2833
+ type: string;
2834
+ };
2835
+ enum?: undefined;
2836
+ format?: undefined;
2837
+ };
2838
+ cell: string;
2839
+ value: string[];
2840
+ issue?: undefined;
2841
+ } | {
2842
+ name: string;
2843
+ field: {
2844
+ type: string;
2845
+ items: {
2846
+ type: string;
2847
+ };
2848
+ enum?: undefined;
2849
+ format?: undefined;
2850
+ };
2851
+ cell: string;
2852
+ value: number[];
2853
+ issue?: undefined;
2854
+ } | {
2855
+ name: string;
2856
+ field: {
2857
+ type: string;
2858
+ items: {
2859
+ type: string;
2860
+ };
2861
+ enum?: undefined;
2862
+ format?: undefined;
2863
+ };
2864
+ cell: string;
2865
+ issue: string;
2866
+ value?: undefined;
2867
+ } | {
2868
+ name: string;
2869
+ field: {
2870
+ type: string;
2871
+ items: {
2872
+ type: string;
2873
+ };
2874
+ enum?: undefined;
2875
+ format?: undefined;
2876
+ };
2877
+ cell: string;
2878
+ value: null;
2879
+ issue?: undefined;
2880
+ })[];
2881
+ rowsCases: ({
2882
+ name: string;
2883
+ schema: {
2884
+ type: string;
2885
+ properties: {
2886
+ date: {
2887
+ type: string;
2888
+ format: string;
2889
+ };
2890
+ hours: {
2891
+ type: string;
2892
+ };
2893
+ note: {
2894
+ type: string;
2895
+ };
2896
+ kind: {
2897
+ type: string;
2898
+ enum: string[];
2899
+ };
2900
+ tags: {
2901
+ type: string;
2902
+ items: {
2903
+ type: string;
2904
+ };
2905
+ };
2906
+ };
2907
+ required: string[];
2908
+ };
2909
+ header: string[];
2910
+ rows: {
2911
+ row: number;
2912
+ cells: string[];
2913
+ }[];
2914
+ mapping: {
2915
+ date: number;
2916
+ hours: number;
2917
+ kind: number;
2918
+ note: number;
2919
+ tags: number;
2920
+ };
2921
+ records: ({
2922
+ row: number;
2923
+ data: {
2924
+ date: string;
2925
+ hours: number;
2926
+ kind: string;
2927
+ note: string;
2928
+ tags: string[];
2929
+ };
2930
+ issues: never[];
2931
+ } | {
2932
+ row: number;
2933
+ data: {
2934
+ date: string;
2935
+ kind: string;
2936
+ hours?: undefined;
2937
+ note?: undefined;
2938
+ tags?: undefined;
2939
+ };
2940
+ issues: never[];
2941
+ } | {
2942
+ row: number;
2943
+ data: {
2944
+ note: string;
2945
+ date?: undefined;
2946
+ hours?: undefined;
2947
+ kind?: undefined;
2948
+ tags?: undefined;
2949
+ };
2950
+ issues: string[];
2951
+ } | {
2952
+ row: number;
2953
+ data: {
2954
+ date: string;
2955
+ hours: number;
2956
+ kind?: undefined;
2957
+ note?: undefined;
2958
+ tags?: undefined;
2959
+ };
2960
+ issues: never[];
2961
+ })[];
2962
+ author?: undefined;
2963
+ } | {
2964
+ name: string;
2965
+ schema: {
2966
+ type: string;
2967
+ properties: {
2968
+ date: {
2969
+ type: string;
2970
+ format: string;
2971
+ };
2972
+ hours: {
2973
+ type: string;
2974
+ };
2975
+ note: {
2976
+ type: string;
2977
+ };
2978
+ kind: {
2979
+ type: string;
2980
+ enum: string[];
2981
+ };
2982
+ tags: {
2983
+ type: string;
2984
+ items: {
2985
+ type: string;
2986
+ };
2987
+ };
2988
+ };
2989
+ required: string[];
2990
+ };
2991
+ header: string[];
2992
+ rows: {
2993
+ row: number;
2994
+ cells: string[];
2995
+ }[];
2996
+ mapping: {
2997
+ date: number;
2998
+ hours: number;
2999
+ note: null;
3000
+ kind: null;
3001
+ tags: null;
3002
+ };
3003
+ records: {
3004
+ row: number;
3005
+ data: {
3006
+ date: string;
3007
+ hours: number;
3008
+ };
3009
+ issues: string[];
3010
+ }[];
3011
+ author?: undefined;
3012
+ } | {
3013
+ name: string;
3014
+ schema: {
3015
+ type: string;
3016
+ properties: {
3017
+ date: {
3018
+ type: string;
3019
+ format: string;
3020
+ };
3021
+ hours: {
3022
+ type: string;
3023
+ };
3024
+ note: {
3025
+ type: string;
3026
+ };
3027
+ kind: {
3028
+ type: string;
3029
+ enum: string[];
3030
+ };
3031
+ tags: {
3032
+ type: string;
3033
+ items: {
3034
+ type: string;
3035
+ };
3036
+ };
3037
+ };
3038
+ required: string[];
3039
+ };
3040
+ header: string[];
3041
+ rows: {
3042
+ row: number;
3043
+ cells: string[];
3044
+ }[];
3045
+ mapping: {
3046
+ date: number;
3047
+ hours: number;
3048
+ kind: null;
3049
+ note: null;
3050
+ tags: null;
3051
+ };
3052
+ author: {
3053
+ column: number;
3054
+ importer: string;
3055
+ members: {
3056
+ id: string;
3057
+ name: string;
3058
+ email: string;
3059
+ }[];
3060
+ };
3061
+ records: ({
3062
+ row: number;
3063
+ data: {
3064
+ date: string;
3065
+ hours: number;
3066
+ };
3067
+ issues: never[];
3068
+ author: string;
3069
+ } | {
3070
+ row: number;
3071
+ data: {
3072
+ date: string;
3073
+ hours: number;
3074
+ };
3075
+ issues: string[];
3076
+ author?: undefined;
3077
+ })[];
3078
+ })[];
3079
+ };
3080
+ export declare const APP_CSV_COPY: {
3081
+ importButton: string;
3082
+ title: string;
3083
+ placeholder: string;
3084
+ chooseFile: string;
3085
+ skip: string;
3086
+ me: string;
3087
+ column: string;
3088
+ issue: string;
3089
+ rowIssue: string;
3090
+ moreIssues: string;
3091
+ ready: string;
3092
+ tooMany: string;
3093
+ noRows: string;
3094
+ importAction: string;
3095
+ imported: string;
3096
+ };
3097
+ export interface CsvRow {
3098
+ /** The record number (header = 1, blank lines counted). */
3099
+ row: number;
3100
+ cells: string[];
3101
+ }
3102
+ export interface CsvTable {
3103
+ header: string[];
3104
+ rows: CsvRow[];
3105
+ }
3106
+ /** RFC 4180 → the header + the data rows (`parseCases`). */
3107
+ export declare function csvParse(input: string): CsvTable;
3108
+ /** A name's matching key: lowercased, only ASCII a–z and 0–9. */
3109
+ export declare function csvKey(name: string): string;
3110
+ /** The first pick per field (`mapCases`): equal keys first, then the ONE
3111
+ * free column containing the field's key; a column maps at most once. */
3112
+ export declare function csvAutoMap(fields: readonly string[], header: readonly string[]): Record<string, number | null>;
3113
+ /** The owner's Author pick: the first column whose key is an `authorKeys` entry, else null (= Me). */
3114
+ export declare function csvAuthorColumn(header: readonly string[]): number | null;
3115
+ export type CsvCell = {
3116
+ ok: true;
3117
+ value: unknown;
3118
+ } | {
3119
+ ok: false;
3120
+ message: string;
3121
+ };
3122
+ /** One cell → the field's value (`cellCases`); empty = null. */
3123
+ export declare function csvCell(field: DataField, cell: string): CsvCell;
3124
+ export interface CsvMember {
3125
+ id: string;
3126
+ name: string;
3127
+ email: string;
3128
+ }
3129
+ export interface CsvAuthor {
3130
+ /** The Author column (null = every row is the importer's). */
3131
+ column: number | null;
3132
+ importer: string;
3133
+ members: readonly CsvMember[];
3134
+ }
3135
+ export interface CsvRecord {
3136
+ row: number;
3137
+ data: Record<string, unknown>;
3138
+ /** A member's id when the row is someone else's (an on-behalf write). */
3139
+ author?: string;
3140
+ issues: string[];
3141
+ }
3142
+ /** The rows → records + their issues (`rowsCases`), before the host's schema check. */
3143
+ export declare function csvRecords(schema: DataSchema, header: readonly string[], rows: readonly CsvRow[], mapping: Readonly<Record<string, number | null>>, author?: CsvAuthor): CsvRecord[];
3144
+ /** The preview's count line (`copy.ready`). */
3145
+ export declare function csvSummary(records: readonly {
3146
+ issues: readonly string[];
3147
+ }[]): string;
3148
+ export {};