npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@tablecraft/adapter-sveltekit

v0.1.1

Published

SvelteKit adapter for TableCraft

Readme

@tablecraft/adapter-sveltekit

SvelteKit server adapter for TableCraft.

The recommended integration is hooks.server.ts, which lets you mount TableCraft behind a configurable prefix such as /api or /api/data without creating route files.

Install

bun add @tablecraft/engine @tablecraft/adapter-sveltekit
# or
npm install @tablecraft/engine @tablecraft/adapter-sveltekit
# or
pnpm add @tablecraft/engine @tablecraft/adapter-sveltekit

Recommended: hooks.server.ts

// src/hooks.server.ts
import type { Handle } from '@sveltejs/kit';
import { createSvelteKitHandle } from '@tablecraft/adapter-sveltekit';
import { db } from '$lib/server/db';
import * as schema from '$lib/server/db/schema';
import { configs } from '$lib/server/tablecraft.config';

export const handle: Handle = createSvelteKitHandle({
  db,
  schema,
  configs,
  prefix: '/api',
  enableDiscovery: true,
  getContext: async (event) => ({
    tenantId: event.locals.tenantId,
    user: event.locals.user,
  }),
  checkAccess: async (config, context) => {
    return context.user?.roles?.includes('admin') ?? false;
  },
});

With that setup:

GET /api/users
GET /api/users/_meta
GET /api/_tables

If you prefer /api/data, change the prefix:

export const handle: Handle = createSvelteKitHandle({
  db,
  schema,
  configs,
  prefix: '/api/data',
});

That gives you:

GET /api/data/users
GET /api/data/users/_meta
GET /api/data/_tables

Using event.locals

This adapter is designed to work with auth/session data stored in locals.

// src/hooks.server.ts
import type { Handle } from '@sveltejs/kit';
import { createSvelteKitHandle } from '@tablecraft/adapter-sveltekit';

const tablecraft = createSvelteKitHandle({
  db,
  schema,
  configs,
  prefix: '/api',
  getContext: async (event) => ({
    tenantId: event.locals.tenantId,
    user: event.locals.user,
  }),
});

export const handle: Handle = async ({ event, resolve }) => {
  event.locals.tenantId = 'tenant_123';
  event.locals.user = {
    id: 'user_1',
    roles: ['admin'],
  };

  return tablecraft({ event, resolve });
};

Composing With sequence

If your app already has auth, session, or logging hooks, compose them with sequence.

Put the handle that populates event.locals before the TableCraft handle.

// src/hooks.server.ts
import type { Handle } from '@sveltejs/kit';
import { sequence } from '@sveltejs/kit/hooks';
import { createSvelteKitHandle } from '@tablecraft/adapter-sveltekit';

const authHandle: Handle = async ({ event, resolve }) => {
  event.locals.tenantId = 'tenant_123';
  event.locals.user = {
    id: 'user_1',
    roles: ['admin'],
  };

  return resolve(event);
};

const tablecraftHandle = createSvelteKitHandle({
  db,
  schema,
  configs,
  prefix: '/api',
  getContext: async (event) => ({
    tenantId: event.locals.tenantId,
    user: event.locals.user,
  }),
});

export const handle: Handle = sequence(authHandle, tablecraftHandle);

