@lastshotlabs/slingshot-entity
npm install @lastshotlabs/slingshot-entity
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
auditEntity
Section titled “auditEntity”Entity audit runner — combines all audit rules.
Pure function: (entityConfig, operations?) → EntityAuditResult
function auditEntity(config: ResolvedEntityConfig, operations?: Record<string, OperationConfig>,): EntityAuditResultSource: packages/slingshot-entity/src/audits/index.ts
buildEntityReceiveHandlers
Section titled “buildEntityReceiveHandlers”applyChannelConfig — builds subscribe guards and event forwarding for config-driven WebSocket entity channels.
Two responsibilities:
- Subscribe guard: parses room names, enforces auth/permissions/middleware
- Event forwarding: wires bus events to WS room publish calls
function buildEntityReceiveHandlers(channelConfig: EntityChannelConfig, entity: ResolvedEntityConfig, getWsState: () => WsState | null, publishFn: WsPublishFn<WsState>, endpoint: string,): Record<string, ChannelIncomingEventDeclaration>Source: packages/slingshot-entity/src/channels/applyChannelConfig.ts
buildPolicyAction
Section titled “buildPolicyAction”Arguments for resolvePolicy.
function buildPolicyAction(opName: string): PolicyActionSource: packages/slingshot-entity/src/policy/resolvePolicy.ts
buildSubscribeGuard
Section titled “buildSubscribeGuard”applyChannelConfig — builds subscribe guards and event forwarding for config-driven WebSocket entity channels.
Two responsibilities:
- Subscribe guard: parses room names, enforces auth/permissions/middleware
- Event forwarding: wires bus events to WS room publish calls
function buildSubscribeGuard(channelConfigs: Map<string, EntityChannelConfig>, deps: ChannelConfigDeps,): (ws: unknown, room: string) => Promise<boolean>Source: packages/slingshot-entity/src/channels/applyChannelConfig.ts
createEntityPlugin
Section titled “createEntityPlugin”createEntityPlugin — Plugin-level orchestration for config-driven entities.
Wires entities into the Slingshot plugin lifecycle:
- setupRoutes: builds bare routes, applies config middleware, mounts onto app
- setupPost: registers permission resource types and post-route integrations
- teardown: unsubscribes cascade event handlers
Consumers wire entities via EntityPluginEntry — either with buildAdapter (manual) or with factories + entityKey (composite, zero-code). This keeps the package free of framework-internal dependencies.
function createEntityPlugin(pluginConfig: EntityPluginConfig): EntityPluginSource: packages/slingshot-entity/src/createEntityPlugin.ts
createLazyMiddleware
Section titled “createLazyMiddleware”Helper used by feature packages whose adapter- or capability-dependent middleware handlers can only be wired after lifecycle hooks run.
The returned ref starts as a pass-through next() no-op. The package
mounts middleware that forwards through ref.handler, then assigns
the real handler from setupMiddleware or setupPost once its
dependencies are resolved.
function createLazyMiddleware(): LazyMiddlewareRefSource: packages/slingshot-entity/src/lazyMiddleware.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
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
createOperationValidator
Section titled “createOperationValidator”Zod schema validation for entity and operation definitions.
These schemas validate the structural correctness of configs. Cross-field validation (e.g., “softDelete field must exist in fields”) uses Zod’s .superRefine() for clear, composable error messages.
function createOperationValidator(fieldNames: readonly string[]): voidSource: packages/slingshot-entity/src/validation.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
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
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
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
defineEntityExecutor
Section titled “defineEntityExecutor”Identifies a generated CRUD route (create/list/get/update/delete) or a named operation route (operations.${name}).
function defineEntityExecutor(builder: EntityRouteExecutorBuilder,): EntityRouteExecutorBuilder; export function defineEntityExecutor< const TRequest extends TypedRouteRequestSpec = TypedRouteRequestSpec, >(definition: EntityRouteExecutorDefinition<TRequest>): EntityRouteExecutorDefinition<TRequest>; export function defineEntityExecutor( builderOrDefinition: EntityRouteExecutorBuilder | EntityRouteExecutorDefinition, ): EntityRouteExecutorBuilder | EntityRouteExecutorDefinitionSource: packages/slingshot-entity/src/routing/entityRoutePlanning.ts
defineEntityRoute
Section titled “defineEntityRoute”Identifies a generated CRUD route (create/list/get/update/delete) or a named operation route (operations.${name}).
function defineEntityRoute< const TRequest extends TypedRouteRequestSpec = TypedRouteRequestSpec,>(route: EntityExtraRoute<TRequest>): EntityExtraRoute<TRequest>Source: packages/slingshot-entity/src/routing/entityRoutePlanning.ts
definePolicyDispatch
Section titled “definePolicyDispatch”Configuration for definePolicyDispatch.
function definePolicyDispatch<TRecord, TInput, TKey extends string = string>(config: PolicyDispatchConfig<TRecord, TInput, TKey>,): PolicyResolver<TRecord, TInput>Source: packages/slingshot-entity/src/policy/definePolicyDispatch.ts
diffEntityConfig
Section titled “diffEntityConfig”Entity config differ — pure function that compares two entity definitions and produces a MigrationPlan describing what changed.
function diffEntityConfig(previous: ResolvedEntityConfig, current: ResolvedEntityConfig,): MigrationPlanSource: packages/slingshot-entity/src/migrations/diff.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
entityConfigSchema
Section titled “entityConfigSchema”Zod schema validation for entity and operation definitions.
These schemas validate the structural correctness of configs. Cross-field validation (e.g., “softDelete field must exist in fields”) uses Zod’s .superRefine() for clear, composable error messages.
Source: packages/slingshot-entity/src/validation.ts
evaluateRouteAuth
Section titled “evaluateRouteAuth”Result of evaluating auth and permission requirements for an entity route.
async function evaluateRouteAuth(c: Context<AppEnv, string>, operationConfig: RouteOperationConfig | undefined, deps: EvaluateRouteAuthDeps,): Promise<RouteAuthResult>Source: packages/slingshot-entity/src/routing/evaluateRouteAuth.ts
field.*() builder API for entity field definitions.
Source: packages/slingshot-entity/src/builders/field.ts
freezeEntityPolicyRegistry
Section titled “freezeEntityPolicyRegistry”Register a policy resolver under a named key. Consumers call this from
their plugin’s setupMiddleware phase, before any slingshot-entity
setupRoutes runs for entities that reference the key.
Two call shapes are supported:
registerEntityPolicy(app, key, resolver)— legacy, key passed as a stringregisterEntityPolicy(app, token)— typed token fromdefinePolicy(...)
Registration after the registry has been frozen (which happens at the
end of slingshot-entity.setupRoutes) throws. This prevents late
registration from silently affecting requests in flight.
function freezeEntityPolicyRegistry(app: Hono<AppEnv>): voidSource: packages/slingshot-entity/src/policy/registerEntityPolicy.ts
generate
Section titled “generate”Pure code generation function.
Takes entity definitions + optional operations → returns Record<string, string> where keys are filenames and values are file contents.
No side effects. No disk I/O. Fully testable.
function generate(config: ResolvedEntityConfig, options?: GenerateOptions,): Record<string, string>Source: packages/slingshot-entity/src/generate.ts
generateInitialMigrationMongo
Section titled “generateInitialMigrationMongo”Initial-migration generator for MongoDB.
Mongo is schemaless, so there is no CREATE TABLE analog — collections are
created lazily on first insert. The “initial” migration for an entity is
therefore just the index and unique-constraint creation.
Output is a mongosh-style script with db.getCollection(...).createIndex(...)
calls. When run by slingshot migrate apply, statements are auto-awaited
inside an async IIFE.
function generateInitialMigrationMongo(config: ResolvedEntityConfig): stringSource: packages/slingshot-entity/src/migrations/generators/initialMongo.ts
generateInitialMigrationPostgres
Section titled “generateInitialMigrationPostgres”Initial-migration generators — emit CREATE TABLE + index DDL for an entity
that has no prior snapshot.
The diff-based generators (generateMigrationPostgres, generateMigrationSqlite)
only emit ALTER TABLE, which is correct for evolution but fails on a fresh
database. A “Prisma-style” workflow needs the full create statement on first
migration so the migration files capture the entire schema state.
Output is deterministic and uses the same section markers as the diff generators so users can edit individual sections without losing them on regeneration.
function generateInitialMigrationPostgres(config: ResolvedEntityConfig): stringSource: packages/slingshot-entity/src/migrations/generators/initial.ts
generateInitialMigrationSqlite
Section titled “generateInitialMigrationSqlite”Initial-migration generators — emit CREATE TABLE + index DDL for an entity
that has no prior snapshot.
The diff-based generators (generateMigrationPostgres, generateMigrationSqlite)
only emit ALTER TABLE, which is correct for evolution but fails on a fresh
database. A “Prisma-style” workflow needs the full create statement on first
migration so the migration files capture the entire schema state.
Output is deterministic and uses the same section markers as the diff generators so users can edit individual sections without losing them on regeneration.
function generateInitialMigrationSqlite(config: ResolvedEntityConfig): stringSource: packages/slingshot-entity/src/migrations/generators/initial.ts
generateMigrationMongo
Section titled “generateMigrationMongo”MongoDB migration generator — MigrationPlan → mongosh-runnable script.
Mongo is schemaless, so field additions are no-ops at the schema level.
Field removals use $unset updateMany. Index changes use createIndex /
dropIndex.
Collection and field names are never inlined as raw identifiers — they go
through db.getCollection("...") and bracket notation so hyphens, dots,
and reserved characters don’t break the generated JavaScript. Output is
deterministic (no timestamps); section markers (CLAUDE.md rule 13) let
users override specific sections without replacing the whole file.
function generateMigrationMongo(plan: MigrationPlan): stringSource: packages/slingshot-entity/src/migrations/generators/mongo.ts
generateMigrationPostgres
Section titled “generateMigrationPostgres”PostgreSQL migration generator — MigrationPlan → SQL statements.
Output is deterministic (no timestamps) so re-running slingshot generate --migration with the same inputs produces byte-identical files. Section
markers delimit each logical block so users can override specific sections
without replacing the whole file (CLAUDE.md rule 13).
function generateMigrationPostgres(plan: MigrationPlan): stringSource: packages/slingshot-entity/src/migrations/generators/postgres.ts
generateMigrations
Section titled “generateMigrations”Schema migrations — diff entity definitions and generate per-backend migration scripts.
function generateMigrations(previous: ResolvedEntityConfig, current: ResolvedEntityConfig, backends?: Backend[],): Record<string, string>Source: packages/slingshot-entity/src/migrations/index.ts
generateMigrationSqlite
Section titled “generateMigrationSqlite”SQLite migration generator — MigrationPlan → SQL statements.
Output is deterministic (no timestamps) so re-running slingshot generate --migration with the same inputs produces byte-identical files. Section
markers delimit each logical block so users can override specific sections
without replacing the whole file (CLAUDE.md rule 13).
function generateMigrationSqlite(plan: MigrationPlan): stringSource: packages/slingshot-entity/src/migrations/generators/sqlite.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
getEntityPluginToolingMetadata
Section titled “getEntityPluginToolingMetadata”createEntityPlugin — Plugin-level orchestration for config-driven entities.
Wires entities into the Slingshot plugin lifecycle:
- setupRoutes: builds bare routes, applies config middleware, mounts onto app
- setupPost: registers permission resource types and post-route integrations
- teardown: unsubscribes cascade event handlers
Consumers wire entities via EntityPluginEntry — either with buildAdapter (manual) or with factories + entityKey (composite, zero-code). This keeps the package free of framework-internal dependencies.
function getEntityPluginToolingMetadata(plugin: unknown,): EntityPluginToolingMetadata | nullSource: packages/slingshot-entity/src/createEntityPlugin.ts
getEntityPolicyResolver
Section titled “getEntityPolicyResolver”Register a policy resolver under a named key. Consumers call this from
their plugin’s setupMiddleware phase, before any slingshot-entity
setupRoutes runs for entities that reference the key.
Two call shapes are supported:
registerEntityPolicy(app, key, resolver)— legacy, key passed as a stringregisterEntityPolicy(app, token)— typed token fromdefinePolicy(...)
Registration after the registry has been frozen (which happens at the
end of slingshot-entity.setupRoutes) throws. This prevents late
registration from silently affecting requests in flight.
function getEntityPolicyResolver(app: Hono<AppEnv>, key: string,): PolicyResolver | undefinedSource: packages/slingshot-entity/src/policy/registerEntityPolicy.ts
index() and relation builders for entity definitions.
function index(fields: string[], opts?: { direction?: 'asc' | 'desc'; unique?: boolean },): IndexDefSource: packages/slingshot-entity/src/builders/entityHelpers.ts
loadSnapshot
Section titled “loadSnapshot”Snapshot store — read/write entity definition snapshots for diffing.
Snapshots are stored as JSON files in a configurable directory (default: .slingshot/snapshots/).
function loadSnapshot(snapshotDir: string, config: ResolvedEntityConfig,): EntitySnapshot | nullSource: packages/slingshot-entity/src/migrations/snapshotStore.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
normalizeEntityRouteShape
Section titled “normalizeEntityRouteShape”Identifies a generated CRUD route (create/list/get/update/delete) or a named operation route (operations.${name}).
function normalizeEntityRouteShape(path: string): stringSource: packages/slingshot-entity/src/routing/entityRoutePlanning.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
planEntityRoutes
Section titled “planEntityRoutes”Identifies a generated CRUD route (create/list/get/update/delete) or a named operation route (operations.${name}).
function planEntityRoutes(entity: ResolvedEntityConfig, operations: Record<string, OperationConfig> | undefined, options?: { routePath?: string; parentPath?: string; extraRoutes?: readonly EntityExtraRoute[]; overrides?: EntityRouteExecutorOverrides; },): PlannedEntityRoute[]Source: packages/slingshot-entity/src/routing/entityRoutePlanning.ts
policyAppliesToOp
Section titled “policyAppliesToOp”Arguments for resolvePolicy.
function policyAppliesToOp(config: EntityRoutePolicyConfig, opName: string): booleanSource: packages/slingshot-entity/src/policy/resolvePolicy.ts
publishEntityAdaptersState
Section titled “publishEntityAdaptersState”Writable plugin state used internally by the framework bootstrap lifecycle.
function publishEntityAdaptersState<TAdapter extends object>(pluginState: PluginStateMap, pluginName: string, entityAdapters: Record<string, TAdapter>,): Readonly<EntityAdaptersPluginState<TAdapter> & Record<string, unknown>>Source: packages/slingshot-core/src/pluginState.ts
registerEntityPolicy
Section titled “registerEntityPolicy”Register a policy resolver under a named key. Consumers call this from
their plugin’s setupMiddleware phase, before any slingshot-entity
setupRoutes runs for entities that reference the key.
Two call shapes are supported:
registerEntityPolicy(app, key, resolver)— legacy, key passed as a stringregisterEntityPolicy(app, token)— typed token fromdefinePolicy(...)
Registration after the registry has been frozen (which happens at the
end of slingshot-entity.setupRoutes) throws. This prevents late
registration from silently affecting requests in flight.
function registerEntityPolicy<TRecord = unknown, TInput = unknown>(app: Hono<AppEnv>, token: PolicyToken<TRecord, TInput>,): void; export function registerEntityPolicy<TRecord = unknown, TInput = unknown>( app: Hono<AppEnv>, key: string, resolver: PolicyResolver<TRecord, TInput>, ): void; export function registerEntityPolicy( app: Hono<AppEnv>, keyOrToken: string | PolicyToken<unknown, unknown>, maybeResolver?: PolicyResolver<unknown, unknown>, ): voidSource: packages/slingshot-entity/src/policy/registerEntityPolicy.ts
relation
Section titled “relation”index() and relation builders for entity definitions.
Source: packages/slingshot-entity/src/builders/entityHelpers.ts
requireEntityAdapter
Section titled “requireEntityAdapter”Writable plugin state used internally by the framework bootstrap lifecycle.
function requireEntityAdapter<TAdapter extends object = object>(input: PluginStateMap | PluginStateCarrier | object | null | undefined, lookup: EntityAdapterLookupInput<TAdapter>,): TAdapterSource: packages/slingshot-core/src/pluginState.ts
resolvePolicy
Section titled “resolvePolicy”Arguments for resolvePolicy.
async function resolvePolicy<TRecord, TInput>(args: ResolvePolicyArgs<TRecord, TInput>,): Promise<void>Source: packages/slingshot-entity/src/policy/resolvePolicy.ts
safeReadJsonBody
Section titled “safeReadJsonBody”Read the parsed JSON body from a Hono context without consuming the
body stream. Relies on Hono’s built-in body caching — c.req.json()
parses on first call and stores the result; subsequent calls return
the cached value.
Returns null on:
- non-JSON content type
- empty body (GET/DELETE)
- malformed JSON (resolver receives
nullinput; it may deny)
Never throws — policy evaluation must never 500 on a client body issue.
async function safeReadJsonBody(c: Context): Promise<Record<string, unknown> | null>Source: packages/slingshot-entity/src/policy/safeReadJsonBody.ts
saveSnapshot
Section titled “saveSnapshot”Snapshot store — read/write entity definition snapshots for diffing.
Snapshots are stored as JSON files in a configurable directory (default: .slingshot/snapshots/).
function saveSnapshot(snapshotDir: string, config: ResolvedEntityConfig): voidSource: packages/slingshot-entity/src/migrations/snapshotStore.ts
scoreEntityRouteSpecificity
Section titled “scoreEntityRouteSpecificity”Identifies a generated CRUD route (create/list/get/update/delete) or a named operation route (operations.${name}).
function scoreEntityRouteSpecificity(path: string): numberSource: packages/slingshot-entity/src/routing/entityRoutePlanning.ts
storageName
Section titled “storageName”Shared naming helpers used by all generators.
Pure, stateless utility functions for converting entity field names and configs into backend-specific representations. Used by every code generator in this package — do not add generator-specific logic here.
function storageName(config: ResolvedEntityConfig, backend: 'sqlite' | 'postgres' | 'mongo' | 'redis',): stringSource: packages/slingshot-entity/src/lib/naming.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
validateEntityConfig
Section titled “validateEntityConfig”Zod schema validation for entity and operation definitions.
These schemas validate the structural correctness of configs. Cross-field validation (e.g., “softDelete field must exist in fields”) uses Zod’s .superRefine() for clear, composable error messages.
function validateEntityConfig(config: unknown): ValidationResultSource: packages/slingshot-entity/src/validation.ts
validateOperations
Section titled “validateOperations”Zod schema validation for entity and operation definitions.
These schemas validate the structural correctness of configs. Cross-field validation (e.g., “softDelete field must exist in fields”) uses Zod’s .superRefine() for clear, composable error messages.
function validateOperations(operations: unknown, fieldNames: readonly string[],): ValidationResultSource: packages/slingshot-entity/src/validation.ts
wireChannelForwarding
Section titled “wireChannelForwarding”applyChannelConfig — builds subscribe guards and event forwarding for config-driven WebSocket entity channels.
Two responsibilities:
- Subscribe guard: parses room names, enforces auth/permissions/middleware
- Event forwarding: wires bus events to WS room publish calls
function wireChannelForwarding(channelConfig: EntityChannelConfig, entity: ResolvedEntityConfig, getWsState: () => WsState | null, bus: SlingshotEventBus, endpoint: string, publishFn: WsPublishFn<WsState>,): () => voidSource: packages/slingshot-entity/src/channels/applyChannelConfig.ts
writeGenerated
Section titled “writeGenerated”CLI wrapper — calls generate(), handles snapshot lifecycle, writes files to disk.
Usage: slingshot-data generate —definition ./src/entities/message.ts —outdir ./src/generated/message
Or programmatically: import { writeGenerated } from ‘@lastshotlabs/slingshot-entity’; writeGenerated(messageConfig, { outDir: ’./src/generated/message’ });
function writeGenerated(config: ResolvedEntityConfig, options: WriteOptions,): Record<string, string>Source: packages/slingshot-entity/src/cli.ts
Interfaces
Section titled “Interfaces”AggregateOpConfig
Section titled “AggregateOpConfig”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
BatchOpConfig
Section titled “BatchOpConfig”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
ChannelConfigDeps
Section titled “ChannelConfigDeps”applyChannelConfig — builds subscribe guards and event forwarding for config-driven WebSocket entity channels.
Two responsibilities:
- Subscribe guard: parses room names, enforces auth/permissions/middleware
- Event forwarding: wires bus events to WS room publish calls
Source: packages/slingshot-entity/src/channels/applyChannelConfig.ts
CollectionOpConfig
Section titled “CollectionOpConfig”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
ComputedAggregateOpConfig
Section titled “ComputedAggregateOpConfig”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
ComputedField
Section titled “ComputedField”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
ConsumeOpConfig
Section titled “ConsumeOpConfig”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
CustomOpConfig
Section titled “CustomOpConfig”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
DeriveOpConfig
Section titled “DeriveOpConfig”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
DeriveSource
Section titled “DeriveSource”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
EntityAdapterLookup
Section titled “EntityAdapterLookup”Instance-scoped map of plugin name -> plugin-owned state.
Each plugin stores its runtime state under its own plugin name key. Values are opaque to the framework; plugins own their state shape and expose typed accessors for dependent plugins.
Source: packages/slingshot-core/src/pluginStateTypes.ts
EntityAuditFinding
Section titled “EntityAuditFinding”Entity audit types — findings produced by audit rules.
Source: packages/slingshot-entity/src/audits/types.ts
EntityAuditResult
Section titled “EntityAuditResult”Entity audit types — findings produced by audit rules.
Source: packages/slingshot-entity/src/audits/types.ts
EntityConfig
Section titled “EntityConfig”Entity configuration types.
Source: packages/slingshot-entity/src/types/entity.ts
EntityExtraRoute
Section titled “EntityExtraRoute”Identifies a generated CRUD route (create/list/get/update/delete) or a named operation route (operations.${name}).
Source: packages/slingshot-entity/src/routing/entityRoutePlanning.ts
EntityPlugin
Section titled “EntityPlugin”createEntityPlugin — Plugin-level orchestration for config-driven entities.
Wires entities into the Slingshot plugin lifecycle:
- setupRoutes: builds bare routes, applies config middleware, mounts onto app
- setupPost: registers permission resource types and post-route integrations
- teardown: unsubscribes cascade event handlers
Consumers wire entities via EntityPluginEntry — either with buildAdapter (manual) or with factories + entityKey (composite, zero-code). This keeps the package free of framework-internal dependencies.
Source: packages/slingshot-entity/src/createEntityPlugin.ts
EntityPluginConfig
Section titled “EntityPluginConfig”createEntityPlugin — Plugin-level orchestration for config-driven entities.
Wires entities into the Slingshot plugin lifecycle:
- setupRoutes: builds bare routes, applies config middleware, mounts onto app
- setupPost: registers permission resource types and post-route integrations
- teardown: unsubscribes cascade event handlers
Consumers wire entities via EntityPluginEntry — either with buildAdapter (manual) or with factories + entityKey (composite, zero-code). This keeps the package free of framework-internal dependencies.
Source: packages/slingshot-entity/src/createEntityPlugin.ts
EntityPluginContext
Section titled “EntityPluginContext”createEntityPlugin — Plugin-level orchestration for config-driven entities.
Wires entities into the Slingshot plugin lifecycle:
- setupRoutes: builds bare routes, applies config middleware, mounts onto app
- setupPost: registers permission resource types and post-route integrations
- teardown: unsubscribes cascade event handlers
Consumers wire entities via EntityPluginEntry — either with buildAdapter (manual) or with factories + entityKey (composite, zero-code). This keeps the package free of framework-internal dependencies.
Source: packages/slingshot-entity/src/createEntityPlugin.ts
EntityPluginToolingMetadata
Section titled “EntityPluginToolingMetadata”createEntityPlugin — Plugin-level orchestration for config-driven entities.
Wires entities into the Slingshot plugin lifecycle:
- setupRoutes: builds bare routes, applies config middleware, mounts onto app
- setupPost: registers permission resource types and post-route integrations
- teardown: unsubscribes cascade event handlers
Consumers wire entities via EntityPluginEntry — either with buildAdapter (manual) or with factories + entityKey (composite, zero-code). This keeps the package free of framework-internal dependencies.
Source: packages/slingshot-entity/src/createEntityPlugin.ts
EntityRouteExecutionContext
Section titled “EntityRouteExecutionContext”Identifies a generated CRUD route (create/list/get/update/delete) or a named operation route (operations.${name}).
Source: packages/slingshot-entity/src/routing/entityRoutePlanning.ts
EntityRouteExecutorBuilderContext
Section titled “EntityRouteExecutorBuilderContext”Identifies a generated CRUD route (create/list/get/update/delete) or a named operation route (operations.${name}).
Source: packages/slingshot-entity/src/routing/entityRoutePlanning.ts
EntityRouteExecutorDefinition
Section titled “EntityRouteExecutorDefinition”Identifies a generated CRUD route (create/list/get/update/delete) or a named operation route (operations.${name}).
Source: packages/slingshot-entity/src/routing/entityRoutePlanning.ts
EntityRouteExecutorOverrides
Section titled “EntityRouteExecutorOverrides”Identifies a generated CRUD route (create/list/get/update/delete) or a named operation route (operations.${name}).
Source: packages/slingshot-entity/src/routing/entityRoutePlanning.ts
EntitySnapshot
Section titled “EntitySnapshot”Schema migration types.
Source: packages/slingshot-entity/src/migrations/types.ts
EntityStorageConventions
Section titled “EntityStorageConventions”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
EntityStorageFieldMap
Section titled “EntityStorageFieldMap”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
EntityStorageHints
Section titled “EntityStorageHints”Entity configuration types.
Source: packages/slingshot-entity/src/types/entity.ts
EntitySystemFields
Section titled “EntitySystemFields”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
EntityTtlConfig
Section titled “EntityTtlConfig”Entity configuration types.
Source: packages/slingshot-entity/src/types/entity.ts
EvaluateRouteAuthDeps
Section titled “EvaluateRouteAuthDeps”Result of evaluating auth and permission requirements for an entity route.
Source: packages/slingshot-entity/src/routing/evaluateRouteAuth.ts
ExistsOpConfig
Section titled “ExistsOpConfig”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
FactoriesEntityModuleWiring
Section titled “FactoriesEntityModuleWiring”Use the framework’s default adapter resolution for the entity.
Source: packages/slingshot-entity/src/packageAuthoring.ts
FieldDef
Section titled “FieldDef”Field type tokens and definition interfaces.
Source: packages/slingshot-entity/src/types/fields.ts
FieldOptions
Section titled “FieldOptions”Field type tokens and definition interfaces.
Source: packages/slingshot-entity/src/types/fields.ts
FieldUpdateOpConfig
Section titled “FieldUpdateOpConfig”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
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
GenerateOptions
Section titled “GenerateOptions”Pure code generation function.
Takes entity definitions + optional operations → returns Record<string, string> where keys are filenames and values are file contents.
No side effects. No disk I/O. Fully testable.
Source: packages/slingshot-entity/src/generate.ts
IncrementOpConfig
Section titled “IncrementOpConfig”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
LazyMiddlewareRef
Section titled “LazyMiddlewareRef”Helper used by feature packages whose adapter- or capability-dependent middleware handlers can only be wired after lifecycle hooks run.
The returned ref starts as a pass-through next() no-op. The package
mounts middleware that forwards through ref.handler, then assigns
the real handler from setupMiddleware or setupPost once its
dependencies are resolved.
Source: packages/slingshot-entity/src/lazyMiddleware.ts
LookupOpConfig
Section titled “LookupOpConfig”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
ManualEntityModuleWiring
Section titled “ManualEntityModuleWiring”Use the framework’s default adapter resolution for the entity.
Source: packages/slingshot-entity/src/packageAuthoring.ts
MigrationPlan
Section titled “MigrationPlan”Schema migration types.
Source: packages/slingshot-entity/src/migrations/types.ts
PackageEntityModule
Section titled “PackageEntityModule”Use the framework’s default adapter resolution for the entity.
Source: packages/slingshot-entity/src/packageAuthoring.ts
PackageEntityModuleImplementation
Section titled “PackageEntityModuleImplementation”Use the framework’s default adapter resolution for the entity.
Source: packages/slingshot-entity/src/packageAuthoring.ts
PaginationConfig
Section titled “PaginationConfig”Entity configuration types.
Source: packages/slingshot-entity/src/types/entity.ts
PlannedEntityRoute
Section titled “PlannedEntityRoute”Identifies a generated CRUD route (create/list/get/update/delete) or a named operation route (operations.${name}).
Source: packages/slingshot-entity/src/routing/entityRoutePlanning.ts
PolicyDispatchConfig
Section titled “PolicyDispatchConfig”Configuration for definePolicyDispatch.
Source: packages/slingshot-entity/src/policy/definePolicyDispatch.ts
RelationDef
Section titled “RelationDef”Entity configuration types.
Source: packages/slingshot-entity/src/types/entity.ts
ResolvedEntityConfig
Section titled “ResolvedEntityConfig”Entity configuration types.
Source: packages/slingshot-entity/src/types/entity.ts
ResolvedEntityStorageConventions
Section titled “ResolvedEntityStorageConventions”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
ResolvedEntityStorageFieldMap
Section titled “ResolvedEntityStorageFieldMap”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
ResolvedEntitySystemFields
Section titled “ResolvedEntitySystemFields”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
ResolvePolicyArgs
Section titled “ResolvePolicyArgs”Arguments for resolvePolicy.
Source: packages/slingshot-entity/src/policy/resolvePolicy.ts
RouteAuthResult
Section titled “RouteAuthResult”Result of evaluating auth and permission requirements for an entity route.
Source: packages/slingshot-entity/src/routing/evaluateRouteAuth.ts
SearchOpConfig
Section titled “SearchOpConfig”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
StandardEntityModuleWiring
Section titled “StandardEntityModuleWiring”Use the framework’s default adapter resolution for the entity.
Source: packages/slingshot-entity/src/packageAuthoring.ts
TenantConfig
Section titled “TenantConfig”Entity configuration types.
Source: packages/slingshot-entity/src/types/entity.ts
TransitionOpConfig
Section titled “TransitionOpConfig”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
UpsertOpConfig
Section titled “UpsertOpConfig”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
ValidationResult
Section titled “ValidationResult”Zod schema validation for entity and operation definitions.
These schemas validate the structural correctness of configs. Cross-field validation (e.g., “softDelete field must exist in fields”) uses Zod’s .superRefine() for clear, composable error messages.
Source: packages/slingshot-entity/src/validation.ts
WriteOptions
Section titled “WriteOptions”CLI wrapper — calls generate(), handles snapshot lifecycle, writes files to disk.
Usage: slingshot-data generate —definition ./src/entities/message.ts —outdir ./src/generated/message
Or programmatically: import { writeGenerated } from ‘@lastshotlabs/slingshot-entity’; writeGenerated(messageConfig, { outDir: ’./src/generated/message’ });
Source: packages/slingshot-entity/src/cli.ts
AuditSeverity
Section titled “AuditSeverity”Entity audit types — findings produced by audit rules.
Source: packages/slingshot-entity/src/audits/types.ts
AutoDefault
Section titled “AutoDefault”Field type tokens and definition interfaces.
Source: packages/slingshot-entity/src/types/fields.ts
BareEntityAdapter
Section titled “BareEntityAdapter”The typed CRUD surface of a bare entity adapter.
Each method mirrors the HTTP verb and semantics used by the generated routes.
Source: packages/slingshot-entity/src/routing/adapterTypes.ts
ChannelMiddlewareHandler
Section titled “ChannelMiddlewareHandler”applyChannelConfig — builds subscribe guards and event forwarding for config-driven WebSocket entity channels.
Two responsibilities:
- Subscribe guard: parses room names, enforces auth/permissions/middleware
- Event forwarding: wires bus events to WS room publish calls
Source: packages/slingshot-entity/src/channels/applyChannelConfig.ts
CollectionOperation
Section titled “CollectionOperation”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
CustomAutoDefaultResolver
Section titled “CustomAutoDefaultResolver”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
CustomOnUpdateResolver
Section titled “CustomOnUpdateResolver”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
DefineEntityConfig
Section titled “DefineEntityConfig”Entity configuration types.
Source: packages/slingshot-entity/src/types/entity.ts
EntityGeneratedRouteKey
Section titled “EntityGeneratedRouteKey”Identifies a generated CRUD route (create/list/get/update/delete) or a named operation route (operations.${name}).
Source: packages/slingshot-entity/src/routing/entityRoutePlanning.ts
EntityModuleWiring
Section titled “EntityModuleWiring”Use the framework’s default adapter resolution for the entity.
Source: packages/slingshot-entity/src/packageAuthoring.ts
EntityPluginEntry
Section titled “EntityPluginEntry”createEntityPlugin — Plugin-level orchestration for config-driven entities.
Wires entities into the Slingshot plugin lifecycle:
- setupRoutes: builds bare routes, applies config middleware, mounts onto app
- setupPost: registers permission resource types and post-route integrations
- teardown: unsubscribes cascade event handlers
Consumers wire entities via EntityPluginEntry — either with buildAdapter (manual) or with factories + entityKey (composite, zero-code). This keeps the package free of framework-internal dependencies.
Source: packages/slingshot-entity/src/createEntityPlugin.ts
EntityRouteExecutor
Section titled “EntityRouteExecutor”Identifies a generated CRUD route (create/list/get/update/delete) or a named operation route (operations.${name}).
Source: packages/slingshot-entity/src/routing/entityRoutePlanning.ts
EntityRouteExecutorBuilder
Section titled “EntityRouteExecutorBuilder”Identifies a generated CRUD route (create/list/get/update/delete) or a named operation route (operations.${name}).
Source: packages/slingshot-entity/src/routing/entityRoutePlanning.ts
ExtractInputVariants
Section titled “ExtractInputVariants”Entity configuration types.
Source: packages/slingshot-entity/src/types/entity.ts
FilterOperator
Section titled “FilterOperator”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
FilterValue
Section titled “FilterValue”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
MergeStrategy
Section titled “MergeStrategy”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
MigrationChange
Section titled “MigrationChange”Schema migration types.
Source: packages/slingshot-entity/src/migrations/types.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
SoftDeleteConfig
Section titled “SoftDeleteConfig”Entity configuration types.
Source: packages/slingshot-entity/src/types/entity.ts
WsPublishFn
Section titled “WsPublishFn”applyChannelConfig — builds subscribe guards and event forwarding for config-driven WebSocket entity channels.
Two responsibilities:
- Subscribe guard: parses room names, enforces auth/permissions/middleware
- Event forwarding: wires bus events to WS room publish calls
Source: packages/slingshot-entity/src/channels/applyChannelConfig.ts
Exports
Section titled “Exports”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
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”Entity definition entry point — dev-time only.
Validates config using Zod schema, resolves PK and storage name.
Source: packages/slingshot-entity/src/defineEntity.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