@putkoff/abstract-securefiles 0.0.47 → 0.0.49

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (197) hide show
  1. package/dist/ConfirmButton.d.ts +5 -0
  2. package/dist/CopyButton.d.ts +4 -0
  3. package/dist/FolderSelect.d.ts +6 -0
  4. package/dist/SecureFiles.d.ts +3 -0
  5. package/dist/ServerFiles.d.ts +6 -0
  6. package/dist/ShareDialog.d.ts +6 -0
  7. package/dist/UploadPanel.d.ts +6 -0
  8. package/dist/api.d.ts +46 -0
  9. package/dist/index.cjs +539 -956
  10. package/dist/index.cjs.map +1 -1
  11. package/dist/index.d.ts +4 -8
  12. package/dist/index.js +531 -902
  13. package/dist/index.js.map +1 -1
  14. package/dist/types.d.ts +54 -0
  15. package/package.json +15 -11
  16. package/src/ConfirmButton.tsx +35 -0
  17. package/src/CopyButton.tsx +24 -0
  18. package/src/FolderSelect.tsx +68 -0
  19. package/src/SecureFiles.tsx +344 -0
  20. package/src/ServerFiles.tsx +324 -0
  21. package/src/ShareDialog.tsx +148 -0
  22. package/src/UploadPanel.tsx +217 -0
  23. package/src/api.ts +119 -0
  24. package/src/index.ts +4 -8
  25. package/src/styles.css +432 -0
  26. package/src/types.ts +54 -0
  27. package/css.d.ts +0 -2
  28. package/dist/App/SecureFiles.d.ts +0 -4
  29. package/dist/App/index.d.ts +0 -1
  30. package/dist/FileHandlers/FileRow/imports.d.ts +0 -2
  31. package/dist/FileHandlers/FileRow/index.d.ts +0 -1
  32. package/dist/FileHandlers/FileRow/src/index.d.ts +0 -1
  33. package/dist/FileHandlers/FileRow/src/row_utils.d.ts +0 -2
  34. package/dist/FileHandlers/FileTable/imports.d.ts +0 -4
  35. package/dist/FileHandlers/FileTable/index.d.ts +0 -1
  36. package/dist/FileHandlers/FileTable/src/index.d.ts +0 -1
  37. package/dist/FileHandlers/FileTable/src/table_utils.d.ts +0 -2
  38. package/dist/FileHandlers/ShareModal/imports.d.ts +0 -2
  39. package/dist/FileHandlers/ShareModal/index.d.ts +0 -1
  40. package/dist/FileHandlers/ShareModal/src/index.d.ts +0 -1
  41. package/dist/FileHandlers/ShareModal/src/share_utils.d.ts +0 -2
  42. package/dist/FileHandlers/Upload/imports.d.ts +0 -2
  43. package/dist/FileHandlers/Upload/index.d.ts +0 -1
  44. package/dist/FileHandlers/Upload/src/index.d.ts +0 -2
  45. package/dist/FileHandlers/Upload/src/upload_utils.d.ts +0 -2
  46. package/dist/FileHandlers/imports.d.ts +0 -4
  47. package/dist/FileHandlers/index.d.ts +0 -4
  48. package/dist/UI/index.d.ts +0 -28
  49. package/dist/file_utils/imports.d.ts +0 -2
  50. package/dist/file_utils/index.d.ts +0 -1
  51. package/dist/file_utils/src/cookieFetch.d.ts +0 -33
  52. package/dist/file_utils/src/delete_utils/imports.d.ts +0 -1
  53. package/dist/file_utils/src/delete_utils/index.d.ts +0 -1
  54. package/dist/file_utils/src/delete_utils/src/delete_row.d.ts +0 -2
  55. package/dist/file_utils/src/delete_utils/src/delete_select.d.ts +0 -4
  56. package/dist/file_utils/src/delete_utils/src/delete_selected.d.ts +0 -2
  57. package/dist/file_utils/src/delete_utils/src/index.d.ts +0 -3
  58. package/dist/file_utils/src/download_utils/imports.d.ts +0 -2
  59. package/dist/file_utils/src/download_utils/index.d.ts +0 -1
  60. package/dist/file_utils/src/download_utils/src/direct_download.d.ts +0 -3
  61. package/dist/file_utils/src/download_utils/src/download_file.d.ts +0 -6
  62. package/dist/file_utils/src/download_utils/src/download_select.d.ts +0 -2
  63. package/dist/file_utils/src/download_utils/src/index.d.ts +0 -5
  64. package/dist/file_utils/src/download_utils/src/target_downloads.d.ts +0 -4
  65. package/dist/file_utils/src/download_utils/src/trigger_download.d.ts +0 -2
  66. package/dist/file_utils/src/imports.d.ts +0 -2
  67. package/dist/file_utils/src/index.d.ts +0 -6
  68. package/dist/file_utils/src/list_utils/imports.d.ts +0 -1
  69. package/dist/file_utils/src/list_utils/index.d.ts +0 -1
  70. package/dist/file_utils/src/list_utils/src/index.d.ts +0 -1
  71. package/dist/file_utils/src/list_utils/src/list_utils.d.ts +0 -2
  72. package/dist/file_utils/src/select_utils/index.d.ts +0 -1
  73. package/dist/file_utils/src/select_utils/src/index.d.ts +0 -3
  74. package/dist/file_utils/src/select_utils/src/init_select_all.d.ts +0 -2
  75. package/dist/file_utils/src/select_utils/src/sync_header_checkbox.d.ts +0 -5
  76. package/dist/file_utils/src/select_utils/src/toggle_checkboxes.d.ts +0 -2
  77. package/dist/file_utils/src/share_utils/imports.d.ts +0 -1
  78. package/dist/file_utils/src/share_utils/index.d.ts +0 -1
  79. package/dist/file_utils/src/share_utils/src/index.d.ts +0 -1
  80. package/dist/file_utils/src/share_utils/src/share_utils.d.ts +0 -7
  81. package/dist/file_utils/src/upload_utils/imports.d.ts +0 -0
  82. package/dist/file_utils/src/upload_utils/index.d.ts +0 -1
  83. package/dist/file_utils/src/upload_utils/src/index.d.ts +0 -3
  84. package/dist/file_utils/src/upload_utils/src/patch_file_settings.d.ts +0 -2
  85. package/dist/file_utils/src/upload_utils/src/upload_file.d.ts +0 -2
  86. package/dist/file_utils/src/upload_utils/src/upload_files.d.ts +0 -5
  87. package/dist/hooks/imports.d.ts +0 -3
  88. package/dist/hooks/index.d.ts +0 -1
  89. package/dist/hooks/useFiles/imports.d.ts +0 -2
  90. package/dist/hooks/useFiles/index.d.ts +0 -1
  91. package/dist/hooks/useFiles/src/deleteFile.d.ts +0 -3
  92. package/dist/hooks/useFiles/src/index.d.ts +0 -6
  93. package/dist/hooks/useFiles/src/load.d.ts +0 -3
  94. package/dist/hooks/useFiles/src/patchShareSettings.d.ts +0 -3
  95. package/dist/hooks/useFiles/src/toggleShare.d.ts +0 -3
  96. package/dist/hooks/useFiles/src/useFiles.d.ts +0 -13
  97. package/dist/hooks/useFiles/src/useSaveShareSettings.d.ts +0 -7
  98. package/dist/imports.d.ts +0 -6
  99. package/dist/index.css +0 -1
  100. package/dist/styles/index.d.ts +0 -1
  101. package/dist/types/index.d.ts +0 -1
  102. package/dist/types/src/index.d.ts +0 -1
  103. package/dist/types/src/types.d.ts +0 -75
  104. package/index.ts +0 -1
  105. package/postcss.config.cjs +0 -8
  106. package/rollup.config.js +0 -38
  107. package/rollup.config.mjs +0 -35
  108. package/src/App/SecureFiles.tsx +0 -45
  109. package/src/App/index.ts +0 -1
  110. package/src/FileHandlers/FileRow/imports.ts +0 -2
  111. package/src/FileHandlers/FileRow/index.ts +0 -1
  112. package/src/FileHandlers/FileRow/src/index.ts +0 -1
  113. package/src/FileHandlers/FileRow/src/row_utils.tsx +0 -143
  114. package/src/FileHandlers/FileTable/imports.ts +0 -15
  115. package/src/FileHandlers/FileTable/index.ts +0 -1
  116. package/src/FileHandlers/FileTable/src/index.ts +0 -1
  117. package/src/FileHandlers/FileTable/src/table_utils.tsx +0 -251
  118. package/src/FileHandlers/ShareModal/imports.ts +0 -2
  119. package/src/FileHandlers/ShareModal/index.ts +0 -1
  120. package/src/FileHandlers/ShareModal/src/index.ts +0 -1
  121. package/src/FileHandlers/ShareModal/src/share_utils.tsx +0 -155
  122. package/src/FileHandlers/Upload/imports.ts +0 -3
  123. package/src/FileHandlers/Upload/index.ts +0 -1
  124. package/src/FileHandlers/Upload/src/index.ts +0 -2
  125. package/src/FileHandlers/Upload/src/upload_utils.tsx +0 -267
  126. package/src/FileHandlers/imports.ts +0 -17
  127. package/src/FileHandlers/index.ts +0 -4
  128. package/src/UI/index.tsx +0 -122
  129. package/src/custom.d.ts +0 -7
  130. package/src/file_utils/imports.ts +0 -2
  131. package/src/file_utils/index.ts +0 -1
  132. package/src/file_utils/src/cookieFetch.ts +0 -109
  133. package/src/file_utils/src/delete_utils/imports.ts +0 -1
  134. package/src/file_utils/src/delete_utils/index.ts +0 -1
  135. package/src/file_utils/src/delete_utils/src/delete_row.ts +0 -11
  136. package/src/file_utils/src/delete_utils/src/delete_select.ts +0 -10
  137. package/src/file_utils/src/delete_utils/src/delete_selected.ts +0 -15
  138. package/src/file_utils/src/delete_utils/src/index.ts +0 -3
  139. package/src/file_utils/src/download_utils/imports.ts +0 -3
  140. package/src/file_utils/src/download_utils/index.ts +0 -1
  141. package/src/file_utils/src/download_utils/src/direct_download.ts +0 -22
  142. package/src/file_utils/src/download_utils/src/download_file.ts +0 -25
  143. package/src/file_utils/src/download_utils/src/download_select.ts +0 -25
  144. package/src/file_utils/src/download_utils/src/index.ts +0 -5
  145. package/src/file_utils/src/download_utils/src/target_downloads.ts +0 -21
  146. package/src/file_utils/src/download_utils/src/trigger_download.ts +0 -14
  147. package/src/file_utils/src/imports.ts +0 -3
  148. package/src/file_utils/src/index.ts +0 -6
  149. package/src/file_utils/src/list_utils/imports.ts +0 -2
  150. package/src/file_utils/src/list_utils/index.ts +0 -1
  151. package/src/file_utils/src/list_utils/src/index.ts +0 -1
  152. package/src/file_utils/src/list_utils/src/list_utils.ts +0 -28
  153. package/src/file_utils/src/select_utils/index.ts +0 -1
  154. package/src/file_utils/src/select_utils/src/index.ts +0 -3
  155. package/src/file_utils/src/select_utils/src/init_select_all.ts +0 -37
  156. package/src/file_utils/src/select_utils/src/sync_header_checkbox.ts +0 -18
  157. package/src/file_utils/src/select_utils/src/toggle_checkboxes.ts +0 -11
  158. package/src/file_utils/src/share_utils/imports.ts +0 -1
  159. package/src/file_utils/src/share_utils/index.ts +0 -1
  160. package/src/file_utils/src/share_utils/src/index.ts +0 -1
  161. package/src/file_utils/src/share_utils/src/share_utils.ts +0 -20
  162. package/src/file_utils/src/upload_utils/imports.ts +0 -1
  163. package/src/file_utils/src/upload_utils/index.ts +0 -1
  164. package/src/file_utils/src/upload_utils/src/index.ts +0 -3
  165. package/src/file_utils/src/upload_utils/src/patch_file_settings.ts +0 -20
  166. package/src/file_utils/src/upload_utils/src/upload_file.ts +0 -27
  167. package/src/file_utils/src/upload_utils/src/upload_files.ts +0 -19
  168. package/src/hooks/imports.ts +0 -3
  169. package/src/hooks/index.ts +0 -1
  170. package/src/hooks/useFiles/imports.ts +0 -3
  171. package/src/hooks/useFiles/index.ts +0 -1
  172. package/src/hooks/useFiles/src/deleteFile.ts +0 -23
  173. package/src/hooks/useFiles/src/index.ts +0 -6
  174. package/src/hooks/useFiles/src/load.ts +0 -39
  175. package/src/hooks/useFiles/src/logs/clipit_logs.log +0 -0
  176. package/src/hooks/useFiles/src/logs/routes_bp.log +0 -0
  177. package/src/hooks/useFiles/src/patchShareSettings.ts +0 -27
  178. package/src/hooks/useFiles/src/toggleShare.ts +0 -28
  179. package/src/hooks/useFiles/src/useFiles.ts +0 -35
  180. package/src/hooks/useFiles/src/useSaveShareSettings.ts +0 -31
  181. package/src/imports.ts +0 -18
  182. package/src/styles/SecureFiles/App.css +0 -42
  183. package/src/styles/SecureFiles/index.css +0 -10
  184. package/src/styles/SecureFiles/logs/clipit_logs.log +0 -0
  185. package/src/styles/SecureFiles/logs/routes_bp.log +0 -0
  186. package/src/styles/SecureFiles/tailwind.css +0 -3
  187. package/src/styles/SecureFiles/window-manager.css +0 -283
  188. package/src/styles/SecureFilesStyles.module.css +0 -287
  189. package/src/styles/index.ts +0 -1
  190. package/src/types/index.ts +0 -1
  191. package/src/types/src/index.ts +0 -1
  192. package/src/types/src/types.ts +0 -88
  193. package/tailwind.config.cjs +0 -7
  194. package/testit.mjs +0 -11
  195. package/testit.ts +0 -3
  196. package/tsconfig.json +0 -27
  197. /package/src/{global.d.ts → css.d.ts} +0 -0
