underpost 3.2.30 → 3.2.80

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 (46) hide show
  1. package/.github/workflows/ghpkg.ci.yml +87 -0
  2. package/.github/workflows/npmpkg.ci.yml +9 -6
  3. package/.github/workflows/publish.ci.yml +3 -3
  4. package/.github/workflows/pwa-microservices-template-page.cd.yml +0 -7
  5. package/.github/workflows/release.cd.yml +1 -1
  6. package/CHANGELOG.md +1230 -971
  7. package/CLI-HELP.md +14 -6
  8. package/README.md +3 -3
  9. package/bin/build.js +40 -4
  10. package/bin/deploy.js +2 -2
  11. package/bump.config.js +1 -0
  12. package/docker-compose.yml +26 -26
  13. package/manifests/cronjobs/dd-cron/dd-cron-backup.yaml +1 -1
  14. package/manifests/cronjobs/dd-cron/dd-cron-dns.yaml +1 -1
  15. package/manifests/deployment/dd-default-development/deployment.yaml +2 -2
  16. package/package.json +15 -15
  17. package/scripts/disk-clean.sh +85 -60
  18. package/scripts/test-monitor.sh +1 -1
  19. package/src/api/core/core.controller.js +4 -65
  20. package/src/api/core/core.router.js +8 -14
  21. package/src/api/default/default.controller.js +2 -70
  22. package/src/api/default/default.router.js +7 -17
  23. package/src/api/document/document.controller.js +5 -77
  24. package/src/api/document/document.router.js +9 -13
  25. package/src/api/file/file.controller.js +9 -53
  26. package/src/api/file/file.router.js +14 -6
  27. package/src/api/test/test.controller.js +8 -53
  28. package/src/api/test/test.router.js +1 -4
  29. package/src/cli/cluster.js +104 -11
  30. package/src/cli/db.js +4 -2
  31. package/src/cli/deploy.js +60 -11
  32. package/src/cli/docker-compose.js +212 -1
  33. package/src/cli/fs.js +45 -25
  34. package/src/cli/image.js +147 -51
  35. package/src/cli/index.js +26 -6
  36. package/src/cli/release.js +50 -4
  37. package/src/cli/repository.js +98 -24
  38. package/src/cli/run.js +380 -178
  39. package/src/cli/secrets.js +75 -46
  40. package/src/cli/ssh.js +30 -11
  41. package/src/client/components/core/Modal.js +38 -4
  42. package/src/index.js +1 -1
  43. package/src/server/catalog.js +2 -0
  44. package/src/server/conf.js +163 -3
  45. package/src/server/downloader.js +3 -3
  46. package/src/server/middlewares.js +152 -0
@@ -7,20 +7,20 @@ set -euo pipefail
7
7
 
8
8
  VACUUM_SIZE="200M" # journalctl vacuum target
9
9
  LARGE_LOG_SIZE="+100M" # threshold for truncation (find syntax)
10
- TMP_AGE_DAYS=3 # remove files older than this from /tmp and /var/tmp
11
- CACHE_AGE_DAYS=30 # remove caches older than this from /var/cache
10
+ TMP_AGE_DAYS=1 # remove files older than this from /tmp and /var/tmp
11
+ CACHE_AGE_DAYS=5 # remove caches older than this from /var/cache
12
12
  KEEP_KERNELS=2 # keep this many latest kernels
13
13
  REMOVE_OPT=0 # ALWAYS allow removing /opt entries (user requested)
14
14
 
15
15
  timestamp() { date +"%F %T"; }
16
16
  log() {
17
- echo "$(timestamp) $*"
17
+ echo "$(timestamp) $*"
18
18
  }
19
19
 
20
20
  # must be root
21
21
  if [ "$EUID" -ne 0 ]; then
22
- echo "This script must be run as root. Exiting."
23
- exit 1
22
+ echo "This script must be run as root. Exiting."
23
+ exit 1
24
24
  fi
25
25
 
26
26
  log "=== Starting Rocky Linux 9 automated cleanup (batch mode) ==="
@@ -46,8 +46,8 @@ journalctl --vacuum-size="$VACUUM_SIZE"
46
46
  # 3) Truncate very large logs in /var/log (safer than delete)
47
47
  log "Truncating logs in /var/log larger than ${LARGE_LOG_SIZE} (keeps zero-sized file so services don't break)..."
