mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-19 13:36:48 +00:00
660e4b9dfc
- Wiki pages (sync to the GitHub wiki on push to main): Plugins overview + trust model, Plugin Development (SDK, definePlugin, ctx, routes/jobs, the client bridge, testing with the mock host), Plugin Permissions reference, and Publishing (registry PR + CI gates + provenance). Linked from the sidebar. - Reference plugin plugin-sdk/examples/trip-countdown: a complete, minimal- permission widget (reads trip data through ctx, renders in the sandboxed iframe via the bridge, filled-in README). Validated in the SDK test suite so it passes the exact gate authors face.
44 lines
1.4 KiB
JavaScript
44 lines
1.4 KiB
JavaScript
// Trip Countdown — reference widget plugin.
|
|
//
|
|
// Demonstrates the full author path: definePlugin, a permission-gated route that
|
|
// reads trip data through ctx, and a response the client iframe renders. Runs
|
|
// isolated; ctx is the only way to reach TREK.
|
|
const { definePlugin } = require('trek-plugin-sdk')
|
|
|
|
/** Days (integer, >= 0) between now and an ISO date, or null if past/absent. */
|
|
function daysUntil(iso) {
|
|
if (!iso) return null
|
|
const then = new Date(iso).getTime()
|
|
if (Number.isNaN(then)) return null
|
|
const diff = Math.ceil((then - Date.now()) / 86_400_000)
|
|
return diff >= 0 ? diff : null
|
|
}
|
|
|
|
module.exports = definePlugin({
|
|
routes: [
|
|
{
|
|
method: 'GET',
|
|
path: '/next',
|
|
auth: true,
|
|
async handler(req, ctx) {
|
|
// The client passes the dashboard's current trip id; the host enforces that
|
|
// req.user actually has access to it, so a plugin can't read foreign trips.
|
|
const tripId = Number(req.query.tripId)
|
|
if (!tripId) return { status: 200, headers: json(), body: JSON.stringify({ trip: null }) }
|
|
|
|
const t = await ctx.trips.getById(tripId, req.user.id)
|
|
const days = daysUntil(t && (t.start_date || t.startDate))
|
|
return {
|
|
status: 200,
|
|
headers: json(),
|
|
body: JSON.stringify({ trip: t ? { name: t.name, days } : null }),
|
|
}
|
|
},
|
|
},
|
|
],
|
|
})
|
|
|
|
function json() {
|
|
return { 'content-type': 'application/json' }
|
|
}
|