kempo 4.5.7 → 4.6.0

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 (57) hide show
  1. package/README.md +1 -1
  2. package/dist/admin/components/tableControls/ExtensionDetails.js +2 -0
  3. package/dist/admin/components/tableControls/ExtensionDetails.js.map +1 -0
  4. package/dist/admin/components/tableControls/InstallExtension.js.map +1 -1
  5. package/dist/admin/components/tableControls/ToggleExtension.js +2 -0
  6. package/dist/admin/components/tableControls/ToggleExtension.js.map +1 -0
  7. package/dist/admin/components/tableControls/UninstallExtension.js +1 -1
  8. package/dist/admin/components/tableControls/UninstallExtension.js.map +1 -1
  9. package/dist/admin/extensions/browse/index.page.html +118 -0
  10. package/dist/admin/extensions/details/index.page.html +254 -0
  11. package/dist/admin/extensions/index.page.html +8 -2
  12. package/dist/kempo/api/extensions/DELETE.js +1 -1
  13. package/dist/kempo/api/extensions/DELETE.js.map +1 -1
  14. package/dist/kempo/api/extensions/POST.js +1 -1
  15. package/dist/kempo/api/extensions/POST.js.map +1 -1
  16. package/dist/kempo/api/extensions/[name]/dependents/GET.js +2 -0
  17. package/dist/kempo/api/extensions/[name]/dependents/GET.js.map +1 -0
  18. package/dist/kempo/api/extensions/[name]/disable/POST.js +1 -1
  19. package/dist/kempo/api/extensions/[name]/disable/POST.js.map +1 -1
  20. package/dist/kempo/api/extensions/[name]/enable/POST.js +1 -1
  21. package/dist/kempo/api/extensions/[name]/enable/POST.js.map +1 -1
  22. package/dist/kempo/api/extensions/[name]/requirements/GET.js +2 -0
  23. package/dist/kempo/api/extensions/[name]/requirements/GET.js.map +1 -0
  24. package/dist/kempo/api/extensions/available/GET.js +1 -1
  25. package/dist/kempo/api/extensions/available/GET.js.map +1 -1
  26. package/dist/kempo/api/extensions/known/GET.js +1 -1
  27. package/dist/kempo/api/extensions/known/GET.js.map +1 -1
  28. package/dist/kempo/api/extensions/rating/PUT.js +2 -0
  29. package/dist/kempo/api/extensions/rating/PUT.js.map +1 -0
  30. package/dist/kempo/icons/payments.svg +1 -0
  31. package/dist/kempo/icons/toll.svg +1 -0
  32. package/dist/kempo/icons/wallet.svg +1 -0
  33. package/dist/kempo/sdk.js +1 -1
  34. package/dist/kempo/sdk.js.map +1 -1
  35. package/middleware/kempo.js +9 -6
  36. package/package.json +1 -1
  37. package/server/utils/extensions/catalogClient.js +203 -0
  38. package/server/utils/extensions/disableExtension.js +2 -32
  39. package/server/utils/extensions/disableExtensionTree.js +46 -0
  40. package/server/utils/extensions/enableExtension.js +2 -33
  41. package/server/utils/extensions/enableExtensionTree.js +54 -0
  42. package/server/utils/extensions/getDependentTree.js +47 -0
  43. package/server/utils/extensions/getExtension.js +4 -3
  44. package/server/utils/extensions/getMarketplaceClient.js +20 -0
  45. package/server/utils/extensions/getRequirementTree.js +43 -0
  46. package/server/utils/extensions/getSiteInstallId.js +21 -0
  47. package/server/utils/extensions/installExtension.js +2 -6
  48. package/server/utils/extensions/installFromCatalog.js +127 -0
  49. package/server/utils/extensions/installPackage.js +36 -0
  50. package/server/utils/extensions/listExtensions.js +8 -7
  51. package/server/utils/extensions/readKempoConfig.js +20 -0
  52. package/server/utils/extensions/scopeCache.js +14 -5
  53. package/server/utils/extensions/uninstallExtension.js +2 -124
  54. package/server/utils/extensions/uninstallExtensionTree.js +165 -0
  55. package/server/utils/extensions/updateExtension.js +9 -7
  56. package/server/utils/hooks/triggerHook.js +8 -0
  57. package/dist/admin/known-extensions.json +0 -1
@@ -1,2 +1,2 @@
1
- import s from"../../../../../../server/utils/permissions/currentUserHasPermission.js";import e from"../../../../../../server/utils/extensions/enableExtension.js";export default async(r,n)=>{const o=r.cookies.session_token,[t,i]=await s(o,"system:extensions:manage");if(t)return n.status(t.code).json({error:t.msg});if(!i)return n.status(403).json({error:"Insufficient permissions"});const a=r.params.name,[m,u]=await e({name:a});if(m)return n.status(m.code).json({error:m.msg});n.json(u)};
1
+ import s from"../../../../../../server/utils/permissions/currentUserHasPermission.js";import e from"../../../../../../server/utils/extensions/enableExtensionTree.js";export default async(r,n)=>{const i=r.cookies.session_token,[t,o]=await s(i,"system:extensions:manage");if(t)return n.status(t.code).json({error:t.msg});if(!o)return n.status(403).json({error:"Insufficient permissions"});const a=r.params.name,[m,u]=await e({name:a,cascade:!0===r.body?.cascade});if(m)return n.status(m.code).json({error:m.msg,requirements:m.requirements,missing:m.missing});n.json(u)};
2
2
  //# sourceMappingURL=C:\Users\dusti\dev\kempo\dist\kempo\api\extensions\[name]\enable\POST.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"src\\kempo\\api\\extensions\\[name]\\enable\\POST.js","names":["currentUserHasPermission","enableExtension","async","request","response","token","cookies","session_token","permError","hasPermission","status","code","json","error","msg","name","params","data"],"sources":["0"],"sourcesContent":["import currentUserHasPermission from '../../../../../../server/utils/permissions/currentUserHasPermission.js';\r\nimport enableExtension from '../../../../../../server/utils/extensions/enableExtension.js';\r\n\r\nexport default async (request, response) => {\r\n const token = request.cookies.session_token;\r\n const [permError, hasPermission] = await currentUserHasPermission(token, 'system:extensions:manage');\r\n\r\n if(permError){\r\n return response.status(permError.code).json({ error: permError.msg });\r\n }\r\n\r\n if(!hasPermission){\r\n return response.status(403).json({ error: 'Insufficient permissions' });\r\n }\r\n\r\n const name = request.params.name;\r\n const [error, data] = await enableExtension({ name });\r\n\r\n if(error){\r\n return response.status(error.code).json({ error: error.msg });\r\n }\r\n\r\n response.json(data);\r\n};\r\n"],"mappings":"OAAOA,MAA8B,gFAC9BC,MAAqB,8EAEbC,MAAOC,EAASC,KAC7B,MAAMC,EAAQF,EAAQG,QAAQC,eACvBC,EAAWC,SAAuBT,EAAyBK,EAAO,4BAEzE,GAAGG,EACD,OAAOJ,EAASM,OAAOF,EAAUG,MAAMC,KAAK,CAAEC,MAAOL,EAAUM,MAGjE,IAAIL,EACF,OAAOL,EAASM,OAAO,KAAKE,KAAK,CAAEC,MAAO,6BAG5C,MAAME,EAAOZ,EAAQa,OAAOD,MACrBF,EAAOI,SAAchB,EAAgB,CAAEc,SAE9C,GAAGF,EACD,OAAOT,EAASM,OAAOG,EAAMF,MAAMC,KAAK,CAAEC,MAAOA,EAAMC,MAGzDV,EAASQ,KAAKK","ignoreList":[]}
1
+ {"version":3,"file":"src\\kempo\\api\\extensions\\[name]\\enable\\POST.js","names":["currentUserHasPermission","enableExtension","async","request","response","token","cookies","session_token","permError","hasPermission","status","code","json","error","msg","name","params","data","cascade","body","requirements","missing"],"sources":["0"],"sourcesContent":["import currentUserHasPermission from '../../../../../../server/utils/permissions/currentUserHasPermission.js';\nimport enableExtension from '../../../../../../server/utils/extensions/enableExtensionTree.js';\n\n/*\n POST /kempo/api/extensions/<name>/enable { cascade? }\n\n Without `cascade`, an extension whose requirements are switched off is refused (409) with the whole\n chain of them as `requirements`. With `cascade: true` they are enabled with it.\n*/\nexport default async (request, response) => {\n const token = request.cookies.session_token;\n const [permError, hasPermission] = await currentUserHasPermission(token, 'system:extensions:manage');\n\n if(permError){\n return response.status(permError.code).json({ error: permError.msg });\n }\n\n if(!hasPermission){\n return response.status(403).json({ error: 'Insufficient permissions' });\n }\n\n const name = request.params.name;\n const [error, data] = await enableExtension({ name, cascade: request.body?.cascade === true });\n\n if(error){\n return response.status(error.code).json({ error: error.msg, requirements: error.requirements, missing: error.missing });\n }\n\n response.json(data);\n};\n"],"mappings":"OAAOA,MAA8B,gFAC9BC,MAAqB,kFAQbC,MAAOC,EAASC,KAC7B,MAAMC,EAAQF,EAAQG,QAAQC,eACvBC,EAAWC,SAAuBT,EAAyBK,EAAO,4BAEzE,GAAGG,EACD,OAAOJ,EAASM,OAAOF,EAAUG,MAAMC,KAAK,CAAEC,MAAOL,EAAUM,MAGjE,IAAIL,EACF,OAAOL,EAASM,OAAO,KAAKE,KAAK,CAAEC,MAAO,6BAG5C,MAAME,EAAOZ,EAAQa,OAAOD,MACrBF,EAAOI,SAAchB,EAAgB,CAAEc,OAAMG,SAAmC,IAA1Bf,EAAQgB,MAAMD,UAE3E,GAAGL,EACD,OAAOT,EAASM,OAAOG,EAAMF,MAAMC,KAAK,CAAEC,MAAOA,EAAMC,IAAKM,aAAcP,EAAMO,aAAcC,QAASR,EAAMQ,UAG/GjB,EAASQ,KAAKK","ignoreList":[]}
@@ -0,0 +1,2 @@
1
+ import s from"../../../../../../server/utils/permissions/currentUserHasPermission.js";import e from"../../../../../../server/utils/extensions/getRequirementTree.js";export default async(r,o)=>{const t=r.cookies.session_token,[n,i]=await s(t,"system:extensions:manage");return n?o.status(n.code).json({error:n.msg}):i?void o.json(await e(r.params.name)):o.status(403).json({error:"Insufficient permissions"})};
2
+ //# sourceMappingURL=C:\Users\dusti\dev\kempo\dist\kempo\api\extensions\[name]\requirements\GET.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"src\\kempo\\api\\extensions\\[name]\\requirements\\GET.js","names":["currentUserHasPermission","getRequirementTree","async","request","response","token","cookies","session_token","permError","hasPermission","status","code","json","error","msg","params","name"],"sources":["0"],"sourcesContent":["import currentUserHasPermission from '../../../../../../server/utils/permissions/currentUserHasPermission.js';\nimport getRequirementTree from '../../../../../../server/utils/extensions/getRequirementTree.js';\n\n/*\n GET /kempo/api/extensions/<name>/requirements\n\n What this extension needs that is switched off (`disabled`, dependencies first, each saying what it\n requires) and what it needs that is not installed at all (`missing`).\n*/\nexport default async (request, response) => {\n const token = request.cookies.session_token;\n const [permError, hasPermission] = await currentUserHasPermission(token, 'system:extensions:manage');\n\n if(permError){\n return response.status(permError.code).json({ error: permError.msg });\n }\n\n if(!hasPermission){\n return response.status(403).json({ error: 'Insufficient permissions' });\n }\n\n response.json(await getRequirementTree(request.params.name));\n};\n"],"mappings":"OAAOA,MAA8B,gFAC9BC,MAAwB,iFAQhBC,MAAOC,EAASC,KAC7B,MAAMC,EAAQF,EAAQG,QAAQC,eACvBC,EAAWC,SAAuBT,EAAyBK,EAAO,4BAEzE,OAAGG,EACMJ,EAASM,OAAOF,EAAUG,MAAMC,KAAK,CAAEC,MAAOL,EAAUM,MAG7DL,OAIJL,EAASQ,WAAWX,EAAmBE,EAAQY,OAAOC,OAH7CZ,EAASM,OAAO,KAAKE,KAAK,CAAEC,MAAO","ignoreList":[]}
@@ -1,2 +1,2 @@
1
- import s from"../../../../../server/utils/permissions/currentUserHasPermission.js";import{readFile as e}from"fs/promises";import{existsSync as o}from"fs";import{join as t}from"path";const n=t(import.meta.dirname,"../../../admin/known-extensions.json");export default async(r,i)=>{const a=r.cookies.session_token,[c,p]=await s(a,"system:extensions:read");if(c)return i.status(c.code).json({error:c.msg});if(!p)return i.status(403).json({error:"Insufficient permissions"});let m=[];o(n)&&(m=JSON.parse(await e(n,"utf-8")));const f=t(process.cwd(),"package.json"),d=JSON.parse(await e(f,"utf-8")),u={...d.dependencies,...d.devDependencies},j=t(process.cwd(),"node_modules"),h=[];for(const[s]of Object.entries(u))try{const n=t(j,s,"kempo-config.json");if(!o(n))continue;const r=t(j,s,"package.json"),i=JSON.parse(await e(r,"utf-8")),a=m.find(e=>e.name===s);h.push({name:s,version:i.version,description:i.description||a?.description||"",author:i.author||a?.author||""})}catch{}i.json({items:h,total:h.length})};
1
+ import s from"../../../../../server/utils/permissions/currentUserHasPermission.js";import{readFile as e}from"fs/promises";import{existsSync as o}from"fs";import{join as t}from"path";export default async(r,n)=>{const i=r.cookies.session_token,[a,c]=await s(i,"system:extensions:read");if(a)return n.status(a.code).json({error:a.msg});if(!c)return n.status(403).json({error:"Insufficient permissions"});const p=JSON.parse(await e(t(process.cwd(),"package.json"),"utf-8")),m={...p.dependencies,...p.devDependencies},f=t(process.cwd(),"node_modules"),u=[];for(const[s]of Object.entries(m))try{if(!o(t(f,s,"kempo-config.json")))continue;const r=JSON.parse(await e(t(f,s,"package.json"),"utf-8"));u.push({name:s,version:r.version,description:r.description||"",author:("object"==typeof r.author?r.author?.name:r.author)||""})}catch{}n.json({items:u,total:u.length})};
2
2
  //# sourceMappingURL=C:\Users\dusti\dev\kempo\dist\kempo\api\extensions\available\GET.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"src\\kempo\\api\\extensions\\available\\GET.js","names":["currentUserHasPermission","readFile","existsSync","join","knownExtensionsPath","dirname","async","request","response","token","cookies","session_token","permError","hasPermission","status","code","json","error","msg","knownExtensions","JSON","parse","pkgPath","process","cwd","projectPkg","allDeps","dependencies","devDependencies","nodeModulesPath","available","depName","Object","entries","kempoConfigPath","depPkgPath","depPkg","known","find","k","name","push","version","description","author","items","total","length"],"sources":["0"],"sourcesContent":["import currentUserHasPermission from '../../../../../server/utils/permissions/currentUserHasPermission.js';\r\nimport { readFile } from 'fs/promises';\r\nimport { existsSync } from 'fs';\r\nimport { join } from 'path';\r\n\r\nconst knownExtensionsPath = join(import.meta.dirname, '../../../admin/known-extensions.json');\r\n\r\nexport default async (request, response) => {\r\n const token = request.cookies.session_token;\r\n const [permError, hasPermission] = await currentUserHasPermission(token, 'system:extensions:read');\r\n\r\n if(permError){\r\n return response.status(permError.code).json({ error: permError.msg });\r\n }\r\n\r\n if(!hasPermission){\r\n return response.status(403).json({ error: 'Insufficient permissions' });\r\n }\r\n\r\n let knownExtensions = [];\r\n if(existsSync(knownExtensionsPath)){\r\n knownExtensions = JSON.parse(await readFile(knownExtensionsPath, 'utf-8'));\r\n }\r\n\r\n const pkgPath = join(process.cwd(), 'package.json');\r\n const projectPkg = JSON.parse(await readFile(pkgPath, 'utf-8'));\r\n const allDeps = {\r\n ...projectPkg.dependencies,\r\n ...projectPkg.devDependencies,\r\n };\r\n\r\n const nodeModulesPath = join(process.cwd(), 'node_modules');\r\n const available = [];\r\n\r\n for(const [depName] of Object.entries(allDeps)){\r\n try {\r\n const kempoConfigPath = join(nodeModulesPath, depName, 'kempo-config.json');\r\n if(!existsSync(kempoConfigPath)) continue;\r\n const depPkgPath = join(nodeModulesPath, depName, 'package.json');\r\n const depPkg = JSON.parse(await readFile(depPkgPath, 'utf-8'));\r\n const known = knownExtensions.find(k => k.name === depName);\r\n available.push({\r\n name: depName,\r\n version: depPkg.version,\r\n description: depPkg.description || known?.description || '',\r\n author: depPkg.author || known?.author || '',\r\n });\r\n } catch {}\r\n }\r\n\r\n response.json({ items: available, total: available.length });\r\n};\r\n"],"mappings":"OAAOA,MAA8B,yFAC5BC,MAAgB,mCAChBC,MAAkB,oBAClBC,MAAY,OAErB,MAAMC,EAAsBD,cAAiBE,QAAS,uDAEvCC,MAAOC,EAASC,KAC7B,MAAMC,EAAQF,EAAQG,QAAQC,eACvBC,EAAWC,SAAuBb,EAAyBS,EAAO,0BAEzE,GAAGG,EACD,OAAOJ,EAASM,OAAOF,EAAUG,MAAMC,KAAK,CAAEC,MAAOL,EAAUM,MAGjE,IAAIL,EACF,OAAOL,EAASM,OAAO,KAAKE,KAAK,CAAEC,MAAO,6BAG5C,IAAIE,EAAkB,GACnBjB,EAAWE,KACZe,EAAkBC,KAAKC,YAAYpB,EAASG,EAAqB,WAGnE,MAAMkB,EAAUnB,EAAKoB,QAAQC,MAAO,gBAC9BC,EAAaL,KAAKC,YAAYpB,EAASqB,EAAS,UAChDI,EAAU,IACXD,EAAWE,gBACXF,EAAWG,iBAGVC,EAAkB1B,EAAKoB,QAAQC,MAAO,gBACtCM,EAAY,GAElB,IAAI,MAAOC,KAAYC,OAAOC,QAAQP,GACpC,IACE,MAAMQ,EAAkB/B,EAAK0B,EAAiBE,EAAS,qBACvD,IAAI7B,EAAWgC,GAAkB,SACjC,MAAMC,EAAahC,EAAK0B,EAAiBE,EAAS,gBAC5CK,EAAShB,KAAKC,YAAYpB,EAASkC,EAAY,UAC/CE,EAAQlB,EAAgBmB,KAAKC,GAAKA,EAAEC,OAAST,GACnDD,EAAUW,KAAK,CACbD,KAAMT,EACNW,QAASN,EAAOM,QAChBC,YAAaP,EAAOO,aAAeN,GAAOM,aAAe,GACzDC,OAAQR,EAAOQ,QAAUP,GAAOO,QAAU,IAE9C,CAAE,MAAO,CAGXpC,EAASQ,KAAK,CAAE6B,MAAOf,EAAWgB,MAAOhB,EAAUiB","ignoreList":[]}