48
48
  find /var/log -type f -size "$LARGE_LOG_SIZE" -print0 2>/dev/null | while IFS= read -r -d '' f; do
49
- echo "Truncating $f"
50
- : > "$f" || echo "Failed to truncate $f"
49
+ echo "Truncating $f"
50
+ : > "$f" || echo "Failed to truncate $f"
51
51
  done
52
52
 
53
53
  # 4) Clean /tmp and /var/tmp older than TMP_AGE_DAYS
@@ -62,87 +62,110 @@ find /var/cache -mindepth 1 -mtime +"$CACHE_AGE_DAYS" -print0 2>/dev/null | xarg
62
62
  # 6) Clean user caches (~/.cache) and Downloads older than CACHE_AGE_DAYS
63
63
  log "Cleaning user caches and old downloads (home dirs)..."
64
64
  for homedir in /home/* /root; do
65
- [ -d "$homedir" ] || continue
66
- usercache="$homedir/.cache"
67
- userdownloads="$homedir/Downloads"
68
- usertrash="$homedir/.local/share/Trash"
69
-
70
- if [ -d "$usercache" ]; then
71
- log "Removing contents of $usercache"
72
- rm -rf "${usercache:?}/"* 2>/dev/null
73
- fi
74
- if [ -d "$userdownloads" ]; then
75
- log "Removing files older than ${CACHE_AGE_DAYS} days from $userdownloads"
76
- find "$userdownloads" -type f -mtime +"$CACHE_AGE_DAYS" -print0 2>/dev/null | xargs -0r rm -f -- 2>/dev/null
77
- fi
78
- if [ -d "$usertrash" ]; then
79
- log "Emptying trash in $usertrash"
80
- rm -rf "${usertrash:?}/"* 2>/dev/null
81
- fi
65
+ [ -d "$homedir" ] || continue
66
+ usercache="$homedir/.cache"
67
+ userdownloads="$homedir/Downloads"
68
+ usertrash="$homedir/.local/share/Trash"
69
+
70
+ if [ -d "$usercache" ]; then
71
+ log "Removing contents of $usercache"
72
+ rm -rf "${usercache:?}/"* 2>/dev/null
73
+ fi
74
+ if [ -d "$userdownloads" ]; then
75
+ log "Removing files older than ${CACHE_AGE_DAYS} days from $userdownloads"
76
+ find "$userdownloads" -type f -mtime +"$CACHE_AGE_DAYS" -print0 2>/dev/null | xargs -0r rm -f -- 2>/dev/null
77
+ fi
78
+ if [ -d "$usertrash" ]; then
79
+ log "Emptying trash in $usertrash"
80
+ rm -rf "${usertrash:?}/"* 2>/dev/null
81
+ fi
82
82
  done
83
83
 
84
- # 7) Docker / Podman cleanup (if present)
84
+ # 7) Docker / Podman cleanup (if present) — this is what actually reclaims the
85
+ # overlay storage behind those duplicated `overlay` df lines.
85
86
  if command -v docker >/dev/null 2>&1; then
86
- log "Docker detected: pruning images/containers/volumes (aggressive)..."
87
- docker system df
88
- docker system prune -a --volumes -f
87
+ log "Docker detected: pruning images/containers/volumes/build cache (aggressive)..."
88
+ docker system df || true
89
+ docker system prune -a --volumes -f || true
90
+ docker builder prune -a -f || true
89
91
  fi
90
92
 
91
93
  if command -v podman >/dev/null 2>&1; then
92
- log "Podman detected: pruning images/containers (aggressive)..."
93
- podman system df
94
- podman system prune -a -f
94
+ log "Podman detected: pruning images/containers/volumes (aggressive)..."
95
+ podman system df || true
96
+ podman system prune -a --volumes -f || true
95
97
  fi
96
98
 
99
+ if command -v buildah >/dev/null 2>&1; then
100
+ log "Buildah detected: removing leftover working containers..."
101
+ buildah rm --all || true
102
+ fi
103
+
104
+ # 7b) Unmount leaked container overlay 'merged' mounts. Pruning frees the data
105
+ # but leaves these mountpoints attached, so they keep flooding `df -h` with
106
+ # identical `overlay ... /merged` rows. Only unmount overlays not backing a
107
+ # still-existing container, so running workloads are never disturbed.
108
+ log "Unmounting orphaned container overlay mounts..."
109
+ if command -v podman >/dev/null 2>&1; then
110
+ podman umount --all >/dev/null 2>&1 || true
111
+ fi
112
+ active_merged="$(podman ps -aq 2>/dev/null | xargs -r -I{} podman inspect --format '{{.GraphDriver.Data.MergedDir}}' {} 2>/dev/null || true)"
113
+ findmnt -rn -o TARGET 2>/dev/null | grep -E '/var/lib/(containers/storage|docker)/overlay.*/merged' | sort -r | while IFS= read -r m; do
114
+ if ! printf '%s\n' "$active_merged" | grep -qxF "$m"; then
115
+ echo "Unmounting orphaned overlay: $m"
116
+ umount -l "$m" 2>/dev/null || true
117
+ fi
118
+ done
119
+
97
120
  # 8) Flatpak unused runtimes/apps (if present)