package/src/api.ts ADDED
@@ -0,0 +1,119 @@
1
+ import type { BrowseResult, LinkRoot, RootChallenge, SecureFile, ShareUpdate } from "./types";
2
+
3
+ export const DEFAULT_API_BASE = "https://api.abstractendeavors.com";
4
+
5
+ export class ApiError extends Error {
6
+ constructor(message: string, public status: number) {
7
+ super(message);
8
+ }
9
+ }
10
+
11
+ async function errorFrom(res: Response): Promise<ApiError> {
12
+ let message = `${res.status} ${res.statusText}`;
13
+ try {
14
+ const body = await res.json();
15
+ message = body?.message || body?.error || message;
16
+ } catch {
17
+ /* non-JSON error body */
18
+ }
19
+ if (res.status === 401) message = "Please log in to use Secure Files.";
20
+ return new ApiError(message, res.status);
21
+ }
22
+
23
+ export function createApi(apiBase: string = DEFAULT_API_BASE) {
24
+ const root = `${apiBase.replace(/\/+$/, "")}/secure-files`;
25
+
26
+ async function json<T>(path: string, init: RequestInit = {}): Promise<T> {
27
+ const res = await fetch(`${root}${path}`, {
28
+ credentials: "include",
29
+ ...init,
30
+ headers: { Accept: "application/json", ...(init.body ? { "Content-Type": "application/json" } : {}) },
31
+ });
32
+ if (!res.ok) throw await errorFrom(res);
33
+ return res.json();
34
+ }
35
+
36
+ return {
37
+ list: () => json<{ user_name: string; is_admin: boolean; files: SecureFile[] }>("/userInfo"),
38
+
39
+ roots: () => json<{ roots: LinkRoot[] }>("/admin/roots"),
40
+
41
+ requestRoot: (path: string) =>
42
+ json<{ challenge: RootChallenge }>("/admin/roots", { method: "POST", body: JSON.stringify({ path }) }),
43
+
44
+ confirmRoot: (nonce: string, signature: string, label?: string) =>
45
+ json<{ roots: LinkRoot[] }>("/admin/roots/confirm", {
46
+ method: "POST",
47
+ body: JSON.stringify({ nonce, signature, label }),
48
+ }),
49
+
50
+ removeRoot: (id: number) => json<{ roots: LinkRoot[] }>(`/admin/roots/${id}`, { method: "DELETE" }),
51
+
52
+ browse: (path: string) => json<BrowseResult>(`/admin/browse?path=${encodeURIComponent(path)}`),
53
+
54
+ link: (paths: string[], folder: string) =>
55
+ json<{ linked: string[]; errors: { path: string; error: string }[] }>("/admin/link", {
56
+ method: "POST",
57
+ body: JSON.stringify({ paths, folder }),
58
+ }),
59
+
60
+ updateShare: (update: ShareUpdate) =>
61
+ json<{ file: SecureFile }>("/files/share", { method: "PATCH", body: JSON.stringify(update) }),
62
+
63
+ remove: (ids: number[]) =>
64
+ json<{ removed: number[]; errors: { id: number; error: string }[] }>("/remove", {
65
+ method: "POST",
66
+ body: JSON.stringify({ ids }),
67
+ }),
68
+
69
+ async download(ids: number[], fallbackName: string): Promise<void> {
70
+ const res = await fetch(`${root}/download`, {
71
+ method: "POST",
72
+ credentials: "include",
73
+ headers: { "Content-Type": "application/json" },
74
+ body: JSON.stringify({ ids }),
75
+ });
76
+ if (!res.ok) throw await errorFrom(res);
77
+ const disposition = res.headers.get("Content-Disposition") || "";
78
+ const match = /filename\*?=(?:UTF-8'')?"?([^";]+)"?/i.exec(disposition);
79
+ const name = match ? decodeURIComponent(match[1]) : fallbackName;
80
+ const url = URL.createObjectURL(await res.blob());
81
+ const a = document.createElement("a");
82
+ a.href = url;
83
+ a.download = name;
84
+ document.body.appendChild(a);
85
+ a.click();
86
+ a.remove();
87
+ setTimeout(() => URL.revokeObjectURL(url), 1000);
88
+ },
89
+
90
+ upload(file: File, relPath: string, onProgress?: (fraction: number) => void): Promise<void> {
91
+ return new Promise((resolve, reject) => {
92
+ const form = new FormData();
93
+ form.append("file", file);
94
+ form.append("rel_path", relPath);
95
+ const xhr = new XMLHttpRequest();
96
+ xhr.open("POST", `${root}/upload`);
97
+ xhr.withCredentials = true;
98
+ xhr.upload.onprogress = (e) => {
99
+ if (e.lengthComputable) onProgress?.(e.loaded / e.total);
100
+ };
101
+ xhr.onload = () => {
102
+ if (xhr.status >= 200 && xhr.status < 300) return resolve();
103
+ let message = `Upload failed (${xhr.status})`;
104
+ try {
105
+ message = JSON.parse(xhr.responseText)?.message || message;
106
+ } catch {
107
+ /* non-JSON */
108
+ }
109
+ if (xhr.status === 401) message = "Please log in to use Secure Files.";
110
+ reject(new ApiError(message, xhr.status));
111
+ };
112
+ xhr.onerror = () => reject(new ApiError("Network error during upload", 0));
113
+ xhr.send(form);
114
+ });
115
+ },
116
+ };
117
+ }
118
+
119
+ export type SecureFilesApi = ReturnType<typeof createApi>;
package/src/index.ts CHANGED
@@ -1,8 +1,4 @@
1
- export { FileRow, ShareModal, FileTable, Upload } from './FileHandlers';
2
- export { useFiles } from './hooks';
3
- export * from './file_utils';
4
- export * from './hooks';
5
- export * from './UI';
6
- export * from './types';
7
- export * from './styles';
8
- export { SecureFiles } from './App'
1
+ export { default as SecureFiles } from "./SecureFiles";
2
+ export { createApi, DEFAULT_API_BASE, ApiError } from "./api";
3
+ export type { SecureFilesApi } from "./api";
4
+ export type { SecureFile, ShareUpdate, SecureFilesProps, LinkRoot, RootChallenge, BrowseResult } from "./types";
package/src/styles.css ADDED
@@ -0,0 +1,432 @@
1
+ .sf-root {
2
+ --sf-border: color-mix(in srgb, currentColor 22%, transparent);
3
+ --sf-subtle: color-mix(in srgb, currentColor 6%, transparent);
4
+ --sf-accent: #2563eb;
5
+ --sf-danger: #dc2626;
6
+ max-width: 1100px;
7
+ margin: 0 auto;
8
+ padding: 16px;
9
+ display: flex;
10
+ flex-direction: column;
11
+ gap: 16px;
12
+ font-size: 14px;
13
+ text-align: left;
14
+ }
15
+ .sf-root *,
16
+ .sf-root *::before,
17
+ .sf-root *::after {
18
+ box-sizing: border-box;
19
+ }
20
+ .sf-head {
21
+ display: flex;
22
+ align-items: baseline;
23
+ justify-content: space-between;
24
+ gap: 12px;
25
+ }
26
+ .sf-head h2 {
27
+ margin: 0;
28
+ font-size: 1.4em;
29
+ }
30
+ .sf-muted {
31
+ opacity: 0.7;
32
+ }
33
+ .sf-error {
34
+ color: var(--sf-danger);
35
+ }
36
+ .sf-row {
37
+ display: flex;
38
+ align-items: center;
39
+ gap: 8px;
40
+ flex-wrap: wrap;
41
+ }
42
+ .sf-row--end {
43
+ justify-content: flex-end;
44
+ }
45
+ .sf-field {
46
+ display: flex;
47
+ flex-direction: column;
48
+ gap: 4px;
49
+ flex: 1;
50
+ min-width: 200px;
51
+ }
52
+ .sf-input {
53
+ font: inherit;
54
+ color: inherit;
55
+ background: var(--sf-subtle);
56
+ border: 1px solid var(--sf-border);
57
+ border-radius: 6px;
58
+ padding: 6px 10px;
59
+ width: 100%;
60
+ min-width: 0;
61
+ }
62
+ .sf-row .sf-input {
63
+ flex: 1;
64
+ width: auto;
65
+ }
66
+ .sf-btn {
67
+ font: inherit;
68
+ color: inherit;
69
+ background: var(--sf-subtle);
70
+ border: 1px solid var(--sf-border);
71
+ border-radius: 6px;
72
+ padding: 5px 12px;
73
+ cursor: pointer;
74
+ white-space: nowrap;
75
+ }
76
+ .sf-btn:hover:not(:disabled) {
77
+ border-color: var(--sf-accent);
78
+ }
79
+ .sf-btn:disabled {
80
+ opacity: 0.45;
81
+ cursor: default;
82
+ }
83
+ .sf-btn--primary {
84
+ background: var(--sf-accent);
85
+ border-color: var(--sf-accent);
86
+ color: #fff;
87
+ }
88
+ .sf-btn--danger:hover:not(:disabled),
89
+ .sf-btn--armed {
90
+ border-color: var(--sf-danger);
91
+ color: var(--sf-danger);
92
+ }
93
+ .sf-btn--armed {
94
+ background: color-mix(in srgb, var(--sf-danger) 12%, transparent);
95
+ }
96
+ .sf-icon-btn {
97
+ font: inherit;
98
+ color: inherit;
99
+ background: none;
100
+ border: 1px solid transparent;
101
+ border-radius: 6px;
102
+ padding: 3px 6px;
103
+ cursor: pointer;
104
+ }
105
+ .sf-icon-btn:hover {
106
+ border-color: var(--sf-border);
107
+ }
108
+ .sf-upload {
109
+ display: flex;
110
+ flex-direction: column;
111
+ gap: 10px;
112
+ }
113
+ .sf-drop {
114
+ border: 2px dashed var(--sf-border);
115
+ border-radius: 12px;
116
+ padding: 28px 24px;
117
+ display: flex;
118
+ align-items: center;
119
+ gap: 20px;
120
+ cursor: pointer;
121
+ user-select: none;
122
+ transition: border-color 0.15s, background 0.15s, box-shadow 0.15s;
123
+ }
124
+ .sf-drop:hover,
125
+ .sf-drop:focus-visible {
126
+ border-color: var(--sf-accent);
127
+ box-shadow: 0 4px 14px color-mix(in srgb, currentColor 10%, transparent);
128
+ outline: none;
129
+ }
130
+ .sf-drop p {
131
+ margin: 0;
132
+ }
133
+ .sf-drop__icon {
134
+ width: 72px;
135
+ height: 72px;
136
+ flex-shrink: 0;
137
+ opacity: 0.6;
138
+ }
139
+ .sf-drop__title {
140
+ font-size: 1.1em;
141
+ font-weight: 600;
142
+ margin-bottom: 4px !important;
143
+ }
144
+ .sf-drop__count {
145
+ margin-top: 6px !important;
146
+ font-weight: 600;
147
+ color: var(--sf-accent);
148
+ }
149
+ .sf-drop--active {
150
+ border-color: var(--sf-accent);
151
+ background: color-mix(in srgb, var(--sf-accent) 8%, transparent);
152
+ }
153
+ .sf-drop--active .sf-drop__icon {
154
+ opacity: 1;
155
+ color: var(--sf-accent);
156
+ }
157
+ .sf-mode {
158
+ gap: 14px;
159
+ }
160
+ .sf-queue progress {
161
+ width: 120px;
162
+ }
163
+ .sf-upload > .sf-row {
164
+ align-items: flex-end;
165
+ }
166
+ .sf-queue {
167
+ list-style: none;
168
+ margin: 0;
169
+ padding: 0;
170
+ display: flex;
171
+ flex-direction: column;
172
+ gap: 4px;
173
+ max-height: 200px;
174
+ overflow: auto;
175
+ }
176
+ .sf-queue li {
177
+ display: flex;
178
+ justify-content: space-between;
179
+ gap: 12px;
180
+ }
181
+ .sf-queue__name {
182
+ overflow: hidden;
183
+ text-overflow: ellipsis;
184
+ white-space: nowrap;
185
+ }
186
+ .sf-toolbar {
187
+ display: flex;
188
+ justify-content: space-between;
189
+ gap: 12px;
190
+ flex-wrap: wrap;
191
+ }
192
+ .sf-search {
193
+ max-width: 320px;
194
+ }
195
+ .sf-table-wrap {
196
+ overflow-x: auto;
197
+ border: 1px solid var(--sf-border);
198
+ border-radius: 8px;
199
+ }
200
+ .sf-table {
201
+ width: 100%;
202
+ border-collapse: collapse;
203
+ }
204
+ .sf-table th,
205
+ .sf-table td {
206
+ padding: 8px 10px;
207
+ border-bottom: 1px solid var(--sf-border);
208
+ text-align: left;
209
+ vertical-align: middle;
210
+ }
211
+ .sf-table tbody tr:last-child td {
212
+ border-bottom: none;
213
+ }
214
+ .sf-table th {
215
+ font-weight: 600;
216
+ background: var(--sf-subtle);
217
+ }
218
+ .sf-col-check {
219
+ width: 36px;
220
+ }
221
+ .sf-col-actions {
222
+ text-align: right !important;
223
+ }
224
+ .sf-dir td {
225
+ background: var(--sf-subtle);
226
+ }
227
+ .sf-dir__toggle {
228
+ font: inherit;
229
+ font-weight: 600;
230
+ color: inherit;
231
+ background: none;
232
+ border: none;
233
+ padding: 0;
234
+ cursor: pointer;
235
+ }
236
+ .sf-busy {
237
+ opacity: 0.55;
238
+ }
239
+ .sf-pill {
240
+ font: inherit;
241
+ font-size: 12px;
242
+ color: inherit;
243
+ background: var(--sf-subtle);
244
+ border: 1px solid var(--sf-border);
245
+ border-radius: 999px;
246
+ padding: 2px 10px;
247
+ cursor: pointer;
248
+ }
249
+ .sf-pill--on {
250
+ background: color-mix(in srgb, #16a34a 18%, transparent);
251
+ border-color: #16a34a;
252
+ }
253
+ .sf-overlay {
254
+ position: fixed;
255
+ inset: 0;
256
+ background: rgba(0, 0, 0, 0.5);
257
+ display: flex;
258
+ align-items: center;
259
+ justify-content: center;
260
+ z-index: 1000;
261
+ padding: 16px;
262
+ }
263
+ .sf-dialog {
264
+ background: Canvas;
265
+ color: CanvasText;
266
+ border-radius: 10px;
267
+ padding: 18px 20px;
268
+ width: min(520px, 100%);
269
+ max-height: 90vh;
270
+ overflow: auto;
271
+ display: flex;
272
+ flex-direction: column;
273
+ gap: 12px;
274
+ text-align: left;
275
+ --sf-border: color-mix(in srgb, CanvasText 22%, transparent);
276
+ --sf-subtle: color-mix(in srgb, CanvasText 6%, transparent);
277
+ }
278
+ .sf-dialog__head {
279
+ display: flex;
280
+ justify-content: space-between;
281
+ align-items: center;
282
+ }
283
+ .sf-dialog__head h3 {
284
+ margin: 0;
285
+ }
286
+ .sf-dialog > .sf-muted {
287
+ margin: 0;
288
+ word-break: break-all;
289
+ }
290
+ .sf-dialog__foot {
291
+ justify-content: flex-end;
292
+ }
293
+ .sf-fieldset {
294
+ border: none;
295
+ margin: 0;
296
+ padding: 0;
297
+ display: flex;
298
+ flex-direction: column;
299
+ gap: 12px;
300
+ }
301
+ .sf-fieldset:disabled {
302
+ opacity: 0.5;
303
+ }
304
+ .sf-fieldset p {
305
+ margin: 0;
306
+ }
307
+ .sf-check {
308
+ display: flex;
309
+ align-items: center;
310
+ gap: 8px;
311
+ cursor: pointer;
312
+ }
313
+ .sf-check--inline {
314
+ display: inline-flex;
315
+ }
316
+ .sf-stack {
317
+ display: flex;
318
+ flex-direction: column;
319
+ gap: 12px;
320
+ }
321
+ .sf-stack p {
322
+ margin: 0;
323
+ }
324
+ .sf-row--bottom {
325
+ align-items: flex-end;
326
+ }
327
+ .sf-field--narrow {
328
+ flex: 0 1 200px;
329
+ min-width: 140px;
330
+ }
331
+ .sf-admin {
332
+ border: 1px solid var(--sf-border);
333
+ border-radius: 10px;
334
+ padding: 10px 14px;
335
+ }
336
+ .sf-admin > summary {
337
+ cursor: pointer;
338
+ font-weight: 600;
339
+ }
340
+ .sf-admin[open] > summary {
341
+ margin-bottom: 12px;
342
+ }
343
+ .sf-card {
344
+ border: 1px solid var(--sf-border);
345
+ border-radius: 8px;
346
+ padding: 12px;
347
+ display: flex;
348
+ flex-direction: column;
349
+ gap: 10px;
350
+ }
351
+ .sf-card h4 {
352
+ margin: 0;
353
+ }
354
+ .sf-card p {
355
+ margin: 0;
356
+ }
357
+ .sf-code {
358
+ font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
359
+ font-size: 12px;
360
+ resize: vertical;
361
+ }
362
+ .sf-roots {
363
+ list-style: none;
364
+ margin: 0;
365
+ padding: 0;
366
+ display: flex;
367
+ flex-direction: column;
368
+ gap: 6px;
369
+ }
370
+ .sf-roots li {
371
+ display: flex;
372
+ justify-content: space-between;
373
+ align-items: center;
374
+ gap: 12px;
375
+ }
376
+ .sf-root-select {
377
+ max-width: 420px;
378
+ }
379
+ .sf-browser {
380
+ border: 1px solid var(--sf-border);
381
+ border-radius: 6px;
382
+ max-height: 320px;
383
+ overflow: auto;
384
+ display: flex;
385
+ flex-direction: column;
386
+ }
387
+ .sf-browser > * {
388
+ padding: 5px 10px;
389
+ border-bottom: 1px solid var(--sf-border);
390
+ }
391
+ .sf-browser > *:last-child {
392
+ border-bottom: none;
393
+ }
394
+ .sf-browser__dir {
395
+ font: inherit;
396
+ color: inherit;
397
+ background: none;
398
+ border: none;
399
+ border-bottom: 1px solid var(--sf-border);
400
+ text-align: left;
401
+ cursor: pointer;
402
+ }
403
+ .sf-browser__dir:hover {
404
+ background: var(--sf-subtle);
405
+ }
406
+ .sf-browser__all {
407
+ background: var(--sf-subtle);
408
+ font-weight: 600;
409
+ }
410
+ .sf-browser__name {
411
+ flex: 1;
412
+ overflow: hidden;
413
+ text-overflow: ellipsis;
414
+ white-space: nowrap;
415
+ }
416
+ .sf-tag {
417
+ display: inline-block;
418
+ margin-left: 8px;
419
+ padding: 0 7px;
420
+ font-size: 11px;
421
+ border-radius: 999px;
422
+ border: 1px solid var(--sf-border);
423
+ vertical-align: middle;
424
+ }
425
+ .sf-tag--warn {
426
+ border-color: var(--sf-danger);
427
+ color: var(--sf-danger);
428
+ }
429
+ .sf-strike {
430
+ text-decoration: line-through;
431
+ opacity: 0.7;
432
+ }
package/src/types.ts ADDED
@@ -0,0 +1,54 @@
1
+ export interface SecureFile {
2
+ id: number;
3
+ filename: string;
4
+ filepath: string;
5
+ uploader_id: string;
6
+ shareable: boolean;
7
+ has_password: boolean;
8
+ download_count: number;
9
+ download_limit: number | null;
10
+ created_at: string | null;
11
+ share_url: string;
12
+ /** true when the entry points at a file elsewhere on the server instead of an upload */
13
+ linked: boolean;
14
+ source_path: string | null;
15
+ /** false when the file is missing on disk (or its allowed directory was removed) */
16
+ available: boolean;
17
+ }
18
+
19
+ export interface LinkRoot {
20
+ id: number;
21
+ path: string;
22
+ label: string | null;
23
+ exists: boolean;
24
+ }
25
+
26
+ export interface RootChallenge {
27
+ nonce: string;
28
+ message: string;
29
+ command: string;
30
+ expires: number;
31
+ }
32
+
33
+ export interface BrowseResult {
34
+ path: string;
35
+ root: string;
36
+ parent: string | null;
37
+ dirs: string[];
38
+ files: { name: string; path: string; size: number; linked_id: number | null }[];
39
+ truncated: boolean;
40
+ }
41
+
42
+ export interface ShareUpdate {
43
+ id: number;
44
+ shareable?: boolean;
45
+ download_limit?: number | null;
46
+ /** null/undefined = leave unchanged, "" = remove, otherwise the new password */
47
+ password?: string | null;
48
+ reset_count?: boolean;
49
+ }
50
+
51
+ export interface SecureFilesProps {
52
+ /** API origin; defaults to https://api.abstractendeavors.com */
53
+ apiBase?: string;
54
+ }
package/css.d.ts DELETED
@@ -1,2 +0,0 @@
1
- declare module '*.css';
2
- declare module '*.module.css';
@@ -1,4 +0,0 @@
1
- import './../styles/SecureFiles/index.css';
2
- import React from 'react';
3
- declare const SecureFiles: React.FC;
4
- export default SecureFiles;
@@ -1 +0,0 @@
1
- export { default as SecureFiles } from './SecureFiles';
@@ -1,2 +0,0 @@
1
- export type { FileRowProps } from './../imports';
2
- export { useState, Button, currentUsername } from './../imports';
@@ -1 +0,0 @@
1
- export { FileRow } from './src';
@@ -1 +0,0 @@
1
- export { default as FileRow } from './row_utils';
@@ -1,2 +0,0 @@
1
- import type { FileRowProps } from './../imports';
2
- export default function FileRow({ file, onDownload, onSettings, onToggleShare, onDelete, }: FileRowProps): import("react/jsx-runtime").JSX.Element;
@@ -1,4 +0,0 @@
1
- export { FileRow } from './../FileRow';
2
- export { ShareModal } from './../ShareModal';
3
- export type { FileItem, FileTableProps } from './../imports';
4
- export { useState, useFiles, downloadFile, Spinner, Input, currentUsername, Button } from './../imports';
@@ -1 +0,0 @@
1
- export { FileTable } from './src';
@@ -1 +0,0 @@
1
- export { default as FileTable } from './table_utils';
@@ -1,2 +0,0 @@
1
- import type { FileTableProps } from './../imports';
2
- export default function FileTable({ files, loading, error, onToggleShare, onPatchShare, onDelete }: FileTableProps): import("react/jsx-runtime").JSX.Element;
@@ -1,2 +0,0 @@
1
- export { Button, Checkbox, Input, ClipboardIcon, createPortal, useEffect, useRef, useState } from './../imports';
2
- export type { ShareModalProps } from './../imports';
@@ -1 +0,0 @@
1
- export { ShareModal } from './src';
@@ -1 +0,0 @@
1
- export { default as ShareModal } from './share_utils';
@@ -1,2 +0,0 @@
1
- import type { ShareModalProps } from './../../imports';
2
- export default function ShareModal({ file, onClose, onSave }: ShareModalProps): import("react").ReactPortal | null;
@@ -1,2 +0,0 @@
1
- export { Input, useFiles, Button, uploadFiles, useState, useRef, useCallback, CloudArrowUpIcon, currentUsername } from './../imports';
2
- export type { UploadProps, FileItem, QueuedFile } from './../imports';
@@ -1 +0,0 @@
1
- export { Upload } from './src';
@@ -1,2 +0,0 @@
1
- export { default as Upload } from './upload_utils';
2
- export type { QueuedFile, UploadProps } from './../../../types';
@@ -1,2 +0,0 @@
1
- import type { UploadProps } from './../imports';
2
- export default function Upload({ onUploaded }: UploadProps): import("react/jsx-runtime").JSX.Element;
@@ -1,4 +0,0 @@
1
- export type { QueuedFile, FileItem, FileTableProps, UploadProps, ShareModalProps, FileRowProps } from './../imports';
2
- export { CloudArrowUpIcon, currentUsername, Button, Checkbox, Input, Spinner, useEffect, useRef, useState, useCallback, ClipboardIcon, createPortal, } from './../imports';
3
- export { useFiles } from './../hooks';
4
- export { downloadFile, uploadFiles } from './../file_utils';