@tablecraft/adapter-sveltekit
v0.1.1
Published
SvelteKit adapter for TableCraft
Maintainers
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-sveltekitRecommended: 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/_tablesIf 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/_tablesUsing 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:
authHandleruns first and populatesevent.localstablecraftHandlereadsevent.localsand 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/_tablesRoute-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/_tablesSplit 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:
prefixmounts the API under a path like/apior/api/datagetContext(event)receives the fullRequestEventcheckAccess(config, context, event)runs before queries/exportenableDiscoverycontrols/_tables- works cleanly with
sequence(...)from@sveltejs/kit/hooks
createSvelteKitHandlers(options)
Returns:
GETfor[table]/+server.tsmetaGETfor[table]/_meta/+server.tstablesGETfor_tables/+server.ts
createSvelteKitRouteHandlers(options)
Returns:
GETfor a fixed table routemetaGETfor that table's metadata route
Direct handler helpers
Also exported:
createSvelteKitHandlercreateSvelteKitMetaHandlercreateSvelteKitDiscoveryHandlercreateSvelteKitRouteHandlercreateSvelteKitRouteMetaHandler
Notes
- The adapter is GET-only because TableCraft query endpoints are read-oriented.
createSvelteKitHandle()only intercepts requests under the configuredprefix; everything else falls through toresolve(event).- If your app uses SvelteKit
kit.paths.base, choose aprefixthat matches the final request pathname seen by the server. - For hook mode,
prefixis the API mount path, not the same thing as SvelteKit's app-level base path setting.
License
MIT
