@coffre/client 0.0.0 → 0.1.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.
@@ -0,0 +1,1722 @@
1
+ //#region src/api.d.ts
2
+ /** Every route, by `METHOD /path`: what a caller sends (the body, or the query of a GET) and gets back. */
3
+ type Api = {
4
+ "GET /me": {
5
+ input: undefined;
6
+ output: {
7
+ principal: {
8
+ type: "service" | "user";
9
+ id: string;
10
+ };
11
+ registered: boolean;
12
+ tampered: boolean;
13
+ instanceRole: "owner" | "root-admin" | "user";
14
+ isRootAdmin: boolean;
15
+ canReadAudit: boolean;
16
+ environments: {
17
+ project: string;
18
+ environment: string;
19
+ permissions: ("audit.read" | "environment.manage" | "grant.manage" | "project.manage" | "secret.archive" | "secret.read" | "secret.write")[];
20
+ }[];
21
+ };
22
+ };
23
+ "GET /projects": {
24
+ input: undefined;
25
+ output: {
26
+ projects: {
27
+ slug: string;
28
+ name: string;
29
+ archivedAt: string | null;
30
+ permissions: ("audit.read" | "environment.manage" | "grant.manage" | "project.manage" | "secret.archive" | "secret.read" | "secret.write")[];
31
+ environments: {
32
+ slug: string;
33
+ name: string;
34
+ accessible: boolean;
35
+ details: null | {
36
+ archivedAt: string | null;
37
+ secretCount: number | null;
38
+ };
39
+ }[];
40
+ }[];
41
+ };
42
+ };
43
+ "PUT /projects/:project": {
44
+ input: {
45
+ name: string;
46
+ };
47
+ output: {
48
+ project: {
49
+ slug: string;
50
+ name: string;
51
+ archivedAt: string | null;
52
+ };
53
+ created: boolean;
54
+ };
55
+ };
56
+ "PATCH /projects/:project": {
57
+ input: {
58
+ name?: string;
59
+ slug?: string;
60
+ archived?: boolean;
61
+ };
62
+ output: {
63
+ project: {
64
+ slug: string;
65
+ name: string;
66
+ archivedAt: string | null;
67
+ };
68
+ };
69
+ };
70
+ "PUT /projects/:project/:environment": {
71
+ input: {
72
+ name: string;
73
+ };
74
+ output: {
75
+ environment: {
76
+ slug: string;
77
+ name: string;
78
+ archivedAt: string | null;
79
+ };
80
+ created: boolean;
81
+ };
82
+ };
83
+ "PATCH /projects/:project/:environment": {
84
+ input: {
85
+ name?: string;
86
+ slug?: string;
87
+ archived?: boolean;
88
+ };
89
+ output: {
90
+ environment: {
91
+ slug: string;
92
+ name: string;
93
+ archivedAt: string | null;
94
+ };
95
+ };
96
+ };
97
+ "GET /secrets/:project/:environment": {
98
+ input: undefined;
99
+ output: {
100
+ permissions: ("audit.read" | "environment.manage" | "grant.manage" | "project.manage" | "secret.archive" | "secret.read" | "secret.write")[];
101
+ keys: {
102
+ key: string;
103
+ archived: boolean;
104
+ version: number | null;
105
+ updatedAt: string | null;
106
+ updatedBy: string | null;
107
+ }[];
108
+ };
109
+ };
110
+ "PATCH /secrets/:project/:environment": {
111
+ input: {
112
+ [key: string]: string | null;
113
+ };
114
+ output: {
115
+ operationId: string;
116
+ keys: {
117
+ [key: string]: {
118
+ version: number;
119
+ } | {
120
+ archived: true;
121
+ };
122
+ };
123
+ } | {
124
+ dryRun: true;
125
+ keys: {
126
+ [key: string]: "added" | "archived" | "changed" | "unchanged";
127
+ };
128
+ };
129
+ };
130
+ "PATCH /secrets/:project/:environment/:key": {
131
+ input: {
132
+ key?: string;
133
+ archived?: boolean;
134
+ };
135
+ output: {
136
+ key: string;
137
+ archived: boolean;
138
+ };
139
+ };
140
+ "GET /secrets/:project/:environment/:key/versions": {
141
+ input: undefined;
142
+ output: {
143
+ key: string;
144
+ archived: boolean;
145
+ versions: {
146
+ version: number;
147
+ createdAt: string;
148
+ createdBy: string;
149
+ current: boolean;
150
+ kek: string;
151
+ }[];
152
+ };
153
+ };
154
+ "POST /secrets/:project/:environment/:key/restore": {
155
+ input: {
156
+ version: number;
157
+ };
158
+ output: {
159
+ key: string;
160
+ version: number;
161
+ };
162
+ };
163
+ "POST /reveals": {
164
+ input: {
165
+ path: string;
166
+ };
167
+ output: {
168
+ operationId: string;
169
+ values: {
170
+ [key: string]: string;
171
+ };
172
+ };
173
+ };
174
+ "GET /members": {
175
+ input: {
176
+ path?: string;
177
+ };
178
+ output: {
179
+ members: {
180
+ member: string;
181
+ principalType: "service" | "user";
182
+ principalId: string;
183
+ instanceRole: "owner" | "root-admin" | "user";
184
+ isRootAdmin: boolean;
185
+ tampered: boolean;
186
+ grants: {
187
+ id: string;
188
+ project: string;
189
+ environment: string | null;
190
+ role: "access-manager" | "auditor" | "developer" | "maintainer" | "owner" | "viewer";
191
+ roleName: string;
192
+ permissions: ("audit.read" | "environment.manage" | "grant.manage" | "project.manage" | "secret.archive" | "secret.read" | "secret.write")[];
193
+ expiresAt: string | null;
194
+ }[];
195
+ }[];
196
+ removed: {
197
+ principalType: "service" | "user";
198
+ principalId: string;
199
+ toRotate: number;
200
+ }[];
201
+ };
202
+ };
203
+ "GET /members/:member": {
204
+ input: undefined;
205
+ output: {
206
+ principalType: "service" | "user";
207
+ principalId: string;
208
+ status: "active" | "removed" | "tampered";
209
+ instanceRole: "owner" | "root-admin" | "user";
210
+ isRootAdmin: boolean;
211
+ removedAt: string | null;
212
+ removedBy: string | null;
213
+ live: {
214
+ grants: number;
215
+ sessions: number;
216
+ tokens: number;
217
+ identities: number;
218
+ };
219
+ exposed: {
220
+ project: string;
221
+ environment: string;
222
+ key: string;
223
+ version: number;
224
+ how: "read" | "wrote";
225
+ at: string;
226
+ }[];
227
+ rotated: number;
228
+ issuedTokens: {
229
+ id: string;
230
+ service: string;
231
+ label: string | null;
232
+ hint: string;
233
+ expiresAt: string;
234
+ lastUsedAt: string | null;
235
+ }[];
236
+ syncs: {
237
+ id: string;
238
+ provider: string;
239
+ providerLabel: string;
240
+ brand: "cloudflare" | "github" | "other" | "railway" | "vercel";
241
+ offered: boolean;
242
+ destination: string;
243
+ config: {
244
+ [key: string]: string | number | boolean | null | Json[] | {
245
+ [key: string]: Json;
246
+ };
247
+ };
248
+ credential: string;
249
+ createdAt: string;
250
+ createdBy: string;
251
+ paused: boolean;
252
+ running: boolean;
253
+ lastRunAt: string | null;
254
+ lastStatus: "failed" | "ok" | "partial" | null;
255
+ lastError: string | null;
256
+ synced: number;
257
+ pending: number;
258
+ skipped: {
259
+ key: string;
260
+ reason: string;
261
+ }[];
262
+ project: string;
263
+ environment: string;
264
+ }[];
265
+ };
266
+ };
267
+ "PUT /members/:member": {
268
+ input: {
269
+ owner?: boolean;
270
+ };
271
+ output: {
272
+ member: string;
273
+ instanceRole: "owner" | "user";
274
+ created: boolean;
275
+ };
276
+ };
277
+ "DELETE /members/:member": {
278
+ input: undefined;
279
+ output: {
280
+ revoked: {
281
+ grants: number;
282
+ sessions: number;
283
+ tokens: number;
284
+ identities: number;
285
+ };
286
+ report: {
287
+ principalType: "service" | "user";
288
+ principalId: string;
289
+ status: "active" | "removed" | "tampered";
290
+ instanceRole: "owner" | "root-admin" | "user";
291
+ isRootAdmin: boolean;
292
+ removedAt: string | null;
293
+ removedBy: string | null;
294
+ live: {
295
+ grants: number;
296
+ sessions: number;
297
+ tokens: number;
298
+ identities: number;
299
+ };
300
+ exposed: {
301
+ project: string;
302
+ environment: string;
303
+ key: string;
304
+ version: number;
305
+ how: "read" | "wrote";
306
+ at: string;
307
+ }[];
308
+ rotated: number;
309
+ issuedTokens: {
310
+ id: string;
311
+ service: string;
312
+ label: string | null;
313
+ hint: string;
314
+ expiresAt: string;
315
+ lastUsedAt: string | null;
316
+ }[];
317
+ syncs: {
318
+ id: string;
319
+ provider: string;
320
+ providerLabel: string;
321
+ brand: "cloudflare" | "github" | "other" | "railway" | "vercel";
322
+ offered: boolean;
323
+ destination: string;
324
+ config: {
325
+ [key: string]: string | number | boolean | null | Json[] | {
326
+ [key: string]: Json;
327
+ };
328
+ };
329
+ credential: string;
330
+ createdAt: string;
331
+ createdBy: string;
332
+ paused: boolean;
333
+ running: boolean;
334
+ lastRunAt: string | null;
335
+ lastStatus: "failed" | "ok" | "partial" | null;
336
+ lastError: string | null;
337
+ synced: number;
338
+ pending: number;
339
+ skipped: {
340
+ key: string;
341
+ reason: string;
342
+ }[];
343
+ project: string;
344
+ environment: string;
345
+ }[];
346
+ };
347
+ };
348
+ };
349
+ "GET /members/:member/tokens": {
350
+ input: undefined;
351
+ output: {
352
+ tokens: {
353
+ id: string;
354
+ label: string | null;
355
+ hint: string;
356
+ createdAt: string;
357
+ createdBy: string;
358
+ expiresAt: string;
359
+ lastUsedAt: string | null;
360
+ lastUsedIp: string | null;
361
+ }[];
362
+ };
363
+ };
364
+ "POST /members/:member/tokens": {
365
+ input: {
366
+ expiresInDays: number;
367
+ label?: string | null;
368
+ };
369
+ output: {
370
+ id: string;
371
+ token: string;
372
+ expiresAt: string;
373
+ };
374
+ };
375
+ "DELETE /members/:member/tokens/:id": {
376
+ input: undefined;
377
+ output: {
378
+ revoked: true;
379
+ };
380
+ };
381
+ "PATCH /access/:member": {
382
+ input: {
383
+ [key: string]: "access-manager" | "auditor" | "developer" | "maintainer" | "owner" | "viewer" | null | {
384
+ role: "access-manager" | "auditor" | "developer" | "maintainer" | "owner" | "viewer";
385
+ until: string | null;
386
+ };
387
+ };
388
+ output: {
389
+ changes: {
390
+ [key: string]: "created" | "revoked" | "unchanged" | "updated";
391
+ };
392
+ };
393
+ };
394
+ "GET /sessions": {
395
+ input: undefined;
396
+ output: {
397
+ sessions: {
398
+ id: string;
399
+ kind: "browser" | "cli";
400
+ label: string | null;
401
+ hint: string;
402
+ provider: string | null;
403
+ createdAt: string;
404
+ expiresAt: string;
405
+ lastUsedAt: string | null;
406
+ lastUsedIp: string | null;
407
+ current: boolean;
408
+ }[];
409
+ };
410
+ };
411
+ "DELETE /sessions/:id": {
412
+ input: undefined;
413
+ output: {
414
+ revoked: true;
415
+ };
416
+ };
417
+ "GET /identities": {
418
+ input: undefined;
419
+ output: {
420
+ identities: {
421
+ id: string;
422
+ provider: string;
423
+ email: string | null;
424
+ createdAt: string;
425
+ lastSignInAt: string | null;
426
+ }[];
427
+ };
428
+ };
429
+ "DELETE /identities/:id": {
430
+ input: undefined;
431
+ output: {
432
+ unlinked: true;
433
+ };
434
+ };
435
+ "GET /device-logins/:code": {
436
+ input: undefined;
437
+ output: {
438
+ request: null | {
439
+ userCode: string;
440
+ clientLabel: string | null;
441
+ clientIp: string | null;
442
+ createdAt: string;
443
+ expiresAt: string;
444
+ };
445
+ sessionDays: number;
446
+ };
447
+ };
448
+ "POST /device-logins/:code": {
449
+ input: {
450
+ approve: boolean;
451
+ };
452
+ output: {
453
+ decided: true;
454
+ };
455
+ };
456
+ "GET /syncs/providers": {
457
+ input: undefined;
458
+ output: {
459
+ providers: {
460
+ brand: "cloudflare" | "github" | "other" | "railway" | "vercel";
461
+ id: string;
462
+ credential: {
463
+ placeholder: string;
464
+ hint: string;
465
+ };
466
+ label: string;
467
+ fields: ({
468
+ type: "text";
469
+ name: string;
470
+ label: string;
471
+ placeholder: string;
472
+ optional?: boolean;
473
+ hint?: string;
474
+ when?: {
475
+ field: string;
476
+ is: string[];
477
+ };
478
+ } | {
479
+ type: "options";
480
+ name: string;
481
+ label: string;
482
+ options: {
483
+ value: string;
484
+ label: string;
485
+ }[];
486
+ multiple: boolean;
487
+ initial: string[];
488
+ hint?: string;
489
+ })[];
490
+ }[];
491
+ };
492
+ };
493
+ "GET /syncs/:project/:environment": {
494
+ input: undefined;
495
+ output: {
496
+ syncs: {
497
+ id: string;
498
+ provider: string;
499
+ providerLabel: string;
500
+ brand: "cloudflare" | "github" | "other" | "railway" | "vercel";
501
+ offered: boolean;
502
+ destination: string;
503
+ config: {
504
+ [key: string]: string | number | boolean | null | Json[] | {
505
+ [key: string]: Json;
506
+ };
507
+ };
508
+ credential: string;
509
+ createdAt: string;
510
+ createdBy: string;
511
+ paused: boolean;
512
+ running: boolean;
513
+ lastRunAt: string | null;
514
+ lastStatus: "failed" | "ok" | "partial" | null;
515
+ lastError: string | null;
516
+ synced: number;
517
+ pending: number;
518
+ skipped: {
519
+ key: string;
520
+ reason: string;
521
+ }[];
522
+ }[];
523
+ canManage: boolean;
524
+ };
525
+ };
526
+ "POST /syncs/:project/:environment": {
527
+ input: {
528
+ provider: string;
529
+ config: {
530
+ [key: string]: unknown;
531
+ };
532
+ credential: string;
533
+ };
534
+ output: {
535
+ id: string;
536
+ provider: string;
537
+ providerLabel: string;
538
+ brand: "cloudflare" | "github" | "other" | "railway" | "vercel";
539
+ offered: boolean;
540
+ destination: string;
541
+ config: {
542
+ [key: string]: string | number | boolean | null | Json[] | {
543
+ [key: string]: Json;
544
+ };
545
+ };
546
+ credential: string;
547
+ createdAt: string;
548
+ createdBy: string;
549
+ paused: boolean;
550
+ running: boolean;
551
+ lastRunAt: string | null;
552
+ lastStatus: "failed" | "ok" | "partial" | null;
553
+ lastError: string | null;
554
+ synced: number;
555
+ pending: number;
556
+ skipped: {
557
+ key: string;
558
+ reason: string;
559
+ }[];
560
+ };
561
+ };
562
+ "PATCH /syncs/by-id/:id": {
563
+ input: {
564
+ paused: boolean;
565
+ };
566
+ output: {
567
+ id: string;
568
+ provider: string;
569
+ providerLabel: string;
570
+ brand: "cloudflare" | "github" | "other" | "railway" | "vercel";
571
+ offered: boolean;
572
+ destination: string;
573
+ config: {
574
+ [key: string]: string | number | boolean | null | Json[] | {
575
+ [key: string]: Json;
576
+ };
577
+ };
578
+ credential: string;
579
+ createdAt: string;
580
+ createdBy: string;
581
+ paused: boolean;
582
+ running: boolean;
583
+ lastRunAt: string | null;
584
+ lastStatus: "failed" | "ok" | "partial" | null;
585
+ lastError: string | null;
586
+ synced: number;
587
+ pending: number;
588
+ skipped: {
589
+ key: string;
590
+ reason: string;
591
+ }[];
592
+ };
593
+ };
594
+ "DELETE /syncs/by-id/:id": {
595
+ input: undefined;
596
+ output: {
597
+ id: string;
598
+ provider: string;
599
+ providerLabel: string;
600
+ brand: "cloudflare" | "github" | "other" | "railway" | "vercel";
601
+ offered: boolean;
602
+ destination: string;
603
+ config: {
604
+ [key: string]: string | number | boolean | null | Json[] | {
605
+ [key: string]: Json;
606
+ };
607
+ };
608
+ credential: string;
609
+ createdAt: string;
610
+ createdBy: string;
611
+ paused: boolean;
612
+ running: boolean;
613
+ lastRunAt: string | null;
614
+ lastStatus: "failed" | "ok" | "partial" | null;
615
+ lastError: string | null;
616
+ synced: number;
617
+ pending: number;
618
+ skipped: {
619
+ key: string;
620
+ reason: string;
621
+ }[];
622
+ };
623
+ };
624
+ "POST /syncs/by-id/:id/runs": {
625
+ input: undefined;
626
+ output: {
627
+ sync: {
628
+ id: string;
629
+ provider: string;
630
+ providerLabel: string;
631
+ brand: "cloudflare" | "github" | "other" | "railway" | "vercel";
632
+ offered: boolean;
633
+ destination: string;
634
+ config: {
635
+ [key: string]: string | number | boolean | null | Json[] | {
636
+ [key: string]: Json;
637
+ };
638
+ };
639
+ credential: string;
640
+ createdAt: string;
641
+ createdBy: string;
642
+ paused: boolean;
643
+ running: boolean;
644
+ lastRunAt: string | null;
645
+ lastStatus: "failed" | "ok" | "partial" | null;
646
+ lastError: string | null;
647
+ synced: number;
648
+ pending: number;
649
+ skipped: {
650
+ key: string;
651
+ reason: string;
652
+ }[];
653
+ };
654
+ outcome: {
655
+ status: "busy";
656
+ } | {
657
+ status: "failed" | "ok" | "partial";
658
+ upserted: string[];
659
+ deleted: string[];
660
+ failed: {
661
+ key: string;
662
+ operation: "delete" | "upsert";
663
+ message: string;
664
+ }[];
665
+ error: string | null;
666
+ };
667
+ };
668
+ };
669
+ "GET /audit": {
670
+ input: {
671
+ path?: string;
672
+ actor?: string;
673
+ decision?: "allow" | "deny";
674
+ detail?: "1" | "true";
675
+ before?: unknown;
676
+ limit?: unknown;
677
+ };
678
+ output: {
679
+ entries: {
680
+ seq: number;
681
+ author: "app" | "vault";
682
+ occurredAt: string;
683
+ actorType: "service" | "system" | "user";
684
+ actorId: string;
685
+ action: string;
686
+ decision: "allow" | "deny";
687
+ reason: string | null;
688
+ detail: boolean;
689
+ subject: string | null;
690
+ project: string | null;
691
+ environment: string | null;
692
+ key: string | null;
693
+ version: number | null;
694
+ operationId: string | null;
695
+ relatedSeq: number | null;
696
+ requestId: string | null;
697
+ metadata: {
698
+ [key: string]: unknown;
699
+ };
700
+ }[];
701
+ hidden?: {
702
+ action: string;
703
+ count: number;
704
+ }[];
705
+ };
706
+ };
707
+ "GET /audit/verification": {
708
+ input: undefined;
709
+ output: {
710
+ ok: true;
711
+ through: number | null;
712
+ entries: number;
713
+ checkpoint: null | {
714
+ seq: number;
715
+ signedAt: string;
716
+ };
717
+ pending?: number;
718
+ } | {
719
+ ok: false;
720
+ through: number | null;
721
+ failedAtSeq: number | null;
722
+ author: "app" | "vault";
723
+ reason: string;
724
+ };
725
+ };
726
+ };
727
+ type AccessValue = "access-manager" | "auditor" | "developer" | "maintainer" | "owner" | "viewer" | null | {
728
+ role: "access-manager" | "auditor" | "developer" | "maintainer" | "owner" | "viewer";
729
+ until: string | null;
730
+ };
731
+ type AuditEntryView = {
732
+ seq: number;
733
+ author: "app" | "vault";
734
+ occurredAt: string;
735
+ actorType: "service" | "system" | "user";
736
+ actorId: string;
737
+ action: string;
738
+ decision: "allow" | "deny";
739
+ reason: string | null;
740
+ detail: boolean;
741
+ subject: string | null;
742
+ project: string | null;
743
+ environment: string | null;
744
+ key: string | null;
745
+ version: number | null;
746
+ operationId: string | null;
747
+ relatedSeq: number | null;
748
+ requestId: string | null;
749
+ metadata: {
750
+ [key: string]: unknown;
751
+ };
752
+ };
753
+ type AuthInfo = {
754
+ signin: null | {
755
+ title: string;
756
+ note: string | null;
757
+ providers: {
758
+ id: string;
759
+ label: string;
760
+ brand: "github" | "google" | "microsoft" | "oidc";
761
+ }[];
762
+ };
763
+ access: null | {
764
+ assertion: boolean;
765
+ };
766
+ };
767
+ type DryRunOutcome = "added" | "archived" | "changed" | "unchanged";
768
+ type DryRunResult = {
769
+ dryRun: true;
770
+ keys: {
771
+ [key: string]: "added" | "archived" | "changed" | "unchanged";
772
+ };
773
+ };
774
+ type IdentityRow = {
775
+ id: string;
776
+ provider: string;
777
+ email: string | null;
778
+ createdAt: string;
779
+ lastSignInAt: string | null;
780
+ };
781
+ type Me = {
782
+ principal: {
783
+ type: "service" | "user";
784
+ id: string;
785
+ };
786
+ registered: boolean;
787
+ tampered: boolean;
788
+ instanceRole: "owner" | "root-admin" | "user";
789
+ isRootAdmin: boolean;
790
+ canReadAudit: boolean;
791
+ environments: {
792
+ project: string;
793
+ environment: string;
794
+ permissions: ("audit.read" | "environment.manage" | "grant.manage" | "project.manage" | "secret.archive" | "secret.read" | "secret.write")[];
795
+ }[];
796
+ };
797
+ type Member = {
798
+ member: string;
799
+ principalType: "service" | "user";
800
+ principalId: string;
801
+ instanceRole: "owner" | "root-admin" | "user";
802
+ isRootAdmin: boolean;
803
+ tampered: boolean;
804
+ grants: {
805
+ id: string;
806
+ project: string;
807
+ environment: string | null;
808
+ role: "access-manager" | "auditor" | "developer" | "maintainer" | "owner" | "viewer";
809
+ roleName: string;
810
+ permissions: ("audit.read" | "environment.manage" | "grant.manage" | "project.manage" | "secret.archive" | "secret.read" | "secret.write")[];
811
+ expiresAt: string | null;
812
+ }[];
813
+ };
814
+ type OffboardingReport = {
815
+ principalType: "service" | "user";
816
+ principalId: string;
817
+ status: "active" | "removed" | "tampered";
818
+ instanceRole: "owner" | "root-admin" | "user";
819
+ isRootAdmin: boolean;
820
+ removedAt: string | null;
821
+ removedBy: string | null;
822
+ live: {
823
+ grants: number;
824
+ sessions: number;
825
+ tokens: number;
826
+ identities: number;
827
+ };
828
+ exposed: {
829
+ project: string;
830
+ environment: string;
831
+ key: string;
832
+ version: number;
833
+ how: "read" | "wrote";
834
+ at: string;
835
+ }[];
836
+ rotated: number;
837
+ issuedTokens: {
838
+ id: string;
839
+ service: string;
840
+ label: string | null;
841
+ hint: string;
842
+ expiresAt: string;
843
+ lastUsedAt: string | null;
844
+ }[];
845
+ syncs: {
846
+ id: string;
847
+ provider: string;
848
+ providerLabel: string;
849
+ brand: "cloudflare" | "github" | "other" | "railway" | "vercel";
850
+ offered: boolean;
851
+ destination: string;
852
+ config: {
853
+ [key: string]: string | number | boolean | null | Json[] | {
854
+ [key: string]: Json;
855
+ };
856
+ };
857
+ credential: string;
858
+ createdAt: string;
859
+ createdBy: string;
860
+ paused: boolean;
861
+ running: boolean;
862
+ lastRunAt: string | null;
863
+ lastStatus: "failed" | "ok" | "partial" | null;
864
+ lastError: string | null;
865
+ synced: number;
866
+ pending: number;
867
+ skipped: {
868
+ key: string;
869
+ reason: string;
870
+ }[];
871
+ project: string;
872
+ environment: string;
873
+ }[];
874
+ };
875
+ type ProjectSummary = {
876
+ slug: string;
877
+ name: string;
878
+ archivedAt: string | null;
879
+ permissions: ("audit.read" | "environment.manage" | "grant.manage" | "project.manage" | "secret.archive" | "secret.read" | "secret.write")[];
880
+ environments: {
881
+ slug: string;
882
+ name: string;
883
+ accessible: boolean;
884
+ details: null | {
885
+ archivedAt: string | null;
886
+ secretCount: number | null;
887
+ };
888
+ }[];
889
+ };
890
+ type RemovedMember = {
891
+ principalType: "service" | "user";
892
+ principalId: string;
893
+ toRotate: number;
894
+ };
895
+ type RunOutcome = {
896
+ status: "busy";
897
+ } | {
898
+ status: "failed" | "ok" | "partial";
899
+ upserted: string[];
900
+ deleted: string[];
901
+ failed: {
902
+ key: string;
903
+ operation: "delete" | "upsert";
904
+ message: string;
905
+ }[];
906
+ error: string | null;
907
+ };
908
+ type SecretKey = {
909
+ key: string;
910
+ archived: boolean;
911
+ version: number | null;
912
+ updatedAt: string | null;
913
+ updatedBy: string | null;
914
+ };
915
+ type SecretVersion = {
916
+ version: number;
917
+ createdAt: string;
918
+ createdBy: string;
919
+ current: boolean;
920
+ kek: string;
921
+ };
922
+ type ServiceTokenRow = {
923
+ id: string;
924
+ label: string | null;
925
+ hint: string;
926
+ createdAt: string;
927
+ createdBy: string;
928
+ expiresAt: string;
929
+ lastUsedAt: string | null;
930
+ lastUsedIp: string | null;
931
+ };
932
+ type SessionRow = {
933
+ id: string;
934
+ kind: "browser" | "cli";
935
+ label: string | null;
936
+ hint: string;
937
+ provider: string | null;
938
+ createdAt: string;
939
+ expiresAt: string;
940
+ lastUsedAt: string | null;
941
+ lastUsedIp: string | null;
942
+ current: boolean;
943
+ };
944
+ type SetResult = {
945
+ operationId: string;
946
+ keys: {
947
+ [key: string]: {
948
+ version: number;
949
+ } | {
950
+ archived: true;
951
+ };
952
+ };
953
+ };
954
+ type SyncField = {
955
+ type: "text";
956
+ name: string;
957
+ label: string;
958
+ placeholder: string;
959
+ optional?: boolean;
960
+ hint?: string;
961
+ when?: {
962
+ field: string;
963
+ is: string[];
964
+ };
965
+ } | {
966
+ type: "options";
967
+ name: string;
968
+ label: string;
969
+ options: {
970
+ value: string;
971
+ label: string;
972
+ }[];
973
+ multiple: boolean;
974
+ initial: string[];
975
+ hint?: string;
976
+ };
977
+ type SyncProviderInfo = {
978
+ brand: "cloudflare" | "github" | "other" | "railway" | "vercel";
979
+ id: string;
980
+ credential: {
981
+ placeholder: string;
982
+ hint: string;
983
+ };
984
+ label: string;
985
+ fields: ({
986
+ type: "text";
987
+ name: string;
988
+ label: string;
989
+ placeholder: string;
990
+ optional?: boolean;
991
+ hint?: string;
992
+ when?: {
993
+ field: string;
994
+ is: string[];
995
+ };
996
+ } | {
997
+ type: "options";
998
+ name: string;
999
+ label: string;
1000
+ options: {
1001
+ value: string;
1002
+ label: string;
1003
+ }[];
1004
+ multiple: boolean;
1005
+ initial: string[];
1006
+ hint?: string;
1007
+ })[];
1008
+ };
1009
+ type SyncView = {
1010
+ id: string;
1011
+ provider: string;
1012
+ providerLabel: string;
1013
+ brand: "cloudflare" | "github" | "other" | "railway" | "vercel";
1014
+ offered: boolean;
1015
+ destination: string;
1016
+ config: {
1017
+ [key: string]: string | number | boolean | null | Json[] | {
1018
+ [key: string]: Json;
1019
+ };
1020
+ };
1021
+ credential: string;
1022
+ createdAt: string;
1023
+ createdBy: string;
1024
+ paused: boolean;
1025
+ running: boolean;
1026
+ lastRunAt: string | null;
1027
+ lastStatus: "failed" | "ok" | "partial" | null;
1028
+ lastError: string | null;
1029
+ synced: number;
1030
+ pending: number;
1031
+ skipped: {
1032
+ key: string;
1033
+ reason: string;
1034
+ }[];
1035
+ };
1036
+ type Json = string | number | boolean | null | Json[] | {
1037
+ [key: string]: Json;
1038
+ };
1039
+ //#endregion
1040
+ //#region src/sync-fields.d.ts
1041
+ type FormValues = Record<string, string | string[]>;
1042
+ export declare function initialValues(provider: SyncProviderInfo): FormValues;
1043
+ /** Whether the rest of the form makes the field meaningful. */
1044
+ export declare function isAsked(field: SyncField, values: FormValues): boolean;
1045
+ /** The label of the first required field left empty, or null when the form can be sent. */
1046
+ export declare function firstMissing(provider: SyncProviderInfo, values: FormValues): string | null;
1047
+ /**
1048
+ * The provider's config. Text is trimmed, and an optional field left empty
1049
+ * is left out rather than sent as "", which the server rightly refuses.
1050
+ */
1051
+ export declare function configFromForm(provider: SyncProviderInfo, values: FormValues): Record<string, unknown>;
1052
+ /**
1053
+ * The config from `name=value` arguments, as the CLI takes them. A field with
1054
+ * several options takes them comma-separated, and one left out gets what the
1055
+ * form preselects. Text goes as typed, for the server to check.
1056
+ */
1057
+ export declare function configFromArguments(provider: SyncProviderInfo, assignments: readonly string[]): Record<string, unknown>;
1058
+ //#endregion
1059
+ //#region src/index.d.ts
1060
+ export type RouteKey = keyof Api;
1061
+ /** What a caller sends: the body, or the query string for a GET. */
1062
+ export type RouteInput<K extends RouteKey> = Api[K]['input'];
1063
+ /** What comes back, as JSON. */
1064
+ export type RouteOutput<K extends RouteKey> = Api[K]['output'];
1065
+ type ParamNames<Pattern> = Pattern extends `${string}:${infer Name}/${infer Rest}` ? Name | ParamNames<`/${Rest}`> : Pattern extends `${string}:${infer Name}` ? Name : never;
1066
+ /** `GET /members/:member` takes `{ member }`. */
1067
+ export type Params<Key> = { [Name in ParamNames<Key>]: string; };
1068
+ export type Transport = (request: Request) => Promise<Response>;
1069
+ export type ClientOptions = {
1070
+ /** The instance's origin, e.g. `https://coffre.acme.example`. */
1071
+ url: string;
1072
+ /** Sent with every request: a bearer token, a Cloudflare Access header. */
1073
+ headers?: () => HeadersInit | Promise<HeadersInit>;
1074
+ transport?: Transport;
1075
+ };
1076
+ /** The API's error shape, `{ error, message }`, with the HTTP status. */
1077
+ declare const COFFRE_ERROR: unique symbol;
1078
+ export declare class CoffreError extends Error {
1079
+ /**
1080
+ * `@coffre/ui`'s prebuilt pages bundle a copy of this class, and a page is
1081
+ * handed a client the server made with this package's. So `instanceof`
1082
+ * asks for the mark every copy leaves, rather than for this copy's prototype.
1083
+ */
1084
+ static [Symbol.hasInstance](value: unknown): boolean;
1085
+ readonly [COFFRE_ERROR] = true;
1086
+ readonly status: number;
1087
+ readonly code: string;
1088
+ /** The vault's own code when it refused: `no_grant`, `removed`, `bulk_limit`, ... */
1089
+ readonly reason: string | undefined;
1090
+ constructor(status: number, code: string, message: string, reason?: string);
1091
+ }
1092
+ type Args<K extends RouteKey> = RouteInput<K> extends undefined ? [params: Params<K>, input?: undefined] : Partial<RouteInput<K>> extends RouteInput<K> ? [params: Params<K>, input?: RouteInput<K>] : [params: Params<K>, input: RouteInput<K>];
1093
+ export declare function createClient(options: ClientOptions): {
1094
+ call: <K extends RouteKey>(key: K, ...[params, input]: Args<K>) => Promise<RouteOutput<K>>;
1095
+ /** How this instance signs people in. Answers anyone, signed in or not. */
1096
+ auth: () => Promise<AuthInfo>;
1097
+ /** Who I am, and every place I can reach. */
1098
+ me: () => Promise<{
1099
+ principal: {
1100
+ type: "service" | "user";
1101
+ id: string;
1102
+ };
1103
+ registered: boolean;
1104
+ tampered: boolean;
1105
+ instanceRole: "owner" | "root-admin" | "user";
1106
+ isRootAdmin: boolean;
1107
+ canReadAudit: boolean;
1108
+ environments: {
1109
+ project: string;
1110
+ environment: string;
1111
+ permissions: ("audit.read" | "environment.manage" | "grant.manage" | "project.manage" | "secret.archive" | "secret.read" | "secret.write")[];
1112
+ }[];
1113
+ }>;
1114
+ projects: {
1115
+ /** With their environments. */
1116
+ list: () => Promise<{
1117
+ projects: {
1118
+ slug: string;
1119
+ name: string;
1120
+ archivedAt: string | null;
1121
+ permissions: ("audit.read" | "environment.manage" | "grant.manage" | "project.manage" | "secret.archive" | "secret.read" | "secret.write")[];
1122
+ environments: {
1123
+ slug: string;
1124
+ name: string;
1125
+ accessible: boolean;
1126
+ details: null | {
1127
+ archivedAt: string | null;
1128
+ secretCount: number | null;
1129
+ };
1130
+ }[];
1131
+ }[];
1132
+ }>;
1133
+ create: (project: string, input: RouteInput<"PUT /projects/:project">) => Promise<{
1134
+ project: {
1135
+ slug: string;
1136
+ name: string;
1137
+ archivedAt: string | null;
1138
+ };
1139
+ created: boolean;
1140
+ }>;
1141
+ update: (project: string, patch: RouteInput<"PATCH /projects/:project">) => Promise<{
1142
+ project: {
1143
+ slug: string;
1144
+ name: string;
1145
+ archivedAt: string | null;
1146
+ };
1147
+ }>;
1148
+ };
1149
+ environments: {
1150
+ create: (path: string, input: RouteInput<"PUT /projects/:project/:environment">) => Promise<{
1151
+ environment: {
1152
+ slug: string;
1153
+ name: string;
1154
+ archivedAt: string | null;
1155
+ };
1156
+ created: boolean;
1157
+ }>;
1158
+ update: (path: string, patch: RouteInput<"PATCH /projects/:project/:environment">) => Promise<{
1159
+ environment: {
1160
+ slug: string;
1161
+ name: string;
1162
+ archivedAt: string | null;
1163
+ };
1164
+ }>;
1165
+ };
1166
+ secrets: {
1167
+ /** Keys, versions and who changed what; never values. */
1168
+ list: (path: string) => Promise<{
1169
+ permissions: ("audit.read" | "environment.manage" | "grant.manage" | "project.manage" | "secret.archive" | "secret.read" | "secret.write")[];
1170
+ keys: {
1171
+ key: string;
1172
+ archived: boolean;
1173
+ version: number | null;
1174
+ updatedAt: string | null;
1175
+ updatedBy: string | null;
1176
+ }[];
1177
+ }>;
1178
+ /** Decrypts one secret, or every secret in an environment. Logged in your name. */
1179
+ reveal: (path: string) => Promise<{
1180
+ operationId: string;
1181
+ values: {
1182
+ [key: string]: string;
1183
+ };
1184
+ }>;
1185
+ /** One transaction, a version and an audit entry per key; `null` archives. */
1186
+ set: (path: string, values: RouteInput<"PATCH /secrets/:project/:environment">) => Promise<SetResult>;
1187
+ /**
1188
+ * What `set` would do to each key, `added`, `changed`, `unchanged` or
1189
+ * `archived`, and nothing else: no value comes back and nothing is
1190
+ * written. Comparing opens the current values, logged as reads.
1191
+ */
1192
+ dryRun: (path: string, values: RouteInput<"PATCH /secrets/:project/:environment">) => Promise<DryRunResult>;
1193
+ history: (path: string) => Promise<{
1194
+ key: string;
1195
+ archived: boolean;
1196
+ versions: {
1197
+ version: number;
1198
+ createdAt: string;
1199
+ createdBy: string;
1200
+ current: boolean;
1201
+ kek: string;
1202
+ }[];
1203
+ }>;
1204
+ /** A new version holding the old one's value. */
1205
+ restore: (path: string, version: number) => Promise<{
1206
+ key: string;
1207
+ version: number;
1208
+ }>;
1209
+ rename: (path: string, key: string) => Promise<{
1210
+ key: string;
1211
+ archived: boolean;
1212
+ }>;
1213
+ update: (path: string, patch: RouteInput<"PATCH /secrets/:project/:environment/:key">) => Promise<{
1214
+ key: string;
1215
+ archived: boolean;
1216
+ }>;
1217
+ };
1218
+ members: {
1219
+ /** People and tokens, their role and their access; at a place, those who reach it. */
1220
+ list: (path?: string) => Promise<{
1221
+ members: {
1222
+ member: string;
1223
+ principalType: "service" | "user";
1224
+ principalId: string;
1225
+ instanceRole: "owner" | "root-admin" | "user";
1226
+ isRootAdmin: boolean;
1227
+ tampered: boolean;
1228
+ grants: {
1229
+ id: string;
1230
+ project: string;
1231
+ environment: string | null;
1232
+ role: "access-manager" | "auditor" | "developer" | "maintainer" | "owner" | "viewer";
1233
+ roleName: string;
1234
+ permissions: ("audit.read" | "environment.manage" | "grant.manage" | "project.manage" | "secret.archive" | "secret.read" | "secret.write")[];
1235
+ expiresAt: string | null;
1236
+ }[];
1237
+ }[];
1238
+ removed: {
1239
+ principalType: "service" | "user";
1240
+ principalId: string;
1241
+ toRotate: number;
1242
+ }[];
1243
+ }>;
1244
+ /** What they hold, and what to rotate if they leave. */
1245
+ get: (member: string) => Promise<{
1246
+ principalType: "service" | "user";
1247
+ principalId: string;
1248
+ status: "active" | "removed" | "tampered";
1249
+ instanceRole: "owner" | "root-admin" | "user";
1250
+ isRootAdmin: boolean;
1251
+ removedAt: string | null;
1252
+ removedBy: string | null;
1253
+ live: {
1254
+ grants: number;
1255
+ sessions: number;
1256
+ tokens: number;
1257
+ identities: number;
1258
+ };
1259
+ exposed: {
1260
+ project: string;
1261
+ environment: string;
1262
+ key: string;
1263
+ version: number;
1264
+ how: "read" | "wrote";
1265
+ at: string;
1266
+ }[];
1267
+ rotated: number;
1268
+ issuedTokens: {
1269
+ id: string;
1270
+ service: string;
1271
+ label: string | null;
1272
+ hint: string;
1273
+ expiresAt: string;
1274
+ lastUsedAt: string | null;
1275
+ }[];
1276
+ syncs: {
1277
+ id: string;
1278
+ provider: string;
1279
+ providerLabel: string;
1280
+ brand: "cloudflare" | "github" | "other" | "railway" | "vercel";
1281
+ offered: boolean;
1282
+ destination: string;
1283
+ config: {
1284
+ [key: string]: string | number | boolean | null | Json[] | {
1285
+ [key: string]: Json;
1286
+ };
1287
+ };
1288
+ credential: string;
1289
+ createdAt: string;
1290
+ createdBy: string;
1291
+ paused: boolean;
1292
+ running: boolean;
1293
+ lastRunAt: string | null;
1294
+ lastStatus: "failed" | "ok" | "partial" | null;
1295
+ lastError: string | null;
1296
+ synced: number;
1297
+ pending: number;
1298
+ skipped: {
1299
+ key: string;
1300
+ reason: string;
1301
+ }[];
1302
+ project: string;
1303
+ environment: string;
1304
+ }[];
1305
+ }>;
1306
+ add: (member: string, input?: RouteInput<"PUT /members/:member">) => Promise<{
1307
+ member: string;
1308
+ instanceRole: "owner" | "user";
1309
+ created: boolean;
1310
+ }>;
1311
+ /** Offboards; returns what to rotate. */
1312
+ remove: (member: string) => Promise<{
1313
+ revoked: {
1314
+ grants: number;
1315
+ sessions: number;
1316
+ tokens: number;
1317
+ identities: number;
1318
+ };
1319
+ report: {
1320
+ principalType: "service" | "user";
1321
+ principalId: string;
1322
+ status: "active" | "removed" | "tampered";
1323
+ instanceRole: "owner" | "root-admin" | "user";
1324
+ isRootAdmin: boolean;
1325
+ removedAt: string | null;
1326
+ removedBy: string | null;
1327
+ live: {
1328
+ grants: number;
1329
+ sessions: number;
1330
+ tokens: number;
1331
+ identities: number;
1332
+ };
1333
+ exposed: {
1334
+ project: string;
1335
+ environment: string;
1336
+ key: string;
1337
+ version: number;
1338
+ how: "read" | "wrote";
1339
+ at: string;
1340
+ }[];
1341
+ rotated: number;
1342
+ issuedTokens: {
1343
+ id: string;
1344
+ service: string;
1345
+ label: string | null;
1346
+ hint: string;
1347
+ expiresAt: string;
1348
+ lastUsedAt: string | null;
1349
+ }[];
1350
+ syncs: {
1351
+ id: string;
1352
+ provider: string;
1353
+ providerLabel: string;
1354
+ brand: "cloudflare" | "github" | "other" | "railway" | "vercel";
1355
+ offered: boolean;
1356
+ destination: string;
1357
+ config: {
1358
+ [key: string]: string | number | boolean | null | Json[] | {
1359
+ [key: string]: Json;
1360
+ };
1361
+ };
1362
+ credential: string;
1363
+ createdAt: string;
1364
+ createdBy: string;
1365
+ paused: boolean;
1366
+ running: boolean;
1367
+ lastRunAt: string | null;
1368
+ lastStatus: "failed" | "ok" | "partial" | null;
1369
+ lastError: string | null;
1370
+ synced: number;
1371
+ pending: number;
1372
+ skipped: {
1373
+ key: string;
1374
+ reason: string;
1375
+ }[];
1376
+ project: string;
1377
+ environment: string;
1378
+ }[];
1379
+ };
1380
+ }>;
1381
+ };
1382
+ tokens: {
1383
+ list: (member: string) => Promise<{
1384
+ tokens: {
1385
+ id: string;
1386
+ label: string | null;
1387
+ hint: string;
1388
+ createdAt: string;
1389
+ createdBy: string;
1390
+ expiresAt: string;
1391
+ lastUsedAt: string | null;
1392
+ lastUsedIp: string | null;
1393
+ }[];
1394
+ }>;
1395
+ /** The value is in the answer, and only there. */
1396
+ issue: (member: string, input: RouteInput<"POST /members/:member/tokens">) => Promise<{
1397
+ id: string;
1398
+ token: string;
1399
+ expiresAt: string;
1400
+ }>;
1401
+ revoke: (member: string, id: string) => Promise<{
1402
+ revoked: true;
1403
+ }>;
1404
+ };
1405
+ access: {
1406
+ /** What they should hold at each place; the server applies the difference. `null` revokes. */
1407
+ set: (member: string, access: RouteInput<"PATCH /access/:member">) => Promise<{
1408
+ changes: {
1409
+ [key: string]: "created" | "revoked" | "unchanged" | "updated";
1410
+ };
1411
+ }>;
1412
+ };
1413
+ /** Where I am signed in. Only where coffre runs its own sign-in. */
1414
+ sessions: {
1415
+ list: () => Promise<{
1416
+ sessions: {
1417
+ id: string;
1418
+ kind: "browser" | "cli";
1419
+ label: string | null;
1420
+ hint: string;
1421
+ provider: string | null;
1422
+ createdAt: string;
1423
+ expiresAt: string;
1424
+ lastUsedAt: string | null;
1425
+ lastUsedIp: string | null;
1426
+ current: boolean;
1427
+ }[];
1428
+ }>;
1429
+ revoke: (id: string) => Promise<{
1430
+ revoked: true;
1431
+ }>;
1432
+ };
1433
+ /** The accounts I sign in with. */
1434
+ identities: {
1435
+ list: () => Promise<{
1436
+ identities: {
1437
+ id: string;
1438
+ provider: string;
1439
+ email: string | null;
1440
+ createdAt: string;
1441
+ lastSignInAt: string | null;
1442
+ }[];
1443
+ }>;
1444
+ unlink: (id: string) => Promise<{
1445
+ unlinked: true;
1446
+ }>;
1447
+ };
1448
+ /** A `coffre login` waiting for someone to approve it, by the code it shows. */
1449
+ deviceLogins: {
1450
+ get: (code: string) => Promise<{
1451
+ request: null | {
1452
+ userCode: string;
1453
+ clientLabel: string | null;
1454
+ clientIp: string | null;
1455
+ createdAt: string;
1456
+ expiresAt: string;
1457
+ };
1458
+ sessionDays: number;
1459
+ }>;
1460
+ decide: (code: string, approve: boolean) => Promise<{
1461
+ decided: true;
1462
+ }>;
1463
+ };
1464
+ syncs: {
1465
+ /** Where a sync can push on this instance, and what each asks for. */
1466
+ providers: () => Promise<{
1467
+ providers: {
1468
+ brand: "cloudflare" | "github" | "other" | "railway" | "vercel";
1469
+ id: string;
1470
+ credential: {
1471
+ placeholder: string;
1472
+ hint: string;
1473
+ };
1474
+ label: string;
1475
+ fields: ({
1476
+ type: "text";
1477
+ name: string;
1478
+ label: string;
1479
+ placeholder: string;
1480
+ optional?: boolean;
1481
+ hint?: string;
1482
+ when?: {
1483
+ field: string;
1484
+ is: string[];
1485
+ };
1486
+ } | {
1487
+ type: "options";
1488
+ name: string;
1489
+ label: string;
1490
+ options: {
1491
+ value: string;
1492
+ label: string;
1493
+ }[];
1494
+ multiple: boolean;
1495
+ initial: string[];
1496
+ hint?: string;
1497
+ })[];
1498
+ }[];
1499
+ }>;
1500
+ list: (path: string) => Promise<{
1501
+ syncs: {
1502
+ id: string;
1503
+ provider: string;
1504
+ providerLabel: string;
1505
+ brand: "cloudflare" | "github" | "other" | "railway" | "vercel";
1506
+ offered: boolean;
1507
+ destination: string;
1508
+ config: {
1509
+ [key: string]: string | number | boolean | null | Json[] | {
1510
+ [key: string]: Json;
1511
+ };
1512
+ };
1513
+ credential: string;
1514
+ createdAt: string;
1515
+ createdBy: string;
1516
+ paused: boolean;
1517
+ running: boolean;
1518
+ lastRunAt: string | null;
1519
+ lastStatus: "failed" | "ok" | "partial" | null;
1520
+ lastError: string | null;
1521
+ synced: number;
1522
+ pending: number;
1523
+ skipped: {
1524
+ key: string;
1525
+ reason: string;
1526
+ }[];
1527
+ }[];
1528
+ canManage: boolean;
1529
+ }>;
1530
+ add: (path: string, input: RouteInput<"POST /syncs/:project/:environment">) => Promise<{
1531
+ id: string;
1532
+ provider: string;
1533
+ providerLabel: string;
1534
+ brand: "cloudflare" | "github" | "other" | "railway" | "vercel";
1535
+ offered: boolean;
1536
+ destination: string;
1537
+ config: {
1538
+ [key: string]: string | number | boolean | null | Json[] | {
1539
+ [key: string]: Json;
1540
+ };
1541
+ };
1542
+ credential: string;
1543
+ createdAt: string;
1544
+ createdBy: string;
1545
+ paused: boolean;
1546
+ running: boolean;
1547
+ lastRunAt: string | null;
1548
+ lastStatus: "failed" | "ok" | "partial" | null;
1549
+ lastError: string | null;
1550
+ synced: number;
1551
+ pending: number;
1552
+ skipped: {
1553
+ key: string;
1554
+ reason: string;
1555
+ }[];
1556
+ }>;
1557
+ update: (id: string, patch: RouteInput<"PATCH /syncs/by-id/:id">) => Promise<{
1558
+ id: string;
1559
+ provider: string;
1560
+ providerLabel: string;
1561
+ brand: "cloudflare" | "github" | "other" | "railway" | "vercel";
1562
+ offered: boolean;
1563
+ destination: string;
1564
+ config: {
1565
+ [key: string]: string | number | boolean | null | Json[] | {
1566
+ [key: string]: Json;
1567
+ };
1568
+ };
1569
+ credential: string;
1570
+ createdAt: string;
1571
+ createdBy: string;
1572
+ paused: boolean;
1573
+ running: boolean;
1574
+ lastRunAt: string | null;
1575
+ lastStatus: "failed" | "ok" | "partial" | null;
1576
+ lastError: string | null;
1577
+ synced: number;
1578
+ pending: number;
1579
+ skipped: {
1580
+ key: string;
1581
+ reason: string;
1582
+ }[];
1583
+ }>;
1584
+ remove: (id: string) => Promise<{
1585
+ id: string;
1586
+ provider: string;
1587
+ providerLabel: string;
1588
+ brand: "cloudflare" | "github" | "other" | "railway" | "vercel";
1589
+ offered: boolean;
1590
+ destination: string;
1591
+ config: {
1592
+ [key: string]: string | number | boolean | null | Json[] | {
1593
+ [key: string]: Json;
1594
+ };
1595
+ };
1596
+ credential: string;
1597
+ createdAt: string;
1598
+ createdBy: string;
1599
+ paused: boolean;
1600
+ running: boolean;
1601
+ lastRunAt: string | null;
1602
+ lastStatus: "failed" | "ok" | "partial" | null;
1603
+ lastError: string | null;
1604
+ synced: number;
1605
+ pending: number;
1606
+ skipped: {
1607
+ key: string;
1608
+ reason: string;
1609
+ }[];
1610
+ }>;
1611
+ run: (id: string) => Promise<{
1612
+ sync: {
1613
+ id: string;
1614
+ provider: string;
1615
+ providerLabel: string;
1616
+ brand: "cloudflare" | "github" | "other" | "railway" | "vercel";
1617
+ offered: boolean;
1618
+ destination: string;
1619
+ config: {
1620
+ [key: string]: string | number | boolean | null | Json[] | {
1621
+ [key: string]: Json;
1622
+ };
1623
+ };
1624
+ credential: string;
1625
+ createdAt: string;
1626
+ createdBy: string;
1627
+ paused: boolean;
1628
+ running: boolean;
1629
+ lastRunAt: string | null;
1630
+ lastStatus: "failed" | "ok" | "partial" | null;
1631
+ lastError: string | null;
1632
+ synced: number;
1633
+ pending: number;
1634
+ skipped: {
1635
+ key: string;
1636
+ reason: string;
1637
+ }[];
1638
+ };
1639
+ outcome: {
1640
+ status: "busy";
1641
+ } | {
1642
+ status: "failed" | "ok" | "partial";
1643
+ upserted: string[];
1644
+ deleted: string[];
1645
+ failed: {
1646
+ key: string;
1647
+ operation: "delete" | "upsert";
1648
+ message: string;
1649
+ }[];
1650
+ error: string | null;
1651
+ };
1652
+ }>;
1653
+ };
1654
+ audit: {
1655
+ list: (query?: RouteInput<"GET /audit">) => Promise<{
1656
+ entries: {
1657
+ seq: number;
1658
+ author: "app" | "vault";
1659
+ occurredAt: string;
1660
+ actorType: "service" | "system" | "user";
1661
+ actorId: string;
1662
+ action: string;
1663
+ decision: "allow" | "deny";
1664
+ reason: string | null;
1665
+ detail: boolean;
1666
+ subject: string | null;
1667
+ project: string | null;
1668
+ environment: string | null;
1669
+ key: string | null;
1670
+ version: number | null;
1671
+ operationId: string | null;
1672
+ relatedSeq: number | null;
1673
+ requestId: string | null;
1674
+ metadata: {
1675
+ [key: string]: unknown;
1676
+ };
1677
+ }[];
1678
+ hidden?: {
1679
+ action: string;
1680
+ count: number;
1681
+ }[];
1682
+ }>;
1683
+ verify: () => Promise<{
1684
+ ok: true;
1685
+ through: number | null;
1686
+ entries: number;
1687
+ checkpoint: null | {
1688
+ seq: number;
1689
+ signedAt: string;
1690
+ };
1691
+ pending?: number;
1692
+ } | {
1693
+ ok: false;
1694
+ through: number | null;
1695
+ failedAtSeq: number | null;
1696
+ author: "app" | "vault";
1697
+ reason: string;
1698
+ }>;
1699
+ };
1700
+ };
1701
+ export type CoffreClient = ReturnType<typeof createClient>;
1702
+ export type ImportAction = Exclude<DryRunOutcome, 'archived'>;
1703
+ /**
1704
+ * What writing these entries (a parsed `.env` file) would do, from a dry run
1705
+ * of the write: the server compares, so no value leaves it, and the values it
1706
+ * opens to compare are logged as reads. `changes` is what to pass to
1707
+ * `secrets.set`: the keys that differ, so an unchanged value does not become
1708
+ * a new version.
1709
+ */
1710
+ export declare function planImport(coffre: CoffreClient, path: string, entries: readonly {
1711
+ key: string;
1712
+ value: string;
1713
+ }[]): Promise<{
1714
+ plan: {
1715
+ key: string;
1716
+ action: ImportAction;
1717
+ version: number | null;
1718
+ }[];
1719
+ changes: Record<string, string>;
1720
+ }>;
1721
+ //#endregion
1722
+ export type { AccessValue, Api, AuditEntryView, AuthInfo, DryRunOutcome, DryRunResult, FormValues, IdentityRow, Json, Me, Member, OffboardingReport, ProjectSummary, RemovedMember, RunOutcome, SecretKey, SecretVersion, ServiceTokenRow, SessionRow, SetResult, SyncField, SyncProviderInfo, SyncView };