@drax/media-back 2.11.0 → 3.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/dist/controllers/FileController.js +38 -0
- package/dist/controllers/MediaController.js +42 -1
- package/dist/factory/services/FileServiceFactory.js +30 -0
- package/dist/index.js +13 -2
- package/dist/interfaces/IFile.js +1 -0
- package/dist/interfaces/IFileRepository.js +1 -0
- package/dist/models/FileModel.js +49 -0
- package/dist/permissions/FilePermissions.js +13 -0
- package/dist/repository/mongo/FileMongoRepository.js +13 -0
- package/dist/repository/sqlite/FileSqliteRepository.js +37 -0
- package/dist/routes/FileRoutes.js +20 -0
- package/dist/schemas/FileSchema.js +51 -0
- package/dist/services/FileService.js +22 -0
- package/package.json +4 -4
- package/src/controllers/FileController.ts +50 -0
- package/src/controllers/MediaController.ts +48 -4
- package/src/factory/services/FileServiceFactory.ts +41 -0
- package/src/index.ts +30 -3
- package/src/interfaces/IFile.ts +67 -0
- package/src/interfaces/IFileRepository.ts +11 -0
- package/src/models/FileModel.ts +65 -0
- package/src/permissions/FilePermissions.ts +17 -0
- package/src/repository/mongo/FileMongoRepository.ts +22 -0
- package/src/repository/sqlite/FileSqliteRepository.ts +46 -0
- package/src/routes/FileRoutes.ts +36 -0
- package/src/schemas/FileSchema.ts +55 -0
- package/src/services/FileService.ts +36 -0
- package/test/modules/media/File/File-endpoints.test.ts +573 -0
- package/test/setup/MongoInMemory.ts +56 -0
- package/test/setup/TestSetup.ts +347 -0
- package/test/setup/data/admin-role.ts +13 -0
- package/test/setup/data/basic-user.ts +14 -0
- package/test/setup/data/file-role.ts +16 -0
- package/test/setup/data/one-tenant.ts +6 -0
- package/test/setup/data/restricted-role.ts +11 -0
- package/test/setup/data/root-user.ts +14 -0
- package/test/setup/data/tenant-one-user.ts +13 -0
- package/test/setup/data/tenant-two-user.ts +14 -0
- package/test/setup/data/two-tenant.ts +6 -0
- package/test/utils/StoreManager.test.ts +1 -1
- package/tsconfig.tsbuildinfo +1 -1
- package/types/controllers/FileController.d.ts +10 -0
- package/types/controllers/FileController.d.ts.map +1 -0
- package/types/controllers/MediaController.d.ts.map +1 -1
- package/types/factory/services/FileServiceFactory.d.ts +8 -0
- package/types/factory/services/FileServiceFactory.d.ts.map +1 -0
- package/types/index.d.ts +13 -1
- package/types/index.d.ts.map +1 -1
- package/types/interfaces/IFile.d.ts +63 -0
- package/types/interfaces/IFile.d.ts.map +1 -0
- package/types/interfaces/IFileRepository.d.ts +6 -0
- package/types/interfaces/IFileRepository.d.ts.map +1 -0
- package/types/models/FileModel.d.ts +15 -0
- package/types/models/FileModel.d.ts.map +1 -0
- package/types/permissions/FilePermissions.d.ts +13 -0
- package/types/permissions/FilePermissions.d.ts.map +1 -0
- package/types/repository/mongo/FileMongoRepository.d.ts +9 -0
- package/types/repository/mongo/FileMongoRepository.d.ts.map +1 -0
- package/types/repository/sqlite/FileSqliteRepository.d.ts +18 -0
- package/types/repository/sqlite/FileSqliteRepository.d.ts.map +1 -0
- package/types/routes/FileRoutes.d.ts +4 -0
- package/types/routes/FileRoutes.d.ts.map +1 -0
- package/types/schemas/FileSchema.d.ts +65 -0
- package/types/schemas/FileSchema.d.ts.map +1 -0
- package/types/services/FileService.d.ts +12 -0
- package/types/services/FileService.d.ts.map +1 -0
|
@@ -0,0 +1,347 @@
|
|
|
1
|
+
import Fastify, { FastifyInstance, FastifyPluginAsync } from "fastify";
|
|
2
|
+
import { LoadCommonConfigFromEnv } from "@drax/common-back";
|
|
3
|
+
import {
|
|
4
|
+
LoadIdentityConfigFromEnv,
|
|
5
|
+
CreateTenantIfNotExist,
|
|
6
|
+
CreateOrUpdateRole,
|
|
7
|
+
CreateUserIfNotExist,
|
|
8
|
+
jwtMiddleware,
|
|
9
|
+
rbacMiddleware,
|
|
10
|
+
apiKeyMiddleware,
|
|
11
|
+
UserRoutes, RoleRoutes, TenantRoutes, UserApiKeyRoutes,
|
|
12
|
+
UserPermissions, RolePermissions, TenantPermissions, UserApiKeyPermissions,
|
|
13
|
+
LoadPermissions
|
|
14
|
+
} from "@drax/identity-back";
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
import adminRoleData from "./data/admin-role";
|
|
18
|
+
import restrictedRoleData from "./data/restricted-role";
|
|
19
|
+
import fileRoleData from "./data/file-role";
|
|
20
|
+
|
|
21
|
+
import rootUserData from "./data/root-user";
|
|
22
|
+
import basicUserData from "./data/basic-user";
|
|
23
|
+
|
|
24
|
+
import { IUser, IRole, ITenant } from "@drax/identity-share";
|
|
25
|
+
import MongoInMemory from "./MongoInMemory";
|
|
26
|
+
|
|
27
|
+
import oneTenant from "./data/one-tenant";
|
|
28
|
+
import twoTenant from "./data/two-tenant";
|
|
29
|
+
import tenantOneUser from "./data/tenant-one-user";
|
|
30
|
+
import tenantTwoUser from "./data/tenant-two-user";
|
|
31
|
+
|
|
32
|
+
interface ITestSetupInput {
|
|
33
|
+
routes?: FastifyPluginAsync[]
|
|
34
|
+
permissions?: object[]
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
class TestSetup {
|
|
38
|
+
|
|
39
|
+
private _fastifyInstance: FastifyInstance;
|
|
40
|
+
private _mongoInMemory: MongoInMemory;
|
|
41
|
+
private _rootUser: IUser;
|
|
42
|
+
private _basicUser: IUser;
|
|
43
|
+
private _adminRole: IRole;
|
|
44
|
+
private _restrictedRole: IRole;
|
|
45
|
+
private _customRoutes: FastifyPluginAsync[] = [];
|
|
46
|
+
private _customPermissions: object[] = [];
|
|
47
|
+
|
|
48
|
+
private _tenantOne: ITenant;
|
|
49
|
+
private _tenantTwo: ITenant;
|
|
50
|
+
private _tenantOneUser: IUser;
|
|
51
|
+
private _tenantTwoUser: IUser;
|
|
52
|
+
|
|
53
|
+
constructor(input?: ITestSetupInput) {
|
|
54
|
+
this._customRoutes = input?.routes ?? [];
|
|
55
|
+
this._customPermissions = input?.permissions ?? [];
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
async setup() {
|
|
59
|
+
this.setupEnvironmentVariables();
|
|
60
|
+
this.setupConfig();
|
|
61
|
+
this.setupPermissions();
|
|
62
|
+
this.setupFastifyInstance();
|
|
63
|
+
await this.setupMongoInMemoryAndConnect();
|
|
64
|
+
await this.setupRootUserAndAdminRole();
|
|
65
|
+
await this.setupBasicUserAndRestrictedRole();
|
|
66
|
+
await this.setupFileRole();
|
|
67
|
+
await this.setupTenantOneAndTenantOneUser();
|
|
68
|
+
await this.setupTenantTwoAndTenantTwoUser();
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
setupEnvironmentVariables() {
|
|
72
|
+
// Define environment variables
|
|
73
|
+
process.env.DRAX_DB_ENGINE = "mongo";
|
|
74
|
+
process.env.DRAX_JWT_SECRET = "xxx";
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
setupConfig() {
|
|
78
|
+
LoadCommonConfigFromEnv();
|
|
79
|
+
LoadIdentityConfigFromEnv();
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
setupPermissions() {
|
|
83
|
+
//Merge All Permissions
|
|
84
|
+
const permissions = [
|
|
85
|
+
...Object.values(UserPermissions),
|
|
86
|
+
...Object.values(RolePermissions),
|
|
87
|
+
...Object.values(TenantPermissions),
|
|
88
|
+
...Object.values(UserApiKeyPermissions),
|
|
89
|
+
...this.getCustomPermissions()
|
|
90
|
+
]
|
|
91
|
+
|
|
92
|
+
//Load All Permissions
|
|
93
|
+
LoadPermissions(permissions)
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
getCustomPermissions() {
|
|
97
|
+
const customPermissions = []
|
|
98
|
+
for (const permission of this._customPermissions) {
|
|
99
|
+
customPermissions.push(...Object.values(permission))
|
|
100
|
+
}
|
|
101
|
+
return customPermissions
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
setupFastifyInstance() {
|
|
105
|
+
this._fastifyInstance = Fastify()
|
|
106
|
+
this._fastifyInstance.setErrorHandler(function (error: any, request, reply) {
|
|
107
|
+
console.error("TEST FASTIFY ERROR CAUGHT:", error);
|
|
108
|
+
reply.status(500).send({ statusCode: 500, error: "InternalServerError", message: error?.message });
|
|
109
|
+
});
|
|
110
|
+
this._fastifyInstance.setValidatorCompiler(() => () => true)
|
|
111
|
+
this._fastifyInstance.addHook('onRequest', jwtMiddleware)
|
|
112
|
+
this._fastifyInstance.addHook('onRequest', rbacMiddleware)
|
|
113
|
+
this._fastifyInstance.addHook('onRequest', apiKeyMiddleware)
|
|
114
|
+
this._fastifyInstance.register(UserRoutes)
|
|
115
|
+
this._fastifyInstance.register(RoleRoutes)
|
|
116
|
+
this._fastifyInstance.register(TenantRoutes)
|
|
117
|
+
this._fastifyInstance.register(UserApiKeyRoutes)
|
|
118
|
+
this.registerRoutes(this._customRoutes)
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
registerRoutes(routes: FastifyPluginAsync[]) {
|
|
122
|
+
for (const route of routes) {
|
|
123
|
+
this._fastifyInstance.register(route)
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
async setupMongoInMemoryAndConnect() {
|
|
128
|
+
this._mongoInMemory = new MongoInMemory();
|
|
129
|
+
await this._mongoInMemory.connect();
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
async setupTenantOneAndTenantOneUser() {
|
|
133
|
+
this._tenantOne = await CreateTenantIfNotExist(oneTenant)
|
|
134
|
+
this._tenantOneUser = await CreateUserIfNotExist({ ...tenantOneUser })
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
async setupTenantTwoAndTenantTwoUser() {
|
|
138
|
+
this._tenantTwo = await CreateTenantIfNotExist(twoTenant)
|
|
139
|
+
this._tenantTwoUser = await CreateUserIfNotExist({ ...tenantTwoUser })
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
async setupRootUserAndAdminRole() {
|
|
143
|
+
this._adminRole = await CreateOrUpdateRole({ ...adminRoleData })
|
|
144
|
+
this._rootUser = await CreateUserIfNotExist({ ...rootUserData })
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
async setupBasicUserAndRestrictedRole() {
|
|
148
|
+
this._restrictedRole = await CreateOrUpdateRole({ ...restrictedRoleData })
|
|
149
|
+
this._basicUser = await CreateUserIfNotExist({ ...basicUserData })
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
async setupFileRole() {
|
|
153
|
+
this._restrictedRole = await CreateOrUpdateRole({ ...fileRoleData })
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
addRoutes(routes) {
|
|
157
|
+
this._fastifyInstance.register(routes)
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
addPermissions(permissions: object) {
|
|
161
|
+
LoadPermissions([...Object.values(permissions)])
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
async dropCollections() {
|
|
165
|
+
await this._mongoInMemory.dropCollections()
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
async dropCollection(collectionName: string) {
|
|
169
|
+
await this._mongoInMemory.dropCollection(collectionName)
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
async dropAndClose() {
|
|
173
|
+
await this._mongoInMemory.dropAndClose()
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
async login(username: string, password: string): Promise<{ accessToken: string }> {
|
|
177
|
+
|
|
178
|
+
const resp = await this._fastifyInstance.inject({
|
|
179
|
+
method: 'POST',
|
|
180
|
+
url: '/api/auth/login',
|
|
181
|
+
payload: { username: username, password: password }
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
let body = resp.json()
|
|
185
|
+
|
|
186
|
+
if (resp.statusCode === 200 && body.accessToken) {
|
|
187
|
+
return { accessToken: body.accessToken }
|
|
188
|
+
} else {
|
|
189
|
+
throw new Error(`Failed to login. Status Code: ${resp.statusCode} body: ${resp.body}`)
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
async rootUserLogin(): Promise<{ accessToken: string }> {
|
|
195
|
+
|
|
196
|
+
const resp = await this._fastifyInstance.inject({
|
|
197
|
+
method: 'POST',
|
|
198
|
+
url: '/api/auth/login',
|
|
199
|
+
payload: {
|
|
200
|
+
username: rootUserData.username,
|
|
201
|
+
password: rootUserData.password
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
let body = resp.json()
|
|
206
|
+
|
|
207
|
+
if (resp.statusCode === 200 && body.accessToken) {
|
|
208
|
+
return { accessToken: body.accessToken }
|
|
209
|
+
} else {
|
|
210
|
+
throw new Error(`Failed to login. Status Code: ${resp.statusCode} body: ${resp.body}`)
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
async basicUserLogin(): Promise<{ accessToken: string }> {
|
|
215
|
+
|
|
216
|
+
const resp = await this._fastifyInstance.inject({
|
|
217
|
+
method: 'POST',
|
|
218
|
+
url: '/api/auth/login',
|
|
219
|
+
payload: {
|
|
220
|
+
username: basicUserData.username,
|
|
221
|
+
password: basicUserData.password
|
|
222
|
+
}
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
let body = resp.json()
|
|
226
|
+
|
|
227
|
+
if (resp.statusCode === 200 && body.accessToken) {
|
|
228
|
+
return { accessToken: body.accessToken }
|
|
229
|
+
} else {
|
|
230
|
+
throw new Error(`Failed to login. Status Code: ${resp.statusCode} body: ${resp.body}`)
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
async tenantOneUserLogin(): Promise<{ accessToken: string }> {
|
|
235
|
+
const resp = await this._fastifyInstance.inject({
|
|
236
|
+
method: 'POST',
|
|
237
|
+
url: '/api/auth/login',
|
|
238
|
+
payload: {
|
|
239
|
+
username: tenantOneUser.username,
|
|
240
|
+
password: tenantOneUser.password
|
|
241
|
+
}
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
let body = resp.json()
|
|
245
|
+
|
|
246
|
+
if (resp.statusCode === 200 && body.accessToken) {
|
|
247
|
+
return { accessToken: body.accessToken }
|
|
248
|
+
} else {
|
|
249
|
+
throw new Error(`Failed to login. Status Code: ${resp.statusCode} body: ${resp.body}`)
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
async tenantTwoUserLogin(): Promise<{ accessToken: string }> {
|
|
254
|
+
const resp = await this._fastifyInstance.inject({
|
|
255
|
+
method: 'POST',
|
|
256
|
+
url: '/api/auth/login',
|
|
257
|
+
payload: {
|
|
258
|
+
username: tenantTwoUser.username,
|
|
259
|
+
password: tenantTwoUser.password
|
|
260
|
+
}
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
let body = resp.json()
|
|
264
|
+
|
|
265
|
+
if (resp.statusCode === 200 && body.accessToken) {
|
|
266
|
+
return { accessToken: body.accessToken }
|
|
267
|
+
} else {
|
|
268
|
+
throw new Error(`Failed to login. Status Code: ${resp.statusCode} body: ${resp.body}`)
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
async me(accessToken: string): Promise<IUser> {
|
|
273
|
+
|
|
274
|
+
const resp = await this._fastifyInstance.inject({
|
|
275
|
+
method: 'GET',
|
|
276
|
+
url: '/api/auth/me',
|
|
277
|
+
headers: { Authorization: `Bearer ${accessToken}` }
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
if (resp.statusCode === 200) {
|
|
281
|
+
let user: IUser = resp.json() as IUser
|
|
282
|
+
return user
|
|
283
|
+
} else {
|
|
284
|
+
throw new Error(`Failed to get me. Status Code: ${resp.statusCode} body: ${resp.body}`)
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
get adminRoleData() {
|
|
292
|
+
return { ...adminRoleData };
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
get restrictedRoleData() {
|
|
296
|
+
return { ...restrictedRoleData };
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
get rootUserData() {
|
|
300
|
+
return { ...rootUserData };
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
get basicUserData() {
|
|
304
|
+
return { ...basicUserData };
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
get tenantOneUserData() {
|
|
308
|
+
return { ...tenantOneUser };
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
get tenantTwoUserData() {
|
|
312
|
+
return { ...tenantTwoUser };
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
get adminRole() {
|
|
316
|
+
return this._adminRole;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
get restrictedRole() {
|
|
320
|
+
return this._restrictedRole;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
get rootUser() {
|
|
324
|
+
return this._rootUser;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
get basicUser() {
|
|
328
|
+
return this._basicUser;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
get fastifyInstance() {
|
|
332
|
+
return this._fastifyInstance;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
get mongoInMemory() {
|
|
336
|
+
return this._mongoInMemory;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
|
|
343
|
+
export default TestSetup
|
|
344
|
+
|
|
345
|
+
export {
|
|
346
|
+
TestSetup
|
|
347
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import {PermissionService} from "@drax/identity-back"
|
|
2
|
+
|
|
3
|
+
const adminRoleData = {
|
|
4
|
+
name: "Admin",
|
|
5
|
+
permissions: PermissionService.getPermissions(),
|
|
6
|
+
childRoles: [],
|
|
7
|
+
readonly: true
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export default adminRoleData
|
|
11
|
+
export {
|
|
12
|
+
adminRoleData
|
|
13
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
|
|
2
|
+
const basicUser = {
|
|
3
|
+
active: true,
|
|
4
|
+
groups: [],
|
|
5
|
+
name: "Basic User",
|
|
6
|
+
username: "basicUser",
|
|
7
|
+
password: "basic.123",
|
|
8
|
+
email: "basic@example.com",
|
|
9
|
+
phone: "123456789",
|
|
10
|
+
role: "Restricted"
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export default basicUser
|
|
14
|
+
export {basicUser}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import FilePermissions from "../../../src/permissions/FilePermissions";
|
|
2
|
+
|
|
3
|
+
const restrictedRoleData = {
|
|
4
|
+
name: "FileRole",
|
|
5
|
+
permissions: [
|
|
6
|
+
FilePermissions.View,
|
|
7
|
+
FilePermissions.Create,
|
|
8
|
+
FilePermissions.Update,
|
|
9
|
+
FilePermissions.Delete,
|
|
10
|
+
],
|
|
11
|
+
childRoles: [],
|
|
12
|
+
readonly: true
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export default restrictedRoleData
|
|
16
|
+
export {restrictedRoleData}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
const tenantOneUser = {
|
|
2
|
+
active: true,
|
|
3
|
+
name: "TenantOneUser",
|
|
4
|
+
username: "tenantoneuser",
|
|
5
|
+
password: "123456789",
|
|
6
|
+
email: "tenantoneuser@example.com",
|
|
7
|
+
phone: "123456789",
|
|
8
|
+
role: "FileRole",
|
|
9
|
+
tenant: 'one'
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export default tenantOneUser
|
|
13
|
+
export {tenantOneUser}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
|
|
2
|
+
const tenantTwoUser = {
|
|
3
|
+
active: true,
|
|
4
|
+
name: "TenantTwoUser",
|
|
5
|
+
username: "tenanttwouser",
|
|
6
|
+
password: "123456789",
|
|
7
|
+
email: "tenanttwouser@example.com",
|
|
8
|
+
phone: "123456789",
|
|
9
|
+
role: "FileRole",
|
|
10
|
+
tenant: 'two'
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export default tenantTwoUser
|
|
14
|
+
export {tenantTwoUser}
|
|
@@ -5,7 +5,7 @@ import type {IUploadFile} from "../../../../common/common-back/src/interfaces/IU
|
|
|
5
5
|
import {join} from "path";
|
|
6
6
|
import UploadFileError from "../../../../common/common-back/src/errors/UploadFileError";
|
|
7
7
|
import StoreManager from "../../../../common/common-back/src/store/StoreManager";
|
|
8
|
-
import path from "path";
|
|
8
|
+
import * as path from "path";
|
|
9
9
|
import {fileURLToPath} from "url";
|
|
10
10
|
|
|
11
11
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|