@axium/storage 0.18.12 → 0.19.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/dist/client/api.d.ts +2 -2
- package/dist/client/api.js +2 -2
- package/dist/common.d.ts +21 -4
- package/dist/common.js +12 -2
- package/dist/server/api.js +4 -1
- package/package.json +1 -1
- package/routes/files/+layout.ts +5 -1
- package/routes/files/usage/+page.svelte +1 -2
- package/routes/files/usage/+page.ts +1 -1
package/dist/client/api.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { GetItemOptions, StorageItemUpdate, UserStorage, UserStorageInfo } from '../common.js';
|
|
1
|
+
import type { GetItemOptions, StorageItemUpdate, UserStorage, UserStorageInfo, UserStorageOptions } from '../common.js';
|
|
2
2
|
import { StorageItemMetadata } from '../common.js';
|
|
3
3
|
import '../polyfills.js';
|
|
4
4
|
export interface UploadOptions {
|
|
@@ -27,7 +27,7 @@ export declare function getDirectoryMetadata(parentId: string): Promise<StorageI
|
|
|
27
27
|
export declare function downloadItem(fileId: string): Promise<Blob>;
|
|
28
28
|
export declare function updateItemMetadata(fileId: string, metadata: StorageItemUpdate): Promise<StorageItemMetadata>;
|
|
29
29
|
export declare function deleteItem(fileId: string): Promise<StorageItemMetadata>;
|
|
30
|
-
export declare function getUserStorage(userId: string): Promise<UserStorage>;
|
|
30
|
+
export declare function getUserStorage(userId: string, options?: UserStorageOptions): Promise<UserStorage>;
|
|
31
31
|
export declare function getUserStats(userId: string): Promise<UserStorageInfo>;
|
|
32
32
|
export declare function getUserTrash(userId: string): Promise<StorageItemMetadata[]>;
|
|
33
33
|
export declare function itemsSharedWith(userId: string): Promise<StorageItemMetadata[]>;
|
package/dist/client/api.js
CHANGED
|
@@ -143,8 +143,8 @@ export async function updateItemMetadata(fileId, metadata) {
|
|
|
143
143
|
export async function deleteItem(fileId) {
|
|
144
144
|
return await fetchAPI('DELETE', 'storage/item/:id', undefined, fileId);
|
|
145
145
|
}
|
|
146
|
-
export async function getUserStorage(userId) {
|
|
147
|
-
return await fetchAPI('GET', 'users/:id/storage',
|
|
146
|
+
export async function getUserStorage(userId, options = {}) {
|
|
147
|
+
return await fetchAPI('GET', 'users/:id/storage', options, userId);
|
|
148
148
|
}
|
|
149
149
|
export async function getUserStats(userId) {
|
|
150
150
|
return await fetchAPI('OPTIONS', 'users/:id/storage', undefined, userId);
|
package/dist/common.d.ts
CHANGED
|
@@ -9,7 +9,7 @@ export declare const StorageItemUpdate: z.ZodObject<{
|
|
|
9
9
|
}, z.core.$strip>;
|
|
10
10
|
export type StorageItemUpdate = z.infer<typeof StorageItemUpdate>;
|
|
11
11
|
export declare const GetItemOptions: z.ZodObject<{
|
|
12
|
-
parents: z.ZodOptional<z.
|
|
12
|
+
parents: z.ZodOptional<z.ZodBoolean>;
|
|
13
13
|
}, z.core.$strip>;
|
|
14
14
|
export interface GetItemOptions extends z.infer<typeof GetItemOptions> {
|
|
15
15
|
}
|
|
@@ -57,6 +57,10 @@ export declare const StorageItemMetadata: z.ZodObject<{
|
|
|
57
57
|
export interface StorageItemMetadata<T extends Record<string, unknown> = Record<string, unknown>> extends z.infer<typeof StorageItemMetadata> {
|
|
58
58
|
metadata: T;
|
|
59
59
|
}
|
|
60
|
+
export declare const StorageItemSorting: z.ZodObject<{
|
|
61
|
+
descending: z.ZodOptional<z.ZodBoolean>;
|
|
62
|
+
by: z.ZodLiteral<"name" | "createdAt" | "modifiedAt" | "size">;
|
|
63
|
+
}, z.core.$strip>;
|
|
60
64
|
export declare const syncProtocolVersion = 0;
|
|
61
65
|
export declare const StorageLimits: z.ZodObject<{
|
|
62
66
|
item_size: z.ZodInt;
|
|
@@ -140,6 +144,14 @@ export declare const UserStorage: z.ZodObject<{
|
|
|
140
144
|
}, z.core.$strip>;
|
|
141
145
|
export interface UserStorage extends z.infer<typeof UserStorage> {
|
|
142
146
|
}
|
|
147
|
+
export declare const UserStorageOptions: z.ZodDefault<z.ZodObject<{
|
|
148
|
+
sort: z.ZodOptional<z.ZodObject<{
|
|
149
|
+
descending: z.ZodOptional<z.ZodBoolean>;
|
|
150
|
+
by: z.ZodLiteral<"name" | "createdAt" | "modifiedAt" | "size">;
|
|
151
|
+
}, z.core.$strip>>;
|
|
152
|
+
}, z.core.$strip>>;
|
|
153
|
+
export interface UserStorageOptions extends z.infer<typeof UserStorageOptions> {
|
|
154
|
+
}
|
|
143
155
|
/**
|
|
144
156
|
* Formats:
|
|
145
157
|
*
|
|
@@ -281,7 +293,12 @@ declare const StorageAPI: {
|
|
|
281
293
|
lastModified: z.ZodCoercedDate<unknown>;
|
|
282
294
|
lastTrashed: z.ZodNullable<z.ZodCoercedDate<unknown>>;
|
|
283
295
|
}, z.core.$strip>;
|
|
284
|
-
readonly GET: z.ZodObject<{
|
|
296
|
+
readonly GET: readonly [z.ZodDefault<z.ZodObject<{
|
|
297
|
+
sort: z.ZodOptional<z.ZodObject<{
|
|
298
|
+
descending: z.ZodOptional<z.ZodBoolean>;
|
|
299
|
+
by: z.ZodLiteral<"name" | "createdAt" | "modifiedAt" | "size">;
|
|
300
|
+
}, z.core.$strip>>;
|
|
301
|
+
}, z.core.$strip>>, z.ZodObject<{
|
|
285
302
|
items: z.ZodArray<z.ZodObject<{
|
|
286
303
|
createdAt: z.ZodCoercedDate<unknown>;
|
|
287
304
|
dataURL: z.ZodString;
|
|
@@ -332,7 +349,7 @@ declare const StorageAPI: {
|
|
|
332
349
|
itemCount: z.ZodInt;
|
|
333
350
|
lastModified: z.ZodCoercedDate<unknown>;
|
|
334
351
|
lastTrashed: z.ZodNullable<z.ZodCoercedDate<unknown>>;
|
|
335
|
-
}, z.core.$strip
|
|
352
|
+
}, z.core.$strip>];
|
|
336
353
|
};
|
|
337
354
|
readonly 'users/:id/storage/root': {
|
|
338
355
|
readonly GET: z.ZodArray<z.ZodObject<{
|
|
@@ -590,7 +607,7 @@ declare const StorageAPI: {
|
|
|
590
607
|
};
|
|
591
608
|
readonly 'storage/item/:id': {
|
|
592
609
|
readonly GET: readonly [z.ZodObject<{
|
|
593
|
-
parents: z.ZodOptional<z.
|
|
610
|
+
parents: z.ZodOptional<z.ZodBoolean>;
|
|
594
611
|
}, z.core.$strip>, z.ZodObject<{
|
|
595
612
|
createdAt: z.ZodCoercedDate<unknown>;
|
|
596
613
|
dataURL: z.ZodString;
|
package/dist/common.js
CHANGED
|
@@ -12,7 +12,7 @@ export const StorageItemUpdate = z
|
|
|
12
12
|
.partial();
|
|
13
13
|
export const GetItemOptions = z
|
|
14
14
|
.object({
|
|
15
|
-
parents: z.
|
|
15
|
+
parents: z.boolean(),
|
|
16
16
|
})
|
|
17
17
|
.partial();
|
|
18
18
|
export const StorageItemMetadata = z.object({
|
|
@@ -33,6 +33,10 @@ export const StorageItemMetadata = z.object({
|
|
|
33
33
|
acl: AccessControl.array().optional(),
|
|
34
34
|
parents: z.object({ id: z.uuid(), name: z.string() }).array().optional(),
|
|
35
35
|
});
|
|
36
|
+
export const StorageItemSorting = z.object({
|
|
37
|
+
descending: z.boolean().optional(),
|
|
38
|
+
by: z.literal(['createdAt', 'modifiedAt', 'name', 'size']),
|
|
39
|
+
});
|
|
36
40
|
export const syncProtocolVersion = 0;
|
|
37
41
|
export const StorageLimits = z.object({
|
|
38
42
|
/** The maximum size per item in MB */
|
|
@@ -56,6 +60,12 @@ export const UserStorage = z.object({
|
|
|
56
60
|
...UserStorageInfo.shape,
|
|
57
61
|
items: StorageItemMetadata.array(),
|
|
58
62
|
});
|
|
63
|
+
export const UserStorageOptions = z
|
|
64
|
+
.object({
|
|
65
|
+
sort: StorageItemSorting,
|
|
66
|
+
})
|
|
67
|
+
.partial()
|
|
68
|
+
.default({});
|
|
59
69
|
/**
|
|
60
70
|
* Formats:
|
|
61
71
|
*
|
|
@@ -135,7 +145,7 @@ export const UploadInitResult = z.discriminatedUnion('status', [
|
|
|
135
145
|
const StorageAPI = {
|
|
136
146
|
'users/:id/storage': {
|
|
137
147
|
OPTIONS: UserStorageInfo,
|
|
138
|
-
GET: UserStorage,
|
|
148
|
+
GET: [UserStorageOptions, UserStorage],
|
|
139
149
|
},
|
|
140
150
|
'users/:id/storage/root': {
|
|
141
151
|
GET: StorageItemMetadata.array(),
|
package/dist/server/api.js
CHANGED
|
@@ -6,7 +6,7 @@ import { error, json, parseBody, parseSearch, withError } from '@axium/server/re
|
|
|
6
6
|
import { addRoute } from '@axium/server/routes';
|
|
7
7
|
import { pick } from 'utilium';
|
|
8
8
|
import * as z from 'zod';
|
|
9
|
-
import { batchFormatVersion, GetItemOptions, StorageItemInit, StorageItemUpdate, syncProtocolVersion } from '../common.js';
|
|
9
|
+
import { batchFormatVersion, GetItemOptions, StorageItemInit, StorageItemUpdate, syncProtocolVersion, UserStorageOptions, } from '../common.js';
|
|
10
10
|
import '../polyfills.js';
|
|
11
11
|
import { getLimits } from './config.js';
|
|
12
12
|
import { deleteRecursive, getParents, getRecursive, getUserStats, parseItem } from './db.js';
|
|
@@ -127,6 +127,7 @@ addRoute({
|
|
|
127
127
|
async GET(request, { id: userId }) {
|
|
128
128
|
if (!getConfig('@axium/storage').enabled)
|
|
129
129
|
error(503, 'User storage is disabled');
|
|
130
|
+
const { sort } = parseSearch(request, UserStorageOptions);
|
|
130
131
|
await checkAuthForUser(request, userId);
|
|
131
132
|
const [items, stats, limits] = await Promise.all([
|
|
132
133
|
database
|
|
@@ -135,6 +136,8 @@ addRoute({
|
|
|
135
136
|
.select(acl.from('storage'))
|
|
136
137
|
.where('userId', '=', userId)
|
|
137
138
|
.where('trashedAt', 'is', null)
|
|
139
|
+
.limit(250)
|
|
140
|
+
.$if(!!sort, qb => qb.orderBy(sort.by, sort.descending ? 'desc' : 'asc'))
|
|
138
141
|
.execute(),
|
|
139
142
|
getUserStats(userId),
|
|
140
143
|
getLimits(userId),
|
package/package.json
CHANGED
package/routes/files/+layout.ts
CHANGED
|
@@ -19,7 +19,11 @@ export async function load({ url, route, parent }) {
|
|
|
19
19
|
},
|
|
20
20
|
{ name: text('page.files.tab.trash'), href: '/files/trash', icon: 'trash', active: route.id.endsWith('/files/trash') },
|
|
21
21
|
{ name: text('page.files.tab.shared'), href: '/files/shared', icon: 'user-group', active: route.id.endsWith('/files/shared') },
|
|
22
|
-
|
|
22
|
+
{ href: '/files/usage', icon: 'chart-pie-simple', active: route.id.endsWith('/files/usage'), mobile: true },
|
|
23
|
+
] satisfies (
|
|
24
|
+
| { name: string; href: LayoutRouteId; icon: string; active: boolean }
|
|
25
|
+
| { href: LayoutRouteId; icon: string; active: boolean; mobile: true }
|
|
26
|
+
)[];
|
|
23
27
|
|
|
24
28
|
return { session, tabs };
|
|
25
29
|
}
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { text } from '@axium/client';
|
|
3
3
|
import { NumberBar } from '@axium/client/components';
|
|
4
|
-
import '@axium/client/styles/list';
|
|
5
4
|
import { formatBytes } from '@axium/core/format';
|
|
6
5
|
import { List } from '@axium/storage/components';
|
|
7
6
|
|
|
8
7
|
const { data } = $props();
|
|
9
8
|
const { limits } = data.info;
|
|
10
9
|
|
|
11
|
-
let items = $state(data.info.items.filter(i => i.type != 'inode/directory')
|
|
10
|
+
let items = $state(data.info.items.filter(i => i.type != 'inode/directory'));
|
|
12
11
|
const usedBytes = $state(data.info.usedBytes);
|
|
13
12
|
|
|
14
13
|
let barText = $derived(
|
|
@@ -8,7 +8,7 @@ export async function load({ parent }) {
|
|
|
8
8
|
|
|
9
9
|
if (!session) redirect(307, '/login?after=/files/usage');
|
|
10
10
|
|
|
11
|
-
const info = await getUserStorage(session.userId);
|
|
11
|
+
const info = await getUserStorage(session.userId, { sort: { by: 'size', descending: true } });
|
|
12
12
|
|
|
13
13
|
return { info };
|
|
14
14
|
}
|