98
121
  if command -v flatpak >/dev/null 2>&1; then
99
- log "Flatpak detected: trying to uninstall unused runtimes/apps..."
100
- flatpak uninstall --unused -y || flatpak uninstall --unused
101
- flatpak repair
122
+ log "Flatpak detected: trying to uninstall unused runtimes/apps..."
123
+ flatpak uninstall --unused -y || flatpak uninstall --unused
124
+ flatpak repair
102
125
  fi
103
126
 
104
127
  # 9) Python Pip cleanup
105
128
  if command -v pip3 >/dev/null 2>&1 || command -v pip >/dev/null 2>&1; then
106
- log "Python Pip detected: cleaning cache..."
107
- if command -v pip3 >/dev/null 2>&1; then
108
- pip3 cache purge
109
- elif command -v pip >/dev/null 2>&1; then
110
- pip cache purge
111
- fi
129
+ log "Python Pip detected: cleaning cache..."
130
+ if command -v pip3 >/dev/null 2>&1; then
131
+ pip3 cache purge
132
+ elif command -v pip >/dev/null 2>&1; then
133
+ pip cache purge
134
+ fi
112
135
  fi
113
136
 
114
137
  # 10) Conda cleanup
115
138
  if command -v conda >/dev/null 2>&1; then
116
- log "Conda detected: cleaning all..."
117
- conda clean --all -y
139
+ log "Conda detected: cleaning all..."
140
+ conda clean --all -y
118
141
  fi
119
142
 
120
143
  # 11) Remove old kernels but keep the last KEEP_KERNELS (safe)
121
144
  log "Removing old kernels, keeping the last $KEEP_KERNELS kernels..."
122
145
  OLD_KERNELS=$(dnf repoquery --installonly --latest-limit=-$KEEP_KERNELS -q 2>/dev/null)
123
146
  if [ -n "$OLD_KERNELS" ]; then
124
- log "Old kernels to remove: $OLD_KERNELS"
125
- dnf -y remove $OLD_KERNELS
147
+ log "Old kernels to remove: $OLD_KERNELS"
148
+ dnf -y remove $OLD_KERNELS
126
149
  else
127
- log "No old kernels found by DNF repoquery. Only $KEEP_KERNELS or fewer are currently installed."
150
+ log "No old kernels found by DNF repoquery. Only $KEEP_KERNELS or fewer are currently installed."
128
151
  fi
129
152
 
130
153
  # 12) /opt review and removal (ON by default now)
131
154
  if [ -d /opt ]; then
