0.1.3Updated 9 days ago

@draco/connect

A minimal, framework-agnostic TypeScript utility for connecting to a Draco backend from Deno or any TypeScript runtime that supports URL imports. It handles authentication cookies, permission announcement, user lookups, and event logging with barebones functionality.

Further functionality and automatic routing will be provided at a later date by:

  • @draco/connect-fresh
  • @draco/connect-oak
  • @draco/connect-hono

Installation

// Import directly via Viapak
import { Draco } from "https://viapak.xyz/@draco/connect";

Configuration

Before using any Draco functions, configure it once on application startup:

await Draco.Configure({
  host: "https://draco.galaxi.online",
  api_key: "your-api-key",
  permissions: Permissions,
  cookie_name: "draco_uuid"
});

Environment variable fallbacks:

You can leave out any of host, api_key or cookie_name in the confuguration as long as you define the following in your environment.

Parameter Environment Fallback
host DRACO_HOST
api_key DRACO_API_KEY
cookie_name DRACO_API_KEY

Using the Available Functions

1. AnnouncePermissions

Synchronize your app’s declared permissions with Draco. Called automatically in Configure(), but can be triggered manually.


2. GetCookie

Retrieve the Draco cookie UUID from a Request object.

const cookie_uuid = Draco.GetCookie(request);

3. CookieRedirect

Initialize a new cookie if missing and redirect back to the same URL. ✅ Use this at the start of a request flow when a Draco UUID is mandatory.

if (!Draco.GetCookie(request)) return Draco.CookieRedirect(request);

4. LoginRedirect

Kick off a login flow with Draco.

return await Draco.LoginRedirect(cookie_uuid, "https://my-app.example.com/destination-after-login");

5. LogoutRedirect

Clear the cookie and return a redirect Response.

return Draco.LogoutRedirect();

6. GetUser

Fetch the current user profile. Uses a built-in memory cache unless force is true.

const user = await Draco.GetUser(request);
// or
const user = await Draco.GetUser(cookie_uuid);

💡 When to use: At the start of any request needing authenticated user data.


7. LogEvent

Record a user activity/event in Draco.

await Draco.LogEvent(request, {
  type: "user_added",
  information: JSON.stringify({ id: 1234 })
});

💡 When to use: Audit logs or privileged user actions.


Permissions

Optimal Structure

Use a flat object mapping human-readable constants to permission keys:

enum Permissions {
  VIEW_DASHBOARD = "view_dashboard",
  EDIT_USERS = "edit_users",
};

Announcing Permissions

Happens in Configure() automatically, but you can call manually:

await Draco.AnnouncePermissions();

Example

Route protection:

if (!user.can(Draco.Permissions.VIEW_DASHBOARD)) {
  return new Response("Forbidden", { status: 403 });
}

Feature flags:

<div>
  { user.can(Draco.Permissions.EDIT_USERS) &&
    <EditButton user={user} />
  }
</div>

Suggested Patterns

1. Request Middleware (Oak/Hono/Fresh adapters)

export async function requireUser(ctx) {
  const draco_uuid = await Draco.GetCookie(ctx.req.raw);
  const user = await Draco.GetUser(draco_uuid);
  if (!user) return await Draco.LoginRedirect(draco_uuid, ctx.req.url);
  ctx.state.user = user;
}

2. Event Logging Wrapper

function logAction(request: Request, type: string, info: Record<string, any>) {
  return Draco.LogEvent(request, { type, information: info });
}

3. Force Cookie Initialization

if (!Draco.GetCookie(req)) return Draco.CookieRedirect(req);
README.md