1
+ {"version":3,"file":"src\\kempo\\api\\extensions\\available\\GET.js","names":["currentUserHasPermission","readFile","existsSync","join","async","request","response","token","cookies","session_token","permError","hasPermission","status","code","json","error","msg","projectPkg","JSON","parse","process","cwd","allDeps","dependencies","devDependencies","nodeModulesPath","available","depName","Object","entries","depPkg","push","name","version","description","author","items","total","length"],"sources":["0"],"sourcesContent":["import currentUserHasPermission from '../../../../../server/utils/permissions/currentUserHasPermission.js';\nimport { readFile } from 'fs/promises';\nimport { existsSync } from 'fs';\nimport { join } from 'path';\n\n/*\n The extension packages already downloaded into this site (in node_modules, declared as dependencies,\n with a kempo-config.json) and so installable without a download. Extensions to browse and download\n come from the marketplace: see /kempo/api/extensions/known.\n*/\nexport default async (request, response) => {\n const token = request.cookies.session_token;\n const [permError, hasPermission] = await currentUserHasPermission(token, 'system:extensions:read');\n\n if(permError){\n return response.status(permError.code).json({ error: permError.msg });\n }\n\n if(!hasPermission){\n return response.status(403).json({ error: 'Insufficient permissions' });\n }\n\n const projectPkg = JSON.parse(await readFile(join(process.cwd(), 'package.json'), 'utf-8'));\n const allDeps = {\n ...projectPkg.dependencies,\n ...projectPkg.devDependencies,\n };\n\n const nodeModulesPath = join(process.cwd(), 'node_modules');\n const available = [];\n\n for(const [depName] of Object.entries(allDeps)){\n try {\n if(!existsSync(join(nodeModulesPath, depName, 'kempo-config.json'))) continue;\n const depPkg = JSON.parse(await readFile(join(nodeModulesPath, depName, 'package.json'), 'utf-8'));\n available.push({\n name: depName,\n version: depPkg.version,\n description: depPkg.description || '',\n author: (typeof depPkg.author === 'object' ? depPkg.author?.name : depPkg.author) || '',\n });\n } catch {}\n }\n\n response.json({ items: available, total: available.length });\n};\n"],"mappings":"OAAOA,MAA8B,yFAC5BC,MAAgB,mCAChBC,MAAkB,oBAClBC,MAAY,sBAONC,MAAOC,EAASC,KAC7B,MAAMC,EAAQF,EAAQG,QAAQC,eACvBC,EAAWC,SAAuBX,EAAyBO,EAAO,0BAEzE,GAAGG,EACD,OAAOJ,EAASM,OAAOF,EAAUG,MAAMC,KAAK,CAAEC,MAAOL,EAAUM,MAGjE,IAAIL,EACF,OAAOL,EAASM,OAAO,KAAKE,KAAK,CAAEC,MAAO,6BAG5C,MAAME,EAAaC,KAAKC,YAAYlB,EAASE,EAAKiB,QAAQC,MAAO,gBAAiB,UAC5EC,EAAU,IACXL,EAAWM,gBACXN,EAAWO,iBAGVC,EAAkBtB,EAAKiB,QAAQC,MAAO,gBACtCK,EAAY,GAElB,IAAI,MAAOC,KAAYC,OAAOC,QAAQP,GACpC,IACE,IAAIpB,EAAWC,EAAKsB,EAAiBE,EAAS,sBAAuB,SACrE,MAAMG,EAASZ,KAAKC,YAAYlB,EAASE,EAAKsB,EAAiBE,EAAS,gBAAiB,UACzFD,EAAUK,KAAK,CACbC,KAAML,EACNM,QAASH,EAAOG,QAChBC,YAAaJ,EAAOI,aAAe,GACnCC,QAAkC,iBAAlBL,EAAOK,OAAsBL,EAAOK,QAAQH,KAAOF,EAAOK,SAAW,IAEzF,CAAE,MAAO,CAGX7B,EAASQ,KAAK,CAAEsB,MAAOV,EAAWW,MAAOX,EAAUY","ignoreList":[]}
@@ -1,2 +1,2 @@
1
- import s from"../../../../../server/utils/permissions/currentUserHasPermission.js";import{readFile as t}from"fs/promises";import{existsSync as o}from"fs";import{join as r}from"path";const e=r(import.meta.dirname,"../../../admin/known-extensions.json");export default async(r,n)=>{const i=r.cookies.session_token,[m,a]=await s(i,"system:extensions:read");if(m)return n.status(m.code).json({error:m.msg});if(!a)return n.status(403).json({error:"Insufficient permissions"});if(!o(e))return n.json({items:[],total:0});const f=JSON.parse(await t(e,"utf-8"));n.json({items:f,total:f.length})};
1
+ import s from"../../../../../server/utils/permissions/currentUserHasPermission.js";import e from"../../../../../server/utils/extensions/getMarketplaceClient.js";import t from"../../../../../server/utils/extensions/getSiteInstallId.js";import n from"../../../../../server/utils/extensions/getExtension.js";export default async(i,r)=>{const o=i.cookies.session_token,[a,l]=await s(o,"system:extensions:read");if(a)return r.status(a.code).json({error:a.msg});if(!l)return r.status(403).json({error:"Insufficient permissions"});const m=await e(),{name:u,search:c,sort:f,limit:d,offset:j}=i.query;if(u){const[s,e]=await m.details(u);if(s)return r.status(s.code).json({error:s.msg});const[,i]=await n({name:u});let o=null;if(i){const[,s]=await t(),[,e]=s?await m.siteRating({installId:s,extension:u}):[null,null];o=e?.rating??null}return r.json({item:e,local:i?{installed:!0,version:i.version,enabled:i.enabled}:{installed:!1},myRating:o})}const[g,p]=await m.list({search:c,sort:f,limit:d,offset:j});if(g)return r.status(g.code).json({error:g.msg});r.json(p)};
2
2
  //# sourceMappingURL=C:\Users\dusti\dev\kempo\dist\kempo\api\extensions\known\GET.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"src\\kempo\\api\\extensions\\known\\GET.js","names":["currentUserHasPermission","readFile","existsSync","join","knownExtensionsPath","dirname","async","request","response","token","cookies","session_token","permError","hasPermission","status","code","json","error","msg","items","total","JSON","parse","length"],"sources":["0"],"sourcesContent":["import currentUserHasPermission from '../../../../../server/utils/permissions/currentUserHasPermission.js';\r\nimport { readFile } from 'fs/promises';\r\nimport { existsSync } from 'fs';\r\nimport { join } from 'path';\r\n\r\nconst knownExtensionsPath = join(import.meta.dirname, '../../../admin/known-extensions.json');\r\n\r\nexport default async (request, response) => {\r\n const token = request.cookies.session_token;\r\n const [permError, hasPermission] = await currentUserHasPermission(token, 'system:extensions:read');\r\n\r\n if(permError){\r\n return response.status(permError.code).json({ error: permError.msg });\r\n }\r\n\r\n if(!hasPermission){\r\n return response.status(403).json({ error: 'Insufficient permissions' });\r\n }\r\n\r\n if(!existsSync(knownExtensionsPath)){\r\n return response.json({ items: [], total: 0 });\r\n }\r\n\r\n const items = JSON.parse(await readFile(knownExtensionsPath, 'utf-8'));\r\n response.json({ items, total: items.length });\r\n};\r\n"],"mappings":"OAAOA,MAA8B,yFAC5BC,MAAgB,mCAChBC,MAAkB,oBAClBC,MAAY,OAErB,MAAMC,EAAsBD,cAAiBE,QAAS,uDAEvCC,MAAOC,EAASC,KAC7B,MAAMC,EAAQF,EAAQG,QAAQC,eACvBC,EAAWC,SAAuBb,EAAyBS,EAAO,0BAEzE,GAAGG,EACD,OAAOJ,EAASM,OAAOF,EAAUG,MAAMC,KAAK,CAAEC,MAAOL,EAAUM,MAGjE,IAAIL,EACF,OAAOL,EAASM,OAAO,KAAKE,KAAK,CAAEC,MAAO,6BAG5C,IAAIf,EAAWE,GACb,OAAOI,EAASQ,KAAK,CAAEG,MAAO,GAAIC,MAAO,IAG3C,MAAMD,EAAQE,KAAKC,YAAYrB,EAASG,EAAqB,UAC7DI,EAASQ,KAAK,CAAEG,QAAOC,MAAOD,EAAMI","ignoreList":[]}
