@coffre/client 0.1.5 → 0.1.7

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,1762 @@
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
+ "GET /audit/keys": {
727
+ input: undefined;
728
+ output: {
729
+ app: {
730
+ keyId: string;
731
+ };
732
+ vault: {
733
+ current: {
734
+ vaultId: string;
735
+ provider: string;
736
+ };
737
+ checks: {
738
+ seq: number;
739
+ vaultId: string;
740
+ provider: string;
741
+ version: string;
742
+ wrapped: string;
743
+ }[];
744
+ };
745
+ };
746
+ };
747
+ };
748
+ type AccessValue = "access-manager" | "auditor" | "developer" | "maintainer" | "owner" | "viewer" | null | {
749
+ role: "access-manager" | "auditor" | "developer" | "maintainer" | "owner" | "viewer";
750
+ until: string | null;
751
+ };
752
+ type AuditEntryView = {
753
+ seq: number;
754
+ author: "app" | "vault";
755
+ occurredAt: string;
756
+ actorType: "service" | "system" | "user";
757
+ actorId: string;
758
+ action: string;
759
+ decision: "allow" | "deny";
760
+ reason: string | null;
761
+ detail: boolean;
762
+ subject: string | null;
763
+ project: string | null;
764
+ environment: string | null;
765
+ key: string | null;
766
+ version: number | null;
767
+ operationId: string | null;
768
+ relatedSeq: number | null;
769
+ requestId: string | null;
770
+ metadata: {
771
+ [key: string]: unknown;
772
+ };
773
+ };
774
+ type AuthInfo = {
775
+ signin: null | {
776
+ title: string;
777
+ note: string | null;
778
+ providers: {
779
+ id: string;
780
+ label: string;
781
+ brand: "github" | "google" | "microsoft" | "oidc";
782
+ }[];
783
+ };
784
+ access: null | {
785
+ assertion: boolean;
786
+ };
787
+ };
788
+ type DryRunOutcome = "added" | "archived" | "changed" | "unchanged";
789
+ type DryRunResult = {
790
+ dryRun: true;
791
+ keys: {
792
+ [key: string]: "added" | "archived" | "changed" | "unchanged";
793
+ };
794
+ };
795
+ type IdentityRow = {
796
+ id: string;
797
+ provider: string;
798
+ email: string | null;
799
+ createdAt: string;
800
+ lastSignInAt: string | null;
801
+ };
802
+ type Me = {
803
+ principal: {
804
+ type: "service" | "user";
805
+ id: string;
806
+ };
807
+ registered: boolean;
808
+ tampered: boolean;
809
+ instanceRole: "owner" | "root-admin" | "user";
810
+ isRootAdmin: boolean;
811
+ canReadAudit: boolean;
812
+ environments: {
813
+ project: string;
814
+ environment: string;
815
+ permissions: ("audit.read" | "environment.manage" | "grant.manage" | "project.manage" | "secret.archive" | "secret.read" | "secret.write")[];
816
+ }[];
817
+ };
818
+ type Member = {
819
+ member: string;
820
+ principalType: "service" | "user";
821
+ principalId: string;
822
+ instanceRole: "owner" | "root-admin" | "user";
823
+ isRootAdmin: boolean;
824
+ tampered: boolean;
825
+ grants: {
826
+ id: string;
827
+ project: string;
828
+ environment: string | null;
829
+ role: "access-manager" | "auditor" | "developer" | "maintainer" | "owner" | "viewer";
830
+ roleName: string;
831
+ permissions: ("audit.read" | "environment.manage" | "grant.manage" | "project.manage" | "secret.archive" | "secret.read" | "secret.write")[];
832
+ expiresAt: string | null;
833
+ }[];
834
+ };
835
+ type OffboardingReport = {
836
+ principalType: "service" | "user";
837
+ principalId: string;
838
+ status: "active" | "removed" | "tampered";
839
+ instanceRole: "owner" | "root-admin" | "user";
840
+ isRootAdmin: boolean;
841
+ removedAt: string | null;
842
+ removedBy: string | null;
843
+ live: {
844
+ grants: number;
845
+ sessions: number;
846
+ tokens: number;
847
+ identities: number;
848
+ };
849
+ exposed: {
850
+ project: string;
851
+ environment: string;
852
+ key: string;
853
+ version: number;
854
+ how: "read" | "wrote";
855
+ at: string;
856
+ }[];
857
+ rotated: number;
858
+ issuedTokens: {
859
+ id: string;
860
+ service: string;
861
+ label: string | null;
862
+ hint: string;
863
+ expiresAt: string;
864
+ lastUsedAt: string | null;
865
+ }[];
866
+ syncs: {
867
+ id: string;
868
+ provider: string;
869
+ providerLabel: string;
870
+ brand: "cloudflare" | "github" | "other" | "railway" | "vercel";
871
+ offered: boolean;
872
+ destination: string;
873
+ config: {
874
+ [key: string]: string | number | boolean | null | Json[] | {
875
+ [key: string]: Json;
876
+ };
877
+ };
878
+ credential: string;
879
+ createdAt: string;
880
+ createdBy: string;
881
+ paused: boolean;
882
+ running: boolean;
883
+ lastRunAt: string | null;
884
+ lastStatus: "failed" | "ok" | "partial" | null;
885
+ lastError: string | null;
886
+ synced: number;
887
+ pending: number;
888
+ skipped: {
889
+ key: string;
890
+ reason: string;
891
+ }[];
892
+ project: string;
893
+ environment: string;
894
+ }[];
895
+ };
896
+ type ProjectSummary = {
897
+ slug: string;
898
+ name: string;
899
+ archivedAt: string | null;
900
+ permissions: ("audit.read" | "environment.manage" | "grant.manage" | "project.manage" | "secret.archive" | "secret.read" | "secret.write")[];
901
+ environments: {
902
+ slug: string;
903
+ name: string;
904
+ accessible: boolean;
905
+ details: null | {
906
+ archivedAt: string | null;
907
+ secretCount: number | null;
908
+ };
909
+ }[];
910
+ };
911
+ type RemovedMember = {
912
+ principalType: "service" | "user";
913
+ principalId: string;
914
+ toRotate: number;
915
+ };
916
+ type RunOutcome = {
917
+ status: "busy";
918
+ } | {
919
+ status: "failed" | "ok" | "partial";
920
+ upserted: string[];
921
+ deleted: string[];
922
+ failed: {
923
+ key: string;
924
+ operation: "delete" | "upsert";
925
+ message: string;
926
+ }[];
927
+ error: string | null;
928
+ };
929
+ type SecretKey = {
930
+ key: string;
931
+ archived: boolean;
932
+ version: number | null;
933
+ updatedAt: string | null;
934
+ updatedBy: string | null;
935
+ };
936
+ type SecretVersion = {
937
+ version: number;
938
+ createdAt: string;
939
+ createdBy: string;
940
+ current: boolean;
941
+ kek: string;
942
+ };
943
+ type ServiceTokenRow = {
944
+ id: string;
945
+ label: string | null;
946
+ hint: string;
947
+ createdAt: string;
948
+ createdBy: string;
949
+ expiresAt: string;
950
+ lastUsedAt: string | null;
951
+ lastUsedIp: string | null;
952
+ };
953
+ type SessionRow = {
954
+ id: string;
955
+ kind: "browser" | "cli";
956
+ label: string | null;
957
+ hint: string;
958
+ provider: string | null;
959
+ createdAt: string;
960
+ expiresAt: string;
961
+ lastUsedAt: string | null;
962
+ lastUsedIp: string | null;
963
+ current: boolean;
964
+ };
965
+ type SetResult = {
966
+ operationId: string;
967
+ keys: {
968
+ [key: string]: {
969
+ version: number;
970
+ } | {
971
+ archived: true;
972
+ };
973
+ };
974
+ };
975
+ type SyncField = {
976
+ type: "text";
977
+ name: string;
978
+ label: string;
979
+ placeholder: string;
980
+ optional?: boolean;
981
+ hint?: string;
982
+ when?: {
983
+ field: string;
984
+ is: string[];
985
+ };
986
+ } | {
987
+ type: "options";
988
+ name: string;
989
+ label: string;
990
+ options: {
991
+ value: string;
992
+ label: string;
993
+ }[];
994
+ multiple: boolean;
995
+ initial: string[];
996
+ hint?: string;
997
+ };
998
+ type SyncProviderInfo = {
999
+ brand: "cloudflare" | "github" | "other" | "railway" | "vercel";
1000
+ id: string;
1001
+ credential: {
1002
+ placeholder: string;
1003
+ hint: string;
1004
+ };
1005
+ label: string;
1006
+ fields: ({
1007
+ type: "text";
1008
+ name: string;
1009
+ label: string;
1010
+ placeholder: string;
1011
+ optional?: boolean;
1012
+ hint?: string;
1013
+ when?: {
1014
+ field: string;
1015
+ is: string[];
1016
+ };
1017
+ } | {
1018
+ type: "options";
1019
+ name: string;
1020
+ label: string;
1021
+ options: {
1022
+ value: string;
1023
+ label: string;
1024
+ }[];
1025
+ multiple: boolean;
1026
+ initial: string[];
1027
+ hint?: string;
1028
+ })[];
1029
+ };
1030
+ type SyncView = {
1031
+ id: string;
1032
+ provider: string;
1033
+ providerLabel: string;
1034
+ brand: "cloudflare" | "github" | "other" | "railway" | "vercel";
1035
+ offered: boolean;
1036
+ destination: string;
1037
+ config: {
1038
+ [key: string]: string | number | boolean | null | Json[] | {
1039
+ [key: string]: Json;
1040
+ };
1041
+ };
1042
+ credential: string;
1043
+ createdAt: string;
1044
+ createdBy: string;
1045
+ paused: boolean;
1046
+ running: boolean;
1047
+ lastRunAt: string | null;
1048
+ lastStatus: "failed" | "ok" | "partial" | null;
1049
+ lastError: string | null;
1050
+ synced: number;
1051
+ pending: number;
1052
+ skipped: {
1053
+ key: string;
1054
+ reason: string;
1055
+ }[];
1056
+ };
1057
+ type Json = string | number | boolean | null | Json[] | {
1058
+ [key: string]: Json;
1059
+ };
1060
+ //#endregion
1061
+ //#region src/sync-fields.d.ts
1062
+ type FormValues = Record<string, string | string[]>;
1063
+ declare function initialValues(provider: SyncProviderInfo): FormValues;
1064
+ /** Whether the rest of the form makes the field meaningful. */
1065
+ declare function isAsked(field: SyncField, values: FormValues): boolean;
1066
+ /** The label of the first required field left empty, or null when the form can be sent. */
1067
+ declare function firstMissing(provider: SyncProviderInfo, values: FormValues): string | null;
1068
+ /**
1069
+ * The provider's config. Text is trimmed, and an optional field left empty
1070
+ * is left out rather than sent as "", which the server rightly refuses.
1071
+ */
1072
+ declare function configFromForm(provider: SyncProviderInfo, values: FormValues): Record<string, unknown>;
1073
+ /**
1074
+ * The config from `name=value` arguments, as the CLI takes them. A field with
1075
+ * several options takes them comma-separated, and one left out gets what the
1076
+ * form preselects. Text goes as typed, for the server to check.
1077
+ */
1078
+ declare function configFromArguments(provider: SyncProviderInfo, assignments: readonly string[]): Record<string, unknown>;
1079
+ //#endregion
1080
+ //#region src/index.d.ts
1081
+ type RouteKey = keyof Api;
1082
+ /** What a caller sends: the body, or the query string for a GET. */
1083
+ type RouteInput<K extends RouteKey> = Api[K]['input'];
1084
+ /** What comes back, as JSON. */
1085
+ type RouteOutput<K extends RouteKey> = Api[K]['output'];
1086
+ type ParamNames<Pattern> = Pattern extends `${string}:${infer Name}/${infer Rest}` ? Name | ParamNames<`/${Rest}`> : Pattern extends `${string}:${infer Name}` ? Name : never;
1087
+ /** `GET /members/:member` takes `{ member }`. */
1088
+ type Params<Key> = { [Name in ParamNames<Key>]: string; };
1089
+ type Transport = (request: Request) => Promise<Response>;
1090
+ type ClientOptions = {
1091
+ /** The instance's origin, e.g. `https://coffre.acme.example`. */
1092
+ url: string;
1093
+ /** Sent with every request: a bearer token, a Cloudflare Access header. */
1094
+ headers?: () => HeadersInit | Promise<HeadersInit>;
1095
+ transport?: Transport;
1096
+ };
1097
+ /** The API's error shape, `{ error, message }`, with the HTTP status. */
1098
+ declare const COFFRE_ERROR: unique symbol;
1099
+ declare class CoffreError extends Error {
1100
+ /**
1101
+ * `@coffre/ui`'s prebuilt pages bundle a copy of this class, and a page is
1102
+ * handed a client the server made with this package's. So `instanceof`
1103
+ * asks for the mark every copy leaves, rather than for this copy's prototype.
1104
+ */
1105
+ static [Symbol.hasInstance](value: unknown): boolean;
1106
+ readonly [COFFRE_ERROR] = true;
1107
+ readonly status: number;
1108
+ readonly code: string;
1109
+ /** The vault's own code when it refused: `no_grant`, `removed`, `bulk_limit`, ... */
1110
+ readonly reason: string | undefined;
1111
+ constructor(status: number, code: string, message: string, reason?: string);
1112
+ }
1113
+ 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>];
1114
+ declare function createClient(options: ClientOptions): {
1115
+ call: <K extends RouteKey>(key: K, ...[params, input]: Args<K>) => Promise<RouteOutput<K>>;
1116
+ /** How this instance signs people in. Answers anyone, signed in or not. */
1117
+ auth: () => Promise<AuthInfo>;
1118
+ /** Who I am, and every place I can reach. */
1119
+ me: () => Promise<{
1120
+ principal: {
1121
+ type: "service" | "user";
1122
+ id: string;
1123
+ };
1124
+ registered: boolean;
1125
+ tampered: boolean;
1126
+ instanceRole: "owner" | "root-admin" | "user";
1127
+ isRootAdmin: boolean;
1128
+ canReadAudit: boolean;
1129
+ environments: {
1130
+ project: string;
1131
+ environment: string;
1132
+ permissions: ("audit.read" | "environment.manage" | "grant.manage" | "project.manage" | "secret.archive" | "secret.read" | "secret.write")[];
1133
+ }[];
1134
+ }>;
1135
+ projects: {
1136
+ /** With their environments. */
1137
+ list: () => Promise<{
1138
+ projects: {
1139
+ slug: string;
1140
+ name: string;
1141
+ archivedAt: string | null;
1142
+ permissions: ("audit.read" | "environment.manage" | "grant.manage" | "project.manage" | "secret.archive" | "secret.read" | "secret.write")[];
1143
+ environments: {
1144
+ slug: string;
1145
+ name: string;
1146
+ accessible: boolean;
1147
+ details: null | {
1148
+ archivedAt: string | null;
1149
+ secretCount: number | null;
1150
+ };
1151
+ }[];
1152
+ }[];
1153
+ }>;
1154
+ create: (project: string, input: RouteInput<"PUT /projects/:project">) => Promise<{
1155
+ project: {
1156
+ slug: string;
1157
+ name: string;
1158
+ archivedAt: string | null;
1159
+ };
1160
+ created: boolean;
1161
+ }>;
1162
+ update: (project: string, patch: RouteInput<"PATCH /projects/:project">) => Promise<{
1163
+ project: {
1164
+ slug: string;
1165
+ name: string;
1166
+ archivedAt: string | null;
1167
+ };
1168
+ }>;
1169
+ };
1170
+ environments: {
1171
+ create: (path: string, input: RouteInput<"PUT /projects/:project/:environment">) => Promise<{
1172
+ environment: {
1173
+ slug: string;
1174
+ name: string;
1175
+ archivedAt: string | null;
1176
+ };
1177
+ created: boolean;
1178
+ }>;
1179
+ update: (path: string, patch: RouteInput<"PATCH /projects/:project/:environment">) => Promise<{
1180
+ environment: {
1181
+ slug: string;
1182
+ name: string;
1183
+ archivedAt: string | null;
1184
+ };
1185
+ }>;
1186
+ };
1187
+ secrets: {
1188
+ /** Keys, versions and who changed what; never values. */
1189
+ list: (path: string) => Promise<{
1190
+ permissions: ("audit.read" | "environment.manage" | "grant.manage" | "project.manage" | "secret.archive" | "secret.read" | "secret.write")[];
1191
+ keys: {
1192
+ key: string;
1193
+ archived: boolean;
1194
+ version: number | null;
1195
+ updatedAt: string | null;
1196
+ updatedBy: string | null;
1197
+ }[];
1198
+ }>;
1199
+ /** Decrypts one secret, or every secret in an environment. Logged in your name. */
1200
+ reveal: (path: string) => Promise<{
1201
+ operationId: string;
1202
+ values: {
1203
+ [key: string]: string;
1204
+ };
1205
+ }>;
1206
+ /** One transaction, a version and an audit entry per key; `null` archives. */
1207
+ set: (path: string, values: RouteInput<"PATCH /secrets/:project/:environment">) => Promise<SetResult>;
1208
+ /**
1209
+ * What `set` would do to each key, `added`, `changed`, `unchanged` or
1210
+ * `archived`, and nothing else: no value comes back and nothing is
1211
+ * written. Comparing opens the current values, logged as reads.
1212
+ */
1213
+ dryRun: (path: string, values: RouteInput<"PATCH /secrets/:project/:environment">) => Promise<DryRunResult>;
1214
+ history: (path: string) => Promise<{
1215
+ key: string;
1216
+ archived: boolean;
1217
+ versions: {
1218
+ version: number;
1219
+ createdAt: string;
1220
+ createdBy: string;
1221
+ current: boolean;
1222
+ kek: string;
1223
+ }[];
1224
+ }>;
1225
+ /** A new version holding the old one's value. */
1226
+ restore: (path: string, version: number) => Promise<{
1227
+ key: string;
1228
+ version: number;
1229
+ }>;
1230
+ rename: (path: string, key: string) => Promise<{
1231
+ key: string;
1232
+ archived: boolean;
1233
+ }>;
1234
+ update: (path: string, patch: RouteInput<"PATCH /secrets/:project/:environment/:key">) => Promise<{
1235
+ key: string;
1236
+ archived: boolean;
1237
+ }>;
1238
+ };
1239
+ members: {
1240
+ /** People and tokens, their role and their access; at a place, those who reach it. */
1241
+ list: (path?: string) => Promise<{
1242
+ members: {
1243
+ member: string;
1244
+ principalType: "service" | "user";
1245
+ principalId: string;
1246
+ instanceRole: "owner" | "root-admin" | "user";
1247
+ isRootAdmin: boolean;
1248
+ tampered: boolean;
1249
+ grants: {
1250
+ id: string;
1251
+ project: string;
1252
+ environment: string | null;
1253
+ role: "access-manager" | "auditor" | "developer" | "maintainer" | "owner" | "viewer";
1254
+ roleName: string;
1255
+ permissions: ("audit.read" | "environment.manage" | "grant.manage" | "project.manage" | "secret.archive" | "secret.read" | "secret.write")[];
1256
+ expiresAt: string | null;
1257
+ }[];
1258
+ }[];
1259
+ removed: {
1260
+ principalType: "service" | "user";
1261
+ principalId: string;
1262
+ toRotate: number;
1263
+ }[];
1264
+ }>;
1265
+ /** What they hold, and what to rotate if they leave. */
1266
+ get: (member: string) => Promise<{
1267
+ principalType: "service" | "user";
1268
+ principalId: string;
1269
+ status: "active" | "removed" | "tampered";
1270
+ instanceRole: "owner" | "root-admin" | "user";
1271
+ isRootAdmin: boolean;
1272
+ removedAt: string | null;
1273
+ removedBy: string | null;
1274
+ live: {
1275
+ grants: number;
1276
+ sessions: number;
1277
+ tokens: number;
1278
+ identities: number;
1279
+ };
1280
+ exposed: {
1281
+ project: string;
1282
+ environment: string;
1283
+ key: string;
1284
+ version: number;
1285
+ how: "read" | "wrote";
1286
+ at: string;
1287
+ }[];
1288
+ rotated: number;
1289
+ issuedTokens: {
1290
+ id: string;
1291
+ service: string;
1292
+ label: string | null;
1293
+ hint: string;
1294
+ expiresAt: string;
1295
+ lastUsedAt: string | null;
1296
+ }[];
1297
+ syncs: {
1298
+ id: string;
1299
+ provider: string;
1300
+ providerLabel: string;
1301
+ brand: "cloudflare" | "github" | "other" | "railway" | "vercel";
1302
+ offered: boolean;
1303
+ destination: string;
1304
+ config: {
1305
+ [key: string]: string | number | boolean | null | Json[] | {
1306
+ [key: string]: Json;
1307
+ };
1308
+ };
1309
+ credential: string;
1310
+ createdAt: string;
1311
+ createdBy: string;
1312
+ paused: boolean;
1313
+ running: boolean;
1314
+ lastRunAt: string | null;
1315
+ lastStatus: "failed" | "ok" | "partial" | null;
1316
+ lastError: string | null;
1317
+ synced: number;
1318
+ pending: number;
1319
+ skipped: {
1320
+ key: string;
1321
+ reason: string;
1322
+ }[];
1323
+ project: string;
1324
+ environment: string;
1325
+ }[];
1326
+ }>;
1327
+ add: (member: string, input?: RouteInput<"PUT /members/:member">) => Promise<{
1328
+ member: string;
1329
+ instanceRole: "owner" | "user";
1330
+ created: boolean;
1331
+ }>;
1332
+ /** Offboards; returns what to rotate. */
1333
+ remove: (member: string) => Promise<{
1334
+ revoked: {
1335
+ grants: number;
1336
+ sessions: number;
1337
+ tokens: number;
1338
+ identities: number;
1339
+ };
1340
+ report: {
1341
+ principalType: "service" | "user";
1342
+ principalId: string;
1343
+ status: "active" | "removed" | "tampered";
1344
+ instanceRole: "owner" | "root-admin" | "user";
1345
+ isRootAdmin: boolean;
1346
+ removedAt: string | null;
1347
+ removedBy: string | null;
1348
+ live: {
1349
+ grants: number;
1350
+ sessions: number;
1351
+ tokens: number;
1352
+ identities: number;
1353
+ };
1354
+ exposed: {
1355
+ project: string;
1356
+ environment: string;
1357
+ key: string;
1358
+ version: number;
1359
+ how: "read" | "wrote";
1360
+ at: string;
1361
+ }[];
1362
+ rotated: number;
1363
+ issuedTokens: {
1364
+ id: string;
1365
+ service: string;
1366
+ label: string | null;
1367
+ hint: string;
1368
+ expiresAt: string;
1369
+ lastUsedAt: string | null;
1370
+ }[];
1371
+ syncs: {
1372
+ id: string;
1373
+ provider: string;
1374
+ providerLabel: string;
1375
+ brand: "cloudflare" | "github" | "other" | "railway" | "vercel";
1376
+ offered: boolean;
1377
+ destination: string;
1378
+ config: {
1379
+ [key: string]: string | number | boolean | null | Json[] | {
1380
+ [key: string]: Json;
1381
+ };
1382
+ };
1383
+ credential: string;
1384
+ createdAt: string;
1385
+ createdBy: string;
1386
+ paused: boolean;
1387
+ running: boolean;
1388
+ lastRunAt: string | null;
1389
+ lastStatus: "failed" | "ok" | "partial" | null;
1390
+ lastError: string | null;
1391
+ synced: number;
1392
+ pending: number;
1393
+ skipped: {
1394
+ key: string;
1395
+ reason: string;
1396
+ }[];
1397
+ project: string;
1398
+ environment: string;
1399
+ }[];
1400
+ };
1401
+ }>;
1402
+ };
1403
+ tokens: {
1404
+ list: (member: string) => Promise<{
1405
+ tokens: {
1406
+ id: string;
1407
+ label: string | null;
1408
+ hint: string;
1409
+ createdAt: string;
1410
+ createdBy: string;
1411
+ expiresAt: string;
1412
+ lastUsedAt: string | null;
1413
+ lastUsedIp: string | null;
1414
+ }[];
1415
+ }>;
1416
+ /** The value is in the answer, and only there. */
1417
+ issue: (member: string, input: RouteInput<"POST /members/:member/tokens">) => Promise<{
1418
+ id: string;
1419
+ token: string;
1420
+ expiresAt: string;
1421
+ }>;
1422
+ revoke: (member: string, id: string) => Promise<{
1423
+ revoked: true;
1424
+ }>;
1425
+ };
1426
+ access: {
1427
+ /** What they should hold at each place; the server applies the difference. `null` revokes. */
1428
+ set: (member: string, access: RouteInput<"PATCH /access/:member">) => Promise<{
1429
+ changes: {
1430
+ [key: string]: "created" | "revoked" | "unchanged" | "updated";
1431
+ };
1432
+ }>;
1433
+ };
1434
+ /** Where I am signed in. Only where coffre runs its own sign-in. */
1435
+ sessions: {
1436
+ list: () => Promise<{
1437
+ sessions: {
1438
+ id: string;
1439
+ kind: "browser" | "cli";
1440
+ label: string | null;
1441
+ hint: string;
1442
+ provider: string | null;
1443
+ createdAt: string;
1444
+ expiresAt: string;
1445
+ lastUsedAt: string | null;
1446
+ lastUsedIp: string | null;
1447
+ current: boolean;
1448
+ }[];
1449
+ }>;
1450
+ revoke: (id: string) => Promise<{
1451
+ revoked: true;
1452
+ }>;
1453
+ };
1454
+ /** The accounts I sign in with. */
1455
+ identities: {
1456
+ list: () => Promise<{
1457
+ identities: {
1458
+ id: string;
1459
+ provider: string;
1460
+ email: string | null;
1461
+ createdAt: string;
1462
+ lastSignInAt: string | null;
1463
+ }[];
1464
+ }>;
1465
+ unlink: (id: string) => Promise<{
1466
+ unlinked: true;
1467
+ }>;
1468
+ };
1469
+ /** A `coffre login` waiting for someone to approve it, by the code it shows. */
1470
+ deviceLogins: {
1471
+ get: (code: string) => Promise<{
1472
+ request: null | {
1473
+ userCode: string;
1474
+ clientLabel: string | null;
1475
+ clientIp: string | null;
1476
+ createdAt: string;
1477
+ expiresAt: string;
1478
+ };
1479
+ sessionDays: number;
1480
+ }>;
1481
+ decide: (code: string, approve: boolean) => Promise<{
1482
+ decided: true;
1483
+ }>;
1484
+ };
1485
+ syncs: {
1486
+ /** Where a sync can push on this instance, and what each asks for. */
1487
+ providers: () => Promise<{
1488
+ providers: {
1489
+ brand: "cloudflare" | "github" | "other" | "railway" | "vercel";
1490
+ id: string;
1491
+ credential: {
1492
+ placeholder: string;
1493
+ hint: string;
1494
+ };
1495
+ label: string;
1496
+ fields: ({
1497
+ type: "text";
1498
+ name: string;
1499
+ label: string;
1500
+ placeholder: string;
1501
+ optional?: boolean;
1502
+ hint?: string;
1503
+ when?: {
1504
+ field: string;
1505
+ is: string[];
1506
+ };
1507
+ } | {
1508
+ type: "options";
1509
+ name: string;
1510
+ label: string;
1511
+ options: {
1512
+ value: string;
1513
+ label: string;
1514
+ }[];
1515
+ multiple: boolean;
1516
+ initial: string[];
1517
+ hint?: string;
1518
+ })[];
1519
+ }[];
1520
+ }>;
1521
+ list: (path: string) => Promise<{
1522
+ syncs: {
1523
+ id: string;
1524
+ provider: string;
1525
+ providerLabel: string;
1526
+ brand: "cloudflare" | "github" | "other" | "railway" | "vercel";
1527
+ offered: boolean;
1528
+ destination: string;
1529
+ config: {
1530
+ [key: string]: string | number | boolean | null | Json[] | {
1531
+ [key: string]: Json;
1532
+ };
1533
+ };
1534
+ credential: string;
1535
+ createdAt: string;
1536
+ createdBy: string;
1537
+ paused: boolean;
1538
+ running: boolean;
1539
+ lastRunAt: string | null;
1540
+ lastStatus: "failed" | "ok" | "partial" | null;
1541
+ lastError: string | null;
1542
+ synced: number;
1543
+ pending: number;
1544
+ skipped: {
1545
+ key: string;
1546
+ reason: string;
1547
+ }[];
1548
+ }[];
1549
+ canManage: boolean;
1550
+ }>;
1551
+ add: (path: string, input: RouteInput<"POST /syncs/:project/:environment">) => Promise<{
1552
+ id: string;
1553
+ provider: string;
1554
+ providerLabel: string;
1555
+ brand: "cloudflare" | "github" | "other" | "railway" | "vercel";
1556
+ offered: boolean;
1557
+ destination: string;
1558
+ config: {
1559
+ [key: string]: string | number | boolean | null | Json[] | {
1560
+ [key: string]: Json;
1561
+ };
1562
+ };
1563
+ credential: string;
1564
+ createdAt: string;
1565
+ createdBy: string;
1566
+ paused: boolean;
1567
+ running: boolean;
1568
+ lastRunAt: string | null;
1569
+ lastStatus: "failed" | "ok" | "partial" | null;
1570
+ lastError: string | null;
1571
+ synced: number;
1572
+ pending: number;
1573
+ skipped: {
1574
+ key: string;
1575
+ reason: string;
1576
+ }[];
1577
+ }>;
1578
+ update: (id: string, patch: RouteInput<"PATCH /syncs/by-id/:id">) => Promise<{
1579
+ id: string;
1580
+ provider: string;
1581
+ providerLabel: string;
1582
+ brand: "cloudflare" | "github" | "other" | "railway" | "vercel";
1583
+ offered: boolean;
1584
+ destination: string;
1585
+ config: {
1586
+ [key: string]: string | number | boolean | null | Json[] | {
1587
+ [key: string]: Json;
1588
+ };
1589
+ };
1590
+ credential: string;
1591
+ createdAt: string;
1592
+ createdBy: string;
1593
+ paused: boolean;
1594
+ running: boolean;
1595
+ lastRunAt: string | null;
1596
+ lastStatus: "failed" | "ok" | "partial" | null;
1597
+ lastError: string | null;
1598
+ synced: number;
1599
+ pending: number;
1600
+ skipped: {
1601
+ key: string;
1602
+ reason: string;
1603
+ }[];
1604
+ }>;
1605
+ remove: (id: string) => Promise<{
1606
+ id: string;
1607
+ provider: string;
1608
+ providerLabel: string;
1609
+ brand: "cloudflare" | "github" | "other" | "railway" | "vercel";
1610
+ offered: boolean;
1611
+ destination: string;
1612
+ config: {
1613
+ [key: string]: string | number | boolean | null | Json[] | {
1614
+ [key: string]: Json;
1615
+ };
1616
+ };
1617
+ credential: string;
1618
+ createdAt: string;
1619
+ createdBy: string;
1620
+ paused: boolean;
1621
+ running: boolean;
1622
+ lastRunAt: string | null;
1623
+ lastStatus: "failed" | "ok" | "partial" | null;
1624
+ lastError: string | null;
1625
+ synced: number;
1626
+ pending: number;
1627
+ skipped: {
1628
+ key: string;
1629
+ reason: string;
1630
+ }[];
1631
+ }>;
1632
+ run: (id: string) => Promise<{
1633
+ sync: {
1634
+ id: string;
1635
+ provider: string;
1636
+ providerLabel: string;
1637
+ brand: "cloudflare" | "github" | "other" | "railway" | "vercel";
1638
+ offered: boolean;
1639
+ destination: string;
1640
+ config: {
1641
+ [key: string]: string | number | boolean | null | Json[] | {
1642
+ [key: string]: Json;
1643
+ };
1644
+ };
1645
+ credential: string;
1646
+ createdAt: string;
1647
+ createdBy: string;
1648
+ paused: boolean;
1649
+ running: boolean;
1650
+ lastRunAt: string | null;
1651
+ lastStatus: "failed" | "ok" | "partial" | null;
1652
+ lastError: string | null;
1653
+ synced: number;
1654
+ pending: number;
1655
+ skipped: {
1656
+ key: string;
1657
+ reason: string;
1658
+ }[];
1659
+ };
1660
+ outcome: {
1661
+ status: "busy";
1662
+ } | {
1663
+ status: "failed" | "ok" | "partial";
1664
+ upserted: string[];
1665
+ deleted: string[];
1666
+ failed: {
1667
+ key: string;
1668
+ operation: "delete" | "upsert";
1669
+ message: string;
1670
+ }[];
1671
+ error: string | null;
1672
+ };
1673
+ }>;
1674
+ };
1675
+ audit: {
1676
+ list: (query?: RouteInput<"GET /audit">) => Promise<{
1677
+ entries: {
1678
+ seq: number;
1679
+ author: "app" | "vault";
1680
+ occurredAt: string;
1681
+ actorType: "service" | "system" | "user";
1682
+ actorId: string;
1683
+ action: string;
1684
+ decision: "allow" | "deny";
1685
+ reason: string | null;
1686
+ detail: boolean;
1687
+ subject: string | null;
1688
+ project: string | null;
1689
+ environment: string | null;
1690
+ key: string | null;
1691
+ version: number | null;
1692
+ operationId: string | null;
1693
+ relatedSeq: number | null;
1694
+ requestId: string | null;
1695
+ metadata: {
1696
+ [key: string]: unknown;
1697
+ };
1698
+ }[];
1699
+ hidden?: {
1700
+ action: string;
1701
+ count: number;
1702
+ }[];
1703
+ }>;
1704
+ verify: () => Promise<{
1705
+ ok: true;
1706
+ through: number | null;
1707
+ entries: number;
1708
+ checkpoint: null | {
1709
+ seq: number;
1710
+ signedAt: string;
1711
+ };
1712
+ pending?: number;
1713
+ } | {
1714
+ ok: false;
1715
+ through: number | null;
1716
+ failedAtSeq: number | null;
1717
+ author: "app" | "vault";
1718
+ reason: string;
1719
+ }>;
1720
+ /** What an escrowed key is checked against: public material, owners and root admins only. */
1721
+ keys: () => Promise<{
1722
+ app: {
1723
+ keyId: string;
1724
+ };
1725
+ vault: {
1726
+ current: {
1727
+ vaultId: string;
1728
+ provider: string;
1729
+ };
1730
+ checks: {
1731
+ seq: number;
1732
+ vaultId: string;
1733
+ provider: string;
1734
+ version: string;
1735
+ wrapped: string;
1736
+ }[];
1737
+ };
1738
+ }>;
1739
+ };
1740
+ };
1741
+ type CoffreClient = ReturnType<typeof createClient>;
1742
+ type ImportAction = Exclude<DryRunOutcome, 'archived'>;
1743
+ /**
1744
+ * What writing these entries (a parsed `.env` file) would do, from a dry run
1745
+ * of the write: the server compares, so no value leaves it, and the values it
1746
+ * opens to compare are logged as reads. `changes` is what to pass to
1747
+ * `secrets.set`: the keys that differ, so an unchanged value does not become
1748
+ * a new version.
1749
+ */
1750
+ declare function planImport(coffre: CoffreClient, path: string, entries: readonly {
1751
+ key: string;
1752
+ value: string;
1753
+ }[]): Promise<{
1754
+ plan: {
1755
+ key: string;
1756
+ action: ImportAction;
1757
+ version: number | null;
1758
+ }[];
1759
+ changes: Record<string, string>;
1760
+ }>;
1761
+ //#endregion
1762
+ export { RemovedMember as A, DryRunResult as C, Member as D, Me as E, SessionRow as F, SetResult as I, SyncField as L, SecretKey as M, SecretVersion as N, OffboardingReport as O, ServiceTokenRow as P, SyncProviderInfo as R, DryRunOutcome as S, Json as T, isAsked as _, Params as a, AuditEntryView as b, RouteOutput as c, planImport as d, FormValues as f, initialValues as g, firstMissing as h, ImportAction as i, RunOutcome as j, ProjectSummary as k, Transport as l, configFromForm as m, CoffreClient as n, RouteInput as o, configFromArguments as p, CoffreError as r, RouteKey as s, ClientOptions as t, createClient as u, AccessValue as v, IdentityRow as w, AuthInfo as x, Api as y, SyncView as z };