kempo 4.2.19 → 4.2.21

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 (176) hide show
  1. package/app-public/CATCH.page.html +15 -0
  2. package/app-public/kempo-global.global.html +0 -6
  3. package/bin/cli.js +4 -21
  4. package/dist/admin/accounts/groups/[name]/index.page.html +114 -4
  5. package/dist/admin/accounts/groups/index.page.html +89 -4
  6. package/dist/admin/accounts/permissions/index.page.html +86 -4
  7. package/dist/admin/accounts/users/[id]/index.page.html +117 -3
  8. package/dist/admin/accounts/users/index.page.html +118 -4
  9. package/dist/admin/components/AddGroupControl.js +1 -5
  10. package/dist/admin/components/AddGroupControl.js.map +1 -1
  11. package/dist/admin/components/AdminTableControl.js +2 -0
  12. package/dist/admin/components/AdminTableControl.js.map +1 -0
  13. package/dist/admin/components/ClearExpiredSessionsControl.js +1 -5
  14. package/dist/admin/components/ClearExpiredSessionsControl.js.map +1 -1
  15. package/dist/admin/components/GroupDeleteSelected.js +1 -5
  16. package/dist/admin/components/GroupDeleteSelected.js.map +1 -1
  17. package/dist/admin/components/GroupRemoveRecord.js +1 -5
  18. package/dist/admin/components/GroupRemoveRecord.js.map +1 -1
  19. package/dist/admin/components/TableRowDelete.js +1 -3
  20. package/dist/admin/components/TableRowDelete.js.map +1 -1
  21. package/dist/admin/components/TableRowLink.js +1 -7
  22. package/dist/admin/components/TableRowLink.js.map +1 -1
  23. package/dist/admin/components/tableControls/AddMember.js +1 -5
  24. package/dist/admin/components/tableControls/AddMember.js.map +1 -1
  25. package/dist/admin/components/tableControls/AddPermission.js +1 -5
  26. package/dist/admin/components/tableControls/AddPermission.js.map +1 -1
  27. package/dist/admin/components/tableControls/InstallExtension.js +1 -5
  28. package/dist/admin/components/tableControls/InstallExtension.js.map +1 -1
  29. package/dist/admin/components/tableControls/UninstallExtension.js +1 -5
  30. package/dist/admin/components/tableControls/UninstallExtension.js.map +1 -1
  31. package/dist/admin/content/fragments/edit/index.page.html +8 -1
  32. package/dist/admin/content/fragments/index.page.html +88 -3
  33. package/dist/admin/content/globals/edit/index.page.html +8 -1
  34. package/dist/admin/content/globals/index.page.html +103 -8
  35. package/dist/admin/content/pages/edit/index.page.html +8 -1
  36. package/dist/admin/content/pages/index.page.html +225 -28
  37. package/dist/admin/content/templates/edit/index.page.html +8 -1
  38. package/dist/admin/content/templates/index.page.html +117 -3
  39. package/dist/admin/default.template.html +20 -1
  40. package/dist/admin/extensions/index.page.html +59 -2
  41. package/dist/admin/icons/extension_add.svg +1 -0
  42. package/dist/admin/icons/extension_remove.svg +1 -0
  43. package/dist/admin/index.page.html +5 -1
  44. package/dist/admin/init.js.map +1 -1
  45. package/dist/admin/nav.fragment.html +84 -2
  46. package/dist/admin/settings/[owner]/[name]/index.page.html +110 -4
  47. package/dist/admin/settings/index.page.html +89 -4
  48. package/dist/kempo/api/admin-globals/DELETE.js +1 -1
  49. package/dist/kempo/api/admin-globals/DELETE.js.map +1 -1
  50. package/dist/kempo/api/admin-globals/GET.js +1 -1
  51. package/dist/kempo/api/admin-globals/GET.js.map +1 -1
  52. package/dist/kempo/api/admin-globals/POST.js +1 -1
  53. package/dist/kempo/api/admin-globals/POST.js.map +1 -1
  54. package/dist/kempo/api/admin-globals/[id]/GET.js +1 -1
  55. package/dist/kempo/api/admin-globals/[id]/GET.js.map +1 -1
  56. package/dist/kempo/api/admin-globals/[id]/PUT.js +1 -1
  57. package/dist/kempo/api/admin-globals/[id]/PUT.js.map +1 -1
  58. package/dist/kempo/api/admin-globals/[id]/disable/PUT.js +1 -1
  59. package/dist/kempo/api/admin-globals/[id]/disable/PUT.js.map +1 -1
  60. package/dist/kempo/api/admin-globals/[id]/enable/PUT.js +1 -1
  61. package/dist/kempo/api/admin-globals/[id]/enable/PUT.js.map +1 -1
  62. package/dist/kempo/api/extensions/DELETE.js +1 -1
  63. package/dist/kempo/api/extensions/DELETE.js.map +1 -1
  64. package/dist/kempo/api/extensions/POST.js +1 -1
  65. package/dist/kempo/api/extensions/POST.js.map +1 -1
  66. package/dist/kempo/api/extensions/[name]/disable/POST.js +1 -1
  67. package/dist/kempo/api/extensions/[name]/disable/POST.js.map +1 -1
  68. package/dist/kempo/api/extensions/[name]/enable/POST.js +1 -1
  69. package/dist/kempo/api/extensions/[name]/enable/POST.js.map +1 -1
  70. package/dist/kempo/api/extensions/[name]/update/POST.js +1 -1
  71. package/dist/kempo/api/extensions/[name]/update/POST.js.map +1 -1
  72. package/dist/kempo/api/extensions/[name]/update-check/GET.js +1 -1
  73. package/dist/kempo/api/extensions/[name]/update-check/GET.js.map +1 -1
  74. package/dist/kempo/api/fragments/DELETE.js +1 -1
  75. package/dist/kempo/api/fragments/DELETE.js.map +1 -1
  76. package/dist/kempo/api/fragments/GET.js +1 -1
  77. package/dist/kempo/api/fragments/GET.js.map +1 -1
  78. package/dist/kempo/api/fragments/POST.js +1 -1
  79. package/dist/kempo/api/fragments/POST.js.map +1 -1
  80. package/dist/kempo/api/fragments/disable/PUT.js +1 -1
  81. package/dist/kempo/api/fragments/disable/PUT.js.map +1 -1
  82. package/dist/kempo/api/fragments/enable/PUT.js +1 -1
  83. package/dist/kempo/api/fragments/enable/PUT.js.map +1 -1
  84. package/dist/kempo/api/fragments/file/GET.js +1 -1
  85. package/dist/kempo/api/fragments/file/GET.js.map +1 -1
  86. package/dist/kempo/api/fragments/file/PATCH.js +1 -1
  87. package/dist/kempo/api/fragments/file/PATCH.js.map +1 -1
  88. package/dist/kempo/api/fragments/file/PUT.js +1 -1
  89. package/dist/kempo/api/fragments/file/PUT.js.map +1 -1
  90. package/dist/kempo/api/fragments/lock/PUT.js +1 -1
  91. package/dist/kempo/api/fragments/lock/PUT.js.map +1 -1
  92. package/dist/kempo/api/globals/DELETE.js +1 -1
  93. package/dist/kempo/api/globals/DELETE.js.map +1 -1
  94. package/dist/kempo/api/globals/GET.js +1 -1
  95. package/dist/kempo/api/globals/GET.js.map +1 -1
  96. package/dist/kempo/api/globals/POST.js +1 -1
  97. package/dist/kempo/api/globals/POST.js.map +1 -1
  98. package/dist/kempo/api/globals/disable/PUT.js +1 -1
  99. package/dist/kempo/api/globals/disable/PUT.js.map +1 -1
  100. package/dist/kempo/api/globals/enable/PUT.js +1 -1
  101. package/dist/kempo/api/globals/enable/PUT.js.map +1 -1
  102. package/dist/kempo/api/globals/entry/GET.js +1 -1
  103. package/dist/kempo/api/globals/entry/GET.js.map +1 -1
  104. package/dist/kempo/api/globals/entry/PUT.js +1 -1
  105. package/dist/kempo/api/globals/entry/PUT.js.map +1 -1
  106. package/dist/kempo/api/globals/lock/PUT.js +1 -1
  107. package/dist/kempo/api/globals/lock/PUT.js.map +1 -1
  108. package/dist/kempo/api/pages/DELETE.js +1 -1
  109. package/dist/kempo/api/pages/DELETE.js.map +1 -1
  110. package/dist/kempo/api/pages/GET.js +1 -1
  111. package/dist/kempo/api/pages/GET.js.map +1 -1
  112. package/dist/kempo/api/pages/POST.js +1 -1
  113. package/dist/kempo/api/pages/POST.js.map +1 -1
  114. package/dist/kempo/api/pages/directories/GET.js +1 -1
  115. package/dist/kempo/api/pages/directories/GET.js.map +1 -1
  116. package/dist/kempo/api/pages/disable/PUT.js +1 -1
  117. package/dist/kempo/api/pages/disable/PUT.js.map +1 -1
  118. package/dist/kempo/api/pages/enable/PUT.js +1 -1
  119. package/dist/kempo/api/pages/enable/PUT.js.map +1 -1
  120. package/dist/kempo/api/pages/file/GET.js +1 -1
  121. package/dist/kempo/api/pages/file/GET.js.map +1 -1
  122. package/dist/kempo/api/pages/file/PATCH.js +1 -1
  123. package/dist/kempo/api/pages/file/PATCH.js.map +1 -1
  124. package/dist/kempo/api/pages/file/PUT.js +1 -1
  125. package/dist/kempo/api/pages/file/PUT.js.map +1 -1
  126. package/dist/kempo/api/pages/lock/PUT.js +1 -1
  127. package/dist/kempo/api/pages/lock/PUT.js.map +1 -1
  128. package/dist/kempo/api/pages/rescan/POST.js +2 -0
  129. package/dist/kempo/api/pages/rescan/POST.js.map +1 -0
  130. package/dist/kempo/api/pages/search/GET.js +1 -1
  131. package/dist/kempo/api/pages/search/GET.js.map +1 -1
  132. package/dist/kempo/api/pages/templates/GET.js +1 -1
  133. package/dist/kempo/api/pages/templates/GET.js.map +1 -1
  134. package/dist/kempo/api/templates/DELETE.js +1 -1
  135. package/dist/kempo/api/templates/DELETE.js.map +1 -1
  136. package/dist/kempo/api/templates/GET.js +1 -1
  137. package/dist/kempo/api/templates/GET.js.map +1 -1
  138. package/dist/kempo/api/templates/POST.js +1 -1
  139. package/dist/kempo/api/templates/POST.js.map +1 -1
  140. package/dist/kempo/api/templates/disable/PUT.js +1 -1
  141. package/dist/kempo/api/templates/disable/PUT.js.map +1 -1
  142. package/dist/kempo/api/templates/enable/PUT.js +1 -1
  143. package/dist/kempo/api/templates/enable/PUT.js.map +1 -1
  144. package/dist/kempo/api/templates/file/GET.js +1 -1
  145. package/dist/kempo/api/templates/file/GET.js.map +1 -1
  146. package/dist/kempo/api/templates/file/PATCH.js +1 -1
  147. package/dist/kempo/api/templates/file/PATCH.js.map +1 -1
  148. package/dist/kempo/api/templates/file/PUT.js +1 -1
  149. package/dist/kempo/api/templates/file/PUT.js.map +1 -1
  150. package/dist/kempo/api/templates/lock/PUT.js +1 -1
  151. package/dist/kempo/api/templates/lock/PUT.js.map +1 -1
  152. package/dist/kempo/api/user/[userid]/name/GET.js +2 -0
  153. package/dist/kempo/api/user/[userid]/name/GET.js.map +1 -0
  154. package/dist/kempo/components/UserDisplayName.js +2 -0
  155. package/dist/kempo/components/UserDisplayName.js.map +1 -0
  156. package/dist/kempo/sdk.js +1 -1
  157. package/dist/kempo/sdk.js.map +1 -1
  158. package/middleware/kempo.js +99 -25
  159. package/package.json +16 -9
  160. package/server/utils/admin-global-content/createAdminGlobalContent.js +4 -3
  161. package/server/utils/admin-global-content/deleteAdminGlobalContent.js +2 -2
  162. package/server/utils/admin-global-content/deleteAdminGlobalContentByOwner.js +2 -2
  163. package/server/utils/admin-global-content/disableAdminGlobalContent.js +2 -2
  164. package/server/utils/admin-global-content/enableAdminGlobalContent.js +2 -2
  165. package/server/utils/admin-global-content/getAdminGlobalContent.js +2 -2
  166. package/server/utils/admin-global-content/helpers.js +12 -1
  167. package/server/utils/admin-global-content/listAdminGlobalContent.js +2 -2
  168. package/server/utils/admin-global-content/updateAdminGlobalContent.js +2 -2
  169. package/server/utils/email/sendEmail.js +9 -3
  170. package/server/utils/extensions/uninstallExtension.js +54 -21
  171. package/server/utils/fragments/listFragments.js +10 -1
  172. package/server/utils/hooks/triggerHook.js +15 -13
  173. package/server/utils/pages/listPages.js +57 -7
  174. package/app-public/kempo-global.global-disabled.html +0 -0
  175. package/app-public/new-page.page.html +0 -17
  176. package/app-public/test.page.html +0 -21