1
+ {"version":3,"file":"src\\kempo\\api\\extensions\\known\\GET.js","names":["currentUserHasPermission","getMarketplaceClient","getSiteInstallId","getExtension","async","request","response","token","cookies","session_token","permError","hasPermission","status","code","json","error","msg","client","name","search","sort","limit","offset","query","item","details","local","mine","installId","given","siteRating","extension","rating","installed","version","enabled","myRating","page","list"],"sources":["0"],"sourcesContent":["import currentUserHasPermission from '../../../../../server/utils/permissions/currentUserHasPermission.js';\nimport getMarketplaceClient from '../../../../../server/utils/extensions/getMarketplaceClient.js';\nimport getSiteInstallId from '../../../../../server/utils/extensions/getSiteInstallId.js';\nimport getExtension from '../../../../../server/utils/extensions/getExtension.js';\n\n/*\n The extension marketplace, through this site's server (the browser never calls it directly).\n\n GET /kempo/api/extensions/known?search=&sort=&limit=&offset= a page of cards\n GET /kempo/api/extensions/known?name=<name> one extension in full, plus whether\n it is installed here and this site's\n own rating of it\n*/\nexport default async (request, response) => {\n const token = request.cookies.session_token;\n const [permError, hasPermission] = await currentUserHasPermission(token, 'system:extensions:read');\n\n if(permError){\n return response.status(permError.code).json({ error: permError.msg });\n }\n\n if(!hasPermission){\n return response.status(403).json({ error: 'Insufficient permissions' });\n }\n\n const client = await getMarketplaceClient();\n const { name, search, sort, limit, offset } = request.query;\n\n if(name){\n const [error, item] = await client.details(name);\n if(error){\n return response.status(error.code).json({ error: error.msg });\n }\n\n const [, local] = await getExtension({ name });\n let mine = null;\n if(local){\n const [, installId] = await getSiteInstallId();\n const [, given] = installId ? await client.siteRating({ installId, extension: name }) : [null, null];\n mine = given?.rating ?? null;\n }\n\n return response.json({\n item,\n local: local ? { installed: true, version: local.version, enabled: local.enabled } : { installed: false },\n myRating: mine,\n });\n }\n\n const [error, page] = await client.list({ search, sort, limit, offset });\n if(error){\n return response.status(error.code).json({ error: error.msg });\n }\n\n response.json(page);\n};\n"],"mappings":"OAAOA,MAA8B,6EAC9BC,MAA0B,wEAC1BC,MAAsB,oEACtBC,MAAkB,wEAUVC,MAAOC,EAASC,KAC7B,MAAMC,EAAQF,EAAQG,QAAQC,eACvBC,EAAWC,SAAuBX,EAAyBO,EAAO,0BAEzE,GAAGG,EACD,OAAOJ,EAASM,OAAOF,EAAUG,MAAMC,KAAK,CAAEC,MAAOL,EAAUM,MAGjE,IAAIL,EACF,OAAOL,EAASM,OAAO,KAAKE,KAAK,CAAEC,MAAO,6BAG5C,MAAME,QAAehB,KACfiB,KAAEA,EAAIC,OAAEA,EAAMC,KAAEA,EAAIC,MAAEA,EAAKC,OAAEA,GAAWjB,EAAQkB,MAEtD,GAAGL,EAAK,CACN,MAAOH,EAAOS,SAAcP,EAAOQ,QAAQP,GAC3C,GAAGH,EACD,OAAOT,EAASM,OAAOG,EAAMF,MAAMC,KAAK,CAAEC,MAAOA,EAAMC,MAGzD,MAAO,CAAEU,SAAevB,EAAa,CAAEe,SACvC,IAAIS,EAAO,KACX,GAAGD,EAAM,CACP,MAAO,CAAEE,SAAmB1B,KACrB,CAAE2B,GAASD,QAAkBX,EAAOa,WAAW,CAAEF,YAAWG,UAAWb,IAAU,CAAC,KAAM,MAC/FS,EAAOE,GAAOG,QAAU,IAC1B,CAEA,OAAO1B,EAASQ,KAAK,CACnBU,OACAE,MAAOA,EAAQ,CAAEO,WAAW,EAAMC,QAASR,EAAMQ,QAASC,QAAST,EAAMS,SAAY,CAAEF,WAAW,GAClGG,SAAUT,GAEd,CAEA,MAAOZ,EAAOsB,SAAcpB,EAAOqB,KAAK,CAAEnB,SAAQC,OAAMC,QAAOC,WAC/D,GAAGP,EACD,OAAOT,EAASM,OAAOG,EAAMF,MAAMC,KAAK,CAAEC,MAAOA,EAAMC,MAGzDV,EAASQ,KAAKuB","ignoreList":[]}
@@ -0,0 +1,2 @@
1
+ import s from"../../../../../server/utils/permissions/currentUserHasPermission.js";import e from"../../../../../server/utils/extensions/getMarketplaceClient.js";import t from"../../../../../server/utils/extensions/getSiteInstallId.js";import r from"../../../../../server/utils/extensions/getExtension.js";export default async(n,o)=>{const i=n.cookies.session_token,[a,u]=await s(i,"system:extensions:install");if(a)return o.status(a.code).json({error:a.msg});if(!u)return o.status(403).json({error:"Insufficient permissions"});const{name:m,rating:l}=n.body||{};if(!Number.isInteger(l)||l<1||l>5)return o.status(400).json({error:"rating must be a whole number from 1 to 5"});const[c]=await r({name:m});if(c)return o.status(404===c.code?409:c.code).json({error:404===c.code?"Only an extension installed on this site can be rated":c.msg});const[f,d]=await t();if(f)return o.status(f.code).json({error:f.msg});const j=await e();await j.report({installId:d,extension:m});const[g,p]=await j.rate({installId:d,extension:m,value:l});if(g)return o.status(g.code).json({error:g.msg});o.json(p)};
2
+ //# sourceMappingURL=C:\Users\dusti\dev\kempo\dist\kempo\api\extensions\rating\PUT.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"src\\kempo\\api\\extensions\\rating\\PUT.js","names":["currentUserHasPermission","getMarketplaceClient","getSiteInstallId","getExtension","async","request","response","token","cookies","session_token","permError","hasPermission","status","code","json","error","msg","name","rating","body","Number","isInteger","localError","idError","installId","client","report","extension","data","rate","value"],"sources":["0"],"sourcesContent":["import currentUserHasPermission from '../../../../../server/utils/permissions/currentUserHasPermission.js';\nimport getMarketplaceClient from '../../../../../server/utils/extensions/getMarketplaceClient.js';\nimport getSiteInstallId from '../../../../../server/utils/extensions/getSiteInstallId.js';\nimport getExtension from '../../../../../server/utils/extensions/getExtension.js';\n\n/*\n PUT /kempo/api/extensions/rating { name, rating: 1-5 }\n\n This site's rating of an extension it has installed. One per extension; sending it again changes it.\n The marketplace only accepts it once the install is a minute old, and says so if it is not.\n*/\nexport default async (request, response) => {\n const token = request.cookies.session_token;\n const [permError, hasPermission] = await currentUserHasPermission(token, 'system:extensions:install');\n\n if(permError){\n return response.status(permError.code).json({ error: permError.msg });\n }\n\n if(!hasPermission){\n return response.status(403).json({ error: 'Insufficient permissions' });\n }\n\n const { name, rating } = request.body || {};\n\n if(!Number.isInteger(rating) || rating < 1 || rating > 5){\n return response.status(400).json({ error: 'rating must be a whole number from 1 to 5' });\n }\n\n const [localError] = await getExtension({ name });\n if(localError){\n return response.status(localError.code === 404 ? 409 : localError.code).json({ error: localError.code === 404 ? 'Only an extension installed on this site can be rated' : localError.msg });\n }\n\n const [idError, installId] = await getSiteInstallId();\n if(idError){\n return response.status(idError.code).json({ error: idError.msg });\n }\n\n const client = await getMarketplaceClient();\n\n /*\n A site that installed before the marketplace existed was never counted. Reporting is idempotent, so\n do it now: otherwise the marketplace would refuse the rating as \"not installed\".\n */\n await client.report({ installId, extension: name });\n\n const [error, data] = await client.rate({ installId, extension: name, value: rating });\n if(error){\n return response.status(error.code).json({ error: error.msg });\n }\n\n response.json(data);\n};\n"],"mappings":"OAAOA,MAA8B,6EAC9BC,MAA0B,wEAC1BC,MAAsB,oEACtBC,MAAkB,wEAQVC,MAAOC,EAASC,KAC7B,MAAMC,EAAQF,EAAQG,QAAQC,eACvBC,EAAWC,SAAuBX,EAAyBO,EAAO,6BAEzE,GAAGG,EACD,OAAOJ,EAASM,OAAOF,EAAUG,MAAMC,KAAK,CAAEC,MAAOL,EAAUM,MAGjE,IAAIL,EACF,OAAOL,EAASM,OAAO,KAAKE,KAAK,CAAEC,MAAO,6BAG5C,MAAME,KAAEA,EAAIC,OAAEA,GAAWb,EAAQc,MAAQ,CAAC,EAE1C,IAAIC,OAAOC,UAAUH,IAAWA,EAAS,GAAKA,EAAS,EACrD,OAAOZ,EAASM,OAAO,KAAKE,KAAK,CAAEC,MAAO,8CAG5C,MAAOO,SAAoBnB,EAAa,CAAEc,SAC1C,GAAGK,EACD,OAAOhB,EAASM,OAA2B,MAApBU,EAAWT,KAAe,IAAMS,EAAWT,MAAMC,KAAK,CAAEC,MAA2B,MAApBO,EAAWT,KAAe,wDAA0DS,EAAWN,MAGvL,MAAOO,EAASC,SAAmBtB,IACnC,GAAGqB,EACD,OAAOjB,EAASM,OAAOW,EAAQV,MAAMC,KAAK,CAAEC,MAAOQ,EAAQP,MAG7D,MAAMS,QAAexB,UAMfwB,EAAOC,OAAO,CAAEF,YAAWG,UAAWV,IAE5C,MAAOF,EAAOa,SAAcH,EAAOI,KAAK,CAAEL,YAAWG,UAAWV,EAAMa,MAAOZ,IAC7E,GAAGH,EACD,OAAOT,EAASM,OAAOG,EAAMF,MAAMC,KAAK,CAAEC,MAAOA,EAAMC,MAGzDV,EAASQ,KAAKc","ignoreList":[]}
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path fill="currentColor" d="M560-440q-50 0-85-35t-35-85q0-50 35-85t85-35q50 0 85 35t35 85q0 50-35 85t-85 35ZM280-320q-33 0-56.5-23.5T200-400v-320q0-33 23.5-56.5T280-800h560q33 0 56.5 23.5T920-720v320q0 33-23.5 56.5T840-320H280Zm80-80h400q0-33 23.5-56.5T840-480v-160q-33 0-56.5-23.5T760-720H360q0 33-23.5 56.5T280-640v160q33 0 56.5 23.5T360-400Zm440 240H120q-33 0-56.5-23.5T40-240v-440h80v440h680v80ZM280-400v-320 320Z"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path fill="currentColor" d="M373-253q-93-93-93-227t93-227q93-93 227-93t227 93q93 93 93 227t-93 227q-93 93-227 93t-227-93Zm-93 83q-106-28-173-114T40-480q0-110 67-196t173-114v84q-72 25-116 87t-44 139q0 77 44 139t116 87v84Zm320-310Zm170 170q70-70 70-170t-70-170q-70-70-170-70t-170 70q-70 70-70 170t70 170q70 70 170 70t170-70Z"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path fill="currentColor" d="M200-120q-33 0-56.5-23.5T120-200v-560q0-33 23.5-56.5T200-840h560q33 0 56.5 23.5T840-760v80h-80v-80H200v560h560v-80h80v80q0 33-23.5 56.5T760-120H200Zm320-160q-33 0-56.5-23.5T440-360v-240q0-33 23.5-56.5T520-680h280q33 0 56.5 23.5T880-600v240q0 33-23.5 56.5T800-280H520Zm280-80v-240H520v240h280Zm-160-60q25 0 42.5-17.5T700-480q0-25-17.5-42.5T640-540q-25 0-42.5 17.5T580-480q0 25 17.5 42.5T640-420Z"/></svg>
package/dist/kempo/sdk.js CHANGED
@@ -1,2 +1,2 @@
1
- import{get as e,post as s,put as o,patch as t,del as n}from"./fetch.js";const a="/kempo/api";export const register=async({email:e,password:o,name:t})=>s(`${a}/auth/register/email`,{email:e,password:o,name:t});export const login=async({email:e,password:o})=>s(`${a}/auth/login/email`,{email:e,password:o});export const logout=async()=>s(`${a}/auth/logout`,{});export const getSession=async()=>e(`${a}/auth/session`);export const forgotPassword=async({email:e})=>s(`${a}/forgot-password`,{email:e});export const resetPassword=async({token:e,password:o,logoutAll:t=!1})=>s(`${a}/auth/reset-password`,{token:e,newPassword:o,logoutAll:t});export const changePassword=async({currentPassword:e,newPassword:o,logoutAll:t})=>s(`${a}/auth/change-password`,{currentPassword:e,newPassword:o,logoutAll:t});export const verifyEmail=async({token:e})=>s(`${a}/auth/verify-email`,{token:e});export const currentUserHasPermission=async({permission:s})=>e(`${a}/user/current/permissions`,{permission:s});export const currentUserHasAllPermissions=async({permissions:s})=>e(`${a}/user/current/permissions/all`,{permissions:s});export const currentUserHasSomePermissions=async({permissions:s})=>e(`${a}/user/current/permissions/some`,{permissions:s});export const getAllCurrentUserPermissions=async()=>e(`${a}/user/current/permissions/list`);export const userHasPermission=async({userid:s,permission:o})=>e(`${a}/user/${s}/permissions`,{permission:o});export const userHasAllPermissions=async({userid:s,permissions:o})=>e(`${a}/user/${s}/permissions/all`,{permissions:o});export const userHasSomePermissions=async({userid:s,permissions:o})=>e(`${a}/user/${s}/permissions/some`,{permissions:o});export const getAllUserPermissions=async({userid:s})=>e(`${a}/user/${s}/permissions/list`);export const getUsers=async({limit:s,offset:o}={})=>e(`${a}/user`,{limit:s,offset:o});export const searchUsers=async({q:s,limit:o,offset:t,inGroup:n,notInGroup:r}={})=>e(`${a}/user/search`,{q:s,limit:o,offset:t,inGroup:n,notInGroup:r});export const createUser=async({name:e,email:o,password:t,emailVerified:n})=>s(`${a}/user/create`,{name:e,email:o,password:t,emailVerified:n});export const deleteUsers=async e=>n(`${a}/user`,{ids:e});export const updateUser=async({id:e,name:s,email:o,emailVerified:n,createdAt:r})=>t(`${a}/user`,{id:e,name:s,email:o,emailVerified:n,createdAt:r});export const getUser=async s=>e(`${a}/user/${s}`);export const getUserSessions=async(s,{limit:o,offset:t}={})=>e(`${a}/user/${s}/sessions`,{limit:o,offset:t});export const deleteUserSession=async(e,s)=>n(`${a}/user/${e}/sessions`,{sessionToken:s});export const deleteExpiredUserSessions=async e=>n(`${a}/user/${e}/sessions/expired`);export const getUserGroups=async(s,{limit:o,offset:t}={})=>e(`${a}/user/${s}/groups`,{limit:o,offset:t});export const addUserToGroup=async(e,o)=>s(`${a}/user/${e}/groups`,{groupName:o});export const removeUserFromGroup=async(e,s)=>n(`${a}/user/${e}/groups`,{groupName:s});export const listGroups=async({limit:s,offset:o,owner:t}={})=>e(`${a}/groups`,{limit:s,offset:o,owner:t});export const createGroup=async({name:e,description:o})=>s(`${a}/groups`,{name:e,description:o});export const updateGroup=async({name:e,newName:s,description:o})=>t(`${a}/groups`,{name:e,newName:s,description:o});export const deleteGroups=async e=>n(`${a}/groups`,{names:e});export const getGroup=async s=>e(`${a}/groups/${encodeURIComponent(s)}`);export const getGroupMembers=async(s,{limit:o,offset:t}={})=>e(`${a}/groups/${encodeURIComponent(s)}/members`,{limit:o,offset:t});export const addMemberToGroup=async(e,o)=>s(`${a}/groups/${encodeURIComponent(e)}/members`,{userId:o});export const removeMemberFromGroup=async(e,s)=>n(`${a}/groups/${encodeURIComponent(e)}/members`,{userId:s});export const getGroupPermissions=async s=>e(`${a}/groups/${encodeURIComponent(s)}/permissions`);export const addPermissionToGroup=async(e,o)=>s(`${a}/groups/${encodeURIComponent(e)}/permissions`,{permissionName:o});export const removePermissionFromGroup=async(e,s)=>n(`${a}/groups/${encodeURIComponent(e)}/permissions`,{permissionName:s});export const listPermissions=async({limit:s,offset:o,owner:t}={})=>e(`${a}/permissions`,{limit:s,offset:o,owner:t});export const createPermissions=async e=>s(`${a}/permissions`,{permissions:e});export const updatePermission=async({name:e,description:s})=>t(`${a}/permissions`,{name:e,description:s});export const deletePermissions=async e=>n(`${a}/permissions`,{names:e});export const getSetting=async(s,o)=>e(`${a}/settings/${encodeURIComponent(s)}/${encodeURIComponent(o)}`);export const listSettings=async({owner:s,limit:o,offset:t}={})=>e(`${a}/settings/${encodeURIComponent(s)}`,{limit:o,offset:t});export const setSetting=async(e,o,t)=>s(`${a}/settings/${encodeURIComponent(e)}/${encodeURIComponent(o)}`,t);export const deleteSetting=async(e,s)=>n(`${a}/settings/${encodeURIComponent(e)}/${encodeURIComponent(s)}`);export const listPages=async({owner:s,showHidden:o,offset:t,limit:n}={})=>e(`${a}/pages`,{owner:s,showHidden:o,offset:t,limit:n});export const rescanPages=async()=>s(`${a}/pages/rescan`,{});export const listTemplates=async()=>e(`${a}/templates`);export const listDirectories=async()=>e(`${a}/pages/directories`);export const getPage=async s=>e(`${a}/pages/file`,{file:s});export const createPage=async({directory:e,name:o,template:t})=>s(`${a}/pages`,{directory:e,name:o,template:t});export const updatePage=async({file:e,name:s,title:t,description:n,author:r,template:i,contents:c,extraMetadata:l})=>o(`${a}/pages/file`,{file:e,name:s,title:t,description:n,author:r,template:i,contents:c,extraMetadata:l});export const deletePages=async e=>n(`${a}/pages`,{files:e});export const disablePage=async e=>o(`${a}/pages/disable`,{file:e});export const enablePage=async e=>o(`${a}/pages/enable`,{file:e});export const movePage=async({file:e,newFile:s})=>t(`${a}/pages/file`,{file:e,newFile:s});export const searchPagesByMetadata=async s=>e(`${a}/pages/search`,{query:JSON.stringify(s)});export const setPageLocked=async({file:e,locked:s})=>o(`${a}/pages/lock`,{file:e,locked:s});export const getTemplate=async s=>e(`${a}/templates/file`,{file:s});export const createTemplate=async({directory:e,name:o,copyFrom:t})=>s(`${a}/templates`,{directory:e,name:o,copyFrom:t});export const updateTemplate=async({file:e,name:s,author:t,markup:n})=>o(`${a}/templates/file`,{file:e,name:s,author:t,markup:n});export const deleteTemplates=async e=>n(`${a}/templates`,{files:e});export const disableTemplate=async e=>o(`${a}/templates/disable`,{file:e});export const enableTemplate=async e=>o(`${a}/templates/enable`,{file:e});export const moveTemplate=async({file:e,newFile:s})=>t(`${a}/templates/file`,{file:e,newFile:s});export const setTemplateLocked=async({file:e,locked:s})=>o(`${a}/templates/lock`,{file:e,locked:s});export const listFragments=async()=>e(`${a}/fragments`);export const getFragment=async s=>e(`${a}/fragments/file`,{file:s});export const createFragment=async({directory:e,name:o})=>s(`${a}/fragments`,{directory:e,name:o});export const updateFragment=async({file:e,author:s,markup:t})=>o(`${a}/fragments/file`,{file:e,author:s,markup:t});export const deleteFragments=async e=>n(`${a}/fragments`,{files:e});export const moveFragment=async({file:e,newFile:s})=>t(`${a}/fragments/file`,{file:e,newFile:s});export const disableFragment=async e=>o(`${a}/fragments/disable`,{file:e});export const enableFragment=async e=>o(`${a}/fragments/enable`,{file:e});export const setFragmentLocked=async({file:e,locked:s})=>o(`${a}/fragments/lock`,{file:e,locked:s});export const listGlobalContent=async()=>e(`${a}/globals`);export const getGlobalContent=async s=>e(`${a}/globals/entry`,{id:s});export const createGlobalContent=async({name:e,location:o,priority:t})=>s(`${a}/globals`,{name:e,location:o,priority:t});export const updateGlobalContent=async({id:e,name:s,location:t,priority:n,markup:r})=>o(`${a}/globals/entry`,{id:e,name:s,location:t,priority:n,markup:r});export const deleteGlobalContent=async e=>n(`${a}/globals`,{ids:e});export const disableGlobalContent=async e=>o(`${a}/globals/disable`,{id:e});export const enableGlobalContent=async e=>o(`${a}/globals/enable`,{id:e});export const setGlobalContentLocked=async({id:e,locked:s})=>o(`${a}/globals/lock`,{id:e,locked:s});export const listExtensions=async({limit:s,offset:o}={})=>e(`${a}/extensions`,{limit:s,offset:o});export const listAvailableExtensions=async()=>e(`${a}/extensions/available`);export const listKnownExtensions=async()=>e(`${a}/extensions/known`);export const getDashboardWidgets=async()=>e(`${a}/dashboard/widgets`);export const getNotifications=async({unreadOnly:s=!1,limit:o,offset:t}={})=>e(`${a}/notifications`,{unreadOnly:s,limit:o,offset:t});export const getUnreadNotificationCount=async()=>e(`${a}/notifications/count`);export const markNotificationRead=async e=>s(`${a}/notifications/${encodeURIComponent(e)}/read`,{});export const markNotificationHandled=async e=>s(`${a}/notifications/${encodeURIComponent(e)}/handled`,{});export const markAllNotificationsRead=async()=>s(`${a}/notifications/read-all`,{});export const dismissNotification=async e=>n(`${a}/notifications/${encodeURIComponent(e)}`);export const listRealtimeConnections=async()=>e(`${a}/realtime/connections`);export const installExtension=async e=>s(`${a}/extensions`,{name:e});export const uninstallExtension=async(e,s=!1)=>n(`${a}/extensions`,{name:e,purgeData:s});export const enableExtension=async e=>s(`${a}/extensions/${encodeURIComponent(e)}/enable`,{});export const disableExtension=async e=>s(`${a}/extensions/${encodeURIComponent(e)}/disable`,{});export const listAdminGlobalContent=async()=>e(`${a}/admin-globals`);export const getAdminGlobalContent=async s=>e(`${a}/admin-globals/${encodeURIComponent(s)}`);export const createAdminGlobalContent=async({name:e,location:o,priority:t,owner:n,markup:r})=>s(`${a}/admin-globals`,{name:e,location:o,priority:t,owner:n,markup:r});export const updateAdminGlobalContent=async(e,{name:s,location:t,priority:n,markup:r})=>o(`${a}/admin-globals/${encodeURIComponent(e)}`,{name:s,location:t,priority:n,markup:r});export const deleteAdminGlobalContent=async e=>n(`${a}/admin-globals`,{ids:e});export const enableAdminGlobalContent=async e=>o(`${a}/admin-globals/${encodeURIComponent(e)}/enable`,{});export const disableAdminGlobalContent=async e=>o(`${a}/admin-globals/${encodeURIComponent(e)}/disable`,{});
1
+ import{get as e,post as s,put as o,patch as n,del as t}from"./fetch.js";const a="/kempo/api";export const register=async({email:e,password:o,name:n})=>s(`${a}/auth/register/email`,{email:e,password:o,name:n});export const login=async({email:e,password:o})=>s(`${a}/auth/login/email`,{email:e,password:o});export const logout=async()=>s(`${a}/auth/logout`,{});export const getSession=async()=>e(`${a}/auth/session`);export const forgotPassword=async({email:e})=>s(`${a}/forgot-password`,{email:e});export const resetPassword=async({token:e,password:o,logoutAll:n=!1})=>s(`${a}/auth/reset-password`,{token:e,newPassword:o,logoutAll:n});export const changePassword=async({currentPassword:e,newPassword:o,logoutAll:n})=>s(`${a}/auth/change-password`,{currentPassword:e,newPassword:o,logoutAll:n});export const verifyEmail=async({token:e})=>s(`${a}/auth/verify-email`,{token:e});export const currentUserHasPermission=async({permission:s})=>e(`${a}/user/current/permissions`,{permission:s});export const currentUserHasAllPermissions=async({permissions:s})=>e(`${a}/user/current/permissions/all`,{permissions:s});export const currentUserHasSomePermissions=async({permissions:s})=>e(`${a}/user/current/permissions/some`,{permissions:s});export const getAllCurrentUserPermissions=async()=>e(`${a}/user/current/permissions/list`);export const userHasPermission=async({userid:s,permission:o})=>e(`${a}/user/${s}/permissions`,{permission:o});export const userHasAllPermissions=async({userid:s,permissions:o})=>e(`${a}/user/${s}/permissions/all`,{permissions:o});export const userHasSomePermissions=async({userid:s,permissions:o})=>e(`${a}/user/${s}/permissions/some`,{permissions:o});export const getAllUserPermissions=async({userid:s})=>e(`${a}/user/${s}/permissions/list`);export const getUsers=async({limit:s,offset:o}={})=>e(`${a}/user`,{limit:s,offset:o});export const searchUsers=async({q:s,limit:o,offset:n,inGroup:t,notInGroup:r}={})=>e(`${a}/user/search`,{q:s,limit:o,offset:n,inGroup:t,notInGroup:r});export const createUser=async({name:e,email:o,password:n,emailVerified:t})=>s(`${a}/user/create`,{name:e,email:o,password:n,emailVerified:t});export const deleteUsers=async e=>t(`${a}/user`,{ids:e});export const updateUser=async({id:e,name:s,email:o,emailVerified:t,createdAt:r})=>n(`${a}/user`,{id:e,name:s,email:o,emailVerified:t,createdAt:r});export const getUser=async s=>e(`${a}/user/${s}`);export const getUserSessions=async(s,{limit:o,offset:n}={})=>e(`${a}/user/${s}/sessions`,{limit:o,offset:n});export const deleteUserSession=async(e,s)=>t(`${a}/user/${e}/sessions`,{sessionToken:s});export const deleteExpiredUserSessions=async e=>t(`${a}/user/${e}/sessions/expired`);export const getUserGroups=async(s,{limit:o,offset:n}={})=>e(`${a}/user/${s}/groups`,{limit:o,offset:n});export const addUserToGroup=async(e,o)=>s(`${a}/user/${e}/groups`,{groupName:o});export const removeUserFromGroup=async(e,s)=>t(`${a}/user/${e}/groups`,{groupName:s});export const listGroups=async({limit:s,offset:o,owner:n}={})=>e(`${a}/groups`,{limit:s,offset:o,owner:n});export const createGroup=async({name:e,description:o})=>s(`${a}/groups`,{name:e,description:o});export const updateGroup=async({name:e,newName:s,description:o})=>n(`${a}/groups`,{name:e,newName:s,description:o});export const deleteGroups=async e=>t(`${a}/groups`,{names:e});export const getGroup=async s=>e(`${a}/groups/${encodeURIComponent(s)}`);export const getGroupMembers=async(s,{limit:o,offset:n}={})=>e(`${a}/groups/${encodeURIComponent(s)}/members`,{limit:o,offset:n});export const addMemberToGroup=async(e,o)=>s(`${a}/groups/${encodeURIComponent(e)}/members`,{userId:o});export const removeMemberFromGroup=async(e,s)=>t(`${a}/groups/${encodeURIComponent(e)}/members`,{userId:s});export const getGroupPermissions=async s=>e(`${a}/groups/${encodeURIComponent(s)}/permissions`);export const addPermissionToGroup=async(e,o)=>s(`${a}/groups/${encodeURIComponent(e)}/permissions`,{permissionName:o});export const removePermissionFromGroup=async(e,s)=>t(`${a}/groups/${encodeURIComponent(e)}/permissions`,{permissionName:s});export const listPermissions=async({limit:s,offset:o,owner:n}={})=>e(`${a}/permissions`,{limit:s,offset:o,owner:n});export const createPermissions=async e=>s(`${a}/permissions`,{permissions:e});export const updatePermission=async({name:e,description:s})=>n(`${a}/permissions`,{name:e,description:s});export const deletePermissions=async e=>t(`${a}/permissions`,{names:e});export const getSetting=async(s,o)=>e(`${a}/settings/${encodeURIComponent(s)}/${encodeURIComponent(o)}`);export const listSettings=async({owner:s,limit:o,offset:n}={})=>e(`${a}/settings/${encodeURIComponent(s)}`,{limit:o,offset:n});export const setSetting=async(e,o,n)=>s(`${a}/settings/${encodeURIComponent(e)}/${encodeURIComponent(o)}`,n);export const deleteSetting=async(e,s)=>t(`${a}/settings/${encodeURIComponent(e)}/${encodeURIComponent(s)}`);export const listPages=async({owner:s,showHidden:o,offset:n,limit:t}={})=>e(`${a}/pages`,{owner:s,showHidden:o,offset:n,limit:t});export const rescanPages=async()=>s(`${a}/pages/rescan`,{});export const listTemplates=async()=>e(`${a}/templates`);export const listDirectories=async()=>e(`${a}/pages/directories`);export const getPage=async s=>e(`${a}/pages/file`,{file:s});export const createPage=async({directory:e,name:o,template:n})=>s(`${a}/pages`,{directory:e,name:o,template:n});export const updatePage=async({file:e,name:s,title:n,description:t,author:r,template:i,contents:c,extraMetadata:l})=>o(`${a}/pages/file`,{file:e,name:s,title:n,description:t,author:r,template:i,contents:c,extraMetadata:l});export const deletePages=async e=>t(`${a}/pages`,{files:e});export const disablePage=async e=>o(`${a}/pages/disable`,{file:e});export const enablePage=async e=>o(`${a}/pages/enable`,{file:e});export const movePage=async({file:e,newFile:s})=>n(`${a}/pages/file`,{file:e,newFile:s});export const searchPagesByMetadata=async s=>e(`${a}/pages/search`,{query:JSON.stringify(s)});export const setPageLocked=async({file:e,locked:s})=>o(`${a}/pages/lock`,{file:e,locked:s});export const getTemplate=async s=>e(`${a}/templates/file`,{file:s});export const createTemplate=async({directory:e,name:o,copyFrom:n})=>s(`${a}/templates`,{directory:e,name:o,copyFrom:n});export const updateTemplate=async({file:e,name:s,author:n,markup:t})=>o(`${a}/templates/file`,{file:e,name:s,author:n,markup:t});export const deleteTemplates=async e=>t(`${a}/templates`,{files:e});export const disableTemplate=async e=>o(`${a}/templates/disable`,{file:e});export const enableTemplate=async e=>o(`${a}/templates/enable`,{file:e});export const moveTemplate=async({file:e,newFile:s})=>n(`${a}/templates/file`,{file:e,newFile:s});export const setTemplateLocked=async({file:e,locked:s})=>o(`${a}/templates/lock`,{file:e,locked:s});export const listFragments=async()=>e(`${a}/fragments`);export const getFragment=async s=>e(`${a}/fragments/file`,{file:s});export const createFragment=async({directory:e,name:o})=>s(`${a}/fragments`,{directory:e,name:o});export const updateFragment=async({file:e,author:s,markup:n})=>o(`${a}/fragments/file`,{file:e,author:s,markup:n});export const deleteFragments=async e=>t(`${a}/fragments`,{files:e});export const moveFragment=async({file:e,newFile:s})=>n(`${a}/fragments/file`,{file:e,newFile:s});export const disableFragment=async e=>o(`${a}/fragments/disable`,{file:e});export const enableFragment=async e=>o(`${a}/fragments/enable`,{file:e});export const setFragmentLocked=async({file:e,locked:s})=>o(`${a}/fragments/lock`,{file:e,locked:s});export const listGlobalContent=async()=>e(`${a}/globals`);export const getGlobalContent=async s=>e(`${a}/globals/entry`,{id:s});export const createGlobalContent=async({name:e,location:o,priority:n})=>s(`${a}/globals`,{name:e,location:o,priority:n});export const updateGlobalContent=async({id:e,name:s,location:n,priority:t,markup:r})=>o(`${a}/globals/entry`,{id:e,name:s,location:n,priority:t,markup:r});export const deleteGlobalContent=async e=>t(`${a}/globals`,{ids:e});export const disableGlobalContent=async e=>o(`${a}/globals/disable`,{id:e});export const enableGlobalContent=async e=>o(`${a}/globals/enable`,{id:e});export const setGlobalContentLocked=async({id:e,locked:s})=>o(`${a}/globals/lock`,{id:e,locked:s});export const listExtensions=async({limit:s,offset:o}={})=>e(`${a}/extensions`,{limit:s,offset:o});export const listAvailableExtensions=async()=>e(`${a}/extensions/available`);export const listKnownExtensions=async({search:s,sort:o,limit:n,offset:t}={})=>e(`${a}/extensions/known`,{search:s,sort:o,limit:n,offset:t});export const getKnownExtension=async s=>e(`${a}/extensions/known`,{name:s});export const rateExtension=async(e,s)=>o(`${a}/extensions/rating`,{name:e,rating:s});export const getDashboardWidgets=async()=>e(`${a}/dashboard/widgets`);export const getNotifications=async({unreadOnly:s=!1,limit:o,offset:n}={})=>e(`${a}/notifications`,{unreadOnly:s,limit:o,offset:n});export const getUnreadNotificationCount=async()=>e(`${a}/notifications/count`);export const markNotificationRead=async e=>s(`${a}/notifications/${encodeURIComponent(e)}/read`,{});export const markNotificationHandled=async e=>s(`${a}/notifications/${encodeURIComponent(e)}/handled`,{});export const markAllNotificationsRead=async()=>s(`${a}/notifications/read-all`,{});export const dismissNotification=async e=>t(`${a}/notifications/${encodeURIComponent(e)}`);export const listRealtimeConnections=async()=>e(`${a}/realtime/connections`);export const installExtension=async(e,{withDependencies:o=!1}={})=>s(`${a}/extensions`,{name:e,withDependencies:o});export const uninstallExtension=async(e,s=!1,{cascade:o=!1}={})=>t(`${a}/extensions`,{name:e,purgeData:s,cascade:o});export const enableExtension=async(e,{cascade:o=!1}={})=>s(`${a}/extensions/${encodeURIComponent(e)}/enable`,{cascade:o});export const getExtensionRequirements=async s=>e(`${a}/extensions/${encodeURIComponent(s)}/requirements`);export const disableExtension=async(e,{cascade:o=!1}={})=>s(`${a}/extensions/${encodeURIComponent(e)}/disable`,{cascade:o});export const getExtensionDependents=async(s,{includeDisabled:o=!1}={})=>e(`${a}/extensions/${encodeURIComponent(s)}/dependents`,{includeDisabled:o?"true":void 0});export const listAdminGlobalContent=async()=>e(`${a}/admin-globals`);export const getAdminGlobalContent=async s=>e(`${a}/admin-globals/${encodeURIComponent(s)}`);export const createAdminGlobalContent=async({name:e,location:o,priority:n,owner:t,markup:r})=>s(`${a}/admin-globals`,{name:e,location:o,priority:n,owner:t,markup:r});export const updateAdminGlobalContent=async(e,{name:s,location:n,priority:t,markup:r})=>o(`${a}/admin-globals/${encodeURIComponent(e)}`,{name:s,location:n,priority:t,markup:r});export const deleteAdminGlobalContent=async e=>t(`${a}/admin-globals`,{ids:e});export const enableAdminGlobalContent=async e=>o(`${a}/admin-globals/${encodeURIComponent(e)}/enable`,{});export const disableAdminGlobalContent=async e=>o(`${a}/admin-globals/${encodeURIComponent(e)}/disable`,{});
2
2
  //# sourceMappingURL=C:\Users\dusti\dev\kempo\dist\kempo\sdk.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"src\\kempo\\sdk.js","names":["get","post","put","patch","del","API_BASE","register","async","email","password","name","login","logout","getSession","forgotPassword","resetPassword","token","logoutAll","newPassword","changePassword","currentPassword","verifyEmail","currentUserHasPermission","permission","currentUserHasAllPermissions","permissions","currentUserHasSomePermissions","getAllCurrentUserPermissions","userHasPermission","userid","userHasAllPermissions","userHasSomePermissions","getAllUserPermissions","getUsers","limit","offset","searchUsers","q","inGroup","notInGroup","createUser","emailVerified","deleteUsers","ids","updateUser","id","createdAt","getUser","getUserSessions","deleteUserSession","sessionToken","deleteExpiredUserSessions","getUserGroups","addUserToGroup","groupName","removeUserFromGroup","listGroups","owner","createGroup","description","updateGroup","newName","deleteGroups","names","getGroup","encodeURIComponent","getGroupMembers","addMemberToGroup","userId","removeMemberFromGroup","getGroupPermissions","addPermissionToGroup","permissionName","removePermissionFromGroup","listPermissions","createPermissions","updatePermission","deletePermissions","getSetting","listSettings","setSetting","data","deleteSetting","listPages","showHidden","rescanPages","listTemplates","listDirectories","getPage","file","createPage","directory","template","updatePage","title","author","contents","extraMetadata","deletePages","files","disablePage","enablePage","movePage","newFile","searchPagesByMetadata","query","JSON","stringify","setPageLocked","locked","getTemplate","createTemplate","copyFrom","updateTemplate","markup","deleteTemplates","disableTemplate","enableTemplate","moveTemplate","setTemplateLocked","listFragments","getFragment","createFragment","updateFragment","deleteFragments","moveFragment","disableFragment","enableFragment","setFragmentLocked","listGlobalContent","getGlobalContent","createGlobalContent","location","priority","updateGlobalContent","deleteGlobalContent","disableGlobalContent","enableGlobalContent","setGlobalContentLocked","listExtensions","listAvailableExtensions","listKnownExtensions","getDashboardWidgets","getNotifications","unreadOnly","getUnreadNotificationCount","markNotificationRead","markNotificationHandled","markAllNotificationsRead","dismissNotification","listRealtimeConnections","installExtension","uninstallExtension","purgeData","enableExtension","disableExtension","listAdminGlobalContent","getAdminGlobalContent","createAdminGlobalContent","updateAdminGlobalContent","deleteAdminGlobalContent","enableAdminGlobalContent","disableAdminGlobalContent"],"sources":["0"],"sourcesContent":["import { get, post, put, patch, del } from './fetch.js';\nconst API_BASE = '/kempo/api';\n\nexport const register = async ({ email, password, name }) =>\n post(`${API_BASE}/auth/register/email`, { email, password, name });\n\nexport const login = async ({ email, password }) =>\n post(`${API_BASE}/auth/login/email`, { email, password });\n\nexport const logout = async () => post(`${API_BASE}/auth/logout`, {});\n\nexport const getSession = async () => get(`${API_BASE}/auth/session`);\n\nexport const forgotPassword = async ({ email }) =>\n post(`${API_BASE}/forgot-password`, { email });\n\nexport const resetPassword = async ({ token, password, logoutAll = false }) =>\n post(`${API_BASE}/auth/reset-password`, { token, newPassword: password, logoutAll });\n \nexport const changePassword = async ({ currentPassword, newPassword, logoutAll }) => \n post(`${API_BASE}/auth/change-password`, { currentPassword, newPassword, logoutAll });\n\nexport const verifyEmail = async ({ token }) =>\n post(`${API_BASE}/auth/verify-email`, { token });\n\nexport const currentUserHasPermission = async ({ permission }) =>\n get(`${API_BASE}/user/current/permissions`, { permission });\n\nexport const currentUserHasAllPermissions = async ({ permissions }) =>\n get(`${API_BASE}/user/current/permissions/all`, { permissions });\n\nexport const currentUserHasSomePermissions = async ({ permissions }) =>\n get(`${API_BASE}/user/current/permissions/some`, { permissions });\n\nexport const getAllCurrentUserPermissions = async () =>\n get(`${API_BASE}/user/current/permissions/list`);\n\nexport const userHasPermission = async ({ userid, permission }) =>\n get(`${API_BASE}/user/${userid}/permissions`, { permission });\n\nexport const userHasAllPermissions = async ({ userid, permissions }) =>\n get(`${API_BASE}/user/${userid}/permissions/all`, { permissions });\n\nexport const userHasSomePermissions = async ({ userid, permissions }) =>\n get(`${API_BASE}/user/${userid}/permissions/some`, { permissions });\n\nexport const getAllUserPermissions = async ({ userid }) =>\n get(`${API_BASE}/user/${userid}/permissions/list`);\n\nexport const getUsers = async ({ limit, offset } = {}) =>\n get(`${API_BASE}/user`, { limit, offset });\n\nexport const searchUsers = async ({ q, limit, offset, inGroup, notInGroup } = {}) =>\n get(`${API_BASE}/user/search`, { q, limit, offset, inGroup, notInGroup });\n\nexport const createUser = async ({ name, email, password, emailVerified }) =>\n post(`${API_BASE}/user/create`, { name, email, password, emailVerified });\n\nexport const deleteUsers = async (ids) =>\n del(`${API_BASE}/user`, { ids });\n\nexport const updateUser = async ({ id, name, email, emailVerified, createdAt }) =>\n patch(`${API_BASE}/user`, { id, name, email, emailVerified, createdAt });\n\nexport const getUser = async (userid) =>\n get(`${API_BASE}/user/${userid}`);\n\nexport const getUserSessions = async (userid, { limit, offset } = {}) =>\n get(`${API_BASE}/user/${userid}/sessions`, { limit, offset });\n\nexport const deleteUserSession = async (userid, sessionToken) =>\n del(`${API_BASE}/user/${userid}/sessions`, { sessionToken });\n\nexport const deleteExpiredUserSessions = async (userid) =>\n del(`${API_BASE}/user/${userid}/sessions/expired`);\n\nexport const getUserGroups = async (userid, { limit, offset } = {}) =>\n get(`${API_BASE}/user/${userid}/groups`, { limit, offset });\n\nexport const addUserToGroup = async (userid, groupName) =>\n post(`${API_BASE}/user/${userid}/groups`, { groupName });\n\nexport const removeUserFromGroup = async (userid, groupName) =>\n del(`${API_BASE}/user/${userid}/groups`, { groupName });\n\nexport const listGroups = async ({ limit, offset, owner } = {}) =>\n get(`${API_BASE}/groups`, { limit, offset, owner });\n\nexport const createGroup = async ({ name, description }) =>\n post(`${API_BASE}/groups`, { name, description });\n\nexport const updateGroup = async ({ name, newName, description }) =>\n patch(`${API_BASE}/groups`, { name, newName, description });\n\nexport const deleteGroups = async (names) =>\n del(`${API_BASE}/groups`, { names });\n\nexport const getGroup = async (name) =>\n get(`${API_BASE}/groups/${encodeURIComponent(name)}`);\n\nexport const getGroupMembers = async (name, { limit, offset } = {}) =>\n get(`${API_BASE}/groups/${encodeURIComponent(name)}/members`, { limit, offset });\n\nexport const addMemberToGroup = async (name, userId) =>\n post(`${API_BASE}/groups/${encodeURIComponent(name)}/members`, { userId });\n\nexport const removeMemberFromGroup = async (name, userId) =>\n del(`${API_BASE}/groups/${encodeURIComponent(name)}/members`, { userId });\n\nexport const getGroupPermissions = async (name) =>\n get(`${API_BASE}/groups/${encodeURIComponent(name)}/permissions`);\n\nexport const addPermissionToGroup = async (name, permissionName) =>\n post(`${API_BASE}/groups/${encodeURIComponent(name)}/permissions`, { permissionName });\n\nexport const removePermissionFromGroup = async (name, permissionName) =>\n del(`${API_BASE}/groups/${encodeURIComponent(name)}/permissions`, { permissionName });\n\nexport const listPermissions = async ({ limit, offset, owner } = {}) =>\n get(`${API_BASE}/permissions`, { limit, offset, owner });\n\nexport const createPermissions = async (permissions) =>\n post(`${API_BASE}/permissions`, { permissions });\n\nexport const updatePermission = async ({ name, description }) =>\n patch(`${API_BASE}/permissions`, { name, description });\n\nexport const deletePermissions = async (names) =>\n del(`${API_BASE}/permissions`, { names });\n\nexport const getSetting = async (owner, name) =>\n get(`${API_BASE}/settings/${encodeURIComponent(owner)}/${encodeURIComponent(name)}`);\n\nexport const listSettings = async ({ owner, limit, offset } = {}) =>\n get(`${API_BASE}/settings/${encodeURIComponent(owner)}`, { limit, offset });\n\nexport const setSetting = async (owner, name, data) =>\n post(`${API_BASE}/settings/${encodeURIComponent(owner)}/${encodeURIComponent(name)}`, data);\n\nexport const deleteSetting = async (owner, name) =>\n del(`${API_BASE}/settings/${encodeURIComponent(owner)}/${encodeURIComponent(name)}`);\n\n/*\n Pages\n*/\n\nexport const listPages = async ({ owner, showHidden, offset, limit } = {}) =>\n get(`${API_BASE}/pages`, { owner, showHidden, offset, limit });\n\nexport const rescanPages = async () =>\n post(`${API_BASE}/pages/rescan`, {});\n\nexport const listTemplates = async () =>\n get(`${API_BASE}/templates`);\n\nexport const listDirectories = async () =>\n get(`${API_BASE}/pages/directories`);\n\nexport const getPage = async (file) =>\n get(`${API_BASE}/pages/file`, { file });\n\nexport const createPage = async ({ directory, name, template }) =>\n post(`${API_BASE}/pages`, { directory, name, template });\n\nexport const updatePage = async ({ file, name, title, description, author, template, contents, extraMetadata }) =>\n put(`${API_BASE}/pages/file`, { file, name, title, description, author, template, contents, extraMetadata });\n\nexport const deletePages = async (files) =>\n del(`${API_BASE}/pages`, { files });\n\nexport const disablePage = async (file) =>\n put(`${API_BASE}/pages/disable`, { file });\n\nexport const enablePage = async (file) =>\n put(`${API_BASE}/pages/enable`, { file });\n\nexport const movePage = async ({ file, newFile }) =>\n patch(`${API_BASE}/pages/file`, { file, newFile });\n\nexport const searchPagesByMetadata = async (query) =>\n get(`${API_BASE}/pages/search`, { query: JSON.stringify(query) });\n\nexport const setPageLocked = async ({ file, locked }) =>\n put(`${API_BASE}/pages/lock`, { file, locked });\n\n/*\n Templates\n*/\n\nexport const getTemplate = async (file) =>\n get(`${API_BASE}/templates/file`, { file });\n\nexport const createTemplate = async ({ directory, name, copyFrom }) =>\n post(`${API_BASE}/templates`, { directory, name, copyFrom });\n\nexport const updateTemplate = async ({ file, name, author, markup }) =>\n put(`${API_BASE}/templates/file`, { file, name, author, markup });\n\nexport const deleteTemplates = async (files) =>\n del(`${API_BASE}/templates`, { files });\n\nexport const disableTemplate = async (file) =>\n put(`${API_BASE}/templates/disable`, { file });\n\nexport const enableTemplate = async (file) =>\n put(`${API_BASE}/templates/enable`, { file });\n\nexport const moveTemplate = async ({ file, newFile }) =>\n patch(`${API_BASE}/templates/file`, { file, newFile });\n\nexport const setTemplateLocked = async ({ file, locked }) =>\n put(`${API_BASE}/templates/lock`, { file, locked });\n\n/*\n Fragments\n*/\n\nexport const listFragments = async () =>\n get(`${API_BASE}/fragments`);\n\nexport const getFragment = async (file) =>\n get(`${API_BASE}/fragments/file`, { file });\n\nexport const createFragment = async ({ directory, name }) =>\n post(`${API_BASE}/fragments`, { directory, name });\n\nexport const updateFragment = async ({ file, author, markup }) =>\n put(`${API_BASE}/fragments/file`, { file, author, markup });\n\nexport const deleteFragments = async (files) =>\n del(`${API_BASE}/fragments`, { files });\n\nexport const moveFragment = async ({ file, newFile }) =>\n patch(`${API_BASE}/fragments/file`, { file, newFile });\n\nexport const disableFragment = async (file) =>\n put(`${API_BASE}/fragments/disable`, { file });\n\nexport const enableFragment = async (file) =>\n put(`${API_BASE}/fragments/enable`, { file });\n\nexport const setFragmentLocked = async ({ file, locked }) =>\n put(`${API_BASE}/fragments/lock`, { file, locked });\n\n/*\n Global Content\n*/\n\nexport const listGlobalContent = async () =>\n get(`${API_BASE}/globals`);\n\nexport const getGlobalContent = async (id) =>\n get(`${API_BASE}/globals/entry`, { id });\n\nexport const createGlobalContent = async ({ name, location, priority }) =>\n post(`${API_BASE}/globals`, { name, location, priority });\n\nexport const updateGlobalContent = async ({ id, name, location, priority, markup }) =>\n put(`${API_BASE}/globals/entry`, { id, name, location, priority, markup });\n\nexport const deleteGlobalContent = async (ids) =>\n del(`${API_BASE}/globals`, { ids });\n\nexport const disableGlobalContent = async (id) =>\n put(`${API_BASE}/globals/disable`, { id });\n\nexport const enableGlobalContent = async (id) =>\n put(`${API_BASE}/globals/enable`, { id });\n\nexport const setGlobalContentLocked = async ({ id, locked }) =>\n put(`${API_BASE}/globals/lock`, { id, locked });\n\n/*\n Extensions\n*/\n\nexport const listExtensions = async ({ limit, offset } = {}) =>\n get(`${API_BASE}/extensions`, { limit, offset });\n\nexport const listAvailableExtensions = async () =>\n get(`${API_BASE}/extensions/available`);\n\nexport const listKnownExtensions = async () =>\n get(`${API_BASE}/extensions/known`);\n\n/*\n Dashboard\n*/\n\nexport const getDashboardWidgets = async () =>\n get(`${API_BASE}/dashboard/widgets`);\n\n/*\n Notifications\n*/\n\nexport const getNotifications = async ({ unreadOnly = false, limit, offset } = {}) =>\n get(`${API_BASE}/notifications`, { unreadOnly, limit, offset });\n\nexport const getUnreadNotificationCount = async () =>\n get(`${API_BASE}/notifications/count`);\n\nexport const markNotificationRead = async (id) =>\n post(`${API_BASE}/notifications/${encodeURIComponent(id)}/read`, {});\n\nexport const markNotificationHandled = async (id) =>\n post(`${API_BASE}/notifications/${encodeURIComponent(id)}/handled`, {});\n\nexport const markAllNotificationsRead = async () =>\n post(`${API_BASE}/notifications/read-all`, {});\n\nexport const dismissNotification = async (id) =>\n del(`${API_BASE}/notifications/${encodeURIComponent(id)}`);\n\nexport const listRealtimeConnections = async () =>\n get(`${API_BASE}/realtime/connections`);\n\nexport const installExtension = async (name) =>\n post(`${API_BASE}/extensions`, { name });\n\nexport const uninstallExtension = async (name, purgeData = false) =>\n del(`${API_BASE}/extensions`, { name, purgeData });\n\nexport const enableExtension = async (name) =>\n post(`${API_BASE}/extensions/${encodeURIComponent(name)}/enable`, {});\n\nexport const disableExtension = async (name) =>\n post(`${API_BASE}/extensions/${encodeURIComponent(name)}/disable`, {});\n\n/*\n Admin Global Content\n*/\n\nexport const listAdminGlobalContent = async () =>\n get(`${API_BASE}/admin-globals`);\n\nexport const getAdminGlobalContent = async (id) =>\n get(`${API_BASE}/admin-globals/${encodeURIComponent(id)}`);\n\nexport const createAdminGlobalContent = async ({ name, location, priority, owner, markup }) =>\n post(`${API_BASE}/admin-globals`, { name, location, priority, owner, markup });\n\nexport const updateAdminGlobalContent = async (id, { name, location, priority, markup }) =>\n put(`${API_BASE}/admin-globals/${encodeURIComponent(id)}`, { name, location, priority, markup });\n\nexport const deleteAdminGlobalContent = async (ids) =>\n del(`${API_BASE}/admin-globals`, { ids });\n\nexport const enableAdminGlobalContent = async (id) =>\n put(`${API_BASE}/admin-globals/${encodeURIComponent(id)}/enable`, {});\n\nexport const disableAdminGlobalContent = async (id) =>\n put(`${API_BASE}/admin-globals/${encodeURIComponent(id)}/disable`, {});\n\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"src\\kempo\\sdk.js","names":["get","post","put","patch","del","API_BASE","register","async","email","password","name","login","logout","getSession","forgotPassword","resetPassword","token","logoutAll","newPassword","changePassword","currentPassword","verifyEmail","currentUserHasPermission","permission","currentUserHasAllPermissions","permissions","currentUserHasSomePermissions","getAllCurrentUserPermissions","userHasPermission","userid","userHasAllPermissions","userHasSomePermissions","getAllUserPermissions","getUsers","limit","offset","searchUsers","q","inGroup","notInGroup","createUser","emailVerified","deleteUsers","ids","updateUser","id","createdAt","getUser","getUserSessions","deleteUserSession","sessionToken","deleteExpiredUserSessions","getUserGroups","addUserToGroup","groupName","removeUserFromGroup","listGroups","owner","createGroup","description","updateGroup","newName","deleteGroups","names","getGroup","encodeURIComponent","getGroupMembers","addMemberToGroup","userId","removeMemberFromGroup","getGroupPermissions","addPermissionToGroup","permissionName","removePermissionFromGroup","listPermissions","createPermissions","updatePermission","deletePermissions","getSetting","listSettings","setSetting","data","deleteSetting","listPages","showHidden","rescanPages","listTemplates","listDirectories","getPage","file","createPage","directory","template","updatePage","title","author","contents","extraMetadata","deletePages","files","disablePage","enablePage","movePage","newFile","searchPagesByMetadata","query","JSON","stringify","setPageLocked","locked","getTemplate","createTemplate","copyFrom","updateTemplate","markup","deleteTemplates","disableTemplate","enableTemplate","moveTemplate","setTemplateLocked","listFragments","getFragment","createFragment","updateFragment","deleteFragments","moveFragment","disableFragment","enableFragment","setFragmentLocked","listGlobalContent","getGlobalContent","createGlobalContent","location","priority","updateGlobalContent","deleteGlobalContent","disableGlobalContent","enableGlobalContent","setGlobalContentLocked","listExtensions","listAvailableExtensions","listKnownExtensions","search","sort","getKnownExtension","rateExtension","rating","getDashboardWidgets","getNotifications","unreadOnly","getUnreadNotificationCount","markNotificationRead","markNotificationHandled","markAllNotificationsRead","dismissNotification","listRealtimeConnections","installExtension","withDependencies","uninstallExtension","purgeData","cascade","enableExtension","getExtensionRequirements","disableExtension","getExtensionDependents","includeDisabled","undefined","listAdminGlobalContent","getAdminGlobalContent","createAdminGlobalContent","updateAdminGlobalContent","deleteAdminGlobalContent","enableAdminGlobalContent","disableAdminGlobalContent"],"sources":["0"],"sourcesContent":["import { get, post, put, patch, del } from './fetch.js';\nconst API_BASE = '/kempo/api';\n\nexport const register = async ({ email, password, name }) =>\n post(`${API_BASE}/auth/register/email`, { email, password, name });\n\nexport const login = async ({ email, password }) =>\n post(`${API_BASE}/auth/login/email`, { email, password });\n\nexport const logout = async () => post(`${API_BASE}/auth/logout`, {});\n\nexport const getSession = async () => get(`${API_BASE}/auth/session`);\n\nexport const forgotPassword = async ({ email }) =>\n post(`${API_BASE}/forgot-password`, { email });\n\nexport const resetPassword = async ({ token, password, logoutAll = false }) =>\n post(`${API_BASE}/auth/reset-password`, { token, newPassword: password, logoutAll });\n \nexport const changePassword = async ({ currentPassword, newPassword, logoutAll }) => \n post(`${API_BASE}/auth/change-password`, { currentPassword, newPassword, logoutAll });\n\nexport const verifyEmail = async ({ token }) =>\n post(`${API_BASE}/auth/verify-email`, { token });\n\nexport const currentUserHasPermission = async ({ permission }) =>\n get(`${API_BASE}/user/current/permissions`, { permission });\n\nexport const currentUserHasAllPermissions = async ({ permissions }) =>\n get(`${API_BASE}/user/current/permissions/all`, { permissions });\n\nexport const currentUserHasSomePermissions = async ({ permissions }) =>\n get(`${API_BASE}/user/current/permissions/some`, { permissions });\n\nexport const getAllCurrentUserPermissions = async () =>\n get(`${API_BASE}/user/current/permissions/list`);\n\nexport const userHasPermission = async ({ userid, permission }) =>\n get(`${API_BASE}/user/${userid}/permissions`, { permission });\n\nexport const userHasAllPermissions = async ({ userid, permissions }) =>\n get(`${API_BASE}/user/${userid}/permissions/all`, { permissions });\n\nexport const userHasSomePermissions = async ({ userid, permissions }) =>\n get(`${API_BASE}/user/${userid}/permissions/some`, { permissions });\n\nexport const getAllUserPermissions = async ({ userid }) =>\n get(`${API_BASE}/user/${userid}/permissions/list`);\n\nexport const getUsers = async ({ limit, offset } = {}) =>\n get(`${API_BASE}/user`, { limit, offset });\n\nexport const searchUsers = async ({ q, limit, offset, inGroup, notInGroup } = {}) =>\n get(`${API_BASE}/user/search`, { q, limit, offset, inGroup, notInGroup });\n\nexport const createUser = async ({ name, email, password, emailVerified }) =>\n post(`${API_BASE}/user/create`, { name, email, password, emailVerified });\n\nexport const deleteUsers = async (ids) =>\n del(`${API_BASE}/user`, { ids });\n\nexport const updateUser = async ({ id, name, email, emailVerified, createdAt }) =>\n patch(`${API_BASE}/user`, { id, name, email, emailVerified, createdAt });\n\nexport const getUser = async (userid) =>\n get(`${API_BASE}/user/${userid}`);\n\nexport const getUserSessions = async (userid, { limit, offset } = {}) =>\n get(`${API_BASE}/user/${userid}/sessions`, { limit, offset });\n\nexport const deleteUserSession = async (userid, sessionToken) =>\n del(`${API_BASE}/user/${userid}/sessions`, { sessionToken });\n\nexport const deleteExpiredUserSessions = async (userid) =>\n del(`${API_BASE}/user/${userid}/sessions/expired`);\n\nexport const getUserGroups = async (userid, { limit, offset } = {}) =>\n get(`${API_BASE}/user/${userid}/groups`, { limit, offset });\n\nexport const addUserToGroup = async (userid, groupName) =>\n post(`${API_BASE}/user/${userid}/groups`, { groupName });\n\nexport const removeUserFromGroup = async (userid, groupName) =>\n del(`${API_BASE}/user/${userid}/groups`, { groupName });\n\nexport const listGroups = async ({ limit, offset, owner } = {}) =>\n get(`${API_BASE}/groups`, { limit, offset, owner });\n\nexport const createGroup = async ({ name, description }) =>\n post(`${API_BASE}/groups`, { name, description });\n\nexport const updateGroup = async ({ name, newName, description }) =>\n patch(`${API_BASE}/groups`, { name, newName, description });\n\nexport const deleteGroups = async (names) =>\n del(`${API_BASE}/groups`, { names });\n\nexport const getGroup = async (name) =>\n get(`${API_BASE}/groups/${encodeURIComponent(name)}`);\n\nexport const getGroupMembers = async (name, { limit, offset } = {}) =>\n get(`${API_BASE}/groups/${encodeURIComponent(name)}/members`, { limit, offset });\n\nexport const addMemberToGroup = async (name, userId) =>\n post(`${API_BASE}/groups/${encodeURIComponent(name)}/members`, { userId });\n\nexport const removeMemberFromGroup = async (name, userId) =>\n del(`${API_BASE}/groups/${encodeURIComponent(name)}/members`, { userId });\n\nexport const getGroupPermissions = async (name) =>\n get(`${API_BASE}/groups/${encodeURIComponent(name)}/permissions`);\n\nexport const addPermissionToGroup = async (name, permissionName) =>\n post(`${API_BASE}/groups/${encodeURIComponent(name)}/permissions`, { permissionName });\n\nexport const removePermissionFromGroup = async (name, permissionName) =>\n del(`${API_BASE}/groups/${encodeURIComponent(name)}/permissions`, { permissionName });\n\nexport const listPermissions = async ({ limit, offset, owner } = {}) =>\n get(`${API_BASE}/permissions`, { limit, offset, owner });\n\nexport const createPermissions = async (permissions) =>\n post(`${API_BASE}/permissions`, { permissions });\n\nexport const updatePermission = async ({ name, description }) =>\n patch(`${API_BASE}/permissions`, { name, description });\n\nexport const deletePermissions = async (names) =>\n del(`${API_BASE}/permissions`, { names });\n\nexport const getSetting = async (owner, name) =>\n get(`${API_BASE}/settings/${encodeURIComponent(owner)}/${encodeURIComponent(name)}`);\n\nexport const listSettings = async ({ owner, limit, offset } = {}) =>\n get(`${API_BASE}/settings/${encodeURIComponent(owner)}`, { limit, offset });\n\nexport const setSetting = async (owner, name, data) =>\n post(`${API_BASE}/settings/${encodeURIComponent(owner)}/${encodeURIComponent(name)}`, data);\n\nexport const deleteSetting = async (owner, name) =>\n del(`${API_BASE}/settings/${encodeURIComponent(owner)}/${encodeURIComponent(name)}`);\n\n/*\n Pages\n*/\n\nexport const listPages = async ({ owner, showHidden, offset, limit } = {}) =>\n get(`${API_BASE}/pages`, { owner, showHidden, offset, limit });\n\nexport const rescanPages = async () =>\n post(`${API_BASE}/pages/rescan`, {});\n\nexport const listTemplates = async () =>\n get(`${API_BASE}/templates`);\n\nexport const listDirectories = async () =>\n get(`${API_BASE}/pages/directories`);\n\nexport const getPage = async (file) =>\n get(`${API_BASE}/pages/file`, { file });\n\nexport const createPage = async ({ directory, name, template }) =>\n post(`${API_BASE}/pages`, { directory, name, template });\n\nexport const updatePage = async ({ file, name, title, description, author, template, contents, extraMetadata }) =>\n put(`${API_BASE}/pages/file`, { file, name, title, description, author, template, contents, extraMetadata });\n\nexport const deletePages = async (files) =>\n del(`${API_BASE}/pages`, { files });\n\nexport const disablePage = async (file) =>\n put(`${API_BASE}/pages/disable`, { file });\n\nexport const enablePage = async (file) =>\n put(`${API_BASE}/pages/enable`, { file });\n\nexport const movePage = async ({ file, newFile }) =>\n patch(`${API_BASE}/pages/file`, { file, newFile });\n\nexport const searchPagesByMetadata = async (query) =>\n get(`${API_BASE}/pages/search`, { query: JSON.stringify(query) });\n\nexport const setPageLocked = async ({ file, locked }) =>\n put(`${API_BASE}/pages/lock`, { file, locked });\n\n/*\n Templates\n*/\n\nexport const getTemplate = async (file) =>\n get(`${API_BASE}/templates/file`, { file });\n\nexport const createTemplate = async ({ directory, name, copyFrom }) =>\n post(`${API_BASE}/templates`, { directory, name, copyFrom });\n\nexport const updateTemplate = async ({ file, name, author, markup }) =>\n put(`${API_BASE}/templates/file`, { file, name, author, markup });\n\nexport const deleteTemplates = async (files) =>\n del(`${API_BASE}/templates`, { files });\n\nexport const disableTemplate = async (file) =>\n put(`${API_BASE}/templates/disable`, { file });\n\nexport const enableTemplate = async (file) =>\n put(`${API_BASE}/templates/enable`, { file });\n\nexport const moveTemplate = async ({ file, newFile }) =>\n patch(`${API_BASE}/templates/file`, { file, newFile });\n\nexport const setTemplateLocked = async ({ file, locked }) =>\n put(`${API_BASE}/templates/lock`, { file, locked });\n\n/*\n Fragments\n*/\n\nexport const listFragments = async () =>\n get(`${API_BASE}/fragments`);\n\nexport const getFragment = async (file) =>\n get(`${API_BASE}/fragments/file`, { file });\n\nexport const createFragment = async ({ directory, name }) =>\n post(`${API_BASE}/fragments`, { directory, name });\n\nexport const updateFragment = async ({ file, author, markup }) =>\n put(`${API_BASE}/fragments/file`, { file, author, markup });\n\nexport const deleteFragments = async (files) =>\n del(`${API_BASE}/fragments`, { files });\n\nexport const moveFragment = async ({ file, newFile }) =>\n patch(`${API_BASE}/fragments/file`, { file, newFile });\n\nexport const disableFragment = async (file) =>\n put(`${API_BASE}/fragments/disable`, { file });\n\nexport const enableFragment = async (file) =>\n put(`${API_BASE}/fragments/enable`, { file });\n\nexport const setFragmentLocked = async ({ file, locked }) =>\n put(`${API_BASE}/fragments/lock`, { file, locked });\n\n/*\n Global Content\n*/\n\nexport const listGlobalContent = async () =>\n get(`${API_BASE}/globals`);\n\nexport const getGlobalContent = async (id) =>\n get(`${API_BASE}/globals/entry`, { id });\n\nexport const createGlobalContent = async ({ name, location, priority }) =>\n post(`${API_BASE}/globals`, { name, location, priority });\n\nexport const updateGlobalContent = async ({ id, name, location, priority, markup }) =>\n put(`${API_BASE}/globals/entry`, { id, name, location, priority, markup });\n\nexport const deleteGlobalContent = async (ids) =>\n del(`${API_BASE}/globals`, { ids });\n\nexport const disableGlobalContent = async (id) =>\n put(`${API_BASE}/globals/disable`, { id });\n\nexport const enableGlobalContent = async (id) =>\n put(`${API_BASE}/globals/enable`, { id });\n\nexport const setGlobalContentLocked = async ({ id, locked }) =>\n put(`${API_BASE}/globals/lock`, { id, locked });\n\n/*\n Extensions\n*/\n\nexport const listExtensions = async ({ limit, offset } = {}) =>\n get(`${API_BASE}/extensions`, { limit, offset });\n\nexport const listAvailableExtensions = async () =>\n get(`${API_BASE}/extensions/available`);\n\nexport const listKnownExtensions = async ({ search, sort, limit, offset } = {}) =>\n get(`${API_BASE}/extensions/known`, { search, sort, limit, offset });\n\nexport const getKnownExtension = async (name) =>\n get(`${API_BASE}/extensions/known`, { name });\n\nexport const rateExtension = async (name, rating) =>\n put(`${API_BASE}/extensions/rating`, { name, rating });\n\n/*\n Dashboard\n*/\n\nexport const getDashboardWidgets = async () =>\n get(`${API_BASE}/dashboard/widgets`);\n\n/*\n Notifications\n*/\n\nexport const getNotifications = async ({ unreadOnly = false, limit, offset } = {}) =>\n get(`${API_BASE}/notifications`, { unreadOnly, limit, offset });\n\nexport const getUnreadNotificationCount = async () =>\n get(`${API_BASE}/notifications/count`);\n\nexport const markNotificationRead = async (id) =>\n post(`${API_BASE}/notifications/${encodeURIComponent(id)}/read`, {});\n\nexport const markNotificationHandled = async (id) =>\n post(`${API_BASE}/notifications/${encodeURIComponent(id)}/handled`, {});\n\nexport const markAllNotificationsRead = async () =>\n post(`${API_BASE}/notifications/read-all`, {});\n\nexport const dismissNotification = async (id) =>\n del(`${API_BASE}/notifications/${encodeURIComponent(id)}`);\n\nexport const listRealtimeConnections = async () =>\n get(`${API_BASE}/realtime/connections`);\n\nexport const installExtension = async (name, { withDependencies = false } = {}) =>\n post(`${API_BASE}/extensions`, { name, withDependencies });\n\nexport const uninstallExtension = async (name, purgeData = false, { cascade = false } = {}) =>\n del(`${API_BASE}/extensions`, { name, purgeData, cascade });\n\nexport const enableExtension = async (name, { cascade = false } = {}) =>\n post(`${API_BASE}/extensions/${encodeURIComponent(name)}/enable`, { cascade });\n\nexport const getExtensionRequirements = async (name) =>\n get(`${API_BASE}/extensions/${encodeURIComponent(name)}/requirements`);\n\nexport const disableExtension = async (name, { cascade = false } = {}) =>\n post(`${API_BASE}/extensions/${encodeURIComponent(name)}/disable`, { cascade });\n\nexport const getExtensionDependents = async (name, { includeDisabled = false } = {}) =>\n get(`${API_BASE}/extensions/${encodeURIComponent(name)}/dependents`, { includeDisabled: includeDisabled ? 'true' : undefined });\n\n/*\n Admin Global Content\n*/\n\nexport const listAdminGlobalContent = async () =>\n get(`${API_BASE}/admin-globals`);\n\nexport const getAdminGlobalContent = async (id) =>\n get(`${API_BASE}/admin-globals/${encodeURIComponent(id)}`);\n\nexport const createAdminGlobalContent = async ({ name, location, priority, owner, markup }) =>\n post(`${API_BASE}/admin-globals`, { name, location, priority, owner, markup });\n\nexport const updateAdminGlobalContent = async (id, { name, location, priority, markup }) =>\n put(`${API_BASE}/admin-globals/${encodeURIComponent(id)}`, { name, location, priority, markup });\n\nexport const deleteAdminGlobalContent = async (ids) =>\n del(`${API_BASE}/admin-globals`, { ids });\n\nexport const enableAdminGlobalContent = async (id) =>\n put(`${API_BASE}/admin-globals/${encodeURIComponent(id)}/enable`, {});\n\nexport const disableAdminGlobalContent = async (id) =>\n put(`${API_BASE}/admin-globals/${encodeURIComponent(id)}/disable`, {});\n\n"],"mappings":"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","ignoreList":[]}