132
- log "/opt usage (top entries):"
133
- du -sh /opt/* 2>/dev/null | sort -h | head -n 20
134
-
135
- if [ "$REMOVE_OPT" = "1" ]; then
136
- OPT_TARGETS=(/opt/local-path-provisioner)
137
- for t in "${OPT_TARGETS[@]}"; do
138
- if [ -d "$t" ]; then
139
- log "Removing $t as REMOVE_OPT=1"
140
- rm -rf "$t"
141
- fi
142
- done
143
- else
144
- log "Automatic /opt removals disabled (set REMOVE_OPT=1 to enable)."
145
- fi
155
+ log "/opt usage (top entries):"
156
+ du -sh /opt/* 2>/dev/null | sort -h | head -n 20
157
+
158
+ if [ "$REMOVE_OPT" = "1" ]; then
159
+ OPT_TARGETS=(/opt/local-path-provisioner)
160
+ for t in "${OPT_TARGETS[@]}"; do
161
+ if [ -d "$t" ]; then
162
+ log "Removing $t as REMOVE_OPT=1"
163
+ rm -rf "$t"
164
+ fi
165
+ done
166
+ else
167
+ log "Automatic /opt removals disabled (set REMOVE_OPT=1 to enable)."
168
+ fi
146
169
  fi
147
170
 
148
171
  # 13) Find large files > 100MB (report only)
@@ -150,8 +173,10 @@ log "Listing files larger than 100MB (report only):"
150
173
  find / -xdev -type f -size +100M -printf '%s\t%p\n' 2>/dev/null | sort -nr | head -n 50 | awk '{printf "%.1fMB\t%s\n",$1/1024/1024,$2}'
151
174
 
152
175
  # Final disk usage
153
- log "Disk usage after cleanup:"
176
+ log "Disk usage cleanup:"
154
177
  df -h
178
+ log "Top-level usage ( / ):"
179
+ du -xh --max-depth=1 / | sort -rh | head -n 20
155
180
 
156
181
  log "=== Cleanup finished ==="
157
182
  exit 0
@@ -24,7 +24,7 @@ MODE=runtime # runtime | instance
24
24
  ENV=development # development | production
25
25
  DEPLOY_ID=dd-test # deploy id (instance mode: parent of conf.instances.json)
26
26
  INSTANCE_IDS= # instance mode: csv of ids (default: all in conf.instances.json)
27
- IMAGE=underpost/wp:v3.2.30 # runtime mode image (instance mode reads image from conf)
27
+ IMAGE=underpost/wp:v3.2.80 # runtime mode image (instance mode reads image from conf)
28
28
  VERSIONS=green # csv of blue/green versions
29
29
  REPLICAS=1 # replicas per deployment
30
30
  NAMESPACE=default # k8s namespace
@@ -1,69 +1,8 @@
1
- import { loggerFactory } from '../../server/logger.js';
1
+ import { buildCrudController, serviceHandler } from '../../server/middlewares.js';
2
2
  import { CoreService } from './core.service.js';
3
3
 
4
- const logger = loggerFactory(import.meta);
5
-
6
- class CoreController {
7
- static post = async (req, res, options) => {
8
- try {
9
- const result = await CoreService.post(req, res, options);
10
- return res.status(200).json({
11
- status: 'success',
12
- data: result,
13
- });
14
- } catch (error) {
15
- logger.error(error, error.stack);
16
- return res.status(400).json({
17
- status: 'error',
18
- message: error.message,
19
- });
20
- }
21
- };
22
- static get = async (req, res, options) => {
23
- try {
24
- const result = await CoreService.put(req, res, options);
25
- return res.status(200).json({
26
- status: 'success',
27
- data: result,
28
- });
29
- } catch (error) {
30
- logger.error(error, error.stack);
31
- return res.status(400).json({
32
- status: 'error',
33
- message: error.message,
34
- });
35
- }
36
- };
37
- static put = async (req, res, options) => {
38
- try {
39
- const result = await CoreService.get(req, res, options);
40
- return res.status(200).json({
41
- status: 'success',
42
- data: result,
43
- });
44
- } catch (error) {
45
- logger.error(error, error.stack);
46
- return res.status(400).json({
47
- status: 'error',
48
- message: error.message,
49
- });
50
- }
51
- };
52
- static delete = async (req, res, options) => {
53
- try {
54
- const result = await CoreService.delete(req, res, options);
55
- return res.status(200).json({
56
- status: 'success',
57
- data: result,
58
- });
59
- } catch (error) {
60
- logger.error(error, error.stack);
61
- return res.status(400).json({
62
- status: 'error',
63
- message: error.message,
64
- });
65
- }
66
- };
67
- }
4
+ const CoreController = buildCrudController(CoreService, {
5
+ get: serviceHandler(CoreService.get),
6
+ });
68
7
 
69
8
  export { CoreController };
@@ -1,9 +1,7 @@
1
+ import express from 'express';
2
+ import { registerCrudRoutes } from '../../server/middlewares.js';
1
3
  import { adminGuard } from '../../server/auth.js';
2
- import { loggerFactory } from '../../server/logger.js';
3
4
  import { CoreController } from './core.controller.js';
4
- import express from 'express';
5
-
6
- const logger = loggerFactory(import.meta);
7
5
 
8
6
  class CoreRouter {
9
7
  /**
@@ -11,16 +9,12 @@ class CoreRouter {
11
9
  * @returns {import('express').Router}
12
10
  */
