@arch-cadre/blog-module 1.0.13 → 1.0.15

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.
Files changed (56) hide show
  1. package/dist/actions/index.cjs +158 -0
  2. package/dist/actions/index.d.ts +4 -37
  3. package/dist/actions/index.mjs +121 -0
  4. package/dist/components/BlogStatsWidget.cjs +45 -0
  5. package/dist/components/BlogStatsWidget.d.ts +2 -1
  6. package/dist/components/BlogStatsWidget.mjs +13 -0
  7. package/dist/components/RecentCommentsWidget.cjs +47 -0
  8. package/dist/components/RecentCommentsWidget.d.ts +2 -1
  9. package/dist/components/RecentCommentsWidget.mjs +28 -0
  10. package/dist/components/RecentPostsWidget.cjs +47 -0
  11. package/dist/components/RecentPostsWidget.d.ts +2 -1
  12. package/dist/components/RecentPostsWidget.mjs +28 -0
  13. package/dist/components/ui/button.cjs +54 -0
  14. package/dist/components/ui/button.mjs +47 -0
  15. package/dist/components/ui/card.cjs +47 -0
  16. package/dist/components/ui/card.mjs +36 -0
  17. package/dist/components/ui/input.cjs +24 -0
  18. package/dist/components/ui/input.mjs +17 -0
  19. package/dist/components/ui/table.cjs +68 -0
  20. package/dist/components/ui/table.mjs +65 -0
  21. package/dist/components/ui/textarea.cjs +22 -0
  22. package/dist/components/ui/textarea.mjs +16 -0
  23. package/dist/index.cjs +100 -0
  24. package/dist/index.mjs +95 -0
  25. package/dist/intl.d.ts +7 -0
  26. package/dist/lib/utils.cjs +11 -0
  27. package/dist/lib/{utils.js → utils.mjs} +1 -1
  28. package/dist/lib/validation.cjs +16 -0
  29. package/dist/lib/validation.d.ts +2 -2
  30. package/dist/lib/validation.mjs +10 -0
  31. package/dist/navigation.cjs +23 -0
  32. package/dist/navigation.mjs +21 -0
  33. package/dist/routes.cjs +74 -0
  34. package/dist/routes.mjs +68 -0
  35. package/dist/schema.cjs +62 -0
  36. package/dist/schema.mjs +53 -0
  37. package/dist/styles/globals.css +1 -0
  38. package/dist/ui/views.cjs +448 -0
  39. package/dist/ui/views.d.ts +6 -5
  40. package/dist/ui/views.mjs +232 -0
  41. package/package.json +14 -10
  42. package/dist/actions/index.js +0 -149
  43. package/dist/components/BlogStatsWidget.js +0 -17
  44. package/dist/components/RecentCommentsWidget.js +0 -24
  45. package/dist/components/RecentPostsWidget.js +0 -24
  46. package/dist/components/ui/button.js +0 -33
  47. package/dist/components/ui/card.js +0 -12
  48. package/dist/components/ui/input.js +0 -8
  49. package/dist/components/ui/table.js +0 -16
  50. package/dist/components/ui/textarea.js +0 -8
  51. package/dist/index.js +0 -98
  52. package/dist/lib/validation.js +0 -11
  53. package/dist/navigation.js +0 -21
  54. package/dist/routes.js +0 -55
  55. package/dist/schema.js +0 -60
  56. package/dist/ui/views.js +0 -119
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.CardTitle = exports.CardHeader = exports.CardContent = exports.Card = void 0;
7
+ var React = _interopRequireWildcard(require("react"));
8
+ var _jsxRuntime = require("react/jsx-runtime");
9
+ var _utils = require("../../lib/utils.cjs");
10
+ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
11
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
12
+ const Card = exports.Card = React.forwardRef(({
13
+ className,
14
+ ...props
15
+ }, ref) => (0, _jsxRuntime.jsx)("div", {
16
+ ref: ref,
17
+ className: (0, _utils.cn)("rounded-xl border bg-card text-card-foreground shadow", className),
18
+ ...props
19
+ }));
20
+ Card.displayName = "Card";
21
+ const CardHeader = exports.CardHeader = React.forwardRef(({
22
+ className,
23
+ ...props
24
+ }, ref) => (0, _jsxRuntime.jsx)("div", {
25
+ ref: ref,
26
+ className: (0, _utils.cn)("flex flex-col space-y-1.5 p-6", className),
27
+ ...props
28
+ }));
29
+ CardHeader.displayName = "CardHeader";
30
+ const CardTitle = exports.CardTitle = React.forwardRef(({
31
+ className,
32
+ ...props
33
+ }, ref) => (0, _jsxRuntime.jsx)("div", {
34
+ ref: ref,
35
+ className: (0, _utils.cn)("font-semibold leading-none tracking-tight", className),
36
+ ...props
37
+ }));
38
+ CardTitle.displayName = "CardTitle";
39
+ const CardContent = exports.CardContent = React.forwardRef(({
40
+ className,
41
+ ...props
42
+ }, ref) => (0, _jsxRuntime.jsx)("div", {
43
+ ref: ref,
44
+ className: (0, _utils.cn)("p-6 pt-0", className),
45
+ ...props
46
+ }));
47
+ CardContent.displayName = "CardContent";
@@ -0,0 +1,36 @@
1
+ import * as React from "react";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { cn } from "../../lib/utils.mjs";
4
+
5
+ const Card = React.forwardRef(({ className, ...props }, ref) =>
6
+ _jsx("div", {
7
+ ref: ref,
8
+ className: cn(
9
+ "rounded-xl border bg-card text-card-foreground shadow",
10
+ className,
11
+ ),
12
+ ...props,
13
+ }),
14
+ );
15
+ Card.displayName = "Card";
16
+ const CardHeader = React.forwardRef(({ className, ...props }, ref) =>
17
+ _jsx("div", {
18
+ ref: ref,
19
+ className: cn("flex flex-col space-y-1.5 p-6", className),
20
+ ...props,
21
+ }),
22
+ );
23
+ CardHeader.displayName = "CardHeader";
24
+ const CardTitle = React.forwardRef(({ className, ...props }, ref) =>
25
+ _jsx("div", {
26
+ ref: ref,
27
+ className: cn("font-semibold leading-none tracking-tight", className),
28
+ ...props,
29
+ }),
30
+ );
31
+ CardTitle.displayName = "CardTitle";
32
+ const CardContent = React.forwardRef(({ className, ...props }, ref) =>
33
+ _jsx("div", { ref: ref, className: cn("p-6 pt-0", className), ...props }),
34
+ );
35
+ CardContent.displayName = "CardContent";
36
+ export { Card, CardHeader, CardTitle, CardContent };
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.Input = void 0;
7
+ var React = _interopRequireWildcard(require("react"));
8
+ var _jsxRuntime = require("react/jsx-runtime");
9
+ var _utils = require("../../lib/utils.cjs");
10
+ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
11
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
12
+ const Input = exports.Input = React.forwardRef(({
13
+ className,
14
+ type,
15
+ ...props
16
+ }, ref) => {
17
+ return (0, _jsxRuntime.jsx)("input", {
18
+ type: type,
19
+ className: (0, _utils.cn)("flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50", className),
20
+ ref: ref,
21
+ ...props
22
+ });
23
+ });
24
+ Input.displayName = "Input";
@@ -0,0 +1,17 @@
1
+ import * as React from "react";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { cn } from "../../lib/utils.mjs";
4
+
5
+ const Input = React.forwardRef(({ className, type, ...props }, ref) => {
6
+ return _jsx("input", {
7
+ type: type,
8
+ className: cn(
9
+ "flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50",
10
+ className,
11
+ ),
12
+ ref: ref,
13
+ ...props,
14
+ });
15
+ });
16
+ Input.displayName = "Input";
17
+ export { Input };
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.TableRow = exports.TableHeader = exports.TableHead = exports.TableCell = exports.TableBody = exports.Table = void 0;
7
+ var React = _interopRequireWildcard(require("react"));
8
+ var _jsxRuntime = require("react/jsx-runtime");
9
+ var _utils = require("../../lib/utils.cjs");
10
+ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
11
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
12
+ const Table = exports.Table = React.forwardRef(({
13
+ className,
14
+ ...props
15
+ }, ref) => (0, _jsxRuntime.jsx)("div", {
16
+ className: "relative w-full overflow-auto",
17
+ children: (0, _jsxRuntime.jsx)("table", {
18
+ ref: ref,
19
+ className: (0, _utils.cn)("w-full caption-bottom text-sm", className),
20
+ ...props
21
+ })
22
+ }));
23
+ Table.displayName = "Table";
24
+ const TableHeader = exports.TableHeader = React.forwardRef(({
25
+ className,
26
+ ...props
27
+ }, ref) => (0, _jsxRuntime.jsx)("thead", {
28
+ ref: ref,
29
+ className: (0, _utils.cn)("[&_tr]:border-b", className),
30
+ ...props
31
+ }));
32
+ TableHeader.displayName = "TableHeader";
33
+ const TableBody = exports.TableBody = React.forwardRef(({
34
+ className,
35
+ ...props
36
+ }, ref) => (0, _jsxRuntime.jsx)("tbody", {
37
+ ref: ref,
38
+ className: (0, _utils.cn)("[&_tr:last-child]:border-0", className),
39
+ ...props
40
+ }));
41
+ TableBody.displayName = "TableBody";
42
+ const TableRow = exports.TableRow = React.forwardRef(({
43
+ className,
44
+ ...props
45
+ }, ref) => (0, _jsxRuntime.jsx)("tr", {
46
+ ref: ref,
47
+ className: (0, _utils.cn)("border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted", className),
48
+ ...props
49
+ }));
50
+ TableRow.displayName = "TableRow";
51
+ const TableHead = exports.TableHead = React.forwardRef(({
52
+ className,
53
+ ...props
54
+ }, ref) => (0, _jsxRuntime.jsx)("th", {
55
+ ref: ref,
56
+ className: (0, _utils.cn)("h-10 px-2 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]", className),
57
+ ...props
58
+ }));
59
+ TableHead.displayName = "TableHead";
60
+ const TableCell = exports.TableCell = React.forwardRef(({
61
+ className,
62
+ ...props
63
+ }, ref) => (0, _jsxRuntime.jsx)("td", {
64
+ ref: ref,
65
+ className: (0, _utils.cn)("p-2 align-middle [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]", className),
66
+ ...props
67
+ }));
68
+ TableCell.displayName = "TableCell";
@@ -0,0 +1,65 @@
1
+ import * as React from "react";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { cn } from "../../lib/utils.mjs";
4
+
5
+ const Table = React.forwardRef(({ className, ...props }, ref) =>
6
+ _jsx("div", {
7
+ className: "relative w-full overflow-auto",
8
+ children: _jsx("table", {
9
+ ref: ref,
10
+ className: cn("w-full caption-bottom text-sm", className),
11
+ ...props,
12
+ }),
13
+ }),
14
+ );
15
+ Table.displayName = "Table";
16
+ const TableHeader = React.forwardRef(({ className, ...props }, ref) =>
17
+ _jsx("thead", {
18
+ ref: ref,
19
+ className: cn("[&_tr]:border-b", className),
20
+ ...props,
21
+ }),
22
+ );
23
+ TableHeader.displayName = "TableHeader";
24
+ const TableBody = React.forwardRef(({ className, ...props }, ref) =>
25
+ _jsx("tbody", {
26
+ ref: ref,
27
+ className: cn("[&_tr:last-child]:border-0", className),
28
+ ...props,
29
+ }),
30
+ );
31
+ TableBody.displayName = "TableBody";
32
+ const TableRow = React.forwardRef(({ className, ...props }, ref) =>
33
+ _jsx("tr", {
34
+ ref: ref,
35
+ className: cn(
36
+ "border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted",
37
+ className,
38
+ ),
39
+ ...props,
40
+ }),
41
+ );
42
+ TableRow.displayName = "TableRow";
43
+ const TableHead = React.forwardRef(({ className, ...props }, ref) =>
44
+ _jsx("th", {
45
+ ref: ref,
46
+ className: cn(
47
+ "h-10 px-2 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",
48
+ className,
49
+ ),
50
+ ...props,
51
+ }),
52
+ );
53
+ TableHead.displayName = "TableHead";
54
+ const TableCell = React.forwardRef(({ className, ...props }, ref) =>
55
+ _jsx("td", {
56
+ ref: ref,
57
+ className: cn(
58
+ "p-2 align-middle [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",
59
+ className,
60
+ ),
61
+ ...props,
62
+ }),
63
+ );
64
+ TableCell.displayName = "TableCell";
65
+ export { Table, TableHeader, TableBody, TableHead, TableRow, TableCell };
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.Textarea = void 0;
7
+ var React = _interopRequireWildcard(require("react"));
8
+ var _jsxRuntime = require("react/jsx-runtime");
9
+ var _utils = require("../../lib/utils.cjs");
10
+ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
11
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
12
+ const Textarea = exports.Textarea = React.forwardRef(({
13
+ className,
14
+ ...props
15
+ }, ref) => {
16
+ return (0, _jsxRuntime.jsx)("textarea", {
17
+ className: (0, _utils.cn)("flex min-h-[60px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50", className),
18
+ ref: ref,
19
+ ...props
20
+ });
21
+ });
22
+ Textarea.displayName = "Textarea";
@@ -0,0 +1,16 @@
1
+ import * as React from "react";
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { cn } from "../../lib/utils.mjs";
4
+
5
+ const Textarea = React.forwardRef(({ className, ...props }, ref) => {
6
+ return _jsx("textarea", {
7
+ className: cn(
8
+ "flex min-h-[60px] w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50",
9
+ className,
10
+ ),
11
+ ref: ref,
12
+ ...props,
13
+ });
14
+ });
15
+ Textarea.displayName = "Textarea";
16
+ export { Textarea };
package/dist/index.cjs ADDED
@@ -0,0 +1,100 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+
7
+ var _server = require("@arch-cadre/core/server");
8
+ var _drizzleOrm = require("drizzle-orm");
9
+ var _manifest = _interopRequireDefault(require("../manifest.json"));
10
+ var _BlogStatsWidget = _interopRequireDefault(require("./components/BlogStatsWidget.cjs"));
11
+ var _RecentCommentsWidget = _interopRequireDefault(require("./components/RecentCommentsWidget.cjs"));
12
+ var _RecentPostsWidget = _interopRequireDefault(require("./components/RecentPostsWidget.cjs"));
13
+ var _navigation = require("./navigation.cjs");
14
+ var _routes = require("./routes.cjs");
15
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
16
+ const BLOG_PERMISSIONS = [{
17
+ name: "post:create",
18
+ description: "Allow creating blog posts"
19
+ }, {
20
+ name: "post:update",
21
+ description: "Allow updating blog posts"
22
+ }, {
23
+ name: "post:delete",
24
+ description: "Allow deleting blog posts"
25
+ }, {
26
+ name: "comment:create",
27
+ description: "Allow creating comments"
28
+ }, {
29
+ name: "comment:update",
30
+ description: "Allow updating comments"
31
+ }, {
32
+ name: "comment:delete",
33
+ description: "Allow deleting comments"
34
+ }];
35
+ const blogModule = {
36
+ manifest: _manifest.default,
37
+ init: async () => {
38
+ console.log("[BlogModule] ready.");
39
+ },
40
+ widgets: [{
41
+ id: "blog-stats",
42
+ name: "Blog Stats",
43
+ area: "dashboard-stats",
44
+ component: _BlogStatsWidget.default,
45
+ priority: 20
46
+ }, {
47
+ id: "recent-posts",
48
+ name: "Recent Posts",
49
+ area: "dashboard-main",
50
+ component: _RecentPostsWidget.default,
51
+ priority: 20
52
+ }, {
53
+ id: "recent-comments",
54
+ name: "Recent Comments",
55
+ area: "dashboard-main",
56
+ component: _RecentCommentsWidget.default,
57
+ priority: 30
58
+ }],
59
+ onEnable: async () => {
60
+ console.log("[BlogModule] enabling and registering permissions...");
61
+ try {
62
+ for (const perm of BLOG_PERMISSIONS) {
63
+ await (0, _server.createPermission)(perm.name, perm.description);
64
+ }
65
+ const roles = await (0, _server.getRoles)();
66
+ const adminRole = roles.find(r => r.name === "admin");
67
+ if (adminRole) {
68
+ const blogPermNames = BLOG_PERMISSIONS.map(p => p.name);
69
+ const blogPerms = await _server.db.select().from(_server.permissionsTable).where((0, _drizzleOrm.inArray)(_server.permissionsTable.name, blogPermNames));
70
+ for (const p of blogPerms) {
71
+ await (0, _server.assignPermissionToRole)(adminRole.id, p.id);
72
+ }
73
+ console.log("[BlogModule] Permissions assigned to admin role.");
74
+ }
75
+ } catch (error) {
76
+ console.error("[BlogModule] Error during permission registration:", error);
77
+ }
78
+ console.log("[BlogModule] enabled.");
79
+ },
80
+ onDisable: async () => {
81
+ console.log("[Blog] onDisable: Cleaning up tables and permissions...");
82
+ try {
83
+ const blogPermNames = BLOG_PERMISSIONS.map(p => p.name);
84
+ await _server.db.delete(_server.permissionsTable).where((0, _drizzleOrm.inArray)(_server.permissionsTable.name, blogPermNames));
85
+ console.log("[BlogModule] Permissions and mappings removed.");
86
+ const tables = ["blog_posts", "blog_comments"];
87
+ for (const table of tables) {
88
+ await _server.db.execute(_drizzleOrm.sql.raw(`DROP TABLE IF EXISTS ${table} CASCADE`));
89
+ }
90
+ } catch (e) {
91
+ console.error("[Blog] onDisable Error:", e);
92
+ }
93
+ },
94
+ routes: {
95
+ public: _routes.publicRoutes,
96
+ private: _routes.privateRoutes
97
+ },
98
+ navigation: _navigation.navigation
99
+ };
100
+ module.exports = blogModule;
package/dist/index.mjs ADDED
@@ -0,0 +1,95 @@
1
+ import {
2
+ assignPermissionToRole,
3
+ createPermission,
4
+ db,
5
+ getRoles,
6
+ permissionsTable
7
+ } from "@arch-cadre/core/server";
8
+ import { inArray, sql } from "drizzle-orm";
9
+ import manifest from "../manifest.json" with { type: "json" };
10
+ import BlogStatsWidget from "./components/BlogStatsWidget.mjs";
11
+ import RecentCommentsWidget from "./components/RecentCommentsWidget.mjs";
12
+ import RecentPostsWidget from "./components/RecentPostsWidget.mjs";
13
+ import { navigation } from "./navigation.mjs";
14
+ import { privateRoutes, publicRoutes } from "./routes.mjs";
15
+ const BLOG_PERMISSIONS = [
16
+ { name: "post:create", description: "Allow creating blog posts" },
17
+ { name: "post:update", description: "Allow updating blog posts" },
18
+ { name: "post:delete", description: "Allow deleting blog posts" },
19
+ { name: "comment:create", description: "Allow creating comments" },
20
+ { name: "comment:update", description: "Allow updating comments" },
21
+ { name: "comment:delete", description: "Allow deleting comments" }
22
+ ];
23
+ const blogModule = {
24
+ manifest,
25
+ init: async () => {
26
+ console.log("[BlogModule] ready.");
27
+ },
28
+ widgets: [
29
+ {
30
+ id: "blog-stats",
31
+ name: "Blog Stats",
32
+ area: "dashboard-stats",
33
+ component: BlogStatsWidget,
34
+ priority: 20
35
+ },
36
+ {
37
+ id: "recent-posts",
38
+ name: "Recent Posts",
39
+ area: "dashboard-main",
40
+ component: RecentPostsWidget,
41
+ priority: 20
42
+ },
43
+ {
44
+ id: "recent-comments",
45
+ name: "Recent Comments",
46
+ area: "dashboard-main",
47
+ component: RecentCommentsWidget,
48
+ priority: 30
49
+ }
50
+ ],
51
+ onEnable: async () => {
52
+ console.log("[BlogModule] enabling and registering permissions...");
53
+ try {
54
+ for (const perm of BLOG_PERMISSIONS) {
55
+ await createPermission(perm.name, perm.description);
56
+ }
57
+ const roles = await getRoles();
58
+ const adminRole = roles.find((r) => r.name === "admin");
59
+ if (adminRole) {
60
+ const blogPermNames = BLOG_PERMISSIONS.map((p) => p.name);
61
+ const blogPerms = await db.select().from(permissionsTable).where(inArray(permissionsTable.name, blogPermNames));
62
+ for (const p of blogPerms) {
63
+ await assignPermissionToRole(adminRole.id, p.id);
64
+ }
65
+ console.log("[BlogModule] Permissions assigned to admin role.");
66
+ }
67
+ } catch (error) {
68
+ console.error(
69
+ "[BlogModule] Error during permission registration:",
70
+ error
71
+ );
72
+ }
73
+ console.log("[BlogModule] enabled.");
74
+ },
75
+ onDisable: async () => {
76
+ console.log("[Blog] onDisable: Cleaning up tables and permissions...");
77
+ try {
78
+ const blogPermNames = BLOG_PERMISSIONS.map((p) => p.name);
79
+ await db.delete(permissionsTable).where(inArray(permissionsTable.name, blogPermNames));
80
+ console.log("[BlogModule] Permissions and mappings removed.");
81
+ const tables = ["blog_posts", "blog_comments"];
82
+ for (const table of tables) {
83
+ await db.execute(sql.raw(`DROP TABLE IF EXISTS ${table} CASCADE`));
84
+ }
85
+ } catch (e) {
86
+ console.error("[Blog] onDisable Error:", e);
87
+ }
88
+ },
89
+ routes: {
90
+ public: publicRoutes,
91
+ private: privateRoutes
92
+ },
93
+ navigation
94
+ };
95
+ export default blogModule;
package/dist/intl.d.ts ADDED
@@ -0,0 +1,7 @@
1
+ import type messages from "../locales/en/global.json";
2
+
3
+ type JsonDataType = typeof messages;
4
+
5
+ declare module "@arch-cadre/intl" {
6
+ export interface IntlMessages extends JsonDataType {}
7
+ }
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.cn = cn;
7
+ var _clsx = require("clsx");
8
+ var _tailwindMerge = require("tailwind-merge");
9
+ function cn(...inputs) {
10
+ return (0, _tailwindMerge.twMerge)((0, _clsx.clsx)(inputs));
11
+ }
@@ -1,5 +1,5 @@
1
1
  import { clsx } from "clsx";
