@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.
@@ -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;AAYvC,eAAO,MAAM,GAAG,GAAU,KAAK,GAAG,EAAE,KAAK,QAAQ,kBAIhD,CAAA;AAED,eAAO,MAAM,IAAI,GAAU,KAAK,GAAG,EAAE,KAAK,QAAQ,kBAyBjD,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 path from "node:path";
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 uploadDir = getUploadDir(req);
17
- const upload = createUpload(uploadDir);
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, comment_id: req.body?.comment_id || null,
33
- filename: req.file.filename, original_name: req.file.originalname,
34
- mime_type: req.file.mimetype, size: req.file.size,
35
- url: `/uploads/issue-attachments/${req.file.filename}`,
36
- uploader_id: req.user?.id ?? "system", workspace_id: issue.workspace_id,
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":"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"}
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;AAcvC,eAAO,MAAM,IAAI,GAAU,KAAK,GAAG,EAAE,KAAK,QAAQ,kBAgCjD,CAAA;AAED,eAAO,MAAM,MAAM,GAAU,KAAK,GAAG,EAAE,KAAK,QAAQ,kBAkBnD,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 { createUpload } from "../../../../../utils/upload.js";
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 uploadDir = getUploadDir(req);
15
- const upload = createUpload(uploadDir);
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
- // Delete old logo file if present
30
- if (existing.logo_url) {
31
- const rootDir = req.scope.resolve("config")?.rootDir ?? process.cwd();
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
- const rootDir = req.scope.resolve("config")?.rootDir ?? process.cwd();
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":"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"}
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"}
@@ -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;AA0BvD,wBAA8B,QAAQ,CAAC,GAAG,EAAE,yBAAyB,GAAG,OAAO,CAAC,IAAI,CAAC,CAIpF"}
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
@@ -28,6 +28,7 @@ const CORE_MODULES = [
28
28
  "@meridianjs/team-member",
29
29
  "@meridianjs/project-member",
30
30
  "@meridianjs/app-role",
31
+ "@meridianjs/org-calendar",
31
32
  ];
32
33
  export default async function register(ctx) {
33
34
  for (const resolve of CORE_MODULES) {
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;CACvB,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"}
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"}
@@ -1,8 +1,23 @@
1
1
  import multer from "multer";
2
2
  /**
3
- * Multer instance for issue attachment uploads.
4
- * Files are stored in <projectRoot>/uploads/issue-attachments/.
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;AAI3B;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,iBAa7C"}
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"}
@@ -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 issue attachment uploads.
6
- * Files are stored in <projectRoot>/uploads/issue-attachments/.
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
@@ -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;AAExC;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,SAAiB;IAC5C,MAAM,OAAO,GAAG,MAAM,CAAC,WAAW,CAAC;QACjC,WAAW,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,CAAC;QACrD,QAAQ,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE;YAC3B,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA;YAC3C,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,YAAY,EAAE,GAAG,CAAC;iBAC/C,OAAO,CAAC,kBAAkB,EAAE,GAAG,CAAC;iBAChC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;YACf,EAAE,CAAC,IAAI,EAAE,GAAG,UAAU,EAAE,IAAI,IAAI,GAAG,GAAG,EAAE,CAAC,CAAA;QAC3C,CAAC;KACF,CAAC,CAAA;IAEF,OAAO,MAAM,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,EAAE,GAAG,IAAI,GAAG,IAAI,EAAE,EAAE,CAAC,CAAA;AACpE,CAAC"}
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.16",
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
  },