@axium/storage 0.11.2 → 0.13.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/db.json +3 -0
- package/dist/client/api.d.ts +1 -4
- package/dist/client/api.js +12 -47
- package/dist/client/cli.js +12 -12
- package/dist/client/local.d.ts +6 -2
- package/dist/client/local.js +2 -3
- package/dist/client/sync.js +1 -1
- package/dist/common.d.ts +294 -76
- package/dist/common.js +77 -1
- package/dist/server/cli.js +2 -2
- package/dist/server/config.d.ts +28 -22
- package/dist/server/config.js +43 -3
- package/package.json +4 -4
- package/routes/+layout.ts +1 -0
package/db.json
CHANGED
|
@@ -28,6 +28,9 @@
|
|
|
28
28
|
"itemId": { "type": "uuid", "required": true, "primary": true, "references": "storage.id", "onDelete": "cascade" },
|
|
29
29
|
"createdAt": { "type": "timestamptz", "required": true, "default": "now()" },
|
|
30
30
|
"permission": { "type": "integer", "required": true, "check": "permission >= 0 AND permission <= 5" }
|
|
31
|
+
},
|
|
32
|
+
"constraints": {
|
|
33
|
+
"PK_acl_storage": { "type": "primary_key", "on": ["userId", "itemId"] }
|
|
31
34
|
}
|
|
32
35
|
}
|
|
33
36
|
},
|
package/dist/client/api.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { StorageItemMetadata, StorageItemUpdate, UserStorage, UserStorageInfo } from '../common.js';
|
|
2
|
-
export declare function parseItem(result: StorageItemMetadata): StorageItemMetadata;
|
|
3
2
|
export interface UploadOptions {
|
|
4
3
|
parentId?: string;
|
|
5
4
|
name?: string;
|
|
@@ -7,9 +6,7 @@ export interface UploadOptions {
|
|
|
7
6
|
export declare function uploadItem(file: Blob | File, opt?: UploadOptions): Promise<StorageItemMetadata>;
|
|
8
7
|
export declare function updateItem(fileId: string, data: Blob): Promise<StorageItemMetadata>;
|
|
9
8
|
export declare function getItemMetadata(fileId: string): Promise<StorageItemMetadata>;
|
|
10
|
-
/**
|
|
11
|
-
* Gets the metadata for all items in a directory.
|
|
12
|
-
*/
|
|
9
|
+
/** Gets the metadata for all items in a directory. */
|
|
13
10
|
export declare function getDirectoryMetadata(parentId: string): Promise<StorageItemMetadata[]>;
|
|
14
11
|
export declare function downloadItem(fileId: string): Promise<Blob>;
|
|
15
12
|
export declare function updateItemMetadata(fileId: string, metadata: StorageItemUpdate): Promise<StorageItemMetadata>;
|
package/dist/client/api.js
CHANGED
|
@@ -20,16 +20,8 @@ async function _upload(method, url, data, extraHeaders = {}) {
|
|
|
20
20
|
const json = await response.json().catch(() => ({ message: 'Unknown server error (invalid JSON response)' }));
|
|
21
21
|
if (!response.ok)
|
|
22
22
|
throw new Error(json.message);
|
|
23
|
-
json.modifiedAt = new Date(json.modifiedAt);
|
|
24
23
|
return json;
|
|
25
24
|
}
|
|
26
|
-
export function parseItem(result) {
|
|
27
|
-
result.createdAt = new Date(result.createdAt);
|
|
28
|
-
result.modifiedAt = new Date(result.modifiedAt);
|
|
29
|
-
if (result.trashedAt)
|
|
30
|
-
result.trashedAt = new Date(result.trashedAt);
|
|
31
|
-
return result;
|
|
32
|
-
}
|
|
33
25
|
function rawStorage(fileId) {
|
|
34
26
|
const raw = '/raw/storage' + (fileId ? '/' + fileId : '');
|
|
35
27
|
if (prefix[0] == '/')
|
|
@@ -44,23 +36,17 @@ export async function uploadItem(file, opt = {}) {
|
|
|
44
36
|
headers['x-parent'] = opt.parentId;
|
|
45
37
|
if (opt.name)
|
|
46
38
|
headers['x-name'] = opt.name;
|
|
47
|
-
return
|
|
39
|
+
return await _upload('PUT', rawStorage(), file, headers);
|
|
48
40
|
}
|
|
49
41
|
export async function updateItem(fileId, data) {
|
|
50
|
-
return
|
|
42
|
+
return await _upload('POST', rawStorage(fileId), data);
|
|
51
43
|
}
|
|
52
44
|
export async function getItemMetadata(fileId) {
|
|
53
|
-
|
|
54
|
-
return parseItem(result);
|
|
45
|
+
return await fetchAPI('GET', 'storage/item/:id', undefined, fileId);
|
|
55
46
|
}
|
|
56
|
-
/**
|
|
57
|
-
* Gets the metadata for all items in a directory.
|
|
58
|
-
*/
|
|
47
|
+
/** Gets the metadata for all items in a directory. */
|
|
59
48
|
export async function getDirectoryMetadata(parentId) {
|
|
60
|
-
|
|
61
|
-
for (const item of result)
|
|
62
|
-
parseItem(item);
|
|
63
|
-
return result;
|
|
49
|
+
return await fetchAPI('GET', 'storage/directory/:id', undefined, parentId);
|
|
64
50
|
}
|
|
65
51
|
export async function downloadItem(fileId) {
|
|
66
52
|
const response = await fetch(rawStorage(fileId), {
|
|
@@ -71,44 +57,23 @@ export async function downloadItem(fileId) {
|
|
|
71
57
|
return await response.blob();
|
|
72
58
|
}
|
|
73
59
|
export async function updateItemMetadata(fileId, metadata) {
|
|
74
|
-
|
|
75
|
-
return parseItem(result);
|
|
60
|
+
return await fetchAPI('PATCH', 'storage/item/:id', metadata, fileId);
|
|
76
61
|
}
|
|
77
62
|
export async function deleteItem(fileId) {
|
|
78
|
-
|
|
79
|
-
return parseItem(result);
|
|
63
|
+
return await fetchAPI('DELETE', 'storage/item/:id', undefined, fileId);
|
|
80
64
|
}
|
|
81
65
|
export async function getUserStorage(userId) {
|
|
82
|
-
|
|
83
|
-
result.lastModified = new Date(result.lastModified);
|
|
84
|
-
if (result.lastTrashed)
|
|
85
|
-
result.lastTrashed = new Date(result.lastTrashed);
|
|
86
|
-
for (const item of result.items)
|
|
87
|
-
parseItem(item);
|
|
88
|
-
return result;
|
|
66
|
+
return await fetchAPI('GET', 'users/:id/storage', undefined, userId);
|
|
89
67
|
}
|
|
90
68
|
export async function getUserStats(userId) {
|
|
91
|
-
|
|
92
|
-
result.lastModified = new Date(result.lastModified);
|
|
93
|
-
if (result.lastTrashed)
|
|
94
|
-
result.lastTrashed = new Date(result.lastTrashed);
|
|
95
|
-
return result;
|
|
69
|
+
return await fetchAPI('OPTIONS', 'users/:id/storage', undefined, userId);
|
|
96
70
|
}
|
|
97
71
|
export async function getUserTrash(userId) {
|
|
98
|
-
|
|
99
|
-
for (const item of result)
|
|
100
|
-
parseItem(item);
|
|
101
|
-
return result;
|
|
72
|
+
return await fetchAPI('GET', 'users/:id/storage/trash', undefined, userId);
|
|
102
73
|
}
|
|
103
74
|
export async function itemsSharedWith(userId) {
|
|
104
|
-
|
|
105
|
-
for (const item of result)
|
|
106
|
-
parseItem(item);
|
|
107
|
-
return result;
|
|
75
|
+
return await fetchAPI('GET', 'users/:id/storage/shared', undefined, userId);
|
|
108
76
|
}
|
|
109
77
|
export async function getUserStorageRoot(userId) {
|
|
110
|
-
|
|
111
|
-
for (const item of result)
|
|
112
|
-
parseItem(item);
|
|
113
|
-
return result;
|
|
78
|
+
return await fetchAPI('GET', 'users/:id/storage/root', undefined, userId);
|
|
114
79
|
}
|
package/dist/client/cli.js
CHANGED
|
@@ -16,7 +16,7 @@ const cli = program
|
|
|
16
16
|
.helpGroup('Plugins:')
|
|
17
17
|
.description('CLI integration for @axium/storage')
|
|
18
18
|
.option('-q, --quiet', 'Suppress output')
|
|
19
|
-
.hook('preAction',
|
|
19
|
+
.hook('preAction', action => {
|
|
20
20
|
const opts = action.optsWithGlobals();
|
|
21
21
|
if (opts.quiet)
|
|
22
22
|
setQuiet(true);
|
|
@@ -33,11 +33,11 @@ cli.command('ls')
|
|
|
33
33
|
.description('List the contents of a folder')
|
|
34
34
|
.argument('<path>', 'remote folder path')
|
|
35
35
|
.option('-l, --long', 'Show more details')
|
|
36
|
-
.option('-h, --human-readable', 'Show sizes in human readable format')
|
|
37
|
-
.action(async function (path) {
|
|
38
|
-
const { users } = await syncCache().catch(io.
|
|
36
|
+
.option('-h, --human-readable', 'Show sizes in human readable format', false)
|
|
37
|
+
.action(async function axium_files_ls(path) {
|
|
38
|
+
const { users } = await syncCache().catch(io.exit);
|
|
39
39
|
const { long, humanReadable } = this.optsWithGlobals();
|
|
40
|
-
const items = await getDirectory(path).catch(io.
|
|
40
|
+
const items = await getDirectory(path).catch(io.exit);
|
|
41
41
|
if (!long) {
|
|
42
42
|
console.log(items.map(colorItem).join('\t'));
|
|
43
43
|
return;
|
|
@@ -53,14 +53,14 @@ cli.command('mkdir')
|
|
|
53
53
|
const pathParts = path.split('/');
|
|
54
54
|
const name = pathParts.pop();
|
|
55
55
|
const parentPath = pathParts.join('/');
|
|
56
|
-
const parent = !parentPath ? null : await resolveItem(parentPath).catch(io.
|
|
56
|
+
const parent = !parentPath ? null : await resolveItem(parentPath).catch(io.exit);
|
|
57
57
|
if (parent) {
|
|
58
58
|
if (!parent)
|
|
59
59
|
io.exit('Could not resolve parent folder.');
|
|
60
60
|
if (parent.type != 'inode/directory')
|
|
61
61
|
io.exit('Parent path is not a directory.');
|
|
62
62
|
}
|
|
63
|
-
await api.uploadItem(new Blob([], { type: 'inode/directory' }), { parentId: parent?.id, name }).catch(io.
|
|
63
|
+
await api.uploadItem(new Blob([], { type: 'inode/directory' }), { parentId: parent?.id, name }).catch(io.exit);
|
|
64
64
|
});
|
|
65
65
|
cli.command('status')
|
|
66
66
|
.option('-v, --verbose', 'Show more details')
|
|
@@ -144,8 +144,8 @@ cli.command('sync')
|
|
|
144
144
|
.addOption(new Option('--delete <mode>', 'Delete local/remote files that were deleted remotely/locally')
|
|
145
145
|
.choices(['local', 'remote', 'none'])
|
|
146
146
|
.default('none'))
|
|
147
|
-
.option('-d, --dry-run', 'Show what would be done, but do not make any changes')
|
|
148
|
-
.option('-v, --verbose', 'Show more details')
|
|
147
|
+
.option('-d, --dry-run', 'Show what would be done, but do not make any changes', false)
|
|
148
|
+
.option('-v, --verbose', 'Show more details', false)
|
|
149
149
|
.argument('[sync]', 'The name of the Sync to sync')
|
|
150
150
|
.action(async (name, opt) => {
|
|
151
151
|
if (name) {
|
|
@@ -167,16 +167,16 @@ cliCache
|
|
|
167
167
|
.command('refresh')
|
|
168
168
|
.description('Force a refresh of the local cache from the server')
|
|
169
169
|
.action(async () => {
|
|
170
|
-
await syncCache(true).catch(io.
|
|
170
|
+
await syncCache(true).catch(io.exit);
|
|
171
171
|
});
|
|
172
172
|
cliCache
|
|
173
173
|
.command('dump')
|
|
174
174
|
.description('Dump the local cache')
|
|
175
175
|
.option('-v, --verbose', 'Show more details')
|
|
176
176
|
.addOption(new Option('-j, --json', 'Output as JSON').conflicts(['verbose', 'quiet']))
|
|
177
|
-
.action(async function () {
|
|
177
|
+
.action(async function axium_files_cache_dump() {
|
|
178
178
|
const opt = this.optsWithGlobals();
|
|
179
|
-
const data = await syncCache(false).catch(io.
|
|
179
|
+
const data = await syncCache(false).catch(io.exit);
|
|
180
180
|
if (opt.json) {
|
|
181
181
|
console.log(JSON.stringify(data));
|
|
182
182
|
return;
|
package/dist/client/local.d.ts
CHANGED
|
@@ -23,12 +23,16 @@ declare const StorageCache: z.ZodObject<{
|
|
|
23
23
|
id: z.ZodUUID;
|
|
24
24
|
name: z.ZodString;
|
|
25
25
|
email: z.ZodOptional<z.ZodEmail>;
|
|
26
|
-
emailVerified: z.ZodOptional<z.ZodOptional<z.ZodNullable<z.
|
|
26
|
+
emailVerified: z.ZodOptional<z.ZodOptional<z.ZodNullable<z.ZodCoercedDate<unknown>>>>;
|
|
27
27
|
image: z.ZodOptional<z.ZodNullable<z.ZodURL>>;
|
|
28
|
-
preferences: z.ZodOptional<z.
|
|
28
|
+
preferences: z.ZodOptional<z.ZodLazy<z.ZodObject<{
|
|
29
|
+
debug: z.ZodDefault<z.ZodBoolean>;
|
|
30
|
+
}, z.core.$strip>>>;
|
|
29
31
|
roles: z.ZodArray<z.ZodString>;
|
|
32
|
+
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
30
33
|
registeredAt: z.ZodCoercedDate<unknown>;
|
|
31
34
|
isAdmin: z.ZodOptional<z.ZodBoolean>;
|
|
35
|
+
isSuspended: z.ZodOptional<z.ZodBoolean>;
|
|
32
36
|
}, z.core.$strip>>;
|
|
33
37
|
}, z.core.$strip>;
|
|
34
38
|
interface StorageCache extends z.infer<typeof StorageCache> {
|
package/dist/client/local.js
CHANGED
|
@@ -61,11 +61,10 @@ export async function syncCache(force = null) {
|
|
|
61
61
|
io.done();
|
|
62
62
|
}
|
|
63
63
|
catch (e) {
|
|
64
|
-
const message = e instanceof Error ? e.message : String(e);
|
|
65
64
|
if (quiet)
|
|
66
|
-
io.exit('Failed to update item metadata: ' +
|
|
65
|
+
io.exit('Failed to update item metadata: ' + io.errorText(e));
|
|
67
66
|
else
|
|
68
|
-
io.exit(
|
|
67
|
+
io.exit(e);
|
|
69
68
|
}
|
|
70
69
|
}
|
|
71
70
|
else {
|
package/dist/client/sync.js
CHANGED
package/dist/common.d.ts
CHANGED
|
@@ -1,80 +1,15 @@
|
|
|
1
1
|
import * as z from 'zod';
|
|
2
|
-
declare
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
};
|
|
14
|
-
'users/:id/storage/shared': {
|
|
15
|
-
GET: StorageItemMetadata[];
|
|
16
|
-
};
|
|
17
|
-
storage: {
|
|
18
|
-
OPTIONS: StoragePublicConfig & {
|
|
19
|
-
syncProtocolVersion: number;
|
|
20
|
-
batchFormatVersion: number;
|
|
21
|
-
};
|
|
22
|
-
};
|
|
23
|
-
'storage/batch': {
|
|
24
|
-
POST: [StorageBatchUpdate[], StorageItemMetadata[]];
|
|
25
|
-
};
|
|
26
|
-
'storage/item/:id': {
|
|
27
|
-
GET: StorageItemMetadata;
|
|
28
|
-
DELETE: StorageItemMetadata;
|
|
29
|
-
PATCH: [z.input<typeof StorageItemUpdate>, StorageItemMetadata];
|
|
30
|
-
};
|
|
31
|
-
'storage/directory/:id': {
|
|
32
|
-
GET: StorageItemMetadata[];
|
|
33
|
-
};
|
|
34
|
-
'storage/directory/:id/recursive': {
|
|
35
|
-
GET: (StorageItemMetadata & {
|
|
36
|
-
path: string;
|
|
37
|
-
})[];
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
export interface StoragePublicConfig {
|
|
42
|
-
/** Configuration for batch updates */
|
|
43
|
-
batch: {
|
|
44
|
-
/** Whether to enable sending multiple files per request */
|
|
45
|
-
enabled: boolean;
|
|
46
|
-
/** Maximum number of items that can be included in a single batch update */
|
|
47
|
-
max_items: number;
|
|
48
|
-
/** Maximum size in KiB per item */
|
|
49
|
-
max_item_size: number;
|
|
50
|
-
};
|
|
51
|
-
/** Whether to split files larger than `max_transfer_size` into multiple chunks */
|
|
52
|
-
chunk: boolean;
|
|
53
|
-
/** Maximum size in MiB per transfer/request */
|
|
54
|
-
max_transfer_size: number;
|
|
55
|
-
/** Maximum number of chunks */
|
|
56
|
-
max_chunks: number;
|
|
57
|
-
}
|
|
58
|
-
export declare const syncProtocolVersion = 0;
|
|
59
|
-
export interface StorageLimits {
|
|
60
|
-
/** The maximum size per item in MB */
|
|
61
|
-
item_size: number;
|
|
62
|
-
/** Maximum number of items per user */
|
|
63
|
-
user_items: number;
|
|
64
|
-
/** The maximum storage size per user in MB */
|
|
65
|
-
user_size: number;
|
|
66
|
-
}
|
|
67
|
-
export interface StorageStats {
|
|
68
|
-
usedBytes: number;
|
|
69
|
-
itemCount: number;
|
|
70
|
-
lastModified: Date;
|
|
71
|
-
lastTrashed: Date | null;
|
|
72
|
-
}
|
|
73
|
-
export interface UserStorageInfo extends StorageStats {
|
|
74
|
-
limits: StorageLimits;
|
|
75
|
-
}
|
|
76
|
-
export interface UserStorage extends UserStorageInfo {
|
|
77
|
-
items: StorageItemMetadata[];
|
|
2
|
+
export declare const StoragePublicConfig: z.ZodObject<{
|
|
3
|
+
batch: z.ZodObject<{
|
|
4
|
+
enabled: z.ZodBoolean;
|
|
5
|
+
max_items: z.ZodNumber;
|
|
6
|
+
max_item_size: z.ZodNumber;
|
|
7
|
+
}, z.core.$strip>;
|
|
8
|
+
chunk: z.ZodBoolean;
|
|
9
|
+
max_transfer_size: z.ZodNumber;
|
|
10
|
+
max_chunks: z.ZodNumber;
|
|
11
|
+
}, z.core.$strip>;
|
|
12
|
+
export interface StoragePublicConfig extends z.infer<typeof StoragePublicConfig> {
|
|
78
13
|
}
|
|
79
14
|
/**
|
|
80
15
|
* An update to file metadata.
|
|
@@ -103,6 +38,63 @@ export declare const StorageItemMetadata: z.ZodObject<{
|
|
|
103
38
|
export interface StorageItemMetadata<T extends Record<string, unknown> = Record<string, unknown>> extends z.infer<typeof StorageItemMetadata> {
|
|
104
39
|
metadata: T;
|
|
105
40
|
}
|
|
41
|
+
export declare const syncProtocolVersion = 0;
|
|
42
|
+
export declare const StorageLimits: z.ZodObject<{
|
|
43
|
+
item_size: z.ZodNumber;
|
|
44
|
+
user_items: z.ZodNumber;
|
|
45
|
+
user_size: z.ZodNumber;
|
|
46
|
+
}, z.core.$strip>;
|
|
47
|
+
export interface StorageLimits extends z.infer<typeof StorageLimits> {
|
|
48
|
+
}
|
|
49
|
+
export declare const StorageStats: z.ZodObject<{
|
|
50
|
+
usedBytes: z.ZodNumber;
|
|
51
|
+
itemCount: z.ZodNumber;
|
|
52
|
+
lastModified: z.ZodCoercedDate<unknown>;
|
|
53
|
+
lastTrashed: z.ZodNullable<z.ZodCoercedDate<unknown>>;
|
|
54
|
+
}, z.core.$strip>;
|
|
55
|
+
export interface StorageStats extends z.infer<typeof StorageStats> {
|
|
56
|
+
}
|
|
57
|
+
export declare const UserStorageInfo: z.ZodObject<{
|
|
58
|
+
limits: z.ZodObject<{
|
|
59
|
+
item_size: z.ZodNumber;
|
|
60
|
+
user_items: z.ZodNumber;
|
|
61
|
+
user_size: z.ZodNumber;
|
|
62
|
+
}, z.core.$strip>;
|
|
63
|
+
usedBytes: z.ZodNumber;
|
|
64
|
+
itemCount: z.ZodNumber;
|
|
65
|
+
lastModified: z.ZodCoercedDate<unknown>;
|
|
66
|
+
lastTrashed: z.ZodNullable<z.ZodCoercedDate<unknown>>;
|
|
67
|
+
}, z.core.$strip>;
|
|
68
|
+
export interface UserStorageInfo extends z.infer<typeof UserStorageInfo> {
|
|
69
|
+
}
|
|
70
|
+
export declare const UserStorage: z.ZodObject<{
|
|
71
|
+
items: z.ZodArray<z.ZodObject<{
|
|
72
|
+
createdAt: z.ZodCoercedDate<unknown>;
|
|
73
|
+
dataURL: z.ZodString;
|
|
74
|
+
hash: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
75
|
+
id: z.ZodUUID;
|
|
76
|
+
immutable: z.ZodBoolean;
|
|
77
|
+
modifiedAt: z.ZodCoercedDate<unknown>;
|
|
78
|
+
name: z.ZodString;
|
|
79
|
+
userId: z.ZodUUID;
|
|
80
|
+
parentId: z.ZodNullable<z.ZodUUID>;
|
|
81
|
+
size: z.ZodInt;
|
|
82
|
+
trashedAt: z.ZodNullable<z.ZodCoercedDate<unknown>>;
|
|
83
|
+
type: z.ZodString;
|
|
84
|
+
metadata: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
85
|
+
}, z.core.$strip>>;
|
|
86
|
+
limits: z.ZodObject<{
|
|
87
|
+
item_size: z.ZodNumber;
|
|
88
|
+
user_items: z.ZodNumber;
|
|
89
|
+
user_size: z.ZodNumber;
|
|
90
|
+
}, z.core.$strip>;
|
|
91
|
+
usedBytes: z.ZodNumber;
|
|
92
|
+
itemCount: z.ZodNumber;
|
|
93
|
+
lastModified: z.ZodCoercedDate<unknown>;
|
|
94
|
+
lastTrashed: z.ZodNullable<z.ZodCoercedDate<unknown>>;
|
|
95
|
+
}, z.core.$strip>;
|
|
96
|
+
export interface UserStorage extends z.infer<typeof UserStorage> {
|
|
97
|
+
}
|
|
106
98
|
/**
|
|
107
99
|
* Formats:
|
|
108
100
|
*
|
|
@@ -130,3 +122,229 @@ export declare const StorageBatchUpdate: z.ZodObject<{
|
|
|
130
122
|
}, z.core.$strip>;
|
|
131
123
|
export interface StorageBatchUpdate extends z.infer<typeof StorageBatchUpdate> {
|
|
132
124
|
}
|
|
125
|
+
declare const StorageAPI: {
|
|
126
|
+
readonly 'users/:id/storage': {
|
|
127
|
+
readonly OPTIONS: z.ZodObject<{
|
|
128
|
+
limits: z.ZodObject<{
|
|
129
|
+
item_size: z.ZodNumber;
|
|
130
|
+
user_items: z.ZodNumber;
|
|
131
|
+
user_size: z.ZodNumber;
|
|
132
|
+
}, z.core.$strip>;
|
|
133
|
+
usedBytes: z.ZodNumber;
|
|
134
|
+
itemCount: z.ZodNumber;
|
|
135
|
+
lastModified: z.ZodCoercedDate<unknown>;
|
|
136
|
+
lastTrashed: z.ZodNullable<z.ZodCoercedDate<unknown>>;
|
|
137
|
+
}, z.core.$strip>;
|
|
138
|
+
readonly GET: z.ZodObject<{
|
|
139
|
+
items: z.ZodArray<z.ZodObject<{
|
|
140
|
+
createdAt: z.ZodCoercedDate<unknown>;
|
|
141
|
+
dataURL: z.ZodString;
|
|
142
|
+
hash: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
143
|
+
id: z.ZodUUID;
|
|
144
|
+
immutable: z.ZodBoolean;
|
|
145
|
+
modifiedAt: z.ZodCoercedDate<unknown>;
|
|
146
|
+
name: z.ZodString;
|
|
147
|
+
userId: z.ZodUUID;
|
|
148
|
+
parentId: z.ZodNullable<z.ZodUUID>;
|
|
149
|
+
size: z.ZodInt;
|
|
150
|
+
trashedAt: z.ZodNullable<z.ZodCoercedDate<unknown>>;
|
|
151
|
+
type: z.ZodString;
|
|
152
|
+
metadata: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
153
|
+
}, z.core.$strip>>;
|
|
154
|
+
limits: z.ZodObject<{
|
|
155
|
+
item_size: z.ZodNumber;
|
|
156
|
+
user_items: z.ZodNumber;
|
|
157
|
+
user_size: z.ZodNumber;
|
|
158
|
+
}, z.core.$strip>;
|
|
159
|
+
usedBytes: z.ZodNumber;
|
|
160
|
+
itemCount: z.ZodNumber;
|
|
161
|
+
lastModified: z.ZodCoercedDate<unknown>;
|
|
162
|
+
lastTrashed: z.ZodNullable<z.ZodCoercedDate<unknown>>;
|
|
163
|
+
}, z.core.$strip>;
|
|
164
|
+
};
|
|
165
|
+
readonly 'users/:id/storage/root': {
|
|
166
|
+
readonly GET: z.ZodArray<z.ZodObject<{
|
|
167
|
+
createdAt: z.ZodCoercedDate<unknown>;
|
|
168
|
+
dataURL: z.ZodString;
|
|
169
|
+
hash: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
170
|
+
id: z.ZodUUID;
|
|
171
|
+
immutable: z.ZodBoolean;
|
|
172
|
+
modifiedAt: z.ZodCoercedDate<unknown>;
|
|
173
|
+
name: z.ZodString;
|
|
174
|
+
userId: z.ZodUUID;
|
|
175
|
+
parentId: z.ZodNullable<z.ZodUUID>;
|
|
176
|
+
size: z.ZodInt;
|
|
177
|
+
trashedAt: z.ZodNullable<z.ZodCoercedDate<unknown>>;
|
|
178
|
+
type: z.ZodString;
|
|
179
|
+
metadata: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
180
|
+
}, z.core.$strip>>;
|
|
181
|
+
};
|
|
182
|
+
readonly 'users/:id/storage/trash': {
|
|
183
|
+
readonly GET: z.ZodArray<z.ZodObject<{
|
|
184
|
+
createdAt: z.ZodCoercedDate<unknown>;
|
|
185
|
+
dataURL: z.ZodString;
|
|
186
|
+
hash: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
187
|
+
id: z.ZodUUID;
|
|
188
|
+
immutable: z.ZodBoolean;
|
|
189
|
+
modifiedAt: z.ZodCoercedDate<unknown>;
|
|
190
|
+
name: z.ZodString;
|
|
191
|
+
userId: z.ZodUUID;
|
|
192
|
+
parentId: z.ZodNullable<z.ZodUUID>;
|
|
193
|
+
size: z.ZodInt;
|
|
194
|
+
trashedAt: z.ZodNullable<z.ZodCoercedDate<unknown>>;
|
|
195
|
+
type: z.ZodString;
|
|
196
|
+
metadata: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
197
|
+
}, z.core.$strip>>;
|
|
198
|
+
};
|
|
199
|
+
readonly 'users/:id/storage/shared': {
|
|
200
|
+
readonly GET: z.ZodArray<z.ZodObject<{
|
|
201
|
+
createdAt: z.ZodCoercedDate<unknown>;
|
|
202
|
+
dataURL: z.ZodString;
|
|
203
|
+
hash: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
204
|
+
id: z.ZodUUID;
|
|
205
|
+
immutable: z.ZodBoolean;
|
|
206
|
+
modifiedAt: z.ZodCoercedDate<unknown>;
|
|
207
|
+
name: z.ZodString;
|
|
208
|
+
userId: z.ZodUUID;
|
|
209
|
+
parentId: z.ZodNullable<z.ZodUUID>;
|
|
210
|
+
size: z.ZodInt;
|
|
211
|
+
trashedAt: z.ZodNullable<z.ZodCoercedDate<unknown>>;
|
|
212
|
+
type: z.ZodString;
|
|
213
|
+
metadata: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
214
|
+
}, z.core.$strip>>;
|
|
215
|
+
};
|
|
216
|
+
readonly storage: {
|
|
217
|
+
readonly OPTIONS: z.ZodObject<{
|
|
218
|
+
batch: z.ZodObject<{
|
|
219
|
+
enabled: z.ZodBoolean;
|
|
220
|
+
max_items: z.ZodNumber;
|
|
221
|
+
max_item_size: z.ZodNumber;
|
|
222
|
+
}, z.core.$strip>;
|
|
223
|
+
chunk: z.ZodBoolean;
|
|
224
|
+
max_transfer_size: z.ZodNumber;
|
|
225
|
+
max_chunks: z.ZodNumber;
|
|
226
|
+
syncProtocolVersion: z.ZodNumber;
|
|
227
|
+
batchFormatVersion: z.ZodNumber;
|
|
228
|
+
}, z.core.$strip>;
|
|
229
|
+
};
|
|
230
|
+
readonly 'storage/batch': {
|
|
231
|
+
readonly POST: readonly [z.ZodArray<z.ZodObject<{
|
|
232
|
+
deleted: z.ZodArray<z.ZodUUID>;
|
|
233
|
+
metadata: z.ZodRecord<z.ZodUUID, z.ZodObject<{
|
|
234
|
+
name: z.ZodOptional<z.ZodString>;
|
|
235
|
+
owner: z.ZodOptional<z.ZodUUID>;
|
|
236
|
+
trash: z.ZodOptional<z.ZodBoolean>;
|
|
237
|
+
}, z.core.$strip>>;
|
|
238
|
+
content: z.ZodRecord<z.ZodUUID, z.ZodObject<{
|
|
239
|
+
offset: z.ZodInt;
|
|
240
|
+
size: z.ZodInt;
|
|
241
|
+
}, z.core.$strip>>;
|
|
242
|
+
}, z.core.$strip>>, z.ZodArray<z.ZodObject<{
|
|
243
|
+
createdAt: z.ZodCoercedDate<unknown>;
|
|
244
|
+
dataURL: z.ZodString;
|
|
245
|
+
hash: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
246
|
+
id: z.ZodUUID;
|
|
247
|
+
immutable: z.ZodBoolean;
|
|
248
|
+
modifiedAt: z.ZodCoercedDate<unknown>;
|
|
249
|
+
name: z.ZodString;
|
|
250
|
+
userId: z.ZodUUID;
|
|
251
|
+
parentId: z.ZodNullable<z.ZodUUID>;
|
|
252
|
+
size: z.ZodInt;
|
|
253
|
+
trashedAt: z.ZodNullable<z.ZodCoercedDate<unknown>>;
|
|
254
|
+
type: z.ZodString;
|
|
255
|
+
metadata: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
256
|
+
}, z.core.$strip>>];
|
|
257
|
+
};
|
|
258
|
+
readonly 'storage/item/:id': {
|
|
259
|
+
readonly GET: z.ZodObject<{
|
|
260
|
+
createdAt: z.ZodCoercedDate<unknown>;
|
|
261
|
+
dataURL: z.ZodString;
|
|
262
|
+
hash: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
263
|
+
id: z.ZodUUID;
|
|
264
|
+
immutable: z.ZodBoolean;
|
|
265
|
+
modifiedAt: z.ZodCoercedDate<unknown>;
|
|
266
|
+
name: z.ZodString;
|
|
267
|
+
userId: z.ZodUUID;
|
|
268
|
+
parentId: z.ZodNullable<z.ZodUUID>;
|
|
269
|
+
size: z.ZodInt;
|
|
270
|
+
trashedAt: z.ZodNullable<z.ZodCoercedDate<unknown>>;
|
|
271
|
+
type: z.ZodString;
|
|
272
|
+
metadata: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
273
|
+
}, z.core.$strip>;
|
|
274
|
+
readonly DELETE: z.ZodObject<{
|
|
275
|
+
createdAt: z.ZodCoercedDate<unknown>;
|
|
276
|
+
dataURL: z.ZodString;
|
|
277
|
+
hash: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
278
|
+
id: z.ZodUUID;
|
|
279
|
+
immutable: z.ZodBoolean;
|
|
280
|
+
modifiedAt: z.ZodCoercedDate<unknown>;
|
|
281
|
+
name: z.ZodString;
|
|
282
|
+
userId: z.ZodUUID;
|
|
283
|
+
parentId: z.ZodNullable<z.ZodUUID>;
|
|
284
|
+
size: z.ZodInt;
|
|
285
|
+
trashedAt: z.ZodNullable<z.ZodCoercedDate<unknown>>;
|
|
286
|
+
type: z.ZodString;
|
|
287
|
+
metadata: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
288
|
+
}, z.core.$strip>;
|
|
289
|
+
readonly PATCH: readonly [z.ZodObject<{
|
|
290
|
+
name: z.ZodOptional<z.ZodString>;
|
|
291
|
+
owner: z.ZodOptional<z.ZodUUID>;
|
|
292
|
+
trash: z.ZodOptional<z.ZodBoolean>;
|
|
293
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
294
|
+
createdAt: z.ZodCoercedDate<unknown>;
|
|
295
|
+
dataURL: z.ZodString;
|
|
296
|
+
hash: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
297
|
+
id: z.ZodUUID;
|
|
298
|
+
immutable: z.ZodBoolean;
|
|
299
|
+
modifiedAt: z.ZodCoercedDate<unknown>;
|
|
300
|
+
name: z.ZodString;
|
|
301
|
+
userId: z.ZodUUID;
|
|
302
|
+
parentId: z.ZodNullable<z.ZodUUID>;
|
|
303
|
+
size: z.ZodInt;
|
|
304
|
+
trashedAt: z.ZodNullable<z.ZodCoercedDate<unknown>>;
|
|
305
|
+
type: z.ZodString;
|
|
306
|
+
metadata: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
307
|
+
}, z.core.$strip>];
|
|
308
|
+
};
|
|
309
|
+
readonly 'storage/directory/:id': {
|
|
310
|
+
readonly GET: z.ZodArray<z.ZodObject<{
|
|
311
|
+
createdAt: z.ZodCoercedDate<unknown>;
|
|
312
|
+
dataURL: z.ZodString;
|
|
313
|
+
hash: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
314
|
+
id: z.ZodUUID;
|
|
315
|
+
immutable: z.ZodBoolean;
|
|
316
|
+
modifiedAt: z.ZodCoercedDate<unknown>;
|
|
317
|
+
name: z.ZodString;
|
|
318
|
+
userId: z.ZodUUID;
|
|
319
|
+
parentId: z.ZodNullable<z.ZodUUID>;
|
|
320
|
+
size: z.ZodInt;
|
|
321
|
+
trashedAt: z.ZodNullable<z.ZodCoercedDate<unknown>>;
|
|
322
|
+
type: z.ZodString;
|
|
323
|
+
metadata: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
324
|
+
}, z.core.$strip>>;
|
|
325
|
+
};
|
|
326
|
+
readonly 'storage/directory/:id/recursive': {
|
|
327
|
+
readonly GET: z.ZodArray<z.ZodObject<{
|
|
328
|
+
createdAt: z.ZodCoercedDate<unknown>;
|
|
329
|
+
dataURL: z.ZodString;
|
|
330
|
+
hash: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
331
|
+
id: z.ZodUUID;
|
|
332
|
+
immutable: z.ZodBoolean;
|
|
333
|
+
modifiedAt: z.ZodCoercedDate<unknown>;
|
|
334
|
+
name: z.ZodString;
|
|
335
|
+
userId: z.ZodUUID;
|
|
336
|
+
parentId: z.ZodNullable<z.ZodUUID>;
|
|
337
|
+
size: z.ZodInt;
|
|
338
|
+
trashedAt: z.ZodNullable<z.ZodCoercedDate<unknown>>;
|
|
339
|
+
type: z.ZodString;
|
|
340
|
+
metadata: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
341
|
+
path: z.ZodString;
|
|
342
|
+
}, z.core.$strip>>;
|
|
343
|
+
};
|
|
344
|
+
};
|
|
345
|
+
type StorageAPI = typeof StorageAPI;
|
|
346
|
+
declare module '@axium/core/api' {
|
|
347
|
+
interface $API extends StorageAPI {
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
export {};
|
package/dist/common.js
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
|
+
import { $API } from '@axium/core';
|
|
1
2
|
import * as z from 'zod';
|
|
2
|
-
export const
|
|
3
|
+
export const StoragePublicConfig = z.object({
|
|
4
|
+
/** Configuration for batch updates */
|
|
5
|
+
batch: z.object({
|
|
6
|
+
/** Whether to enable sending multiple files per request */
|
|
7
|
+
enabled: z.boolean(),
|
|
8
|
+
/** Maximum number of items that can be included in a single batch update */
|
|
9
|
+
max_items: z.number(),
|
|
10
|
+
/** Maximum size in KiB per item */
|
|
11
|
+
max_item_size: z.number(),
|
|
12
|
+
}),
|
|
13
|
+
/** Whether to split files larger than `max_transfer_size` into multiple chunks */
|
|
14
|
+
chunk: z.boolean(),
|
|
15
|
+
/** Maximum size in MiB per transfer/request */
|
|
16
|
+
max_transfer_size: z.number(),
|
|
17
|
+
/** Maximum number of chunks */
|
|
18
|
+
max_chunks: z.number(),
|
|
19
|
+
});
|
|
3
20
|
/**
|
|
4
21
|
* An update to file metadata.
|
|
5
22
|
*/
|
|
@@ -26,6 +43,29 @@ export const StorageItemMetadata = z.object({
|
|
|
26
43
|
type: z.string(),
|
|
27
44
|
metadata: z.record(z.string(), z.unknown()),
|
|
28
45
|
});
|
|
46
|
+
export const syncProtocolVersion = 0;
|
|
47
|
+
export const StorageLimits = z.object({
|
|
48
|
+
/** The maximum size per item in MB */
|
|
49
|
+
item_size: z.number(),
|
|
50
|
+
/** Maximum number of items per user */
|
|
51
|
+
user_items: z.number(),
|
|
52
|
+
/** The maximum storage size per user in MB */
|
|
53
|
+
user_size: z.number(),
|
|
54
|
+
});
|
|
55
|
+
export const StorageStats = z.object({
|
|
56
|
+
usedBytes: z.number().nonnegative(),
|
|
57
|
+
itemCount: z.number().nonnegative(),
|
|
58
|
+
lastModified: z.coerce.date(),
|
|
59
|
+
lastTrashed: z.coerce.date().nullable(),
|
|
60
|
+
});
|
|
61
|
+
export const UserStorageInfo = z.object({
|
|
62
|
+
...StorageStats.shape,
|
|
63
|
+
limits: StorageLimits,
|
|
64
|
+
});
|
|
65
|
+
export const UserStorage = z.object({
|
|
66
|
+
...UserStorageInfo.shape,
|
|
67
|
+
items: StorageItemMetadata.array(),
|
|
68
|
+
});
|
|
29
69
|
/**
|
|
30
70
|
* Formats:
|
|
31
71
|
*
|
|
@@ -45,3 +85,39 @@ export const StorageBatchUpdate = z.object({
|
|
|
45
85
|
metadata: z.record(z.uuid(), StorageItemUpdate),
|
|
46
86
|
content: z.record(z.uuid(), BatchedContentChange),
|
|
47
87
|
});
|
|
88
|
+
const StorageAPI = {
|
|
89
|
+
'users/:id/storage': {
|
|
90
|
+
OPTIONS: UserStorageInfo,
|
|
91
|
+
GET: UserStorage,
|
|
92
|
+
},
|
|
93
|
+
'users/:id/storage/root': {
|
|
94
|
+
GET: StorageItemMetadata.array(),
|
|
95
|
+
},
|
|
96
|
+
'users/:id/storage/trash': {
|
|
97
|
+
GET: StorageItemMetadata.array(),
|
|
98
|
+
},
|
|
99
|
+
'users/:id/storage/shared': {
|
|
100
|
+
GET: StorageItemMetadata.array(),
|
|
101
|
+
},
|
|
102
|
+
storage: {
|
|
103
|
+
OPTIONS: StoragePublicConfig.extend({
|
|
104
|
+
syncProtocolVersion: z.number(),
|
|
105
|
+
batchFormatVersion: z.number(),
|
|
106
|
+
}),
|
|
107
|
+
},
|
|
108
|
+
'storage/batch': {
|
|
109
|
+
POST: [StorageBatchUpdate.array(), StorageItemMetadata.array()],
|
|
110
|
+
},
|
|
111
|
+
'storage/item/:id': {
|
|
112
|
+
GET: StorageItemMetadata,
|
|
113
|
+
DELETE: StorageItemMetadata,
|
|
114
|
+
PATCH: [StorageItemUpdate, StorageItemMetadata],
|
|
115
|
+
},
|
|
116
|
+
'storage/directory/:id': {
|
|
117
|
+
GET: StorageItemMetadata.array(),
|
|
118
|
+
},
|
|
119
|
+
'storage/directory/:id/recursive': {
|
|
120
|
+
GET: StorageItemMetadata.extend({ path: z.string() }).array(),
|
|
121
|
+
},
|
|
122
|
+
};
|
|
123
|
+
Object.assign($API, StorageAPI);
|
package/dist/server/cli.js
CHANGED
|
@@ -27,7 +27,7 @@ cli.command('query')
|
|
|
27
27
|
.addOption(new Option('-u, --user <user>', 'Filter by user UUID or email').argParser(lookupUser))
|
|
28
28
|
.option('-m, --min-size <size>', 'Filter by minimum size', _byteSize('Invalid minimum size.'))
|
|
29
29
|
.option('-M, --max-size <size>', 'Filter by maximum size', _byteSize('Invalid maximum size.'))
|
|
30
|
-
.addOption(new Option('--size', 'Filter by exact size').conflicts(['minSize', 'maxSize']).argParser(_byteSize('Invalid size.')))
|
|
30
|
+
.addOption(new Option('--size <size>', 'Filter by exact size').conflicts(['minSize', 'maxSize']).argParser(_byteSize('Invalid size.')))
|
|
31
31
|
.option('-l, --limit <n>', 'Limit the number of results', (v) => z.coerce.number().int().min(1).max(1000).parse(v), 100)
|
|
32
32
|
.option('-j, --json', 'Output results as JSON', false)
|
|
33
33
|
.addOption(new Option('-f, --format <format>', 'How to format output lines').conflicts('json').default('{id} {type} {size} {userId} {name}'))
|
|
@@ -63,7 +63,7 @@ cli.command('query')
|
|
|
63
63
|
if (opt.size !== undefined) {
|
|
64
64
|
query = query.where('size', '=', opt.size);
|
|
65
65
|
}
|
|
66
|
-
const rawItems = await query.execute().catch(io.
|
|
66
|
+
const rawItems = await query.execute().catch(io.exit);
|
|
67
67
|
const items = rawItems.map(parseItem);
|
|
68
68
|
if (!items.length) {
|
|
69
69
|
console.log(styleText(['italic', 'dim'], 'No storage items match the provided filters.'));
|
package/dist/server/config.d.ts
CHANGED
|
@@ -1,28 +1,33 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { StorageLimits } from '../common.js';
|
|
2
2
|
import '../polyfills.js';
|
|
3
|
+
import * as z from 'zod';
|
|
4
|
+
declare const StorageConfig: z.ZodObject<{
|
|
5
|
+
batch: z.ZodObject<{
|
|
6
|
+
enabled: z.ZodBoolean;
|
|
7
|
+
max_items: z.ZodNumber;
|
|
8
|
+
max_item_size: z.ZodNumber;
|
|
9
|
+
}, z.core.$strip>;
|
|
10
|
+
chunk: z.ZodBoolean;
|
|
11
|
+
max_transfer_size: z.ZodNumber;
|
|
12
|
+
max_chunks: z.ZodNumber;
|
|
13
|
+
app_enabled: z.ZodBoolean;
|
|
14
|
+
cas: z.ZodOptional<z.ZodObject<{
|
|
15
|
+
enabled: z.ZodBoolean;
|
|
16
|
+
include: z.ZodArray<z.ZodString>;
|
|
17
|
+
exclude: z.ZodArray<z.ZodString>;
|
|
18
|
+
}, z.core.$strip>>;
|
|
19
|
+
data: z.ZodString;
|
|
20
|
+
enabled: z.ZodBoolean;
|
|
21
|
+
limits: z.ZodObject<{
|
|
22
|
+
item_size: z.ZodNumber;
|
|
23
|
+
user_items: z.ZodNumber;
|
|
24
|
+
user_size: z.ZodNumber;
|
|
25
|
+
}, z.core.$strip>;
|
|
26
|
+
trash_duration: z.ZodNumber;
|
|
27
|
+
}, z.core.$strip>;
|
|
3
28
|
declare module '@axium/server/config' {
|
|
4
29
|
interface Config {
|
|
5
|
-
storage:
|
|
6
|
-
/** Whether the files app is enabled. Requires `enabled` */
|
|
7
|
-
app_enabled: boolean;
|
|
8
|
-
/** Content Addressable Storage (CAS) configuration */
|
|
9
|
-
cas: {
|
|
10
|
-
/** Whether to use CAS */
|
|
11
|
-
enabled: boolean;
|
|
12
|
-
/** Mime types to include when determining if CAS should be used */
|
|
13
|
-
include: string[];
|
|
14
|
-
/** Mime types to exclude when determining if CAS should be used */
|
|
15
|
-
exclude: string[];
|
|
16
|
-
};
|
|
17
|
-
/** Path to data directory */
|
|
18
|
-
data: string;
|
|
19
|
-
/** Whether the storage API endpoints are enabled */
|
|
20
|
-
enabled: boolean;
|
|
21
|
-
/** Default limits */
|
|
22
|
-
limits: StorageLimits;
|
|
23
|
-
/** How many days files are kept in the trash */
|
|
24
|
-
trash_duration: number;
|
|
25
|
-
};
|
|
30
|
+
storage: z.infer<typeof StorageConfig>;
|
|
26
31
|
}
|
|
27
32
|
}
|
|
28
33
|
export declare const defaultCASMime: RegExp[];
|
|
@@ -45,3 +50,4 @@ export type ExternalLimitHandler = (userId?: string) => StorageLimits | Promise<
|
|
|
45
50
|
*/
|
|
46
51
|
export declare function useLimits(handler: ExternalLimitHandler): void;
|
|
47
52
|
export declare function getLimits(userId?: string): Promise<StorageLimits>;
|
|
53
|
+
export {};
|
package/dist/server/config.js
CHANGED
|
@@ -1,7 +1,35 @@
|
|
|
1
1
|
import { Severity } from '@axium/core';
|
|
2
2
|
import { addEvent } from '@axium/server/audit';
|
|
3
|
-
import { addConfigDefaults, config } from '@axium/server/config';
|
|
3
|
+
import { addConfig, addConfigDefaults, config } from '@axium/server/config';
|
|
4
|
+
import { StorageLimits, StoragePublicConfig } from '../common.js';
|
|
4
5
|
import '../polyfills.js';
|
|
6
|
+
import * as z from 'zod';
|
|
7
|
+
const StorageConfig = StoragePublicConfig.safeExtend({
|
|
8
|
+
/** Whether the files app is enabled. Requires `enabled` */
|
|
9
|
+
app_enabled: z.boolean(),
|
|
10
|
+
/** Content Addressable Storage (CAS) configuration */
|
|
11
|
+
cas: z
|
|
12
|
+
.object({
|
|
13
|
+
/** Whether to use CAS */
|
|
14
|
+
enabled: z.boolean(),
|
|
15
|
+
/** Mime types to include when determining if CAS should be used */
|
|
16
|
+
include: z.string().array(),
|
|
17
|
+
/** Mime types to exclude when determining if CAS should be used */
|
|
18
|
+
exclude: z.string().array(),
|
|
19
|
+
})
|
|
20
|
+
.optional(),
|
|
21
|
+
/** Path to data directory */
|
|
22
|
+
data: z.string(),
|
|
23
|
+
/** Whether the storage API endpoints are enabled */
|
|
24
|
+
enabled: z.boolean(),
|
|
25
|
+
/** Default limits */
|
|
26
|
+
limits: StorageLimits,
|
|
27
|
+
/** How many days files are kept in the trash */
|
|
28
|
+
trash_duration: z.number(),
|
|
29
|
+
});
|
|
30
|
+
addConfig({
|
|
31
|
+
storage: StorageConfig.optional(),
|
|
32
|
+
});
|
|
5
33
|
export const defaultCASMime = [/video\/.*/, /audio\/.*/];
|
|
6
34
|
addConfigDefaults({
|
|
7
35
|
storage: {
|
|
@@ -29,8 +57,20 @@ addConfigDefaults({
|
|
|
29
57
|
trash_duration: 30,
|
|
30
58
|
},
|
|
31
59
|
});
|
|
32
|
-
addEvent({
|
|
33
|
-
|
|
60
|
+
addEvent({
|
|
61
|
+
source: '@axium/storage',
|
|
62
|
+
name: 'storage_type_mismatch',
|
|
63
|
+
severity: Severity.Warning,
|
|
64
|
+
tags: ['mimetype'],
|
|
65
|
+
extra: { item: z.string() },
|
|
66
|
+
});
|
|
67
|
+
addEvent({
|
|
68
|
+
source: '@axium/storage',
|
|
69
|
+
name: 'storage_size_mismatch',
|
|
70
|
+
severity: Severity.Warning,
|
|
71
|
+
tags: [],
|
|
72
|
+
extra: { item: z.string().nullable() },
|
|
73
|
+
});
|
|
34
74
|
let _getLimits = null;
|
|
35
75
|
/**
|
|
36
76
|
* Define the handler to get limits for a user externally.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@axium/storage",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0",
|
|
4
4
|
"author": "James Prevett <axium@jamespre.dev>",
|
|
5
5
|
"description": "User file storage for Axium",
|
|
6
6
|
"funding": {
|
|
@@ -39,9 +39,9 @@
|
|
|
39
39
|
"build": "tsc"
|
|
40
40
|
},
|
|
41
41
|
"peerDependencies": {
|
|
42
|
-
"@axium/client": ">=0.
|
|
43
|
-
"@axium/core": ">=0.
|
|
44
|
-
"@axium/server": ">=0.
|
|
42
|
+
"@axium/client": ">=0.11.0",
|
|
43
|
+
"@axium/core": ">=0.17.0",
|
|
44
|
+
"@axium/server": ">=0.30.0",
|
|
45
45
|
"@sveltejs/kit": "^2.27.3",
|
|
46
46
|
"utilium": "^2.3.8"
|
|
47
47
|
},
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import '@axium/storage/common';
|