@brftech/filex-core 0.31.0 → 0.33.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.
- package/README.md +26 -2
- package/dist/{CsvViewer-DxujFEM3.js → CsvViewer-CqWeV8VO.js} +22 -22
- package/dist/CsvViewer-CqWeV8VO.js.map +1 -0
- package/dist/{DrawioViewer-DCvWnX2t.js → DrawioViewer-BNALOB04.js} +16 -16
- package/dist/DrawioViewer-BNALOB04.js.map +1 -0
- package/dist/filex-core.js +9346 -8069
- package/dist/filex-core.js.map +1 -1
- package/dist/filex-core.umd.cjs +49 -49
- package/dist/filex-core.umd.cjs.map +1 -1
- package/dist/index.d.ts +235 -16
- package/dist/style.css +1 -1
- package/package.json +1 -1
- package/src/FileExplorer.vue +776 -246
- package/src/components/CommandPalette.vue +21 -5
- package/src/components/ConnectionsPanel.vue +2 -1
- package/src/components/E2eRecoveryUnlockModal.vue +29 -4
- package/src/components/FilterBar.vue +244 -0
- package/src/components/GalleryView.vue +12 -1
- package/src/components/GridView.vue +48 -5
- package/src/components/InspectorPanel.vue +231 -8
- package/src/components/ListView.vue +12 -3
- package/src/components/NFSExportsPanel.vue +2 -1
- package/src/components/PendingOpsTray.vue +1 -1
- package/src/components/PresenceBar.vue +3 -2
- package/src/components/S3KeysPanel.vue +2 -1
- package/src/components/SSHKeysPanel.vue +2 -1
- package/src/components/SecondaryPane.vue +28 -13
- package/src/components/SideNav.vue +161 -1
- package/src/components/StarButton.vue +2 -1
- package/src/components/TabBar.vue +2 -2
- package/src/components/ThemeGallery.vue +1 -1
- package/src/components/TokensPanel.vue +2 -1
- package/src/components/Toolbar.vue +244 -58
- package/src/components/ViewSwitcher.vue +81 -0
- package/src/composables/useFileApi.ts +49 -2
- package/src/composables/useLocale.ts +1 -1
- package/src/composables/useOperations.ts +3 -3
- package/src/composables/usePendingOps.ts +1 -1
- package/src/composables/useTabs.ts +1 -1
- package/src/composables/useUploadChunked.ts +39 -7
- package/src/index.ts +8 -2
- package/src/lib/e2ecrypto.ts +191 -3
- package/src/lib/fileFilters.ts +143 -0
- package/src/lib/listing.ts +47 -0
- package/src/lib/themes.ts +7 -7
- package/src/lib/transfer.ts +6 -6
- package/src/locales/en.ts +115 -0
- package/src/locales/index.ts +1 -0
- package/src/locales/resolve.ts +66 -0
- package/src/locales/tr.ts +116 -0
- package/src/modals/ConvertModal.vue +14 -12
- package/src/modals/NewFolderModal.vue +1 -1
- package/src/modals/PermissionsModal.vue +30 -13
- package/src/modals/PreviewModal.vue +9 -9
- package/src/styles/base.css +520 -26
- package/src/styles/variables.css +1 -1
- package/src/types/ExplorerConfig.ts +18 -2
- package/src/types/FileNode.ts +1 -1
- package/src/viewers/CsvViewer.vue +4 -4
- package/src/viewers/DrawioViewer.vue +2 -2
- package/dist/CsvViewer-DxujFEM3.js.map +0 -1
- package/dist/DrawioViewer-DCvWnX2t.js.map +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -54,6 +54,13 @@ declare type __VLS_Props_11 = {
|
|
|
54
54
|
/** ui-fix — mirror the main panel's virtual `.trash` row at storage root
|
|
55
55
|
* so both split panes list identical rows (no row-offset). Defaults on. */
|
|
56
56
|
trashVisible?: boolean;
|
|
57
|
+
/**
|
|
58
|
+
* The navigation panel is already offering Trash, so neither pane draws the
|
|
59
|
+
* virtual row. Passed down rather than worked out here: the panel belongs to
|
|
60
|
+
* the host explorer, and a pane that guessed at it is how the two halves of a
|
|
61
|
+
* split end up listing different rows.
|
|
62
|
+
*/
|
|
63
|
+
navOffersTrash?: boolean;
|
|
57
64
|
};
|
|
58
65
|
|
|
59
66
|
declare type __VLS_Props_12 = {
|
|
@@ -85,9 +92,15 @@ declare type __VLS_Props_14 = {
|
|
|
85
92
|
locale: LocaleCode;
|
|
86
93
|
/** The folder has a user recovery key slot (v2 markers created since 0.31). */
|
|
87
94
|
hasRecovery: boolean;
|
|
88
|
-
/**
|
|
89
|
-
|
|
90
|
-
|
|
95
|
+
/**
|
|
96
|
+
* Whether the escrow door applies to THIS folder — see escrowAvailability.
|
|
97
|
+
* 'predates' and 'other-key' are not "no escrow tab"; they are two
|
|
98
|
+
* different facts the dialog has to state, because an admin who knows the
|
|
99
|
+
* installation has escrow reads a missing tab as a bug and tries the key
|
|
100
|
+
* anyway.
|
|
101
|
+
*/
|
|
102
|
+
escrowState: EscrowAvailability;
|
|
103
|
+
/** Short id of the escrow key THIS FOLDER was sealed to, when it has one. */
|
|
91
104
|
escrowKid?: string | null;
|
|
92
105
|
busy?: boolean;
|
|
93
106
|
/** Set by the parent after a failed attempt. */
|
|
@@ -287,6 +300,40 @@ declare type __VLS_Props_9 = {
|
|
|
287
300
|
narrow?: boolean;
|
|
288
301
|
};
|
|
289
302
|
|
|
303
|
+
/**
|
|
304
|
+
* Give an EXISTING v2 folder an escrow slot, in place, using the folder
|
|
305
|
+
* password its owner has just typed.
|
|
306
|
+
*
|
|
307
|
+
* ── Why this exists ─────────────────────────────────────────────────
|
|
308
|
+
*
|
|
309
|
+
* Escrow used to be all-or-nothing at install time, and then adoptable but
|
|
310
|
+
* never retroactive: on any installation that had been running for a while,
|
|
311
|
+
* escrow covered only folders nobody had created yet. On a real deployment
|
|
312
|
+
* the folders that matter already exist, so "new folders only" means escrow
|
|
313
|
+
* covers nothing anyone cares about.
|
|
314
|
+
*
|
|
315
|
+
* The server still cannot do this, and that has not changed: adding a slot
|
|
316
|
+
* needs the folder master key, which needs a credential the server has never
|
|
317
|
+
* held. What CAN do it is the browser, at the one moment the password is in
|
|
318
|
+
* memory — exactly where `upgradeMarkerV1` already lives. Same moment, same
|
|
319
|
+
* shape, different slot.
|
|
320
|
+
*
|
|
321
|
+
* ⚠⚠ Accepting hands the operator of this installation a second, permanent
|
|
322
|
+
* way into this folder. It is the folder's owner who decides, from inside,
|
|
323
|
+
* with the password; no configuration change and no admin action can do it
|
|
324
|
+
* for them. The caller MUST say that in those words before calling this —
|
|
325
|
+
* see `e2e.escrowoffer.*` in the locales.
|
|
326
|
+
*
|
|
327
|
+
* ⚠ v2 only. A v1 marker has no slots at all; the path for those is
|
|
328
|
+
* `upgradeMarkerV1`, which already seals an escrow slot when the
|
|
329
|
+
* installation has a key and already discloses it. Two doors into the same
|
|
330
|
+
* room would be two chances to get the disclosure wrong.
|
|
331
|
+
*
|
|
332
|
+
* ⚠ No file is re-encrypted, moved or rewritten. Only `.filex-e2e.json`
|
|
333
|
+
* changes, and only by gaining `esc` (and losing `esc_declined`).
|
|
334
|
+
*/
|
|
335
|
+
export declare function addEscrowSlot(marker: E2eMarker, password: string, escrowPublicKey: string): Promise<E2eMarker>;
|
|
336
|
+
|
|
290
337
|
/**
|
|
291
338
|
* The self-service API-token surface (`/api/tokens`).
|
|
292
339
|
*
|
|
@@ -589,6 +636,19 @@ export declare function createMarker(password: string, iterations?: number): Pro
|
|
|
589
636
|
kek: CryptoKey;
|
|
590
637
|
}>;
|
|
591
638
|
|
|
639
|
+
/**
|
|
640
|
+
* Record that this folder's owner was offered an escrow slot and declined.
|
|
641
|
+
*
|
|
642
|
+
* A refusal is a decision, not a delay: without this the offer would come
|
|
643
|
+
* back on every single unlock, which is how people learn to click past
|
|
644
|
+
* security dialogs without reading them. Nothing about the folder's keys
|
|
645
|
+
* changes — the only effect is that filex stops asking.
|
|
646
|
+
*
|
|
647
|
+
* Reversible by `addEscrowSlot`, which is the way back for somebody who
|
|
648
|
+
* says no today and changes their mind next month.
|
|
649
|
+
*/
|
|
650
|
+
export declare function declineEscrowSlot(marker: E2eMarker, when: string): E2eMarker;
|
|
651
|
+
|
|
592
652
|
/**
|
|
593
653
|
* Decrypt a 'filexe2e' blob with the folder master key. Throws
|
|
594
654
|
* E2eDecryptError on a wrong key / tampered data, and a plain Error when the
|
|
@@ -612,6 +672,15 @@ declare type Density = 'comfortable' | 'compact';
|
|
|
612
672
|
*/
|
|
613
673
|
export declare function deriveKek(password: string, salt: Uint8Array, iterations: number): Promise<CryptoKey>;
|
|
614
674
|
|
|
675
|
+
/**
|
|
676
|
+
* The browser's preference, or `en`.
|
|
677
|
+
*
|
|
678
|
+
* ⚠ Guarded for a non-browser runtime: this package is imported by SSR and by
|
|
679
|
+
* unit tests under Node, where `navigator` is absent — and an exception here
|
|
680
|
+
* would take down the whole explorer over a language choice.
|
|
681
|
+
*/
|
|
682
|
+
export declare function detectLocale(): LocaleCode;
|
|
683
|
+
|
|
615
684
|
export declare const E2E_DEFAULT_ITERATIONS = 600000;
|
|
616
685
|
|
|
617
686
|
/** The only escrow algorithm this version understands. */
|
|
@@ -661,10 +730,19 @@ export declare const E2E_MAGIC = "filexe2e";
|
|
|
661
730
|
* - No key, password or recovery key is ever stored, logged or sent to a
|
|
662
731
|
* server. The FMK lives in an in-memory key ring and dies with the tab.
|
|
663
732
|
* - `deriveKek` imports non-extractable. Raw KEK bytes are produced ONLY
|
|
664
|
-
* by `deriveKekBits`, only
|
|
665
|
-
*
|
|
733
|
+
* by `deriveKekBits`, only for a marker whose FMK *is* the KEK
|
|
734
|
+
* (`upgradeMarkerV1`, and `addEscrowSlot` on a folder it produced), and
|
|
735
|
+
* only long enough to wrap them into a slot.
|
|
666
736
|
* - A folder created while escrow was off carries no escrow slot, so the
|
|
667
|
-
* escrow key cannot open it
|
|
737
|
+
* escrow key cannot open it, and nothing the OPERATOR does changes
|
|
738
|
+
* that — not enabling escrow, not adopting it, not any admin action or
|
|
739
|
+
* future version. That is arithmetic, not policy: adding a slot needs
|
|
740
|
+
* the folder master key, and the server has never held a credential
|
|
741
|
+
* that produces one.
|
|
742
|
+
* - The folder's OWNER can, from inside, with the password:
|
|
743
|
+
* `addEscrowSlot`. That is the only door, it opens from one side only,
|
|
744
|
+
* and it is the reason `escrowAvailability` says "not as things stand"
|
|
745
|
+
* rather than "never".
|
|
668
746
|
*
|
|
669
747
|
* File layout ('filexe2e' magic, fixed 97-byte header) — UNCHANGED in v2:
|
|
670
748
|
* [0..8) magic "filexe2e"
|
|
@@ -722,6 +800,23 @@ export declare interface E2eMarker {
|
|
|
722
800
|
rk?: E2eRecoverySlot;
|
|
723
801
|
/** v2 only, optional: the operator escrow slot. */
|
|
724
802
|
esc?: E2eEscrowSlot;
|
|
803
|
+
/**
|
|
804
|
+
* v2 only, optional: an ISO timestamp recording that this folder's owner
|
|
805
|
+
* was OFFERED an escrow slot and said no.
|
|
806
|
+
*
|
|
807
|
+
* It lives in the marker rather than in browser storage because the unit
|
|
808
|
+
* of the decision is the FOLDER, not the device: the same person opening
|
|
809
|
+
* the folder from their phone must not be asked again, and a decision
|
|
810
|
+
* that vanished when someone cleared their site data would be no decision
|
|
811
|
+
* at all. It travels with the folder through a move, a backup and a
|
|
812
|
+
* restore, for the same reason the key slots do.
|
|
813
|
+
*
|
|
814
|
+
* It holds no key material and hides nothing from the operator — it is a
|
|
815
|
+
* record of an answer, and its only effect is that filex stops asking.
|
|
816
|
+
* `addEscrowSlot` clears it, so a decline is reversible by the one person
|
|
817
|
+
* who can reverse it.
|
|
818
|
+
*/
|
|
819
|
+
esc_declined?: string;
|
|
725
820
|
}
|
|
726
821
|
|
|
727
822
|
/** User-recovery-key slot: HKDF salt + the FMK wrapped under the derived key. */
|
|
@@ -823,6 +918,41 @@ export declare function ensureHighlight(): Promise<unknown | null>;
|
|
|
823
918
|
*/
|
|
824
919
|
export declare function ensureMonaco(): Promise<unknown | null>;
|
|
825
920
|
|
|
921
|
+
/**
|
|
922
|
+
* Why the escrow door is, or is not, on offer for this folder.
|
|
923
|
+
*
|
|
924
|
+
* 'off' this installation has no escrow key at all.
|
|
925
|
+
* 'available' the folder is sealed to THIS installation's escrow key.
|
|
926
|
+
* 'predates' the installation has an escrow key, and this folder has no
|
|
927
|
+
* escrow slot: it was created before escrow existed here.
|
|
928
|
+
* 'other-key' the folder carries an escrow slot sealed to a DIFFERENT
|
|
929
|
+
* key id — it came from another installation, via a restore
|
|
930
|
+
* or a copied data directory.
|
|
931
|
+
*
|
|
932
|
+
* ⚠ 'predates' exists because escrow can be ADOPTED by an installation
|
|
933
|
+
* that already has folders (FILEX_INSTALLATION_E2E_ESCROW_ADOPT), and
|
|
934
|
+
* adoption is not retroactive: the folder's master key was wrapped to its
|
|
935
|
+
* recovery paths when the folder was created. Before this distinction
|
|
936
|
+
* existed the dialog simply showed no Escrow tab, which is true but says
|
|
937
|
+
* nothing — an admin who knows escrow is on reads a missing tab as a bug,
|
|
938
|
+
* tries the key anyway, and learns the real answer from a failure. The UI
|
|
939
|
+
* has to say it instead.
|
|
940
|
+
*
|
|
941
|
+
* ⚠⚠ 'predates' means "not as things stand", NOT "never". The folder's
|
|
942
|
+
* owner can add a slot from inside with the password (`addEscrowSlot`,
|
|
943
|
+
* offered at unlock). Any wording built on this state has to leave that
|
|
944
|
+
* door visible, or it tells an operator their escrow key can never reach a
|
|
945
|
+
* folder whose owner could hand it over this afternoon.
|
|
946
|
+
*
|
|
947
|
+
* ⚠ 'other-key' was a quieter lie: the dialog labelled the escrow field
|
|
948
|
+
* with the INSTALLATION's key id whatever the folder's slot said, so a
|
|
949
|
+
* folder restored from another install looked openable by the key the
|
|
950
|
+
* operator has, and was not.
|
|
951
|
+
*/
|
|
952
|
+
export declare type EscrowAvailability = 'off' | 'available' | 'predates' | 'other-key';
|
|
953
|
+
|
|
954
|
+
export declare function escrowAvailability(m: E2eMarker | null, installationKid: string | null | undefined): EscrowAvailability;
|
|
955
|
+
|
|
826
956
|
/**
|
|
827
957
|
* Stable short name for an escrow key: first 8 bytes of SHA-256(SPKI), hex.
|
|
828
958
|
* Written into every escrow slot so a marker says WHICH key opens it, and so
|
|
@@ -830,6 +960,27 @@ export declare function ensureMonaco(): Promise<unknown | null>;
|
|
|
830
960
|
*/
|
|
831
961
|
export declare function escrowKeyId(spkiB64: string): Promise<string>;
|
|
832
962
|
|
|
963
|
+
/**
|
|
964
|
+
* Whether this folder's owner should be offered an escrow slot, and whether
|
|
965
|
+
* they have already answered.
|
|
966
|
+
*
|
|
967
|
+
* 'n/a' nothing to offer: the installation has no escrow key, the
|
|
968
|
+
* folder already has a slot, or the marker is v1 (whose path
|
|
969
|
+
* is `upgradeMarkerV1`).
|
|
970
|
+
* 'offer' the offer applies and no answer has been recorded.
|
|
971
|
+
* 'declined' the offer applies and the owner said no. Do not ask again;
|
|
972
|
+
* leave a way back.
|
|
973
|
+
*
|
|
974
|
+
* ⚠ This deliberately does NOT look at whether the folder is unlocked. That
|
|
975
|
+
* is the caller's business, and it matters: the offer may only be shown
|
|
976
|
+
* after an unlock actually succeeded, because accepting needs the password
|
|
977
|
+
* and because asking someone who cannot open the folder to give away a key
|
|
978
|
+
* to it is asking the wrong person.
|
|
979
|
+
*/
|
|
980
|
+
export declare type EscrowOfferState = 'n/a' | 'offer' | 'declined';
|
|
981
|
+
|
|
982
|
+
export declare function escrowOfferState(m: E2eMarker | null, installationKid: string | null | undefined): EscrowOfferState;
|
|
983
|
+
|
|
833
984
|
export declare interface ExplorerConfig {
|
|
834
985
|
/**
|
|
835
986
|
* Modern shorthand: URL prefix for the standard /api/files/* layout.
|
|
@@ -872,7 +1023,7 @@ export declare interface ExplorerConfig {
|
|
|
872
1023
|
*/
|
|
873
1024
|
onlyOfficeConfig?: string;
|
|
874
1025
|
/**
|
|
875
|
-
* Standalone editor page base — when set, "
|
|
1026
|
+
* Standalone editor page base — when set, "Open" on an office file
|
|
876
1027
|
* opens `${openPageBase}?path=...&mode=edit` in a new tab instead
|
|
877
1028
|
* of the modal preview.
|
|
878
1029
|
*/
|
|
@@ -988,6 +1139,22 @@ export declare interface ExplorerConfig {
|
|
|
988
1139
|
* navigation panel starts expanded, the tab strip
|
|
989
1140
|
* and split pane are off, the gallery view mode and
|
|
990
1141
|
* the host's "How to connect" surface are hidden.
|
|
1142
|
+
* 'drive' — everything `simple` does, plus the shell an end
|
|
1143
|
+
* user already knows: one primary "New" menu, one
|
|
1144
|
+
* search field in the header (with its ⌘K/Ctrl+K
|
|
1145
|
+
* escalation into the command palette), a filter row
|
|
1146
|
+
* under the breadcrumb, Folders and Files as
|
|
1147
|
+
* labelled sections in grid view, the details panel
|
|
1148
|
+
* split into Details / Activity, and a storage line
|
|
1149
|
+
* under the navigation.
|
|
1150
|
+
*
|
|
1151
|
+
* ⚠ `drive` is a SUPERSET of `simple`, not a sibling: everything `simple`
|
|
1152
|
+
* turns off stays off, and the code asks `simpleUi` for those questions so a
|
|
1153
|
+
* later change to `simple` cannot silently miss `drive`. It is a third value
|
|
1154
|
+
* rather than a second boolean because "which chrome" is ONE question with
|
|
1155
|
+
* three answers — a `driveShell: true` next to `uiProfile: 'standard'` would
|
|
1156
|
+
* be a combination nobody can describe, and keeping that question single is
|
|
1157
|
+
* why `uiProfile` was a preset to begin with.
|
|
991
1158
|
*
|
|
992
1159
|
* Why it exists (GitHub #14): the reporter's users are not in IT and read
|
|
993
1160
|
* split panes, tabs and mount instructions as a file manager they would have
|
|
@@ -999,7 +1166,7 @@ export declare interface ExplorerConfig {
|
|
|
999
1166
|
* rest of the chrome differ. A viewer's own collapse choice, once made,
|
|
1000
1167
|
* outranks the profile — it is a per-viewer preference, not a policy.
|
|
1001
1168
|
*/
|
|
1002
|
-
uiProfile?: 'standard' | 'simple';
|
|
1169
|
+
uiProfile?: 'standard' | 'simple' | 'drive';
|
|
1003
1170
|
/**
|
|
1004
1171
|
* Render the navigation panel (Upload · Recent / Starred / Shared with me /
|
|
1005
1172
|
* Trash · the storage list). Collapsible to an icon rail by the viewer, whose
|
|
@@ -1324,6 +1491,8 @@ inspectorOpen?: boolean;
|
|
|
1324
1491
|
navOpen?: boolean;
|
|
1325
1492
|
navEnabled?: boolean;
|
|
1326
1493
|
viewModes?: ViewMode[];
|
|
1494
|
+
shell?: "classic" | "drive";
|
|
1495
|
+
scopeLabel?: string;
|
|
1327
1496
|
}> & Readonly<{
|
|
1328
1497
|
onAction?: ((key: string) => any) | undefined;
|
|
1329
1498
|
onUpload?: (() => any) | undefined;
|
|
@@ -1338,6 +1507,7 @@ onRefresh?: (() => any) | undefined;
|
|
|
1338
1507
|
"onToggle-nav"?: (() => any) | undefined;
|
|
1339
1508
|
"onOpen-theme"?: (() => any) | undefined;
|
|
1340
1509
|
"onOpen-shortcut-settings"?: (() => any) | undefined;
|
|
1510
|
+
"onOpen-palette"?: ((query: string) => any) | undefined;
|
|
1341
1511
|
}>, {
|
|
1342
1512
|
focusSearch: () => Promise<void>;
|
|
1343
1513
|
}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {} & {
|
|
@@ -1354,6 +1524,7 @@ refresh: () => any;
|
|
|
1354
1524
|
"toggle-nav": () => any;
|
|
1355
1525
|
"open-theme": () => any;
|
|
1356
1526
|
"open-shortcut-settings": () => any;
|
|
1527
|
+
"open-palette": (query: string) => any;
|
|
1357
1528
|
}, PublicProps, {}, false, {}, {}, GlobalComponents, GlobalDirectives, string, {
|
|
1358
1529
|
primaryEl: HTMLDivElement;
|
|
1359
1530
|
wideMoreBtnEl: HTMLButtonElement;
|
|
@@ -1463,6 +1634,8 @@ inspectorOpen?: boolean;
|
|
|
1463
1634
|
navOpen?: boolean;
|
|
1464
1635
|
navEnabled?: boolean;
|
|
1465
1636
|
viewModes?: ViewMode[];
|
|
1637
|
+
shell?: "classic" | "drive";
|
|
1638
|
+
scopeLabel?: string;
|
|
1466
1639
|
}> & Readonly<{
|
|
1467
1640
|
onAction?: ((key: string) => any) | undefined;
|
|
1468
1641
|
onUpload?: (() => any) | undefined;
|
|
@@ -1477,6 +1650,7 @@ onRefresh?: (() => any) | undefined;
|
|
|
1477
1650
|
"onToggle-nav"?: (() => any) | undefined;
|
|
1478
1651
|
"onOpen-theme"?: (() => any) | undefined;
|
|
1479
1652
|
"onOpen-shortcut-settings"?: (() => any) | undefined;
|
|
1653
|
+
"onOpen-palette"?: ((query: string) => any) | undefined;
|
|
1480
1654
|
}>, {
|
|
1481
1655
|
focusSearch: () => Promise<void>;
|
|
1482
1656
|
}, {}, {}, {}, {}> | null;
|
|
@@ -1496,6 +1670,7 @@ viewMode?: ViewMode;
|
|
|
1496
1670
|
thumbSrc?: (n: FileNode) => string | null;
|
|
1497
1671
|
keepBadgeFor?: (n: FileNode) => "kept" | "syncing" | "cloud" | "partial" | null;
|
|
1498
1672
|
trashVisible?: boolean;
|
|
1673
|
+
navOffersTrash?: boolean;
|
|
1499
1674
|
}> & Readonly<{
|
|
1500
1675
|
onTransfer?: ((p: {
|
|
1501
1676
|
sources: string[];
|
|
@@ -1550,6 +1725,7 @@ viewMode?: ViewMode;
|
|
|
1550
1725
|
thumbSrc?: (n: FileNode) => string | null;
|
|
1551
1726
|
keepBadgeFor?: (n: FileNode) => "kept" | "syncing" | "cloud" | "partial" | null;
|
|
1552
1727
|
trashVisible?: boolean;
|
|
1728
|
+
navOffersTrash?: boolean;
|
|
1553
1729
|
}> & Readonly<{
|
|
1554
1730
|
onTransfer?: ((p: {
|
|
1555
1731
|
sources: string[];
|
|
@@ -2054,7 +2230,7 @@ export declare interface OperationInput {
|
|
|
2054
2230
|
percent: number | null;
|
|
2055
2231
|
status: OperationStatus;
|
|
2056
2232
|
error?: string | null;
|
|
2057
|
-
/** Queue op accepted but not started yet ("
|
|
2233
|
+
/** Queue op accepted but not started yet ("Queued"). */
|
|
2058
2234
|
queued?: boolean;
|
|
2059
2235
|
/** Progress counters for queue ops (3/5 items). */
|
|
2060
2236
|
doneCount?: number;
|
|
@@ -2082,9 +2258,9 @@ export declare interface OperationInput {
|
|
|
2082
2258
|
* are registered per row so the panel can route user intent back to the
|
|
2083
2259
|
* owning surface without the store knowing any transport details.
|
|
2084
2260
|
*
|
|
2085
|
-
* Lifecycle rules (per the
|
|
2261
|
+
* Lifecycle rules (per the Operations Center contract):
|
|
2086
2262
|
* - running rows live in `active`;
|
|
2087
|
-
* - done/aborted rows linger in `active` for DONE_LINGER_MS ("
|
|
2263
|
+
* - done/aborted rows linger in `active` for DONE_LINGER_MS ("done"
|
|
2088
2264
|
* flash) then move to `history` (session-only, capped);
|
|
2089
2265
|
* - error rows are STICKY: they stay in `active` until the user
|
|
2090
2266
|
* dismisses or retries them — even after the source list swept them
|
|
@@ -2213,6 +2389,14 @@ onNav?: ((delta: number) => any) | undefined;
|
|
|
2213
2389
|
"onOpen-full"?: (() => any) | undefined;
|
|
2214
2390
|
}>, {}, {}, {}, {}, string, ComponentProvideOptions, false, {}, any>;
|
|
2215
2391
|
|
|
2392
|
+
/** surucu:d1 — `GET /api/files/quota/me` (quota.Snapshot). */
|
|
2393
|
+
declare interface QuotaSnapshot {
|
|
2394
|
+
used_bytes: number;
|
|
2395
|
+
quota_bytes: number;
|
|
2396
|
+
percent_used: number;
|
|
2397
|
+
unlimited: boolean;
|
|
2398
|
+
}
|
|
2399
|
+
|
|
2216
2400
|
export declare const RecentlyOpened: DefineComponent<__VLS_Props_5, {}, {}, {}, {}, ComponentOptionsMixin, ComponentOptionsMixin, {} & {
|
|
2217
2401
|
error: (message: string) => any;
|
|
2218
2402
|
open: (node: RecentNode) => any;
|
|
@@ -2260,6 +2444,31 @@ declare interface ResolveEmailResponse {
|
|
|
2260
2444
|
*/
|
|
2261
2445
|
export declare function resolveEndpoints(config: ExplorerConfig): EndpointMap;
|
|
2262
2446
|
|
|
2447
|
+
/**
|
|
2448
|
+
* Resolve the locale to render in.
|
|
2449
|
+
*
|
|
2450
|
+
* Order, and the reasoning for it:
|
|
2451
|
+
*
|
|
2452
|
+
* 1. **What the host asked for.** An explicit `locale` always wins. A host
|
|
2453
|
+
* that names a language has made a decision, and guessing over it would
|
|
2454
|
+
* make the prop advisory.
|
|
2455
|
+
* 2. **What the browser asks for**, via `navigator.languages` /
|
|
2456
|
+
* `navigator.language` — the same signal `Accept-Language` carries, and
|
|
2457
|
+
* the reason a Turkish reader gets Turkish without the embedder doing
|
|
2458
|
+
* anything.
|
|
2459
|
+
* 3. **`en`.**
|
|
2460
|
+
*
|
|
2461
|
+
* ⚠ Step 2 makes the same embed render differently for two people. That is
|
|
2462
|
+
* deliberate — it is what "follow the browser" means — but it also means a
|
|
2463
|
+
* screenshot, a test or a bug report about this component must state its
|
|
2464
|
+
* locale, because the component alone no longer determines it. Pass an
|
|
2465
|
+
* explicit `locale` anywhere the answer has to be stable.
|
|
2466
|
+
*
|
|
2467
|
+
* Matching is on the primary subtag, so `tr-TR` and `en-GB` resolve; anything
|
|
2468
|
+
* with no catalogue falls through rather than half-rendering.
|
|
2469
|
+
*/
|
|
2470
|
+
export declare function resolveLocale(explicit?: LocaleCode | '' | null): LocaleCode;
|
|
2471
|
+
|
|
2263
2472
|
/** How long an unfinished record is worth keeping. The server sweeps its own
|
|
2264
2473
|
* staging after FILEX_UPLOAD_STAGING_TTL (24 h by default); a note that
|
|
2265
2474
|
* outlives the bytes it describes only produces a confusing "resuming…" that
|
|
@@ -2945,10 +3154,17 @@ export declare interface UploadOptions {
|
|
|
2945
3154
|
onDone?: (job: UploadJob, result: UploadResult) => void;
|
|
2946
3155
|
onError?: (job: UploadJob, err: Error) => void;
|
|
2947
3156
|
/**
|
|
2948
|
-
* Wait for the backend transfer before resolving.
|
|
2949
|
-
*
|
|
2950
|
-
*
|
|
2951
|
-
*
|
|
3157
|
+
* Wait for the backend transfer before resolving. Defaults to TRUE, because
|
|
3158
|
+
* "the server has the bytes" and "the storage has the bytes" are different
|
|
3159
|
+
* claims and only the second one is an upload.
|
|
3160
|
+
*
|
|
3161
|
+
* ⚠ It used to default to false and no caller ever set it, so the job went
|
|
3162
|
+
* straight to `done` on the 202 — a transfer that failed afterwards in the
|
|
3163
|
+
* ops worker left the user looking at a finished upload for a file that was
|
|
3164
|
+
* never stored (issue #16: every file over the chunk threshold, on every S3
|
|
3165
|
+
* backend). The `transferring` phase is short for a healthy storage and is
|
|
3166
|
+
* the only place a failure can still be shown, so it is the default; pass
|
|
3167
|
+
* false to opt out where the wait is genuinely unwanted.
|
|
2952
3168
|
*/
|
|
2953
3169
|
waitForTransfer?: boolean;
|
|
2954
3170
|
}
|
|
@@ -3008,6 +3224,7 @@ export declare function useFileApi(config: ExplorerConfig): {
|
|
|
3008
3224
|
limit?: number;
|
|
3009
3225
|
scope?: GlobalSearchScope;
|
|
3010
3226
|
}) => Promise<GlobalSearchHit[]>;
|
|
3227
|
+
quotaMe: () => Promise<QuotaSnapshot | null>;
|
|
3011
3228
|
subfolders: (path: string) => Promise<{
|
|
3012
3229
|
folders: FileNode[];
|
|
3013
3230
|
}>;
|
|
@@ -3038,7 +3255,9 @@ export declare function useFileApi(config: ExplorerConfig): {
|
|
|
3038
3255
|
uploadMultipart: (path: string, files: File[], onProgress?: (p: number) => void) => Promise<ManagerResponse>;
|
|
3039
3256
|
downloadUrl: (path: string) => string;
|
|
3040
3257
|
previewUrl: (path: string) => string;
|
|
3041
|
-
fetchBlob: (path: string
|
|
3258
|
+
fetchBlob: (path: string, opts?: {
|
|
3259
|
+
fresh?: boolean;
|
|
3260
|
+
}) => Promise<{
|
|
3042
3261
|
url: string;
|
|
3043
3262
|
blob: Blob;
|
|
3044
3263
|
mime: string;
|