13
11
  static router(options) {
14
- const router = express.Router();
15
- router.post(`/:id`, options.authMiddleware, adminGuard, async (req, res) => await CoreController.post(req, res, options));
16
- router.post(`/`, options.authMiddleware, adminGuard, async (req, res) => await CoreController.post(req, res, options));
17
- router.get(`/:id`, options.authMiddleware, adminGuard, async (req, res) => await CoreController.get(req, res, options));
18
- router.get(`/`, options.authMiddleware, adminGuard, async (req, res) => await CoreController.get(req, res, options));
19
- router.put(`/:id`, options.authMiddleware, adminGuard, async (req, res) => await CoreController.put(req, res, options));
20
- router.put(`/`, options.authMiddleware, adminGuard, async (req, res) => await CoreController.put(req, res, options));
21
- router.delete(`/:id`, options.authMiddleware, adminGuard, async (req, res) => await CoreController.delete(req, res, options));
22
- router.delete(`/`, options.authMiddleware, adminGuard, async (req, res) => await CoreController.delete(req, res, options));
23
- return router;
12
+ const adminOnly = [options.authMiddleware, adminGuard];
13
+ return registerCrudRoutes(express.Router(), CoreController, options, {
14
+ readGuards: adminOnly,
15
+ writeGuards: adminOnly,
16
+ deleteAllGuards: adminOnly,
17
+ });
24
18
  }
25
19
  }
26
20
 
@@ -1,74 +1,6 @@
1
- import { loggerFactory } from '../../server/logger.js';
1
+ import { buildCrudController } from '../../server/middlewares.js';
2
2
  import { DefaultService } from './default.service.js';
3
3
 
4
- const logger = loggerFactory(import.meta);
5
-
6
- class DefaultController {
7
- static post = async (req, res, options) => {
8
- try {
9
- const result = await DefaultService.post(req, res, options);
10
- return res.status(200).json({
11
- status: 'success',
12
- data: result,
13
- });
14
- } catch (error) {
15
- logger.error(error, error.stack);
16
- return res.status(400).json({
17
- status: 'error',
18
- message: error.message,
19
- });
20
- }
21
- };
22
- static get = async (req, res, options) => {
23
- try {
24
- const { page, limit } = req.query;
25
- const result = await DefaultService.get(
26
- { ...req, query: { ...req.query, page: parseInt(page), limit: parseInt(limit) } },
27
- res,
28
- options,
29
- );
30
- return res.status(200).json({
31
- status: 'success',
32
- data: result,
33
- });
34
- } catch (error) {
35
- logger.error(error, error.stack);
36
- return res.status(400).json({
37
- status: 'error',
38
- message: error.message,
39
- });
40
- }
41
- };
42
- static put = async (req, res, options) => {
43
- try {
44
- const result = await DefaultService.put(req, res, options);
45
- return res.status(200).json({
46
- status: 'success',
47
- data: result,
48
- });
49
- } catch (error) {
50
- logger.error(error, error.stack);
51
- return res.status(400).json({
52
- status: 'error',
53
- message: error.message,
54
- });
55
- }
56
- };
57
- static delete = async (req, res, options) => {
58
- try {
59
- const result = await DefaultService.delete(req, res, options);
60
- return res.status(200).json({
61
- status: 'success',
62
- data: result,
63
- });
64
- } catch (error) {
65
- logger.error(error, error.stack);
66
- return res.status(400).json({
67
- status: 'error',
68
- message: error.message,
69
- });
70
- }
71
- };
72
- }
4
+ const DefaultController = buildCrudController(DefaultService);
73
5
 
74
6
  export { DefaultController };
@@ -1,8 +1,6 @@
1
- import { loggerFactory } from '../../server/logger.js';
2
- import { DefaultController } from './default.controller.js';
3
1
  import express from 'express';
4
-
5
- const logger = loggerFactory(import.meta);
2
+ import { registerCrudRoutes } from '../../server/middlewares.js';
3
+ import { DefaultController } from './default.controller.js';
6
4
 
