@lastshotlabs/slingshot
npm install @lastshotlabs/slingshot
Functions
Section titled “Functions”applyDefaults
Section titled “applyDefaults”Shared field-mapping utilities for config-driven adapters.
- camelCase ↔ snake_case conversion
- SQL / Mongo type mapping
- Record transformation (domain ↔ storage)
- Auto-default resolution
- Naming conventions per backend
function applyDefaults(input: Record<string, unknown>, fields: Record<string, FieldDef>, customAutoDefault?: CustomAutoDefaultResolver,): Record<string, unknown>Source: packages/slingshot-entity/src/configDriven/fieldUtils.ts
applyOnUpdate
Section titled “applyOnUpdate”Shared field-mapping utilities for config-driven adapters.
- camelCase ↔ snake_case conversion
- SQL / Mongo type mapping
- Record transformation (domain ↔ storage)
- Auto-default resolution
- Naming conventions per backend
function applyOnUpdate(input: Record<string, unknown>, fields: Record<string, FieldDef>, customOnUpdate?: CustomOnUpdateResolver,): Record<string, unknown>Source: packages/slingshot-entity/src/configDriven/fieldUtils.ts
assertProductionReadiness
Section titled “assertProductionReadiness”function assertProductionReadiness(config: AuditConfig, options?: ProductionReadinessAuditOptions,): ProductionReadinessReportSource: src/prodReadiness.ts
auditLog
Section titled “auditLog”Skip logging for requests with these HTTP methods (e.g. ["GET", "HEAD"]).
function auditLog(options: AuditLogMiddlewareOptions): MiddlewareHandler<AppEnv>Source: src/framework/middleware/auditLog.ts
auditProductionReadiness
Section titled “auditProductionReadiness”function auditProductionReadiness(config: AuditConfig, options: ProductionReadinessAuditOptions = {},): ProductionReadinessReportSource: src/prodReadiness.ts
botProtection
Section titled “botProtection”Convert a dotted-decimal IPv4 string to an unsigned 32-bit integer.
function botProtection({ blockList = [] }: BotProtectionOptions): MiddlewareHandlerSource: src/framework/middleware/botProtection.ts
bustCache
Section titled “bustCache”Get or create the Mongoose CacheEntry model on the given connection. Accepts connection and mongoose module as parameters — no module-level state.
async function bustCache(key: string, app: object): voidSource: src/framework/middleware/cacheResponse.ts
bustCachePattern
Section titled “bustCachePattern”Get or create the Mongoose CacheEntry model on the given connection. Accepts connection and mongoose module as parameters — no module-level state.
async function bustCachePattern(pattern: string, app: object): voidSource: src/framework/middleware/cacheResponse.ts
cacheResponse
Section titled “cacheResponse”Get or create the Mongoose CacheEntry model on the given connection. Accepts connection and mongoose module as parameters — no module-level state.
function cacheResponse({ ttl, key, store: storeOverride, }: CacheOptions): MiddlewareHandler<AppEnv>Source: src/framework/middleware/cacheResponse.ts
closeMetricsQueues
Section titled “closeMetricsQueues”Create a fresh, instance-scoped metrics state container.
async function closeMetricsQueues(state: MetricsState): Promise<void>Source: src/framework/metrics/registry.ts
createApp
Section titled “createApp”Absolute path to the service’s routes directory (use import.meta.dir + “/routes”). Optional — omit when all routes are registered via plugins.
async function createApp<T extends object = object>(config: CreateAppConfig<T>,): Promise<CreateAppResult>Source: src/app.ts
createAuditLogProvider
Section titled “createAuditLogProvider”Configuration for creating an audit log provider.
function createAuditLogProvider(options: AuditLogOptions): AuditLogProviderSource: src/framework/auditLog/index.ts
createAuthPlugin
Section titled “createAuthPlugin”Creates the slingshot-auth plugin instance for use with createApp(), createServer(),
or as a standalone Hono plugin via plugin.setup().
The plugin bootstraps all auth subsystems (session store, adapters, rate limiting, credential stuffing detection, OAuth providers, MFA, SAML, SCIM, etc.) and mounts the corresponding route handlers on the Hono app.
Remarks: - In standalone mode (no SlingshotFrameworkConfig), config.runtime.password is required. - Production boot requires an explicit security.signing.sessionBinding choice. Without it a stolen JWT+session pair is usable from any IP or browser. Set security.signing.sessionBinding to either a real binding policy or false to acknowledge the risk explicitly. - OAuth routes are provided by @lastshotlabs/slingshot-oauth and mounted by that plugin.
function createAuthPlugin(rawConfig: AuthPluginConfig): StandalonePluginSource: packages/slingshot-auth/src/plugin.ts
createInProcessAdapter
Section titled “createInProcessAdapter”Narrow, untyped view of the event bus for string-keyed subscriptions.
Plugins that subscribe to dynamically named events (e.g. entity:${storageName}.created)
cast the typed SlingshotEventBus to this interface rather than widening the global
SlingshotEventMap. This keeps type widening local per rule 12.
Defined here once so every consumer imports the same shape (rule 6). Use Pick to
narrow further when a module only needs emit or only needs on/off.
function createInProcessAdapter(serializationOpts?: EventBusSerializationOptions,): SlingshotEventBusSource: packages/slingshot-core/src/eventBus.ts
createMemoryEntityAdapter
Section titled “createMemoryEntityAdapter”Config-driven memory adapter generator.
Produces an EntityAdapter backed by an in-memory Map with LRU eviction, optional TTL, soft-delete, cursor pagination, and tenant scoping.
function createMemoryEntityAdapter<Entity, CreateInput, UpdateInput>(config: ResolvedEntityConfig, operations?: Record<string, OperationConfig>,): EntityAdapter<Entity, CreateInput, UpdateInput> & Record<string, unknown>Source: packages/slingshot-entity/src/configDriven/memoryAdapter.ts
createMetricsState
Section titled “createMetricsState”Create a fresh, instance-scoped metrics state container.
function createMetricsState(): MetricsStateSource: src/framework/metrics/registry.ts
createMongoEntityAdapter
Section titled “createMongoEntityAdapter”Config-driven MongoDB adapter generator.
Lazily creates a Mongoose model from the entity config, including compound indices, TTL expiration, soft-delete, cursor pagination, and tenant scoping.
function createMongoEntityAdapter<Entity, CreateInput, UpdateInput>(conn: Connection, mongoosePkg: MongooseModule, config: ResolvedEntityConfig, operations?: Record<string, OperationConfig>,): EntityAdapter<Entity, CreateInput, UpdateInput> & Record<string, unknown>Source: packages/slingshot-entity/src/configDriven/mongoAdapter.ts
createPostgresEntityAdapter
Section titled “createPostgresEntityAdapter”Config-driven PostgreSQL adapter generator.
Produces a full EntityAdapter implementation backed by a pg connection pool,
driven entirely by ResolvedEntityConfig — no hand-written SQL schema required.
Features:
- Auto-creates the table on first use (
CREATE TABLE IF NOT EXISTS) with correct column types,NOT NULLconstraints, and aPRIMARY KEY. - Creates compound indexes (
CREATE INDEX IF NOT EXISTS) and unique constraints (CREATE UNIQUE INDEX IF NOT EXISTS) fromconfig.indexesandconfig.uniques. - Optional TTL column (configurable, default
_expires_at) whenconfig.ttl.defaultSecondsis set. - Soft-delete:
delete()writes the soft-delete field value instead ofDELETE. - Cursor pagination: multi-field lexicographic cursors via
buildCursorForRecord/decodeCursor. create()uses plainINSERT; primary-key and unique conflicts reject consistently with the memory and SQLite adapters. Replacement requires an explicit update/upsert operation.- Spreads
buildPostgresOperations()result to attach custom operation methods.
function createPostgresEntityAdapter<Entity, CreateInput, UpdateInput>(pool: PgPool, config: ResolvedEntityConfig, operations?: Record<string, OperationConfig>,): EntityAdapter<Entity, CreateInput, UpdateInput> & Record<string, unknown>Source: packages/slingshot-entity/src/configDriven/postgresAdapter.ts
createPresignedUrl
Section titled “createPresignedUrl”Sign data with the active key (first element of secret).
Normalizes string | string[] so that an array is never passed directly to
createHmac() — which would silently call .toString() and produce
“[object Array]” as the key.
function createPresignedUrl(base: string, key: string, opts: { method: string; expiry: number; extra?: Record<string, string> }, secret: string | string[],): stringSource: src/lib/signing.ts
createRedisEntityAdapter
Section titled “createRedisEntityAdapter”Config-driven Redis adapter generator.
Records are stored as JSON strings under prefixed keys. Supports TTL, soft-delete, cursor pagination, and tenant scoping.
function createRedisEntityAdapter<Entity, CreateInput, UpdateInput>(redis: RedisLike, appName: string, config: ResolvedEntityConfig, operations?: Record<string, OperationConfig>,): EntityAdapter<Entity, CreateInput, UpdateInput> & Record<string, unknown>Source: packages/slingshot-entity/src/configDriven/redisAdapter.ts
createRedisTransport
Section titled “createRedisTransport”ioredis connection options or a Redis URL string
function createRedisTransport(opts: RedisTransportOptions): WsTransportAdapterSource: src/framework/ws/redisTransport.ts
createRoute
Section titled “createRoute”The schema parameter type expected by zodOpenAPIRegistry.add().
function createRoute<T extends RouteConfig>(config: T): TSource: packages/slingshot-core/src/createRoute.ts
createRouter
Section titled “createRouter”A single field-level validation error detail produced by the default formatter.
function createRouter(): voidSource: packages/slingshot-core/src/context.ts
createServer
Section titled “createServer”Shutdown registry shape. Lives on process via a well-known Symbol so there
is zero module-level mutable state. The registry is truly process-scoped
(where POSIX signals live) and survives module re-evaluation.
async function createServer<T extends object = object>(config: CreateServerConfig<T>,): Promise<Server<SocketData<T>>>Source: src/server.ts
createSlingshotAdminPlugin
Section titled “createSlingshotAdminPlugin”Configuration for the Slingshot-integrated admin plugin.
Extends AdminPluginConfig with optional overrides for accessProvider,
managedUserProvider, and permissions. When these are omitted, sensible
framework defaults are resolved automatically:
accessProviderdefaults tocreateSlingshotAuthAccessProvider, which reads permissions from the auth runtime context.managedUserProviderdefaults tocreateSlingshotManagedUserProvider, constructed from the auth runtime adapter, config, and session repository.permissionsdefaults to the value stored underPERMISSIONS_STATE_KEYinctx.pluginState— set by the community plugin or another permissions source during itssetupRoutesphase.
All three are required at route-registration time. If permissions is not provided
and no plugin has populated PERMISSIONS_STATE_KEY, setupPost throws.
function createSlingshotAdminPlugin(config: SlingshotAdminPluginConfig): SlingshotPluginSource: src/framework/admin/index.ts
createSqliteEntityAdapter
Section titled “createSqliteEntityAdapter”Config-driven SQLite adapter generator.
Auto-creates the table on first use, generates indices for indexed fields, and handles domain ↔ storage mapping including dates, JSON, booleans, etc. Supports soft-delete, cursor pagination, TTL, and tenant scoping.
function createSqliteEntityAdapter<Entity, CreateInput, UpdateInput>(db: SqliteDb, config: ResolvedEntityConfig, operations?: Record<string, OperationConfig>,): EntityAdapter<Entity, CreateInput, UpdateInput> & Record<string, unknown>Source: packages/slingshot-entity/src/configDriven/sqliteAdapter.ts
createSseUpgradeHandler
Section titled “createSseUpgradeHandler”Per-app SSE connection registry.
Manages the full lifecycle of Server-Sent Event connections: opening streams,
broadcasting events to connected clients, optional per-client filtering, and
graceful shutdown. One registry instance is created per app via
createSseRegistry and stored in the app context.
All methods are safe to call from any async context — the internal map is updated synchronously and eviction is performed inline on enqueue failure.
function createSseUpgradeHandler<T extends object = object>(endpoint: string, actorResolver?: RequestActorResolver | null,): (req: Request) => Promise<SseClientData<T>>Source: src/framework/sse/index.ts
createTenantService
Section titled “createTenantService”Read-only representation of a tenant record.
function createTenantService(conn: Connection, getTenantCache?: () => { delete(tenantId: string): void } | null, ): TenantServiceSource: src/framework/tenancy/service.ts
createWsUpgradeHandler
Section titled “createWsUpgradeHandler”Per-socket data attached to every WebSocket connection by the Bun server.
This type is the data object passed to all ws.* handler callbacks
(open, message, close, drain). The generic T parameter lets
plugins attach custom fields (e.g., roomId) at upgrade time. The base
fields are populated by createWsUpgradeHandler.
function createWsUpgradeHandler(server: Server<BaseSocketData>, endpoint: string, actorResolver?: RequestActorResolver | null): voidSource: src/framework/ws/index.ts
cursorParams
Section titled “cursorParams”Default values for cursor-based pagination query parameters.
function cursorParams(defaults?: CursorParamDefaults): voidSource: src/framework/lib/pagination.ts
cursorResponse
Section titled “cursorResponse”Default values for cursor-based pagination query parameters.
function cursorResponse<T extends ZodType>(itemSchema: T, name: string): voidSource: src/framework/lib/pagination.ts
decodeCursor
Section titled “decodeCursor”Shared field-mapping utilities for config-driven adapters.
- camelCase ↔ snake_case conversion
- SQL / Mongo type mapping
- Record transformation (domain ↔ storage)
- Auto-default resolution
- Naming conventions per backend
function decodeCursor(cursor: string): Record<string, unknown>Source: packages/slingshot-entity/src/configDriven/fieldUtils.ts
defaultValidationErrorFormatter
Section titled “defaultValidationErrorFormatter”A single field-level validation error detail produced by the default formatter.
Source: packages/slingshot-core/src/context.ts
defineApp
Section titled “defineApp”Canonical declarative app config shape.
Alias of CreateServerConfig surfaced under a friendlier name. Users
author this in app.config.ts and the framework boots from the default
export.
function defineApp<T extends object = object>(config: AppConfig<T>): AppConfig<T>Source: src/defineApp.ts
defineCapability
Section titled “defineCapability”Typed, named token a package publishes and consumers resolve to exchange a capability value across packages.
function defineCapability<TValue>(name: string): PackageCapabilityHandle<TValue>Source: packages/slingshot-core/src/packageAuthoring.ts
definePackage
Section titled “definePackage”Typed, named token a package publishes and consumers resolve to exchange a capability value across packages.
function definePackage(input: DefinePackageInput): SlingshotPackageDefinitionSource: packages/slingshot-core/src/packageAuthoring.ts
definePackageContract
Section titled “definePackageContract”Typed, named token a package publishes and consumers resolve to exchange a capability value across packages.
function definePackageContract<const TName extends string>(contractName: TName,): PackageContract<TName>Source: packages/slingshot-core/src/packageAuthoring.ts
deleteUploadRecord
Section titled “deleteUploadRecord”Store a new upload record. Keyed by the storage key.
async function deleteUploadRecord(key: string, app: object): Promise<boolean>Source: src/framework/upload/registry.ts
encodeCursor
Section titled “encodeCursor”Shared field-mapping utilities for config-driven adapters.
- camelCase ↔ snake_case conversion
- SQL / Mongo type mapping
- Record transformation (domain ↔ storage)
- Auto-default resolution
- Naming conventions per backend
function encodeCursor(values: Record<string, unknown>): stringSource: packages/slingshot-entity/src/configDriven/fieldUtils.ts
entity
Section titled “entity”Use the framework’s default adapter resolution for the entity.
function entity< const TConfig extends ResolvedEntityConfig, const TOperations extends EntityOperationsInput = undefined,>(config: { /** Resolved entity config to mount. */ readonly config: TConfig; /** Operation map or `defineOperations(...)` result used for generated routes. */ readonly operations?: TOperations; /** Additional custom routes mounted inside the entity route shell. */ readonly extraRoutes?: readonly EntityExtraRoute[]; /** Generated-route executor overrides. */ readonly overrides?: EntityRouteExecutorOverrides; /** Optional realtime channel declarations. */ readonly channels?: EntityChannelConfig; /** Optional route path override relative to the package mount path. */ readonly path?: string; /** Optional parent path prefix for nested entity routes. */ readonly parentPath?: string; /** Adapter wiring override. Defaults to `{ mode: 'standard' }`. */ readonly wiring?: EntityModuleWiring; }): PackageEntityModule< PackageEntityAdapterFor<TConfig, NormalizeOperationsInput<TOperations>>, EntityMiddlewareNamesOf<TConfig> >; export function entity(config:Source: packages/slingshot-entity/src/packageAuthoring.ts
entityRef
Section titled “entityRef”Typed, named token a package publishes and consumers resolve to exchange a capability value across packages.
function entityRef<TAdapter>(entity: SlingshotPackageEntityModuleLike<TAdapter>, options?: { plugin?: string },): PackageEntityRef<TAdapter>; /** * Create a typed entity ref directly from a package/entity name pair. * * @deprecated For cross-package entity access, prefer publishing a typed ref through a * package contract: `Matches.publicEntities(Source: packages/slingshot-core/src/packageAuthoring.ts
Config-driven entity & repository generation.
Plugin authors describe an entity’s shape declaratively using the field.*() builder
API, then get generated TypeScript types, Zod schemas, adapter interfaces, and
backend-specific implementations from a single source of truth.
import { defineEntity, field, index } from '@lastshotlabs/slingshot-core';
export const Message = defineEntity('Message', {namespace: 'chat',fields: {id: field.string({ primary: true, default: 'uuid' }),roomId: field.string(),authorId: field.string(),content: field.string(),type: field.enum(['text', 'image', 'system'], { default: 'text' }),metadata: field.json({ optional: true }),createdAt: field.date({ default: 'now' }),updatedAt: field.date({ default: 'now', onUpdate: 'now' }),},softDelete: { field: 'status', value: 'deleted' },defaultSort: { field: 'createdAt', direction: 'desc' },pagination: { cursor: { fields: ['createdAt', 'id'] }, defaultLimit: 50, maxLimit: 200 },indexes: [index(['roomId', 'createdAt'], { direction: 'desc' }),index(['authorId', 'createdAt'], { direction: 'desc' }),],});Source: packages/slingshot-core/src/entityConfig.ts
generateSchemas
Section titled “generateSchemas”Zod schema generation from entity config.
Derives four Zod schemas from a ResolvedEntityConfig at runtime, without any
code generation step. Schemas are consumed by route handlers for request validation
and by the REST API generator for OpenAPI type inference.
Generated schemas:
entitySchema— Full record shape; optional fields become.optional().createSchema— Create input; excludes auto-default fields (uuid,now,cuid) andonUpdatefields. Fields with literal defaults or marked optional are optional in this schema.updateSchema— Partial update input; all included fields are.optional(). Excludes immutable fields andonUpdatefields.listOptionsSchema— Filter + pagination options for list endpoints. Includes enum/boolean fields, all indexed fields, the tenant field, andlimit/cursor/sortDir.
function generateSchemas(config: ResolvedEntityConfig, inputVariant?: string,): GeneratedSchemasSource: packages/slingshot-entity/src/configDriven/schemaGen.ts
getActor
Section titled “getActor”Resolve the canonical actor for a Hono request context.
Reads the actor variable published by the auth middleware (identify,
bearerAuth, or a custom identity middleware). Returns ANONYMOUS_ACTOR
when no actor has been published.
function getActor(c: Context<AppEnv>): ActorSource: packages/slingshot-core/src/actorContext.ts
getActorId
Section titled “getActorId”Resolve the canonical actor for a Hono request context.
Reads the actor variable published by the auth middleware (identify,
bearerAuth, or a custom identity middleware). Returns ANONYMOUS_ACTOR
when no actor has been published.
function getActorId(c: Context<AppEnv>): string | nullSource: packages/slingshot-core/src/actorContext.ts
getActorTenantId
Section titled “getActorTenantId”Resolve the canonical actor for a Hono request context.
Reads the actor variable published by the auth middleware (identify,
bearerAuth, or a custom identity middleware). Returns ANONYMOUS_ACTOR
when no actor has been published.
function getActorTenantId(c: Context<AppEnv>): string | nullSource: packages/slingshot-core/src/actorContext.ts
getClientIp
Section titled “getClientIp”Attach a trust-proxy depth to a raw Request object for standalone (non-framework) usage.
When using getClientIp outside of a full Slingshot app (e.g., in a plain Hono server),
call this function before the request reaches the handler so getClientIp can read the
correct proxy trust depth from the request.
Remarks: Side effects: this function mutates the Request object by defining a non-enumerable property keyed by an internal Symbol. The mutation is confined to the single Request instance — it does not affect other requests or global state. The property is configurable: true so it can be overwritten by a subsequent call with a different value on the same request object.
Remarks: In a full Slingshot app, do NOT call this — set trustProxy in the app config instead and the framework reads it from SlingshotContext. This function is only for plain Hono servers that call getClientIp() directly without a SlingshotContext in scope.
function getClientIp<E extends AppEnv>(c: Context<E>): stringSource: packages/slingshot-core/src/clientIp.ts
getContext
Section titled “getContext”Attach a SlingshotContext to a Hono app instance.
Called once by createApp() after the context is fully assembled. The context is stored
as a non-enumerable property keyed by a well-known Symbol so that it does not appear
in object spreads or JSON.stringify output. When the target object exposes
app.use(...) (for example a Hono app in standalone tests), attachContext()
also installs a lightweight request middleware that seeds c.set('slingshotCtx', ctx)
so request-time helpers like getSlingshotCtx(c) work without the full createApp()
bootstrap.
Remarks: Do not call from plugin or application code. This function is called exactly once per app instance by createApp() after the context is fully assembled.
Remarks: Calling attachContext more than once on the same app object with different context instances causes two categories of breakage, so this function now throws instead of allowing a second attachment:
Remarks: 1. Duplicate context per app — a second call would otherwise overwrite the first context. Any code that captured a reference to the first context via getContext(app) would then hold stale state while request middleware could still reference the old closure.
Remarks: 2. WeakMap collision — framework internals that key off the app object (e.g. the Reflect-symbol DI table) are keyed by app identity. If two contexts share the same app reference they collide on those lookups, producing hard-to-diagnose bugs where one plugin’s resolver or repo leaks into another app instance’s context.
Remarks: Plugin code should always call getContext(app) to read the context and must never attempt to create or attach one.
function getContext(app: object): SlingshotContextSource: packages/slingshot-core/src/context/contextStore.ts
getContextOrNull
Section titled “getContextOrNull”Attach a SlingshotContext to a Hono app instance.
Called once by createApp() after the context is fully assembled. The context is stored
as a non-enumerable property keyed by a well-known Symbol so that it does not appear
in object spreads or JSON.stringify output. When the target object exposes
app.use(...) (for example a Hono app in standalone tests), attachContext()
also installs a lightweight request middleware that seeds c.set('slingshotCtx', ctx)
so request-time helpers like getSlingshotCtx(c) work without the full createApp()
bootstrap.
Remarks: Do not call from plugin or application code. This function is called exactly once per app instance by createApp() after the context is fully assembled.
Remarks: Calling attachContext more than once on the same app object with different context instances causes two categories of breakage, so this function now throws instead of allowing a second attachment:
Remarks: 1. Duplicate context per app — a second call would otherwise overwrite the first context. Any code that captured a reference to the first context via getContext(app) would then hold stale state while request middleware could still reference the old closure.
Remarks: 2. WeakMap collision — framework internals that key off the app object (e.g. the Reflect-symbol DI table) are keyed by app identity. If two contexts share the same app reference they collide on those lookups, producing hard-to-diagnose bugs where one plugin’s resolver or repo leaks into another app instance’s context.
Remarks: Plugin code should always call getContext(app) to read the context and must never attempt to create or attach one.
function getContextOrNull(app: object): SlingshotContext | nullSource: packages/slingshot-core/src/context/contextStore.ts
getMongoFromApp
Section titled “getMongoFromApp”Lazy mongoose module loader — caching a require() result, not runtime state.
function getMongoFromApp(app: object,): { auth: Connection | null; app: Connection | null } | nullSource: src/lib/mongo.ts
getMongooseModule
Section titled “getMongooseModule”Lazy mongoose module loader — caching a require() result, not runtime state.
function getMongooseModule(): MongooseModuleSource: src/lib/mongo.ts
getRedisFromApp
Section titled “getRedisFromApp”Redis host:port (e.g., “localhost:6379”)
function getRedisFromApp(app: object): RedisClass | nullSource: src/lib/redis.ts
getRequestTenantId
Section titled “getRequestTenantId”Resolve the canonical actor for a Hono request context.
Reads the actor variable published by the auth middleware (identify,
bearerAuth, or a custom identity middleware). Returns ANONYMOUS_ACTOR
when no actor has been published.
function getRequestTenantId(c: Context<AppEnv>): string | nullSource: packages/slingshot-core/src/actorContext.ts
getRoomPresence
Section titled “getRoomPresence”True when the user holds at least one live socket in the room.
Presence is the only reliable liveness signal for a room member: the engine’s
per-player connected flag exists only while a game runtime is active, so a
lobby (no runtime yet) has no other way to tell whether the host is still
there. Apps use this to detect an absent host and offer recovery.
function getRoomPresence(state: WsState, endpoint: string, room: string): string[]Source: src/framework/ws/presence.ts
getRooms
Section titled “getRooms”Safe default room-subscribe authorization, applied when an endpoint provides
no explicit onRoomSubscribe guard.
Raw {action:'subscribe', room} messages are handled before per-event auth,
so without a guard any socket — including an anonymous one — could subscribe
to another user’s private room (e.g. sessions:<sid>:player:<victimUserId>)
and receive their private state. This default denies subscription to any
per-user room (a room containing a :player:<userId> segment) unless the
socket’s authenticated actor IS that user. The target userId is embedded in
the room name, so this self-authorization needs no external session lookup.
All other rooms remain allowed by default so existing consumers and
legitimate session-room subscriptions keep working. Endpoints that need
stricter or namespace-specific rules set their own onRoomSubscribe, which
fully replaces this default.
function getRooms(state: WsState, endpoint: string): string[]Source: src/framework/ws/rooms.ts
getRoomSubscribers
Section titled “getRoomSubscribers”Safe default room-subscribe authorization, applied when an endpoint provides
no explicit onRoomSubscribe guard.
Raw {action:'subscribe', room} messages are handled before per-event auth,
so without a guard any socket — including an anonymous one — could subscribe
to another user’s private room (e.g. sessions:<sid>:player:<victimUserId>)
and receive their private state. This default denies subscription to any
per-user room (a room containing a :player:<userId> segment) unless the
socket’s authenticated actor IS that user. The target userId is embedded in
the room name, so this self-authorization needs no external session lookup.
All other rooms remain allowed by default so existing consumers and
legitimate session-room subscriptions keep working. Endpoints that need
stricter or namespace-specific rules set their own onRoomSubscribe, which
fully replaces this default.
function getRoomSubscribers(state: WsState, endpoint: string, room: string): string[]Source: src/framework/ws/rooms.ts
getServerContext
Section titled “getServerContext”Shutdown registry shape. Lives on process via a well-known Symbol so there
is zero module-level mutable state. The registry is truly process-scoped
(where POSIX signals live) and survives module re-evaluation.
function getServerContext(server: object): SlingshotContext | nullSource: src/server.ts
getSlingshotCtx
Section titled “getSlingshotCtx”A single field-level validation error detail produced by the default formatter.
function getSlingshotCtx(c: Context<AppEnv>): SlingshotContextSource: packages/slingshot-core/src/context.ts
getSubscriptions
Section titled “getSubscriptions”Safe default room-subscribe authorization, applied when an endpoint provides
no explicit onRoomSubscribe guard.
Raw {action:'subscribe', room} messages are handled before per-event auth,
so without a guard any socket — including an anonymous one — could subscribe
to another user’s private room (e.g. sessions:<sid>:player:<victimUserId>)
and receive their private state. This default denies subscription to any
per-user room (a room containing a :player:<userId> segment) unless the
socket’s authenticated actor IS that user. The target userId is embedded in
the room name, so this self-authorization needs no external session lookup.
All other rooms remain allowed by default so existing consumers and
legitimate session-room subscriptions keep working. Endpoints that need
stricter or namespace-specific rules set their own onRoomSubscribe, which
fully replaces this default.
function getSubscriptions<T extends WithRooms>(ws: ServerWebSocket<T>): string[]Source: src/framework/ws/rooms.ts
getUploadRecord
Section titled “getUploadRecord”Store a new upload record. Keyed by the storage key.
async function getUploadRecord(key: string, app: object): Promise<UploadRecord | null>Source: src/framework/upload/registry.ts
getUserPresence
Section titled “getUserPresence”True when the user holds at least one live socket in the room.
Presence is the only reliable liveness signal for a room member: the engine’s
per-player connected flag exists only while a game runtime is active, so a
lobby (no runtime yet) has no other way to tell whether the host is still
there. Apps use this to detect an absent host and offer recovery.
function getUserPresence(state: WsState, userId: string): string[]Source: src/framework/ws/presence.ts
handleUpload
Section titled “handleUpload”Options for the handleUpload middleware.
All fields are optional overrides of the app-level upload configuration
stored in SlingshotContext. Values provided here take precedence over the
app-level defaults for a specific route.
See UploadOpts (from @framework/upload/upload) for available fields:
maxFileSize, maxFiles, allowedMimeTypes, keyPrefix, etc.
function handleUpload(opts?: UploadMiddlewareOptions): MiddlewareHandler<AppEnv>Source: src/framework/middleware/upload.ts
hmacSign
Section titled “hmacSign”Sign data with the active key (first element of secret).
Normalizes string | string[] so that an array is never passed directly to
createHmac() — which would silently call .toString() and produce
“[object Array]” as the key.
function hmacSign(data: string, secret: string | string[]): stringSource: src/lib/signing.ts
hmacVerify
Section titled “hmacVerify”Sign data with the active key (first element of secret).
Normalizes string | string[] so that an array is never passed directly to
createHmac() — which would silently call .toString() and produce
“[object Array]” as the key.
function hmacVerify(data: string, sig: string, secret: string | string[]): booleanSource: src/lib/signing.ts
idempotent
Section titled “idempotent”TTL in seconds for cached responses. Default: 86400 (24 hours).
function idempotent(opts?: IdempotencyOptions): MiddlewareHandler<AppEnv>Source: src/framework/lib/idempotency.ts
incrementCounter
Section titled “incrementCounter”Create a fresh, instance-scoped metrics state container.
function incrementCounter(state: MetricsState, name: string, labels: Labels, amount = 1,): voidSource: src/framework/metrics/registry.ts
Config-driven entity & repository generation.
Plugin authors describe an entity’s shape declaratively using the field.*() builder
API, then get generated TypeScript types, Zod schemas, adapter interfaces, and
backend-specific implementations from a single source of truth.
import { defineEntity, field, index } from '@lastshotlabs/slingshot-core';
export const Message = defineEntity('Message', {namespace: 'chat',fields: {id: field.string({ primary: true, default: 'uuid' }),roomId: field.string(),authorId: field.string(),content: field.string(),type: field.enum(['text', 'image', 'system'], { default: 'text' }),metadata: field.json({ optional: true }),createdAt: field.date({ default: 'now' }),updatedAt: field.date({ default: 'now', onUpdate: 'now' }),},softDelete: { field: 'status', value: 'deleted' },defaultSort: { field: 'createdAt', direction: 'desc' },pagination: { cursor: { fields: ['createdAt', 'id'] }, defaultLimit: 50, maxLimit: 200 },indexes: [index(['roomId', 'createdAt'], { direction: 'desc' }),index(['authorId', 'createdAt'], { direction: 'desc' }),],});function index(fields: string[], opts?: { direction?: 'asc' | 'desc'; unique?: boolean },): IndexDefSource: packages/slingshot-core/src/entityConfig.ts
inspectPackage
Section titled “inspectPackage”Typed, named token a package publishes and consumers resolve to exchange a capability value across packages.
function inspectPackage(pkg: SlingshotPackageDefinition): PackageInspectionSource: packages/slingshot-core/src/packageAuthoring.ts
invalidateTenantCache
Section titled “invalidateTenantCache”A fixed-capacity in-memory LRU cache with per-entry TTL.
Entries are evicted in least-recently-used order when the cache reaches
maxSize. Expired entries are lazily removed on read (no background timer).
Used internally by createTenantMiddleware to cache resolved TenantConfig
objects and avoid redundant onResolve calls.
function invalidateTenantCache(cache: TenantResolutionCache | null | undefined, tenantId: string,): voidSource: src/framework/middleware/tenant.ts
isUserPresent
Section titled “isUserPresent”True when the user holds at least one live socket in the room.
Presence is the only reliable liveness signal for a room member: the engine’s
per-player connected flag exists only while a game runtime is active, so a
lobby (no runtime yet) has no other way to tell whether the host is still
there. Apps use this to detect an absent host and offer recovery.
function isUserPresent(state: WsState, endpoint: string, room: string, userId: string,): booleanSource: src/framework/ws/presence.ts
localStorage
Section titled “localStorage”Default RuntimeFs implementation using Bun’s native file APIs.
function localStorage(config: LocalStorageConfig): StorageAdapterSource: src/framework/adapters/localStorage.ts
Verbose-mode console logger.
Writes to console.log when LOGGING_VERBOSE=true or when NODE_ENV is
not 'production'. Silenced in production by default.
function log(...args: unknown[]): voidSource: src/framework/lib/logger.ts
maybeEntityAdapter
Section titled “maybeEntityAdapter”Writable plugin state used internally by the framework bootstrap lifecycle.
function maybeEntityAdapter<TAdapter extends object = object>(input: PluginStateMap | PluginStateCarrier | object | null | undefined, lookup: EntityAdapterLookupInput<TAdapter>,): TAdapter | nullSource: packages/slingshot-core/src/pluginState.ts
maybeSignCursor
Section titled “maybeSignCursor”Default values for cursor-based pagination query parameters.
function maybeSignCursor(cursor: string | null, signing?: { config: SigningConfig | null; secret: string | string[] | null },): string | nullSource: src/framework/lib/pagination.ts
memoryStorage
Section titled “memoryStorage”Create a StorageAdapter that stores files in-process in a Map.
Remarks: Ephemeral, in-process only — all stored data lives in heap memory and is discarded when the process exits or the adapter is garbage-collected. This adapter is suitable for development, testing, and single-process environments only. It must not be used in production multi-process deployments because files stored in one process are invisible to other processes.
Remarks: Entries are evicted via LRU when the store reaches DEFAULT_MAX_ENTRIES (imported from slingshot-core) to prevent unbounded memory growth.
function memoryStorage(): StorageAdapterSource: src/framework/adapters/memoryStorage.ts
metricsCollector
Section titled “metricsCollector”Instance-owned metrics registry.
function metricsCollector(options: MetricsMiddlewareOptions): MiddlewareHandler<AppEnv>Source: src/framework/middleware/metrics.ts
observeHistogram
Section titled “observeHistogram”Create a fresh, instance-scoped metrics state container.
function observeHistogram(state: MetricsState, name: string, labels: Labels, value: number, buckets: number[] = DEFAULT_BUCKETS,): voidSource: src/framework/metrics/registry.ts
offsetParams
Section titled “offsetParams”Default overrides for offset-based pagination query parameters. All fields are optional — omitted fields fall back to framework defaults (limit=50, offset=0, maxLimit=200).
function offsetParams(defaults?: OffsetParamDefaults): voidSource: packages/slingshot-core/src/pagination.ts
op.*() builder API for operation definitions.
Each builder adds the kind discriminant and returns a typed config object.
Pure functions — no side effects, no validation (that’s defineOperations’ job).
Source: packages/slingshot-entity/src/builders/op.ts
paginatedResponse
Section titled “paginatedResponse”Default overrides for offset-based pagination query parameters. All fields are optional — omitted fields fall back to framework defaults (limit=50, offset=0, maxLimit=200).
function paginatedResponse<T extends ZodType>(itemSchema: T, name: string): voidSource: packages/slingshot-core/src/pagination.ts
parseCursorParams
Section titled “parseCursorParams”Default values for cursor-based pagination query parameters.
function parseCursorParams(raw: { limit?: string; cursor?: string }, defaults?: CursorParamDefaults, signing?: { config: SigningConfig | null; secret: string | string[] | null },): ParsedCursorParams &Source: src/framework/lib/pagination.ts
parseOffsetParams
Section titled “parseOffsetParams”Default overrides for offset-based pagination query parameters. All fields are optional — omitted fields fall back to framework defaults (limit=50, offset=0, maxLimit=200).
function parseOffsetParams(raw: { limit?: string; offset?: string }, defaults?: OffsetParamDefaults,): ParsedOffsetParamsSource: packages/slingshot-core/src/pagination.ts
parseUpload
Section titled “parseUpload”Options for configuring file upload parsing and storage.
async function parseUpload(c: Context<AppEnv>, opts?: UploadOpts,): Promise<UploadResult[]>Source: src/framework/upload/upload.ts
provideCapability
Section titled “provideCapability”Typed, named token a package publishes and consumers resolve to exchange a capability value across packages.
function provideCapability<TValue>(capability: PackageCapabilityHandle<TValue>, resolve: PublishedPackageCapability<TValue>['resolve'],): PublishedPackageCapability<TValue>Source: packages/slingshot-core/src/packageAuthoring.ts
publish
Section titled “publish”Safe default room-subscribe authorization, applied when an endpoint provides
no explicit onRoomSubscribe guard.
Raw {action:'subscribe', room} messages are handled before per-event auth,
so without a guard any socket — including an anonymous one — could subscribe
to another user’s private room (e.g. sessions:<sid>:player:<victimUserId>)
and receive their private state. This default denies subscription to any
per-user room (a room containing a :player:<userId> segment) unless the
socket’s authenticated actor IS that user. The target userId is embedded in
the room name, so this self-authorization needs no external session lookup.
All other rooms remain allowed by default so existing consumers and
legitimate session-room subscriptions keep working. Endpoints that need
stricter or namespace-specific rules set their own onRoomSubscribe, which
fully replaces this default.
function publish(state: WsState, endpoint: string, room: string, data: unknown, options?: PublishOptions,): voidSource: src/framework/ws/rooms.ts
rateLimit
Section titled “rateLimit”Also rate-limit by HTTP fingerprint in addition to IP. Default: false
function rateLimit({ windowMs, max, fingerprintLimit = false, }: RateLimitOptions): MiddlewareHandler<AppEnv>Source: src/framework/middleware/rateLimit.ts
registerGaugeCallback
Section titled “registerGaugeCallback”Create a fresh, instance-scoped metrics state container.
function registerGaugeCallback(state: MetricsState, name: string, cb: GaugeCallback): voidSource: src/framework/metrics/registry.ts
registerSchema
Section titled “registerSchema”The schema parameter type expected by zodOpenAPIRegistry.add().
function registerSchema<T extends ZodType>(name: string, schema: T): TSource: packages/slingshot-core/src/createRoute.ts
registerSchemas
Section titled “registerSchemas”The schema parameter type expected by zodOpenAPIRegistry.add().
Source: packages/slingshot-core/src/createRoute.ts
registerUpload
Section titled “registerUpload”Store a new upload record. Keyed by the storage key.
async function registerUpload(record: UploadRecord, app: object): Promise<void>Source: src/framework/upload/registry.ts
relation
Section titled “relation”Config-driven entity & repository generation.
Plugin authors describe an entity’s shape declaratively using the field.*() builder
API, then get generated TypeScript types, Zod schemas, adapter interfaces, and
backend-specific implementations from a single source of truth.
import { defineEntity, field, index } from '@lastshotlabs/slingshot-core';
export const Message = defineEntity('Message', {namespace: 'chat',fields: {id: field.string({ primary: true, default: 'uuid' }),roomId: field.string(),authorId: field.string(),content: field.string(),type: field.enum(['text', 'image', 'system'], { default: 'text' }),metadata: field.json({ optional: true }),createdAt: field.date({ default: 'now' }),updatedAt: field.date({ default: 'now', onUpdate: 'now' }),},softDelete: { field: 'status', value: 'deleted' },defaultSort: { field: 'createdAt', direction: 'desc' },pagination: { cursor: { fields: ['createdAt', 'id'] }, defaultLimit: 50, maxLimit: 200 },indexes: [index(['roomId', 'createdAt'], { direction: 'desc' }),index(['authorId', 'createdAt'], { direction: 'desc' }),],});Source: packages/slingshot-core/src/entityConfig.ts
requestId
Section titled “requestId”Hono middleware that generates and propagates a unique request identifier.
A fresh UUID v4 is generated server-side on every request. Client-supplied
X-Request-Id headers are intentionally ignored — accepting client-provided
values would allow audit log spoofing and idempotency key manipulation.
The ID is:
- Set on the Hono context via
c.set('requestId', id)so it is accessible in all subsequent middleware and route handlers. - Written to the
X-Request-Idresponse header after the handler chain completes, allowing clients to correlate requests with server-side logs.
Source: src/framework/middleware/requestId.ts
requestLogger
Section titled “requestLogger”Severity level for a structured request log entry.
"info"— successful responses (status < 400)."warn"— client-error responses (status 400–499)."error"— server-error responses (status >= 500) or unhandled exceptions.
function requestLogger(options: RequestLoggerOptions = {}): MiddlewareHandler<AppEnv>Source: src/framework/middleware/requestLogger.ts
requireCaptcha
Section titled “requireCaptcha”Middleware factory that verifies a CAPTCHA token from the request body.
When no config is provided, falls back to the captcha configuration
from the app’s SlingshotContext. If neither is available, the
middleware is a no-op (passes through to the next handler).
function requireCaptcha(config?: CaptchaConfig): MiddlewareHandler<AppEnv>Source: src/framework/middleware/captcha.ts
requireSignedRequest
Section titled “requireSignedRequest”Allowed age of the timestamp in milliseconds. Default: 300_000 (5 min).
function requireSignedRequest(opts?: RequestSigningOptions): MiddlewareHandler<AppEnv>Source: src/framework/middleware/requestSigning.ts
Typed, named token a package publishes and consumers resolve to exchange a capability value across packages.
Source: packages/slingshot-core/src/packageAuthoring.ts
s3Storage
Section titled “s3Storage”function s3Storage(config: S3StorageConfig): StorageAdapterSource: src/framework/adapters/s3Storage.ts
SECURITY_EVENT_TYPES
Section titled “SECURITY_EVENT_TYPES”Narrow, untyped view of the event bus for string-keyed subscriptions.
Plugins that subscribe to dynamically named events (e.g. entity:${storageName}.created)
cast the typed SlingshotEventBus to this interface rather than widening the global
SlingshotEventMap. This keeps type widening local per rule 12.
Defined here once so every consumer imports the same shape (rule 6). Use Pick to
narrow further when a module only needs emit or only needs on/off.
Source: packages/slingshot-core/src/eventBus.ts
serializeMetrics
Section titled “serializeMetrics”Create a fresh, instance-scoped metrics state container.
async function serializeMetrics(state: MetricsState): Promise<string>Source: src/framework/metrics/registry.ts
sha256
Section titled “sha256”Constant-time string comparison to prevent timing attacks on secret verification.
Uses Node.js’s native crypto.timingSafeEqual so that the comparison time is
independent of how many characters match. When the strings differ in length, a
same-buffer compare is performed to burn equivalent time before returning false.
function sha256(input: string): stringSource: packages/slingshot-core/src/crypto.ts
signCookieValue
Section titled “signCookieValue”Sign data with the active key (first element of secret).
Normalizes string | string[] so that an array is never passed directly to
createHmac() — which would silently call .toString() and produce
“[object Array]” as the key.
function signCookieValue(value: string, secret: string | string[]): stringSource: src/lib/signing.ts
signCursor
Section titled “signCursor”Sign data with the active key (first element of secret).
Normalizes string | string[] so that an array is never passed directly to
createHmac() — which would silently call .toString() and produce
“[object Array]” as the key.
function signCursor(payload: string, secret: string | string[]): stringSource: src/lib/signing.ts
timingSafeEqual
Section titled “timingSafeEqual”Constant-time string comparison to prevent timing attacks on secret verification.
Uses Node.js’s native crypto.timingSafeEqual so that the comparison time is
independent of how many characters match. When the strings differ in length, a
same-buffer compare is performed to burn equivalent time before returning false.
function timingSafeEqual(a: string, b: string): booleanSource: packages/slingshot-core/src/crypto.ts
toCamelCase
Section titled “toCamelCase”Shared field-mapping utilities for config-driven adapters.
- camelCase ↔ snake_case conversion
- SQL / Mongo type mapping
- Record transformation (domain ↔ storage)
- Auto-default resolution
- Naming conventions per backend
function toCamelCase(str: string): stringSource: packages/slingshot-entity/src/configDriven/fieldUtils.ts
toSnakeCase
Section titled “toSnakeCase”Shared field-mapping utilities for config-driven adapters.
- camelCase ↔ snake_case conversion
- SQL / Mongo type mapping
- Record transformation (domain ↔ storage)
- Auto-default resolution
- Naming conventions per backend
function toSnakeCase(str: string): stringSource: packages/slingshot-entity/src/configDriven/fieldUtils.ts
validate
Section titled “validate”Parse and validate the JSON body of a Request against a Zod schema.
async function validate<T extends z.ZodType>(schema: T, req: Request,): Promise<z.output<T>>Source: src/framework/lib/validate.ts
verifyCookieValue
Section titled “verifyCookieValue”Sign data with the active key (first element of secret).
Normalizes string | string[] so that an array is never passed directly to
createHmac() — which would silently call .toString() and produce
“[object Array]” as the key.
function verifyCookieValue(signed: string, secret: string | string[]): string | nullSource: src/lib/signing.ts
verifyCursor
Section titled “verifyCursor”Sign data with the active key (first element of secret).
Normalizes string | string[] so that an array is never passed directly to
createHmac() — which would silently call .toString() and produce
“[object Array]” as the key.
function verifyCursor(cursor: string, secret: string | string[]): string | nullSource: src/lib/signing.ts
verifyPresignedUrl
Section titled “verifyPresignedUrl”Sign data with the active key (first element of secret).
Normalizes string | string[] so that an array is never passed directly to
createHmac() — which would silently call .toString() and produce
“[object Array]” as the key.
function verifyPresignedUrl(url: string, method: string, secret: string | string[],): voidSource: src/lib/signing.ts
webhookAuth
Section titled “webhookAuth”Header name containing the Unix timestamp (seconds or ms).
function webhookAuth(options: WebhookAuthOptions): MiddlewareHandler<AppEnv>Source: src/framework/middleware/webhookAuth.ts
withSecurity
Section titled “withSecurity”The schema parameter type expected by zodOpenAPIRegistry.add().
function withSecurity<T extends RouteConfig>(route: T, ...schemes: Array<Record<string, string[]>>): TSource: packages/slingshot-core/src/createRoute.ts
wsEndpointKey
Section titled “wsEndpointKey”Produces a collision-safe composite key for scoping rooms to an endpoint.
Both endpoint and room are percent-encoded before joining with :.
Since encodeURIComponent encodes : → %3A, the literal : separator
can only come from this function — not from endpoint or room values.
Examples: wsEndpointKey(“/chat”, “general”) → “%2Fchat:general” wsEndpointKey(“/chat”, “room:1”) → “%2Fchat:room%3A1” wsEndpointKey(“/a:b”, “c”) → “%2Fa%3Ab:c” wsEndpointKey(“/notifications”, “x”) → “%2Fnotifications:x”
Used for: in-memory room maps, Redis channel names, Redis message keys. NOT used for: SQLite or MongoDB schemas (those store endpoint + room separately).
function wsEndpointKey(endpoint: string, room: string): stringSource: src/framework/ws/namespace.ts
zodToMongoose
Section titled “zodToMongoose”Lazily access the Mongoose Schema class (avoids top-level require of mongoose)
function zodToMongoose(zodSchema: ZodObjectLike, config: ZodToMongooseConfig = {},): Record<string, unknown>Source: src/framework/lib/zodToMongoose.ts
Constants
Section titled “Constants”COOKIE_CSRF_TOKEN
Section titled “COOKIE_CSRF_TOKEN”Cookie name for the session access token (HttpOnly, short-lived). Used by the auth plugin to set and read the primary session credential.
Source: packages/slingshot-core/src/constants.ts
COOKIE_REFRESH_TOKEN
Section titled “COOKIE_REFRESH_TOKEN”Cookie name for the session access token (HttpOnly, short-lived). Used by the auth plugin to set and read the primary session credential.
Source: packages/slingshot-core/src/constants.ts
COOKIE_TOKEN
Section titled “COOKIE_TOKEN”Cookie name for the session access token (HttpOnly, short-lived). Used by the auth plugin to set and read the primary session credential.
Source: packages/slingshot-core/src/constants.ts
HEADER_CSRF_TOKEN
Section titled “HEADER_CSRF_TOKEN”Cookie name for the session access token (HttpOnly, short-lived). Used by the auth plugin to set and read the primary session credential.
Source: packages/slingshot-core/src/constants.ts
HEADER_IDEMPOTENCY_KEY
Section titled “HEADER_IDEMPOTENCY_KEY”Cookie name for the session access token (HttpOnly, short-lived). Used by the auth plugin to set and read the primary session credential.
Source: packages/slingshot-core/src/constants.ts
HEADER_REFRESH_TOKEN
Section titled “HEADER_REFRESH_TOKEN”Cookie name for the session access token (HttpOnly, short-lived). Used by the auth plugin to set and read the primary session credential.
Source: packages/slingshot-core/src/constants.ts
HEADER_REQUEST_ID
Section titled “HEADER_REQUEST_ID”Cookie name for the session access token (HttpOnly, short-lived). Used by the auth plugin to set and read the primary session credential.
Source: packages/slingshot-core/src/constants.ts
HEADER_SIGNATURE
Section titled “HEADER_SIGNATURE”Cookie name for the session access token (HttpOnly, short-lived). Used by the auth plugin to set and read the primary session credential.
Source: packages/slingshot-core/src/constants.ts
HEADER_TIMESTAMP
Section titled “HEADER_TIMESTAMP”Cookie name for the session access token (HttpOnly, short-lived). Used by the auth plugin to set and read the primary session credential.
Source: packages/slingshot-core/src/constants.ts
HEADER_USER_TOKEN
Section titled “HEADER_USER_TOKEN”Cookie name for the session access token (HttpOnly, short-lived). Used by the auth plugin to set and read the primary session credential.
Source: packages/slingshot-core/src/constants.ts
Classes
Section titled “Classes”HttpError
Section titled “HttpError”Base error class for all Slingshot errors.
Carries a machine-readable code string for programmatic discrimination
and an optional cause for error chaining. Feature packages should extend
this class (or one of the HTTP-aware subclasses) rather than throwing
generic Error instances.
Source: packages/slingshot-core/src/errors.ts
InMemoryTransport
Section titled “InMemoryTransport”Pluggable transport for cross-instance WebSocket message delivery.
publish() is called on every room broadcast — the transport fans out
the message to other server instances (e.g. via Redis pub/sub).
connect() is called once at server startup. The onMessage callback
should be invoked when a message arrives from another instance —
it will be delivered to local sockets via Bun’s native server.publish().
disconnect() is called on graceful shutdown.
Source: src/framework/ws/transport.ts
ProductionReadinessError
Section titled “ProductionReadinessError”Source: src/prodReadiness.ts
ValidationError
Section titled “ValidationError”Base error class for all Slingshot errors.
Carries a machine-readable code string for programmatic discrimination
and an optional cause for error chaining. Feature packages should extend
this class (or one of the HTTP-aware subclasses) rather than throwing
generic Error instances.
Source: packages/slingshot-core/src/errors.ts
Interfaces
Section titled “Interfaces”AppMeta
Section titled “AppMeta”Source: src/config/types/meta.ts
AuditLogEntry
Section titled “AuditLogEntry”A single audit log entry recording an HTTP request or admin action.
Stored by AuditLogProvider.logEntry() and queryable via AuditLogProvider.getLogs().
The audit middleware creates entries automatically for authenticated requests.
Source: packages/slingshot-core/src/auditLog.ts
AuditLogMiddlewareOptions
Section titled “AuditLogMiddlewareOptions”Source: src/framework/middleware/auditLog.ts
AuditLogOptions
Section titled “AuditLogOptions”Configuration for creating an audit log provider.
Source: src/framework/auditLog/index.ts
AuditLogQuery
Section titled “AuditLogQuery”Configuration for creating an audit log provider.
Source: src/framework/auditLog/index.ts
AuthDbConfig
Section titled “AuthDbConfig”Database/store connection configuration for slingshot-auth.
Controls which persistence backends are used for sessions, OAuth state, and the user auth adapter. Each field is optional — defaults are chosen by the bootstrap layer based on what is available (Redis → SQLite → memory).
Remarks: When running under the full framework (createApp / createServer), connection objects are provided automatically via SlingshotFrameworkConfig. These fields are only relevant in standalone mode or when explicitly overriding framework-provided connections.
Source: packages/slingshot-auth/src/types/config.ts
AuthSecurityConfig
Section titled “AuthSecurityConfig”Database/store connection configuration for slingshot-auth.
Controls which persistence backends are used for sessions, OAuth state, and the user auth adapter. Each field is optional — defaults are chosen by the bootstrap layer based on what is available (Redis → SQLite → memory).
Remarks: When running under the full framework (createApp / createServer), connection objects are provided automatically via SlingshotFrameworkConfig. These fields are only relevant in standalone mode or when explicitly overriding framework-provided connections.
Source: packages/slingshot-auth/src/types/config.ts
BotProtectionConfig
Section titled “BotProtectionConfig”Source: src/config/types/security.ts
BotProtectionOptions
Section titled “BotProtectionOptions”Source: src/framework/middleware/botProtection.ts
CaptchaConfig
Section titled “CaptchaConfig”Supported CAPTCHA verification providers.
'recaptcha'— Google reCAPTCHA v2 or v3'hcaptcha'— hCaptcha'turnstile'— Cloudflare Turnstile
Source: packages/slingshot-core/src/captcha.ts
CreateAppConfig
Section titled “CreateAppConfig”Source: src/app.ts
CreateAppResult
Section titled “CreateAppResult”Absolute path to the service’s routes directory (use import.meta.dir + “/routes”). Optional — omit when all routes are registered via plugins.
Source: src/app.ts
CreateServerConfig
Section titled “CreateServerConfig”Source: src/server.ts
CreateTenantOptions
Section titled “CreateTenantOptions”Read-only representation of a tenant record.
Source: src/framework/tenancy/service.ts
CursorPaginationOptions
Section titled “CursorPaginationOptions”Config-driven entity & repository generation.
Plugin authors describe an entity’s shape declaratively using the field.*() builder
API, then get generated TypeScript types, Zod schemas, adapter interfaces, and
backend-specific implementations from a single source of truth.
import { defineEntity, field, index } from '@lastshotlabs/slingshot-core';
export const Message = defineEntity('Message', {namespace: 'chat',fields: {id: field.string({ primary: true, default: 'uuid' }),roomId: field.string(),authorId: field.string(),content: field.string(),type: field.enum(['text', 'image', 'system'], { default: 'text' }),metadata: field.json({ optional: true }),createdAt: field.date({ default: 'now' }),updatedAt: field.date({ default: 'now', onUpdate: 'now' }),},softDelete: { field: 'status', value: 'deleted' },defaultSort: { field: 'createdAt', direction: 'desc' },pagination: { cursor: { fields: ['createdAt', 'id'] }, defaultLimit: 50, maxLimit: 200 },indexes: [index(['roomId', 'createdAt'], { direction: 'desc' }),index(['authorId', 'createdAt'], { direction: 'desc' }),],});Source: packages/slingshot-core/src/entityConfig.ts
CursorParamDefaults
Section titled “CursorParamDefaults”Default values for cursor-based pagination query parameters.
Source: src/framework/lib/pagination.ts
CursorResult
Section titled “CursorResult”Default values for cursor-based pagination query parameters.
Source: src/framework/lib/pagination.ts
DbConfig
Section titled “DbConfig”Source: src/config/types/db.ts
DefaultValidationErrorBody
Section titled “DefaultValidationErrorBody”A single field-level validation error detail produced by the default formatter.
Source: packages/slingshot-core/src/context.ts
DefinePackageInput
Section titled “DefinePackageInput”Typed, named token a package publishes and consumers resolve to exchange a capability value across packages.
Source: packages/slingshot-core/src/packageAuthoring.ts
DomainRouteDefinition
Section titled “DomainRouteDefinition”Typed, named token a package publishes and consumers resolve to exchange a capability value across packages.
Source: packages/slingshot-core/src/packageAuthoring.ts
EntityAdapter
Section titled “EntityAdapter”Config-driven entity & repository generation.
Plugin authors describe an entity’s shape declaratively using the field.*() builder
API, then get generated TypeScript types, Zod schemas, adapter interfaces, and
backend-specific implementations from a single source of truth.
import { defineEntity, field, index } from '@lastshotlabs/slingshot-core';
export const Message = defineEntity('Message', {namespace: 'chat',fields: {id: field.string({ primary: true, default: 'uuid' }),roomId: field.string(),authorId: field.string(),content: field.string(),type: field.enum(['text', 'image', 'system'], { default: 'text' }),metadata: field.json({ optional: true }),createdAt: field.date({ default: 'now' }),updatedAt: field.date({ default: 'now', onUpdate: 'now' }),},softDelete: { field: 'status', value: 'deleted' },defaultSort: { field: 'createdAt', direction: 'desc' },pagination: { cursor: { fields: ['createdAt', 'id'] }, defaultLimit: 50, maxLimit: 200 },indexes: [index(['roomId', 'createdAt'], { direction: 'desc' }),index(['authorId', 'createdAt'], { direction: 'desc' }),],});Source: packages/slingshot-core/src/entityConfig.ts
EntityConfig
Section titled “EntityConfig”Config-driven entity & repository generation.
Plugin authors describe an entity’s shape declaratively using the field.*() builder
API, then get generated TypeScript types, Zod schemas, adapter interfaces, and
backend-specific implementations from a single source of truth.
import { defineEntity, field, index } from '@lastshotlabs/slingshot-core';
export const Message = defineEntity('Message', {namespace: 'chat',fields: {id: field.string({ primary: true, default: 'uuid' }),roomId: field.string(),authorId: field.string(),content: field.string(),type: field.enum(['text', 'image', 'system'], { default: 'text' }),metadata: field.json({ optional: true }),createdAt: field.date({ default: 'now' }),updatedAt: field.date({ default: 'now', onUpdate: 'now' }),},softDelete: { field: 'status', value: 'deleted' },defaultSort: { field: 'createdAt', direction: 'desc' },pagination: { cursor: { fields: ['createdAt', 'id'] }, defaultLimit: 50, maxLimit: 200 },indexes: [index(['roomId', 'createdAt'], { direction: 'desc' }),index(['authorId', 'createdAt'], { direction: 'desc' }),],});Source: packages/slingshot-core/src/entityConfig.ts
FieldDef
Section titled “FieldDef”Config-driven entity & repository generation.
Plugin authors describe an entity’s shape declaratively using the field.*() builder
API, then get generated TypeScript types, Zod schemas, adapter interfaces, and
backend-specific implementations from a single source of truth.
import { defineEntity, field, index } from '@lastshotlabs/slingshot-core';
export const Message = defineEntity('Message', {namespace: 'chat',fields: {id: field.string({ primary: true, default: 'uuid' }),roomId: field.string(),authorId: field.string(),content: field.string(),type: field.enum(['text', 'image', 'system'], { default: 'text' }),metadata: field.json({ optional: true }),createdAt: field.date({ default: 'now' }),updatedAt: field.date({ default: 'now', onUpdate: 'now' }),},softDelete: { field: 'status', value: 'deleted' },defaultSort: { field: 'createdAt', direction: 'desc' },pagination: { cursor: { fields: ['createdAt', 'id'] }, defaultLimit: 50, maxLimit: 200 },indexes: [index(['roomId', 'createdAt'], { direction: 'desc' }),index(['authorId', 'createdAt'], { direction: 'desc' }),],});Source: packages/slingshot-core/src/entityConfig.ts
FieldOptions
Section titled “FieldOptions”Config-driven entity & repository generation.
Plugin authors describe an entity’s shape declaratively using the field.*() builder
API, then get generated TypeScript types, Zod schemas, adapter interfaces, and
backend-specific implementations from a single source of truth.
import { defineEntity, field, index } from '@lastshotlabs/slingshot-core';
export const Message = defineEntity('Message', {namespace: 'chat',fields: {id: field.string({ primary: true, default: 'uuid' }),roomId: field.string(),authorId: field.string(),content: field.string(),type: field.enum(['text', 'image', 'system'], { default: 'text' }),metadata: field.json({ optional: true }),createdAt: field.date({ default: 'now' }),updatedAt: field.date({ default: 'now', onUpdate: 'now' }),},softDelete: { field: 'status', value: 'deleted' },defaultSort: { field: 'createdAt', direction: 'desc' },pagination: { cursor: { fields: ['createdAt', 'id'] }, defaultLimit: 50, maxLimit: 200 },indexes: [index(['roomId', 'createdAt'], { direction: 'desc' }),index(['authorId', 'createdAt'], { direction: 'desc' }),],});Source: packages/slingshot-core/src/entityConfig.ts
GeneratedSchemas
Section titled “GeneratedSchemas”Zod schema generation from entity config.
Derives four Zod schemas from a ResolvedEntityConfig at runtime, without any
code generation step. Schemas are consumed by route handlers for request validation
and by the REST API generator for OpenAPI type inference.
Generated schemas:
entitySchema— Full record shape; optional fields become.optional().createSchema— Create input; excludes auto-default fields (uuid,now,cuid) andonUpdatefields. Fields with literal defaults or marked optional are optional in this schema.updateSchema— Partial update input; all included fields are.optional(). Excludes immutable fields andonUpdatefields.listOptionsSchema— Filter + pagination options for list endpoints. Includes enum/boolean fields, all indexed fields, the tenant field, andlimit/cursor/sortDir.
Source: packages/slingshot-entity/src/configDriven/schemaGen.ts
HeartbeatConfig
Section titled “HeartbeatConfig”Per-endpoint WebSocket heartbeat configuration.
The server sends periodic pings; sockets that fail to respond with a pong within the timeout window are closed automatically.
Source: src/framework/ws/heartbeat.ts
HookServices
Section titled “HookServices”HookServices — typed accessors for out-of-request callbacks.
Auth lifecycle hooks, orchestration workflow hooks, and queue dead-letter callbacks
fire outside any Hono request context — there is no c to read state from. Without
a canonical contract these callbacks ended up starved differently in each plugin
(some got pluginState, others got only request metadata, others nothing at all).
HookServices is the shared shape every plugin’s out-of-request callbacks intersect
into their payload. Hook authors get the same typed accessors that
PackageDomainRouteContext exposes to package-authored route handlers, so the
ergonomics line up across request and non-request callsites:
postLogin: async ({ userId, services }) => {const adapter = services.entities.get(GuestIdentity); // typed via entity moduleconst mailer = services.capabilities.require(MailerCapability);await services.bus.emit('user.signed-in', { userId });}Plugins build a HookServices instance by calling buildHookServices() at the call
site of each hook, threading their own pluginState/bus/logger and the app’s
Hono reference. The framework supplies the shared
SlingshotContext.capabilityProviders map so capability lookups work identically to
those inside request handlers.
Worker-process boundary. Some adapters (notably the Temporal orchestration worker)
run hook code in a separate process where the framework’s app is not reachable.
Those callsites pass services: undefined rather than fabricate broken accessors.
Hook authors who need framework state from worker-mode code should restructure their
work to run at the workflow level (in-process) and thread data into the task input.
Source: packages/slingshot-core/src/hookServices.ts
IdempotencyAdapter
Section titled “IdempotencyAdapter”Storage contract for idempotency key deduplication.
When a client retries a mutating request with the same Idempotency-Key header,
the idempotency middleware looks up the cached response via this adapter and returns
it instead of executing the handler again.
Remarks: Implementations must respect the ttlSeconds argument in set() — records should expire automatically after the configured TTL. The framework sets a default TTL of 24 hours for idempotency records.
Source: packages/slingshot-core/src/idempotencyAdapter.ts
IdempotencyOptions
Section titled “IdempotencyOptions”Source: src/framework/lib/idempotency.ts
IndexDef
Section titled “IndexDef”Config-driven entity & repository generation.
Plugin authors describe an entity’s shape declaratively using the field.*() builder
API, then get generated TypeScript types, Zod schemas, adapter interfaces, and
backend-specific implementations from a single source of truth.
import { defineEntity, field, index } from '@lastshotlabs/slingshot-core';
export const Message = defineEntity('Message', {namespace: 'chat',fields: {id: field.string({ primary: true, default: 'uuid' }),roomId: field.string(),authorId: field.string(),content: field.string(),type: field.enum(['text', 'image', 'system'], { default: 'text' }),metadata: field.json({ optional: true }),createdAt: field.date({ default: 'now' }),updatedAt: field.date({ default: 'now', onUpdate: 'now' }),},softDelete: { field: 'status', value: 'deleted' },defaultSort: { field: 'createdAt', direction: 'desc' },pagination: { cursor: { fields: ['createdAt', 'id'] }, defaultLimit: 50, maxLimit: 200 },indexes: [index(['roomId', 'createdAt'], { direction: 'desc' }),index(['authorId', 'createdAt'], { direction: 'desc' }),],});Source: packages/slingshot-core/src/entityConfig.ts
JobsConfig
Section titled “JobsConfig”Source: src/config/types/jobs.ts
LocalStorageConfig
Section titled “LocalStorageConfig”Source: src/framework/adapters/localStorage.ts
LoggingConfig
Section titled “LoggingConfig”Source: src/config/types/logging.ts
MetricsConfig
Section titled “MetricsConfig”Source: src/config/types/metrics.ts
MetricsMiddlewareOptions
Section titled “MetricsMiddlewareOptions”Source: src/framework/middleware/metrics.ts
ObservabilityConfig
Section titled “ObservabilityConfig”Configuration for distributed tracing via OpenTelemetry.
Slingshot instruments bootstrap phases, request lifecycles, and plugin
lifecycle calls with OTel spans. The framework depends on
@opentelemetry/api only — install an OTel SDK and exporter in your app
to collect spans.
When enabled is false or omitted, no tracer is created and no spans are
recorded. The OTel API returns no-op implementations in that case, so there
is zero runtime overhead.
Source: src/config/types/observability.ts
OffsetParamDefaults
Section titled “OffsetParamDefaults”Default overrides for offset-based pagination query parameters. All fields are optional — omitted fields fall back to framework defaults (limit=50, offset=0, maxLimit=200).
Source: packages/slingshot-core/src/pagination.ts
PackageCapabilityHandle
Section titled “PackageCapabilityHandle”Typed, named token a package publishes and consumers resolve to exchange a capability value across packages.
Source: packages/slingshot-core/src/packageAuthoring.ts
PackageCapabilityReader
Section titled “PackageCapabilityReader”Typed, named token a package publishes and consumers resolve to exchange a capability value across packages.
Source: packages/slingshot-core/src/packageAuthoring.ts
PackageContract
Section titled “PackageContract”Typed, named token a package publishes and consumers resolve to exchange a capability value across packages.
Source: packages/slingshot-core/src/packageAuthoring.ts
PackageDomainRouteContext
Section titled “PackageDomainRouteContext”Typed, named token a package publishes and consumers resolve to exchange a capability value across packages.
Source: packages/slingshot-core/src/packageAuthoring.ts
PackageEntityModule
Section titled “PackageEntityModule”Use the framework’s default adapter resolution for the entity.
Source: packages/slingshot-entity/src/packageAuthoring.ts
PackageEntityReader
Section titled “PackageEntityReader”Typed, named token a package publishes and consumers resolve to exchange a capability value across packages.
Source: packages/slingshot-core/src/packageAuthoring.ts
PackageEntityRef
Section titled “PackageEntityRef”Typed, named token a package publishes and consumers resolve to exchange a capability value across packages.
Source: packages/slingshot-core/src/packageAuthoring.ts
PackageInspection
Section titled “PackageInspection”Typed, named token a package publishes and consumers resolve to exchange a capability value across packages.
Source: packages/slingshot-core/src/packageAuthoring.ts
PackageRouteRequestContext
Section titled “PackageRouteRequestContext”Typed, named token a package publishes and consumers resolve to exchange a capability value across packages.
Source: packages/slingshot-core/src/packageAuthoring.ts
PaginationConfig
Section titled “PaginationConfig”Config-driven entity & repository generation.
Plugin authors describe an entity’s shape declaratively using the field.*() builder
API, then get generated TypeScript types, Zod schemas, adapter interfaces, and
backend-specific implementations from a single source of truth.
import { defineEntity, field, index } from '@lastshotlabs/slingshot-core';
export const Message = defineEntity('Message', {namespace: 'chat',fields: {id: field.string({ primary: true, default: 'uuid' }),roomId: field.string(),authorId: field.string(),content: field.string(),type: field.enum(['text', 'image', 'system'], { default: 'text' }),metadata: field.json({ optional: true }),createdAt: field.date({ default: 'now' }),updatedAt: field.date({ default: 'now', onUpdate: 'now' }),},softDelete: { field: 'status', value: 'deleted' },defaultSort: { field: 'createdAt', direction: 'desc' },pagination: { cursor: { fields: ['createdAt', 'id'] }, defaultLimit: 50, maxLimit: 200 },indexes: [index(['roomId', 'createdAt'], { direction: 'desc' }),index(['authorId', 'createdAt'], { direction: 'desc' }),],});Source: packages/slingshot-core/src/entityConfig.ts
ParsedCursorParams
Section titled “ParsedCursorParams”Default values for cursor-based pagination query parameters.
Source: src/framework/lib/pagination.ts
ParsedOffsetParams
Section titled “ParsedOffsetParams”Default overrides for offset-based pagination query parameters. All fields are optional — omitted fields fall back to framework defaults (limit=50, offset=0, maxLimit=200).
Source: packages/slingshot-core/src/pagination.ts
PermissionsConfig
Section titled “PermissionsConfig”Server-level permissions configuration.
When set, the framework bootstraps a shared PermissionsAdapter,
PermissionRegistry, and PermissionEvaluator from the existing infra
connection and writes them to ctx.pluginState at PERMISSIONS_STATE_KEY
before any plugin setup phase runs.
Plugins that accept permissions in their own config remain backward
compatible - an explicit plugin-level config takes precedence over the
server-level bootstrap.
Requires @lastshotlabs/slingshot-permissions to be installed. A clear
error is thrown at startup if the package is missing.
Source: src/config/types/permissions.ts
PresignedUrlConfig
Section titled “PresignedUrlConfig”Source: src/config/types/upload.ts
ProductionReadinessAuditOptions
Section titled “ProductionReadinessAuditOptions”Source: src/prodReadiness.ts
ProductionReadinessFinding
Section titled “ProductionReadinessFinding”Source: src/prodReadiness.ts
ProductionReadinessReport
Section titled “ProductionReadinessReport”Source: src/prodReadiness.ts
PublishedPackageCapability
Section titled “PublishedPackageCapability”Typed, named token a package publishes and consumers resolve to exchange a capability value across packages.
Source: packages/slingshot-core/src/packageAuthoring.ts
PublishOptions
Section titled “PublishOptions”Source: src/framework/ws/rooms.ts
RateLimitOptions
Section titled “RateLimitOptions”Source: src/framework/middleware/rateLimit.ts
RedisCredentials
Section titled “RedisCredentials”Source: src/lib/redis.ts
RedisTransportOptions
Section titled “RedisTransportOptions”Source: src/framework/ws/redisTransport.ts
RelationDef
Section titled “RelationDef”Config-driven entity & repository generation.
Plugin authors describe an entity’s shape declaratively using the field.*() builder
API, then get generated TypeScript types, Zod schemas, adapter interfaces, and
backend-specific implementations from a single source of truth.
import { defineEntity, field, index } from '@lastshotlabs/slingshot-core';
export const Message = defineEntity('Message', {namespace: 'chat',fields: {id: field.string({ primary: true, default: 'uuid' }),roomId: field.string(),authorId: field.string(),content: field.string(),type: field.enum(['text', 'image', 'system'], { default: 'text' }),metadata: field.json({ optional: true }),createdAt: field.date({ default: 'now' }),updatedAt: field.date({ default: 'now', onUpdate: 'now' }),},softDelete: { field: 'status', value: 'deleted' },defaultSort: { field: 'createdAt', direction: 'desc' },pagination: { cursor: { fields: ['createdAt', 'id'] }, defaultLimit: 50, maxLimit: 200 },indexes: [index(['roomId', 'createdAt'], { direction: 'desc' }),index(['authorId', 'createdAt'], { direction: 'desc' }),],});Source: packages/slingshot-core/src/entityConfig.ts
RequestLogEntry
Section titled “RequestLogEntry”Severity level for a structured request log entry.
"info"— successful responses (status < 400)."warn"— client-error responses (status 400–499)."error"— server-error responses (status >= 500) or unhandled exceptions.
Source: src/framework/middleware/requestLogger.ts
RequestLoggerOptions
Section titled “RequestLoggerOptions”Source: src/framework/middleware/requestLogger.ts
RequestSigningOptions
Section titled “RequestSigningOptions”Source: src/framework/middleware/requestSigning.ts
ResolvedEntityConfig
Section titled “ResolvedEntityConfig”Config-driven entity & repository generation.
Plugin authors describe an entity’s shape declaratively using the field.*() builder
API, then get generated TypeScript types, Zod schemas, adapter interfaces, and
backend-specific implementations from a single source of truth.
import { defineEntity, field, index } from '@lastshotlabs/slingshot-core';
export const Message = defineEntity('Message', {namespace: 'chat',fields: {id: field.string({ primary: true, default: 'uuid' }),roomId: field.string(),authorId: field.string(),content: field.string(),type: field.enum(['text', 'image', 'system'], { default: 'text' }),metadata: field.json({ optional: true }),createdAt: field.date({ default: 'now' }),updatedAt: field.date({ default: 'now', onUpdate: 'now' }),},softDelete: { field: 'status', value: 'deleted' },defaultSort: { field: 'createdAt', direction: 'desc' },pagination: { cursor: { fields: ['createdAt', 'id'] }, defaultLimit: 50, maxLimit: 200 },indexes: [index(['roomId', 'createdAt'], { direction: 'desc' }),index(['authorId', 'createdAt'], { direction: 'desc' }),],});Source: packages/slingshot-core/src/entityConfig.ts
ResolvedOperations
Section titled “ResolvedOperations”Operation configuration types — canonical definitions.
12 declarative operation patterns + 1 custom escape hatch.
Both the codegen package (slingshot-data) and the runtime framework import from here.
Single source of truth — never duplicate these types in consumer packages.
Remarks: Operation configs are consumed by: - slingshot-data code generators to produce typed adapter implementations - The runtime framework’s op.* executor registry for live evaluation - InferOperationMethods<Ops, Entity> for TypeScript adapter method typing
Source: packages/slingshot-core/src/operations.ts
ResolvedPersistence
Section titled “ResolvedPersistence”Resolved persistence repositories for the application instance.
Created by resolveFrameworkPersistence() during server bootstrap and wired into
SlingshotContext by createApp(). All repositories are instance-scoped — no
shared module-level state across app instances.
Remarks: Access these repositories via ctx.persistence.* in plugin setupPost hooks and in framework middleware. Never access them before createApp() completes.
Source: packages/slingshot-core/src/context/slingshotContext.ts
S3StorageConfig
Section titled “S3StorageConfig”Configuration for the S3-compatible storage adapter.
Compatible with AWS S3, Cloudflare R2, MinIO, and any S3-compatible endpoint.
Source: src/framework/adapters/s3Storage.ts
SecurityConfig
Section titled “SecurityConfig”Source: src/config/types/security.ts
SlingshotAdminPluginConfig
Section titled “SlingshotAdminPluginConfig”Configuration for the Slingshot-integrated admin plugin.
Extends AdminPluginConfig with optional overrides for accessProvider,
managedUserProvider, and permissions. When these are omitted, sensible
framework defaults are resolved automatically:
accessProviderdefaults tocreateSlingshotAuthAccessProvider, which reads permissions from the auth runtime context.managedUserProviderdefaults tocreateSlingshotManagedUserProvider, constructed from the auth runtime adapter, config, and session repository.permissionsdefaults to the value stored underPERMISSIONS_STATE_KEYinctx.pluginState— set by the community plugin or another permissions source during itssetupRoutesphase.
All three are required at route-registration time. If permissions is not provided
and no plugin has populated PERMISSIONS_STATE_KEY, setupPost throws.
Source: src/framework/admin/index.ts
SlingshotContext
Section titled “SlingshotContext”Resolved persistence repositories for the application instance.
Created by resolveFrameworkPersistence() during server bootstrap and wired into
SlingshotContext by createApp(). All repositories are instance-scoped — no
shared module-level state across app instances.
Remarks: Access these repositories via ctx.persistence.* in plugin setupPost hooks and in framework middleware. Never access them before createApp() completes.
Source: packages/slingshot-core/src/context/slingshotContext.ts
SlingshotEventBus
Section titled “SlingshotEventBus”Narrow, untyped view of the event bus for string-keyed subscriptions.
Plugins that subscribe to dynamically named events (e.g. entity:${storageName}.created)
cast the typed SlingshotEventBus to this interface rather than widening the global
SlingshotEventMap. This keeps type widening local per rule 12.
Defined here once so every consumer imports the same shape (rule 6). Use Pick to
narrow further when a module only needs emit or only needs on/off.
Source: packages/slingshot-core/src/eventBus.ts
SlingshotEventMap
Section titled “SlingshotEventMap”Central event map for all built-in Slingshot events.
Typed key to payload pairs consumed by SlingshotEventBus. Plugin packages
extend this map via TypeScript module augmentation in their own events.ts
file, never by modifying this interface directly.
Source: packages/slingshot-core/src/eventMap.ts
SlingshotPackageDefinition
Section titled “SlingshotPackageDefinition”Typed, named token a package publishes and consumers resolve to exchange a capability value across packages.
Source: packages/slingshot-core/src/packageAuthoring.ts
SlingshotPlugin
Section titled “SlingshotPlugin”Context object passed to all plugin lifecycle methods.
Using an options object instead of positional parameters means adding a new field in the future is non-breaking — plugins that don’t need the new field simply don’t destructure it.
Source: packages/slingshot-core/src/plugin.ts
SlingshotResolvedConfig
Section titled “SlingshotResolvedConfig”Resolved persistence repositories for the application instance.
Created by resolveFrameworkPersistence() during server bootstrap and wired into
SlingshotContext by createApp(). All repositories are instance-scoped — no
shared module-level state across app instances.
Remarks: Access these repositories via ctx.persistence.* in plugin setupPost hooks and in framework middleware. Never access them before createApp() completes.
Source: packages/slingshot-core/src/context/slingshotContext.ts
SseConfig
Section titled “SseConfig”Source: src/config/types/sse.ts
SseEndpointConfig
Section titled “SseEndpointConfig”Data attached to each active SSE connection.
The generic parameter T allows endpoint-specific metadata to be added at
upgrade time (e.g., subscription filters). The base fields (id, actor,
requestTenantId, endpoint) are always present.
Source: packages/slingshot-core/src/sse.ts
StandalonePlugin
Section titled “StandalonePlugin”Context object passed to all plugin lifecycle methods.
Using an options object instead of positional parameters means adding a new field in the future is non-breaking — plugins that don’t need the new field simply don’t destructure it.
Source: packages/slingshot-core/src/plugin.ts
StorageAdapter
Section titled “StorageAdapter”Pluggable object storage adapter for the upload middleware.
Implement this interface to connect any storage backend (S3, R2, local disk, etc.) to the Slingshot upload infrastructure. Registered via the uploads plugin configuration.
Source: packages/slingshot-core/src/storageAdapter.ts
TenancyConfig
Section titled “TenancyConfig”Source: src/config/types/tenancy.ts
TenantConfig
Section titled “TenantConfig”Config-driven entity & repository generation.
Plugin authors describe an entity’s shape declaratively using the field.*() builder
API, then get generated TypeScript types, Zod schemas, adapter interfaces, and
backend-specific implementations from a single source of truth.
import { defineEntity, field, index } from '@lastshotlabs/slingshot-core';
export const Message = defineEntity('Message', {namespace: 'chat',fields: {id: field.string({ primary: true, default: 'uuid' }),roomId: field.string(),authorId: field.string(),content: field.string(),type: field.enum(['text', 'image', 'system'], { default: 'text' }),metadata: field.json({ optional: true }),createdAt: field.date({ default: 'now' }),updatedAt: field.date({ default: 'now', onUpdate: 'now' }),},softDelete: { field: 'status', value: 'deleted' },defaultSort: { field: 'createdAt', direction: 'desc' },pagination: { cursor: { fields: ['createdAt', 'id'] }, defaultLimit: 50, maxLimit: 200 },indexes: [index(['roomId', 'createdAt'], { direction: 'desc' }),index(['authorId', 'createdAt'], { direction: 'desc' }),],});Source: packages/slingshot-core/src/entityConfig.ts
TenantInfo
Section titled “TenantInfo”Read-only representation of a tenant record.
Source: src/framework/tenancy/service.ts
TenantService
Section titled “TenantService”Read-only representation of a tenant record.
Source: src/framework/tenancy/service.ts
TracingConfig
Section titled “TracingConfig”Configuration for distributed tracing via OpenTelemetry.
Slingshot instruments bootstrap phases, request lifecycles, and plugin
lifecycle calls with OTel spans. The framework depends on
@opentelemetry/api only — install an OTel SDK and exporter in your app
to collect spans.
When enabled is false or omitted, no tracer is created and no spans are
recorded. The OTel API returns no-op implementations in that case, so there
is zero runtime overhead.
Source: src/config/types/observability.ts
TypedRouteContext
Section titled “TypedRouteContext”Typed, named token a package publishes and consumers resolve to exchange a capability value across packages.
Source: packages/slingshot-core/src/packageAuthoring.ts
TypedRouteRequestSpec
Section titled “TypedRouteRequestSpec”Typed, named token a package publishes and consumers resolve to exchange a capability value across packages.
Source: packages/slingshot-core/src/packageAuthoring.ts
TypedRouteResponseSpec
Section titled “TypedRouteResponseSpec”Typed, named token a package publishes and consumers resolve to exchange a capability value across packages.
Source: packages/slingshot-core/src/packageAuthoring.ts
UploadConfig
Section titled “UploadConfig”Source: src/config/types/upload.ts
UploadOpts
Section titled “UploadOpts”Options for configuring file upload parsing and storage.
Source: src/framework/upload/upload.ts
UploadRecord
Section titled “UploadRecord”Metadata record stored when a file is uploaded via the framework upload middleware.
Used to verify ownership and tenancy when users request presigned download URLs
or initiate delete operations. Stored in the UploadRegistryRepository.
Source: packages/slingshot-core/src/uploadRegistry.ts
UploadRegistryRepository
Section titled “UploadRegistryRepository”Metadata record stored when a file is uploaded via the framework upload middleware.
Used to verify ownership and tenancy when users request presigned download URLs
or initiate delete operations. Stored in the UploadRegistryRepository.
Source: packages/slingshot-core/src/uploadRegistry.ts
UploadResult
Section titled “UploadResult”Pluggable object storage adapter for the upload middleware.
Implement this interface to connect any storage backend (S3, R2, local disk, etc.) to the Slingshot upload infrastructure. Registered via the uploads plugin configuration.
Source: packages/slingshot-core/src/storageAdapter.ts
ValidationConfig
Section titled “ValidationConfig”Source: src/config/types/validation.ts
ValidationErrorDetail
Section titled “ValidationErrorDetail”A single field-level validation error detail produced by the default formatter.
Source: packages/slingshot-core/src/context.ts
VersioningConfig
Section titled “VersioningConfig”Source: src/config/types/versioning.ts
WebhookAuthOptions
Section titled “WebhookAuthOptions”Source: src/framework/middleware/webhookAuth.ts
WebhookTimestampOptions
Section titled “WebhookTimestampOptions”Source: src/framework/middleware/webhookAuth.ts
WsConfig
Section titled “WsConfig”Source: src/config/types/ws.ts
WsEventContext
Section titled “WsEventContext”Authentication level required for a WebSocket event or endpoint.
'userAuth'— requires an authenticated user session.'bearer'— requires a valid bearer token.'none'— no authentication required.
Source: src/config/types/ws.ts
WsIncomingEventConfig
Section titled “WsIncomingEventConfig”Source: src/config/types/ws.ts
WsMessageRepository
Section titled “WsMessageRepository”A single WebSocket message that has been persisted to the backing store. Includes a unique ID and a creation timestamp for history and cursor pagination.
Source: packages/slingshot-core/src/wsMessages.ts
WsState
Section titled “WsState”Resolved persistence repositories for the application instance.
Created by resolveFrameworkPersistence() during server bootstrap and wired into
SlingshotContext by createApp(). All repositories are instance-scoped — no
shared module-level state across app instances.
Remarks: Access these repositories via ctx.persistence.* in plugin setupPost hooks and in framework middleware. Never access them before createApp() completes.
Source: packages/slingshot-core/src/context/slingshotContext.ts
WsTransportAdapter
Section titled “WsTransportAdapter”Pluggable transport for cross-instance WebSocket message delivery.
publish() is called on every room broadcast — the transport fans out
the message to other server instances (e.g. via Redis pub/sub).
connect() is called once at server startup. The onMessage callback
should be invoked when a message arrives from another instance —
it will be delivered to local sockets via Bun’s native server.publish().
disconnect() is called on graceful shutdown.
Source: src/framework/ws/transport.ts
WsTransportHandle
Section titled “WsTransportHandle”Resolved persistence repositories for the application instance.
Created by resolveFrameworkPersistence() during server bootstrap and wired into
SlingshotContext by createApp(). All repositories are instance-scoped — no
shared module-level state across app instances.
Remarks: Access these repositories via ctx.persistence.* in plugin setupPost hooks and in framework middleware. Never access them before createApp() completes.
Source: packages/slingshot-core/src/context/slingshotContext.ts
AccountDeletionConfig
Section titled “AccountDeletionConfig”Source: src/app.ts
AppConfig
Section titled “AppConfig”Canonical declarative app config shape.
Alias of CreateServerConfig surfaced under a friendlier name. Users
author this in app.config.ts and the framework boots from the default
export.
Source: src/defineApp.ts
AppEnv
Section titled “AppEnv”A single field-level validation error detail produced by the default formatter.
Source: packages/slingshot-core/src/context.ts
AppVariables
Section titled “AppVariables”A single field-level validation error detail produced by the default formatter.
Source: packages/slingshot-core/src/context.ts
AuthConfig
Section titled “AuthConfig”Source: src/app.ts
AuthPluginConfig
Section titled “AuthPluginConfig”Database/store connection configuration for slingshot-auth.
Controls which persistence backends are used for sessions, OAuth state, and the user auth adapter. Each field is optional — defaults are chosen by the bootstrap layer based on what is available (Redis → SQLite → memory).
Remarks: When running under the full framework (createApp / createServer), connection objects are provided automatically via SlingshotFrameworkConfig. These fields are only relevant in standalone mode or when explicitly overriding framework-provided connections.
Source: packages/slingshot-auth/src/types/config.ts
AuthRateLimitConfig
Section titled “AuthRateLimitConfig”Source: src/app.ts
BreachedPasswordConfig
Section titled “BreachedPasswordConfig”Source: src/app.ts
CaptchaProvider
Section titled “CaptchaProvider”Supported CAPTCHA verification providers.
'recaptcha'— Google reCAPTCHA v2 or v3'hcaptcha'— hCaptcha'turnstile'— Cloudflare Turnstile
Source: packages/slingshot-core/src/captcha.ts
CsrfConfig
Section titled “CsrfConfig”Source: src/app.ts
DtoMapperConfig
Section titled “DtoMapperConfig”Source: src/framework/lib/createDtoMapper.ts
EmailVerificationConfig
Section titled “EmailVerificationConfig”Source: src/app.ts
EntityModuleWiring
Section titled “EntityModuleWiring”Use the framework’s default adapter resolution for the entity.
Source: packages/slingshot-entity/src/packageAuthoring.ts
EntityPaginatedResult
Section titled “EntityPaginatedResult”Source: packages/slingshot-core/src/entityConfig.ts
FieldType
Section titled “FieldType”Config-driven entity & repository generation.
Plugin authors describe an entity’s shape declaratively using the field.*() builder
API, then get generated TypeScript types, Zod schemas, adapter interfaces, and
backend-specific implementations from a single source of truth.
import { defineEntity, field, index } from '@lastshotlabs/slingshot-core';
export const Message = defineEntity('Message', {namespace: 'chat',fields: {id: field.string({ primary: true, default: 'uuid' }),roomId: field.string(),authorId: field.string(),content: field.string(),type: field.enum(['text', 'image', 'system'], { default: 'text' }),metadata: field.json({ optional: true }),createdAt: field.date({ default: 'now' }),updatedAt: field.date({ default: 'now', onUpdate: 'now' }),},softDelete: { field: 'status', value: 'deleted' },defaultSort: { field: 'createdAt', direction: 'desc' },pagination: { cursor: { fields: ['createdAt', 'id'] }, defaultLimit: 50, maxLimit: 200 },indexes: [index(['roomId', 'createdAt'], { direction: 'desc' }),index(['authorId', 'createdAt'], { direction: 'desc' }),],});Source: packages/slingshot-core/src/entityConfig.ts
FrameworkSecretsLiteral
Section titled “FrameworkSecretsLiteral”Source: ./app
InferCreateInput
Section titled “InferCreateInput”Config-driven entity & repository generation.
Plugin authors describe an entity’s shape declaratively using the field.*() builder
API, then get generated TypeScript types, Zod schemas, adapter interfaces, and
backend-specific implementations from a single source of truth.
import { defineEntity, field, index } from '@lastshotlabs/slingshot-core';
export const Message = defineEntity('Message', {namespace: 'chat',fields: {id: field.string({ primary: true, default: 'uuid' }),roomId: field.string(),authorId: field.string(),content: field.string(),type: field.enum(['text', 'image', 'system'], { default: 'text' }),metadata: field.json({ optional: true }),createdAt: field.date({ default: 'now' }),updatedAt: field.date({ default: 'now', onUpdate: 'now' }),},softDelete: { field: 'status', value: 'deleted' },defaultSort: { field: 'createdAt', direction: 'desc' },pagination: { cursor: { fields: ['createdAt', 'id'] }, defaultLimit: 50, maxLimit: 200 },indexes: [index(['roomId', 'createdAt'], { direction: 'desc' }),index(['authorId', 'createdAt'], { direction: 'desc' }),],});Source: packages/slingshot-core/src/entityConfig.ts
InferEntity
Section titled “InferEntity”Config-driven entity & repository generation.
Plugin authors describe an entity’s shape declaratively using the field.*() builder
API, then get generated TypeScript types, Zod schemas, adapter interfaces, and
backend-specific implementations from a single source of truth.
import { defineEntity, field, index } from '@lastshotlabs/slingshot-core';
export const Message = defineEntity('Message', {namespace: 'chat',fields: {id: field.string({ primary: true, default: 'uuid' }),roomId: field.string(),authorId: field.string(),content: field.string(),type: field.enum(['text', 'image', 'system'], { default: 'text' }),metadata: field.json({ optional: true }),createdAt: field.date({ default: 'now' }),updatedAt: field.date({ default: 'now', onUpdate: 'now' }),},softDelete: { field: 'status', value: 'deleted' },defaultSort: { field: 'createdAt', direction: 'desc' },pagination: { cursor: { fields: ['createdAt', 'id'] }, defaultLimit: 50, maxLimit: 200 },indexes: [index(['roomId', 'createdAt'], { direction: 'desc' }),index(['authorId', 'createdAt'], { direction: 'desc' }),],});Source: packages/slingshot-core/src/entityConfig.ts
InferUpdateInput
Section titled “InferUpdateInput”Config-driven entity & repository generation.
Plugin authors describe an entity’s shape declaratively using the field.*() builder
API, then get generated TypeScript types, Zod schemas, adapter interfaces, and
backend-specific implementations from a single source of truth.
import { defineEntity, field, index } from '@lastshotlabs/slingshot-core';
export const Message = defineEntity('Message', {namespace: 'chat',fields: {id: field.string({ primary: true, default: 'uuid' }),roomId: field.string(),authorId: field.string(),content: field.string(),type: field.enum(['text', 'image', 'system'], { default: 'text' }),metadata: field.json({ optional: true }),createdAt: field.date({ default: 'now' }),updatedAt: field.date({ default: 'now', onUpdate: 'now' }),},softDelete: { field: 'status', value: 'deleted' },defaultSort: { field: 'createdAt', direction: 'desc' },pagination: { cursor: { fields: ['createdAt', 'id'] }, defaultLimit: 50, maxLimit: 200 },indexes: [index(['roomId', 'createdAt'], { direction: 'desc' }),index(['authorId', 'createdAt'], { direction: 'desc' }),],});Source: packages/slingshot-core/src/entityConfig.ts
JwtConfig
Section titled “JwtConfig”Source: src/app.ts
LogLevel
Section titled “LogLevel”Severity level for a structured request log entry.
"info"— successful responses (status < 400)."warn"— client-error responses (status 400–499)."error"— server-error responses (status >= 500) or unhandled exceptions.
Source: src/framework/middleware/requestLogger.ts
MagicLinkConfig
Section titled “MagicLinkConfig”Source: src/app.ts
MfaConfig
Section titled “MfaConfig”Source: src/app.ts
MfaEmailOtpConfig
Section titled “MfaEmailOtpConfig”Source: src/app.ts
MfaWebAuthnConfig
Section titled “MfaWebAuthnConfig”Source: src/app.ts
ModelSchemasConfig
Section titled “ModelSchemasConfig”Source: ./app
MongoCredentials
Section titled “MongoCredentials”Source: src/lib/mongo.ts
OAuthConfig
Section titled “OAuthConfig”Source: src/app.ts
OidcConfig
Section titled “OidcConfig”Source: src/app.ts
OperationConfig
Section titled “OperationConfig”Operation configuration types — canonical definitions.
12 declarative operation patterns + 1 custom escape hatch.
Both the codegen package (slingshot-data) and the runtime framework import from here.
Single source of truth — never duplicate these types in consumer packages.
Remarks: Operation configs are consumed by: - slingshot-data code generators to produce typed adapter implementations - The runtime framework’s op.* executor registry for live evaluation - InferOperationMethods<Ops, Entity> for TypeScript adapter method typing
Source: packages/slingshot-core/src/operations.ts
PackageEntityAdapterFor
Section titled “PackageEntityAdapterFor”Use the framework’s default adapter resolution for the entity.
Source: packages/slingshot-entity/src/packageAuthoring.ts
PasswordResetConfig
Section titled “PasswordResetConfig”Source: src/app.ts
PrimaryField
Section titled “PrimaryField”Source: src/app.ts
ProductionReadinessCategory
Section titled “ProductionReadinessCategory”Source: src/prodReadiness.ts
ProductionReadinessConfig
Section titled “ProductionReadinessConfig”Source: src/prodReadiness.ts
ProductionReadinessSeverity
Section titled “ProductionReadinessSeverity”Source: src/prodReadiness.ts
RefreshTokenConfig
Section titled “RefreshTokenConfig”Source: src/app.ts
SamlConfig
Section titled “SamlConfig”Source: src/app.ts
ScimConfig
Section titled “ScimConfig”Source: src/app.ts
SecretsConfig
Section titled “SecretsConfig”Source: src/config/types/secrets.ts
SecurityEventKey
Section titled “SecurityEventKey”Central event map for all built-in Slingshot events.
Typed key to payload pairs consumed by SlingshotEventBus. Plugin packages
extend this map via TypeScript module augmentation in their own events.ts
file, never by modifying this interface directly.
Source: packages/slingshot-core/src/eventMap.ts
SigningConfig
Section titled “SigningConfig”Source: src/app.ts
SocketData
Section titled “SocketData”Per-socket data attached to every WebSocket connection by the Bun server.
This type is the data object passed to all ws.* handler callbacks
(open, message, close, drain). The generic T parameter lets
plugins attach custom fields (e.g., roomId) at upgrade time. The base
fields are populated by createWsUpgradeHandler.
Source: src/framework/ws/index.ts
SoftDeleteConfig
Section titled “SoftDeleteConfig”Config-driven entity & repository generation.
Plugin authors describe an entity’s shape declaratively using the field.*() builder
API, then get generated TypeScript types, Zod schemas, adapter interfaces, and
backend-specific implementations from a single source of truth.
import { defineEntity, field, index } from '@lastshotlabs/slingshot-core';
export const Message = defineEntity('Message', {namespace: 'chat',fields: {id: field.string({ primary: true, default: 'uuid' }),roomId: field.string(),authorId: field.string(),content: field.string(),type: field.enum(['text', 'image', 'system'], { default: 'text' }),metadata: field.json({ optional: true }),createdAt: field.date({ default: 'now' }),updatedAt: field.date({ default: 'now', onUpdate: 'now' }),},softDelete: { field: 'status', value: 'deleted' },defaultSort: { field: 'createdAt', direction: 'desc' },pagination: { cursor: { fields: ['createdAt', 'id'] }, defaultLimit: 50, maxLimit: 200 },indexes: [index(['roomId', 'createdAt'], { direction: 'desc' }),index(['authorId', 'createdAt'], { direction: 'desc' }),],});Source: packages/slingshot-core/src/entityConfig.ts
SseClientData
Section titled “SseClientData”Source: src/framework/sse/index.ts
SseFilter
Section titled “SseFilter”Source: src/framework/sse/index.ts
StepUpConfig
Section titled “StepUpConfig”Source: src/app.ts
TypedRouteInput
Section titled “TypedRouteInput”Typed, named token a package publishes and consumers resolve to exchange a capability value across packages.
Source: packages/slingshot-core/src/packageAuthoring.ts
TypedRouteResponses
Section titled “TypedRouteResponses”Typed, named token a package publishes and consumers resolve to exchange a capability value across packages.
Source: packages/slingshot-core/src/packageAuthoring.ts
UploadMiddlewareOptions
Section titled “UploadMiddlewareOptions”Options for the handleUpload middleware.
All fields are optional overrides of the app-level upload configuration
stored in SlingshotContext. Values provided here take precedence over the
app-level defaults for a specific route.
See UploadOpts (from @framework/upload/upload) for available fields:
maxFileSize, maxFiles, allowedMimeTypes, keyPrefix, etc.
Source: src/framework/middleware/upload.ts
ValidationErrorFormatter
Section titled “ValidationErrorFormatter”A single field-level validation error detail produced by the default formatter.
Source: packages/slingshot-core/src/context.ts
WsAuthConfig
Section titled “WsAuthConfig”Authentication level required for a WebSocket event or endpoint.
'userAuth'— requires an authenticated user session.'bearer'— requires a valid bearer token.'none'— no authentication required.
Source: src/config/types/ws.ts
WsEventHandler
Section titled “WsEventHandler”Authentication level required for a WebSocket event or endpoint.
'userAuth'— requires an authenticated user session.'bearer'— requires a valid bearer token.'none'— no authentication required.
Source: src/config/types/ws.ts
WsMiddlewareHandler
Section titled “WsMiddlewareHandler”Authentication level required for a WebSocket event or endpoint.
'userAuth'— requires an authenticated user session.'bearer'— requires a valid bearer token.'none'— no authentication required.
Source: src/config/types/ws.ts
ZodToMongooseConfig
Section titled “ZodToMongooseConfig”Source: src/framework/lib/zodToMongoose.ts
ZodToMongooseRefConfig
Section titled “ZodToMongooseRefConfig”Source: src/framework/lib/zodToMongoose.ts
Exports
Section titled “Exports”createChildSpan
Section titled “createChildSpan”Source: ./app
createCompositeFactories
Section titled “createCompositeFactories”Multi-entity composition — combine multiple entity adapters into a single plugin adapter, optionally with operations.
Plugins typically persist several related entities together (e.g. rooms + messages).
Rather than returning multiple separate factory objects, createCompositeFactories()
merges them behind a single RepoFactories<CompositeAdapter> object. The composite
adapter exposes each entity’s adapter under its own key, plus a clear() method
that resets all entities simultaneously (useful in tests).
Source: packages/slingshot-entity/src/configDriven/composition.ts
createDtoMapper
Section titled “createDtoMapper”DB field name -> API field name for ObjectId refs (e.g., { account: “accountId” })
Source: src/framework/lib/createDtoMapper.ts
createEntityFactories
Section titled “createEntityFactories”Config-driven adapter factory generator.
Pure runtime builder for entity repo factories. This package-side version
intentionally stays free of app/framework wiring so workspace packages can
depend on it without pulling in src/framework.
Source: packages/slingshot-entity/src/configDriven/createEntityFactories.ts
defineEntity
Section titled “defineEntity”Config-driven entity & repository generation.
Plugin authors describe an entity’s shape declaratively using the field.*() builder
API, then get generated TypeScript types, Zod schemas, adapter interfaces, and
backend-specific implementations from a single source of truth.
import { defineEntity, field, index } from '@lastshotlabs/slingshot-core';
export const Message = defineEntity('Message', {namespace: 'chat',fields: {id: field.string({ primary: true, default: 'uuid' }),roomId: field.string(),authorId: field.string(),content: field.string(),type: field.enum(['text', 'image', 'system'], { default: 'text' }),metadata: field.json({ optional: true }),createdAt: field.date({ default: 'now' }),updatedAt: field.date({ default: 'now', onUpdate: 'now' }),},softDelete: { field: 'status', value: 'deleted' },defaultSort: { field: 'createdAt', direction: 'desc' },pagination: { cursor: { fields: ['createdAt', 'id'] }, defaultLimit: 50, maxLimit: 200 },indexes: [index(['roomId', 'createdAt'], { direction: 'desc' }),index(['authorId', 'createdAt'], { direction: 'desc' }),],});Source: packages/slingshot-core/src/entityConfig.ts
defineOperations
Section titled “defineOperations”Operations definition entry point — dev-time only.
Validates operation configs using Zod schema against entity field names.
Source: packages/slingshot-entity/src/defineOperations.ts
domain
Section titled “domain”Typed, named token a package publishes and consumers resolve to exchange a capability value across packages.
Source: packages/slingshot-core/src/packageAuthoring.ts