2
2
  import { twMerge } from "tailwind-merge";
3
3
  export function cn(...inputs) {
4
- return twMerge(clsx(inputs));
4
+ return twMerge(clsx(inputs));
5
5
  }
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.postSchema = exports.commentSchema = void 0;
7
+ var _zod = require("zod");
8
+ const postSchema = exports.postSchema = _zod.z.object({
9
+ title: _zod.z.string().min(3, "Title must be at least 3 characters"),
10
+ content: _zod.z.string().min(10, "Content must be at least 10 characters"),
11
+ slug: _zod.z.string().min(3, "Slug is required")
12
+ });
13
+ const commentSchema = exports.commentSchema = _zod.z.object({
14
+ content: _zod.z.string().min(2, "Comment is too short"),
15
+ postId: _zod.z.string().uuid()
16
+ });
@@ -5,12 +5,12 @@ export declare const postSchema: z.ZodObject<{
5
5
  slug: z.ZodString;
6
6
  }, "strip", z.ZodTypeAny, {
7
7
  title: string;
8
- slug: string;
9
8
  content: string;
9
+ slug: string;
10
10
  }, {
11
11
  title: string;
12
- slug: string;
13
12
  content: string;
13
+ slug: string;
14
14
  }>;
15
15
  export declare const commentSchema: z.ZodObject<{
16
16
  content: z.ZodString;
@@ -0,0 +1,10 @@
1
+ import { z } from "zod";
2
+ export const postSchema = z.object({
3
+ title: z.string().min(3, "Title must be at least 3 characters"),
4
+ content: z.string().min(10, "Content must be at least 10 characters"),
5
+ slug: z.string().min(3, "Slug is required")
6
+ });
7
+ export const commentSchema = z.object({
8
+ content: z.string().min(2, "Comment is too short"),
9
+ postId: z.string().uuid()
10
+ });
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.navigation = void 0;
7
+ var _intl = require("@arch-cadre/intl");
8
+ const navigation = exports.navigation = {
9
+ public: [{
10
+ title: (0, _intl.i18n)("Blog"),
11
+ url: "/blog",
12
+ icon: "solar:pen-2-broken"
13
+ }],
14
+ admin: {
15
+ [(0, _intl.i18n)("CMS")]: [{
16
+ title: (0, _intl.i18n)("Blog Manager"),
17
+ url: "/blog",
18
+ icon: "solar:posts-carousel-vertical-broken",
19
+ roles: ["admin"],
20
+ permissions: ["post:create", "post:update", "post:delete"]
21
+ }]
22
+ }
23
+ };
@@ -0,0 +1,21 @@
1
+ import { i18n } from "@arch-cadre/intl";
2
+ export const navigation = {
3
+ public: [
4
+ {
5
+ title: i18n("Blog"),
6
+ url: "/blog",
7
+ icon: "solar:pen-2-broken"
8
+ }
9
+ ],
10
+ admin: {
11
+ [i18n("CMS")]: [
12
+ {
13
+ title: i18n("Blog Manager"),
14
+ url: "/blog",
15
+ icon: "solar:posts-carousel-vertical-broken",
16
+ roles: ["admin"],
17
+ permissions: ["post:create", "post:update", "post:delete"]
18
+ }
19
+ ]
20
+ }
21
+ };