@meridianjs/meridian 0.1.16 → 0.1.18
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/api/admin/issues/[id]/attachments/route.d.ts.map +1 -1
- package/dist/api/admin/issues/[id]/attachments/route.js +12 -20
- package/dist/api/admin/issues/[id]/attachments/route.js.map +1 -1
- package/dist/api/admin/org/calendar/route.d.ts +4 -0
- package/dist/api/admin/org/calendar/route.d.ts.map +1 -0
- package/dist/api/admin/org/calendar/route.js +37 -0
- package/dist/api/admin/org/calendar/route.js.map +1 -0
- package/dist/api/admin/org/holidays/[holidayId]/route.d.ts +4 -0
- package/dist/api/admin/org/holidays/[holidayId]/route.d.ts.map +1 -0
- package/dist/api/admin/org/holidays/[holidayId]/route.js +34 -0
- package/dist/api/admin/org/holidays/[holidayId]/route.js.map +1 -0
- package/dist/api/admin/org/holidays/route.d.ts +4 -0
- package/dist/api/admin/org/holidays/route.d.ts.map +1 -0
- package/dist/api/admin/org/holidays/route.js +38 -0
- package/dist/api/admin/org/holidays/route.js.map +1 -0
- package/dist/api/admin/workspaces/[id]/logo/route.d.ts.map +1 -1
- package/dist/api/admin/workspaces/[id]/logo/route.js +8 -29
- package/dist/api/admin/workspaces/[id]/logo/route.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/utils/upload.d.ts +18 -3
- package/dist/utils/upload.d.ts.map +1 -1
- package/dist/utils/upload.js +66 -3
- package/dist/utils/upload.js.map +1 -1
- package/package.json +2 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../src/api/admin/issues/[id]/attachments/route.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../src/api/admin/issues/[id]/attachments/route.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAGvC,eAAO,MAAM,GAAG,GAAU,KAAK,GAAG,EAAE,KAAK,QAAQ,kBAIhD,CAAA;AAED,eAAO,MAAM,IAAI,GAAU,KAAK,GAAG,EAAE,KAAK,QAAQ,kBAuBjD,CAAA"}
|
|
@@ -1,24 +1,12 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { mkdirSync } from "node:fs";
|
|
3
|
-
import { createUpload } from "../../../../../utils/upload.js";
|
|
4
|
-
function getUploadDir(req) {
|
|
5
|
-
const rootDir = req.scope.resolve("config")?.rootDir ?? process.cwd();
|
|
6
|
-
const uploadDir = path.join(rootDir, "uploads", "issue-attachments");
|
|
7
|
-
mkdirSync(uploadDir, { recursive: true });
|
|
8
|
-
return uploadDir;
|
|
9
|
-
}
|
|
1
|
+
import { processUpload } from "../../../../../utils/upload.js";
|
|
10
2
|
export const GET = async (req, res) => {
|
|
11
3
|
const issueService = req.scope.resolve("issueModuleService");
|
|
12
4
|
const attachments = await issueService.listAttachmentsByIssue(req.params.id);
|
|
13
5
|
res.json({ attachments });
|
|
14
6
|
};
|
|
15
7
|
export const POST = async (req, res) => {
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
await new Promise((resolve, reject) => {
|
|
19
|
-
upload.single("file")(req, res, (err) => err ? reject(err) : resolve());
|
|
20
|
-
});
|
|
21
|
-
if (!req.file) {
|
|
8
|
+
const upload = await processUpload(req, res, "file", "issue-attachments");
|
|
9
|
+
if (!upload) {
|
|
22
10
|
res.status(400).json({ error: { message: "No file uploaded. Use multipart/form-data with field name 'file'." } });
|
|
23
11
|
return;
|
|
24
12
|
}
|
|
@@ -29,11 +17,15 @@ export const POST = async (req, res) => {
|
|
|
29
17
|
return;
|
|
30
18
|
}
|
|
31
19
|
const attachment = await issueService.createAttachment({
|
|
32
|
-
issue_id: req.params.id,
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
20
|
+
issue_id: req.params.id,
|
|
21
|
+
comment_id: req.body?.comment_id || null,
|
|
22
|
+
filename: upload.filename,
|
|
23
|
+
original_name: upload.originalName,
|
|
24
|
+
mime_type: upload.mimetype,
|
|
25
|
+
size: upload.size,
|
|
26
|
+
url: upload.url,
|
|
27
|
+
uploader_id: req.user?.id ?? "system",
|
|
28
|
+
workspace_id: issue.workspace_id,
|
|
37
29
|
});
|
|
38
30
|
res.status(201).json({ attachment });
|
|
39
31
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route.js","sourceRoot":"","sources":["../../../../../../src/api/admin/issues/[id]/attachments/route.ts"],"names":[],"mappings":"AACA,OAAO,
|
|
1
|
+
{"version":3,"file":"route.js","sourceRoot":"","sources":["../../../../../../src/api/admin/issues/[id]/attachments/route.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAA;AAE9D,MAAM,CAAC,MAAM,GAAG,GAAG,KAAK,EAAE,GAAQ,EAAE,GAAa,EAAE,EAAE;IACnD,MAAM,YAAY,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,oBAAoB,CAAQ,CAAA;IACnE,MAAM,WAAW,GAAG,MAAM,YAAY,CAAC,sBAAsB,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;IAC5E,GAAG,CAAC,IAAI,CAAC,EAAE,WAAW,EAAE,CAAC,CAAA;AAC3B,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,IAAI,GAAG,KAAK,EAAE,GAAQ,EAAE,GAAa,EAAE,EAAE;IACpD,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,mBAAmB,CAAC,CAAA;IACzE,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,mEAAmE,EAAE,EAAE,CAAC,CAAA;QACjH,OAAM;IACR,CAAC;IAED,MAAM,YAAY,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,oBAAoB,CAAQ,CAAA;IACnE,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAA;IAC/E,IAAI,CAAC,KAAK,EAAE,CAAC;QAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,kBAAkB,EAAE,EAAE,CAAC,CAAC;QAAC,OAAM;IAAC,CAAC;IAExF,MAAM,UAAU,GAAG,MAAM,YAAY,CAAC,gBAAgB,CAAC;QACrD,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,EAAE;QACvB,UAAU,EAAE,GAAG,CAAC,IAAI,EAAE,UAAU,IAAI,IAAI;QACxC,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,aAAa,EAAE,MAAM,CAAC,YAAY;QAClC,SAAS,EAAE,MAAM,CAAC,QAAQ;QAC1B,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,GAAG,EAAE,MAAM,CAAC,GAAG;QACf,WAAW,EAAE,GAAG,CAAC,IAAI,EAAE,EAAE,IAAI,QAAQ;QACrC,YAAY,EAAE,KAAK,CAAC,YAAY;KACjC,CAAC,CAAA;IACF,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,CAAC,CAAA;AACtC,CAAC,CAAA"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { Response, NextFunction } from "express";
|
|
2
|
+
export declare const GET: (req: any, res: Response, next: NextFunction) => Promise<void>;
|
|
3
|
+
export declare const PUT: (req: any, res: Response, next: NextFunction) => Promise<void>;
|
|
4
|
+
//# sourceMappingURL=route.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../src/api/admin/org/calendar/route.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAGrD,eAAO,MAAM,GAAG,GAAU,KAAK,GAAG,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,kBAQpE,CAAA;AAED,eAAO,MAAM,GAAG,GAAU,KAAK,GAAG,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,kBAyBpE,CAAA"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { requireRoles } from "@meridianjs/auth";
|
|
2
|
+
export const GET = async (req, res, next) => {
|
|
3
|
+
try {
|
|
4
|
+
const service = req.scope.resolve("orgCalendarModuleService");
|
|
5
|
+
const calendar = await service.getOrCreateCalendar();
|
|
6
|
+
res.json({ working_days: calendar.working_days, timezone: calendar.timezone });
|
|
7
|
+
}
|
|
8
|
+
catch (err) {
|
|
9
|
+
next(err);
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
export const PUT = async (req, res, next) => {
|
|
13
|
+
requireRoles("super-admin", "admin")(req, res, async () => {
|
|
14
|
+
try {
|
|
15
|
+
const service = req.scope.resolve("orgCalendarModuleService");
|
|
16
|
+
const { working_days, timezone } = req.body;
|
|
17
|
+
const calendar = await service.getOrCreateCalendar();
|
|
18
|
+
const updates = {};
|
|
19
|
+
if (working_days && typeof working_days === "object") {
|
|
20
|
+
const days = ["mon", "tue", "wed", "thu", "fri", "sat", "sun"];
|
|
21
|
+
const normalized = {};
|
|
22
|
+
for (const day of days) {
|
|
23
|
+
normalized[day] = working_days[day] === true;
|
|
24
|
+
}
|
|
25
|
+
updates.working_days = normalized;
|
|
26
|
+
}
|
|
27
|
+
if (timezone !== undefined)
|
|
28
|
+
updates.timezone = timezone ?? null;
|
|
29
|
+
const updated = await service.updateOrgCalendar(calendar.id, updates);
|
|
30
|
+
res.json({ working_days: updated.working_days, timezone: updated.timezone });
|
|
31
|
+
}
|
|
32
|
+
catch (err) {
|
|
33
|
+
next(err);
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
};
|
|
37
|
+
//# sourceMappingURL=route.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"route.js","sourceRoot":"","sources":["../../../../../src/api/admin/org/calendar/route.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAE/C,MAAM,CAAC,MAAM,GAAG,GAAG,KAAK,EAAE,GAAQ,EAAE,GAAa,EAAE,IAAkB,EAAE,EAAE;IACvE,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,0BAA0B,CAAQ,CAAA;QACpE,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,mBAAmB,EAAE,CAAA;QACpD,GAAG,CAAC,IAAI,CAAC,EAAE,YAAY,EAAE,QAAQ,CAAC,YAAY,EAAE,QAAQ,EAAE,QAAQ,CAAC,QAAQ,EAAE,CAAC,CAAA;IAChF,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,GAAG,CAAC,CAAA;IACX,CAAC;AACH,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,GAAG,GAAG,KAAK,EAAE,GAAQ,EAAE,GAAa,EAAE,IAAkB,EAAE,EAAE;IACvE,YAAY,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,IAAI,EAAE;QACxD,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,0BAA0B,CAAQ,CAAA;YACpE,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,GAAG,GAAG,CAAC,IAAI,CAAA;YAE3C,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,mBAAmB,EAAE,CAAA;YAEpD,MAAM,OAAO,GAA4B,EAAE,CAAA;YAC3C,IAAI,YAAY,IAAI,OAAO,YAAY,KAAK,QAAQ,EAAE,CAAC;gBACrD,MAAM,IAAI,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAA;gBAC9D,MAAM,UAAU,GAA4B,EAAE,CAAA;gBAC9C,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;oBACvB,UAAU,CAAC,GAAG,CAAC,GAAG,YAAY,CAAC,GAAG,CAAC,KAAK,IAAI,CAAA;gBAC9C,CAAC;gBACD,OAAO,CAAC,YAAY,GAAG,UAAU,CAAA;YACnC,CAAC;YACD,IAAI,QAAQ,KAAK,SAAS;gBAAE,OAAO,CAAC,QAAQ,GAAG,QAAQ,IAAI,IAAI,CAAA;YAE/D,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,iBAAiB,CAAC,QAAQ,CAAC,EAAE,EAAE,OAAO,CAAC,CAAA;YACrE,GAAG,CAAC,IAAI,CAAC,EAAE,YAAY,EAAE,OAAO,CAAC,YAAY,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAA;QAC9E,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,GAAG,CAAC,CAAA;QACX,CAAC;IACH,CAAC,CAAC,CAAA;AACJ,CAAC,CAAA"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { Response, NextFunction } from "express";
|
|
2
|
+
export declare const PUT: (req: any, res: Response, next: NextFunction) => Promise<void>;
|
|
3
|
+
export declare const DELETE: (req: any, res: Response, next: NextFunction) => Promise<void>;
|
|
4
|
+
//# sourceMappingURL=route.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../src/api/admin/org/holidays/[holidayId]/route.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAGrD,eAAO,MAAM,GAAG,GAAU,KAAK,GAAG,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,kBAgBpE,CAAA;AAED,eAAO,MAAM,MAAM,GAAU,KAAK,GAAG,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,kBAUvE,CAAA"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { requireRoles } from "@meridianjs/auth";
|
|
2
|
+
export const PUT = async (req, res, next) => {
|
|
3
|
+
requireRoles("super-admin", "admin")(req, res, async () => {
|
|
4
|
+
try {
|
|
5
|
+
const service = req.scope.resolve("orgCalendarModuleService");
|
|
6
|
+
const { name, date, recurring } = req.body;
|
|
7
|
+
const updates = {};
|
|
8
|
+
if (name !== undefined)
|
|
9
|
+
updates.name = name.trim();
|
|
10
|
+
if (date !== undefined)
|
|
11
|
+
updates.date = new Date(date);
|
|
12
|
+
if (recurring !== undefined)
|
|
13
|
+
updates.recurring = recurring === true;
|
|
14
|
+
const holiday = await service.updateOrgHoliday(req.params.holidayId, updates);
|
|
15
|
+
res.json({ holiday });
|
|
16
|
+
}
|
|
17
|
+
catch (err) {
|
|
18
|
+
next(err);
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
};
|
|
22
|
+
export const DELETE = async (req, res, next) => {
|
|
23
|
+
requireRoles("super-admin", "admin")(req, res, async () => {
|
|
24
|
+
try {
|
|
25
|
+
const service = req.scope.resolve("orgCalendarModuleService");
|
|
26
|
+
await service.deleteOrgHoliday(req.params.holidayId);
|
|
27
|
+
res.status(204).send();
|
|
28
|
+
}
|
|
29
|
+
catch (err) {
|
|
30
|
+
next(err);
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
};
|
|
34
|
+
//# sourceMappingURL=route.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"route.js","sourceRoot":"","sources":["../../../../../../src/api/admin/org/holidays/[holidayId]/route.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAE/C,MAAM,CAAC,MAAM,GAAG,GAAG,KAAK,EAAE,GAAQ,EAAE,GAAa,EAAE,IAAkB,EAAE,EAAE;IACvE,YAAY,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,IAAI,EAAE;QACxD,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,0BAA0B,CAAQ,CAAA;YACpE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,GAAG,CAAC,IAAI,CAAA;YAC1C,MAAM,OAAO,GAA4B,EAAE,CAAA;YAC3C,IAAI,IAAI,KAAK,SAAS;gBAAE,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,CAAA;YAClD,IAAI,IAAI,KAAK,SAAS;gBAAE,OAAO,CAAC,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,CAAA;YACrD,IAAI,SAAS,KAAK,SAAS;gBAAE,OAAO,CAAC,SAAS,GAAG,SAAS,KAAK,IAAI,CAAA;YAEnE,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,gBAAgB,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,CAAA;YAC7E,GAAG,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC,CAAA;QACvB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,GAAG,CAAC,CAAA;QACX,CAAC;IACH,CAAC,CAAC,CAAA;AACJ,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,MAAM,GAAG,KAAK,EAAE,GAAQ,EAAE,GAAa,EAAE,IAAkB,EAAE,EAAE;IAC1E,YAAY,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,IAAI,EAAE;QACxD,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,0BAA0B,CAAQ,CAAA;YACpE,MAAM,OAAO,CAAC,gBAAgB,CAAC,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;YACpD,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAA;QACxB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,GAAG,CAAC,CAAA;QACX,CAAC;IACH,CAAC,CAAC,CAAA;AACJ,CAAC,CAAA"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { Response, NextFunction } from "express";
|
|
2
|
+
export declare const GET: (req: any, res: Response, next: NextFunction) => Promise<void>;
|
|
3
|
+
export declare const POST: (req: any, res: Response, next: NextFunction) => Promise<void>;
|
|
4
|
+
//# sourceMappingURL=route.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../src/api/admin/org/holidays/route.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAGrD,eAAO,MAAM,GAAG,GAAU,KAAK,GAAG,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,kBASpE,CAAA;AAED,eAAO,MAAM,IAAI,GAAU,KAAK,GAAG,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,kBAyBrE,CAAA"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { requireRoles } from "@meridianjs/auth";
|
|
2
|
+
export const GET = async (req, res, next) => {
|
|
3
|
+
try {
|
|
4
|
+
const service = req.scope.resolve("orgCalendarModuleService");
|
|
5
|
+
const year = req.query.year ? parseInt(req.query.year, 10) : new Date().getFullYear();
|
|
6
|
+
const holidays = await service.listHolidaysByYear(year);
|
|
7
|
+
res.json({ holidays, count: holidays.length });
|
|
8
|
+
}
|
|
9
|
+
catch (err) {
|
|
10
|
+
next(err);
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
export const POST = async (req, res, next) => {
|
|
14
|
+
requireRoles("super-admin", "admin")(req, res, async () => {
|
|
15
|
+
try {
|
|
16
|
+
const service = req.scope.resolve("orgCalendarModuleService");
|
|
17
|
+
const { name, date, recurring } = req.body;
|
|
18
|
+
if (!name || typeof name !== "string" || name.trim().length === 0) {
|
|
19
|
+
res.status(400).json({ error: { message: "name is required" } });
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
if (!date || typeof date !== "string") {
|
|
23
|
+
res.status(400).json({ error: { message: "date is required (YYYY-MM-DD)" } });
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const holiday = await service.createOrgHoliday({
|
|
27
|
+
name: name.trim(),
|
|
28
|
+
date: new Date(date),
|
|
29
|
+
recurring: recurring === true,
|
|
30
|
+
});
|
|
31
|
+
res.status(201).json({ holiday });
|
|
32
|
+
}
|
|
33
|
+
catch (err) {
|
|
34
|
+
next(err);
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
};
|
|
38
|
+
//# sourceMappingURL=route.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"route.js","sourceRoot":"","sources":["../../../../../src/api/admin/org/holidays/route.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAE/C,MAAM,CAAC,MAAM,GAAG,GAAG,KAAK,EAAE,GAAQ,EAAE,GAAa,EAAE,IAAkB,EAAE,EAAE;IACvE,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,0BAA0B,CAAQ,CAAA;QACpE,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC,IAAc,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;QAC/F,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAA;QACvD,GAAG,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAA;IAChD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,GAAG,CAAC,CAAA;IACX,CAAC;AACH,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,IAAI,GAAG,KAAK,EAAE,GAAQ,EAAE,GAAa,EAAE,IAAkB,EAAE,EAAE;IACxE,YAAY,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,IAAI,EAAE;QACxD,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,0BAA0B,CAAQ,CAAA;YACpE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,GAAG,CAAC,IAAI,CAAA;YAE1C,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAClE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,kBAAkB,EAAE,EAAE,CAAC,CAAA;gBAChE,OAAM;YACR,CAAC;YACD,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACtC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,+BAA+B,EAAE,EAAE,CAAC,CAAA;gBAC7E,OAAM;YACR,CAAC;YAED,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,gBAAgB,CAAC;gBAC7C,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE;gBACjB,IAAI,EAAE,IAAI,IAAI,CAAC,IAAI,CAAC;gBACpB,SAAS,EAAE,SAAS,KAAK,IAAI;aAC9B,CAAC,CAAA;YACF,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,CAAC,CAAA;QACnC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAI,CAAC,GAAG,CAAC,CAAA;QACX,CAAC;IACH,CAAC,CAAC,CAAA;AACJ,CAAC,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../src/api/admin/workspaces/[id]/logo/route.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../src/api/admin/workspaces/[id]/logo/route.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAIvC,eAAO,MAAM,IAAI,GAAU,KAAK,GAAG,EAAE,KAAK,QAAQ,kBAoBjD,CAAA;AAED,eAAO,MAAM,MAAM,GAAU,KAAK,GAAG,EAAE,KAAK,QAAQ,kBAanD,CAAA"}
|
|
@@ -1,22 +1,9 @@
|
|
|
1
|
-
import path from "node:path";
|
|
2
|
-
import fs from "node:fs";
|
|
3
|
-
import { mkdirSync } from "node:fs";
|
|
4
1
|
import { requirePermission } from "@meridianjs/auth";
|
|
5
|
-
import {
|
|
6
|
-
function getUploadDir(req) {
|
|
7
|
-
const rootDir = req.scope.resolve("config")?.rootDir ?? process.cwd();
|
|
8
|
-
const uploadDir = path.join(rootDir, "uploads", "workspace-logos");
|
|
9
|
-
mkdirSync(uploadDir, { recursive: true });
|
|
10
|
-
return uploadDir;
|
|
11
|
-
}
|
|
2
|
+
import { processUpload, deleteUpload } from "../../../../../utils/upload.js";
|
|
12
3
|
export const POST = async (req, res) => {
|
|
13
4
|
requirePermission("workspace:update")(req, res, async () => {
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
await new Promise((resolve, reject) => {
|
|
17
|
-
upload.single("logo")(req, res, (err) => (err ? reject(err) : resolve()));
|
|
18
|
-
});
|
|
19
|
-
if (!req.file) {
|
|
5
|
+
const upload = await processUpload(req, res, "logo", "workspace-logos");
|
|
6
|
+
if (!upload) {
|
|
20
7
|
res.status(400).json({ error: { message: "No file uploaded. Use multipart/form-data with field name 'logo'." } });
|
|
21
8
|
return;
|
|
22
9
|
}
|
|
@@ -26,14 +13,9 @@ export const POST = async (req, res) => {
|
|
|
26
13
|
res.status(404).json({ error: { message: "Workspace not found." } });
|
|
27
14
|
return;
|
|
28
15
|
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
const oldFilePath = path.join(rootDir, existing.logo_url);
|
|
33
|
-
fs.unlink(oldFilePath, () => { });
|
|
34
|
-
}
|
|
35
|
-
const logo_url = `/uploads/workspace-logos/${req.file.filename}`;
|
|
36
|
-
const workspace = await workspaceService.updateWorkspace(req.params.id, { logo_url });
|
|
16
|
+
if (existing.logo_url)
|
|
17
|
+
await deleteUpload(req, existing.logo_url);
|
|
18
|
+
const workspace = await workspaceService.updateWorkspace(req.params.id, { logo_url: upload.url });
|
|
37
19
|
res.json({ workspace });
|
|
38
20
|
});
|
|
39
21
|
};
|
|
@@ -45,11 +27,8 @@ export const DELETE = async (req, res) => {
|
|
|
45
27
|
res.status(404).json({ error: { message: "Workspace not found." } });
|
|
46
28
|
return;
|
|
47
29
|
}
|
|
48
|
-
if (existing.logo_url)
|
|
49
|
-
|
|
50
|
-
const filePath = path.join(rootDir, existing.logo_url);
|
|
51
|
-
fs.unlink(filePath, () => { });
|
|
52
|
-
}
|
|
30
|
+
if (existing.logo_url)
|
|
31
|
+
await deleteUpload(req, existing.logo_url);
|
|
53
32
|
const workspace = await workspaceService.updateWorkspace(req.params.id, { logo_url: null });
|
|
54
33
|
res.json({ workspace });
|
|
55
34
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route.js","sourceRoot":"","sources":["../../../../../../src/api/admin/workspaces/[id]/logo/route.ts"],"names":[],"mappings":"AACA,OAAO,
|
|
1
|
+
{"version":3,"file":"route.js","sourceRoot":"","sources":["../../../../../../src/api/admin/workspaces/[id]/logo/route.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AACpD,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAA;AAE5E,MAAM,CAAC,MAAM,IAAI,GAAG,KAAK,EAAE,GAAQ,EAAE,GAAa,EAAE,EAAE;IACpD,iBAAiB,CAAC,kBAAkB,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,IAAI,EAAE;QACzD,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,iBAAiB,CAAC,CAAA;QACvE,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,mEAAmE,EAAE,EAAE,CAAC,CAAA;YACjH,OAAM;QACR,CAAC;QAED,MAAM,gBAAgB,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,wBAAwB,CAAQ,CAAA;QAC3E,MAAM,QAAQ,GAAG,MAAM,gBAAgB,CAAC,iBAAiB,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAA;QAC1F,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,sBAAsB,EAAE,EAAE,CAAC,CAAA;YACpE,OAAM;QACR,CAAC;QAED,IAAI,QAAQ,CAAC,QAAQ;YAAE,MAAM,YAAY,CAAC,GAAG,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAA;QAEjE,MAAM,SAAS,GAAG,MAAM,gBAAgB,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,MAAM,CAAC,GAAG,EAAE,CAAC,CAAA;QACjG,GAAG,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,CAAC,CAAA;IACzB,CAAC,CAAC,CAAA;AACJ,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,MAAM,GAAG,KAAK,EAAE,GAAQ,EAAE,GAAa,EAAE,EAAE;IACtD,iBAAiB,CAAC,kBAAkB,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,IAAI,EAAE;QACzD,MAAM,gBAAgB,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,wBAAwB,CAAQ,CAAA;QAC3E,MAAM,QAAQ,GAAG,MAAM,gBAAgB,CAAC,iBAAiB,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAA;QAC1F,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,sBAAsB,EAAE,EAAE,CAAC,CAAA;YACpE,OAAM;QACR,CAAC;QAED,IAAI,QAAQ,CAAC,QAAQ;YAAE,MAAM,YAAY,CAAC,GAAG,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAA;QACjE,MAAM,SAAS,GAAG,MAAM,gBAAgB,CAAC,eAAe,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAA;QAC3F,GAAG,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,CAAC,CAAA;IACzB,CAAC,CAAC,CAAA;AACJ,CAAC,CAAA"}
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAA;AAIlE;;;GAGG;AACH,eAAO,MAAM,UAAU,QAAgC,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAA;AAIlE;;;GAGG;AACH,eAAO,MAAM,UAAU,QAAgC,CAAA;AA2BvD,wBAA8B,QAAQ,CAAC,GAAG,EAAE,yBAAyB,GAAG,OAAO,CAAC,IAAI,CAAC,CAIpF"}
|
package/dist/index.js
CHANGED
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AACxC,OAAO,IAAI,MAAM,WAAW,CAAA;AAG5B,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;AAE9D;;;GAGG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,CAAA;AAEvD;;;;;;;GAOG;AACH,MAAM,YAAY,GAAG;IACnB,kBAAkB;IAClB,uBAAuB;IACvB,kBAAkB;IAClB,qBAAqB;IACrB,mBAAmB;IACnB,oBAAoB;IACpB,sBAAsB;IACtB,0BAA0B;IAC1B,wBAAwB;IACxB,8BAA8B;IAC9B,yBAAyB;IACzB,4BAA4B;IAC5B,sBAAsB;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AACxC,OAAO,IAAI,MAAM,WAAW,CAAA;AAG5B,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;AAE9D;;;GAGG;AACH,MAAM,CAAC,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,CAAC,CAAA;AAEvD;;;;;;;GAOG;AACH,MAAM,YAAY,GAAG;IACnB,kBAAkB;IAClB,uBAAuB;IACvB,kBAAkB;IAClB,qBAAqB;IACrB,mBAAmB;IACnB,oBAAoB;IACpB,sBAAsB;IACtB,0BAA0B;IAC1B,wBAAwB;IACxB,8BAA8B;IAC9B,yBAAyB;IACzB,4BAA4B;IAC5B,sBAAsB;IACtB,0BAA0B;CAC3B,CAAA;AAED,MAAM,CAAC,OAAO,CAAC,KAAK,UAAU,QAAQ,CAAC,GAA8B;IACnE,KAAK,MAAM,OAAO,IAAI,YAAY,EAAE,CAAC;QACnC,MAAM,GAAG,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,CAAC,CAAA;IAClC,CAAC;AACH,CAAC"}
|
package/dist/utils/upload.d.ts
CHANGED
|
@@ -1,8 +1,23 @@
|
|
|
1
1
|
import multer from "multer";
|
|
2
2
|
/**
|
|
3
|
-
* Multer instance for
|
|
4
|
-
* Files are stored in
|
|
5
|
-
* The upload directory must exist before the server starts.
|
|
3
|
+
* Multer instance for disk-based file uploads.
|
|
4
|
+
* Files are stored in the given uploadDir.
|
|
6
5
|
*/
|
|
7
6
|
export declare function createUpload(uploadDir: string): multer.Multer;
|
|
7
|
+
export interface UploadResult {
|
|
8
|
+
url: string;
|
|
9
|
+
filename: string;
|
|
10
|
+
originalName: string;
|
|
11
|
+
mimetype: string;
|
|
12
|
+
size: number;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Handles file upload via S3 (if storageProvider is registered) or local disk.
|
|
16
|
+
* Returns null if no file was included in the request.
|
|
17
|
+
*/
|
|
18
|
+
export declare function processUpload(req: any, res: any, fieldName: string, subDir: string): Promise<UploadResult | null>;
|
|
19
|
+
/**
|
|
20
|
+
* Deletes a file by URL/key via S3 or local disk. Fire-and-forget safe (swallows errors).
|
|
21
|
+
*/
|
|
22
|
+
export declare function deleteUpload(req: any, urlOrKey: string): Promise<void>;
|
|
8
23
|
//# sourceMappingURL=upload.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../../src/utils/upload.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAA;
|
|
1
|
+
{"version":3,"file":"upload.d.ts","sourceRoot":"","sources":["../../src/utils/upload.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAA;AAO3B;;;GAGG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,iBAa7C;AAED,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAA;IACX,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,EAAE,MAAM,CAAA;IACpB,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,MAAM,CAAA;CACb;AAED;;;GAGG;AACH,wBAAsB,aAAa,CACjC,GAAG,EAAE,GAAG,EACR,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAuC9B;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAc5E"}
|
package/dist/utils/upload.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import multer from "multer";
|
|
2
2
|
import path from "node:path";
|
|
3
|
+
import fs from "node:fs";
|
|
4
|
+
import { mkdirSync } from "node:fs";
|
|
3
5
|
import { randomUUID } from "node:crypto";
|
|
4
6
|
/**
|
|
5
|
-
* Multer instance for
|
|
6
|
-
* Files are stored in
|
|
7
|
-
* The upload directory must exist before the server starts.
|
|
7
|
+
* Multer instance for disk-based file uploads.
|
|
8
|
+
* Files are stored in the given uploadDir.
|
|
8
9
|
*/
|
|
9
10
|
export function createUpload(uploadDir) {
|
|
10
11
|
const storage = multer.diskStorage({
|
|
@@ -19,4 +20,66 @@ export function createUpload(uploadDir) {
|
|
|
19
20
|
});
|
|
20
21
|
return multer({ storage, limits: { fileSize: 50 * 1024 * 1024 } });
|
|
21
22
|
}
|
|
23
|
+
/**
|
|
24
|
+
* Handles file upload via S3 (if storageProvider is registered) or local disk.
|
|
25
|
+
* Returns null if no file was included in the request.
|
|
26
|
+
*/
|
|
27
|
+
export async function processUpload(req, res, fieldName, subDir) {
|
|
28
|
+
let storageProvider = null;
|
|
29
|
+
try {
|
|
30
|
+
storageProvider = req.scope.resolve("storageProvider");
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
// storageProvider not registered — fall back to local disk
|
|
34
|
+
}
|
|
35
|
+
if (storageProvider) {
|
|
36
|
+
const upload = multer({ storage: multer.memoryStorage(), limits: { fileSize: 50 * 1024 * 1024 } });
|
|
37
|
+
await new Promise((resolve, reject) => upload.single(fieldName)(req, res, (err) => (err ? reject(err) : resolve())));
|
|
38
|
+
if (!req.file)
|
|
39
|
+
return null;
|
|
40
|
+
const { url, key } = await storageProvider.upload(req.file, subDir);
|
|
41
|
+
return {
|
|
42
|
+
url,
|
|
43
|
+
filename: key,
|
|
44
|
+
originalName: req.file.originalname,
|
|
45
|
+
mimetype: req.file.mimetype,
|
|
46
|
+
size: req.file.size,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
const rootDir = req.scope.resolve("config")?.rootDir ?? process.cwd();
|
|
51
|
+
const uploadDir = path.join(rootDir, "uploads", subDir);
|
|
52
|
+
mkdirSync(uploadDir, { recursive: true });
|
|
53
|
+
const upload = createUpload(uploadDir);
|
|
54
|
+
await new Promise((resolve, reject) => upload.single(fieldName)(req, res, (err) => (err ? reject(err) : resolve())));
|
|
55
|
+
if (!req.file)
|
|
56
|
+
return null;
|
|
57
|
+
return {
|
|
58
|
+
url: `/uploads/${subDir}/${req.file.filename}`,
|
|
59
|
+
filename: req.file.filename,
|
|
60
|
+
originalName: req.file.originalname,
|
|
61
|
+
mimetype: req.file.mimetype,
|
|
62
|
+
size: req.file.size,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Deletes a file by URL/key via S3 or local disk. Fire-and-forget safe (swallows errors).
|
|
68
|
+
*/
|
|
69
|
+
export async function deleteUpload(req, urlOrKey) {
|
|
70
|
+
let storageProvider = null;
|
|
71
|
+
try {
|
|
72
|
+
storageProvider = req.scope.resolve("storageProvider");
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
// storageProvider not registered — fall back to local disk
|
|
76
|
+
}
|
|
77
|
+
if (storageProvider) {
|
|
78
|
+
await storageProvider.delete(urlOrKey).catch(() => { });
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
const rootDir = req.scope.resolve("config")?.rootDir ?? process.cwd();
|
|
82
|
+
fs.unlink(path.join(rootDir, urlOrKey), () => { });
|
|
83
|
+
}
|
|
84
|
+
}
|
|
22
85
|
//# sourceMappingURL=upload.js.map
|
package/dist/utils/upload.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"upload.js","sourceRoot":"","sources":["../../src/utils/upload.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAA;AAC3B,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"upload.js","sourceRoot":"","sources":["../../src/utils/upload.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@meridianjs/meridian",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.18",
|
|
4
4
|
"description": "Default API routes, workflows, links, and subscribers for Meridian applications",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.js",
|
|
@@ -37,6 +37,7 @@
|
|
|
37
37
|
"@meridianjs/team-member": "^0.1.0",
|
|
38
38
|
"@meridianjs/project-member": "^0.1.0",
|
|
39
39
|
"@meridianjs/app-role": "^0.1.0",
|
|
40
|
+
"@meridianjs/org-calendar": "^0.1.0",
|
|
40
41
|
"multer": "^1.4.5-lts.1",
|
|
41
42
|
"zod": "^3.24.0"
|
|
42
43
|
},
|