@vex-chat/spire 0.7.4 → 1.0.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 +82 -26
- package/dist/ClientManager.d.ts +24 -25
- package/dist/ClientManager.js +232 -509
- package/dist/ClientManager.js.map +1 -0
- package/dist/Database.d.ts +49 -41
- package/dist/Database.js +698 -716
- package/dist/Database.js.map +1 -0
- package/dist/Spire.d.ts +23 -15
- package/dist/Spire.js +518 -218
- package/dist/Spire.js.map +1 -0
- package/dist/__tests__/Database.spec.js +113 -73
- package/dist/__tests__/Database.spec.js.map +1 -0
- package/dist/db/schema.d.ts +134 -0
- package/dist/db/schema.js +2 -0
- package/dist/db/schema.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +3 -5
- package/dist/index.js.map +1 -0
- package/dist/middleware/validate.d.ts +12 -0
- package/dist/middleware/validate.js +35 -0
- package/dist/middleware/validate.js.map +1 -0
- package/dist/migrations/2026-04-06_initial-schema.d.ts +3 -0
- package/dist/migrations/2026-04-06_initial-schema.js +192 -0
- package/dist/migrations/2026-04-06_initial-schema.js.map +1 -0
- package/dist/run.js +26 -21
- package/dist/run.js.map +1 -0
- package/dist/server/avatar.d.ts +3 -4
- package/dist/server/avatar.js +85 -67
- package/dist/server/avatar.js.map +1 -0
- package/dist/server/errors.d.ts +59 -0
- package/dist/server/errors.js +94 -0
- package/dist/server/errors.js.map +1 -0
- package/dist/server/file.d.ts +3 -4
- package/dist/server/file.js +101 -61
- package/dist/server/file.js.map +1 -0
- package/dist/server/index.d.ts +9 -6
- package/dist/server/index.js +595 -70
- package/dist/server/index.js.map +1 -0
- package/dist/server/invite.d.ts +4 -5
- package/dist/server/invite.js +21 -103
- package/dist/server/invite.js.map +1 -0
- package/dist/server/openapi.d.ts +2 -0
- package/dist/server/openapi.js +40 -0
- package/dist/server/openapi.js.map +1 -0
- package/dist/server/permissions.d.ts +16 -0
- package/dist/server/permissions.js +22 -0
- package/dist/server/permissions.js.map +1 -0
- package/dist/server/rateLimit.d.ts +28 -0
- package/dist/server/rateLimit.js +58 -0
- package/dist/server/rateLimit.js.map +1 -0
- package/dist/server/user.d.ts +4 -7
- package/dist/server/user.js +66 -76
- package/dist/server/user.js.map +1 -0
- package/dist/server/utils.d.ts +35 -7
- package/dist/server/utils.js +50 -6
- package/dist/server/utils.js.map +1 -0
- package/dist/types/express.d.ts +20 -0
- package/dist/types/express.js +2 -0
- package/dist/types/express.js.map +1 -0
- package/dist/utils/createLogger.js +13 -19
- package/dist/utils/createLogger.js.map +1 -0
- package/dist/utils/createUint8UUID.js +6 -10
- package/dist/utils/createUint8UUID.js.map +1 -0
- package/dist/utils/jwtSecret.d.ts +7 -0
- package/dist/utils/jwtSecret.js +15 -0
- package/dist/utils/jwtSecret.js.map +1 -0
- package/dist/utils/loadEnv.js +7 -22
- package/dist/utils/loadEnv.js.map +1 -0
- package/dist/utils/msgpack.d.ts +2 -0
- package/dist/utils/msgpack.js +4 -0
- package/dist/utils/msgpack.js.map +1 -0
- package/package.json +91 -63
- package/src/ClientManager.ts +434 -0
- package/src/Database.ts +925 -0
- package/src/Spire.ts +878 -0
- package/src/__tests__/Database.spec.ts +167 -0
- package/src/ambient-modules.d.ts +1 -0
- package/src/db/schema.ts +165 -0
- package/src/index.ts +3 -0
- package/src/middleware/validate.ts +38 -0
- package/src/migrations/2026-04-06_initial-schema.ts +218 -0
- package/src/run.ts +37 -0
- package/src/server/avatar.ts +141 -0
- package/src/server/errors.ts +133 -0
- package/src/server/file.ts +172 -0
- package/src/server/index.ts +855 -0
- package/src/server/invite.ts +65 -0
- package/src/server/openapi.ts +51 -0
- package/src/server/permissions.ts +40 -0
- package/src/server/rateLimit.ts +86 -0
- package/src/server/user.ts +125 -0
- package/src/server/utils.ts +59 -0
- package/src/types/express.ts +23 -0
- package/src/utils/createLogger.ts +47 -0
- package/src/utils/createUint8UUID.ts +9 -0
- package/src/utils/jwtSecret.ts +16 -0
- package/src/utils/loadEnv.ts +15 -0
- package/src/utils/msgpack.ts +4 -0
- package/avatars/169d76cb-6e7c-4e24-8224-017673eed8ff +0 -0
- package/avatars/1cae8d0b-0c6b-4c73-b25c-2d2349a57122 +0 -0
- package/avatars/1d87bc2b-71fc-4818-8004-40d04093e5fc +0 -0
- package/avatars/1f2c3d62-8b4d-465a-9895-51a24caef00d +0 -0
- package/avatars/245ee7fc-1004-41ab-adab-a04c9ceb9d7a +0 -0
- package/avatars/2465c28c-bdaf-4fa2-b42a-d054f04dc39b +0 -0
- package/avatars/3900a674-a2dd-4996-a61d-8c29b3270f41 +0 -0
- package/avatars/3c3b9c77-ea50-45e7-bb25-65d6f3d2a219 +0 -0
- package/avatars/414a2ff4-ad2f-4a7d-aa27-3b09ad3522b2 +0 -0
- package/avatars/522fe504-f0ad-4ed4-9dc6-e5dc2338e531 +0 -0
- package/avatars/53e5eb29-e7d1-4d58-add9-d44f39f0cfb7 +0 -0
- package/avatars/54d3f757-1038-41c8-bfb9-efd37b6e8ebe +0 -0
- package/avatars/623e86d7-c49c-46f6-9b76-ca70c9dbc43b +0 -0
- package/avatars/66e2abae-60f5-4dd1-b9fb-297a4bedfeb0 +0 -0
- package/avatars/6f37980e-f6fa-4d6d-9206-24050b403f45 +0 -0
- package/avatars/80138ece-eb5c-4b20-817b-903d6b0f54ae +0 -0
- package/avatars/841c77d3-37c4-431b-be22-672888062874 +0 -0
- package/avatars/88051a61-2bda-4750-95a3-5fb0b4918149 +0 -0
- package/avatars/89540973-c421-4bf1-8b89-9f1eaa51c1b5 +0 -0
- package/avatars/8a802fad-8c99-4942-8f80-47cec600149c +0 -0
- package/avatars/90531d8a-907a-4a1a-ac45-c85e4acb0df9 +0 -0
- package/avatars/9b7d0da9-b8d6-4801-b128-9993f79f464a +0 -0
- package/avatars/9bc456f1-c4c4-48a1-b9e6-fd44dd744a72 +0 -0
- package/avatars/9cf878bf-7430-49ec-a47a-78f3c93793dd +0 -0
- package/avatars/9ee82847-6ad3-45e5-92b9-f474a6c54d96 +0 -0
- package/avatars/ab44c857-d81d-4c88-85db-32f9532e5376 +0 -0
- package/avatars/b396a8d2-dc14-48d2-aac4-3755dc637051 +0 -0
- package/avatars/b6ac11c5-a8b2-4e0a-995a-9c87f1e58787 +0 -0
- package/avatars/b79d6855-b738-434c-be32-809637e62b9b +0 -0
- package/avatars/bbcd0188-d6a5-48ae-90fb-be5ff30599ab +0 -0
- package/avatars/bc7a9e0e-4720-4a6e-a90d-c11fec94d380 +0 -0
- package/avatars/c1c4889f-8383-4041-8bdd-9fded4046f37 +0 -0
- package/avatars/c4c7203c-d93a-4749-ade2-17053acf1d2a +0 -0
- package/avatars/ca974a70-0a23-4668-8b80-c4304dc7f793 +0 -0
- package/avatars/cf119a0d-eb3f-4bed-905b-f14a876c3535 +0 -0
- package/avatars/d464b03d-30c2-49e3-a666-80aefa8a1b35 +0 -0
- package/avatars/da0eee89-82f0-4d45-ab48-7d2786b634c5 +0 -0
- package/avatars/de4c77a5-68e9-4bb2-b40d-d964bf377d61 +0 -0
- package/avatars/dea95395-7d0b-42aa-a9ed-40c7d4fb4c48 +0 -0
- package/avatars/edb30749-59ba-4aa2-9c52-0fb22048f4cf +0 -0
- package/avatars/f17c245a-af7d-445b-9365-49f7f54b1eeb +0 -0
- package/avatars/f1ee6a35-b262-4dbf-99f5-3d011e3b98ec +0 -0
- package/avatars/f802bdd0-345d-41f6-9184-0f30e1258fb3 +0 -0
- package/dist/migrations/20210103192527_users.d.ts +0 -3
- package/dist/migrations/20210103192527_users.js +0 -30
- package/dist/migrations/20210103193502_mail.d.ts +0 -3
- package/dist/migrations/20210103193502_mail.js +0 -35
- package/dist/migrations/20210103193525_preKeys.d.ts +0 -3
- package/dist/migrations/20210103193525_preKeys.js +0 -30
- package/dist/migrations/20210103193553_oneTimeKeys.d.ts +0 -3
- package/dist/migrations/20210103193553_oneTimeKeys.js +0 -30
- package/dist/migrations/20210103193615_servers.d.ts +0 -3
- package/dist/migrations/20210103193615_servers.js +0 -28
- package/dist/migrations/20210103193729_channels.d.ts +0 -3
- package/dist/migrations/20210103193729_channels.js +0 -28
- package/dist/migrations/20210103193749_permissions.d.ts +0 -3
- package/dist/migrations/20210103193749_permissions.js +0 -30
- package/dist/migrations/20210103193801_files.d.ts +0 -3
- package/dist/migrations/20210103193801_files.js +0 -28
- package/files/00ea7368-45a7-4f6a-a199-974da14be1a0 +0 -0
- package/files/039503d2-a170-4962-b921-c97994ba64ff +0 -0
- package/files/14b6fa02-4cbb-40df-be4f-a07187cb619e +0 -0
- package/files/15c04cb1-dc6a-4f19-aa6f-4a3b92d05bf7 +0 -0
- package/files/2a8d411c-8b92-4532-b84d-d64c638d6293 +0 -0
- package/files/37de2cd3-08a8-4044-9c37-e13386765f3d +0 -0
- package/files/42452029-284e-4c81-9f18-feb6ce309eed +0 -0
- package/files/43d09f2f-29c8-415f-8c4a-23f2a32eb79e +0 -0
- package/files/52992923-33ab-44a1-8118-605e9b4856a7 +0 -0
- package/files/53180681-36e2-49c0-8382-94dca0da09bf +0 -0
- package/files/5a56cd7b-1d04-4619-b60f-1e5515b9164a +0 -0
- package/files/5ced7676-20c4-4219-a4f2-70a25eb7eea8 +0 -0
- package/files/60e787ff-8ec5-444d-b963-0aaf5313b53e +0 -0
- package/files/67a17729-fcb7-4339-9499-1fc08fea72ca +0 -0
- package/files/68d09565-908d-4a67-8f09-e183f8708eb4 +0 -0
- package/files/70e587c5-56e8-47f0-bd36-691efcb0cc2e +0 -4
- package/files/7a227619-b715-4e2c-a79d-b2158d56a799 +0 -0
- package/files/7e3cc3ea-b706-4835-994d-65d33acaf369 +0 -0
- package/files/816f72a0-65dc-40c1-8862-1d22065cca3c +0 -0
- package/files/8bf84972-5086-4631-a752-093d7b1a098b +0 -0
- package/files/8c46e3bc-3f2e-441d-b8cc-17428fc3d219 +0 -0
- package/files/8eb83364-8826-4eee-895a-ba5cd3ab85e9 +0 -0
- package/files/8faefaea-14e3-49e4-ac74-9710622bfae9 +0 -0
- package/files/91af08c2-9dca-41f4-b6c6-b7bf33505df9 +0 -0
- package/files/9349dffa-35dd-49a0-a651-10b438038f95 +0 -0
- package/files/b0a12a41-6283-4f27-b2c8-66774991d96c +0 -0
- package/files/b28afb08-d18b-48a8-93c3-6a59c66d8fee +0 -0
- package/files/be60fe01-1578-4363-a908-41500092b77d +0 -0
- package/files/cf7b90e3-734a-4453-9ff3-9a331404b5ef +0 -0
- package/files/d1be30aa-8ff4-41c1-b360-f65922029047 +0 -0
- package/files/d2d31a57-a413-443c-9b97-fa9ca394ef0b +0 -0
- package/files/d357f223-b786-478d-a113-b53cb62acdab +0 -0
- package/files/d4a69ee0-05c4-4ff0-8753-624cdd0f24e9 +0 -0
- package/files/d57f411b-1874-4f00-a6b0-2f86de6b229d +0 -0
- package/files/d85aaa33-7f70-4a70-b3d2-cad667beb38c +0 -0
- package/files/db2fc236-dbe0-4d24-bfaf-884829fd090a +0 -0
- package/files/df2e20ec-6dcc-4402-94ee-7d1163f84197 +0 -0
- package/files/e0880ab5-6d49-4dc0-a5ec-0d3793a8a7b8 +0 -0
- package/files/e59ee9c6-5aea-48ea-b3d9-94a324dc2260 +0 -0
- package/files/e6d7aad6-4220-4ce7-85f8-89d0b1f0cc89 +0 -0
- package/files/f0bfc98c-3534-459d-931a-7c6e77bde153 +0 -0
- package/files/f8443740-050c-4714-9bf6-334783ae6ffd +0 -0
- package/files/fc405ae7-f9fb-455d-ac8c-0ca0d88d4115 +0 -0
- package/jest.config.js +0 -13
- package/spire.sqlite +0 -0
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import { sql } from "kysely";
|
|
2
|
+
export async function down(db) {
|
|
3
|
+
const tables = [
|
|
4
|
+
"service_metrics",
|
|
5
|
+
"invites",
|
|
6
|
+
"emojis",
|
|
7
|
+
"files",
|
|
8
|
+
"permissions",
|
|
9
|
+
"channels",
|
|
10
|
+
"servers",
|
|
11
|
+
"oneTimeKeys",
|
|
12
|
+
"preKeys",
|
|
13
|
+
"mail",
|
|
14
|
+
"devices",
|
|
15
|
+
"users",
|
|
16
|
+
];
|
|
17
|
+
for (const table of tables) {
|
|
18
|
+
await db.schema.dropTable(table).ifExists().execute();
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
export async function up(db) {
|
|
22
|
+
await db.schema
|
|
23
|
+
.createTable("users")
|
|
24
|
+
.ifNotExists()
|
|
25
|
+
.addColumn("userID", "varchar(255)", (cb) => cb.primaryKey())
|
|
26
|
+
.addColumn("username", "varchar(255)", (cb) => cb.unique())
|
|
27
|
+
.addColumn("passwordHash", "text")
|
|
28
|
+
.addColumn("passwordSalt", "text")
|
|
29
|
+
.addColumn("lastSeen", "text")
|
|
30
|
+
.execute();
|
|
31
|
+
await db.schema
|
|
32
|
+
.createTable("devices")
|
|
33
|
+
.ifNotExists()
|
|
34
|
+
.addColumn("deviceID", "varchar(255)", (cb) => cb.primaryKey())
|
|
35
|
+
.addColumn("signKey", "varchar(255)", (cb) => cb.unique())
|
|
36
|
+
.addColumn("owner", "varchar(255)")
|
|
37
|
+
.addColumn("name", "varchar(255)")
|
|
38
|
+
.addColumn("lastLogin", "text")
|
|
39
|
+
.addColumn("deleted", "integer", (cb) => cb.defaultTo(0))
|
|
40
|
+
.execute();
|
|
41
|
+
await db.schema
|
|
42
|
+
.createTable("mail")
|
|
43
|
+
.ifNotExists()
|
|
44
|
+
.addColumn("nonce", "varchar(255)", (cb) => cb.primaryKey())
|
|
45
|
+
.addColumn("recipient", "varchar(255)")
|
|
46
|
+
.addColumn("mailID", "varchar(255)")
|
|
47
|
+
.addColumn("sender", "varchar(255)")
|
|
48
|
+
.addColumn("header", "text")
|
|
49
|
+
.addColumn("cipher", "text")
|
|
50
|
+
.addColumn("group", "varchar(255)")
|
|
51
|
+
.addColumn("extra", "text")
|
|
52
|
+
.addColumn("mailType", "integer")
|
|
53
|
+
.addColumn("time", "text")
|
|
54
|
+
.addColumn("forward", "integer", (cb) => cb.defaultTo(0))
|
|
55
|
+
.addColumn("authorID", "varchar(255)")
|
|
56
|
+
.addColumn("readerID", "varchar(255)")
|
|
57
|
+
.execute();
|
|
58
|
+
await db.schema
|
|
59
|
+
.createIndex("mail_recipient_idx")
|
|
60
|
+
.ifNotExists()
|
|
61
|
+
.on("mail")
|
|
62
|
+
.column("recipient")
|
|
63
|
+
.execute();
|
|
64
|
+
await db.schema
|
|
65
|
+
.createTable("preKeys")
|
|
66
|
+
.ifNotExists()
|
|
67
|
+
.addColumn("keyID", "varchar(255)", (cb) => cb.primaryKey())
|
|
68
|
+
.addColumn("userID", "varchar(255)")
|
|
69
|
+
.addColumn("deviceID", "varchar(255)", (cb) => cb.unique())
|
|
70
|
+
.addColumn("publicKey", "text")
|
|
71
|
+
.addColumn("signature", "text")
|
|
72
|
+
.addColumn("index", "integer")
|
|
73
|
+
.execute();
|
|
74
|
+
await db.schema
|
|
75
|
+
.createIndex("preKeys_userID_idx")
|
|
76
|
+
.ifNotExists()
|
|
77
|
+
.on("preKeys")
|
|
78
|
+
.column("userID")
|
|
79
|
+
.execute();
|
|
80
|
+
await db.schema
|
|
81
|
+
.createIndex("preKeys_deviceID_idx")
|
|
82
|
+
.ifNotExists()
|
|
83
|
+
.on("preKeys")
|
|
84
|
+
.column("deviceID")
|
|
85
|
+
.execute();
|
|
86
|
+
await db.schema
|
|
87
|
+
.createTable("oneTimeKeys")
|
|
88
|
+
.ifNotExists()
|
|
89
|
+
.addColumn("keyID", "varchar(255)", (cb) => cb.primaryKey())
|
|
90
|
+
.addColumn("userID", "varchar(255)")
|
|
91
|
+
.addColumn("deviceID", "varchar(255)")
|
|
92
|
+
.addColumn("publicKey", "text")
|
|
93
|
+
.addColumn("signature", "text")
|
|
94
|
+
.addColumn("index", "integer")
|
|
95
|
+
.execute();
|
|
96
|
+
await db.schema
|
|
97
|
+
.createIndex("oneTimeKeys_userID_idx")
|
|
98
|
+
.ifNotExists()
|
|
99
|
+
.on("oneTimeKeys")
|
|
100
|
+
.column("userID")
|
|
101
|
+
.execute();
|
|
102
|
+
await db.schema
|
|
103
|
+
.createIndex("oneTimeKeys_deviceID_idx")
|
|
104
|
+
.ifNotExists()
|
|
105
|
+
.on("oneTimeKeys")
|
|
106
|
+
.column("deviceID")
|
|
107
|
+
.execute();
|
|
108
|
+
await db.schema
|
|
109
|
+
.createTable("servers")
|
|
110
|
+
.ifNotExists()
|
|
111
|
+
.addColumn("serverID", "varchar(255)", (cb) => cb.primaryKey())
|
|
112
|
+
.addColumn("name", "varchar(255)")
|
|
113
|
+
.addColumn("icon", "varchar(255)")
|
|
114
|
+
.execute();
|
|
115
|
+
await db.schema
|
|
116
|
+
.createTable("channels")
|
|
117
|
+
.ifNotExists()
|
|
118
|
+
.addColumn("channelID", "varchar(255)", (cb) => cb.primaryKey())
|
|
119
|
+
.addColumn("serverID", "varchar(255)")
|
|
120
|
+
.addColumn("name", "varchar(255)")
|
|
121
|
+
.execute();
|
|
122
|
+
await db.schema
|
|
123
|
+
.createTable("permissions")
|
|
124
|
+
.ifNotExists()
|
|
125
|
+
.addColumn("permissionID", "varchar(255)", (cb) => cb.primaryKey())
|
|
126
|
+
.addColumn("userID", "varchar(255)")
|
|
127
|
+
.addColumn("resourceType", "varchar(255)")
|
|
128
|
+
.addColumn("resourceID", "varchar(255)")
|
|
129
|
+
.addColumn("powerLevel", "integer")
|
|
130
|
+
.execute();
|
|
131
|
+
await db.schema
|
|
132
|
+
.createIndex("permissions_userID_idx")
|
|
133
|
+
.ifNotExists()
|
|
134
|
+
.on("permissions")
|
|
135
|
+
.column("userID")
|
|
136
|
+
.execute();
|
|
137
|
+
await db.schema
|
|
138
|
+
.createIndex("permissions_resourceID_idx")
|
|
139
|
+
.ifNotExists()
|
|
140
|
+
.on("permissions")
|
|
141
|
+
.column("resourceID")
|
|
142
|
+
.execute();
|
|
143
|
+
await db.schema
|
|
144
|
+
.createTable("files")
|
|
145
|
+
.ifNotExists()
|
|
146
|
+
.addColumn("fileID", "varchar(255)", (cb) => cb.primaryKey())
|
|
147
|
+
.addColumn("owner", "varchar(255)")
|
|
148
|
+
.addColumn("nonce", "varchar(255)")
|
|
149
|
+
.execute();
|
|
150
|
+
await db.schema
|
|
151
|
+
.createIndex("files_owner_idx")
|
|
152
|
+
.ifNotExists()
|
|
153
|
+
.on("files")
|
|
154
|
+
.column("owner")
|
|
155
|
+
.execute();
|
|
156
|
+
await db.schema
|
|
157
|
+
.createTable("emojis")
|
|
158
|
+
.ifNotExists()
|
|
159
|
+
.addColumn("emojiID", "varchar(255)", (cb) => cb.primaryKey())
|
|
160
|
+
.addColumn("owner", "varchar(255)")
|
|
161
|
+
.addColumn("name", "varchar(255)")
|
|
162
|
+
.execute();
|
|
163
|
+
await db.schema
|
|
164
|
+
.createIndex("emojis_owner_idx")
|
|
165
|
+
.ifNotExists()
|
|
166
|
+
.on("emojis")
|
|
167
|
+
.column("owner")
|
|
168
|
+
.execute();
|
|
169
|
+
await db.schema
|
|
170
|
+
.createTable("invites")
|
|
171
|
+
.ifNotExists()
|
|
172
|
+
.addColumn("inviteID", "varchar(255)", (cb) => cb.primaryKey())
|
|
173
|
+
.addColumn("serverID", "varchar(255)")
|
|
174
|
+
.addColumn("owner", "varchar(255)")
|
|
175
|
+
.addColumn("expiration", "text")
|
|
176
|
+
.execute();
|
|
177
|
+
await db.schema
|
|
178
|
+
.createIndex("invites_serverID_idx")
|
|
179
|
+
.ifNotExists()
|
|
180
|
+
.on("invites")
|
|
181
|
+
.column("serverID")
|
|
182
|
+
.execute();
|
|
183
|
+
await db.schema
|
|
184
|
+
.createTable("service_metrics")
|
|
185
|
+
.ifNotExists()
|
|
186
|
+
.addColumn("metric_key", "varchar(255)", (cb) => cb.primaryKey())
|
|
187
|
+
.addColumn("metric_value", "bigint", (cb) => cb.notNull().defaultTo(0))
|
|
188
|
+
.execute();
|
|
189
|
+
// Seed the requests_total metric row
|
|
190
|
+
await sql `INSERT OR IGNORE INTO service_metrics (metric_key, metric_value) VALUES ('requests_total', 0)`.execute(db);
|
|
191
|
+
}
|
|
192
|
+
//# sourceMappingURL=2026-04-06_initial-schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"2026-04-06_initial-schema.js","sourceRoot":"","sources":["../../src/migrations/2026-04-06_initial-schema.ts"],"names":[],"mappings":"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"}
|
package/dist/run.js
CHANGED
|
@@ -1,25 +1,30 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
-
});
|
|
10
|
-
};
|
|
11
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
const Spire_1 = require("./Spire");
|
|
13
|
-
const loadEnv_1 = require("./utils/loadEnv");
|
|
1
|
+
import { Spire } from "./Spire.js";
|
|
2
|
+
import { loadEnv } from "./utils/loadEnv.js";
|
|
14
3
|
function main() {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
4
|
+
// load the environment variables — loadEnv() exits if required vars are missing
|
|
5
|
+
loadEnv();
|
|
6
|
+
const spk = process.env["SPK"];
|
|
7
|
+
if (!spk) {
|
|
8
|
+
throw new Error("SPK must be set (loadEnv should have caught this).");
|
|
9
|
+
}
|
|
10
|
+
const apiPort = process.env["API_PORT"];
|
|
11
|
+
const dbType = parseDbType(process.env["DB_TYPE"]);
|
|
12
|
+
new Spire(spk, {
|
|
13
|
+
...(apiPort !== undefined ? { apiPort: Number(apiPort) } : {}),
|
|
14
|
+
...(dbType !== undefined ? { dbType } : {}),
|
|
15
|
+
logLevel: "info",
|
|
23
16
|
});
|
|
24
17
|
}
|
|
18
|
+
function parseDbType(value) {
|
|
19
|
+
switch (value) {
|
|
20
|
+
case "mysql":
|
|
21
|
+
case "sqlite":
|
|
22
|
+
case "sqlite3":
|
|
23
|
+
case "sqlite3mem":
|
|
24
|
+
return value;
|
|
25
|
+
default:
|
|
26
|
+
return undefined;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
25
29
|
main();
|
|
30
|
+
//# sourceMappingURL=run.js.map
|
package/dist/run.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run.js","sourceRoot":"","sources":["../src/run.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAE7C,SAAS,IAAI;IACT,gFAAgF;IAChF,OAAO,EAAE,CAAC;IAEV,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAC/B,IAAI,CAAC,GAAG,EAAE,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;IAC1E,CAAC;IAED,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IACxC,MAAM,MAAM,GAAG,WAAW,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC;IAEnD,IAAI,KAAK,CAAC,GAAG,EAAE;QACX,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9D,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3C,QAAQ,EAAE,MAAM;KACnB,CAAC,CAAC;AACP,CAAC;AAED,SAAS,WAAW,CAAC,KAAyB;IAC1C,QAAQ,KAAK,EAAE,CAAC;QACZ,KAAK,OAAO,CAAC;QACb,KAAK,QAAQ,CAAC;QACd,KAAK,SAAS,CAAC;QACf,KAAK,YAAY;YACb,OAAO,KAAK,CAAC;QACjB;YACI,OAAO,SAAS,CAAC;IACzB,CAAC;AACL,CAAC;AAED,IAAI,EAAE,CAAC"}
|
package/dist/server/avatar.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
import winston from "winston";
|
|
3
|
-
|
|
4
|
-
export declare const getAvatarRouter: (db: Database, log: winston.Logger) => import("express-ws").Router;
|
|
1
|
+
import type { Database } from "../Database.ts";
|
|
2
|
+
import type winston from "winston";
|
|
3
|
+
export declare const getAvatarRouter: (db: Database, log: winston.Logger) => import("express-serve-static-core").Router;
|
package/dist/server/avatar.js
CHANGED
|
@@ -1,92 +1,110 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
const
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
router.get("/:userID", (req, res) => __awaiter(void 0, void 0, void 0, function* () {
|
|
25
|
-
const stream = fs_1.default.createReadStream("./avatars/" + req.params.userID);
|
|
26
|
-
stream.on("error", (err) => {
|
|
27
|
-
// log.error(err.toString());
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import * as fsp from "node:fs/promises";
|
|
3
|
+
import express from "express";
|
|
4
|
+
import { XUtils } from "@vex-chat/crypto";
|
|
5
|
+
import { FilePayloadSchema } from "@vex-chat/types";
|
|
6
|
+
import { fileTypeFromBuffer, fileTypeFromFile } from "file-type";
|
|
7
|
+
import multer from "multer";
|
|
8
|
+
import { z } from "zod/v4";
|
|
9
|
+
import { uploadLimiter } from "./rateLimit.js";
|
|
10
|
+
import { getParam, getUser } from "./utils.js";
|
|
11
|
+
import { ALLOWED_IMAGE_TYPES, protect } from "./index.js";
|
|
12
|
+
const safePathParam = z.string().regex(/^[a-zA-Z0-9._-]+$/);
|
|
13
|
+
export const getAvatarRouter = (db, log) => {
|
|
14
|
+
const router = express.Router();
|
|
15
|
+
router.get("/:userID", async (req, res) => {
|
|
16
|
+
const safeId = safePathParam.safeParse(getParam(req, "userID"));
|
|
17
|
+
if (!safeId.success) {
|
|
18
|
+
res.sendStatus(400);
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
const filePath = "./avatars/" + safeId.data;
|
|
22
|
+
const typeDetails = await fileTypeFromFile(filePath).catch(() => null);
|
|
23
|
+
if (!typeDetails) {
|
|
28
24
|
res.sendStatus(404);
|
|
29
|
-
|
|
30
|
-
const typeDetails = yield file_type_1.default.fromStream(stream);
|
|
31
|
-
if (typeDetails) {
|
|
32
|
-
res.set("Content-type", typeDetails.mime);
|
|
25
|
+
return;
|
|
33
26
|
}
|
|
27
|
+
res.set("Content-type", typeDetails.mime);
|
|
34
28
|
res.set("Cache-control", "public, max-age=31536000");
|
|
35
|
-
const
|
|
36
|
-
|
|
29
|
+
const stream = fs.createReadStream(filePath);
|
|
30
|
+
stream.on("error", (err) => {
|
|
37
31
|
log.error(err.toString());
|
|
38
32
|
res.sendStatus(500);
|
|
39
33
|
});
|
|
40
|
-
|
|
41
|
-
})
|
|
42
|
-
router.post("/:userID",
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
34
|
+
stream.pipe(res);
|
|
35
|
+
});
|
|
36
|
+
router.post("/:userID/json", protect, async (req, res) => {
|
|
37
|
+
const parsed = FilePayloadSchema.safeParse(req.body);
|
|
38
|
+
if (!parsed.success) {
|
|
39
|
+
res.status(400).json({
|
|
40
|
+
error: "Invalid file payload",
|
|
41
|
+
issues: parsed.error.issues,
|
|
42
|
+
});
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
const payload = parsed.data;
|
|
46
|
+
const userDetails = getUser(req);
|
|
47
|
+
const deviceDetails = req.device;
|
|
48
|
+
if (!deviceDetails) {
|
|
49
|
+
res.sendStatus(401);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
if (!payload.file) {
|
|
53
|
+
log.warn("MISSING FILE");
|
|
54
|
+
res.sendStatus(400);
|
|
47
55
|
return;
|
|
48
56
|
}
|
|
49
|
-
const
|
|
50
|
-
const mimeType =
|
|
51
|
-
|
|
52
|
-
const allowedTypes = [
|
|
53
|
-
"image/jpeg",
|
|
54
|
-
"image/png",
|
|
55
|
-
"image/gif",
|
|
56
|
-
"image/apng",
|
|
57
|
-
"image/avif",
|
|
58
|
-
"image/svg+xml",
|
|
59
|
-
];
|
|
60
|
-
if (!allowedTypes.includes((mimeType === null || mimeType === void 0 ? void 0 : mimeType.mime) || "no/type")) {
|
|
57
|
+
const buf = Buffer.from(XUtils.decodeBase64(payload.file));
|
|
58
|
+
const mimeType = await fileTypeFromBuffer(buf);
|
|
59
|
+
if (!ALLOWED_IMAGE_TYPES.includes(mimeType?.mime || "no/type")) {
|
|
61
60
|
res.status(400).send({
|
|
62
|
-
error: "Unsupported file type. Expected jpeg, png, gif, apng, avif, or svg but received " +
|
|
61
|
+
error: "Unsupported file type. Expected jpeg, png, gif, apng, avif, or svg but received " +
|
|
62
|
+
String(mimeType?.ext),
|
|
63
63
|
});
|
|
64
64
|
return;
|
|
65
65
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
66
|
+
try {
|
|
67
|
+
// write the file to disk
|
|
68
|
+
await fsp.writeFile("avatars/" + userDetails.userID, buf);
|
|
69
|
+
log.info("Wrote new avatar " + userDetails.userID);
|
|
70
|
+
res.sendStatus(200);
|
|
71
|
+
}
|
|
72
|
+
catch (err) {
|
|
73
|
+
log.warn(String(err));
|
|
74
|
+
res.sendStatus(500);
|
|
72
75
|
}
|
|
73
|
-
|
|
74
|
-
|
|
76
|
+
});
|
|
77
|
+
router.post("/:userID", uploadLimiter, protect, multer().single("avatar"), async (req, res) => {
|
|
78
|
+
const userDetails = getUser(req);
|
|
79
|
+
const deviceDetails = req.device;
|
|
80
|
+
if (!deviceDetails) {
|
|
75
81
|
res.sendStatus(401);
|
|
76
82
|
return;
|
|
77
83
|
}
|
|
84
|
+
if (!req.file) {
|
|
85
|
+
log.warn("MISSING FILE");
|
|
86
|
+
res.sendStatus(400);
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
const mimeType = await fileTypeFromBuffer(req.file.buffer);
|
|
90
|
+
if (!ALLOWED_IMAGE_TYPES.includes(mimeType?.mime || "no/type")) {
|
|
91
|
+
res.status(400).send({
|
|
92
|
+
error: "Unsupported file type. Expected jpeg, png, gif, apng, avif, or svg but received " +
|
|
93
|
+
String(mimeType?.ext),
|
|
94
|
+
});
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
78
97
|
try {
|
|
79
98
|
// write the file to disk
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
});
|
|
99
|
+
await fsp.writeFile("avatars/" + userDetails.userID, req.file.buffer);
|
|
100
|
+
log.info("Wrote new avatar " + userDetails.userID);
|
|
83
101
|
res.sendStatus(200);
|
|
84
102
|
}
|
|
85
103
|
catch (err) {
|
|
86
|
-
log.warn(err);
|
|
104
|
+
log.warn(String(err));
|
|
87
105
|
res.sendStatus(500);
|
|
88
106
|
}
|
|
89
|
-
})
|
|
107
|
+
});
|
|
90
108
|
return router;
|
|
91
109
|
};
|
|
92
|
-
|
|
110
|
+
//# sourceMappingURL=avatar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"avatar.js","sourceRoot":"","sources":["../../src/server/avatar.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Centralized HTTP error handling.
|
|
3
|
+
*
|
|
4
|
+
* Fixes two classes of CodeQL findings:
|
|
5
|
+
*
|
|
6
|
+
* - **CWE-209 / CWE-497 — Information exposure through stack trace.**
|
|
7
|
+
* Previously, every route catch block did
|
|
8
|
+
* `res.status(500).send(String(err))`, leaking raw error objects
|
|
9
|
+
* (which include database internals, file paths, and stack traces)
|
|
10
|
+
* back to the client. The new pattern: throw `AppError(status, msg)`
|
|
11
|
+
* or let an unknown error propagate, and the single 4-arg middleware
|
|
12
|
+
* below converts it into a JSON response with a generic message
|
|
13
|
+
* while logging the full internals server-side via winston.
|
|
14
|
+
*
|
|
15
|
+
* - **CWE-79 / CWE-116 — Exception text reinterpreted as HTML.** Express's
|
|
16
|
+
* default finalhandler sends thrown `Error` objects as
|
|
17
|
+
* `Content-Type: text/html`, which means `throw new Error("bad param: "
|
|
18
|
+
* + req.params.name)` became reflected XSS when the error page
|
|
19
|
+
* rendered. The handler below ALWAYS sends `application/json`, so
|
|
20
|
+
* even if a message somehow contains user input, the browser can't
|
|
21
|
+
* execute it. The companion fix is `getParam()` in `utils.ts` now
|
|
22
|
+
* throwing `AppError(400, "Missing route parameter")` with no user
|
|
23
|
+
* input in the message string.
|
|
24
|
+
*
|
|
25
|
+
* Express 5 has native async support, so throwing from an async
|
|
26
|
+
* handler auto-forwards to `next(err)` and hits this middleware. No
|
|
27
|
+
* `express-async-errors` shim needed.
|
|
28
|
+
*/
|
|
29
|
+
import type { ErrorRequestHandler } from "express";
|
|
30
|
+
import type winston from "winston";
|
|
31
|
+
/**
|
|
32
|
+
* Operational HTTP errors that are safe to surface to the client.
|
|
33
|
+
*
|
|
34
|
+
* - `status` — HTTP status code (400, 401, 403, 404, 409, etc.)
|
|
35
|
+
* - `message` — client-safe message, MUST NOT contain request data
|
|
36
|
+
* (route params, body fields, query strings). Anything operator-
|
|
37
|
+
* only (database errors, file paths) belongs in winston logs, not
|
|
38
|
+
* in this string.
|
|
39
|
+
*
|
|
40
|
+
* Anything that isn't an `AppError` (raw `Error`, `TypeError`, a
|
|
41
|
+
* rejected promise from a DB query, etc.) is treated by the central
|
|
42
|
+
* handler as a **programmer error** — the client gets a generic 500
|
|
43
|
+
* with no detail, and the real error is logged server-side.
|
|
44
|
+
*/
|
|
45
|
+
export declare class AppError extends Error {
|
|
46
|
+
readonly status: number;
|
|
47
|
+
constructor(status: number, message: string);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Factory producing the central Express 5 error middleware.
|
|
51
|
+
*
|
|
52
|
+
* Register this as the LAST middleware in the app, after every
|
|
53
|
+
* route and router has been mounted:
|
|
54
|
+
*
|
|
55
|
+
* api.use("/user", userRouter);
|
|
56
|
+
* // ... all other routers ...
|
|
57
|
+
* api.use(errorHandler(log));
|
|
58
|
+
*/
|
|
59
|
+
export declare const errorHandler: (log: winston.Logger) => ErrorRequestHandler;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { ZodError } from "zod/v4";
|
|
3
|
+
/**
|
|
4
|
+
* Operational HTTP errors that are safe to surface to the client.
|
|
5
|
+
*
|
|
6
|
+
* - `status` — HTTP status code (400, 401, 403, 404, 409, etc.)
|
|
7
|
+
* - `message` — client-safe message, MUST NOT contain request data
|
|
8
|
+
* (route params, body fields, query strings). Anything operator-
|
|
9
|
+
* only (database errors, file paths) belongs in winston logs, not
|
|
10
|
+
* in this string.
|
|
11
|
+
*
|
|
12
|
+
* Anything that isn't an `AppError` (raw `Error`, `TypeError`, a
|
|
13
|
+
* rejected promise from a DB query, etc.) is treated by the central
|
|
14
|
+
* handler as a **programmer error** — the client gets a generic 500
|
|
15
|
+
* with no detail, and the real error is logged server-side.
|
|
16
|
+
*/
|
|
17
|
+
export class AppError extends Error {
|
|
18
|
+
status;
|
|
19
|
+
constructor(status, message) {
|
|
20
|
+
super(message);
|
|
21
|
+
this.name = "AppError";
|
|
22
|
+
this.status = status;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Factory producing the central Express 5 error middleware.
|
|
27
|
+
*
|
|
28
|
+
* Register this as the LAST middleware in the app, after every
|
|
29
|
+
* route and router has been mounted:
|
|
30
|
+
*
|
|
31
|
+
* api.use("/user", userRouter);
|
|
32
|
+
* // ... all other routers ...
|
|
33
|
+
* api.use(errorHandler(log));
|
|
34
|
+
*/
|
|
35
|
+
export const errorHandler = (log) => (err, req, res, _next) => {
|
|
36
|
+
// If headers already went out there's nothing safe to do except
|
|
37
|
+
// let Express's default handler close the socket.
|
|
38
|
+
if (res.headersSent) {
|
|
39
|
+
_next(err);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
const requestId = randomUUID();
|
|
43
|
+
let status = 500;
|
|
44
|
+
let clientMessage = "Internal Server Error";
|
|
45
|
+
let details;
|
|
46
|
+
if (err instanceof ZodError) {
|
|
47
|
+
// Validation failure at a trust boundary. The issue list is
|
|
48
|
+
// structured JSON (no raw user input as a rendered string),
|
|
49
|
+
// so it's safe to surface to help clients fix their payload.
|
|
50
|
+
status = 400;
|
|
51
|
+
clientMessage = "Validation failed";
|
|
52
|
+
details = err.issues;
|
|
53
|
+
}
|
|
54
|
+
else if (err instanceof AppError) {
|
|
55
|
+
status = err.status;
|
|
56
|
+
clientMessage = err.message;
|
|
57
|
+
}
|
|
58
|
+
// Log the full internals server-side. `err instanceof Error` also
|
|
59
|
+
// catches AppError (extends Error), so we get stacks and messages
|
|
60
|
+
// for every branch in the logs.
|
|
61
|
+
if (err instanceof Error) {
|
|
62
|
+
log.error("request failed", {
|
|
63
|
+
error: {
|
|
64
|
+
message: err.message,
|
|
65
|
+
name: err.name,
|
|
66
|
+
stack: err.stack,
|
|
67
|
+
},
|
|
68
|
+
method: req.method,
|
|
69
|
+
path: req.path,
|
|
70
|
+
requestId,
|
|
71
|
+
status,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
log.error("request failed", {
|
|
76
|
+
error: String(err),
|
|
77
|
+
method: req.method,
|
|
78
|
+
path: req.path,
|
|
79
|
+
requestId,
|
|
80
|
+
status,
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
// ALWAYS JSON — prevents the exception-text-as-HTML XSS vector.
|
|
84
|
+
res.status(status)
|
|
85
|
+
.type("application/json")
|
|
86
|
+
.json({
|
|
87
|
+
error: {
|
|
88
|
+
message: clientMessage,
|
|
89
|
+
requestId,
|
|
90
|
+
...(details !== undefined ? { details } : {}),
|
|
91
|
+
},
|
|
92
|
+
});
|
|
93
|
+
};
|
|
94
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/server/errors.ts"],"names":[],"mappings":"AA+BA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAElC;;;;;;;;;;;;;GAaG;AACH,MAAM,OAAO,QAAS,SAAQ,KAAK;IACf,MAAM,CAAS;IAE/B,YAAY,MAAc,EAAE,OAAe;QACvC,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;QACvB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACzB,CAAC;CACJ;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,YAAY,GACrB,CAAC,GAAmB,EAAuB,EAAE,CAC7C,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE;IACrB,gEAAgE;IAChE,kDAAkD;IAClD,IAAI,GAAG,CAAC,WAAW,EAAE,CAAC;QAClB,KAAK,CAAC,GAAG,CAAC,CAAC;QACX,OAAO;IACX,CAAC;IAED,MAAM,SAAS,GAAG,UAAU,EAAE,CAAC;IAE/B,IAAI,MAAM,GAAG,GAAG,CAAC;IACjB,IAAI,aAAa,GAAG,uBAAuB,CAAC;IAC5C,IAAI,OAAgB,CAAC;IAErB,IAAI,GAAG,YAAY,QAAQ,EAAE,CAAC;QAC1B,4DAA4D;QAC5D,4DAA4D;QAC5D,6DAA6D;QAC7D,MAAM,GAAG,GAAG,CAAC;QACb,aAAa,GAAG,mBAAmB,CAAC;QACpC,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC;IACzB,CAAC;SAAM,IAAI,GAAG,YAAY,QAAQ,EAAE,CAAC;QACjC,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC;QACpB,aAAa,GAAG,GAAG,CAAC,OAAO,CAAC;IAChC,CAAC;IAED,kEAAkE;IAClE,kEAAkE;IAClE,gCAAgC;IAChC,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;QACvB,GAAG,CAAC,KAAK,CAAC,gBAAgB,EAAE;YACxB,KAAK,EAAE;gBACH,OAAO,EAAE,GAAG,CAAC,OAAO;gBACpB,IAAI,EAAE,GAAG,CAAC,IAAI;gBACd,KAAK,EAAE,GAAG,CAAC,KAAK;aACnB;YACD,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,SAAS;YACT,MAAM;SACT,CAAC,CAAC;IACP,CAAC;SAAM,CAAC;QACJ,GAAG,CAAC,KAAK,CAAC,gBAAgB,EAAE;YACxB,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC;YAClB,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,SAAS;YACT,MAAM;SACT,CAAC,CAAC;IACP,CAAC;IAED,gEAAgE;IAChE,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC;SACb,IAAI,CAAC,kBAAkB,CAAC;SACxB,IAAI,CAAC;QACF,KAAK,EAAE;YACH,OAAO,EAAE,aAAa;YACtB,SAAS;YACT,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAChD;KACJ,CAAC,CAAC;AACX,CAAC,CAAC"}
|
package/dist/server/file.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
import winston from "winston";
|
|
3
|
-
|
|
4
|
-
export declare const getFileRouter: (db: Database, log: winston.Logger) => import("express-ws").Router;
|
|
1
|
+
import type { Database } from "../Database.ts";
|
|
2
|
+
import type winston from "winston";
|
|
3
|
+
export declare const getFileRouter: (db: Database, log: winston.Logger) => import("express-serve-static-core").Router;
|