@@ -2,14 +2,17 @@ import { readFile } from 'fs/promises';
2
2
  import { relative } from 'path';
3
3
  import scanDir from '../fs/scanDir.js';
4
4
  import parseFrontmatter from '../fs/parseFrontmatter.js';
5
+ import getSetting from '../settings/getSetting.js';
5
6
 
6
- const RESERVED_KEYS = new Set(['owner', 'name', 'author', 'created', 'updated', 'locked', 'title', 'description']);
7
+ const RESERVED_KEYS = new Set(['owner', 'name', 'author', 'created', 'updated', 'locked', 'hidden', 'title', 'description']);
7
8
 
8
- export default async ({ rootDir, owner }) => {
9
- if(!rootDir){
10
- return [{ code: 400, msg: 'Root directory is required' }, null];
11
- }
9
+ /*
10
+ In-memory cache keyed by rootDir.
11
+ TTL is read from the 'system:pages:cacheTtl' setting (milliseconds, default 60000).
12
+ */
13
+ const cache = new Map();
12
14
 
15
+ const scan = async (rootDir) => {
13
16
  const pages = await scanDir(rootDir, rootDir, async (fullPath, entry, root) => {
14
17
  const isDisabled = entry.name.endsWith('.page-disabled.html');
15
18
  if(entry.isDirectory() || (!entry.name.endsWith('.page.html') && !isDisabled)) return null;
@@ -32,6 +35,7 @@ export default async ({ rootDir, owner }) => {
32
35
  title: meta.title || '',
33
36
  owner: meta.owner || 'custom',
34
37
  locked: meta.locked === 'true',
38
+ hidden: meta.hidden === 'true',
35
39
  disabled: isDisabled,
36
40
  author: meta.author || '',
37
41
  description: meta.description || '',
@@ -41,8 +45,54 @@ export default async ({ rootDir, owner }) => {
41
45
  };
42
46
  });
43
47
 
44
- const filtered = owner ? pages.filter(page => page.owner === owner) : pages;
48
+ const scannedAt = Date.now();
49
+ cache.set(rootDir, { pages, scannedAt });
50
+ return scannedAt;
51
+ };
52
+
53
+ export default async ({ rootDir, owner, forceRescan = false, showHidden = true, offset = 0, limit = 0 }) => {
54
+ if(!rootDir){
55
+ return [{ code: 400, msg: 'Root directory is required' }, null];
56
+ }
57
+
58
+ const [, cacheTtl] = await getSetting('system', 'pages:cacheTtl', 60000);
59
+ const cached = cache.get(rootDir);
60
+
61
+ if(!forceRescan && cached && (Date.now() - cached.scannedAt < cacheTtl)){
62
+ return [null, buildResult(cached.pages, cached.scannedAt, { owner, showHidden, offset, limit })];
63
+ }
64
+
65
+ const scannedAt = await scan(rootDir);
66
+ const { pages } = cache.get(rootDir);
67
+ return [null, buildResult(pages, scannedAt, { owner, showHidden, offset, limit })];
68
+ };
69
+
70
+ const buildResult = (allPages, scannedAt, { owner, showHidden, offset, limit }) => {
71
+ let filtered = showHidden ? allPages : allPages.filter(p => !p.hidden);
72
+
73
+ if(owner === 'extension'){
74
+ filtered = filtered.filter(p => p.owner !== 'custom' && p.owner !== 'system');
75
+ } else if(owner){
76
+ filtered = filtered.filter(p => p.owner === owner);
77
+ }
78
+
79
+ filtered = filtered.slice().sort((a, b) => {
80
+ const aPath = a.file.replace(/\.page(-disabled)?\.html$/, '');
81
+ const bPath = b.file.replace(/\.page(-disabled)?\.html$/, '');
82
+ const aDir = aPath.includes('/') ? aPath.split('/').slice(0, -1).join('/') : '';
83
+ const bDir = bPath.includes('/') ? bPath.split('/').slice(0, -1).join('/') : '';
84
+ if(aPath === 'index' || aPath === '') return -1;
85
+ if(bPath === 'index' || bPath === '') return 1;
86
+ if(aDir !== bDir){
87
+ if(!aDir) return -1;
88
+ if(!bDir) return 1;
89
+ return aDir.localeCompare(bDir);
90
+ }
91
+ return aPath.localeCompare(bPath);
92
+ });
45
93
 
46
- return [null, { pages: filtered, total: filtered.length }];
94
+ const total = filtered.length;
95
+ const pages = limit > 0 ? filtered.slice(offset, offset + limit) : filtered.slice(offset);
96
+ return { pages, total, scannedAt };
47
97
  };
48
98
 
File without changes
@@ -1,17 +0,0 @@
1
- <!--
2
- owner: custom
3
- name: new page
4
- author:
5
- created: 2026-04-16T06:21:26.074Z
6
- updated: 2026-04-19T20:54:05.204Z
7
- title: new page
8
- description:
9
- -->
10
- <page template="split" title="new page">
11
- <content>
12
- <h1>New Page</h1>
13
- </content>
14
- <content location="left">
15
- <p>Left</p>
16
- </content>
17
- </page>
@@ -1,21 +0,0 @@
1
- <!--
2
- owner: custom
3
- name: test
4
- author: Dustin
5
- created: 2026-04-11T06:13:14.666Z
6
- updated: 2026-04-16T21:13:12.153Z
7
- title: test
8
- description:
9
- locked: true
10
- -->
11
- <page template="split" title="test">
12
- <content location="left">
13
- <p>Left Side MEnu</p>
14
- </content>
15
- <content>
16
- <h1>Test</h1>
17
- </content>
18
- <content location="scripts">
19
- <p><br></p>
20
- </content>
21
- </page>