@@ -6,6 +6,7 @@ import getSession from '../server/utils/auth/getSession.js';
6
6
  import currentUserHasPermission from '../server/utils/permissions/currentUserHasPermission.js';
7
7
  import { LEXICAL_BASE, bundleFileName as lexicalBundleFileName } from '../server/utils/lexical/packages.js';
8
8
  import { getEnabledExtensions } from '../server/utils/extensions/scopeCache.js';
9
+ import readKempoConfig from '../server/utils/extensions/readKempoConfig.js';
9
10
  import { extensionAdminDirs, extensionPublicDirs } from '../server/utils/extensions/contentDirs.js';
10
11
  import triggerHook from '../server/utils/hooks/triggerHook.js';
11
12
  import { ADMIN_GLOBALS_DIR } from '../server/utils/admin-global-content/helpers.js';
@@ -394,19 +395,21 @@ export default config => {
394
395
  const publicContentDirs = await extensionPublicDirs();
395
396
 
396
397
  for(const ext of extensions){
397
- let pkgPath, pkg;
398
+ const extRoot = join(NODE_MODULES, ext.name);
399
+ let kempo;
398
400
  try {
399
- pkgPath = join(NODE_MODULES, ext.name, 'package.json');
400
- pkg = JSON.parse(await readFile(pkgPath, 'utf-8'));
401
- } catch { continue; }
401
+ ({ kempo } = await readKempoConfig(extRoot));
402
+ } catch {
403
+ continue;
404
+ }
402
405
 
403
- const scope = pkg.kempo?.['public-scope'];
406
+ const scope = kempo['public-scope'];
404
407
  if(!scope) continue;
405
408
 
406
409
  const scopePrefix = `/${scope}`;
407
410
  if(url !== scopePrefix && !url.startsWith(`${scopePrefix}/`)) continue;
408
411
 
409
- const publicDir = join(dirname(pkgPath), 'public');
412
+ const publicDir = join(extRoot, 'public');
410
413
  const subPath = url.slice(scopePrefix.length) || '/';
411
414
  const method = request.method?.toUpperCase() || 'GET';
412
415
  const resolveDir = buildResolveDir(PROJECT_PUBLIC, url);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kempo",
3
- "version": "4.5.7",
3
+ "version": "4.6.0",
4
4
  "type": "module",
5
5
  "description": "A fullstack CMS framework for creating websites with user authentication",
6
6
  "scripts": {
@@ -0,0 +1,203 @@
1
+ /*
2
+ The extension marketplace (https://extensions.kempo.dev), as this site's SERVER sees it. The browser
3
+ only ever talks to this site's own API, which calls this.
4
+
5
+ list a page of cards: search, sort, limit, offset
6
+ details everything about one extension, with its full dependency tree
7
+ report tell the marketplace this site installed an extension (counted once per site)
8
+ rate this site's rating of an extension
9
+
10
+ Reads are cached in memory for `ttlMs`, and an older copy is served when the marketplace cannot be
11
+ reached (marked `stale`). Concurrent identical reads share one request. Nothing is ever executed
12
+ from a response, and only known fields are kept, with their types and sizes checked, links limited to
13
+ http(s), and the response size capped.
14
+
15
+ Every function returns [error, data] and never throws.
16
+ */
17
+
18
+ export const DEFAULT_CATALOG_URL = 'https://extensions.kempo.dev/api/v1';
19
+
20
+ export const NAME_PATTERN = /^(@[a-z0-9-~][a-z0-9-._~]*\/)?[a-z0-9-~][a-z0-9-._~]*$/;
21
+
22
+ const MAX_BYTES = 2 * 1024 * 1024;
23
+ const MAX_README = 200 * 1024;
24
+ const MAX_CACHED = 200;
25
+
26
+ const text = (value, max = 1000) => typeof value === 'string' ? value.slice(0, max) : '';
27
+
28
+ const link = value => /^https?:\/\//i.test(text(value, 2000)) ? text(value, 2000) : '';
29
+
30
+ const count = value => Number.isFinite(value) && value >= 0 ? Math.floor(value) : 0;
31
+
32
+ const names = value => (Array.isArray(value) ? value : []).filter(item => typeof item === 'string' && NAME_PATTERN.test(item));
33
+
34
+ const described = (list, fields) => (Array.isArray(list) ? list : [])
35
+ .filter(item => item && typeof item === 'object' && typeof item[fields[0]] === 'string')
36
+ .slice(0, 200)
37
+ .map(item => Object.fromEntries(fields.map(field => [field, text(item[field], 500)])));
38
+
39
+ const rating = value => ({
40
+ average: Number.isFinite(value?.average) ? Math.min(5, Math.max(0, value.average)) : null,
41
+ count: count(value?.count),
42
+ });
43
+
44
+ /* A card in a list. */
45
+ export const normalizeCard = raw => {
46
+ if(!raw || typeof raw !== 'object' || typeof raw.name !== 'string' || !NAME_PATTERN.test(raw.name)) return null;
47
+ return {
48
+ name: raw.name,
49
+ description: text(raw.description, 2000),
50
+ author: text(raw.author, 200),
51
+ version: text(raw.version, 100),
52
+ installable: raw.installable !== false,
53
+ installs: count(raw.installs),
54
+ rating: rating(raw.rating),
55
+ source: text(raw.source, 50) || 'catalogue',
56
+ pricing: { type: text(raw.pricing?.type, 50) || 'free' },
57
+ };
58
+ };
59
+
60
+ /* One extension in full. */
61
+ export const normalizeDetails = raw => {
62
+ const card = normalizeCard(raw);
63
+ if(!card) return null;
64
+ return {
65
+ ...card,
66
+ license: text(raw.license, 100),
67
+ homepage: link(raw.homepage),
68
+ origin: { type: raw.origin?.type === 'npm' ? 'npm' : 'repository', url: link(raw.origin?.url) },
69
+ keywords: (Array.isArray(raw.keywords) ? raw.keywords : []).filter(item => typeof item === 'string').slice(0, 20).map(item => item.slice(0, 50)),
70
+ requires: { kempo: text(raw.requires?.kempo, 100), extensions: names(raw.requires?.extensions) },
71
+ provides: {
72
+ publicScope: text(raw.provides?.publicScope, 100),
73
+ permissions: described(raw.provides?.permissions, ['name', 'description']),
74
+ settings: described(raw.provides?.settings, ['name', 'type', 'description']),
75
+ groups: described(raw.provides?.groups, ['name', 'description']),
76
+ widgets: described(raw.provides?.widgets, ['key', 'title', 'description']),
77
+ },
78
+ npmDependencies: Object.fromEntries(Object.entries(raw.npmDependencies && typeof raw.npmDependencies === 'object' ? raw.npmDependencies : {})
79
+ .filter(([key, range]) => typeof range === 'string').slice(0, 100).map(([key, range]) => [key.slice(0, 214), range.slice(0, 100)])),
80
+ readme: typeof raw.readme === 'string' ? raw.readme.slice(0, MAX_README) : null,
81
+ stale: raw.stale === true,
82
+ dependencies: {
83
+ /* Dependencies first: the order to install them in. */
84
+ extensions: (Array.isArray(raw.dependencies?.extensions) ? raw.dependencies.extensions : [])
85
+ .filter(item => item && typeof item.name === 'string' && NAME_PATTERN.test(item.name))
86
+ .slice(0, 100)
87
+ .map(item => ({
88
+ name: item.name,
89
+ description: text(item.description, 2000),
90
+ version: text(item.version, 100),
91
+ installable: item.installable !== false,
92
+ requires: names(item.requires),
93
+ })),
94
+ unresolved: names(raw.dependencies?.unresolved),
95
+ },
96
+ };
97
+ };
98
+
99
+ export const normalizePage = raw => {
100
+ if(!raw || typeof raw !== 'object' || !Array.isArray(raw.items)) return null;
101
+ return {
102
+ total: count(raw.total),
103
+ limit: count(raw.limit),
104
+ offset: count(raw.offset),
105
+ items: raw.items.map(normalizeCard).filter(Boolean),
106
+ };
107
+ };
108
+
109
+ const encodeName = name => encodeURIComponent(name);
110
+
111
+ /*
112
+ A client for one marketplace address. Pass `baseUrl: ''` for none: every call then answers 503, which
113
+ is how a site turns the marketplace off.
114
+ */
115
+ export const createCatalogClient = ({ baseUrl = DEFAULT_CATALOG_URL, fetchImpl = fetch, ttlMs = 5 * 60 * 1000, timeoutMs = 8000, now = Date.now } = {}) => {
116
+ const base = String(baseUrl || '').trim().replace(/\/$/, '');
117
+ const cache = new Map();
118
+ const inflight = new Map();
119
+
120
+ const unavailable = () => [{ code: 503, msg: base ? 'The extension marketplace is not reachable' : 'The extension marketplace is turned off for this site' }, null];
121
+
122
+ const request = async (method, path, body) => {
123
+ const response = await fetchImpl(`${base}${path}`, {
124
+ method,
125
+ signal: AbortSignal.timeout(timeoutMs),
126
+ headers: { accept: 'application/json', ...(body ? { 'content-type': 'application/json' } : {}) },
127
+ body: body ? JSON.stringify(body) : undefined,
128
+ });
129
+ const raw = await response.text();
130
+ if(raw.length > MAX_BYTES) throw new Error('the response is too large');
131
+ let data = null;
132
+ try {
133
+ data = raw ? JSON.parse(raw) : null;
134
+ } catch {
135
+ throw new Error('the response is not JSON');
136
+ }
137
+ return { status: response.status, ok: response.ok, data };
138
+ };
139
+
140
+ const fail = (response, fallback) => [{ code: response.status >= 400 && response.status < 600 ? response.status : 502, msg: text(response.data?.error, 300) || fallback }, null];
141
+
142
+ /* A cached read: fresh from memory, else fetched, else the older copy, else an error. */
143
+ const read = async (path, normalize, pick = data => data) => {
144
+ if(!base) return unavailable();
145
+
146
+ const cached = cache.get(path);
147
+ if(cached && now() - cached.at < ttlMs) return [null, cached.value];
148
+
149
+ if(!inflight.has(path)){
150
+ inflight.set(path, (async () => {
151
+ try {
152
+ const response = await request('GET', path);
153
+ if(!response.ok) return fail(response, `The marketplace answered ${response.status}`);
154
+ const value = normalize(pick(response.data));
155
+ if(!value) return [{ code: 502, msg: 'The marketplace sent something that is not understood' }, null];
156
+ if(cache.size >= MAX_CACHED) cache.delete(cache.keys().next().value);
157
+ cache.set(path, { value, at: now() });
158
+ return [null, value];
159
+ } catch(error) {
160
+ if(cached) return [null, { ...cached.value, stale: true }];
161
+ return [{ code: 503, msg: `The extension marketplace could not be reached: ${error.message}` }, null];
162
+ } finally {
163
+ inflight.delete(path);
164
+ }
165
+ })());
166
+ }
167
+ return inflight.get(path);
168
+ };
169
+
170
+ const write = async (method, path, body) => {
171
+ if(!base) return unavailable();
172
+ try {
173
+ const response = await request(method, path, body);
174
+ if(!response.ok) return fail(response, `The marketplace answered ${response.status}`);
175
+ /* Counts and averages just changed, so what is held in memory is out of date. */
176
+ if(method !== 'GET') cache.clear();
177
+ return [null, response.data];
178
+ } catch(error) {
179
+ return [{ code: 503, msg: `The extension marketplace could not be reached: ${error.message}` }, null];
180
+ }
181
+ };
182
+
183
+ return {
184
+ list: ({ search, sort, limit, offset } = {}) => {
185
+ const query = new URLSearchParams();
186
+ if(search) query.set('search', String(search).slice(0, 100));
187
+ if(sort) query.set('sort', String(sort));
188
+ if(limit) query.set('limit', String(limit));
189
+ if(offset) query.set('offset', String(offset));
190
+ return read(`/extensions${query.size ? `?${query}` : ''}`, normalizePage);
191
+ },
192
+
193
+ details: name => NAME_PATTERN.test(name || '')
194
+ ? read(`/extensions/${encodeName(name)}`, normalizeDetails, data => data?.extension)
195
+ : Promise.resolve([{ code: 400, msg: 'Extension name is not a valid package name' }, null]),
196
+
197
+ report: ({ installId, extension }) => write('POST', `/extensions/${encodeName(extension)}/installs`, { installId }),
198
+
199
+ rate: ({ installId, extension, value }) => write('PUT', `/extensions/${encodeName(extension)}/rating`, { installId, rating: value }),
200
+
201
+ siteRating: ({ installId, extension }) => write('GET', `/extensions/${encodeName(extension)}/rating?installId=${encodeURIComponent(installId)}`),
202
+ };
203
+ };
@@ -1,32 +1,2 @@
1
- import db from '../../db/index.js';
2
- import { extension } from '../../db/schema.js';
3
- import { eq } from 'drizzle-orm';
4
- import { invalidateScopeCache } from './scopeCache.js';
5
- import { getEnabledDependents } from './dependencies.js';
6
-
7
- export default async ({ name }) => {
8
- if(!name){
9
- return [{ code: 400, msg: 'Extension name is required' }, null];
10
- }
11
-
12
- const dependents = await getEnabledDependents(name);
13
- if(dependents.length){
14
- return [{ code: 409, msg: `${dependents.join(', ')} depends on this extension and is still enabled` }, null];
15
- }
16
-
17
- try {
18
- const updated = await db.update(extension)
19
- .set({ enabled: false, updatedAt: new Date() })
20
- .where(eq(extension.name, name))
21
- .returning();
22
-
23
- if(!updated.length){
24
- return [{ code: 404, msg: 'Extension not found' }, null];
25
- }
26
-
27
- invalidateScopeCache();
28
- return [null, updated[0]];
29
- } catch(error) {
30
- return [{ code: 500, msg: 'Failed to disable extension' }, null];
31
- }
32
- };
1
+ /* The name callers import; the implementation, with its cascade over dependents, is in disableExtensionTree.js. */
2
+ export { default } from './disableExtensionTree.js';