7
5
  class DefaultRouter {
8
6
  /**
@@ -10,19 +8,11 @@ class DefaultRouter {
10
8
  * @returns {import('express').Router}
11
9
  */
12
10
  static router(options) {
13
- const router = express.Router();
14
- router.post(`/:id`, async (req, res) => await DefaultController.post(req, res, options));
15
- router.post(`/`, async (req, res) => await DefaultController.post(req, res, options));
16
- router.get(`/:id`,
17
- // options.authMiddleware,
18
- async (req, res) => await DefaultController.get(req, res, options),
19
- );
20
- router.get(`/`, async (req, res) => await DefaultController.get(req, res, options));
21
- router.put(`/:id`, async (req, res) => await DefaultController.put(req, res, options));
22
- router.put(`/`, async (req, res) => await DefaultController.put(req, res, options));
23
- router.delete(`/:id`, async (req, res) => await DefaultController.delete(req, res, options));
24
- router.delete(`/`, async (req, res) => await DefaultController.delete(req, res, options));
25
- return router;
11
+ // Fully unguarded (matches prior behavior).
12
+ return registerCrudRoutes(express.Router(), DefaultController, options, {
13
+ writeGuards: [],
14
+ deleteAllGuards: [],
15
+ });
26
16
  }
27
17
  }
28
18
 
@@ -1,81 +1,9 @@
1
- import { loggerFactory } from '../../server/logger.js';
1
+ import { buildCrudController, serviceHandler } from '../../server/middlewares.js';
2
2
  import { DocumentService } from './document.service.js';
3
- const logger = loggerFactory(import.meta);
4
3
 
5
- class DocumentController {
6
- static post = async (req, res, options) => {
7
- try {
8
- return res.status(200).json({
9
- status: 'success',
10
- data: await DocumentService.post(req, res, options),
11
- });
12
- } catch (error) {
13
- logger.error(error, error.stack);
14
- return res.status(400).json({
15
- status: 'error',
16
- message: error.message,
17
- });
18
- }
19
- };
20
- static get = async (req, res, options) => {
21
- try {
22
- return res.status(200).json({
23
- status: 'success',
24
- data: await DocumentService.get(req, res, options),
25
- });
26
- } catch (error) {
27
- logger.error(error, error.stack);
28
- return res.status(400).json({
29
- status: 'error',
30
- message: error.message,
31
- });
32
- }
33
- };
34
- static delete = async (req, res, options) => {
35
- try {
36
- const result = await DocumentService.delete(req, res, options);
37
- return res.status(200).json({
38
- status: 'success',
39
- data: result,
40
- });
41
- } catch (error) {
42
- logger.error(error, error.stack);
43
- return res.status(400).json({
44
- status: 'error',
45
- message: error.message,
46
- });
47
- }
48
- };
49
- static put = async (req, res, options) => {
50
- try {
51
- const result = await DocumentService.put(req, res, options);
52
- return res.status(200).json({
53
- status: 'success',
54
- data: result,
55
- });
56
- } catch (error) {
57
- logger.error(error, error.stack);
58
- return res.status(400).json({
59
- status: 'error',
60
- message: error.message,
61
- });
62
- }
63
- };
64
- static patch = async (req, res, options) => {
65
- try {
66
- const result = await DocumentService.patch(req, res, options);
67
- return res.status(200).json({
68
- status: 'success',
69
- data: result,
70
- });
71
- } catch (error) {
72
- logger.error(error, error.stack);
73
- return res.status(400).json({
74
- status: 'error',
75
- message: error.message,
76
- });
77
- }
78
- };
79
- }
4
+ const DocumentController = buildCrudController(DocumentService, {
5
+ get: serviceHandler(DocumentService.get),
6
+ patch: serviceHandler(DocumentService.patch),
7
+ });
80
8
 
81
9
  export { DocumentController };
@@ -1,8 +1,6 @@
1
- import { loggerFactory } from '../../server/logger.js';
2
- import { DocumentController } from './document.controller.js';
3
1
  import express from 'express';
4
-
5
- const logger = loggerFactory(import.meta);
2
+ import { registerCrudRoutes } from '../../server/middlewares.js';
3
+ import { DocumentController } from './document.controller.js';
6
4
 
