kempo 4.2.40 → 4.4.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.
- package/README.md +7 -0
- package/app-public/default.template.html +1 -1
- package/dist/admin/nav.fragment.html +5 -0
- package/dist/admin/realtime/index.page.html +81 -0
- package/dist/kempo/api/realtime/WS.js +2 -0
- package/dist/kempo/api/realtime/WS.js.map +1 -0
- package/dist/kempo/api/realtime/connections/GET.js +2 -0
- package/dist/kempo/api/realtime/connections/GET.js.map +1 -0
- package/dist/kempo/icons/credit_card.svg +1 -0
- package/dist/kempo/icons/sensors.svg +1 -0
- package/dist/kempo/realtime.js +2 -0
- package/dist/kempo/realtime.js.map +1 -0
- package/dist/kempo/sdk.js +1 -1
- package/dist/kempo/sdk.js.map +1 -1
- package/middleware/kempo.js +30 -15
- package/package.json +2 -2
- package/scripts/init-db.js +4 -1
- package/server/db/schema.js +30 -1
- package/server/sdk.js +5 -0
- package/server/utils/extensions/contentDirs.js +27 -0
- package/server/utils/realtime/Hub.js +695 -0
- package/server/utils/realtime/channels.js +247 -0
- package/server/utils/realtime/closeConnection.js +4 -0
- package/server/utils/realtime/constants.js +20 -0
- package/server/utils/realtime/duration.js +18 -0
- package/server/utils/realtime/getHub.js +15 -0
- package/server/utils/realtime/index.js +15 -0
- package/server/utils/realtime/listConnections.js +4 -0
- package/server/utils/realtime/listSubscribers.js +4 -0
- package/server/utils/realtime/pruneMessages.js +45 -0
- package/server/utils/realtime/publish.js +86 -0
- package/server/utils/realtime/sendToConnection.js +4 -0
- package/server/utils/realtime/unregisterChannel.js +19 -0
- package/server/utils/routing/serveUnmatched.js +8 -1
package/README.md
CHANGED
|
@@ -168,6 +168,8 @@ Kempo provides these tables out of the box:
|
|
|
168
168
|
| `permission` | Named permissions (e.g. `system:admin:access`) |
|
|
169
169
|
| `groupPermission` | Group-to-permission assignments |
|
|
170
170
|
| `setting` | Key-value settings with type, visibility, and ownership |
|
|
171
|
+
| `realtimeMessage` | Messages on channels that persist, so a reconnecting client can replay what it missed |
|
|
172
|
+
| `realtimeChannel` | How far each realtime channel has been pruned, to tell a client it missed messages |
|
|
171
173
|
|
|
172
174
|
## Frontend SDK
|
|
173
175
|
|
|
@@ -322,6 +324,7 @@ The `init-db.js` script seeds these permissions:
|
|
|
322
324
|
| `system:settings:read` | View private settings |
|
|
323
325
|
| `system:settings:update` | Update settings |
|
|
324
326
|
| `system:custom-settings:manage` | Create and delete custom settings |
|
|
327
|
+
| `system:realtime:read` | View realtime connections and channels |
|
|
325
328
|
|
|
326
329
|
Two default groups are created:
|
|
327
330
|
|
|
@@ -341,6 +344,10 @@ Two default groups are created:
|
|
|
341
344
|
|
|
342
345
|
Settings can be managed through the admin panel at `/admin/settings` or the SDK.
|
|
343
346
|
|
|
347
|
+
## Realtime
|
|
348
|
+
|
|
349
|
+
Extensions can push live updates to browsers: declare a channel, publish to it from any server code, and every subscribed browser on any kempo process receives it. Channels can persist messages so a client that reconnects replays what it missed, and a browser client handles connecting and reconnecting. Browsers can also send to a channel, where the extension's own handler receives and answers it, and extensions observe connections through hooks and act on them through SDK functions, so interactive features (chat, collaboration, games) can be built as extensions without touching a socket. Fast traffic can use an in-memory channel that skips the database, and connections are limited and backpressured. It uses a Postgres `LISTEN`/`NOTIFY` bus, so it needs no extra service. See [docs/realtime.md](docs/realtime.md).
|
|
350
|
+
|
|
344
351
|
## Email
|
|
345
352
|
|
|
346
353
|
Kempo uses [Resend](https://resend.com/) for sending emails. Set `RESEND_API_KEY` and `EMAIL_FROM` in your `.env` file.
|
|
@@ -72,6 +72,11 @@
|
|
|
72
72
|
href="/admin/extensions"
|
|
73
73
|
no-expand
|
|
74
74
|
>Extensions</k-aside-item>
|
|
75
|
+
<k-aside-item
|
|
76
|
+
icon="sensors"
|
|
77
|
+
href="/admin/realtime"
|
|
78
|
+
no-expand
|
|
79
|
+
>Realtime</k-aside-item>
|
|
75
80
|
<hr>
|
|
76
81
|
<location name="admin-nav-extensions"></location>
|
|
77
82
|
<k-aside-spacer></k-aside-spacer>
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
<!--
|
|
2
|
+
locked: true
|
|
3
|
+
-->
|
|
4
|
+
<page title="Realtime - Admin">
|
|
5
|
+
<content>
|
|
6
|
+
<script type="module" src="/kempo-ui/components/Table.js"></script>
|
|
7
|
+
<script type="module" src="/kempo-ui/components/Icon.js"></script>
|
|
8
|
+
|
|
9
|
+
<div class="d-f mb">
|
|
10
|
+
<h1 class="flex mb0">Realtime</h1>
|
|
11
|
+
<button id="refresh"><k-icon name="replay"></k-icon> Refresh</button>
|
|
12
|
+
</div>
|
|
13
|
+
|
|
14
|
+
<p class="tc-muted" id="scope">Loading…</p>
|
|
15
|
+
|
|
16
|
+
<h2>Connections</h2>
|
|
17
|
+
<k-table id="connectionsTable" placeholder="No one is connected to this process."></k-table>
|
|
18
|
+
|
|
19
|
+
<h2>Channels</h2>
|
|
20
|
+
<k-table id="channelsTable" placeholder="Nothing is subscribed to any channel on this process."></k-table>
|
|
21
|
+
|
|
22
|
+
<p class="small tc-muted">
|
|
23
|
+
Sockets are held by the process that accepted them, so with several kempo processes behind a load balancer this
|
|
24
|
+
page shows only the one that answered this request. Messages still reach every process.
|
|
25
|
+
</p>
|
|
26
|
+
|
|
27
|
+
</content>
|
|
28
|
+
<content location="scripts">
|
|
29
|
+
<script type="module">
|
|
30
|
+
import { listRealtimeConnections } from '/kempo/sdk.js';
|
|
31
|
+
|
|
32
|
+
const connectionsTable = document.getElementById('connectionsTable');
|
|
33
|
+
const channelsTable = document.getElementById('channelsTable');
|
|
34
|
+
const scope = document.getElementById('scope');
|
|
35
|
+
const formatTime = value => new Date(value).toLocaleString();
|
|
36
|
+
|
|
37
|
+
const refresh = async () => {
|
|
38
|
+
const [error, data] = await listRealtimeConnections();
|
|
39
|
+
|
|
40
|
+
if(error){
|
|
41
|
+
scope.textContent = error.code === 403
|
|
42
|
+
? 'You do not have permission to view realtime connections.'
|
|
43
|
+
: `Could not load connections: ${error.msg}`;
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
scope.textContent = `${data.connections.length} connection${data.connections.length === 1 ? '' : 's'} on process ${data.process}.`;
|
|
48
|
+
|
|
49
|
+
connectionsTable.setData({
|
|
50
|
+
records: data.connections.map(connection => ({
|
|
51
|
+
id: connection.id,
|
|
52
|
+
user: connection.userName || connection.userId,
|
|
53
|
+
path: connection.path,
|
|
54
|
+
channels: connection.channels.join(', ') || 'none',
|
|
55
|
+
connectedAt: formatTime(connection.connectedAt),
|
|
56
|
+
lastActivity: formatTime(connection.lastActivity)
|
|
57
|
+
})),
|
|
58
|
+
fields: [
|
|
59
|
+
{ name: 'user', label: 'User' },
|
|
60
|
+
{ name: 'path', label: 'Path' },
|
|
61
|
+
{ name: 'channels', label: 'Channels' },
|
|
62
|
+
{ name: 'connectedAt', label: 'Connected' },
|
|
63
|
+
{ name: 'lastActivity', label: 'Last activity' }
|
|
64
|
+
]
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
channelsTable.setData({
|
|
68
|
+
records: data.channels.map(channel => ({ id: channel.channel, channel: channel.channel, subscribers: channel.subscribers })),
|
|
69
|
+
fields: [
|
|
70
|
+
{ name: 'channel', label: 'Channel' },
|
|
71
|
+
{ name: 'subscribers', label: 'Subscribers' }
|
|
72
|
+
]
|
|
73
|
+
});
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
document.getElementById('refresh').addEventListener('click', refresh);
|
|
77
|
+
await refresh();
|
|
78
|
+
setInterval(refresh, 5000);
|
|
79
|
+
</script>
|
|
80
|
+
</content>
|
|
81
|
+
</page>
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import e from"../../../../server/utils/auth/getSession.js";import r from"../../../../server/utils/realtime/getHub.js";import{TOO_MANY_CONNECTIONS_CODE as n}from"../../../../server/utils/realtime/constants.js";export default async(t,s)=>{const c=t.cookies.session_token,[a,o]=await e({token:c});if(a)return 500===a.code?s.reject(500,"Failed to verify session"):s.reject(401,"Authentication required");const i=r(),u=(e,r)=>s.send(JSON.stringify(e),r);let d=null;s.on("open",()=>{const[e,r]=i.addSubscriber({token:c,user:o.user,path:t.path,deliver:u,close:(e,r)=>s.close(e,r)});e?s.close(429===e.code?n:1011,e.msg):(d=r.id,s.data.userId=o.user.id,u({type:"ready",userId:o.user.id}))}),s.on("message",async(e,r)=>{if(!d)return;let n;try{n=r?null:JSON.parse(e)}catch(e){n=null}if(!n||"object"!=typeof n)return u({type:"error",code:400,msg:"Frames must be JSON objects"});if(i.touch({id:d}),"subscribe"===n.type){const[e]=await i.subscribe({id:d,channel:n.channel,since:n.since});return void(e&&u({type:"error",channel:n.channel,code:e.code,msg:e.msg}))}if("send"===n.type){const[e,r]=await i.handleMessage({id:d,channel:n.channel,data:n.data});if(e)return u({type:"error",channel:n.channel,ref:n.ref,code:e.code,msg:e.msg});if(void 0===n.ref)return;try{return u({type:"ack",channel:n.channel,ref:n.ref,data:r})}catch(e){return u({type:"error",channel:n.channel,ref:n.ref,code:500,msg:"The handler returned something that cannot be sent"})}}if("unsubscribe"===n.type)return i.unsubscribe({id:d,channel:n.channel}),u({type:"unsubscribed",channel:n.channel});u({type:"error",code:400,msg:`Unknown frame type "${n.type}"`})}),s.on("close",e=>{d&&i.removeSubscriber({id:d,reason:e})})};
|
|
2
|
+
//# sourceMappingURL=C:\Users\dusti\dev\kempo\dist\kempo\api\realtime\WS.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"src\\kempo\\api\\realtime\\WS.js","names":["getSession","getHub","TOO_MANY_CONNECTIONS_CODE","async","request","socket","token","cookies","session_token","error","sessionData","code","reject","hub","send","frame","options","JSON","stringify","subscriberId","on","addError","added","addSubscriber","user","path","deliver","close","reason","msg","id","data","userId","type","isBinary","parse","parseError","touch","subscribeError","subscribe","channel","since","sendError","result","handleMessage","ref","undefined","serializeError","unsubscribe","removeSubscriber"],"sources":["0"],"sourcesContent":["import getSession from '../../../../server/utils/auth/getSession.js';\nimport getHub from '../../../../server/utils/realtime/getHub.js';\nimport { TOO_MANY_CONNECTIONS_CODE } from '../../../../server/utils/realtime/constants.js';\n\n/*\n The realtime socket, served at /kempo/api/realtime.\n\n This is only the HTTP layer: it turns the session cookie into a user, hands frames to the hub, and\n hands the hub's frames back to the socket. Channels, authorization, delivery and replay all live in\n server/utils/realtime.\n\n Client to server: { type: 'subscribe', channel, since? }, { type: 'unsubscribe', channel } and\n { type: 'send', channel, data, ref? }. A send is handed to the channel's own handler; with a `ref` the\n handler's return value comes back as an ack carrying the same ref.\n Server to client: ready, subscribed, unsubscribed, message, direct, ack, gap and error frames.\n*/\nexport default async (request, socket) => {\n const token = request.cookies.session_token;\n const [error, sessionData] = await getSession({ token });\n\n if(error){\n return error.code === 500\n ? socket.reject(500, 'Failed to verify session')\n : socket.reject(401, 'Authentication required');\n }\n\n const hub = getHub();\n const send = (frame, options) => socket.send(JSON.stringify(frame), options);\n let subscriberId = null;\n\n /*\n Registered on open rather than here. This route runs before the handshake completes, so a client\n that disconnects in between would otherwise leave a subscriber that no close event ever removes.\n */\n socket.on('open', () => {\n const [addError, added] = hub.addSubscriber({\n token,\n user: sessionData.user,\n path: request.path,\n deliver: send,\n close: (code, reason) => socket.close(code, reason)\n });\n\n if(addError){\n // The user is at their connection limit: retrying would be refused again, so tell the client to stop\n socket.close(addError.code === 429 ? TOO_MANY_CONNECTIONS_CODE : 1011, addError.msg);\n return;\n }\n\n subscriberId = added.id;\n socket.data.userId = sessionData.user.id;\n send({ type: 'ready', userId: sessionData.user.id });\n });\n\n socket.on('message', async (data, isBinary) => {\n if(!subscriberId) return;\n\n let frame;\n try {\n frame = isBinary ? null : JSON.parse(data);\n } catch(parseError) {\n frame = null;\n }\n if(!frame || typeof frame !== 'object'){\n return send({ type: 'error', code: 400, msg: 'Frames must be JSON objects' });\n }\n\n hub.touch({ id: subscriberId });\n\n if(frame.type === 'subscribe'){\n const [subscribeError] = await hub.subscribe({ id: subscriberId, channel: frame.channel, since: frame.since });\n if(subscribeError){\n send({ type: 'error', channel: frame.channel, code: subscribeError.code, msg: subscribeError.msg });\n }\n return;\n }\n\n if(frame.type === 'send'){\n const [sendError, result] = await hub.handleMessage({ id: subscriberId, channel: frame.channel, data: frame.data });\n\n if(sendError){\n return send({ type: 'error', channel: frame.channel, ref: frame.ref, code: sendError.code, msg: sendError.msg });\n }\n if(frame.ref === undefined) return;\n\n try {\n return send({ type: 'ack', channel: frame.channel, ref: frame.ref, data: result });\n } catch(serializeError) {\n return send({ type: 'error', channel: frame.channel, ref: frame.ref, code: 500, msg: 'The handler returned something that cannot be sent' });\n }\n }\n\n if(frame.type === 'unsubscribe'){\n hub.unsubscribe({ id: subscriberId, channel: frame.channel });\n return send({ type: 'unsubscribed', channel: frame.channel });\n }\n\n send({ type: 'error', code: 400, msg: `Unknown frame type \"${frame.type}\"` });\n });\n\n socket.on('close', (code) => {\n if(subscriberId) hub.removeSubscriber({ id: subscriberId, reason: code });\n });\n};\n"],"mappings":"OAAOA,MAAgB,qDAChBC,MAAY,kFACVC,MAAiC,gEAc3BC,MAAOC,EAASC,KAC7B,MAAMC,EAAQF,EAAQG,QAAQC,eACvBC,EAAOC,SAAqBV,EAAW,CAAEM,UAEhD,GAAGG,EACD,OAAsB,MAAfA,EAAME,KACTN,EAAOO,OAAO,IAAK,4BACnBP,EAAOO,OAAO,IAAK,2BAGzB,MAAMC,EAAMZ,IACNa,EAAO,CAACC,EAAOC,IAAYX,EAAOS,KAAKG,KAAKC,UAAUH,GAAQC,GACpE,IAAIG,EAAe,KAMnBd,EAAOe,GAAG,OAAQ,KAChB,MAAOC,EAAUC,GAAST,EAAIU,cAAc,CAC1CjB,QACAkB,KAAMd,EAAYc,KAClBC,KAAMrB,EAAQqB,KACdC,QAASZ,EACTa,MAAO,CAAChB,EAAMiB,IAAWvB,EAAOsB,MAAMhB,EAAMiB,KAG3CP,EAEDhB,EAAOsB,MAAwB,MAAlBN,EAASV,KAAeT,EAA4B,KAAMmB,EAASQ,MAIlFV,EAAeG,EAAMQ,GACrBzB,EAAO0B,KAAKC,OAAStB,EAAYc,KAAKM,GACtChB,EAAK,CAAEmB,KAAM,QAASD,OAAQtB,EAAYc,KAAKM,QAGjDzB,EAAOe,GAAG,UAAWjB,MAAO4B,EAAMG,KAChC,IAAIf,EAAc,OAElB,IAAIJ,EACJ,IACEA,EAAQmB,EAAW,KAAOjB,KAAKkB,MAAMJ,EACvC,CAAE,MAAMK,GACNrB,EAAQ,IACV,CACA,IAAIA,GAA0B,iBAAVA,EAClB,OAAOD,EAAK,CAAEmB,KAAM,QAAStB,KAAM,IAAKkB,IAAK,gCAK/C,GAFAhB,EAAIwB,MAAM,CAAEP,GAAIX,IAEE,cAAfJ,EAAMkB,KAAqB,CAC5B,MAAOK,SAAwBzB,EAAI0B,UAAU,CAAET,GAAIX,EAAcqB,QAASzB,EAAMyB,QAASC,MAAO1B,EAAM0B,QAItG,YAHGH,GACDxB,EAAK,CAAEmB,KAAM,QAASO,QAASzB,EAAMyB,QAAS7B,KAAM2B,EAAe3B,KAAMkB,IAAKS,EAAeT,MAGjG,CAEA,GAAkB,SAAfd,EAAMkB,KAAgB,CACvB,MAAOS,EAAWC,SAAgB9B,EAAI+B,cAAc,CAAEd,GAAIX,EAAcqB,QAASzB,EAAMyB,QAAST,KAAMhB,EAAMgB,OAE5G,GAAGW,EACD,OAAO5B,EAAK,CAAEmB,KAAM,QAASO,QAASzB,EAAMyB,QAASK,IAAK9B,EAAM8B,IAAKlC,KAAM+B,EAAU/B,KAAMkB,IAAKa,EAAUb,MAE5G,QAAiBiB,IAAd/B,EAAM8B,IAAmB,OAE5B,IACE,OAAO/B,EAAK,CAAEmB,KAAM,MAAOO,QAASzB,EAAMyB,QAASK,IAAK9B,EAAM8B,IAAKd,KAAMY,GAC3E,CAAE,MAAMI,GACN,OAAOjC,EAAK,CAAEmB,KAAM,QAASO,QAASzB,EAAMyB,QAASK,IAAK9B,EAAM8B,IAAKlC,KAAM,IAAKkB,IAAK,sDACvF,CACF,CAEA,GAAkB,gBAAfd,EAAMkB,KAEP,OADApB,EAAImC,YAAY,CAAElB,GAAIX,EAAcqB,QAASzB,EAAMyB,UAC5C1B,EAAK,CAAEmB,KAAM,eAAgBO,QAASzB,EAAMyB,UAGrD1B,EAAK,CAAEmB,KAAM,QAAStB,KAAM,IAAKkB,IAAK,uBAAuBd,EAAMkB,YAGrE5B,EAAOe,GAAG,QAAUT,IACfQ,GAAcN,EAAIoC,iBAAiB,CAAEnB,GAAIX,EAAcS,OAAQjB","ignoreList":[]}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import s from"../../../../../server/utils/permissions/currentUserHasPermission.js";import r from"../../../../../server/utils/realtime/listConnections.js";export default async(e,t)=>{const o=e.cookies.session_token,[i,n]=await s(o,"system:realtime:read");if(i)return t.status(i.code).json({error:i.msg});if(!n)return t.status(403).json({error:"Insufficient permissions"});const[m,a]=r();if(m)return t.status(m.code).json({error:m.msg});t.json(a)};
|
|
2
|
+
//# sourceMappingURL=C:\Users\dusti\dev\kempo\dist\kempo\api\realtime\connections\GET.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"src\\kempo\\api\\realtime\\connections\\GET.js","names":["currentUserHasPermission","listConnections","async","request","response","token","cookies","session_token","permError","hasPermission","status","code","json","error","msg","data"],"sources":["0"],"sourcesContent":["import currentUserHasPermission from '../../../../../server/utils/permissions/currentUserHasPermission.js';\nimport listConnections from '../../../../../server/utils/realtime/listConnections.js';\n\nexport default async (request, response) => {\n const token = request.cookies.session_token;\n const [permError, hasPermission] = await currentUserHasPermission(token, 'system:realtime: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 [error, data] = listConnections();\n\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,MAAqB,yEAEbC,MAAOC,EAASC,KAC7B,MAAMC,EAAQF,EAAQG,QAAQC,eACvBC,EAAWC,SAAuBT,EAAyBK,EAAO,wBAEzE,GAAGG,EACD,OAAOJ,EAASM,OAAOF,EAAUG,MAAMC,KAAK,CAAEC,MAAOL,EAAUM,MAGjE,IAAIL,EACF,OAAOL,EAASM,OAAO,KAAKE,KAAK,CAAEC,MAAO,6BAG5C,MAAOA,EAAOE,GAAQd,IAEtB,GAAGY,EACD,OAAOT,EAASM,OAAOG,EAAMF,MAAMC,KAAK,CAAEC,MAAOA,EAAMC,MAGzDV,EAASQ,KAAKG","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path fill="currentColor" d="M880-720v480q0 33-23.5 56.5T800-160H160q-33 0-56.5-23.5T80-240v-480q0-33 23.5-56.5T160-800h640q33 0 56.5 23.5T880-720ZM160-640h640v-80H160v80Zm0 160v240h640v-240H160Zm0 240v-480 480Z"/></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 -960 960 960"><path fill="currentColor" d="M197-197q-54-55-85.5-127.5T80-480q0-84 31.5-156.5T197-763l57 57q-44 44-69 102t-25 124q0 67 25 125t69 101l-57 57Zm113-113q-32-33-51-76.5T240-480q0-51 19-94.5t51-75.5l57 57q-22 22-34.5 51T320-480q0 33 12.5 62t34.5 51l-57 57Zm113.5-113.5Q400-447 400-480t23.5-56.5Q447-560 480-560t56.5 23.5Q560-513 560-480t-23.5 56.5Q513-400 480-400t-56.5-23.5ZM650-310l-57-57q22-22 34.5-51t12.5-62q0-33-12.5-62T593-593l57-57q32 32 51 75.5t19 94.5q0 50-19 93.5T650-310Zm113 113-57-57q44-44 69-102t25-124q0-67-25-125t-69-101l57-57q54 54 85.5 126.5T880-480q0 83-31.5 155.5T763-197Z"/></svg>
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
const e=1001,t=async()=>{try{const e=await fetch("/kempo/api/auth/session");if(!e.ok)return!0;const t=await e.json();return Boolean(t.user)}catch(e){return!0}};export class RealtimeClient{#e;#t;#s;#i;#n;#r;#o=null;#a="idle";#d=0;#c=null;#h=!1;#l=new Map;#u={status:new Set,ready:new Set,direct:new Set};#p=new Map;#f=1;userId=null;constructor({url:e,WebSocket:s=globalThis.WebSocket,checkSession:i=t,backoff:n={},random:r=Math.random}={}){this.#e=e,this.#t=s,this.#s=i,this.#i=n.base??1e3,this.#n=n.max??3e4,this.#r=r}get status(){return this.#a}onStatus=e=>(this.#u.status.add(e),()=>this.#u.status.delete(e));onReady=e=>(this.#u.ready.add(e),this.userId&&e(this.userId),()=>this.#u.ready.delete(e));onDirect=e=>(this.#u.direct.add(e),()=>this.#u.direct.delete(e));send=(e,t,{timeout:s=1e4}={})=>new Promise((i,n)=>{if(1!==this.#o?.readyState)return void n({code:503,msg:"Not connected"});const r=this.#f++,o=setTimeout(()=>{this.#p.delete(r),n({code:504,msg:"No reply from the server"})},s);this.#p.set(r,{resolve:i,reject:n,timer:o}),this.#m({type:"send",channel:e,data:t,ref:r})});subscribe=(e,t,{since:s,onGap:i,onError:n,onSubscribed:r}={})=>{let o=this.#l.get(e);return o||(o={handlers:new Set,gapHandlers:new Set,errorHandlers:new Set,subscribedHandlers:new Set,lastId:s??null,failed:!1,confirmed:!1},this.#l.set(e,o)),o.handlers.add(t),i&&o.gapHandlers.add(i),n&&o.errorHandlers.add(n),r&&o.subscribedHandlers.add(r),1===o.handlers.size?this.#b(e,o):r&&o.confirmed&&queueMicrotask(()=>this.#y(()=>r({channel:e}))),()=>{o.handlers.delete(t),i&&o.gapHandlers.delete(i),n&&o.errorHandlers.delete(n),r&&o.subscribedHandlers.delete(r),o.handlers.size||(this.#l.delete(e),this.#m({type:"unsubscribe",channel:e}))}};start=()=>{this.#o||this.#h||this.#g()};close=()=>{this.#h=!0,clearTimeout(this.#c),this.#c=null,this.#S({code:503,msg:"Client closed"}),this.#k("closed"),this.#o?.close(1e3),this.#o=null};#g=()=>{this.#k(this.#d>0?"reconnecting":"connecting");let e=!1,t=!1;const s=new this.#t(this.#e??`${"https:"===location.protocol?"wss:":"ws:"}//${location.host}/kempo/api/realtime`);this.#o=s;const i=i=>{t||(t=!0,this.#o===s&&(this.#o=null),this.#S({code:503,msg:"Connection lost"}),this.#w(i,e))};s.addEventListener("open",()=>{e=!0,this.#d=0,this.#k("open");for(const[e,t]of this.#l)t.confirmed=!1,this.#b(e,t)}),s.addEventListener("message",e=>this.#v(e.data)),s.addEventListener("close",e=>i(e.code)),s.addEventListener("error",()=>{e||i(1006)})};#w=async(t,s)=>{if(this.#h)return;if(4401===t)return this.#h=!0,void this.#k("unauthenticated");if(4429===t)return this.#h=!0,void this.#k("refused");if(!s&&t!==e){const e=await this.#s();if(this.#h)return;if(!1===e)return this.#h=!0,void this.#k("unauthenticated")}this.#k("reconnecting"),this.#d+=t===e?0:1;const i=Math.min(this.#n,this.#i*2**Math.max(0,this.#d-1)),n=t===e?Math.min(250,this.#i):i*(.5+.5*this.#r());this.#c=setTimeout(()=>{this.#c=null,this.#h||this.#g()},n)};#b=(e,t)=>{if(t.failed)return;const s={type:"subscribe",channel:e};null!==t.lastId&&(s.since=t.lastId),this.#m(s)};#m=e=>{1===this.#o?.readyState&&this.#o.send(JSON.stringify(e))};#v=e=>{let t;try{t=JSON.parse(e)}catch(e){return}if("ready"===t.type){this.userId=t.userId;for(const e of this.#u.ready)e(t.userId);return}if("direct"===t.type){for(const e of this.#u.direct)this.#y(()=>e(t.data));return}if(("ack"===t.type||"error"===t.type)&&void 0!==t.ref){const e=this.#p.get(t.ref);if(!e)return;return this.#p.delete(t.ref),clearTimeout(e.timer),void("ack"===t.type?e.resolve(t.data):e.reject({code:t.code,msg:t.msg}))}const s=this.#l.get(t.channel);if(s)if("subscribed"!==t.type)if("message"!==t.type)if("gap"!==t.type){if("error"===t.type){s.failed=!0;for(const e of s.errorHandlers)this.#y(()=>e({channel:t.channel,code:t.code,msg:t.msg}))}}else for(const e of s.gapHandlers)this.#y(()=>e({channel:t.channel}));else{void 0!==t.id&&(s.lastId=t.id);for(const e of s.handlers)this.#y(()=>e(t.data,{channel:t.channel,id:t.id}))}else{s.confirmed=!0;for(const e of s.subscribedHandlers)this.#y(()=>e({channel:t.channel}))}};#S=e=>{for(const[t,s]of this.#p)clearTimeout(s.timer),s.reject(e),this.#p.delete(t)};#y=e=>{try{e()}catch(e){console.error("[kempo realtime] a handler threw:",e)}};#k=e=>{if(this.#a!==e){this.#a=e;for(const t of this.#u.status)this.#y(()=>t(e))}}}export const connect=e=>{const t=new RealtimeClient(e);return t.start(),t};
|
|
2
|
+
//# sourceMappingURL=C:\Users\dusti\dev\kempo\dist\kempo\realtime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"src\\kempo\\realtime.js","names":["GOING_AWAY","defaultCheckSession","async","response","fetch","ok","body","json","Boolean","user","error","RealtimeClient","url","WebSocketImpl","checkSession","base","max","random","socket","status","attempts","timer","stopped","subscriptions","Map","listeners","Set","ready","direct","pending","nextRef","userId","constructor","WebSocket","globalThis","backoff","Math","this","onStatus","listener","add","delete","onReady","onDirect","send","channel","data","timeout","Promise","resolve","reject","readyState","code","msg","ref","setTimeout","set","type","subscribe","handler","since","onGap","onError","onSubscribed","subscription","get","handlers","gapHandlers","errorHandlers","subscribedHandlers","lastId","failed","confirmed","size","sendSubscribe","queueMicrotask","safely","start","open","close","clearTimeout","rejectPending","setStatus","opened","finished","location","protocol","host","finish","closed","addEventListener","event","received","signedIn","exponential","min","delay","frame","JSON","stringify","raw","parse","undefined","id","fn","console","connect","options","client"],"sources":["0"],"sourcesContent":["/*\n Browser client for kempo's realtime socket.\n\n import { connect } from '/kempo/realtime.js';\n\n const realtime = connect();\n const stop = realtime.subscribe('my-extension:status', (data, { id }) => { ... }, {\n onGap: () => refetchEverything()\n });\n\n // Send to the channel's handler on the server, and wait for its reply\n const reply = await realtime.send('my-extension:status', { action: 'ping' });\n\n A browser does not reconnect a WebSocket that closes, so this does: with backoff, resubscribing to\n every channel and asking for what it missed since the last message it saw. It stops for good when the\n session has ended, since retrying could never succeed.\n*/\n\nconst DEFAULT_PATH = '/kempo/api/realtime';\nconst SESSION_ENDED = 4401;\nconst TOO_MANY_CONNECTIONS = 4429;\nconst GOING_AWAY = 1001;\n\nconst defaultUrl = () => `${location.protocol === 'https:' ? 'wss:' : 'ws:'}//${location.host}${DEFAULT_PATH}`;\n\n/*\n Distinguishes \"signed out\" from \"the network is down\". A failed handshake looks identical either way\n to a browser (a bare close with no status), so this asks the session endpoint. Only a definite answer\n that there is no session stops the retrying; anything unclear keeps trying.\n*/\nconst defaultCheckSession = async () => {\n try {\n const response = await fetch('/kempo/api/auth/session');\n if(!response.ok) return true;\n const body = await response.json();\n return Boolean(body.user);\n } catch(error) {\n return true;\n }\n};\n\nexport class RealtimeClient {\n #url;\n #WebSocketImpl;\n #checkSession;\n #base;\n #max;\n #random;\n #socket = null;\n #status = 'idle';\n #attempts = 0;\n #timer = null;\n #stopped = false;\n #subscriptions = new Map();\n #listeners = { status: new Set(), ready: new Set(), direct: new Set() };\n #pending = new Map();\n #nextRef = 1;\n\n userId = null;\n\n constructor({\n url,\n WebSocket: WebSocketImpl = globalThis.WebSocket,\n checkSession = defaultCheckSession,\n backoff = {},\n random = Math.random\n } = {}){\n this.#url = url;\n this.#WebSocketImpl = WebSocketImpl;\n this.#checkSession = checkSession;\n this.#base = backoff.base ?? 1000;\n this.#max = backoff.max ?? 30000;\n this.#random = random;\n }\n\n /*\n State\n */\n\n get status(){\n return this.#status;\n }\n\n onStatus = (listener) => {\n this.#listeners.status.add(listener);\n return () => this.#listeners.status.delete(listener);\n };\n\n onReady = (listener) => {\n this.#listeners.ready.add(listener);\n if(this.userId) listener(this.userId);\n return () => this.#listeners.ready.delete(listener);\n };\n\n // Messages the server sent to this connection alone, rather than to a channel\n onDirect = (listener) => {\n this.#listeners.direct.add(listener);\n return () => this.#listeners.direct.delete(listener);\n };\n\n /*\n Sending\n\n A message goes to the channel's handler on the server, and the promise settles with what the handler\n returned, or rejects with { code, msg }. It is not queued while disconnected: a message a game or an\n editor sends is stale by the time the connection comes back, so the caller is told it did not go.\n */\n\n send = (channel, data, { timeout = 10000 } = {}) => new Promise((resolve, reject) => {\n if(this.#socket?.readyState !== 1){\n reject({ code: 503, msg: 'Not connected' });\n return;\n }\n\n const ref = this.#nextRef++;\n const timer = setTimeout(() => {\n this.#pending.delete(ref);\n reject({ code: 504, msg: 'No reply from the server' });\n }, timeout);\n\n this.#pending.set(ref, { resolve, reject, timer });\n this.#send({ type: 'send', channel, data, ref });\n });\n\n /*\n Subscriptions\n\n Several handlers can share one channel; the server is only told when the first arrives and when the\n last leaves. `since` lets a caller that remembers the last id it processed (across a page load, say)\n resume from there rather than from now.\n */\n\n subscribe = (channel, handler, { since, onGap, onError, onSubscribed } = {}) => {\n let subscription = this.#subscriptions.get(channel);\n\n if(!subscription){\n subscription = { handlers: new Set(), gapHandlers: new Set(), errorHandlers: new Set(), subscribedHandlers: new Set(), lastId: since ?? null, failed: false, confirmed: false };\n this.#subscriptions.set(channel, subscription);\n }\n\n subscription.handlers.add(handler);\n if(onGap) subscription.gapHandlers.add(onGap);\n if(onError) subscription.errorHandlers.add(onError);\n if(onSubscribed) subscription.subscribedHandlers.add(onSubscribed);\n\n // A repeat handler on a channel the server already confirmed needs no frame; a first one does\n if(subscription.handlers.size === 1) this.#sendSubscribe(channel, subscription);\n // The server will not confirm again, so a late arrival is told straight away what it is waiting for\n else if(onSubscribed && subscription.confirmed) queueMicrotask(() => this.#safely(() => onSubscribed({ channel })));\n\n return () => {\n subscription.handlers.delete(handler);\n if(onGap) subscription.gapHandlers.delete(onGap);\n if(onError) subscription.errorHandlers.delete(onError);\n if(onSubscribed) subscription.subscribedHandlers.delete(onSubscribed);\n\n if(!subscription.handlers.size){\n this.#subscriptions.delete(channel);\n this.#send({ type: 'unsubscribe', channel });\n }\n };\n };\n\n /*\n Lifecycle\n */\n\n start = () => {\n if(this.#socket || this.#stopped) return;\n this.#open();\n };\n\n close = () => {\n this.#stopped = true;\n clearTimeout(this.#timer);\n this.#timer = null;\n this.#rejectPending({ code: 503, msg: 'Client closed' });\n this.#setStatus('closed');\n this.#socket?.close(1000);\n this.#socket = null;\n };\n\n #open = () => {\n this.#setStatus(this.#attempts > 0 ? 'reconnecting' : 'connecting');\n\n let opened = false;\n let finished = false;\n const socket = new this.#WebSocketImpl(this.#url ?? defaultUrl());\n this.#socket = socket;\n\n // One attempt ends once, however many of error and close report it\n const finish = (code) => {\n if(finished) return;\n finished = true;\n if(this.#socket === socket) this.#socket = null;\n this.#rejectPending({ code: 503, msg: 'Connection lost' });\n this.#closed(code, opened);\n };\n\n socket.addEventListener('open', () => {\n opened = true;\n this.#attempts = 0;\n this.#setStatus('open');\n for(const [channel, subscription] of this.#subscriptions){\n subscription.confirmed = false;\n this.#sendSubscribe(channel, subscription);\n }\n });\n\n socket.addEventListener('message', event => this.#received(event.data));\n\n socket.addEventListener('close', event => finish(event.code));\n\n /*\n A browser follows a failed connection with a close event; Node's WebSocket sends only the error. A\n client that waited for close would then never retry, so a failure before the socket opened ends the\n attempt on its own. After it opened, an error is always followed by a close carrying the real code.\n */\n socket.addEventListener('error', () => {\n if(!opened) finish(1006);\n });\n };\n\n #closed = async (code, opened) => {\n if(this.#stopped) return;\n\n if(code === SESSION_ENDED){\n this.#stopped = true;\n this.#setStatus('unauthenticated');\n return;\n }\n\n // The user is at their connection limit; reconnecting would only be refused again\n if(code === TOO_MANY_CONNECTIONS){\n this.#stopped = true;\n this.#setStatus('refused');\n return;\n }\n\n /*\n A handshake that never completed is either a network problem or a refused session, and the browser\n cannot say which, so ask. A restart (1001) is neither, so it skips the check and comes straight back.\n */\n if(!opened && code !== GOING_AWAY){\n const signedIn = await this.#checkSession();\n if(this.#stopped) return;\n if(signedIn === false){\n this.#stopped = true;\n this.#setStatus('unauthenticated');\n return;\n }\n }\n\n this.#setStatus('reconnecting');\n this.#attempts += code === GOING_AWAY ? 0 : 1;\n\n const exponential = Math.min(this.#max, this.#base * 2 ** Math.max(0, this.#attempts - 1));\n // Jitter, so a restart does not bring every client back in the same instant\n const delay = code === GOING_AWAY ? Math.min(250, this.#base) : exponential * (0.5 + this.#random() * 0.5);\n\n this.#timer = setTimeout(() => {\n this.#timer = null;\n if(!this.#stopped) this.#open();\n }, delay);\n };\n\n /*\n Frames\n */\n\n #sendSubscribe = (channel, subscription) => {\n if(subscription.failed) return;\n const frame = { type: 'subscribe', channel };\n if(subscription.lastId !== null) frame.since = subscription.lastId;\n this.#send(frame);\n };\n\n #send = (frame) => {\n if(this.#socket?.readyState === 1) this.#socket.send(JSON.stringify(frame));\n };\n\n #received = (raw) => {\n let frame;\n try {\n frame = JSON.parse(raw);\n } catch(error) {\n return;\n }\n\n if(frame.type === 'ready'){\n this.userId = frame.userId;\n for(const listener of this.#listeners.ready) listener(frame.userId);\n return;\n }\n\n if(frame.type === 'direct'){\n for(const listener of this.#listeners.direct) this.#safely(() => listener(frame.data));\n return;\n }\n\n // A reply to a send(), matched by its ref before anything is routed by channel\n if((frame.type === 'ack' || frame.type === 'error') && frame.ref !== undefined){\n const pending = this.#pending.get(frame.ref);\n if(!pending) return;\n this.#pending.delete(frame.ref);\n clearTimeout(pending.timer);\n if(frame.type === 'ack') pending.resolve(frame.data);\n else pending.reject({ code: frame.code, msg: frame.msg });\n return;\n }\n\n const subscription = this.#subscriptions.get(frame.channel);\n if(!subscription) return;\n\n // The server has granted the subscription, on the first connection and again after every reconnect\n if(frame.type === 'subscribed'){\n subscription.confirmed = true;\n for(const handler of subscription.subscribedHandlers) this.#safely(() => handler({ channel: frame.channel }));\n return;\n }\n\n if(frame.type === 'message'){\n if(frame.id !== undefined) subscription.lastId = frame.id;\n for(const handler of subscription.handlers) this.#safely(() => handler(frame.data, { channel: frame.channel, id: frame.id }));\n return;\n }\n\n if(frame.type === 'gap'){\n for(const handler of subscription.gapHandlers) this.#safely(() => handler({ channel: frame.channel }));\n return;\n }\n\n if(frame.type === 'error'){\n // A refused subscription would be refused again on every reconnect, so it is not retried\n subscription.failed = true;\n for(const handler of subscription.errorHandlers) this.#safely(() => handler({ channel: frame.channel, code: frame.code, msg: frame.msg }));\n }\n };\n\n #rejectPending = (error) => {\n for(const [ref, pending] of this.#pending){\n clearTimeout(pending.timer);\n pending.reject(error);\n this.#pending.delete(ref);\n }\n };\n\n // One handler throwing must not stop the others, or the frames behind it\n #safely = (fn) => {\n try {\n fn();\n } catch(error) {\n console.error('[kempo realtime] a handler threw:', error);\n }\n };\n\n #setStatus = (status) => {\n if(this.#status === status) return;\n this.#status = status;\n for(const listener of this.#listeners.status) this.#safely(() => listener(status));\n };\n}\n\nexport const connect = (options) => {\n const client = new RealtimeClient(options);\n client.start();\n return client;\n};\n"],"mappings":"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","ignoreList":[]}
|
package/dist/kempo/sdk.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{get as e,post as s,put as o,patch as n,del as t}from"./fetch.js";const r="/kempo/api";export const register=async({email:e,password:o,name:n})=>s(`${r}/auth/register/email`,{email:e,password:o,name:n});export const login=async({email:e,password:o})=>s(`${r}/auth/login/email`,{email:e,password:o});export const logout=async()=>s(`${r}/auth/logout`,{});export const getSession=async()=>e(`${r}/auth/session`);export const forgotPassword=async({email:e})=>s(`${r}/forgot-password`,{email:e});export const resetPassword=async({token:e,password:o,logoutAll:n=!1})=>s(`${r}/auth/reset-password`,{token:e,newPassword:o,logoutAll:n});export const changePassword=async({currentPassword:e,newPassword:o,logoutAll:n})=>s(`${r}/auth/change-password`,{currentPassword:e,newPassword:o,logoutAll:n});export const verifyEmail=async({token:e})=>s(`${r}/auth/verify-email`,{token:e});export const currentUserHasPermission=async({permission:s})=>e(`${r}/user/current/permissions`,{permission:s});export const currentUserHasAllPermissions=async({permissions:s})=>e(`${r}/user/current/permissions/all`,{permissions:s});export const currentUserHasSomePermissions=async({permissions:s})=>e(`${r}/user/current/permissions/some`,{permissions:s});export const getAllCurrentUserPermissions=async()=>e(`${r}/user/current/permissions/list`);export const userHasPermission=async({userid:s,permission:o})=>e(`${r}/user/${s}/permissions`,{permission:o});export const userHasAllPermissions=async({userid:s,permissions:o})=>e(`${r}/user/${s}/permissions/all`,{permissions:o});export const userHasSomePermissions=async({userid:s,permissions:o})=>e(`${r}/user/${s}/permissions/some`,{permissions:o});export const getAllUserPermissions=async({userid:s})=>e(`${r}/user/${s}/permissions/list`);export const getUsers=async({limit:s,offset:o}={})=>e(`${r}/user`,{limit:s,offset:o});export const searchUsers=async({q:s,limit:o,offset:n,inGroup:t,notInGroup:a}={})=>e(`${r}/user/search`,{q:s,limit:o,offset:n,inGroup:t,notInGroup:a});export const createUser=async({name:e,email:o,password:n,emailVerified:t})=>s(`${r}/user/create`,{name:e,email:o,password:n,emailVerified:t});export const deleteUsers=async e=>t(`${r}/user`,{ids:e});export const updateUser=async({id:e,name:s,email:o,emailVerified:t,createdAt:a})=>n(`${r}/user`,{id:e,name:s,email:o,emailVerified:t,createdAt:a});export const getUser=async s=>e(`${r}/user/${s}`);export const getUserSessions=async(s,{limit:o,offset:n}={})=>e(`${r}/user/${s}/sessions`,{limit:o,offset:n});export const deleteUserSession=async(e,s)=>t(`${r}/user/${e}/sessions`,{sessionToken:s});export const deleteExpiredUserSessions=async e=>t(`${r}/user/${e}/sessions/expired`);export const getUserGroups=async(s,{limit:o,offset:n}={})=>e(`${r}/user/${s}/groups`,{limit:o,offset:n});export const addUserToGroup=async(e,o)=>s(`${r}/user/${e}/groups`,{groupName:o});export const removeUserFromGroup=async(e,s)=>t(`${r}/user/${e}/groups`,{groupName:s});export const listGroups=async({limit:s,offset:o,owner:n}={})=>e(`${r}/groups`,{limit:s,offset:o,owner:n});export const createGroup=async({name:e,description:o})=>s(`${r}/groups`,{name:e,description:o});export const updateGroup=async({name:e,newName:s,description:o})=>n(`${r}/groups`,{name:e,newName:s,description:o});export const deleteGroups=async e=>t(`${r}/groups`,{names:e});export const getGroup=async s=>e(`${r}/groups/${encodeURIComponent(s)}`);export const getGroupMembers=async(s,{limit:o,offset:n}={})=>e(`${r}/groups/${encodeURIComponent(s)}/members`,{limit:o,offset:n});export const addMemberToGroup=async(e,o)=>s(`${r}/groups/${encodeURIComponent(e)}/members`,{userId:o});export const removeMemberFromGroup=async(e,s)=>t(`${r}/groups/${encodeURIComponent(e)}/members`,{userId:s});export const getGroupPermissions=async s=>e(`${r}/groups/${encodeURIComponent(s)}/permissions`);export const addPermissionToGroup=async(e,o)=>s(`${r}/groups/${encodeURIComponent(e)}/permissions`,{permissionName:o});export const removePermissionFromGroup=async(e,s)=>t(`${r}/groups/${encodeURIComponent(e)}/permissions`,{permissionName:s});export const listPermissions=async({limit:s,offset:o,owner:n}={})=>e(`${r}/permissions`,{limit:s,offset:o,owner:n});export const createPermissions=async e=>s(`${r}/permissions`,{permissions:e});export const updatePermission=async({name:e,description:s})=>n(`${r}/permissions`,{name:e,description:s});export const deletePermissions=async e=>t(`${r}/permissions`,{names:e});export const getSetting=async(s,o)=>e(`${r}/settings/${encodeURIComponent(s)}/${encodeURIComponent(o)}`);export const listSettings=async({owner:s,limit:o,offset:n}={})=>e(`${r}/settings/${encodeURIComponent(s)}`,{limit:o,offset:n});export const setSetting=async(e,o,n)=>s(`${r}/settings/${encodeURIComponent(e)}/${encodeURIComponent(o)}`,n);export const deleteSetting=async(e,s)=>t(`${r}/settings/${encodeURIComponent(e)}/${encodeURIComponent(s)}`);export const listPages=async({owner:s,showHidden:o,offset:n,limit:t}={})=>e(`${r}/pages`,{owner:s,showHidden:o,offset:n,limit:t});export const rescanPages=async()=>s(`${r}/pages/rescan`,{});export const listTemplates=async()=>e(`${r}/templates`);export const listDirectories=async()=>e(`${r}/pages/directories`);export const getPage=async s=>e(`${r}/pages/file`,{file:s});export const createPage=async({directory:e,name:o,template:n})=>s(`${r}/pages`,{directory:e,name:o,template:n});export const updatePage=async({file:e,name:s,title:n,description:t,author:a,template:i,contents:c,extraMetadata:l})=>o(`${r}/pages/file`,{file:e,name:s,title:n,description:t,author:a,template:i,contents:c,extraMetadata:l});export const deletePages=async e=>t(`${r}/pages`,{files:e});export const disablePage=async e=>o(`${r}/pages/disable`,{file:e});export const enablePage=async e=>o(`${r}/pages/enable`,{file:e});export const movePage=async({file:e,newFile:s})=>n(`${r}/pages/file`,{file:e,newFile:s});export const searchPagesByMetadata=async s=>e(`${r}/pages/search`,{query:JSON.stringify(s)});export const setPageLocked=async({file:e,locked:s})=>o(`${r}/pages/lock`,{file:e,locked:s});export const getTemplate=async s=>e(`${r}/templates/file`,{file:s});export const createTemplate=async({directory:e,name:o,copyFrom:n})=>s(`${r}/templates`,{directory:e,name:o,copyFrom:n});export const updateTemplate=async({file:e,name:s,author:n,markup:t})=>o(`${r}/templates/file`,{file:e,name:s,author:n,markup:t});export const deleteTemplates=async e=>t(`${r}/templates`,{files:e});export const disableTemplate=async e=>o(`${r}/templates/disable`,{file:e});export const enableTemplate=async e=>o(`${r}/templates/enable`,{file:e});export const moveTemplate=async({file:e,newFile:s})=>n(`${r}/templates/file`,{file:e,newFile:s});export const setTemplateLocked=async({file:e,locked:s})=>o(`${r}/templates/lock`,{file:e,locked:s});export const listFragments=async()=>e(`${r}/fragments`);export const getFragment=async s=>e(`${r}/fragments/file`,{file:s});export const createFragment=async({directory:e,name:o})=>s(`${r}/fragments`,{directory:e,name:o});export const updateFragment=async({file:e,author:s,markup:n})=>o(`${r}/fragments/file`,{file:e,author:s,markup:n});export const deleteFragments=async e=>t(`${r}/fragments`,{files:e});export const moveFragment=async({file:e,newFile:s})=>n(`${r}/fragments/file`,{file:e,newFile:s});export const disableFragment=async e=>o(`${r}/fragments/disable`,{file:e});export const enableFragment=async e=>o(`${r}/fragments/enable`,{file:e});export const setFragmentLocked=async({file:e,locked:s})=>o(`${r}/fragments/lock`,{file:e,locked:s});export const listGlobalContent=async()=>e(`${r}/globals`);export const getGlobalContent=async s=>e(`${r}/globals/entry`,{id:s});export const createGlobalContent=async({name:e,location:o,priority:n})=>s(`${r}/globals`,{name:e,location:o,priority:n});export const updateGlobalContent=async({id:e,name:s,location:n,priority:t,markup:a})=>o(`${r}/globals/entry`,{id:e,name:s,location:n,priority:t,markup:a});export const deleteGlobalContent=async e=>t(`${r}/globals`,{ids:e});export const disableGlobalContent=async e=>o(`${r}/globals/disable`,{id:e});export const enableGlobalContent=async e=>o(`${r}/globals/enable`,{id:e});export const setGlobalContentLocked=async({id:e,locked:s})=>o(`${r}/globals/lock`,{id:e,locked:s});export const listExtensions=async({limit:s,offset:o}={})=>e(`${r}/extensions`,{limit:s,offset:o});export const listAvailableExtensions=async()=>e(`${r}/extensions/available`);export const listKnownExtensions=async()=>e(`${r}/extensions/known`);export const installExtension=async e=>s(`${r}/extensions`,{name:e});export const uninstallExtension=async(e,s=!1)=>t(`${r}/extensions`,{name:e,purgeData:s});export const enableExtension=async e=>s(`${r}/extensions/${encodeURIComponent(e)}/enable`,{});export const disableExtension=async e=>s(`${r}/extensions/${encodeURIComponent(e)}/disable`,{});export const listAdminGlobalContent=async()=>e(`${r}/admin-globals`);export const getAdminGlobalContent=async s=>e(`${r}/admin-globals/${encodeURIComponent(s)}`);export const createAdminGlobalContent=async({name:e,location:o,priority:n,owner:t,markup:a})=>s(`${r}/admin-globals`,{name:e,location:o,priority:n,owner:t,markup:a});export const updateAdminGlobalContent=async(e,{name:s,location:n,priority:t,markup:a})=>o(`${r}/admin-globals/${encodeURIComponent(e)}`,{name:s,location:n,priority:t,markup:a});export const deleteAdminGlobalContent=async e=>t(`${r}/admin-globals`,{ids:e});export const enableAdminGlobalContent=async e=>o(`${r}/admin-globals/${encodeURIComponent(e)}/enable`,{});export const disableAdminGlobalContent=async e=>o(`${r}/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 r="/kempo/api";export const register=async({email:e,password:o,name:n})=>s(`${r}/auth/register/email`,{email:e,password:o,name:n});export const login=async({email:e,password:o})=>s(`${r}/auth/login/email`,{email:e,password:o});export const logout=async()=>s(`${r}/auth/logout`,{});export const getSession=async()=>e(`${r}/auth/session`);export const forgotPassword=async({email:e})=>s(`${r}/forgot-password`,{email:e});export const resetPassword=async({token:e,password:o,logoutAll:n=!1})=>s(`${r}/auth/reset-password`,{token:e,newPassword:o,logoutAll:n});export const changePassword=async({currentPassword:e,newPassword:o,logoutAll:n})=>s(`${r}/auth/change-password`,{currentPassword:e,newPassword:o,logoutAll:n});export const verifyEmail=async({token:e})=>s(`${r}/auth/verify-email`,{token:e});export const currentUserHasPermission=async({permission:s})=>e(`${r}/user/current/permissions`,{permission:s});export const currentUserHasAllPermissions=async({permissions:s})=>e(`${r}/user/current/permissions/all`,{permissions:s});export const currentUserHasSomePermissions=async({permissions:s})=>e(`${r}/user/current/permissions/some`,{permissions:s});export const getAllCurrentUserPermissions=async()=>e(`${r}/user/current/permissions/list`);export const userHasPermission=async({userid:s,permission:o})=>e(`${r}/user/${s}/permissions`,{permission:o});export const userHasAllPermissions=async({userid:s,permissions:o})=>e(`${r}/user/${s}/permissions/all`,{permissions:o});export const userHasSomePermissions=async({userid:s,permissions:o})=>e(`${r}/user/${s}/permissions/some`,{permissions:o});export const getAllUserPermissions=async({userid:s})=>e(`${r}/user/${s}/permissions/list`);export const getUsers=async({limit:s,offset:o}={})=>e(`${r}/user`,{limit:s,offset:o});export const searchUsers=async({q:s,limit:o,offset:n,inGroup:t,notInGroup:a}={})=>e(`${r}/user/search`,{q:s,limit:o,offset:n,inGroup:t,notInGroup:a});export const createUser=async({name:e,email:o,password:n,emailVerified:t})=>s(`${r}/user/create`,{name:e,email:o,password:n,emailVerified:t});export const deleteUsers=async e=>t(`${r}/user`,{ids:e});export const updateUser=async({id:e,name:s,email:o,emailVerified:t,createdAt:a})=>n(`${r}/user`,{id:e,name:s,email:o,emailVerified:t,createdAt:a});export const getUser=async s=>e(`${r}/user/${s}`);export const getUserSessions=async(s,{limit:o,offset:n}={})=>e(`${r}/user/${s}/sessions`,{limit:o,offset:n});export const deleteUserSession=async(e,s)=>t(`${r}/user/${e}/sessions`,{sessionToken:s});export const deleteExpiredUserSessions=async e=>t(`${r}/user/${e}/sessions/expired`);export const getUserGroups=async(s,{limit:o,offset:n}={})=>e(`${r}/user/${s}/groups`,{limit:o,offset:n});export const addUserToGroup=async(e,o)=>s(`${r}/user/${e}/groups`,{groupName:o});export const removeUserFromGroup=async(e,s)=>t(`${r}/user/${e}/groups`,{groupName:s});export const listGroups=async({limit:s,offset:o,owner:n}={})=>e(`${r}/groups`,{limit:s,offset:o,owner:n});export const createGroup=async({name:e,description:o})=>s(`${r}/groups`,{name:e,description:o});export const updateGroup=async({name:e,newName:s,description:o})=>n(`${r}/groups`,{name:e,newName:s,description:o});export const deleteGroups=async e=>t(`${r}/groups`,{names:e});export const getGroup=async s=>e(`${r}/groups/${encodeURIComponent(s)}`);export const getGroupMembers=async(s,{limit:o,offset:n}={})=>e(`${r}/groups/${encodeURIComponent(s)}/members`,{limit:o,offset:n});export const addMemberToGroup=async(e,o)=>s(`${r}/groups/${encodeURIComponent(e)}/members`,{userId:o});export const removeMemberFromGroup=async(e,s)=>t(`${r}/groups/${encodeURIComponent(e)}/members`,{userId:s});export const getGroupPermissions=async s=>e(`${r}/groups/${encodeURIComponent(s)}/permissions`);export const addPermissionToGroup=async(e,o)=>s(`${r}/groups/${encodeURIComponent(e)}/permissions`,{permissionName:o});export const removePermissionFromGroup=async(e,s)=>t(`${r}/groups/${encodeURIComponent(e)}/permissions`,{permissionName:s});export const listPermissions=async({limit:s,offset:o,owner:n}={})=>e(`${r}/permissions`,{limit:s,offset:o,owner:n});export const createPermissions=async e=>s(`${r}/permissions`,{permissions:e});export const updatePermission=async({name:e,description:s})=>n(`${r}/permissions`,{name:e,description:s});export const deletePermissions=async e=>t(`${r}/permissions`,{names:e});export const getSetting=async(s,o)=>e(`${r}/settings/${encodeURIComponent(s)}/${encodeURIComponent(o)}`);export const listSettings=async({owner:s,limit:o,offset:n}={})=>e(`${r}/settings/${encodeURIComponent(s)}`,{limit:o,offset:n});export const setSetting=async(e,o,n)=>s(`${r}/settings/${encodeURIComponent(e)}/${encodeURIComponent(o)}`,n);export const deleteSetting=async(e,s)=>t(`${r}/settings/${encodeURIComponent(e)}/${encodeURIComponent(s)}`);export const listPages=async({owner:s,showHidden:o,offset:n,limit:t}={})=>e(`${r}/pages`,{owner:s,showHidden:o,offset:n,limit:t});export const rescanPages=async()=>s(`${r}/pages/rescan`,{});export const listTemplates=async()=>e(`${r}/templates`);export const listDirectories=async()=>e(`${r}/pages/directories`);export const getPage=async s=>e(`${r}/pages/file`,{file:s});export const createPage=async({directory:e,name:o,template:n})=>s(`${r}/pages`,{directory:e,name:o,template:n});export const updatePage=async({file:e,name:s,title:n,description:t,author:a,template:i,contents:c,extraMetadata:l})=>o(`${r}/pages/file`,{file:e,name:s,title:n,description:t,author:a,template:i,contents:c,extraMetadata:l});export const deletePages=async e=>t(`${r}/pages`,{files:e});export const disablePage=async e=>o(`${r}/pages/disable`,{file:e});export const enablePage=async e=>o(`${r}/pages/enable`,{file:e});export const movePage=async({file:e,newFile:s})=>n(`${r}/pages/file`,{file:e,newFile:s});export const searchPagesByMetadata=async s=>e(`${r}/pages/search`,{query:JSON.stringify(s)});export const setPageLocked=async({file:e,locked:s})=>o(`${r}/pages/lock`,{file:e,locked:s});export const getTemplate=async s=>e(`${r}/templates/file`,{file:s});export const createTemplate=async({directory:e,name:o,copyFrom:n})=>s(`${r}/templates`,{directory:e,name:o,copyFrom:n});export const updateTemplate=async({file:e,name:s,author:n,markup:t})=>o(`${r}/templates/file`,{file:e,name:s,author:n,markup:t});export const deleteTemplates=async e=>t(`${r}/templates`,{files:e});export const disableTemplate=async e=>o(`${r}/templates/disable`,{file:e});export const enableTemplate=async e=>o(`${r}/templates/enable`,{file:e});export const moveTemplate=async({file:e,newFile:s})=>n(`${r}/templates/file`,{file:e,newFile:s});export const setTemplateLocked=async({file:e,locked:s})=>o(`${r}/templates/lock`,{file:e,locked:s});export const listFragments=async()=>e(`${r}/fragments`);export const getFragment=async s=>e(`${r}/fragments/file`,{file:s});export const createFragment=async({directory:e,name:o})=>s(`${r}/fragments`,{directory:e,name:o});export const updateFragment=async({file:e,author:s,markup:n})=>o(`${r}/fragments/file`,{file:e,author:s,markup:n});export const deleteFragments=async e=>t(`${r}/fragments`,{files:e});export const moveFragment=async({file:e,newFile:s})=>n(`${r}/fragments/file`,{file:e,newFile:s});export const disableFragment=async e=>o(`${r}/fragments/disable`,{file:e});export const enableFragment=async e=>o(`${r}/fragments/enable`,{file:e});export const setFragmentLocked=async({file:e,locked:s})=>o(`${r}/fragments/lock`,{file:e,locked:s});export const listGlobalContent=async()=>e(`${r}/globals`);export const getGlobalContent=async s=>e(`${r}/globals/entry`,{id:s});export const createGlobalContent=async({name:e,location:o,priority:n})=>s(`${r}/globals`,{name:e,location:o,priority:n});export const updateGlobalContent=async({id:e,name:s,location:n,priority:t,markup:a})=>o(`${r}/globals/entry`,{id:e,name:s,location:n,priority:t,markup:a});export const deleteGlobalContent=async e=>t(`${r}/globals`,{ids:e});export const disableGlobalContent=async e=>o(`${r}/globals/disable`,{id:e});export const enableGlobalContent=async e=>o(`${r}/globals/enable`,{id:e});export const setGlobalContentLocked=async({id:e,locked:s})=>o(`${r}/globals/lock`,{id:e,locked:s});export const listExtensions=async({limit:s,offset:o}={})=>e(`${r}/extensions`,{limit:s,offset:o});export const listAvailableExtensions=async()=>e(`${r}/extensions/available`);export const listKnownExtensions=async()=>e(`${r}/extensions/known`);export const listRealtimeConnections=async()=>e(`${r}/realtime/connections`);export const installExtension=async e=>s(`${r}/extensions`,{name:e});export const uninstallExtension=async(e,s=!1)=>t(`${r}/extensions`,{name:e,purgeData:s});export const enableExtension=async e=>s(`${r}/extensions/${encodeURIComponent(e)}/enable`,{});export const disableExtension=async e=>s(`${r}/extensions/${encodeURIComponent(e)}/disable`,{});export const listAdminGlobalContent=async()=>e(`${r}/admin-globals`);export const getAdminGlobalContent=async s=>e(`${r}/admin-globals/${encodeURIComponent(s)}`);export const createAdminGlobalContent=async({name:e,location:o,priority:n,owner:t,markup:a})=>s(`${r}/admin-globals`,{name:e,location:o,priority:n,owner:t,markup:a});export const updateAdminGlobalContent=async(e,{name:s,location:n,priority:t,markup:a})=>o(`${r}/admin-globals/${encodeURIComponent(e)}`,{name:s,location:n,priority:t,markup:a});export const deleteAdminGlobalContent=async e=>t(`${r}/admin-globals`,{ids:e});export const enableAdminGlobalContent=async e=>o(`${r}/admin-globals/${encodeURIComponent(e)}/enable`,{});export const disableAdminGlobalContent=async e=>o(`${r}/admin-globals/${encodeURIComponent(e)}/disable`,{});
|
|
2
2
|
//# sourceMappingURL=C:\Users\dusti\dev\kempo\dist\kempo\sdk.js.map
|
package/dist/kempo/sdk.js.map
CHANGED
|
@@ -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","installExtension","uninstallExtension","purgeData","enableExtension","disableExtension","listAdminGlobalContent","getAdminGlobalContent","createAdminGlobalContent","updateAdminGlobalContent","deleteAdminGlobalContent","enableAdminGlobalContent","disableAdminGlobalContent"],"sources":["0"],"sourcesContent":["import { get, post, put, patch, del } from './fetch.js';\r\nconst API_BASE = '/kempo/api';\r\n\r\nexport const register = async ({ email, password, name }) =>\r\n post(`${API_BASE}/auth/register/email`, { email, password, name });\r\n\r\nexport const login = async ({ email, password }) =>\r\n post(`${API_BASE}/auth/login/email`, { email, password });\r\n\r\nexport const logout = async () => post(`${API_BASE}/auth/logout`, {});\r\n\r\nexport const getSession = async () => get(`${API_BASE}/auth/session`);\r\n\r\nexport const forgotPassword = async ({ email }) =>\r\n post(`${API_BASE}/forgot-password`, { email });\r\n\r\nexport const resetPassword = async ({ token, password, logoutAll = false }) =>\r\n post(`${API_BASE}/auth/reset-password`, { token, newPassword: password, logoutAll });\r\n \r\nexport const changePassword = async ({ currentPassword, newPassword, logoutAll }) => \r\n post(`${API_BASE}/auth/change-password`, { currentPassword, newPassword, logoutAll });\r\n\r\nexport const verifyEmail = async ({ token }) =>\r\n post(`${API_BASE}/auth/verify-email`, { token });\r\n\r\nexport const currentUserHasPermission = async ({ permission }) =>\r\n get(`${API_BASE}/user/current/permissions`, { permission });\r\n\r\nexport const currentUserHasAllPermissions = async ({ permissions }) =>\r\n get(`${API_BASE}/user/current/permissions/all`, { permissions });\r\n\r\nexport const currentUserHasSomePermissions = async ({ permissions }) =>\r\n get(`${API_BASE}/user/current/permissions/some`, { permissions });\r\n\r\nexport const getAllCurrentUserPermissions = async () =>\r\n get(`${API_BASE}/user/current/permissions/list`);\r\n\r\nexport const userHasPermission = async ({ userid, permission }) =>\r\n get(`${API_BASE}/user/${userid}/permissions`, { permission });\r\n\r\nexport const userHasAllPermissions = async ({ userid, permissions }) =>\r\n get(`${API_BASE}/user/${userid}/permissions/all`, { permissions });\r\n\r\nexport const userHasSomePermissions = async ({ userid, permissions }) =>\r\n get(`${API_BASE}/user/${userid}/permissions/some`, { permissions });\r\n\r\nexport const getAllUserPermissions = async ({ userid }) =>\r\n get(`${API_BASE}/user/${userid}/permissions/list`);\r\n\r\nexport const getUsers = async ({ limit, offset } = {}) =>\r\n get(`${API_BASE}/user`, { limit, offset });\r\n\r\nexport const searchUsers = async ({ q, limit, offset, inGroup, notInGroup } = {}) =>\r\n get(`${API_BASE}/user/search`, { q, limit, offset, inGroup, notInGroup });\r\n\r\nexport const createUser = async ({ name, email, password, emailVerified }) =>\r\n post(`${API_BASE}/user/create`, { name, email, password, emailVerified });\r\n\r\nexport const deleteUsers = async (ids) =>\r\n del(`${API_BASE}/user`, { ids });\r\n\r\nexport const updateUser = async ({ id, name, email, emailVerified, createdAt }) =>\r\n patch(`${API_BASE}/user`, { id, name, email, emailVerified, createdAt });\r\n\r\nexport const getUser = async (userid) =>\r\n get(`${API_BASE}/user/${userid}`);\r\n\r\nexport const getUserSessions = async (userid, { limit, offset } = {}) =>\r\n get(`${API_BASE}/user/${userid}/sessions`, { limit, offset });\r\n\r\nexport const deleteUserSession = async (userid, sessionToken) =>\r\n del(`${API_BASE}/user/${userid}/sessions`, { sessionToken });\r\n\r\nexport const deleteExpiredUserSessions = async (userid) =>\r\n del(`${API_BASE}/user/${userid}/sessions/expired`);\r\n\r\nexport const getUserGroups = async (userid, { limit, offset } = {}) =>\r\n get(`${API_BASE}/user/${userid}/groups`, { limit, offset });\r\n\r\nexport const addUserToGroup = async (userid, groupName) =>\r\n post(`${API_BASE}/user/${userid}/groups`, { groupName });\r\n\r\nexport const removeUserFromGroup = async (userid, groupName) =>\r\n del(`${API_BASE}/user/${userid}/groups`, { groupName });\r\n\r\nexport const listGroups = async ({ limit, offset, owner } = {}) =>\r\n get(`${API_BASE}/groups`, { limit, offset, owner });\r\n\r\nexport const createGroup = async ({ name, description }) =>\r\n post(`${API_BASE}/groups`, { name, description });\r\n\r\nexport const updateGroup = async ({ name, newName, description }) =>\r\n patch(`${API_BASE}/groups`, { name, newName, description });\r\n\r\nexport const deleteGroups = async (names) =>\r\n del(`${API_BASE}/groups`, { names });\r\n\r\nexport const getGroup = async (name) =>\r\n get(`${API_BASE}/groups/${encodeURIComponent(name)}`);\r\n\r\nexport const getGroupMembers = async (name, { limit, offset } = {}) =>\r\n get(`${API_BASE}/groups/${encodeURIComponent(name)}/members`, { limit, offset });\r\n\r\nexport const addMemberToGroup = async (name, userId) =>\r\n post(`${API_BASE}/groups/${encodeURIComponent(name)}/members`, { userId });\r\n\r\nexport const removeMemberFromGroup = async (name, userId) =>\r\n del(`${API_BASE}/groups/${encodeURIComponent(name)}/members`, { userId });\r\n\r\nexport const getGroupPermissions = async (name) =>\r\n get(`${API_BASE}/groups/${encodeURIComponent(name)}/permissions`);\r\n\r\nexport const addPermissionToGroup = async (name, permissionName) =>\r\n post(`${API_BASE}/groups/${encodeURIComponent(name)}/permissions`, { permissionName });\r\n\r\nexport const removePermissionFromGroup = async (name, permissionName) =>\r\n del(`${API_BASE}/groups/${encodeURIComponent(name)}/permissions`, { permissionName });\r\n\r\nexport const listPermissions = async ({ limit, offset, owner } = {}) =>\r\n get(`${API_BASE}/permissions`, { limit, offset, owner });\r\n\r\nexport const createPermissions = async (permissions) =>\r\n post(`${API_BASE}/permissions`, { permissions });\r\n\r\nexport const updatePermission = async ({ name, description }) =>\r\n patch(`${API_BASE}/permissions`, { name, description });\r\n\r\nexport const deletePermissions = async (names) =>\r\n del(`${API_BASE}/permissions`, { names });\r\n\r\nexport const getSetting = async (owner, name) =>\r\n get(`${API_BASE}/settings/${encodeURIComponent(owner)}/${encodeURIComponent(name)}`);\r\n\r\nexport const listSettings = async ({ owner, limit, offset } = {}) =>\r\n get(`${API_BASE}/settings/${encodeURIComponent(owner)}`, { limit, offset });\r\n\r\nexport const setSetting = async (owner, name, data) =>\r\n post(`${API_BASE}/settings/${encodeURIComponent(owner)}/${encodeURIComponent(name)}`, data);\r\n\r\nexport const deleteSetting = async (owner, name) =>\r\n del(`${API_BASE}/settings/${encodeURIComponent(owner)}/${encodeURIComponent(name)}`);\r\n\r\n/*\r\n Pages\r\n*/\r\n\r\nexport const listPages = async ({ owner, showHidden, offset, limit } = {}) =>\r\n get(`${API_BASE}/pages`, { owner, showHidden, offset, limit });\r\n\r\nexport const rescanPages = async () =>\r\n post(`${API_BASE}/pages/rescan`, {});\r\n\r\nexport const listTemplates = async () =>\r\n get(`${API_BASE}/templates`);\r\n\r\nexport const listDirectories = async () =>\r\n get(`${API_BASE}/pages/directories`);\r\n\r\nexport const getPage = async (file) =>\r\n get(`${API_BASE}/pages/file`, { file });\r\n\r\nexport const createPage = async ({ directory, name, template }) =>\r\n post(`${API_BASE}/pages`, { directory, name, template });\r\n\r\nexport const updatePage = async ({ file, name, title, description, author, template, contents, extraMetadata }) =>\r\n put(`${API_BASE}/pages/file`, { file, name, title, description, author, template, contents, extraMetadata });\r\n\r\nexport const deletePages = async (files) =>\r\n del(`${API_BASE}/pages`, { files });\r\n\r\nexport const disablePage = async (file) =>\r\n put(`${API_BASE}/pages/disable`, { file });\r\n\r\nexport const enablePage = async (file) =>\r\n put(`${API_BASE}/pages/enable`, { file });\r\n\r\nexport const movePage = async ({ file, newFile }) =>\r\n patch(`${API_BASE}/pages/file`, { file, newFile });\r\n\r\nexport const searchPagesByMetadata = async (query) =>\r\n get(`${API_BASE}/pages/search`, { query: JSON.stringify(query) });\r\n\r\nexport const setPageLocked = async ({ file, locked }) =>\r\n put(`${API_BASE}/pages/lock`, { file, locked });\r\n\r\n/*\r\n Templates\r\n*/\r\n\r\nexport const getTemplate = async (file) =>\r\n get(`${API_BASE}/templates/file`, { file });\r\n\r\nexport const createTemplate = async ({ directory, name, copyFrom }) =>\r\n post(`${API_BASE}/templates`, { directory, name, copyFrom });\r\n\r\nexport const updateTemplate = async ({ file, name, author, markup }) =>\r\n put(`${API_BASE}/templates/file`, { file, name, author, markup });\r\n\r\nexport const deleteTemplates = async (files) =>\r\n del(`${API_BASE}/templates`, { files });\r\n\r\nexport const disableTemplate = async (file) =>\r\n put(`${API_BASE}/templates/disable`, { file });\r\n\r\nexport const enableTemplate = async (file) =>\r\n put(`${API_BASE}/templates/enable`, { file });\r\n\r\nexport const moveTemplate = async ({ file, newFile }) =>\r\n patch(`${API_BASE}/templates/file`, { file, newFile });\r\n\r\nexport const setTemplateLocked = async ({ file, locked }) =>\r\n put(`${API_BASE}/templates/lock`, { file, locked });\r\n\r\n/*\r\n Fragments\r\n*/\r\n\r\nexport const listFragments = async () =>\r\n get(`${API_BASE}/fragments`);\r\n\r\nexport const getFragment = async (file) =>\r\n get(`${API_BASE}/fragments/file`, { file });\r\n\r\nexport const createFragment = async ({ directory, name }) =>\r\n post(`${API_BASE}/fragments`, { directory, name });\r\n\r\nexport const updateFragment = async ({ file, author, markup }) =>\r\n put(`${API_BASE}/fragments/file`, { file, author, markup });\r\n\r\nexport const deleteFragments = async (files) =>\r\n del(`${API_BASE}/fragments`, { files });\r\n\r\nexport const moveFragment = async ({ file, newFile }) =>\r\n patch(`${API_BASE}/fragments/file`, { file, newFile });\r\n\r\nexport const disableFragment = async (file) =>\r\n put(`${API_BASE}/fragments/disable`, { file });\r\n\r\nexport const enableFragment = async (file) =>\r\n put(`${API_BASE}/fragments/enable`, { file });\r\n\r\nexport const setFragmentLocked = async ({ file, locked }) =>\r\n put(`${API_BASE}/fragments/lock`, { file, locked });\r\n\r\n/*\r\n Global Content\r\n*/\r\n\r\nexport const listGlobalContent = async () =>\r\n get(`${API_BASE}/globals`);\r\n\r\nexport const getGlobalContent = async (id) =>\r\n get(`${API_BASE}/globals/entry`, { id });\r\n\r\nexport const createGlobalContent = async ({ name, location, priority }) =>\r\n post(`${API_BASE}/globals`, { name, location, priority });\r\n\r\nexport const updateGlobalContent = async ({ id, name, location, priority, markup }) =>\r\n put(`${API_BASE}/globals/entry`, { id, name, location, priority, markup });\r\n\r\nexport const deleteGlobalContent = async (ids) =>\r\n del(`${API_BASE}/globals`, { ids });\r\n\r\nexport const disableGlobalContent = async (id) =>\r\n put(`${API_BASE}/globals/disable`, { id });\r\n\r\nexport const enableGlobalContent = async (id) =>\r\n put(`${API_BASE}/globals/enable`, { id });\r\n\r\nexport const setGlobalContentLocked = async ({ id, locked }) =>\r\n put(`${API_BASE}/globals/lock`, { id, locked });\r\n\r\n/*\r\n Extensions\r\n*/\r\n\r\nexport const listExtensions = async ({ limit, offset } = {}) =>\r\n get(`${API_BASE}/extensions`, { limit, offset });\r\n\r\nexport const listAvailableExtensions = async () =>\r\n get(`${API_BASE}/extensions/available`);\r\n\r\nexport const listKnownExtensions = async () =>\r\n get(`${API_BASE}/extensions/known`);\r\n\r\nexport const installExtension = async (name) =>\r\n post(`${API_BASE}/extensions`, { name });\r\n\r\nexport const uninstallExtension = async (name, purgeData = false) =>\r\n del(`${API_BASE}/extensions`, { name, purgeData });\r\n\r\nexport const enableExtension = async (name) =>\r\n post(`${API_BASE}/extensions/${encodeURIComponent(name)}/enable`, {});\r\n\r\nexport const disableExtension = async (name) =>\r\n post(`${API_BASE}/extensions/${encodeURIComponent(name)}/disable`, {});\r\n\r\n/*\r\n Admin Global Content\r\n*/\r\n\r\nexport const listAdminGlobalContent = async () =>\r\n get(`${API_BASE}/admin-globals`);\r\n\r\nexport const getAdminGlobalContent = async (id) =>\r\n get(`${API_BASE}/admin-globals/${encodeURIComponent(id)}`);\r\n\r\nexport const createAdminGlobalContent = async ({ name, location, priority, owner, markup }) =>\r\n post(`${API_BASE}/admin-globals`, { name, location, priority, owner, markup });\r\n\r\nexport const updateAdminGlobalContent = async (id, { name, location, priority, markup }) =>\r\n put(`${API_BASE}/admin-globals/${encodeURIComponent(id)}`, { name, location, priority, markup });\r\n\r\nexport const deleteAdminGlobalContent = async (ids) =>\r\n del(`${API_BASE}/admin-globals`, { ids });\r\n\r\nexport const enableAdminGlobalContent = async (id) =>\r\n put(`${API_BASE}/admin-globals/${encodeURIComponent(id)}/enable`, {});\r\n\r\nexport const disableAdminGlobalContent = async (id) =>\r\n put(`${API_BASE}/admin-globals/${encodeURIComponent(id)}/disable`, {});\r\n\r\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","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\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":[]}
|
package/middleware/kempo.js
CHANGED
|
@@ -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 { extensionAdminDirs, extensionPublicDirs } from '../server/utils/extensions/contentDirs.js';
|
|
9
10
|
import triggerHook from '../server/utils/hooks/triggerHook.js';
|
|
10
11
|
import { ADMIN_GLOBALS_DIR } from '../server/utils/admin-global-content/helpers.js';
|
|
11
12
|
|
|
@@ -112,7 +113,7 @@ const executeRouteFile = async (filePath, request, response, params = {}) => {
|
|
|
112
113
|
extensions guard their own private pages. Rendering a page anywhere without this helper silently
|
|
113
114
|
bypasses those guards.
|
|
114
115
|
*/
|
|
115
|
-
const renderGuardedPage = async (pageFilePath, request, response, rootDir, resolveDir, params = {}, extraGlobalDirs = []) => {
|
|
116
|
+
const renderGuardedPage = async (pageFilePath, request, response, rootDir, resolveDir, params = {}, extraGlobalDirs = [], extraFragmentDirs = []) => {
|
|
116
117
|
try {
|
|
117
118
|
await triggerHook('middleware:before_page', {
|
|
118
119
|
url: request.url.split('?')[0],
|
|
@@ -127,7 +128,7 @@ const renderGuardedPage = async (pageFilePath, request, response, rootDir, resol
|
|
|
127
128
|
return;
|
|
128
129
|
}
|
|
129
130
|
|
|
130
|
-
const html = await renderExternalPage(pageFilePath, rootDir, resolveDir, {}, {}, 10, extraGlobalDirs);
|
|
131
|
+
const html = await renderExternalPage(pageFilePath, rootDir, resolveDir, {}, {}, 10, extraGlobalDirs, extraFragmentDirs);
|
|
131
132
|
response.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
|
|
132
133
|
response.end(html);
|
|
133
134
|
};
|
|
@@ -145,16 +146,22 @@ const renderGuardedPage = async (pageFilePath, request, response, rootDir, resol
|
|
|
145
146
|
*/
|
|
146
147
|
export const adminGlobalDirs = async () => [
|
|
147
148
|
ADMIN_GLOBALS_DIR,
|
|
148
|
-
...
|
|
149
|
+
...await extensionAdminDirs(),
|
|
149
150
|
];
|
|
150
151
|
|
|
151
|
-
|
|
152
|
+
/*
|
|
153
|
+
Fragments an admin render may pull from extension packages. ADMIN_GLOBALS_DIR is deliberately not
|
|
154
|
+
here: it holds admin-authored global content and never fragments.
|
|
155
|
+
*/
|
|
156
|
+
export const adminFragmentDirs = () => extensionAdminDirs();
|
|
157
|
+
|
|
158
|
+
const serveDir = async (dirPath, method, request, response, resolveDir, rootDir, params = {}, extraGlobalDirs = [], extraFragmentDirs = []) => {
|
|
152
159
|
const candidates = [`${method}.js`, 'index.page.html', 'index.js', 'index.html', 'CATCH.js'];
|
|
153
160
|
for(const candidate of candidates){
|
|
154
161
|
const candidatePath = join(dirPath, candidate);
|
|
155
162
|
try { await stat(candidatePath); } catch { continue; }
|
|
156
163
|
if(candidate.endsWith('.page.html')){
|
|
157
|
-
await renderGuardedPage(candidatePath, request, response, rootDir, resolveDir, params, extraGlobalDirs);
|
|
164
|
+
await renderGuardedPage(candidatePath, request, response, rootDir, resolveDir, params, extraGlobalDirs, extraFragmentDirs);
|
|
158
165
|
return true;
|
|
159
166
|
}
|
|
160
167
|
if(ROUTE_FILES.includes(candidate)){
|
|
@@ -271,9 +278,10 @@ export default config => {
|
|
|
271
278
|
const segments = url.slice('/admin'.length).replace(/^\//, '').split('/').filter(Boolean);
|
|
272
279
|
const resolveDir = buildResolveDir(ADMIN_ROOT, url);
|
|
273
280
|
const globalDirs = await adminGlobalDirs();
|
|
281
|
+
const fragmentDirs = await adminFragmentDirs();
|
|
274
282
|
|
|
275
283
|
if(segments.length === 0){
|
|
276
|
-
const served = await serveDir(ADMIN_ROOT, method, request, response, resolveDir, ADMIN_ROOT, {}, globalDirs);
|
|
284
|
+
const served = await serveDir(ADMIN_ROOT, method, request, response, resolveDir, ADMIN_ROOT, {}, globalDirs, fragmentDirs);
|
|
277
285
|
if(served) return;
|
|
278
286
|
} else {
|
|
279
287
|
const walked = await walkDynamic(ADMIN_ROOT, segments);
|
|
@@ -283,12 +291,12 @@ export default config => {
|
|
|
283
291
|
try { fileStat = await stat(filePath); } catch { /* not found */ }
|
|
284
292
|
|
|
285
293
|
if(fileStat?.isDirectory()){
|
|
286
|
-
const served = await serveDir(filePath, method, request, response, resolveDir, ADMIN_ROOT, params, globalDirs);
|
|
294
|
+
const served = await serveDir(filePath, method, request, response, resolveDir, ADMIN_ROOT, params, globalDirs, fragmentDirs);
|
|
287
295
|
if(served) return;
|
|
288
296
|
} else if(fileStat?.isFile()){
|
|
289
297
|
const name = filePath.split(/[/\\]/).pop();
|
|
290
298
|
if(name.endsWith('.page.html')){
|
|
291
|
-
await renderGuardedPage(filePath, request, response, ADMIN_ROOT, resolveDir, params, globalDirs);
|
|
299
|
+
await renderGuardedPage(filePath, request, response, ADMIN_ROOT, resolveDir, params, globalDirs, fragmentDirs);
|
|
292
300
|
return;
|
|
293
301
|
}
|
|
294
302
|
if(ROUTE_FILES.includes(name)){
|
|
@@ -317,6 +325,7 @@ export default config => {
|
|
|
317
325
|
const resolveDir = buildResolveDir(ADMIN_ROOT, url);
|
|
318
326
|
const method = request.method?.toUpperCase() || 'GET';
|
|
319
327
|
const globalDirs = await adminGlobalDirs();
|
|
328
|
+
const fragmentDirs = await adminFragmentDirs();
|
|
320
329
|
|
|
321
330
|
const pageCandidates = subPath.endsWith('/')
|
|
322
331
|
? [join(adminDir, subPath, 'index.page.html')]
|
|
@@ -329,7 +338,7 @@ export default config => {
|
|
|
329
338
|
try {
|
|
330
339
|
await stat(pagePath);
|
|
331
340
|
} catch { continue; }
|
|
332
|
-
await renderGuardedPage(pagePath, request, response, ADMIN_ROOT, resolveDir, {}, globalDirs);
|
|
341
|
+
await renderGuardedPage(pagePath, request, response, ADMIN_ROOT, resolveDir, {}, globalDirs, fragmentDirs);
|
|
333
342
|
return;
|
|
334
343
|
}
|
|
335
344
|
|
|
@@ -351,12 +360,12 @@ export default config => {
|
|
|
351
360
|
let walkedStat;
|
|
352
361
|
try { walkedStat = await stat(walkedPath); } catch { /* not found */ }
|
|
353
362
|
if(walkedStat?.isDirectory()){
|
|
354
|
-
const served = await serveDir(walkedPath, method, request, response, resolveDir, ADMIN_ROOT, params, globalDirs);
|
|
363
|
+
const served = await serveDir(walkedPath, method, request, response, resolveDir, ADMIN_ROOT, params, globalDirs, fragmentDirs);
|
|
355
364
|
if(served) return;
|
|
356
365
|
} else if(walkedStat?.isFile()){
|
|
357
366
|
const name = walkedPath.split(/[/\\]/).pop();
|
|
358
367
|
if(name.endsWith('.page.html')){
|
|
359
|
-
await renderGuardedPage(walkedPath, request, response, ADMIN_ROOT, resolveDir, params, globalDirs);
|
|
368
|
+
await renderGuardedPage(walkedPath, request, response, ADMIN_ROOT, resolveDir, params, globalDirs, fragmentDirs);
|
|
360
369
|
return;
|
|
361
370
|
}
|
|
362
371
|
if(ROUTE_FILES.includes(name)){
|
|
@@ -378,6 +387,12 @@ export default config => {
|
|
|
378
387
|
*/
|
|
379
388
|
const extensions = await getEnabledExtensions();
|
|
380
389
|
|
|
390
|
+
/*
|
|
391
|
+
Resolved once for every public render below — an extension's own scoped pages, the consumer's
|
|
392
|
+
pages, and the 404 alike — so any enabled extension can contribute to any of them.
|
|
393
|
+
*/
|
|
394
|
+
const publicContentDirs = await extensionPublicDirs();
|
|
395
|
+
|
|
381
396
|
for(const ext of extensions){
|
|
382
397
|
let pkgPath, pkg;
|
|
383
398
|
try {
|
|
@@ -398,7 +413,7 @@ export default config => {
|
|
|
398
413
|
const segments = subPath.replace(/^\//, '').split('/').filter(Boolean);
|
|
399
414
|
|
|
400
415
|
if(segments.length === 0){
|
|
401
|
-
const served = await serveDir(publicDir, method, request, response, resolveDir, PROJECT_PUBLIC);
|
|
416
|
+
const served = await serveDir(publicDir, method, request, response, resolveDir, PROJECT_PUBLIC, {}, publicContentDirs, publicContentDirs);
|
|
402
417
|
if(served) return;
|
|
403
418
|
return next();
|
|
404
419
|
}
|
|
@@ -410,12 +425,12 @@ export default config => {
|
|
|
410
425
|
try { fileStat = await stat(filePath); } catch { /* not found */ }
|
|
411
426
|
|
|
412
427
|
if(fileStat?.isDirectory()){
|
|
413
|
-
const served = await serveDir(filePath, method, request, response, resolveDir, PROJECT_PUBLIC, params);
|
|
428
|
+
const served = await serveDir(filePath, method, request, response, resolveDir, PROJECT_PUBLIC, params, publicContentDirs, publicContentDirs);
|
|
414
429
|
if(served) return;
|
|
415
430
|
} else if(fileStat?.isFile()){
|
|
416
431
|
const name = filePath.split(/[/\\]/).pop();
|
|
417
432
|
if(name.endsWith('.page.html')){
|
|
418
|
-
await renderGuardedPage(filePath, request, response, PROJECT_PUBLIC, resolveDir, params);
|
|
433
|
+
await renderGuardedPage(filePath, request, response, PROJECT_PUBLIC, resolveDir, params, publicContentDirs, publicContentDirs);
|
|
419
434
|
return;
|
|
420
435
|
}
|
|
421
436
|
if(ROUTE_FILES.includes(name)){
|
|
@@ -448,7 +463,7 @@ export default config => {
|
|
|
448
463
|
|
|
449
464
|
for(const pageFilePath of candidates){
|
|
450
465
|
try { await stat(pageFilePath); } catch { continue; }
|
|
451
|
-
await renderGuardedPage(pageFilePath, request, response, PROJECT_PUBLIC, resolveDir);
|
|
466
|
+
await renderGuardedPage(pageFilePath, request, response, PROJECT_PUBLIC, resolveDir, {}, publicContentDirs, publicContentDirs);
|
|
452
467
|
return;
|
|
453
468
|
}
|
|
454
469
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kempo",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.4.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A fullstack CMS framework for creating websites with user authentication",
|
|
6
6
|
"scripts": {
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
},
|
|
59
59
|
"peerDependencies": {
|
|
60
60
|
"kempo-css": ">=2.2.5",
|
|
61
|
-
"kempo-server": ">=3.
|
|
61
|
+
"kempo-server": ">=3.4.0",
|
|
62
62
|
"kempo-ui": ">=0.4.39"
|
|
63
63
|
},
|
|
64
64
|
"devDependencies": {
|
package/scripts/init-db.js
CHANGED
|
@@ -46,6 +46,8 @@ const DEFAULT_PERMISSIONS = [
|
|
|
46
46
|
{ name: 'system:extensions:uninstall', description: 'Uninstall extensions' },
|
|
47
47
|
{ name: 'system:extensions:manage', description: 'Enable and disable extensions' },
|
|
48
48
|
|
|
49
|
+
{ name: 'system:realtime:read', description: 'View realtime connections and channels' },
|
|
50
|
+
|
|
49
51
|
{ name: 'system:admin:access', description: 'Access admin panel' },
|
|
50
52
|
];
|
|
51
53
|
|
|
@@ -66,7 +68,8 @@ const DEFAULT_GROUPS = {
|
|
|
66
68
|
'system:menus:create', 'system:menus:read', 'system:menus:update', 'system:menus:delete',
|
|
67
69
|
'system:fragments:read', 'system:fragments:create', 'system:fragments:update', 'system:fragments:delete',
|
|
68
70
|
'system:globals:read', 'system:globals:create', 'system:globals:update', 'system:globals:delete',
|
|
69
|
-
'system:extensions:read', 'system:extensions:install', 'system:extensions:uninstall', 'system:extensions:manage'
|
|
71
|
+
'system:extensions:read', 'system:extensions:install', 'system:extensions:uninstall', 'system:extensions:manage',
|
|
72
|
+
'system:realtime:read'
|
|
70
73
|
]
|
|
71
74
|
}
|
|
72
75
|
};
|