That order matters:

  • authHandle runs first and populates event.locals
  • tablecraftHandle reads event.locals and serves /api/*
  • non-TableCraft requests continue through the rest of the chain

Query Examples

GET /api/users?page=1&pageSize=25&sort=-createdAt
GET /api/orders?filter[status]=paid
GET /api/products?filter[price][gte]=100
GET /api/users?search=john
GET /api/users?export=csv
GET /api/users/_meta
GET /api/_tables

Route-File Alternative

If you prefer explicit route files, the adapter also supports SvelteKit +server.ts handlers.

Single catch-all route

// src/routes/api/[...table]/+server.ts
import { createSvelteKitHandler } from '@tablecraft/adapter-sveltekit';
import { db } from '$lib/server/db';
import * as schema from '$lib/server/db/schema';
import { configs } from '$lib/server/tablecraft.config';

export const GET = createSvelteKitHandler({
  db,
  schema,
  configs,
  enableDiscovery: true,
  getContext: async (event) => ({
    tenantId: event.locals.tenantId,
    user: event.locals.user,
  }),
});

That single file can serve:

GET /api/users
GET /api/users/_meta
GET /api/_tables

Split route files

// src/lib/server/tablecraft.ts
import { createSvelteKitHandlers } from '@tablecraft/adapter-sveltekit';
import { db } from '$lib/server/db';
import * as schema from '$lib/server/db/schema';
import { configs } from '$lib/server/tablecraft.config';

export const tablecraft = createSvelteKitHandlers({
  db,
  schema,
  configs,
  enableDiscovery: true,
});
// src/routes/api/data/[table]/+server.ts
import { tablecraft } from '$lib/server/tablecraft';

export const GET = tablecraft.GET;
// src/routes/api/data/[table]/_meta/+server.ts
import { tablecraft } from '$lib/server/tablecraft';

export const GET = tablecraft.metaGET;
// src/routes/api/data/_tables/+server.ts
import { tablecraft } from '$lib/server/tablecraft';

export const GET = tablecraft.tablesGET;

Single-Table Routes

If you only want one table per endpoint:

// src/lib/server/users-tablecraft.ts
import { createSvelteKitRouteHandlers } from '@tablecraft/adapter-sveltekit';
import { db } from '$lib/server/db';
import * as schema from '$lib/server/db/schema';
import { usersConfig } from '$lib/server/tablecraft.config';

export const usersTablecraft = createSvelteKitRouteHandlers({
  db,
  schema,
  config: usersConfig,
  getContext: async (event) => ({
    tenantId: event.locals.tenantId,
    user: event.locals.user,
  }),
});
// src/routes/api/users/+server.ts
import { usersTablecraft } from '$lib/server/users-tablecraft';

export const GET = usersTablecraft.GET;
// src/routes/api/users/_meta/+server.ts
import { usersTablecraft } from '$lib/server/users-tablecraft';

export const GET = usersTablecraft.metaGET;

API

import type { Handle, RequestEvent } from '@sveltejs/kit';
import type { EngineContext, TableConfig } from '@tablecraft/engine';
import type {
  SvelteKitHandleOptions,
  SvelteKitHandlerOptions,
  SvelteKitRouteOptions,
} from '@tablecraft/adapter-sveltekit';

createSvelteKitHandle(options)

Returns a SvelteKit Handle for hooks.server.ts.

Options:

  • prefix mounts the API under a path like /api or /api/data
  • getContext(event) receives the full RequestEvent
  • checkAccess(config, context, event) runs before queries/export
  • enableDiscovery controls /_tables
  • works cleanly with sequence(...) from @sveltejs/kit/hooks

createSvelteKitHandlers(options)

Returns:

  • GET for [table]/+server.ts
  • metaGET for [table]/_meta/+server.ts
  • tablesGET for _tables/+server.ts

createSvelteKitRouteHandlers(options)

Returns:

  • GET for a fixed table route
  • metaGET for that table's metadata route

Direct handler helpers

Also exported:

  • createSvelteKitHandler
  • createSvelteKitMetaHandler
  • createSvelteKitDiscoveryHandler
  • createSvelteKitRouteHandler
  • createSvelteKitRouteMetaHandler

Notes

  • The adapter is GET-only because TableCraft query endpoints are read-oriented.
  • createSvelteKitHandle() only intercepts requests under the configured prefix; everything else falls through to resolve(event).
  • If your app uses SvelteKit kit.paths.base, choose a prefix that matches the final request pathname seen by the server.
  • For hook mode, prefix is the API mount path, not the same thing as SvelteKit's app-level base path setting.

License

MIT