7
5
  class DocumentRouter {
8
6
  /**
@@ -11,23 +9,21 @@ class DocumentRouter {
11
9
  */
12
10
  static router(options) {
13
11
  const router = express.Router();
14
- router.post(`/:id`, options.authMiddleware, async (req, res) => await DocumentController.post(req, res, options));
15
- router.post(`/`, options.authMiddleware, async (req, res) => await DocumentController.post(req, res, options));
12
+ const authOnly = [options.authMiddleware];
13
+ // Public listings must come before the guarded generic /:id routes.
16
14
  router.get(`/public/high`, async (req, res) => await DocumentController.get(req, res, options));
17
15
  router.get(`/public`, async (req, res) => await DocumentController.get(req, res, options));
18
- router.get(`/:id`, options.authMiddleware, async (req, res) => await DocumentController.get(req, res, options));
19
- router.get(`/`, options.authMiddleware, async (req, res) => await DocumentController.get(req, res, options));
20
- router.put(`/:id`, options.authMiddleware, async (req, res) => await DocumentController.put(req, res, options));
21
- router.put(`/`, options.authMiddleware, async (req, res) => await DocumentController.put(req, res, options));
22
16
  router.patch(`/:id/copy-share-link`, async (req, res) => await DocumentController.patch(req, res, options));
23
17
  router.patch(
24
18
  `/:id/toggle-public`,
25
19
  options.authMiddleware,
26
20
  async (req, res) => await DocumentController.patch(req, res, options),
27
21
  );
28
- router.delete(`/:id`, options.authMiddleware, async (req, res) => await DocumentController.delete(req, res, options));
29
- router.delete(`/`, options.authMiddleware, async (req, res) => await DocumentController.delete(req, res, options));
30
- return router;
22
+ return registerCrudRoutes(router, DocumentController, options, {
23
+ readGuards: authOnly,
24
+ writeGuards: authOnly,
25
+ deleteAllGuards: authOnly,
26
+ });
31
27
  }
32
28
  }
33
29
 
@@ -1,59 +1,15 @@
1
- import { loggerFactory } from '../../server/logger.js';
1
+ import { controllerHandler, sendSuccess, serviceHandler, setCrossOriginHeaders } from '../../server/middlewares.js';
2
2
  import { FileService } from './file.service.js';
3
- const logger = loggerFactory(import.meta);
4
3
 
5
4
  class FileController {
6
- static post = async (req, res, options) => {
7
- try {
8
- return res.status(200).json({
9
- status: 'success',
10
- data: await FileService.post(req, res, options),
11
- });
12
- } catch (error) {
13
- logger.error(error, error.stack);
14
- return res.status(400).json({
15
- status: 'error',
16
- message: error.message,
17
- });
18
- }
19
- };
20
- static get = async (req, res, options) => {
21
- try {
22
- if (req && req.headers && req.headers.origin) {
23
- res.set('Access-Control-Allow-Origin', req.headers.origin);
24
- } else res.setHeader('Access-Control-Allow-Origin', '*');
25
- res.setHeader('Cross-Origin-Resource-Policy', 'cross-origin');
26
- const result = await FileService.get(req, res, options);
27
- if (result instanceof Buffer) {
28
- return res.status(200).end(result);
29
- }
30
- return res.status(200).json({
31
- status: 'success',
32
- data: result,
33
- });
34
- } catch (error) {
35
- logger.error(error, error.stack);
36
- return res.status(400).json({
37
- status: 'error',
38
- message: error.message,
39
- });
40
- }
41
- };
42
- static delete = async (req, res, options) => {
43
- try {
44
- const result = await FileService.delete(req, res, options);
45
- return res.status(200).json({
46
- status: 'success',
47
- data: result,
48
- });
49
- } catch (error) {
50
- logger.error(error, error.stack);
51
- return res.status(400).json({
52
- status: 'error',
53
- message: error.message,
54
- });
55
- }
56
- };
5
+ static post = serviceHandler(FileService.post);
6
+ static get = controllerHandler(async (req, res, options) => {
7
+ setCrossOriginHeaders(req, res);
8
+ const result = await FileService.get(req, res, options);
9
+ if (result instanceof Buffer) return res.status(200).end(result);
10
+ return sendSuccess(res, result);
11
+ });
12
+ static delete = serviceHandler(FileService.delete);
57
13
  }
58
14
 
59
15
  export { FileController };