@semilayer/core 0.1.2 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,43 @@
1
+ <p align="right">
2
+ <img src="https://raw.githubusercontent.com/semilayer/semilayer/main/assets/logo.png" alt="SemiLayer" width="120" />
3
+ <br />
4
+ <strong>@semilayer/core</strong>
5
+ </p>
6
+
7
+ <p align="right">
8
+ Core types, schema definitions, and <code>defineConfig</code> for <a href="https://semilayer.com">SemiLayer</a> — the intelligence layer for any database. Shared by the CLI, client, codegen, and every first-party package.
9
+ </p>
10
+
11
+ ---
12
+
13
+ ## Install
14
+
15
+ ```bash
16
+ pnpm add @semilayer/core
17
+ ```
18
+
19
+ ## Usage
20
+
21
+ ```ts
22
+ import { defineConfig } from '@semilayer/core'
23
+
24
+ export default defineConfig({
25
+ project: 'my-app',
26
+ sources: {
27
+ main: { bridge: '@semilayer/bridge-postgres', url: process.env.DATABASE_URL! },
28
+ },
29
+ lenses: {
30
+ articles: {
31
+ source: 'main',
32
+ table: 'articles',
33
+ facets: { search: true, similar: true },
34
+ },
35
+ },
36
+ })
37
+ ```
38
+
39
+ See [semilayer.dev](https://semilayer.dev) for the full docs.
40
+
41
+ ## License
42
+
43
+ MIT
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/constants.ts","../src/validate.ts","../src/mapping.ts","../src/hash.ts","../src/type-mapper.ts","../src/stream.ts","../src/deployment.ts"],"sourcesContent":["import type { SemiLayerConfig } from './config.js'\nimport { validateConfig } from './validate.js'\n\nexport function defineConfig(config: SemiLayerConfig): SemiLayerConfig {\n validateConfig(config)\n return config\n}\n\nexport { validateConfig } from './validate.js'\n\nexport type {\n SemiLayerConfig,\n SourceConfig,\n LensConfig,\n FieldConfig,\n SearchFacetConfig,\n SimilarFacetConfig,\n DedupFacetConfig,\n ClassifyFacetConfig,\n FacetConfig,\n AuthConfig,\n JwtConfig,\n JwtClaims,\n AccessRule,\n AccessRuleResult,\n ClaimCheck,\n EnvironmentAuthConfig,\n LensRules,\n LensRuleKey,\n StreamRules,\n EmbeddingConfig,\n BuiltinTransform,\n TransformSpec,\n SyncInterval,\n} from './config.js'\n\nexport { resolveSourceColumns, resolveEmbeddingFields, resolveEmbeddingFieldNames } from './mapping.js'\nexport type { EmbeddingField } from './mapping.js'\nexport { canonicalHash } from './hash.js'\nexport { mapDbTypeToFieldType } from './type-mapper.js'\n\nexport type {\n WhereClause,\n OrderByClause,\n QueryOptions,\n QueryResult,\n} from './query.js'\n\nexport type {\n BridgeRow,\n ReadOptions,\n ReadResult,\n TargetColumnInfo,\n TargetSchema,\n Bridge,\n BridgeConstructor,\n} from './bridge.js'\n\nexport type {\n TransportMode,\n TransportOptions,\n} from './transport.js'\n\nexport {\n STREAM_MODES,\n LIVE_TAIL_MODES,\n STREAM_OPS,\n STREAM_FRAME_TYPES,\n STREAM_EVENT_KINDS,\n STREAM_ERROR_CODES,\n STREAM_CLOSE_CODES,\n deriveLiveTailMode,\n isStreamingEnabled,\n isLiveTailModeEnabled,\n} from './stream.js'\n\nexport type {\n StreamMode,\n LiveTailMode,\n StreamOp,\n StreamFrameType,\n StreamEventKind,\n StreamErrorCode,\n StreamCloseCode,\n StreamSearchParams,\n StreamQueryParams,\n SubscribeParams,\n StreamOpFrame,\n StreamMeta,\n StreamRowFrame,\n StreamDoneFrame,\n StreamEventFrame,\n StreamErrorFrame,\n StreamPingFrame,\n StreamPongFrame,\n StreamFrame,\n StreamEvent,\n StreamSearchRow,\n DeriveLiveTailModeInput,\n} from './stream.js'\n\nexport type {\n IngestJobPayload,\n IngestJobData,\n IngestControl,\n RateLimitState,\n IngestErrorEntry,\n LensStatusInfo,\n QueueCounts,\n FailedJobInfo,\n} from './ingest.js'\n\nexport {\n FACET_NAMES,\n FUTURE_FACETS,\n FIELD_TYPES,\n INGEST_JOB_TYPES,\n LENS_STATUSES,\n INGEST_STATUSES,\n KEY_PREFIXES,\n DEPLOYMENT_MODES,\n SOURCE_FEATURES,\n TRANSFORM_TYPES,\n MERGE_STRATEGIES,\n} from './constants.js'\n\nexport type {\n FacetName,\n FieldType,\n IngestJobType,\n IngestStatus,\n LensStatus,\n DeploymentMode,\n SourceFeature,\n TransformType,\n MergeStrategy,\n} from './constants.js'\n\nexport type {\n ISODateString,\n Org,\n Project,\n Environment,\n Source,\n Lens,\n ApiKeyInfo,\n Member,\n IngestRun,\n Page,\n Tier,\n TierOverride,\n TierSummary,\n AuthUser,\n AuthOrg,\n MeResponse,\n NewKeyPair,\n CreateProjectResponse,\n CreateEnvResponse,\n PushLensSummary,\n PushIngestJob,\n PushResponse,\n StatusEnvironment,\n StatusResponse,\n PlatformAdmin,\n AuditLogEntry,\n PlatformStats,\n SystemHealth,\n InAppNotification,\n NotificationPreferenceSummary,\n OrgListItem,\n OrgDetailResponse,\n ProjectWithEnvs,\n InviteInfo,\n DriftLensInfo,\n DriftResponse,\n EnvsResponse,\n ConfigExportResponse,\n LensComparison,\n LensCreateResponse,\n DailyMetrics,\n MetricPoint,\n BannerData,\n FeedbackItem,\n FeedbackDetail,\n BannedIp,\n BannedUser,\n SearchParams,\n SearchResult,\n SearchResponse,\n SimilarParams,\n SimilarResponse,\n QueryParams,\n QueryResponse,\n AdminUserListItem,\n AdminUserListResponse,\n AdminUserOrgMembership,\n AdminUserDetail,\n AdminAssignUserBody,\n PendingInvite,\n PendingInvitesResponse,\n // Step 12 — Billing\n BillingSnapshot,\n BillingPlan,\n UsageMetricSnapshot,\n BillingCycleInfo,\n Invoice,\n TierFull,\n TiersResponse,\n CheckoutRequest,\n BillingRedirectResponse,\n CancelSubscriptionRequest,\n AdminMrrSnapshot,\n AdminCashSnapshot,\n AdminStripeEventRow,\n AdminOrgUsage,\n AdminTopConsumerRow,\n AdminTopConsumersResponse,\n TierOverrideRequest,\n QuotaErrorResponse,\n} from './models.js'\n\nexport { getDeploymentMode, isSaasMode } from './deployment.js'\n","export const FACET_NAMES = [\n 'search',\n 'similar',\n] as const\n\nexport type FacetName = (typeof FACET_NAMES)[number]\n\n/** Facets planned for future releases. Config types exist but no runtime support yet. */\nexport const FUTURE_FACETS = ['dedup', 'classify'] as const\n\nexport const FIELD_TYPES = [\n 'text',\n 'number',\n 'boolean',\n 'date',\n 'json',\n 'enum',\n 'relation',\n] as const\n\nexport type FieldType = (typeof FIELD_TYPES)[number]\n\nexport const INGEST_JOB_TYPES = [\n 'full',\n 'incremental',\n 'delete',\n 'records',\n 'sync',\n] as const\n\nexport type IngestJobType = (typeof INGEST_JOB_TYPES)[number]\n\nexport const LENS_STATUSES = [\n 'paused',\n 'indexing',\n 'ready',\n 'error',\n] as const\n\nexport type LensStatus = (typeof LENS_STATUSES)[number]\n\nexport const INGEST_STATUSES = [\n 'queued',\n 'running',\n 'completed',\n 'failed',\n] as const\n\nexport type IngestStatus = (typeof INGEST_STATUSES)[number]\n\nexport const KEY_PREFIXES = {\n serviceKey: 'sk_',\n publishableKey: 'pk_',\n ingestKey: 'ik_',\n} as const\n\nexport const DEPLOYMENT_MODES = ['saas', 'enterprise'] as const\n\nexport type DeploymentMode = (typeof DEPLOYMENT_MODES)[number]\n\nexport const SOURCE_FEATURES = [\n 'incremental',\n 'change-tracking',\n 'streaming',\n] as const\n\nexport type SourceFeature = (typeof SOURCE_FEATURES)[number]\n\nexport const TRANSFORM_TYPES = [\n 'toString',\n 'toNumber',\n 'toBoolean',\n 'toDate',\n 'round',\n 'trim',\n 'lowercase',\n 'uppercase',\n 'default',\n 'split',\n 'join',\n 'truncate',\n 'replace',\n 'custom',\n] as const\n\nexport type TransformType = (typeof TRANSFORM_TYPES)[number]\n\nexport const MERGE_STRATEGIES = ['concat', 'coalesce'] as const\n\nexport type MergeStrategy = (typeof MERGE_STRATEGIES)[number]\n","import type {\n SemiLayerConfig,\n FieldConfig,\n BuiltinTransform,\n TransformSpec,\n} from './config.js'\nimport { FACET_NAMES, TRANSFORM_TYPES } from './constants.js'\n\nexport function validateConfig(config: SemiLayerConfig): void {\n if (!config.stack || typeof config.stack !== 'string') {\n throw new Error('config.stack must be a non-empty string')\n }\n\n const sourceNames = Object.keys(config.sources)\n if (sourceNames.length === 0) {\n throw new Error('config.sources must define at least one source')\n }\n\n const lensEntries = Object.entries(config.lenses)\n if (lensEntries.length === 0) {\n throw new Error('config.lenses must define at least one lens')\n }\n\n for (const [lensName, lens] of lensEntries) {\n if (!sourceNames.includes(lens.source)) {\n throw new Error(\n `lens \"${lensName}\" references unknown source \"${lens.source}\"`,\n )\n }\n\n const fieldEntries = Object.entries(lens.fields)\n const fieldNames = fieldEntries.map(([name]) => name)\n\n // ── Primary key resolution ─────────────────────────────────\n if (lens.primaryKey) {\n if (!fieldNames.includes(lens.primaryKey)) {\n throw new Error(\n `lens \"${lensName}\" primaryKey \"${lens.primaryKey}\" does not exist in fields`,\n )\n }\n const pkInFields = fieldEntries.filter(([, f]) => f.primaryKey)\n const firstPk = pkInFields[0]\n if (firstPk && firstPk[0] !== lens.primaryKey) {\n throw new Error(\n `lens \"${lensName}\" has primaryKey \"${lens.primaryKey}\" but field \"${firstPk[0]}\" also has primaryKey: true`,\n )\n }\n } else {\n const primaryKeys = fieldEntries.filter(([, f]) => f.primaryKey)\n if (primaryKeys.length !== 1) {\n throw new Error(\n `lens \"${lensName}\" must have exactly one primary key field (found ${primaryKeys.length})`,\n )\n }\n }\n\n // ── Field validation (type-specific + mapping props) ──────\n for (const [fieldName, field] of fieldEntries) {\n if (field.type === 'enum' && (!field.values || field.values.length === 0)) {\n throw new Error(\n `field \"${fieldName}\" in lens \"${lensName}\" is type \"enum\" but has no values`,\n )\n }\n if (field.type === 'relation' && !field.to) {\n throw new Error(\n `field \"${fieldName}\" in lens \"${lensName}\" is type \"relation\" but has no \"to\"`,\n )\n }\n\n // Mapping validation — inline\n validateFieldMapping(lensName, fieldName, field)\n }\n\n // ── Sync interval validation ─────────────────────────────────\n if (lens.syncInterval) {\n const valid = ['1m', '5m', '15m', '30m', '1h', '6h', '24h']\n if (!valid.includes(lens.syncInterval)) {\n throw new Error(\n `lens \"${lensName}\" syncInterval \"${lens.syncInterval}\" is invalid (valid: ${valid.join(', ')})`,\n )\n }\n }\n\n // ── Rules validation ───────────────────────────────────────\n if (lens.rules) {\n const validAccessRuleKeys = new Set<string>([\n ...Object.keys(lens.facets ?? {}),\n 'query',\n ])\n\n for (const [key, rule] of Object.entries(lens.rules)) {\n // `stream` is a transport, not an access rule — it has its own shape.\n if (key === 'stream') {\n if (rule == null) continue\n if (typeof rule !== 'object' || Array.isArray(rule)) {\n throw new Error(\n `lens \"${lensName}\" rule \"stream\" must be an object`,\n )\n }\n const streamRule = rule as { enabled?: unknown; modes?: unknown; maxLiveSubscriptions?: unknown }\n if (streamRule.enabled !== undefined && typeof streamRule.enabled !== 'boolean') {\n throw new Error(\n `lens \"${lensName}\" rule \"stream.enabled\" must be a boolean`,\n )\n }\n if (streamRule.modes !== undefined) {\n if (!Array.isArray(streamRule.modes)) {\n throw new Error(\n `lens \"${lensName}\" rule \"stream.modes\" must be an array`,\n )\n }\n for (const mode of streamRule.modes) {\n if (mode !== 'chunked' && mode !== 'live') {\n throw new Error(\n `lens \"${lensName}\" rule \"stream.modes\" contains invalid mode \"${String(mode)}\" (valid: chunked, live)`,\n )\n }\n }\n }\n if (streamRule.maxLiveSubscriptions !== undefined) {\n if (\n typeof streamRule.maxLiveSubscriptions !== 'number' ||\n !Number.isFinite(streamRule.maxLiveSubscriptions) ||\n streamRule.maxLiveSubscriptions < 0\n ) {\n throw new Error(\n `lens \"${lensName}\" rule \"stream.maxLiveSubscriptions\" must be a non-negative number`,\n )\n }\n }\n continue\n }\n\n if (!validAccessRuleKeys.has(key)) {\n throw new Error(\n `lens \"${lensName}\" has rule for \"${key}\" but no matching facet (valid: ${[...validAccessRuleKeys].join(', ')}, stream)`,\n )\n }\n\n if (rule !== 'public' && rule !== 'authenticated' && typeof rule !== 'function') {\n throw new Error(\n `lens \"${lensName}\" rule \"${key}\" must be 'public', 'authenticated', or a function`,\n )\n }\n }\n }\n\n // ── Facet validation (directly against field keys) ─────────\n for (const [facetName, facet] of Object.entries(lens.facets)) {\n if (!FACET_NAMES.includes(facetName as never)) {\n throw new Error(\n `lens \"${lensName}\" has invalid facet name \"${facetName}\" (valid: ${FACET_NAMES.join(', ')})`,\n )\n }\n\n if ('fields' in facet && Array.isArray(facet.fields)) {\n for (const ref of facet.fields) {\n if (!fieldNames.includes(ref)) {\n throw new Error(\n `facet \"${facetName}\" in lens \"${lensName}\" references unknown field \"${ref}\"`,\n )\n }\n }\n }\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Field mapping validation\n// ---------------------------------------------------------------------------\n\nfunction validateFieldMapping(\n lensName: string,\n fieldName: string,\n field: FieldConfig,\n): void {\n if (field.from === undefined) return // identity mapping, nothing to validate\n\n if (Array.isArray(field.from)) {\n // Multi-source\n if (!field.merge) {\n throw new Error(\n `field \"${fieldName}\" in lens \"${lensName}\" has multiple sources but no merge strategy`,\n )\n }\n if (field.merge === 'concat' && field.separator === undefined) {\n throw new Error(\n `field \"${fieldName}\" in lens \"${lensName}\" uses merge \"concat\" but has no separator`,\n )\n }\n if (field.from.length < 2) {\n throw new Error(\n `field \"${fieldName}\" in lens \"${lensName}\" has multi-source from but fewer than 2 entries`,\n )\n }\n } else if (typeof field.from !== 'string') {\n throw new Error(\n `field \"${fieldName}\" in lens \"${lensName}\" has invalid from value (must be string or string[])`,\n )\n }\n\n if (field.transform) {\n validateTransformSpec(lensName, fieldName, field.transform)\n }\n}\n\nfunction validateTransformSpec(lensName: string, fieldName: string, spec: TransformSpec): void {\n const transforms = Array.isArray(spec) ? spec : [spec]\n for (const t of transforms) {\n if (!t || typeof t !== 'object' || !('type' in t)) {\n throw new Error(\n `field \"${fieldName}\" in lens \"${lensName}\" has invalid transform (missing type)`,\n )\n }\n if (!TRANSFORM_TYPES.includes(t.type as never)) {\n throw new Error(\n `field \"${fieldName}\" in lens \"${lensName}\" has unknown transform type \"${t.type}\"`,\n )\n }\n validateTransformFields(lensName, fieldName, t)\n }\n}\n\nfunction validateTransformFields(lensName: string, fieldName: string, t: BuiltinTransform): void {\n switch (t.type) {\n case 'split':\n if (typeof t.separator !== 'string') {\n throw new Error(\n `field \"${fieldName}\" in lens \"${lensName}\" transform \"split\" requires \"separator\"`,\n )\n }\n break\n case 'join':\n if (typeof t.separator !== 'string') {\n throw new Error(\n `field \"${fieldName}\" in lens \"${lensName}\" transform \"join\" requires \"separator\"`,\n )\n }\n break\n case 'truncate':\n if (typeof t.length !== 'number' || t.length < 0) {\n throw new Error(\n `field \"${fieldName}\" in lens \"${lensName}\" transform \"truncate\" requires positive \"length\"`,\n )\n }\n break\n case 'replace':\n if (typeof t.pattern !== 'string' || typeof t.replacement !== 'string') {\n throw new Error(\n `field \"${fieldName}\" in lens \"${lensName}\" transform \"replace\" requires \"pattern\" and \"replacement\"`,\n )\n }\n break\n case 'custom':\n if (typeof t.body !== 'string') {\n throw new Error(\n `field \"${fieldName}\" in lens \"${lensName}\" transform \"custom\" requires \"body\" string`,\n )\n }\n break\n case 'round':\n if (t.mode && !['round', 'ceil', 'floor'].includes(t.mode)) {\n throw new Error(\n `field \"${fieldName}\" in lens \"${lensName}\" transform \"round\" mode must be 'round', 'ceil', or 'floor'`,\n )\n }\n break\n }\n}\n","import type { FieldConfig } from './config.js'\n\n/**\n * Returns the list of source column names that the bridge needs to read.\n * Derives from `from` properties on fields, falling back to the output field name.\n */\nexport function resolveSourceColumns(fields: Record<string, FieldConfig>): string[] {\n const cols = new Set<string>()\n for (const [outputName, config] of Object.entries(fields)) {\n if (config.from) {\n if (Array.isArray(config.from)) {\n for (const src of config.from) cols.add(src)\n } else {\n cols.add(config.from)\n }\n } else {\n cols.add(outputName)\n }\n }\n return [...cols]\n}\n\nexport interface EmbeddingField {\n field: string\n weight: number\n}\n\n/**\n * Returns the output field names that are marked for embedding,\n * with their weights. Weight controls how many times a field's text\n * is repeated in the embedding input (higher = more relevance).\n */\nexport function resolveEmbeddingFields(fields: Record<string, FieldConfig>): EmbeddingField[] {\n const result: EmbeddingField[] = []\n for (const [name, config] of Object.entries(fields)) {\n if (!config.searchable) continue\n const weight =\n typeof config.searchable === 'object'\n ? (config.searchable.weight ?? 1)\n : 1\n result.push({ field: name, weight })\n }\n return result\n}\n\n/**\n * Convenience: returns just the field names (for APIs that only need names).\n */\nexport function resolveEmbeddingFieldNames(fields: Record<string, FieldConfig>): string[] {\n return resolveEmbeddingFields(fields).map((e) => e.field)\n}\n","import { createHash } from 'node:crypto'\n\n/**\n * Creates a deterministic SHA-256 hash of any JSON-serializable value.\n * Object keys are sorted recursively to ensure determinism regardless of insertion order.\n */\nexport function canonicalHash(obj: unknown): string {\n const json = JSON.stringify(sortKeys(obj)) ?? 'null'\n const digest = createHash('sha256').update(json).digest('hex')\n return `sha256:${digest}`\n}\n\nfunction sortKeys(value: unknown): unknown {\n if (value === null || value === undefined) return value\n if (Array.isArray(value)) return value.map(sortKeys)\n if (typeof value === 'object') {\n const sorted: Record<string, unknown> = {}\n for (const key of Object.keys(value as Record<string, unknown>).sort()) {\n sorted[key] = sortKeys((value as Record<string, unknown>)[key])\n }\n return sorted\n }\n return value\n}\n","import type { FieldType } from './constants.js'\n\nconst DB_TYPE_MAP: Record<string, FieldType> = {\n // Text\n varchar: 'text',\n text: 'text',\n char: 'text',\n 'character varying': 'text',\n character: 'text',\n citext: 'text',\n uuid: 'text',\n name: 'text',\n\n // Number\n integer: 'number',\n int: 'number',\n int4: 'number',\n bigint: 'number',\n int8: 'number',\n smallint: 'number',\n int2: 'number',\n numeric: 'number',\n decimal: 'number',\n real: 'number',\n float4: 'number',\n 'double precision': 'number',\n float8: 'number',\n serial: 'number',\n bigserial: 'number',\n\n // Boolean\n boolean: 'boolean',\n bool: 'boolean',\n\n // Date\n timestamp: 'date',\n 'timestamp with time zone': 'date',\n 'timestamp without time zone': 'date',\n timestamptz: 'date',\n date: 'date',\n time: 'date',\n 'time with time zone': 'date',\n 'time without time zone': 'date',\n timetz: 'date',\n\n // JSON\n json: 'json',\n jsonb: 'json',\n\n // Arrays → json\n 'ARRAY': 'json',\n}\n\n/**\n * Maps a raw database column type to a SemiLayer FieldType.\n * Falls back to 'text' for unknown types.\n */\nexport function mapDbTypeToFieldType(dbType: string): FieldType {\n const normalized = dbType.toLowerCase().trim()\n return DB_TYPE_MAP[normalized] ?? 'text'\n}\n","import type { SearchResult, SearchParams, QueryParams } from './models.js'\nimport type { SourceFeature } from './constants.js'\nimport type { LensRules, SyncInterval } from './config.js'\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nexport const STREAM_MODES = ['chunked', 'live'] as const\nexport type StreamMode = (typeof STREAM_MODES)[number]\n\nexport const LIVE_TAIL_MODES = ['push', 'polling', 'unsupported'] as const\nexport type LiveTailMode = (typeof LIVE_TAIL_MODES)[number]\n\n/** WebSocket op names sent from client to server in the `op` field. */\nexport const STREAM_OPS = [\n 'search.stream',\n 'query.stream',\n 'subscribe',\n 'observe',\n 'unsubscribe',\n] as const\nexport type StreamOp = (typeof STREAM_OPS)[number]\n\n/** Frame `type` values for both directions. */\nexport const STREAM_FRAME_TYPES = [\n 'row',\n 'done',\n 'error',\n 'event',\n 'ping',\n 'pong',\n] as const\nexport type StreamFrameType = (typeof STREAM_FRAME_TYPES)[number]\n\n/** Subscription event kinds (mirrors ingest write operations). */\nexport const STREAM_EVENT_KINDS = ['insert', 'update', 'delete'] as const\nexport type StreamEventKind = (typeof STREAM_EVENT_KINDS)[number]\n\n/** Error codes carried in `error` frames. */\nexport const STREAM_ERROR_CODES = [\n 'rate_limited',\n 'forbidden',\n 'bad_request',\n 'not_found',\n 'internal',\n] as const\nexport type StreamErrorCode = (typeof STREAM_ERROR_CODES)[number]\n\n/**\n * WebSocket close codes.\n *\n * Reserved codes (1xxx) follow RFC 6455. The 4xxx range is application-defined.\n */\nexport const STREAM_CLOSE_CODES = {\n /** Normal close — client called .close() or server finished. */\n normal: 1000,\n /** Server-side internal error. */\n internal: 1011,\n /** Auth failed during the upgrade handshake. */\n authFailed: 4401,\n /** Lens forbids streaming (rules.stream.enabled === false or modes[] excludes the requested mode). */\n forbidden: 4403,\n /** Rate-limited at handshake — over `concurrentWsConnections` for the org. */\n rateLimited: 4290,\n /** Mid-stream `wsRowsPerHour` quota exceeded. */\n quotaExceeded: 4291,\n} as const\n\nexport type StreamCloseCode = (typeof STREAM_CLOSE_CODES)[keyof typeof STREAM_CLOSE_CODES]\n\n// ---------------------------------------------------------------------------\n// Request shapes\n// ---------------------------------------------------------------------------\n\nexport interface StreamSearchParams extends SearchParams {\n /** Optional batch size hint — server may ignore. Default: 50. */\n batchSize?: number\n}\n\nexport interface StreamQueryParams extends QueryParams {\n /** Optional batch size hint — server may ignore. Default: 100. */\n batchSize?: number\n}\n\nexport interface SubscribeParams {\n /**\n * Optional in-process filter applied to events before they're emitted.\n * v0.1: simple equality only. Complex predicate pushdown is a v0.2 feature.\n */\n filter?: Record<string, unknown>\n}\n\n// ---------------------------------------------------------------------------\n// Op frame (client → server)\n// ---------------------------------------------------------------------------\n\n/**\n * One control frame sent from client to server. Multiple ops can ride a single\n * WebSocket connection — `id` is the multiplexing key the server echoes back\n * on response frames.\n */\nexport interface StreamOpFrame {\n id: string\n op: StreamOp\n params?: StreamSearchParams | StreamQueryParams | SubscribeParams | Record<string, unknown>\n}\n\n// ---------------------------------------------------------------------------\n// Response frames (server → client)\n// ---------------------------------------------------------------------------\n\nexport interface StreamMeta {\n count: number\n durationMs: number\n}\n\n/** A row from a chunked search/query stream. */\nexport interface StreamRowFrame<T = Record<string, unknown>> {\n id: string\n type: 'row'\n data: T\n}\n\n/** Terminal frame for a chunked op — no more rows will arrive for this id. */\nexport interface StreamDoneFrame {\n id: string\n type: 'done'\n meta: StreamMeta\n}\n\n/** Subscription event — pushed for each matching ingest write. */\nexport interface StreamEventFrame<T = Record<string, unknown>> {\n id: string\n type: 'event'\n kind: StreamEventKind\n record: T\n}\n\n/** Error attached to a specific op id (or global if id omitted). */\nexport interface StreamErrorFrame {\n id?: string\n type: 'error'\n code: StreamErrorCode\n message: string\n}\n\n/** Server heartbeat. Client must reply with a `pong` frame. */\nexport interface StreamPingFrame {\n type: 'ping'\n}\n\n/** Client heartbeat reply. */\nexport interface StreamPongFrame {\n type: 'pong'\n}\n\n/** Discriminated union of every frame the server can send. */\nexport type StreamFrame<T = Record<string, unknown>> =\n | StreamRowFrame<T>\n | StreamDoneFrame\n | StreamEventFrame<T>\n | StreamErrorFrame\n | StreamPingFrame\n | StreamPongFrame\n\n// ---------------------------------------------------------------------------\n// Public consumer types\n// ---------------------------------------------------------------------------\n\n/** What `BeamClient.subscribe()` yields per event. */\nexport interface StreamEvent<M = Record<string, unknown>> {\n kind: StreamEventKind\n record: M\n}\n\n/** What `BeamClient.streamSearch()` yields per row. */\nexport type StreamSearchRow<M = Record<string, unknown>> = SearchResult<M>\n\n// ---------------------------------------------------------------------------\n// Live tail mode derivation\n// ---------------------------------------------------------------------------\n\nexport interface DeriveLiveTailModeInput {\n /** Lens rules — if `rules.stream.modes` excludes `'live'`, the mode is `unsupported`. */\n rules?: LensRules\n /** Lens sync interval — presence implies polling-mode ingest. */\n syncInterval?: SyncInterval\n /** Source feature flags from the bridge. */\n bridgeFeatures?: SourceFeature[]\n /**\n * Whether at least one ingest key (ik_) exists for the lens. This is a\n * runtime fact (DB-derived) — callers must look it up before invoking.\n */\n acceptsIngestKey: boolean\n}\n\n/**\n * Is streaming enabled at all for this lens? Returns false only when the lens\n * config explicitly opts out via `rules.stream.enabled === false`. Default: true.\n *\n * This is the question the worker asks before populating the live tail buffer:\n * if a lens has streaming disabled, no one can subscribe, so there is no point\n * paying for the INSERT + NOTIFY.\n */\nexport function isStreamingEnabled(rules?: LensRules): boolean {\n return rules?.stream?.enabled !== false\n}\n\n/**\n * Is the `live` stream mode allowed for this lens? Returns false if streaming\n * is fully disabled OR if `rules.stream.modes` is set and excludes `'live'`.\n * Default: true.\n *\n * This is the gate for the worker's observation pathway. When false, the worker\n * skips the live tail buffer entirely — observation is microweight, but it is\n * not zero, and there is no value populating a buffer subscribers can never read.\n */\nexport function isLiveTailModeEnabled(rules?: LensRules): boolean {\n if (!isStreamingEnabled(rules)) return false\n const modes = rules?.stream?.modes\n if (modes && !modes.includes('live')) return false\n return true\n}\n\n/**\n * Derive the live-tail mode for a lens.\n *\n * Live tail rides our **own ingest write path**, not bridge-native CDC. So as\n * long as records are being written to `vectors.embeddings` by *some* ingest\n * pathway, live tail works:\n *\n * - `'push'` — the lens accepts `ik_` ingest webhooks → near-realtime fan-out\n * - `'polling'` — the bridge supports incremental sync and a syncInterval is set\n * → smooth-but-bursty fan-out at the polling cadence\n * - `'unsupported'` — neither path is available, OR `rules.stream.modes`\n * explicitly excludes `'live'`. The Console Explorer disables the live tab\n * and the `subscribe` op returns a forbidden close code.\n */\nexport function deriveLiveTailMode(input: DeriveLiveTailModeInput): LiveTailMode {\n // Explicit opt-out via lens rules\n const streamRules = input.rules?.stream\n if (streamRules?.enabled === false) return 'unsupported'\n if (streamRules?.modes && !streamRules.modes.includes('live')) return 'unsupported'\n\n // Push mode — ingest webhook key exists\n if (input.acceptsIngestKey) return 'push'\n\n // Polling mode — incremental sync configured\n if (input.syncInterval && input.bridgeFeatures?.includes('incremental')) {\n return 'polling'\n }\n\n return 'unsupported'\n}\n","import type { DeploymentMode } from './constants.js'\n\nexport function getDeploymentMode(): DeploymentMode {\n return (process.env.DEPLOYMENT_MODE as DeploymentMode) ?? 'enterprise'\n}\n\nexport function isSaasMode(): boolean {\n return getDeploymentMode() === 'saas'\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/constants.ts","../src/validate.ts","../src/mapping.ts","../src/hash.ts","../src/type-mapper.ts","../src/stream.ts","../src/deployment.ts"],"sourcesContent":["import type { SemiLayerConfig } from './config.js'\nimport { validateConfig } from './validate.js'\n\nexport function defineConfig(config: SemiLayerConfig): SemiLayerConfig {\n validateConfig(config)\n return config\n}\n\nexport { validateConfig } from './validate.js'\n\nexport type {\n SemiLayerConfig,\n SourceConfig,\n LensConfig,\n FieldConfig,\n SearchFacetConfig,\n SimilarFacetConfig,\n DedupFacetConfig,\n ClassifyFacetConfig,\n FacetConfig,\n AuthConfig,\n JwtConfig,\n JwtClaims,\n AccessRule,\n AccessRuleResult,\n ClaimCheck,\n EnvironmentAuthConfig,\n LensRules,\n LensRuleKey,\n StreamRules,\n EmbeddingConfig,\n BuiltinTransform,\n TransformSpec,\n SyncInterval,\n} from './config.js'\n\nexport { resolveSourceColumns, resolveEmbeddingFields, resolveEmbeddingFieldNames } from './mapping.js'\nexport type { EmbeddingField } from './mapping.js'\nexport { canonicalHash } from './hash.js'\nexport { mapDbTypeToFieldType } from './type-mapper.js'\n\nexport type {\n WhereClause,\n OrderByClause,\n QueryOptions,\n QueryResult,\n} from './query.js'\n\nexport type {\n BridgeRow,\n ReadOptions,\n ReadResult,\n TargetColumnInfo,\n TargetSchema,\n Bridge,\n BridgeConstructor,\n BridgeFieldSchema,\n BridgeManifest,\n} from './bridge.js'\n\nexport type {\n TransportMode,\n TransportOptions,\n} from './transport.js'\n\nexport {\n STREAM_MODES,\n LIVE_TAIL_MODES,\n STREAM_OPS,\n STREAM_FRAME_TYPES,\n STREAM_EVENT_KINDS,\n STREAM_ERROR_CODES,\n STREAM_CLOSE_CODES,\n deriveLiveTailMode,\n isStreamingEnabled,\n isLiveTailModeEnabled,\n} from './stream.js'\n\nexport type {\n StreamMode,\n LiveTailMode,\n StreamOp,\n StreamFrameType,\n StreamEventKind,\n StreamErrorCode,\n StreamCloseCode,\n StreamSearchParams,\n StreamQueryParams,\n SubscribeParams,\n StreamOpFrame,\n StreamMeta,\n StreamRowFrame,\n StreamDoneFrame,\n StreamEventFrame,\n StreamErrorFrame,\n StreamPingFrame,\n StreamPongFrame,\n StreamFrame,\n StreamEvent,\n StreamSearchRow,\n DeriveLiveTailModeInput,\n} from './stream.js'\n\nexport type {\n IngestJobPayload,\n IngestJobData,\n IngestControl,\n RateLimitState,\n IngestErrorEntry,\n LensStatusInfo,\n QueueCounts,\n FailedJobInfo,\n} from './ingest.js'\n\nexport {\n FACET_NAMES,\n FUTURE_FACETS,\n FIELD_TYPES,\n INGEST_JOB_TYPES,\n LENS_STATUSES,\n INGEST_STATUSES,\n KEY_PREFIXES,\n DEPLOYMENT_MODES,\n SOURCE_FEATURES,\n TRANSFORM_TYPES,\n MERGE_STRATEGIES,\n} from './constants.js'\n\nexport type {\n FacetName,\n FieldType,\n IngestJobType,\n IngestStatus,\n LensStatus,\n DeploymentMode,\n SourceFeature,\n TransformType,\n MergeStrategy,\n} from './constants.js'\n\nexport type {\n ISODateString,\n Org,\n Project,\n Environment,\n Source,\n Lens,\n ApiKeyInfo,\n Member,\n IngestRun,\n Page,\n Tier,\n TierOverride,\n TierSummary,\n AuthUser,\n AuthOrg,\n MeResponse,\n NewKeyPair,\n CreateProjectResponse,\n CreateEnvResponse,\n PushLensSummary,\n PushIngestJob,\n PushResponse,\n StatusEnvironment,\n StatusResponse,\n PlatformAdmin,\n AuditLogEntry,\n PlatformStats,\n SystemHealth,\n InAppNotification,\n NotificationPreferenceSummary,\n OrgListItem,\n OrgDetailResponse,\n ProjectWithEnvs,\n InviteInfo,\n DriftLensInfo,\n DriftResponse,\n EnvsResponse,\n ConfigExportResponse,\n LensComparison,\n LensCreateResponse,\n DailyMetrics,\n MetricPoint,\n BannerData,\n FeedbackItem,\n FeedbackDetail,\n BannedIp,\n BannedUser,\n SearchParams,\n SearchResult,\n SearchResponse,\n SimilarParams,\n SimilarResponse,\n QueryParams,\n QueryResponse,\n AdminUserListItem,\n AdminUserListResponse,\n AdminUserOrgMembership,\n AdminUserDetail,\n AdminAssignUserBody,\n PendingInvite,\n PendingInvitesResponse,\n // Step 12 — Billing\n BillingSnapshot,\n BillingPlan,\n UsageMetricSnapshot,\n BillingCycleInfo,\n Invoice,\n TierFull,\n TiersResponse,\n CheckoutRequest,\n BillingRedirectResponse,\n CancelSubscriptionRequest,\n AdminMrrSnapshot,\n AdminCashSnapshot,\n AdminStripeEventRow,\n AdminOrgUsage,\n AdminTopConsumerRow,\n AdminTopConsumersResponse,\n TierOverrideRequest,\n QuotaErrorResponse,\n BridgeManifestsResponse,\n} from './models.js'\n\nexport { getDeploymentMode, isSaasMode } from './deployment.js'\n","export const FACET_NAMES = [\n 'search',\n 'similar',\n] as const\n\nexport type FacetName = (typeof FACET_NAMES)[number]\n\n/** Facets planned for future releases. Config types exist but no runtime support yet. */\nexport const FUTURE_FACETS = ['dedup', 'classify'] as const\n\nexport const FIELD_TYPES = [\n 'text',\n 'number',\n 'boolean',\n 'date',\n 'json',\n 'enum',\n 'relation',\n] as const\n\nexport type FieldType = (typeof FIELD_TYPES)[number]\n\nexport const INGEST_JOB_TYPES = [\n 'full',\n 'incremental',\n 'delete',\n 'records',\n 'sync',\n] as const\n\nexport type IngestJobType = (typeof INGEST_JOB_TYPES)[number]\n\nexport const LENS_STATUSES = [\n 'paused',\n 'indexing',\n 'ready',\n 'error',\n] as const\n\nexport type LensStatus = (typeof LENS_STATUSES)[number]\n\nexport const INGEST_STATUSES = [\n 'queued',\n 'running',\n 'completed',\n 'failed',\n] as const\n\nexport type IngestStatus = (typeof INGEST_STATUSES)[number]\n\nexport const KEY_PREFIXES = {\n serviceKey: 'sk_',\n publishableKey: 'pk_',\n ingestKey: 'ik_',\n} as const\n\nexport const DEPLOYMENT_MODES = ['saas', 'enterprise'] as const\n\nexport type DeploymentMode = (typeof DEPLOYMENT_MODES)[number]\n\nexport const SOURCE_FEATURES = [\n 'incremental',\n 'change-tracking',\n 'streaming',\n] as const\n\nexport type SourceFeature = (typeof SOURCE_FEATURES)[number]\n\nexport const TRANSFORM_TYPES = [\n 'toString',\n 'toNumber',\n 'toBoolean',\n 'toDate',\n 'round',\n 'trim',\n 'lowercase',\n 'uppercase',\n 'default',\n 'split',\n 'join',\n 'truncate',\n 'replace',\n 'custom',\n] as const\n\nexport type TransformType = (typeof TRANSFORM_TYPES)[number]\n\nexport const MERGE_STRATEGIES = ['concat', 'coalesce'] as const\n\nexport type MergeStrategy = (typeof MERGE_STRATEGIES)[number]\n","import type {\n SemiLayerConfig,\n FieldConfig,\n BuiltinTransform,\n TransformSpec,\n} from './config.js'\nimport { FACET_NAMES, TRANSFORM_TYPES } from './constants.js'\n\nexport function validateConfig(config: SemiLayerConfig): void {\n if (!config.stack || typeof config.stack !== 'string') {\n throw new Error('config.stack must be a non-empty string')\n }\n\n const sourceNames = Object.keys(config.sources)\n if (sourceNames.length === 0) {\n throw new Error('config.sources must define at least one source')\n }\n\n const lensEntries = Object.entries(config.lenses)\n if (lensEntries.length === 0) {\n throw new Error('config.lenses must define at least one lens')\n }\n\n for (const [lensName, lens] of lensEntries) {\n if (!sourceNames.includes(lens.source)) {\n throw new Error(\n `lens \"${lensName}\" references unknown source \"${lens.source}\"`,\n )\n }\n\n const fieldEntries = Object.entries(lens.fields)\n const fieldNames = fieldEntries.map(([name]) => name)\n\n // ── Primary key resolution ─────────────────────────────────\n if (lens.primaryKey) {\n if (!fieldNames.includes(lens.primaryKey)) {\n throw new Error(\n `lens \"${lensName}\" primaryKey \"${lens.primaryKey}\" does not exist in fields`,\n )\n }\n const pkInFields = fieldEntries.filter(([, f]) => f.primaryKey)\n const firstPk = pkInFields[0]\n if (firstPk && firstPk[0] !== lens.primaryKey) {\n throw new Error(\n `lens \"${lensName}\" has primaryKey \"${lens.primaryKey}\" but field \"${firstPk[0]}\" also has primaryKey: true`,\n )\n }\n } else {\n const primaryKeys = fieldEntries.filter(([, f]) => f.primaryKey)\n if (primaryKeys.length !== 1) {\n throw new Error(\n `lens \"${lensName}\" must have exactly one primary key field (found ${primaryKeys.length})`,\n )\n }\n }\n\n // ── Field validation (type-specific + mapping props) ──────\n for (const [fieldName, field] of fieldEntries) {\n if (field.type === 'enum' && (!field.values || field.values.length === 0)) {\n throw new Error(\n `field \"${fieldName}\" in lens \"${lensName}\" is type \"enum\" but has no values`,\n )\n }\n if (field.type === 'relation' && !field.to) {\n throw new Error(\n `field \"${fieldName}\" in lens \"${lensName}\" is type \"relation\" but has no \"to\"`,\n )\n }\n\n // Mapping validation — inline\n validateFieldMapping(lensName, fieldName, field)\n }\n\n // ── Sync interval validation ─────────────────────────────────\n if (lens.syncInterval) {\n const valid = ['1m', '5m', '15m', '30m', '1h', '6h', '24h']\n if (!valid.includes(lens.syncInterval)) {\n throw new Error(\n `lens \"${lensName}\" syncInterval \"${lens.syncInterval}\" is invalid (valid: ${valid.join(', ')})`,\n )\n }\n }\n\n // ── Rules validation ───────────────────────────────────────\n if (lens.rules) {\n const validAccessRuleKeys = new Set<string>([\n ...Object.keys(lens.facets ?? {}),\n 'query',\n ])\n\n for (const [key, rule] of Object.entries(lens.rules)) {\n // `stream` is a transport, not an access rule — it has its own shape.\n if (key === 'stream') {\n if (rule == null) continue\n if (typeof rule !== 'object' || Array.isArray(rule)) {\n throw new Error(\n `lens \"${lensName}\" rule \"stream\" must be an object`,\n )\n }\n const streamRule = rule as { enabled?: unknown; modes?: unknown; maxLiveSubscriptions?: unknown }\n if (streamRule.enabled !== undefined && typeof streamRule.enabled !== 'boolean') {\n throw new Error(\n `lens \"${lensName}\" rule \"stream.enabled\" must be a boolean`,\n )\n }\n if (streamRule.modes !== undefined) {\n if (!Array.isArray(streamRule.modes)) {\n throw new Error(\n `lens \"${lensName}\" rule \"stream.modes\" must be an array`,\n )\n }\n for (const mode of streamRule.modes) {\n if (mode !== 'chunked' && mode !== 'live') {\n throw new Error(\n `lens \"${lensName}\" rule \"stream.modes\" contains invalid mode \"${String(mode)}\" (valid: chunked, live)`,\n )\n }\n }\n }\n if (streamRule.maxLiveSubscriptions !== undefined) {\n if (\n typeof streamRule.maxLiveSubscriptions !== 'number' ||\n !Number.isFinite(streamRule.maxLiveSubscriptions) ||\n streamRule.maxLiveSubscriptions < 0\n ) {\n throw new Error(\n `lens \"${lensName}\" rule \"stream.maxLiveSubscriptions\" must be a non-negative number`,\n )\n }\n }\n continue\n }\n\n if (!validAccessRuleKeys.has(key)) {\n throw new Error(\n `lens \"${lensName}\" has rule for \"${key}\" but no matching facet (valid: ${[...validAccessRuleKeys].join(', ')}, stream)`,\n )\n }\n\n if (rule !== 'public' && rule !== 'authenticated' && typeof rule !== 'function') {\n throw new Error(\n `lens \"${lensName}\" rule \"${key}\" must be 'public', 'authenticated', or a function`,\n )\n }\n }\n }\n\n // ── Facet validation (directly against field keys) ─────────\n for (const [facetName, facet] of Object.entries(lens.facets)) {\n if (!FACET_NAMES.includes(facetName as never)) {\n throw new Error(\n `lens \"${lensName}\" has invalid facet name \"${facetName}\" (valid: ${FACET_NAMES.join(', ')})`,\n )\n }\n\n if ('fields' in facet && Array.isArray(facet.fields)) {\n for (const ref of facet.fields) {\n if (!fieldNames.includes(ref)) {\n throw new Error(\n `facet \"${facetName}\" in lens \"${lensName}\" references unknown field \"${ref}\"`,\n )\n }\n }\n }\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Field mapping validation\n// ---------------------------------------------------------------------------\n\nfunction validateFieldMapping(\n lensName: string,\n fieldName: string,\n field: FieldConfig,\n): void {\n if (field.from === undefined) return // identity mapping, nothing to validate\n\n if (Array.isArray(field.from)) {\n // Multi-source\n if (!field.merge) {\n throw new Error(\n `field \"${fieldName}\" in lens \"${lensName}\" has multiple sources but no merge strategy`,\n )\n }\n if (field.merge === 'concat' && field.separator === undefined) {\n throw new Error(\n `field \"${fieldName}\" in lens \"${lensName}\" uses merge \"concat\" but has no separator`,\n )\n }\n if (field.from.length < 2) {\n throw new Error(\n `field \"${fieldName}\" in lens \"${lensName}\" has multi-source from but fewer than 2 entries`,\n )\n }\n } else if (typeof field.from !== 'string') {\n throw new Error(\n `field \"${fieldName}\" in lens \"${lensName}\" has invalid from value (must be string or string[])`,\n )\n }\n\n if (field.transform) {\n validateTransformSpec(lensName, fieldName, field.transform)\n }\n}\n\nfunction validateTransformSpec(lensName: string, fieldName: string, spec: TransformSpec): void {\n const transforms = Array.isArray(spec) ? spec : [spec]\n for (const t of transforms) {\n if (!t || typeof t !== 'object' || !('type' in t)) {\n throw new Error(\n `field \"${fieldName}\" in lens \"${lensName}\" has invalid transform (missing type)`,\n )\n }\n if (!TRANSFORM_TYPES.includes(t.type as never)) {\n throw new Error(\n `field \"${fieldName}\" in lens \"${lensName}\" has unknown transform type \"${t.type}\"`,\n )\n }\n validateTransformFields(lensName, fieldName, t)\n }\n}\n\nfunction validateTransformFields(lensName: string, fieldName: string, t: BuiltinTransform): void {\n switch (t.type) {\n case 'split':\n if (typeof t.separator !== 'string') {\n throw new Error(\n `field \"${fieldName}\" in lens \"${lensName}\" transform \"split\" requires \"separator\"`,\n )\n }\n break\n case 'join':\n if (typeof t.separator !== 'string') {\n throw new Error(\n `field \"${fieldName}\" in lens \"${lensName}\" transform \"join\" requires \"separator\"`,\n )\n }\n break\n case 'truncate':\n if (typeof t.length !== 'number' || t.length < 0) {\n throw new Error(\n `field \"${fieldName}\" in lens \"${lensName}\" transform \"truncate\" requires positive \"length\"`,\n )\n }\n break\n case 'replace':\n if (typeof t.pattern !== 'string' || typeof t.replacement !== 'string') {\n throw new Error(\n `field \"${fieldName}\" in lens \"${lensName}\" transform \"replace\" requires \"pattern\" and \"replacement\"`,\n )\n }\n break\n case 'custom':\n if (typeof t.body !== 'string') {\n throw new Error(\n `field \"${fieldName}\" in lens \"${lensName}\" transform \"custom\" requires \"body\" string`,\n )\n }\n break\n case 'round':\n if (t.mode && !['round', 'ceil', 'floor'].includes(t.mode)) {\n throw new Error(\n `field \"${fieldName}\" in lens \"${lensName}\" transform \"round\" mode must be 'round', 'ceil', or 'floor'`,\n )\n }\n break\n }\n}\n","import type { FieldConfig } from './config.js'\n\n/**\n * Returns the list of source column names that the bridge needs to read.\n * Derives from `from` properties on fields, falling back to the output field name.\n */\nexport function resolveSourceColumns(fields: Record<string, FieldConfig>): string[] {\n const cols = new Set<string>()\n for (const [outputName, config] of Object.entries(fields)) {\n if (config.from) {\n if (Array.isArray(config.from)) {\n for (const src of config.from) cols.add(src)\n } else {\n cols.add(config.from)\n }\n } else {\n cols.add(outputName)\n }\n }\n return [...cols]\n}\n\nexport interface EmbeddingField {\n field: string\n weight: number\n}\n\n/**\n * Returns the output field names that are marked for embedding,\n * with their weights. Weight controls how many times a field's text\n * is repeated in the embedding input (higher = more relevance).\n */\nexport function resolveEmbeddingFields(fields: Record<string, FieldConfig>): EmbeddingField[] {\n const result: EmbeddingField[] = []\n for (const [name, config] of Object.entries(fields)) {\n if (!config.searchable) continue\n const weight =\n typeof config.searchable === 'object'\n ? (config.searchable.weight ?? 1)\n : 1\n result.push({ field: name, weight })\n }\n return result\n}\n\n/**\n * Convenience: returns just the field names (for APIs that only need names).\n */\nexport function resolveEmbeddingFieldNames(fields: Record<string, FieldConfig>): string[] {\n return resolveEmbeddingFields(fields).map((e) => e.field)\n}\n","import { createHash } from 'node:crypto'\n\n/**\n * Creates a deterministic SHA-256 hash of any JSON-serializable value.\n * Object keys are sorted recursively to ensure determinism regardless of insertion order.\n */\nexport function canonicalHash(obj: unknown): string {\n const json = JSON.stringify(sortKeys(obj)) ?? 'null'\n const digest = createHash('sha256').update(json).digest('hex')\n return `sha256:${digest}`\n}\n\nfunction sortKeys(value: unknown): unknown {\n if (value === null || value === undefined) return value\n if (Array.isArray(value)) return value.map(sortKeys)\n if (typeof value === 'object') {\n const sorted: Record<string, unknown> = {}\n for (const key of Object.keys(value as Record<string, unknown>).sort()) {\n sorted[key] = sortKeys((value as Record<string, unknown>)[key])\n }\n return sorted\n }\n return value\n}\n","import type { FieldType } from './constants.js'\n\nconst DB_TYPE_MAP: Record<string, FieldType> = {\n // Text\n varchar: 'text',\n text: 'text',\n char: 'text',\n 'character varying': 'text',\n character: 'text',\n citext: 'text',\n uuid: 'text',\n name: 'text',\n\n // Number\n integer: 'number',\n int: 'number',\n int4: 'number',\n bigint: 'number',\n int8: 'number',\n smallint: 'number',\n int2: 'number',\n numeric: 'number',\n decimal: 'number',\n real: 'number',\n float4: 'number',\n 'double precision': 'number',\n float8: 'number',\n serial: 'number',\n bigserial: 'number',\n\n // Boolean\n boolean: 'boolean',\n bool: 'boolean',\n\n // Date\n timestamp: 'date',\n 'timestamp with time zone': 'date',\n 'timestamp without time zone': 'date',\n timestamptz: 'date',\n date: 'date',\n time: 'date',\n 'time with time zone': 'date',\n 'time without time zone': 'date',\n timetz: 'date',\n\n // JSON\n json: 'json',\n jsonb: 'json',\n\n // Arrays → json\n 'ARRAY': 'json',\n}\n\n/**\n * Maps a raw database column type to a SemiLayer FieldType.\n * Falls back to 'text' for unknown types.\n */\nexport function mapDbTypeToFieldType(dbType: string): FieldType {\n const normalized = dbType.toLowerCase().trim()\n return DB_TYPE_MAP[normalized] ?? 'text'\n}\n","import type { SearchResult, SearchParams, QueryParams } from './models.js'\nimport type { SourceFeature } from './constants.js'\nimport type { LensRules, SyncInterval } from './config.js'\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nexport const STREAM_MODES = ['chunked', 'live'] as const\nexport type StreamMode = (typeof STREAM_MODES)[number]\n\nexport const LIVE_TAIL_MODES = ['push', 'polling', 'unsupported'] as const\nexport type LiveTailMode = (typeof LIVE_TAIL_MODES)[number]\n\n/** WebSocket op names sent from client to server in the `op` field. */\nexport const STREAM_OPS = [\n 'search.stream',\n 'query.stream',\n 'subscribe',\n 'observe',\n 'unsubscribe',\n] as const\nexport type StreamOp = (typeof STREAM_OPS)[number]\n\n/** Frame `type` values for both directions. */\nexport const STREAM_FRAME_TYPES = [\n 'row',\n 'done',\n 'error',\n 'event',\n 'ping',\n 'pong',\n] as const\nexport type StreamFrameType = (typeof STREAM_FRAME_TYPES)[number]\n\n/** Subscription event kinds (mirrors ingest write operations). */\nexport const STREAM_EVENT_KINDS = ['insert', 'update', 'delete'] as const\nexport type StreamEventKind = (typeof STREAM_EVENT_KINDS)[number]\n\n/** Error codes carried in `error` frames. */\nexport const STREAM_ERROR_CODES = [\n 'rate_limited',\n 'forbidden',\n 'bad_request',\n 'not_found',\n 'internal',\n] as const\nexport type StreamErrorCode = (typeof STREAM_ERROR_CODES)[number]\n\n/**\n * WebSocket close codes.\n *\n * Reserved codes (1xxx) follow RFC 6455. The 4xxx range is application-defined.\n */\nexport const STREAM_CLOSE_CODES = {\n /** Normal close — client called .close() or server finished. */\n normal: 1000,\n /** Server-side internal error. */\n internal: 1011,\n /** Auth failed during the upgrade handshake. */\n authFailed: 4401,\n /** Lens forbids streaming (rules.stream.enabled === false or modes[] excludes the requested mode). */\n forbidden: 4403,\n /** Rate-limited at handshake — over `concurrentWsConnections` for the org. */\n rateLimited: 4290,\n /** Mid-stream `wsRowsPerHour` quota exceeded. */\n quotaExceeded: 4291,\n} as const\n\nexport type StreamCloseCode = (typeof STREAM_CLOSE_CODES)[keyof typeof STREAM_CLOSE_CODES]\n\n// ---------------------------------------------------------------------------\n// Request shapes\n// ---------------------------------------------------------------------------\n\nexport interface StreamSearchParams extends SearchParams {\n /** Optional batch size hint — server may ignore. Default: 50. */\n batchSize?: number\n}\n\nexport interface StreamQueryParams extends QueryParams {\n /** Optional batch size hint — server may ignore. Default: 100. */\n batchSize?: number\n}\n\nexport interface SubscribeParams {\n /**\n * Optional in-process filter applied to events before they're emitted.\n * v0.1: simple equality only. Complex predicate pushdown is a v0.2 feature.\n */\n filter?: Record<string, unknown>\n}\n\n// ---------------------------------------------------------------------------\n// Op frame (client → server)\n// ---------------------------------------------------------------------------\n\n/**\n * One control frame sent from client to server. Multiple ops can ride a single\n * WebSocket connection — `id` is the multiplexing key the server echoes back\n * on response frames.\n */\nexport interface StreamOpFrame {\n id: string\n op: StreamOp\n params?: StreamSearchParams | StreamQueryParams | SubscribeParams | Record<string, unknown>\n}\n\n// ---------------------------------------------------------------------------\n// Response frames (server → client)\n// ---------------------------------------------------------------------------\n\nexport interface StreamMeta {\n count: number\n durationMs: number\n}\n\n/** A row from a chunked search/query stream. */\nexport interface StreamRowFrame<T = Record<string, unknown>> {\n id: string\n type: 'row'\n data: T\n}\n\n/** Terminal frame for a chunked op — no more rows will arrive for this id. */\nexport interface StreamDoneFrame {\n id: string\n type: 'done'\n meta: StreamMeta\n}\n\n/** Subscription event — pushed for each matching ingest write. */\nexport interface StreamEventFrame<T = Record<string, unknown>> {\n id: string\n type: 'event'\n kind: StreamEventKind\n record: T\n}\n\n/** Error attached to a specific op id (or global if id omitted). */\nexport interface StreamErrorFrame {\n id?: string\n type: 'error'\n code: StreamErrorCode\n message: string\n}\n\n/** Server heartbeat. Client must reply with a `pong` frame. */\nexport interface StreamPingFrame {\n type: 'ping'\n}\n\n/** Client heartbeat reply. */\nexport interface StreamPongFrame {\n type: 'pong'\n}\n\n/** Discriminated union of every frame the server can send. */\nexport type StreamFrame<T = Record<string, unknown>> =\n | StreamRowFrame<T>\n | StreamDoneFrame\n | StreamEventFrame<T>\n | StreamErrorFrame\n | StreamPingFrame\n | StreamPongFrame\n\n// ---------------------------------------------------------------------------\n// Public consumer types\n// ---------------------------------------------------------------------------\n\n/** What `BeamClient.subscribe()` yields per event. */\nexport interface StreamEvent<M = Record<string, unknown>> {\n kind: StreamEventKind\n record: M\n}\n\n/** What `BeamClient.streamSearch()` yields per row. */\nexport type StreamSearchRow<M = Record<string, unknown>> = SearchResult<M>\n\n// ---------------------------------------------------------------------------\n// Live tail mode derivation\n// ---------------------------------------------------------------------------\n\nexport interface DeriveLiveTailModeInput {\n /** Lens rules — if `rules.stream.modes` excludes `'live'`, the mode is `unsupported`. */\n rules?: LensRules\n /** Lens sync interval — presence implies polling-mode ingest. */\n syncInterval?: SyncInterval\n /** Source feature flags from the bridge. */\n bridgeFeatures?: SourceFeature[]\n /**\n * Whether at least one ingest key (ik_) exists for the lens. This is a\n * runtime fact (DB-derived) — callers must look it up before invoking.\n */\n acceptsIngestKey: boolean\n}\n\n/**\n * Is streaming enabled at all for this lens? Returns false only when the lens\n * config explicitly opts out via `rules.stream.enabled === false`. Default: true.\n *\n * This is the question the worker asks before populating the live tail buffer:\n * if a lens has streaming disabled, no one can subscribe, so there is no point\n * paying for the INSERT + NOTIFY.\n */\nexport function isStreamingEnabled(rules?: LensRules): boolean {\n return rules?.stream?.enabled !== false\n}\n\n/**\n * Is the `live` stream mode allowed for this lens? Returns false if streaming\n * is fully disabled OR if `rules.stream.modes` is set and excludes `'live'`.\n * Default: true.\n *\n * This is the gate for the worker's observation pathway. When false, the worker\n * skips the live tail buffer entirely — observation is microweight, but it is\n * not zero, and there is no value populating a buffer subscribers can never read.\n */\nexport function isLiveTailModeEnabled(rules?: LensRules): boolean {\n if (!isStreamingEnabled(rules)) return false\n const modes = rules?.stream?.modes\n if (modes && !modes.includes('live')) return false\n return true\n}\n\n/**\n * Derive the live-tail mode for a lens.\n *\n * Live tail rides our **own ingest write path**, not bridge-native CDC. So as\n * long as records are being written to `vectors.embeddings` by *some* ingest\n * pathway, live tail works:\n *\n * - `'push'` — the lens accepts `ik_` ingest webhooks → near-realtime fan-out\n * - `'polling'` — the bridge supports incremental sync and a syncInterval is set\n * → smooth-but-bursty fan-out at the polling cadence\n * - `'unsupported'` — neither path is available, OR `rules.stream.modes`\n * explicitly excludes `'live'`. The Console Explorer disables the live tab\n * and the `subscribe` op returns a forbidden close code.\n */\nexport function deriveLiveTailMode(input: DeriveLiveTailModeInput): LiveTailMode {\n // Explicit opt-out via lens rules\n const streamRules = input.rules?.stream\n if (streamRules?.enabled === false) return 'unsupported'\n if (streamRules?.modes && !streamRules.modes.includes('live')) return 'unsupported'\n\n // Push mode — ingest webhook key exists\n if (input.acceptsIngestKey) return 'push'\n\n // Polling mode — incremental sync configured\n if (input.syncInterval && input.bridgeFeatures?.includes('incremental')) {\n return 'polling'\n }\n\n return 'unsupported'\n}\n","import type { DeploymentMode } from './constants.js'\n\nexport function getDeploymentMode(): DeploymentMode {\n return (process.env.DEPLOYMENT_MODE as DeploymentMode) ?? 'enterprise'\n}\n\nexport function isSaasMode(): boolean {\n return getDeploymentMode() === 'saas'\n}\n"],"mappings":"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","names":[]}
package/dist/index.d.cts CHANGED
@@ -279,6 +279,33 @@ interface QueryResult<T> {
279
279
  }
280
280
 
281
281
  type BridgeRow = Record<string, unknown>;
282
+ interface BridgeFieldSchema {
283
+ key: string;
284
+ label: string;
285
+ /** Determines the input type rendered in the UI and the prompt type in CLI. */
286
+ type: 'string' | 'password' | 'number' | 'boolean';
287
+ required: boolean;
288
+ placeholder?: string;
289
+ default?: string | number | boolean;
290
+ /** Short hint shown below the input. */
291
+ hint?: string;
292
+ /** Primary fields render immediately; advanced fields collapse behind a toggle. */
293
+ group?: 'primary' | 'advanced';
294
+ }
295
+ interface BridgeManifest {
296
+ /** npm package name, e.g. '@semilayer/bridge-postgres' */
297
+ packageName: string;
298
+ /** Human-readable name shown in dropdowns, e.g. 'PostgreSQL' */
299
+ displayName: string;
300
+ /** Icon slug for bundled UI icons, e.g. 'postgres' */
301
+ icon?: string;
302
+ /** Whether the bridge also accepts a single connection URL instead of individual fields. */
303
+ supportsUrl: boolean;
304
+ /** Example URL shown when the user chooses URL mode. */
305
+ urlPlaceholder?: string;
306
+ /** Individual config fields, in display order. */
307
+ fields: BridgeFieldSchema[];
308
+ }
282
309
  interface ReadOptions {
283
310
  fields?: string[];
284
311
  cursor?: string;
@@ -314,7 +341,14 @@ interface Bridge {
314
341
  /** Introspect a target's schema (columns, types, PKs). Not all bridges support this. */
315
342
  introspectTarget?(target: string): Promise<TargetSchema>;
316
343
  }
317
- type BridgeConstructor = new (config: Record<string, unknown>) => Bridge;
344
+ /**
345
+ * A bridge constructor may optionally declare a static `manifest` describing
346
+ * its config shape. The console and CLI use this to render dynamic forms and
347
+ * prompts without any hardcoded per-bridge knowledge.
348
+ */
349
+ type BridgeConstructor = (new (config: Record<string, unknown>) => Bridge) & {
350
+ manifest?: BridgeManifest;
351
+ };
318
352
 
319
353
  /** Thin envelope — what the service enqueues */
320
354
  interface IngestJobPayload {
@@ -1093,6 +1127,11 @@ interface QuotaErrorResponse {
1093
1127
  upgradeUrl: string;
1094
1128
  }
1095
1129
 
1130
+ /** Response from `GET /v1/bridge-manifests` — public, no auth required. */
1131
+ interface BridgeManifestsResponse {
1132
+ bridges: BridgeManifest[];
1133
+ }
1134
+
1096
1135
  declare const STREAM_MODES: readonly ["chunked", "live"];
1097
1136
  type StreamMode = (typeof STREAM_MODES)[number];
1098
1137
  declare const LIVE_TAIL_MODES: readonly ["push", "polling", "unsupported"];
@@ -1254,4 +1293,4 @@ declare function isSaasMode(): boolean;
1254
1293
 
1255
1294
  declare function defineConfig(config: SemiLayerConfig): SemiLayerConfig;
1256
1295
 
1257
- export { type AccessRule, type AccessRuleResult, type AdminAssignUserBody, type AdminCashSnapshot, type AdminMrrSnapshot, type AdminOrgUsage, type AdminStripeEventRow, type AdminTopConsumerRow, type AdminTopConsumersResponse, type AdminUserDetail, type AdminUserListItem, type AdminUserListResponse, type AdminUserOrgMembership, type ApiKeyInfo, type AuditLogEntry, type AuthConfig, type AuthOrg, type AuthUser, type BannedIp, type BannedUser, type BannerData, type BillingCycleInfo, type BillingPlan, type BillingRedirectResponse, type BillingSnapshot, type Bridge, type BridgeConstructor, type BridgeRow, type BuiltinTransform, type CancelSubscriptionRequest, type CheckoutRequest, type ClaimCheck, type ClassifyFacetConfig, type ConfigExportResponse, type CreateEnvResponse, type CreateProjectResponse, DEPLOYMENT_MODES, type DailyMetrics, type DedupFacetConfig, type DeploymentMode, type DeriveLiveTailModeInput, type DriftLensInfo, type DriftResponse, type EmbeddingConfig, type EmbeddingField, type Environment, type EnvironmentAuthConfig, type EnvsResponse, FACET_NAMES, FIELD_TYPES, FUTURE_FACETS, type FacetConfig, type FacetName, type FailedJobInfo, type FeedbackDetail, type FeedbackItem, type FieldConfig, type FieldType, INGEST_JOB_TYPES, INGEST_STATUSES, type ISODateString, type InAppNotification, type IngestControl, type IngestErrorEntry, type IngestJobData, type IngestJobPayload, type IngestJobType, type IngestRun, type IngestStatus, type InviteInfo, type Invoice, type JwtClaims, type JwtConfig, KEY_PREFIXES, LENS_STATUSES, LIVE_TAIL_MODES, type Lens, type LensComparison, type LensConfig, type LensCreateResponse, type LensRuleKey, type LensRules, type LensStatus, type LensStatusInfo, type LiveTailMode, MERGE_STRATEGIES, type MeResponse, type Member, type MergeStrategy, type MetricPoint, type NewKeyPair, type NotificationPreferenceSummary, type OrderByClause, type Org, type OrgDetailResponse, type OrgListItem, type Page, type PendingInvite, type PendingInvitesResponse, type PlatformAdmin, type PlatformStats, type Project, type ProjectWithEnvs, type PushIngestJob, type PushLensSummary, type PushResponse, type QueryOptions, type QueryParams, type QueryResponse, type QueryResult, type QueueCounts, type QuotaErrorResponse, type RateLimitState, type ReadOptions, type ReadResult, SOURCE_FEATURES, STREAM_CLOSE_CODES, STREAM_ERROR_CODES, STREAM_EVENT_KINDS, STREAM_FRAME_TYPES, STREAM_MODES, STREAM_OPS, type SearchFacetConfig, type SearchParams, type SearchResponse, type SearchResult, type SemiLayerConfig, type SimilarFacetConfig, type SimilarParams, type SimilarResponse, type Source, type SourceConfig, type SourceFeature, type StatusEnvironment, type StatusResponse, type StreamCloseCode, type StreamDoneFrame, type StreamErrorCode, type StreamErrorFrame, type StreamEvent, type StreamEventFrame, type StreamEventKind, type StreamFrame, type StreamFrameType, type StreamMeta, type StreamMode, type StreamOp, type StreamOpFrame, type StreamPingFrame, type StreamPongFrame, type StreamQueryParams, type StreamRowFrame, type StreamRules, type StreamSearchParams, type StreamSearchRow, type SubscribeParams, type SyncInterval, type SystemHealth, TRANSFORM_TYPES, type TargetColumnInfo, type TargetSchema, type Tier, type TierFull, type TierOverride, type TierOverrideRequest, type TierSummary, type TiersResponse, type TransformSpec, type TransformType, type TransportMode, type TransportOptions, type UsageMetricSnapshot, type WhereClause, canonicalHash, defineConfig, deriveLiveTailMode, getDeploymentMode, isLiveTailModeEnabled, isSaasMode, isStreamingEnabled, mapDbTypeToFieldType, resolveEmbeddingFieldNames, resolveEmbeddingFields, resolveSourceColumns, validateConfig };
1296
+ export { type AccessRule, type AccessRuleResult, type AdminAssignUserBody, type AdminCashSnapshot, type AdminMrrSnapshot, type AdminOrgUsage, type AdminStripeEventRow, type AdminTopConsumerRow, type AdminTopConsumersResponse, type AdminUserDetail, type AdminUserListItem, type AdminUserListResponse, type AdminUserOrgMembership, type ApiKeyInfo, type AuditLogEntry, type AuthConfig, type AuthOrg, type AuthUser, type BannedIp, type BannedUser, type BannerData, type BillingCycleInfo, type BillingPlan, type BillingRedirectResponse, type BillingSnapshot, type Bridge, type BridgeConstructor, type BridgeFieldSchema, type BridgeManifest, type BridgeManifestsResponse, type BridgeRow, type BuiltinTransform, type CancelSubscriptionRequest, type CheckoutRequest, type ClaimCheck, type ClassifyFacetConfig, type ConfigExportResponse, type CreateEnvResponse, type CreateProjectResponse, DEPLOYMENT_MODES, type DailyMetrics, type DedupFacetConfig, type DeploymentMode, type DeriveLiveTailModeInput, type DriftLensInfo, type DriftResponse, type EmbeddingConfig, type EmbeddingField, type Environment, type EnvironmentAuthConfig, type EnvsResponse, FACET_NAMES, FIELD_TYPES, FUTURE_FACETS, type FacetConfig, type FacetName, type FailedJobInfo, type FeedbackDetail, type FeedbackItem, type FieldConfig, type FieldType, INGEST_JOB_TYPES, INGEST_STATUSES, type ISODateString, type InAppNotification, type IngestControl, type IngestErrorEntry, type IngestJobData, type IngestJobPayload, type IngestJobType, type IngestRun, type IngestStatus, type InviteInfo, type Invoice, type JwtClaims, type JwtConfig, KEY_PREFIXES, LENS_STATUSES, LIVE_TAIL_MODES, type Lens, type LensComparison, type LensConfig, type LensCreateResponse, type LensRuleKey, type LensRules, type LensStatus, type LensStatusInfo, type LiveTailMode, MERGE_STRATEGIES, type MeResponse, type Member, type MergeStrategy, type MetricPoint, type NewKeyPair, type NotificationPreferenceSummary, type OrderByClause, type Org, type OrgDetailResponse, type OrgListItem, type Page, type PendingInvite, type PendingInvitesResponse, type PlatformAdmin, type PlatformStats, type Project, type ProjectWithEnvs, type PushIngestJob, type PushLensSummary, type PushResponse, type QueryOptions, type QueryParams, type QueryResponse, type QueryResult, type QueueCounts, type QuotaErrorResponse, type RateLimitState, type ReadOptions, type ReadResult, SOURCE_FEATURES, STREAM_CLOSE_CODES, STREAM_ERROR_CODES, STREAM_EVENT_KINDS, STREAM_FRAME_TYPES, STREAM_MODES, STREAM_OPS, type SearchFacetConfig, type SearchParams, type SearchResponse, type SearchResult, type SemiLayerConfig, type SimilarFacetConfig, type SimilarParams, type SimilarResponse, type Source, type SourceConfig, type SourceFeature, type StatusEnvironment, type StatusResponse, type StreamCloseCode, type StreamDoneFrame, type StreamErrorCode, type StreamErrorFrame, type StreamEvent, type StreamEventFrame, type StreamEventKind, type StreamFrame, type StreamFrameType, type StreamMeta, type StreamMode, type StreamOp, type StreamOpFrame, type StreamPingFrame, type StreamPongFrame, type StreamQueryParams, type StreamRowFrame, type StreamRules, type StreamSearchParams, type StreamSearchRow, type SubscribeParams, type SyncInterval, type SystemHealth, TRANSFORM_TYPES, type TargetColumnInfo, type TargetSchema, type Tier, type TierFull, type TierOverride, type TierOverrideRequest, type TierSummary, type TiersResponse, type TransformSpec, type TransformType, type TransportMode, type TransportOptions, type UsageMetricSnapshot, type WhereClause, canonicalHash, defineConfig, deriveLiveTailMode, getDeploymentMode, isLiveTailModeEnabled, isSaasMode, isStreamingEnabled, mapDbTypeToFieldType, resolveEmbeddingFieldNames, resolveEmbeddingFields, resolveSourceColumns, validateConfig };
package/dist/index.d.ts CHANGED
@@ -279,6 +279,33 @@ interface QueryResult<T> {
279
279
  }
280
280
 
281
281
  type BridgeRow = Record<string, unknown>;
282
+ interface BridgeFieldSchema {
283
+ key: string;
284
+ label: string;
285
+ /** Determines the input type rendered in the UI and the prompt type in CLI. */
286
+ type: 'string' | 'password' | 'number' | 'boolean';
287
+ required: boolean;
288
+ placeholder?: string;
289
+ default?: string | number | boolean;
290
+ /** Short hint shown below the input. */
291
+ hint?: string;
292
+ /** Primary fields render immediately; advanced fields collapse behind a toggle. */
293
+ group?: 'primary' | 'advanced';
294
+ }
295
+ interface BridgeManifest {
296
+ /** npm package name, e.g. '@semilayer/bridge-postgres' */
297
+ packageName: string;
298
+ /** Human-readable name shown in dropdowns, e.g. 'PostgreSQL' */
299
+ displayName: string;
300
+ /** Icon slug for bundled UI icons, e.g. 'postgres' */
301
+ icon?: string;
302
+ /** Whether the bridge also accepts a single connection URL instead of individual fields. */
303
+ supportsUrl: boolean;
304
+ /** Example URL shown when the user chooses URL mode. */
305
+ urlPlaceholder?: string;
306
+ /** Individual config fields, in display order. */
307
+ fields: BridgeFieldSchema[];
308
+ }
282
309
  interface ReadOptions {
283
310
  fields?: string[];
284
311
  cursor?: string;
@@ -314,7 +341,14 @@ interface Bridge {
314
341
  /** Introspect a target's schema (columns, types, PKs). Not all bridges support this. */
315
342
  introspectTarget?(target: string): Promise<TargetSchema>;
316
343
  }
317
- type BridgeConstructor = new (config: Record<string, unknown>) => Bridge;
344
+ /**
345
+ * A bridge constructor may optionally declare a static `manifest` describing
346
+ * its config shape. The console and CLI use this to render dynamic forms and
347
+ * prompts without any hardcoded per-bridge knowledge.
348
+ */
349
+ type BridgeConstructor = (new (config: Record<string, unknown>) => Bridge) & {
350
+ manifest?: BridgeManifest;
351
+ };
318
352
 
319
353
  /** Thin envelope — what the service enqueues */
320
354
  interface IngestJobPayload {
@@ -1093,6 +1127,11 @@ interface QuotaErrorResponse {
1093
1127
  upgradeUrl: string;
1094
1128
  }
1095
1129
 
1130
+ /** Response from `GET /v1/bridge-manifests` — public, no auth required. */
1131
+ interface BridgeManifestsResponse {
1132
+ bridges: BridgeManifest[];
1133
+ }
1134
+
1096
1135
  declare const STREAM_MODES: readonly ["chunked", "live"];
1097
1136
  type StreamMode = (typeof STREAM_MODES)[number];
1098
1137
  declare const LIVE_TAIL_MODES: readonly ["push", "polling", "unsupported"];
@@ -1254,4 +1293,4 @@ declare function isSaasMode(): boolean;
1254
1293
 
1255
1294
  declare function defineConfig(config: SemiLayerConfig): SemiLayerConfig;
1256
1295
 
1257
- export { type AccessRule, type AccessRuleResult, type AdminAssignUserBody, type AdminCashSnapshot, type AdminMrrSnapshot, type AdminOrgUsage, type AdminStripeEventRow, type AdminTopConsumerRow, type AdminTopConsumersResponse, type AdminUserDetail, type AdminUserListItem, type AdminUserListResponse, type AdminUserOrgMembership, type ApiKeyInfo, type AuditLogEntry, type AuthConfig, type AuthOrg, type AuthUser, type BannedIp, type BannedUser, type BannerData, type BillingCycleInfo, type BillingPlan, type BillingRedirectResponse, type BillingSnapshot, type Bridge, type BridgeConstructor, type BridgeRow, type BuiltinTransform, type CancelSubscriptionRequest, type CheckoutRequest, type ClaimCheck, type ClassifyFacetConfig, type ConfigExportResponse, type CreateEnvResponse, type CreateProjectResponse, DEPLOYMENT_MODES, type DailyMetrics, type DedupFacetConfig, type DeploymentMode, type DeriveLiveTailModeInput, type DriftLensInfo, type DriftResponse, type EmbeddingConfig, type EmbeddingField, type Environment, type EnvironmentAuthConfig, type EnvsResponse, FACET_NAMES, FIELD_TYPES, FUTURE_FACETS, type FacetConfig, type FacetName, type FailedJobInfo, type FeedbackDetail, type FeedbackItem, type FieldConfig, type FieldType, INGEST_JOB_TYPES, INGEST_STATUSES, type ISODateString, type InAppNotification, type IngestControl, type IngestErrorEntry, type IngestJobData, type IngestJobPayload, type IngestJobType, type IngestRun, type IngestStatus, type InviteInfo, type Invoice, type JwtClaims, type JwtConfig, KEY_PREFIXES, LENS_STATUSES, LIVE_TAIL_MODES, type Lens, type LensComparison, type LensConfig, type LensCreateResponse, type LensRuleKey, type LensRules, type LensStatus, type LensStatusInfo, type LiveTailMode, MERGE_STRATEGIES, type MeResponse, type Member, type MergeStrategy, type MetricPoint, type NewKeyPair, type NotificationPreferenceSummary, type OrderByClause, type Org, type OrgDetailResponse, type OrgListItem, type Page, type PendingInvite, type PendingInvitesResponse, type PlatformAdmin, type PlatformStats, type Project, type ProjectWithEnvs, type PushIngestJob, type PushLensSummary, type PushResponse, type QueryOptions, type QueryParams, type QueryResponse, type QueryResult, type QueueCounts, type QuotaErrorResponse, type RateLimitState, type ReadOptions, type ReadResult, SOURCE_FEATURES, STREAM_CLOSE_CODES, STREAM_ERROR_CODES, STREAM_EVENT_KINDS, STREAM_FRAME_TYPES, STREAM_MODES, STREAM_OPS, type SearchFacetConfig, type SearchParams, type SearchResponse, type SearchResult, type SemiLayerConfig, type SimilarFacetConfig, type SimilarParams, type SimilarResponse, type Source, type SourceConfig, type SourceFeature, type StatusEnvironment, type StatusResponse, type StreamCloseCode, type StreamDoneFrame, type StreamErrorCode, type StreamErrorFrame, type StreamEvent, type StreamEventFrame, type StreamEventKind, type StreamFrame, type StreamFrameType, type StreamMeta, type StreamMode, type StreamOp, type StreamOpFrame, type StreamPingFrame, type StreamPongFrame, type StreamQueryParams, type StreamRowFrame, type StreamRules, type StreamSearchParams, type StreamSearchRow, type SubscribeParams, type SyncInterval, type SystemHealth, TRANSFORM_TYPES, type TargetColumnInfo, type TargetSchema, type Tier, type TierFull, type TierOverride, type TierOverrideRequest, type TierSummary, type TiersResponse, type TransformSpec, type TransformType, type TransportMode, type TransportOptions, type UsageMetricSnapshot, type WhereClause, canonicalHash, defineConfig, deriveLiveTailMode, getDeploymentMode, isLiveTailModeEnabled, isSaasMode, isStreamingEnabled, mapDbTypeToFieldType, resolveEmbeddingFieldNames, resolveEmbeddingFields, resolveSourceColumns, validateConfig };
1296
+ export { type AccessRule, type AccessRuleResult, type AdminAssignUserBody, type AdminCashSnapshot, type AdminMrrSnapshot, type AdminOrgUsage, type AdminStripeEventRow, type AdminTopConsumerRow, type AdminTopConsumersResponse, type AdminUserDetail, type AdminUserListItem, type AdminUserListResponse, type AdminUserOrgMembership, type ApiKeyInfo, type AuditLogEntry, type AuthConfig, type AuthOrg, type AuthUser, type BannedIp, type BannedUser, type BannerData, type BillingCycleInfo, type BillingPlan, type BillingRedirectResponse, type BillingSnapshot, type Bridge, type BridgeConstructor, type BridgeFieldSchema, type BridgeManifest, type BridgeManifestsResponse, type BridgeRow, type BuiltinTransform, type CancelSubscriptionRequest, type CheckoutRequest, type ClaimCheck, type ClassifyFacetConfig, type ConfigExportResponse, type CreateEnvResponse, type CreateProjectResponse, DEPLOYMENT_MODES, type DailyMetrics, type DedupFacetConfig, type DeploymentMode, type DeriveLiveTailModeInput, type DriftLensInfo, type DriftResponse, type EmbeddingConfig, type EmbeddingField, type Environment, type EnvironmentAuthConfig, type EnvsResponse, FACET_NAMES, FIELD_TYPES, FUTURE_FACETS, type FacetConfig, type FacetName, type FailedJobInfo, type FeedbackDetail, type FeedbackItem, type FieldConfig, type FieldType, INGEST_JOB_TYPES, INGEST_STATUSES, type ISODateString, type InAppNotification, type IngestControl, type IngestErrorEntry, type IngestJobData, type IngestJobPayload, type IngestJobType, type IngestRun, type IngestStatus, type InviteInfo, type Invoice, type JwtClaims, type JwtConfig, KEY_PREFIXES, LENS_STATUSES, LIVE_TAIL_MODES, type Lens, type LensComparison, type LensConfig, type LensCreateResponse, type LensRuleKey, type LensRules, type LensStatus, type LensStatusInfo, type LiveTailMode, MERGE_STRATEGIES, type MeResponse, type Member, type MergeStrategy, type MetricPoint, type NewKeyPair, type NotificationPreferenceSummary, type OrderByClause, type Org, type OrgDetailResponse, type OrgListItem, type Page, type PendingInvite, type PendingInvitesResponse, type PlatformAdmin, type PlatformStats, type Project, type ProjectWithEnvs, type PushIngestJob, type PushLensSummary, type PushResponse, type QueryOptions, type QueryParams, type QueryResponse, type QueryResult, type QueueCounts, type QuotaErrorResponse, type RateLimitState, type ReadOptions, type ReadResult, SOURCE_FEATURES, STREAM_CLOSE_CODES, STREAM_ERROR_CODES, STREAM_EVENT_KINDS, STREAM_FRAME_TYPES, STREAM_MODES, STREAM_OPS, type SearchFacetConfig, type SearchParams, type SearchResponse, type SearchResult, type SemiLayerConfig, type SimilarFacetConfig, type SimilarParams, type SimilarResponse, type Source, type SourceConfig, type SourceFeature, type StatusEnvironment, type StatusResponse, type StreamCloseCode, type StreamDoneFrame, type StreamErrorCode, type StreamErrorFrame, type StreamEvent, type StreamEventFrame, type StreamEventKind, type StreamFrame, type StreamFrameType, type StreamMeta, type StreamMode, type StreamOp, type StreamOpFrame, type StreamPingFrame, type StreamPongFrame, type StreamQueryParams, type StreamRowFrame, type StreamRules, type StreamSearchParams, type StreamSearchRow, type SubscribeParams, type SyncInterval, type SystemHealth, TRANSFORM_TYPES, type TargetColumnInfo, type TargetSchema, type Tier, type TierFull, type TierOverride, type TierOverrideRequest, type TierSummary, type TiersResponse, type TransformSpec, type TransformType, type TransportMode, type TransportOptions, type UsageMetricSnapshot, type WhereClause, canonicalHash, defineConfig, deriveLiveTailMode, getDeploymentMode, isLiveTailModeEnabled, isSaasMode, isStreamingEnabled, mapDbTypeToFieldType, resolveEmbeddingFieldNames, resolveEmbeddingFields, resolveSourceColumns, validateConfig };
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/constants.ts","../src/validate.ts","../src/mapping.ts","../src/hash.ts","../src/type-mapper.ts","../src/stream.ts","../src/deployment.ts","../src/index.ts"],"sourcesContent":["export const FACET_NAMES = [\n 'search',\n 'similar',\n] as const\n\nexport type FacetName = (typeof FACET_NAMES)[number]\n\n/** Facets planned for future releases. Config types exist but no runtime support yet. */\nexport const FUTURE_FACETS = ['dedup', 'classify'] as const\n\nexport const FIELD_TYPES = [\n 'text',\n 'number',\n 'boolean',\n 'date',\n 'json',\n 'enum',\n 'relation',\n] as const\n\nexport type FieldType = (typeof FIELD_TYPES)[number]\n\nexport const INGEST_JOB_TYPES = [\n 'full',\n 'incremental',\n 'delete',\n 'records',\n 'sync',\n] as const\n\nexport type IngestJobType = (typeof INGEST_JOB_TYPES)[number]\n\nexport const LENS_STATUSES = [\n 'paused',\n 'indexing',\n 'ready',\n 'error',\n] as const\n\nexport type LensStatus = (typeof LENS_STATUSES)[number]\n\nexport const INGEST_STATUSES = [\n 'queued',\n 'running',\n 'completed',\n 'failed',\n] as const\n\nexport type IngestStatus = (typeof INGEST_STATUSES)[number]\n\nexport const KEY_PREFIXES = {\n serviceKey: 'sk_',\n publishableKey: 'pk_',\n ingestKey: 'ik_',\n} as const\n\nexport const DEPLOYMENT_MODES = ['saas', 'enterprise'] as const\n\nexport type DeploymentMode = (typeof DEPLOYMENT_MODES)[number]\n\nexport const SOURCE_FEATURES = [\n 'incremental',\n 'change-tracking',\n 'streaming',\n] as const\n\nexport type SourceFeature = (typeof SOURCE_FEATURES)[number]\n\nexport const TRANSFORM_TYPES = [\n 'toString',\n 'toNumber',\n 'toBoolean',\n 'toDate',\n 'round',\n 'trim',\n 'lowercase',\n 'uppercase',\n 'default',\n 'split',\n 'join',\n 'truncate',\n 'replace',\n 'custom',\n] as const\n\nexport type TransformType = (typeof TRANSFORM_TYPES)[number]\n\nexport const MERGE_STRATEGIES = ['concat', 'coalesce'] as const\n\nexport type MergeStrategy = (typeof MERGE_STRATEGIES)[number]\n","import type {\n SemiLayerConfig,\n FieldConfig,\n BuiltinTransform,\n TransformSpec,\n} from './config.js'\nimport { FACET_NAMES, TRANSFORM_TYPES } from './constants.js'\n\nexport function validateConfig(config: SemiLayerConfig): void {\n if (!config.stack || typeof config.stack !== 'string') {\n throw new Error('config.stack must be a non-empty string')\n }\n\n const sourceNames = Object.keys(config.sources)\n if (sourceNames.length === 0) {\n throw new Error('config.sources must define at least one source')\n }\n\n const lensEntries = Object.entries(config.lenses)\n if (lensEntries.length === 0) {\n throw new Error('config.lenses must define at least one lens')\n }\n\n for (const [lensName, lens] of lensEntries) {\n if (!sourceNames.includes(lens.source)) {\n throw new Error(\n `lens \"${lensName}\" references unknown source \"${lens.source}\"`,\n )\n }\n\n const fieldEntries = Object.entries(lens.fields)\n const fieldNames = fieldEntries.map(([name]) => name)\n\n // ── Primary key resolution ─────────────────────────────────\n if (lens.primaryKey) {\n if (!fieldNames.includes(lens.primaryKey)) {\n throw new Error(\n `lens \"${lensName}\" primaryKey \"${lens.primaryKey}\" does not exist in fields`,\n )\n }\n const pkInFields = fieldEntries.filter(([, f]) => f.primaryKey)\n const firstPk = pkInFields[0]\n if (firstPk && firstPk[0] !== lens.primaryKey) {\n throw new Error(\n `lens \"${lensName}\" has primaryKey \"${lens.primaryKey}\" but field \"${firstPk[0]}\" also has primaryKey: true`,\n )\n }\n } else {\n const primaryKeys = fieldEntries.filter(([, f]) => f.primaryKey)\n if (primaryKeys.length !== 1) {\n throw new Error(\n `lens \"${lensName}\" must have exactly one primary key field (found ${primaryKeys.length})`,\n )\n }\n }\n\n // ── Field validation (type-specific + mapping props) ──────\n for (const [fieldName, field] of fieldEntries) {\n if (field.type === 'enum' && (!field.values || field.values.length === 0)) {\n throw new Error(\n `field \"${fieldName}\" in lens \"${lensName}\" is type \"enum\" but has no values`,\n )\n }\n if (field.type === 'relation' && !field.to) {\n throw new Error(\n `field \"${fieldName}\" in lens \"${lensName}\" is type \"relation\" but has no \"to\"`,\n )\n }\n\n // Mapping validation — inline\n validateFieldMapping(lensName, fieldName, field)\n }\n\n // ── Sync interval validation ─────────────────────────────────\n if (lens.syncInterval) {\n const valid = ['1m', '5m', '15m', '30m', '1h', '6h', '24h']\n if (!valid.includes(lens.syncInterval)) {\n throw new Error(\n `lens \"${lensName}\" syncInterval \"${lens.syncInterval}\" is invalid (valid: ${valid.join(', ')})`,\n )\n }\n }\n\n // ── Rules validation ───────────────────────────────────────\n if (lens.rules) {\n const validAccessRuleKeys = new Set<string>([\n ...Object.keys(lens.facets ?? {}),\n 'query',\n ])\n\n for (const [key, rule] of Object.entries(lens.rules)) {\n // `stream` is a transport, not an access rule — it has its own shape.\n if (key === 'stream') {\n if (rule == null) continue\n if (typeof rule !== 'object' || Array.isArray(rule)) {\n throw new Error(\n `lens \"${lensName}\" rule \"stream\" must be an object`,\n )\n }\n const streamRule = rule as { enabled?: unknown; modes?: unknown; maxLiveSubscriptions?: unknown }\n if (streamRule.enabled !== undefined && typeof streamRule.enabled !== 'boolean') {\n throw new Error(\n `lens \"${lensName}\" rule \"stream.enabled\" must be a boolean`,\n )\n }\n if (streamRule.modes !== undefined) {\n if (!Array.isArray(streamRule.modes)) {\n throw new Error(\n `lens \"${lensName}\" rule \"stream.modes\" must be an array`,\n )\n }\n for (const mode of streamRule.modes) {\n if (mode !== 'chunked' && mode !== 'live') {\n throw new Error(\n `lens \"${lensName}\" rule \"stream.modes\" contains invalid mode \"${String(mode)}\" (valid: chunked, live)`,\n )\n }\n }\n }\n if (streamRule.maxLiveSubscriptions !== undefined) {\n if (\n typeof streamRule.maxLiveSubscriptions !== 'number' ||\n !Number.isFinite(streamRule.maxLiveSubscriptions) ||\n streamRule.maxLiveSubscriptions < 0\n ) {\n throw new Error(\n `lens \"${lensName}\" rule \"stream.maxLiveSubscriptions\" must be a non-negative number`,\n )\n }\n }\n continue\n }\n\n if (!validAccessRuleKeys.has(key)) {\n throw new Error(\n `lens \"${lensName}\" has rule for \"${key}\" but no matching facet (valid: ${[...validAccessRuleKeys].join(', ')}, stream)`,\n )\n }\n\n if (rule !== 'public' && rule !== 'authenticated' && typeof rule !== 'function') {\n throw new Error(\n `lens \"${lensName}\" rule \"${key}\" must be 'public', 'authenticated', or a function`,\n )\n }\n }\n }\n\n // ── Facet validation (directly against field keys) ─────────\n for (const [facetName, facet] of Object.entries(lens.facets)) {\n if (!FACET_NAMES.includes(facetName as never)) {\n throw new Error(\n `lens \"${lensName}\" has invalid facet name \"${facetName}\" (valid: ${FACET_NAMES.join(', ')})`,\n )\n }\n\n if ('fields' in facet && Array.isArray(facet.fields)) {\n for (const ref of facet.fields) {\n if (!fieldNames.includes(ref)) {\n throw new Error(\n `facet \"${facetName}\" in lens \"${lensName}\" references unknown field \"${ref}\"`,\n )\n }\n }\n }\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Field mapping validation\n// ---------------------------------------------------------------------------\n\nfunction validateFieldMapping(\n lensName: string,\n fieldName: string,\n field: FieldConfig,\n): void {\n if (field.from === undefined) return // identity mapping, nothing to validate\n\n if (Array.isArray(field.from)) {\n // Multi-source\n if (!field.merge) {\n throw new Error(\n `field \"${fieldName}\" in lens \"${lensName}\" has multiple sources but no merge strategy`,\n )\n }\n if (field.merge === 'concat' && field.separator === undefined) {\n throw new Error(\n `field \"${fieldName}\" in lens \"${lensName}\" uses merge \"concat\" but has no separator`,\n )\n }\n if (field.from.length < 2) {\n throw new Error(\n `field \"${fieldName}\" in lens \"${lensName}\" has multi-source from but fewer than 2 entries`,\n )\n }\n } else if (typeof field.from !== 'string') {\n throw new Error(\n `field \"${fieldName}\" in lens \"${lensName}\" has invalid from value (must be string or string[])`,\n )\n }\n\n if (field.transform) {\n validateTransformSpec(lensName, fieldName, field.transform)\n }\n}\n\nfunction validateTransformSpec(lensName: string, fieldName: string, spec: TransformSpec): void {\n const transforms = Array.isArray(spec) ? spec : [spec]\n for (const t of transforms) {\n if (!t || typeof t !== 'object' || !('type' in t)) {\n throw new Error(\n `field \"${fieldName}\" in lens \"${lensName}\" has invalid transform (missing type)`,\n )\n }\n if (!TRANSFORM_TYPES.includes(t.type as never)) {\n throw new Error(\n `field \"${fieldName}\" in lens \"${lensName}\" has unknown transform type \"${t.type}\"`,\n )\n }\n validateTransformFields(lensName, fieldName, t)\n }\n}\n\nfunction validateTransformFields(lensName: string, fieldName: string, t: BuiltinTransform): void {\n switch (t.type) {\n case 'split':\n if (typeof t.separator !== 'string') {\n throw new Error(\n `field \"${fieldName}\" in lens \"${lensName}\" transform \"split\" requires \"separator\"`,\n )\n }\n break\n case 'join':\n if (typeof t.separator !== 'string') {\n throw new Error(\n `field \"${fieldName}\" in lens \"${lensName}\" transform \"join\" requires \"separator\"`,\n )\n }\n break\n case 'truncate':\n if (typeof t.length !== 'number' || t.length < 0) {\n throw new Error(\n `field \"${fieldName}\" in lens \"${lensName}\" transform \"truncate\" requires positive \"length\"`,\n )\n }\n break\n case 'replace':\n if (typeof t.pattern !== 'string' || typeof t.replacement !== 'string') {\n throw new Error(\n `field \"${fieldName}\" in lens \"${lensName}\" transform \"replace\" requires \"pattern\" and \"replacement\"`,\n )\n }\n break\n case 'custom':\n if (typeof t.body !== 'string') {\n throw new Error(\n `field \"${fieldName}\" in lens \"${lensName}\" transform \"custom\" requires \"body\" string`,\n )\n }\n break\n case 'round':\n if (t.mode && !['round', 'ceil', 'floor'].includes(t.mode)) {\n throw new Error(\n `field \"${fieldName}\" in lens \"${lensName}\" transform \"round\" mode must be 'round', 'ceil', or 'floor'`,\n )\n }\n break\n }\n}\n","import type { FieldConfig } from './config.js'\n\n/**\n * Returns the list of source column names that the bridge needs to read.\n * Derives from `from` properties on fields, falling back to the output field name.\n */\nexport function resolveSourceColumns(fields: Record<string, FieldConfig>): string[] {\n const cols = new Set<string>()\n for (const [outputName, config] of Object.entries(fields)) {\n if (config.from) {\n if (Array.isArray(config.from)) {\n for (const src of config.from) cols.add(src)\n } else {\n cols.add(config.from)\n }\n } else {\n cols.add(outputName)\n }\n }\n return [...cols]\n}\n\nexport interface EmbeddingField {\n field: string\n weight: number\n}\n\n/**\n * Returns the output field names that are marked for embedding,\n * with their weights. Weight controls how many times a field's text\n * is repeated in the embedding input (higher = more relevance).\n */\nexport function resolveEmbeddingFields(fields: Record<string, FieldConfig>): EmbeddingField[] {\n const result: EmbeddingField[] = []\n for (const [name, config] of Object.entries(fields)) {\n if (!config.searchable) continue\n const weight =\n typeof config.searchable === 'object'\n ? (config.searchable.weight ?? 1)\n : 1\n result.push({ field: name, weight })\n }\n return result\n}\n\n/**\n * Convenience: returns just the field names (for APIs that only need names).\n */\nexport function resolveEmbeddingFieldNames(fields: Record<string, FieldConfig>): string[] {\n return resolveEmbeddingFields(fields).map((e) => e.field)\n}\n","import { createHash } from 'node:crypto'\n\n/**\n * Creates a deterministic SHA-256 hash of any JSON-serializable value.\n * Object keys are sorted recursively to ensure determinism regardless of insertion order.\n */\nexport function canonicalHash(obj: unknown): string {\n const json = JSON.stringify(sortKeys(obj)) ?? 'null'\n const digest = createHash('sha256').update(json).digest('hex')\n return `sha256:${digest}`\n}\n\nfunction sortKeys(value: unknown): unknown {\n if (value === null || value === undefined) return value\n if (Array.isArray(value)) return value.map(sortKeys)\n if (typeof value === 'object') {\n const sorted: Record<string, unknown> = {}\n for (const key of Object.keys(value as Record<string, unknown>).sort()) {\n sorted[key] = sortKeys((value as Record<string, unknown>)[key])\n }\n return sorted\n }\n return value\n}\n","import type { FieldType } from './constants.js'\n\nconst DB_TYPE_MAP: Record<string, FieldType> = {\n // Text\n varchar: 'text',\n text: 'text',\n char: 'text',\n 'character varying': 'text',\n character: 'text',\n citext: 'text',\n uuid: 'text',\n name: 'text',\n\n // Number\n integer: 'number',\n int: 'number',\n int4: 'number',\n bigint: 'number',\n int8: 'number',\n smallint: 'number',\n int2: 'number',\n numeric: 'number',\n decimal: 'number',\n real: 'number',\n float4: 'number',\n 'double precision': 'number',\n float8: 'number',\n serial: 'number',\n bigserial: 'number',\n\n // Boolean\n boolean: 'boolean',\n bool: 'boolean',\n\n // Date\n timestamp: 'date',\n 'timestamp with time zone': 'date',\n 'timestamp without time zone': 'date',\n timestamptz: 'date',\n date: 'date',\n time: 'date',\n 'time with time zone': 'date',\n 'time without time zone': 'date',\n timetz: 'date',\n\n // JSON\n json: 'json',\n jsonb: 'json',\n\n // Arrays → json\n 'ARRAY': 'json',\n}\n\n/**\n * Maps a raw database column type to a SemiLayer FieldType.\n * Falls back to 'text' for unknown types.\n */\nexport function mapDbTypeToFieldType(dbType: string): FieldType {\n const normalized = dbType.toLowerCase().trim()\n return DB_TYPE_MAP[normalized] ?? 'text'\n}\n","import type { SearchResult, SearchParams, QueryParams } from './models.js'\nimport type { SourceFeature } from './constants.js'\nimport type { LensRules, SyncInterval } from './config.js'\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nexport const STREAM_MODES = ['chunked', 'live'] as const\nexport type StreamMode = (typeof STREAM_MODES)[number]\n\nexport const LIVE_TAIL_MODES = ['push', 'polling', 'unsupported'] as const\nexport type LiveTailMode = (typeof LIVE_TAIL_MODES)[number]\n\n/** WebSocket op names sent from client to server in the `op` field. */\nexport const STREAM_OPS = [\n 'search.stream',\n 'query.stream',\n 'subscribe',\n 'observe',\n 'unsubscribe',\n] as const\nexport type StreamOp = (typeof STREAM_OPS)[number]\n\n/** Frame `type` values for both directions. */\nexport const STREAM_FRAME_TYPES = [\n 'row',\n 'done',\n 'error',\n 'event',\n 'ping',\n 'pong',\n] as const\nexport type StreamFrameType = (typeof STREAM_FRAME_TYPES)[number]\n\n/** Subscription event kinds (mirrors ingest write operations). */\nexport const STREAM_EVENT_KINDS = ['insert', 'update', 'delete'] as const\nexport type StreamEventKind = (typeof STREAM_EVENT_KINDS)[number]\n\n/** Error codes carried in `error` frames. */\nexport const STREAM_ERROR_CODES = [\n 'rate_limited',\n 'forbidden',\n 'bad_request',\n 'not_found',\n 'internal',\n] as const\nexport type StreamErrorCode = (typeof STREAM_ERROR_CODES)[number]\n\n/**\n * WebSocket close codes.\n *\n * Reserved codes (1xxx) follow RFC 6455. The 4xxx range is application-defined.\n */\nexport const STREAM_CLOSE_CODES = {\n /** Normal close — client called .close() or server finished. */\n normal: 1000,\n /** Server-side internal error. */\n internal: 1011,\n /** Auth failed during the upgrade handshake. */\n authFailed: 4401,\n /** Lens forbids streaming (rules.stream.enabled === false or modes[] excludes the requested mode). */\n forbidden: 4403,\n /** Rate-limited at handshake — over `concurrentWsConnections` for the org. */\n rateLimited: 4290,\n /** Mid-stream `wsRowsPerHour` quota exceeded. */\n quotaExceeded: 4291,\n} as const\n\nexport type StreamCloseCode = (typeof STREAM_CLOSE_CODES)[keyof typeof STREAM_CLOSE_CODES]\n\n// ---------------------------------------------------------------------------\n// Request shapes\n// ---------------------------------------------------------------------------\n\nexport interface StreamSearchParams extends SearchParams {\n /** Optional batch size hint — server may ignore. Default: 50. */\n batchSize?: number\n}\n\nexport interface StreamQueryParams extends QueryParams {\n /** Optional batch size hint — server may ignore. Default: 100. */\n batchSize?: number\n}\n\nexport interface SubscribeParams {\n /**\n * Optional in-process filter applied to events before they're emitted.\n * v0.1: simple equality only. Complex predicate pushdown is a v0.2 feature.\n */\n filter?: Record<string, unknown>\n}\n\n// ---------------------------------------------------------------------------\n// Op frame (client → server)\n// ---------------------------------------------------------------------------\n\n/**\n * One control frame sent from client to server. Multiple ops can ride a single\n * WebSocket connection — `id` is the multiplexing key the server echoes back\n * on response frames.\n */\nexport interface StreamOpFrame {\n id: string\n op: StreamOp\n params?: StreamSearchParams | StreamQueryParams | SubscribeParams | Record<string, unknown>\n}\n\n// ---------------------------------------------------------------------------\n// Response frames (server → client)\n// ---------------------------------------------------------------------------\n\nexport interface StreamMeta {\n count: number\n durationMs: number\n}\n\n/** A row from a chunked search/query stream. */\nexport interface StreamRowFrame<T = Record<string, unknown>> {\n id: string\n type: 'row'\n data: T\n}\n\n/** Terminal frame for a chunked op — no more rows will arrive for this id. */\nexport interface StreamDoneFrame {\n id: string\n type: 'done'\n meta: StreamMeta\n}\n\n/** Subscription event — pushed for each matching ingest write. */\nexport interface StreamEventFrame<T = Record<string, unknown>> {\n id: string\n type: 'event'\n kind: StreamEventKind\n record: T\n}\n\n/** Error attached to a specific op id (or global if id omitted). */\nexport interface StreamErrorFrame {\n id?: string\n type: 'error'\n code: StreamErrorCode\n message: string\n}\n\n/** Server heartbeat. Client must reply with a `pong` frame. */\nexport interface StreamPingFrame {\n type: 'ping'\n}\n\n/** Client heartbeat reply. */\nexport interface StreamPongFrame {\n type: 'pong'\n}\n\n/** Discriminated union of every frame the server can send. */\nexport type StreamFrame<T = Record<string, unknown>> =\n | StreamRowFrame<T>\n | StreamDoneFrame\n | StreamEventFrame<T>\n | StreamErrorFrame\n | StreamPingFrame\n | StreamPongFrame\n\n// ---------------------------------------------------------------------------\n// Public consumer types\n// ---------------------------------------------------------------------------\n\n/** What `BeamClient.subscribe()` yields per event. */\nexport interface StreamEvent<M = Record<string, unknown>> {\n kind: StreamEventKind\n record: M\n}\n\n/** What `BeamClient.streamSearch()` yields per row. */\nexport type StreamSearchRow<M = Record<string, unknown>> = SearchResult<M>\n\n// ---------------------------------------------------------------------------\n// Live tail mode derivation\n// ---------------------------------------------------------------------------\n\nexport interface DeriveLiveTailModeInput {\n /** Lens rules — if `rules.stream.modes` excludes `'live'`, the mode is `unsupported`. */\n rules?: LensRules\n /** Lens sync interval — presence implies polling-mode ingest. */\n syncInterval?: SyncInterval\n /** Source feature flags from the bridge. */\n bridgeFeatures?: SourceFeature[]\n /**\n * Whether at least one ingest key (ik_) exists for the lens. This is a\n * runtime fact (DB-derived) — callers must look it up before invoking.\n */\n acceptsIngestKey: boolean\n}\n\n/**\n * Is streaming enabled at all for this lens? Returns false only when the lens\n * config explicitly opts out via `rules.stream.enabled === false`. Default: true.\n *\n * This is the question the worker asks before populating the live tail buffer:\n * if a lens has streaming disabled, no one can subscribe, so there is no point\n * paying for the INSERT + NOTIFY.\n */\nexport function isStreamingEnabled(rules?: LensRules): boolean {\n return rules?.stream?.enabled !== false\n}\n\n/**\n * Is the `live` stream mode allowed for this lens? Returns false if streaming\n * is fully disabled OR if `rules.stream.modes` is set and excludes `'live'`.\n * Default: true.\n *\n * This is the gate for the worker's observation pathway. When false, the worker\n * skips the live tail buffer entirely — observation is microweight, but it is\n * not zero, and there is no value populating a buffer subscribers can never read.\n */\nexport function isLiveTailModeEnabled(rules?: LensRules): boolean {\n if (!isStreamingEnabled(rules)) return false\n const modes = rules?.stream?.modes\n if (modes && !modes.includes('live')) return false\n return true\n}\n\n/**\n * Derive the live-tail mode for a lens.\n *\n * Live tail rides our **own ingest write path**, not bridge-native CDC. So as\n * long as records are being written to `vectors.embeddings` by *some* ingest\n * pathway, live tail works:\n *\n * - `'push'` — the lens accepts `ik_` ingest webhooks → near-realtime fan-out\n * - `'polling'` — the bridge supports incremental sync and a syncInterval is set\n * → smooth-but-bursty fan-out at the polling cadence\n * - `'unsupported'` — neither path is available, OR `rules.stream.modes`\n * explicitly excludes `'live'`. The Console Explorer disables the live tab\n * and the `subscribe` op returns a forbidden close code.\n */\nexport function deriveLiveTailMode(input: DeriveLiveTailModeInput): LiveTailMode {\n // Explicit opt-out via lens rules\n const streamRules = input.rules?.stream\n if (streamRules?.enabled === false) return 'unsupported'\n if (streamRules?.modes && !streamRules.modes.includes('live')) return 'unsupported'\n\n // Push mode — ingest webhook key exists\n if (input.acceptsIngestKey) return 'push'\n\n // Polling mode — incremental sync configured\n if (input.syncInterval && input.bridgeFeatures?.includes('incremental')) {\n return 'polling'\n }\n\n return 'unsupported'\n}\n","import type { DeploymentMode } from './constants.js'\n\nexport function getDeploymentMode(): DeploymentMode {\n return (process.env.DEPLOYMENT_MODE as DeploymentMode) ?? 'enterprise'\n}\n\nexport function isSaasMode(): boolean {\n return getDeploymentMode() === 'saas'\n}\n","import type { SemiLayerConfig } from './config.js'\nimport { validateConfig } from './validate.js'\n\nexport function defineConfig(config: SemiLayerConfig): SemiLayerConfig {\n validateConfig(config)\n return config\n}\n\nexport { validateConfig } from './validate.js'\n\nexport type {\n SemiLayerConfig,\n SourceConfig,\n LensConfig,\n FieldConfig,\n SearchFacetConfig,\n SimilarFacetConfig,\n DedupFacetConfig,\n ClassifyFacetConfig,\n FacetConfig,\n AuthConfig,\n JwtConfig,\n JwtClaims,\n AccessRule,\n AccessRuleResult,\n ClaimCheck,\n EnvironmentAuthConfig,\n LensRules,\n LensRuleKey,\n StreamRules,\n EmbeddingConfig,\n BuiltinTransform,\n TransformSpec,\n SyncInterval,\n} from './config.js'\n\nexport { resolveSourceColumns, resolveEmbeddingFields, resolveEmbeddingFieldNames } from './mapping.js'\nexport type { EmbeddingField } from './mapping.js'\nexport { canonicalHash } from './hash.js'\nexport { mapDbTypeToFieldType } from './type-mapper.js'\n\nexport type {\n WhereClause,\n OrderByClause,\n QueryOptions,\n QueryResult,\n} from './query.js'\n\nexport type {\n BridgeRow,\n ReadOptions,\n ReadResult,\n TargetColumnInfo,\n TargetSchema,\n Bridge,\n BridgeConstructor,\n} from './bridge.js'\n\nexport type {\n TransportMode,\n TransportOptions,\n} from './transport.js'\n\nexport {\n STREAM_MODES,\n LIVE_TAIL_MODES,\n STREAM_OPS,\n STREAM_FRAME_TYPES,\n STREAM_EVENT_KINDS,\n STREAM_ERROR_CODES,\n STREAM_CLOSE_CODES,\n deriveLiveTailMode,\n isStreamingEnabled,\n isLiveTailModeEnabled,\n} from './stream.js'\n\nexport type {\n StreamMode,\n LiveTailMode,\n StreamOp,\n StreamFrameType,\n StreamEventKind,\n StreamErrorCode,\n StreamCloseCode,\n StreamSearchParams,\n StreamQueryParams,\n SubscribeParams,\n StreamOpFrame,\n StreamMeta,\n StreamRowFrame,\n StreamDoneFrame,\n StreamEventFrame,\n StreamErrorFrame,\n StreamPingFrame,\n StreamPongFrame,\n StreamFrame,\n StreamEvent,\n StreamSearchRow,\n DeriveLiveTailModeInput,\n} from './stream.js'\n\nexport type {\n IngestJobPayload,\n IngestJobData,\n IngestControl,\n RateLimitState,\n IngestErrorEntry,\n LensStatusInfo,\n QueueCounts,\n FailedJobInfo,\n} from './ingest.js'\n\nexport {\n FACET_NAMES,\n FUTURE_FACETS,\n FIELD_TYPES,\n INGEST_JOB_TYPES,\n LENS_STATUSES,\n INGEST_STATUSES,\n KEY_PREFIXES,\n DEPLOYMENT_MODES,\n SOURCE_FEATURES,\n TRANSFORM_TYPES,\n MERGE_STRATEGIES,\n} from './constants.js'\n\nexport type {\n FacetName,\n FieldType,\n IngestJobType,\n IngestStatus,\n LensStatus,\n DeploymentMode,\n SourceFeature,\n TransformType,\n MergeStrategy,\n} from './constants.js'\n\nexport type {\n ISODateString,\n Org,\n Project,\n Environment,\n Source,\n Lens,\n ApiKeyInfo,\n Member,\n IngestRun,\n Page,\n Tier,\n TierOverride,\n TierSummary,\n AuthUser,\n AuthOrg,\n MeResponse,\n NewKeyPair,\n CreateProjectResponse,\n CreateEnvResponse,\n PushLensSummary,\n PushIngestJob,\n PushResponse,\n StatusEnvironment,\n StatusResponse,\n PlatformAdmin,\n AuditLogEntry,\n PlatformStats,\n SystemHealth,\n InAppNotification,\n NotificationPreferenceSummary,\n OrgListItem,\n OrgDetailResponse,\n ProjectWithEnvs,\n InviteInfo,\n DriftLensInfo,\n DriftResponse,\n EnvsResponse,\n ConfigExportResponse,\n LensComparison,\n LensCreateResponse,\n DailyMetrics,\n MetricPoint,\n BannerData,\n FeedbackItem,\n FeedbackDetail,\n BannedIp,\n BannedUser,\n SearchParams,\n SearchResult,\n SearchResponse,\n SimilarParams,\n SimilarResponse,\n QueryParams,\n QueryResponse,\n AdminUserListItem,\n AdminUserListResponse,\n AdminUserOrgMembership,\n AdminUserDetail,\n AdminAssignUserBody,\n PendingInvite,\n PendingInvitesResponse,\n // Step 12 — Billing\n BillingSnapshot,\n BillingPlan,\n UsageMetricSnapshot,\n BillingCycleInfo,\n Invoice,\n TierFull,\n TiersResponse,\n CheckoutRequest,\n BillingRedirectResponse,\n CancelSubscriptionRequest,\n AdminMrrSnapshot,\n AdminCashSnapshot,\n AdminStripeEventRow,\n AdminOrgUsage,\n AdminTopConsumerRow,\n AdminTopConsumersResponse,\n TierOverrideRequest,\n QuotaErrorResponse,\n} from './models.js'\n\nexport { getDeploymentMode, isSaasMode } from './deployment.js'\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/constants.ts","../src/validate.ts","../src/mapping.ts","../src/hash.ts","../src/type-mapper.ts","../src/stream.ts","../src/deployment.ts","../src/index.ts"],"sourcesContent":["export const FACET_NAMES = [\n 'search',\n 'similar',\n] as const\n\nexport type FacetName = (typeof FACET_NAMES)[number]\n\n/** Facets planned for future releases. Config types exist but no runtime support yet. */\nexport const FUTURE_FACETS = ['dedup', 'classify'] as const\n\nexport const FIELD_TYPES = [\n 'text',\n 'number',\n 'boolean',\n 'date',\n 'json',\n 'enum',\n 'relation',\n] as const\n\nexport type FieldType = (typeof FIELD_TYPES)[number]\n\nexport const INGEST_JOB_TYPES = [\n 'full',\n 'incremental',\n 'delete',\n 'records',\n 'sync',\n] as const\n\nexport type IngestJobType = (typeof INGEST_JOB_TYPES)[number]\n\nexport const LENS_STATUSES = [\n 'paused',\n 'indexing',\n 'ready',\n 'error',\n] as const\n\nexport type LensStatus = (typeof LENS_STATUSES)[number]\n\nexport const INGEST_STATUSES = [\n 'queued',\n 'running',\n 'completed',\n 'failed',\n] as const\n\nexport type IngestStatus = (typeof INGEST_STATUSES)[number]\n\nexport const KEY_PREFIXES = {\n serviceKey: 'sk_',\n publishableKey: 'pk_',\n ingestKey: 'ik_',\n} as const\n\nexport const DEPLOYMENT_MODES = ['saas', 'enterprise'] as const\n\nexport type DeploymentMode = (typeof DEPLOYMENT_MODES)[number]\n\nexport const SOURCE_FEATURES = [\n 'incremental',\n 'change-tracking',\n 'streaming',\n] as const\n\nexport type SourceFeature = (typeof SOURCE_FEATURES)[number]\n\nexport const TRANSFORM_TYPES = [\n 'toString',\n 'toNumber',\n 'toBoolean',\n 'toDate',\n 'round',\n 'trim',\n 'lowercase',\n 'uppercase',\n 'default',\n 'split',\n 'join',\n 'truncate',\n 'replace',\n 'custom',\n] as const\n\nexport type TransformType = (typeof TRANSFORM_TYPES)[number]\n\nexport const MERGE_STRATEGIES = ['concat', 'coalesce'] as const\n\nexport type MergeStrategy = (typeof MERGE_STRATEGIES)[number]\n","import type {\n SemiLayerConfig,\n FieldConfig,\n BuiltinTransform,\n TransformSpec,\n} from './config.js'\nimport { FACET_NAMES, TRANSFORM_TYPES } from './constants.js'\n\nexport function validateConfig(config: SemiLayerConfig): void {\n if (!config.stack || typeof config.stack !== 'string') {\n throw new Error('config.stack must be a non-empty string')\n }\n\n const sourceNames = Object.keys(config.sources)\n if (sourceNames.length === 0) {\n throw new Error('config.sources must define at least one source')\n }\n\n const lensEntries = Object.entries(config.lenses)\n if (lensEntries.length === 0) {\n throw new Error('config.lenses must define at least one lens')\n }\n\n for (const [lensName, lens] of lensEntries) {\n if (!sourceNames.includes(lens.source)) {\n throw new Error(\n `lens \"${lensName}\" references unknown source \"${lens.source}\"`,\n )\n }\n\n const fieldEntries = Object.entries(lens.fields)\n const fieldNames = fieldEntries.map(([name]) => name)\n\n // ── Primary key resolution ─────────────────────────────────\n if (lens.primaryKey) {\n if (!fieldNames.includes(lens.primaryKey)) {\n throw new Error(\n `lens \"${lensName}\" primaryKey \"${lens.primaryKey}\" does not exist in fields`,\n )\n }\n const pkInFields = fieldEntries.filter(([, f]) => f.primaryKey)\n const firstPk = pkInFields[0]\n if (firstPk && firstPk[0] !== lens.primaryKey) {\n throw new Error(\n `lens \"${lensName}\" has primaryKey \"${lens.primaryKey}\" but field \"${firstPk[0]}\" also has primaryKey: true`,\n )\n }\n } else {\n const primaryKeys = fieldEntries.filter(([, f]) => f.primaryKey)\n if (primaryKeys.length !== 1) {\n throw new Error(\n `lens \"${lensName}\" must have exactly one primary key field (found ${primaryKeys.length})`,\n )\n }\n }\n\n // ── Field validation (type-specific + mapping props) ──────\n for (const [fieldName, field] of fieldEntries) {\n if (field.type === 'enum' && (!field.values || field.values.length === 0)) {\n throw new Error(\n `field \"${fieldName}\" in lens \"${lensName}\" is type \"enum\" but has no values`,\n )\n }\n if (field.type === 'relation' && !field.to) {\n throw new Error(\n `field \"${fieldName}\" in lens \"${lensName}\" is type \"relation\" but has no \"to\"`,\n )\n }\n\n // Mapping validation — inline\n validateFieldMapping(lensName, fieldName, field)\n }\n\n // ── Sync interval validation ─────────────────────────────────\n if (lens.syncInterval) {\n const valid = ['1m', '5m', '15m', '30m', '1h', '6h', '24h']\n if (!valid.includes(lens.syncInterval)) {\n throw new Error(\n `lens \"${lensName}\" syncInterval \"${lens.syncInterval}\" is invalid (valid: ${valid.join(', ')})`,\n )\n }\n }\n\n // ── Rules validation ───────────────────────────────────────\n if (lens.rules) {\n const validAccessRuleKeys = new Set<string>([\n ...Object.keys(lens.facets ?? {}),\n 'query',\n ])\n\n for (const [key, rule] of Object.entries(lens.rules)) {\n // `stream` is a transport, not an access rule — it has its own shape.\n if (key === 'stream') {\n if (rule == null) continue\n if (typeof rule !== 'object' || Array.isArray(rule)) {\n throw new Error(\n `lens \"${lensName}\" rule \"stream\" must be an object`,\n )\n }\n const streamRule = rule as { enabled?: unknown; modes?: unknown; maxLiveSubscriptions?: unknown }\n if (streamRule.enabled !== undefined && typeof streamRule.enabled !== 'boolean') {\n throw new Error(\n `lens \"${lensName}\" rule \"stream.enabled\" must be a boolean`,\n )\n }\n if (streamRule.modes !== undefined) {\n if (!Array.isArray(streamRule.modes)) {\n throw new Error(\n `lens \"${lensName}\" rule \"stream.modes\" must be an array`,\n )\n }\n for (const mode of streamRule.modes) {\n if (mode !== 'chunked' && mode !== 'live') {\n throw new Error(\n `lens \"${lensName}\" rule \"stream.modes\" contains invalid mode \"${String(mode)}\" (valid: chunked, live)`,\n )\n }\n }\n }\n if (streamRule.maxLiveSubscriptions !== undefined) {\n if (\n typeof streamRule.maxLiveSubscriptions !== 'number' ||\n !Number.isFinite(streamRule.maxLiveSubscriptions) ||\n streamRule.maxLiveSubscriptions < 0\n ) {\n throw new Error(\n `lens \"${lensName}\" rule \"stream.maxLiveSubscriptions\" must be a non-negative number`,\n )\n }\n }\n continue\n }\n\n if (!validAccessRuleKeys.has(key)) {\n throw new Error(\n `lens \"${lensName}\" has rule for \"${key}\" but no matching facet (valid: ${[...validAccessRuleKeys].join(', ')}, stream)`,\n )\n }\n\n if (rule !== 'public' && rule !== 'authenticated' && typeof rule !== 'function') {\n throw new Error(\n `lens \"${lensName}\" rule \"${key}\" must be 'public', 'authenticated', or a function`,\n )\n }\n }\n }\n\n // ── Facet validation (directly against field keys) ─────────\n for (const [facetName, facet] of Object.entries(lens.facets)) {\n if (!FACET_NAMES.includes(facetName as never)) {\n throw new Error(\n `lens \"${lensName}\" has invalid facet name \"${facetName}\" (valid: ${FACET_NAMES.join(', ')})`,\n )\n }\n\n if ('fields' in facet && Array.isArray(facet.fields)) {\n for (const ref of facet.fields) {\n if (!fieldNames.includes(ref)) {\n throw new Error(\n `facet \"${facetName}\" in lens \"${lensName}\" references unknown field \"${ref}\"`,\n )\n }\n }\n }\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// Field mapping validation\n// ---------------------------------------------------------------------------\n\nfunction validateFieldMapping(\n lensName: string,\n fieldName: string,\n field: FieldConfig,\n): void {\n if (field.from === undefined) return // identity mapping, nothing to validate\n\n if (Array.isArray(field.from)) {\n // Multi-source\n if (!field.merge) {\n throw new Error(\n `field \"${fieldName}\" in lens \"${lensName}\" has multiple sources but no merge strategy`,\n )\n }\n if (field.merge === 'concat' && field.separator === undefined) {\n throw new Error(\n `field \"${fieldName}\" in lens \"${lensName}\" uses merge \"concat\" but has no separator`,\n )\n }\n if (field.from.length < 2) {\n throw new Error(\n `field \"${fieldName}\" in lens \"${lensName}\" has multi-source from but fewer than 2 entries`,\n )\n }\n } else if (typeof field.from !== 'string') {\n throw new Error(\n `field \"${fieldName}\" in lens \"${lensName}\" has invalid from value (must be string or string[])`,\n )\n }\n\n if (field.transform) {\n validateTransformSpec(lensName, fieldName, field.transform)\n }\n}\n\nfunction validateTransformSpec(lensName: string, fieldName: string, spec: TransformSpec): void {\n const transforms = Array.isArray(spec) ? spec : [spec]\n for (const t of transforms) {\n if (!t || typeof t !== 'object' || !('type' in t)) {\n throw new Error(\n `field \"${fieldName}\" in lens \"${lensName}\" has invalid transform (missing type)`,\n )\n }\n if (!TRANSFORM_TYPES.includes(t.type as never)) {\n throw new Error(\n `field \"${fieldName}\" in lens \"${lensName}\" has unknown transform type \"${t.type}\"`,\n )\n }\n validateTransformFields(lensName, fieldName, t)\n }\n}\n\nfunction validateTransformFields(lensName: string, fieldName: string, t: BuiltinTransform): void {\n switch (t.type) {\n case 'split':\n if (typeof t.separator !== 'string') {\n throw new Error(\n `field \"${fieldName}\" in lens \"${lensName}\" transform \"split\" requires \"separator\"`,\n )\n }\n break\n case 'join':\n if (typeof t.separator !== 'string') {\n throw new Error(\n `field \"${fieldName}\" in lens \"${lensName}\" transform \"join\" requires \"separator\"`,\n )\n }\n break\n case 'truncate':\n if (typeof t.length !== 'number' || t.length < 0) {\n throw new Error(\n `field \"${fieldName}\" in lens \"${lensName}\" transform \"truncate\" requires positive \"length\"`,\n )\n }\n break\n case 'replace':\n if (typeof t.pattern !== 'string' || typeof t.replacement !== 'string') {\n throw new Error(\n `field \"${fieldName}\" in lens \"${lensName}\" transform \"replace\" requires \"pattern\" and \"replacement\"`,\n )\n }\n break\n case 'custom':\n if (typeof t.body !== 'string') {\n throw new Error(\n `field \"${fieldName}\" in lens \"${lensName}\" transform \"custom\" requires \"body\" string`,\n )\n }\n break\n case 'round':\n if (t.mode && !['round', 'ceil', 'floor'].includes(t.mode)) {\n throw new Error(\n `field \"${fieldName}\" in lens \"${lensName}\" transform \"round\" mode must be 'round', 'ceil', or 'floor'`,\n )\n }\n break\n }\n}\n","import type { FieldConfig } from './config.js'\n\n/**\n * Returns the list of source column names that the bridge needs to read.\n * Derives from `from` properties on fields, falling back to the output field name.\n */\nexport function resolveSourceColumns(fields: Record<string, FieldConfig>): string[] {\n const cols = new Set<string>()\n for (const [outputName, config] of Object.entries(fields)) {\n if (config.from) {\n if (Array.isArray(config.from)) {\n for (const src of config.from) cols.add(src)\n } else {\n cols.add(config.from)\n }\n } else {\n cols.add(outputName)\n }\n }\n return [...cols]\n}\n\nexport interface EmbeddingField {\n field: string\n weight: number\n}\n\n/**\n * Returns the output field names that are marked for embedding,\n * with their weights. Weight controls how many times a field's text\n * is repeated in the embedding input (higher = more relevance).\n */\nexport function resolveEmbeddingFields(fields: Record<string, FieldConfig>): EmbeddingField[] {\n const result: EmbeddingField[] = []\n for (const [name, config] of Object.entries(fields)) {\n if (!config.searchable) continue\n const weight =\n typeof config.searchable === 'object'\n ? (config.searchable.weight ?? 1)\n : 1\n result.push({ field: name, weight })\n }\n return result\n}\n\n/**\n * Convenience: returns just the field names (for APIs that only need names).\n */\nexport function resolveEmbeddingFieldNames(fields: Record<string, FieldConfig>): string[] {\n return resolveEmbeddingFields(fields).map((e) => e.field)\n}\n","import { createHash } from 'node:crypto'\n\n/**\n * Creates a deterministic SHA-256 hash of any JSON-serializable value.\n * Object keys are sorted recursively to ensure determinism regardless of insertion order.\n */\nexport function canonicalHash(obj: unknown): string {\n const json = JSON.stringify(sortKeys(obj)) ?? 'null'\n const digest = createHash('sha256').update(json).digest('hex')\n return `sha256:${digest}`\n}\n\nfunction sortKeys(value: unknown): unknown {\n if (value === null || value === undefined) return value\n if (Array.isArray(value)) return value.map(sortKeys)\n if (typeof value === 'object') {\n const sorted: Record<string, unknown> = {}\n for (const key of Object.keys(value as Record<string, unknown>).sort()) {\n sorted[key] = sortKeys((value as Record<string, unknown>)[key])\n }\n return sorted\n }\n return value\n}\n","import type { FieldType } from './constants.js'\n\nconst DB_TYPE_MAP: Record<string, FieldType> = {\n // Text\n varchar: 'text',\n text: 'text',\n char: 'text',\n 'character varying': 'text',\n character: 'text',\n citext: 'text',\n uuid: 'text',\n name: 'text',\n\n // Number\n integer: 'number',\n int: 'number',\n int4: 'number',\n bigint: 'number',\n int8: 'number',\n smallint: 'number',\n int2: 'number',\n numeric: 'number',\n decimal: 'number',\n real: 'number',\n float4: 'number',\n 'double precision': 'number',\n float8: 'number',\n serial: 'number',\n bigserial: 'number',\n\n // Boolean\n boolean: 'boolean',\n bool: 'boolean',\n\n // Date\n timestamp: 'date',\n 'timestamp with time zone': 'date',\n 'timestamp without time zone': 'date',\n timestamptz: 'date',\n date: 'date',\n time: 'date',\n 'time with time zone': 'date',\n 'time without time zone': 'date',\n timetz: 'date',\n\n // JSON\n json: 'json',\n jsonb: 'json',\n\n // Arrays → json\n 'ARRAY': 'json',\n}\n\n/**\n * Maps a raw database column type to a SemiLayer FieldType.\n * Falls back to 'text' for unknown types.\n */\nexport function mapDbTypeToFieldType(dbType: string): FieldType {\n const normalized = dbType.toLowerCase().trim()\n return DB_TYPE_MAP[normalized] ?? 'text'\n}\n","import type { SearchResult, SearchParams, QueryParams } from './models.js'\nimport type { SourceFeature } from './constants.js'\nimport type { LensRules, SyncInterval } from './config.js'\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nexport const STREAM_MODES = ['chunked', 'live'] as const\nexport type StreamMode = (typeof STREAM_MODES)[number]\n\nexport const LIVE_TAIL_MODES = ['push', 'polling', 'unsupported'] as const\nexport type LiveTailMode = (typeof LIVE_TAIL_MODES)[number]\n\n/** WebSocket op names sent from client to server in the `op` field. */\nexport const STREAM_OPS = [\n 'search.stream',\n 'query.stream',\n 'subscribe',\n 'observe',\n 'unsubscribe',\n] as const\nexport type StreamOp = (typeof STREAM_OPS)[number]\n\n/** Frame `type` values for both directions. */\nexport const STREAM_FRAME_TYPES = [\n 'row',\n 'done',\n 'error',\n 'event',\n 'ping',\n 'pong',\n] as const\nexport type StreamFrameType = (typeof STREAM_FRAME_TYPES)[number]\n\n/** Subscription event kinds (mirrors ingest write operations). */\nexport const STREAM_EVENT_KINDS = ['insert', 'update', 'delete'] as const\nexport type StreamEventKind = (typeof STREAM_EVENT_KINDS)[number]\n\n/** Error codes carried in `error` frames. */\nexport const STREAM_ERROR_CODES = [\n 'rate_limited',\n 'forbidden',\n 'bad_request',\n 'not_found',\n 'internal',\n] as const\nexport type StreamErrorCode = (typeof STREAM_ERROR_CODES)[number]\n\n/**\n * WebSocket close codes.\n *\n * Reserved codes (1xxx) follow RFC 6455. The 4xxx range is application-defined.\n */\nexport const STREAM_CLOSE_CODES = {\n /** Normal close — client called .close() or server finished. */\n normal: 1000,\n /** Server-side internal error. */\n internal: 1011,\n /** Auth failed during the upgrade handshake. */\n authFailed: 4401,\n /** Lens forbids streaming (rules.stream.enabled === false or modes[] excludes the requested mode). */\n forbidden: 4403,\n /** Rate-limited at handshake — over `concurrentWsConnections` for the org. */\n rateLimited: 4290,\n /** Mid-stream `wsRowsPerHour` quota exceeded. */\n quotaExceeded: 4291,\n} as const\n\nexport type StreamCloseCode = (typeof STREAM_CLOSE_CODES)[keyof typeof STREAM_CLOSE_CODES]\n\n// ---------------------------------------------------------------------------\n// Request shapes\n// ---------------------------------------------------------------------------\n\nexport interface StreamSearchParams extends SearchParams {\n /** Optional batch size hint — server may ignore. Default: 50. */\n batchSize?: number\n}\n\nexport interface StreamQueryParams extends QueryParams {\n /** Optional batch size hint — server may ignore. Default: 100. */\n batchSize?: number\n}\n\nexport interface SubscribeParams {\n /**\n * Optional in-process filter applied to events before they're emitted.\n * v0.1: simple equality only. Complex predicate pushdown is a v0.2 feature.\n */\n filter?: Record<string, unknown>\n}\n\n// ---------------------------------------------------------------------------\n// Op frame (client → server)\n// ---------------------------------------------------------------------------\n\n/**\n * One control frame sent from client to server. Multiple ops can ride a single\n * WebSocket connection — `id` is the multiplexing key the server echoes back\n * on response frames.\n */\nexport interface StreamOpFrame {\n id: string\n op: StreamOp\n params?: StreamSearchParams | StreamQueryParams | SubscribeParams | Record<string, unknown>\n}\n\n// ---------------------------------------------------------------------------\n// Response frames (server → client)\n// ---------------------------------------------------------------------------\n\nexport interface StreamMeta {\n count: number\n durationMs: number\n}\n\n/** A row from a chunked search/query stream. */\nexport interface StreamRowFrame<T = Record<string, unknown>> {\n id: string\n type: 'row'\n data: T\n}\n\n/** Terminal frame for a chunked op — no more rows will arrive for this id. */\nexport interface StreamDoneFrame {\n id: string\n type: 'done'\n meta: StreamMeta\n}\n\n/** Subscription event — pushed for each matching ingest write. */\nexport interface StreamEventFrame<T = Record<string, unknown>> {\n id: string\n type: 'event'\n kind: StreamEventKind\n record: T\n}\n\n/** Error attached to a specific op id (or global if id omitted). */\nexport interface StreamErrorFrame {\n id?: string\n type: 'error'\n code: StreamErrorCode\n message: string\n}\n\n/** Server heartbeat. Client must reply with a `pong` frame. */\nexport interface StreamPingFrame {\n type: 'ping'\n}\n\n/** Client heartbeat reply. */\nexport interface StreamPongFrame {\n type: 'pong'\n}\n\n/** Discriminated union of every frame the server can send. */\nexport type StreamFrame<T = Record<string, unknown>> =\n | StreamRowFrame<T>\n | StreamDoneFrame\n | StreamEventFrame<T>\n | StreamErrorFrame\n | StreamPingFrame\n | StreamPongFrame\n\n// ---------------------------------------------------------------------------\n// Public consumer types\n// ---------------------------------------------------------------------------\n\n/** What `BeamClient.subscribe()` yields per event. */\nexport interface StreamEvent<M = Record<string, unknown>> {\n kind: StreamEventKind\n record: M\n}\n\n/** What `BeamClient.streamSearch()` yields per row. */\nexport type StreamSearchRow<M = Record<string, unknown>> = SearchResult<M>\n\n// ---------------------------------------------------------------------------\n// Live tail mode derivation\n// ---------------------------------------------------------------------------\n\nexport interface DeriveLiveTailModeInput {\n /** Lens rules — if `rules.stream.modes` excludes `'live'`, the mode is `unsupported`. */\n rules?: LensRules\n /** Lens sync interval — presence implies polling-mode ingest. */\n syncInterval?: SyncInterval\n /** Source feature flags from the bridge. */\n bridgeFeatures?: SourceFeature[]\n /**\n * Whether at least one ingest key (ik_) exists for the lens. This is a\n * runtime fact (DB-derived) — callers must look it up before invoking.\n */\n acceptsIngestKey: boolean\n}\n\n/**\n * Is streaming enabled at all for this lens? Returns false only when the lens\n * config explicitly opts out via `rules.stream.enabled === false`. Default: true.\n *\n * This is the question the worker asks before populating the live tail buffer:\n * if a lens has streaming disabled, no one can subscribe, so there is no point\n * paying for the INSERT + NOTIFY.\n */\nexport function isStreamingEnabled(rules?: LensRules): boolean {\n return rules?.stream?.enabled !== false\n}\n\n/**\n * Is the `live` stream mode allowed for this lens? Returns false if streaming\n * is fully disabled OR if `rules.stream.modes` is set and excludes `'live'`.\n * Default: true.\n *\n * This is the gate for the worker's observation pathway. When false, the worker\n * skips the live tail buffer entirely — observation is microweight, but it is\n * not zero, and there is no value populating a buffer subscribers can never read.\n */\nexport function isLiveTailModeEnabled(rules?: LensRules): boolean {\n if (!isStreamingEnabled(rules)) return false\n const modes = rules?.stream?.modes\n if (modes && !modes.includes('live')) return false\n return true\n}\n\n/**\n * Derive the live-tail mode for a lens.\n *\n * Live tail rides our **own ingest write path**, not bridge-native CDC. So as\n * long as records are being written to `vectors.embeddings` by *some* ingest\n * pathway, live tail works:\n *\n * - `'push'` — the lens accepts `ik_` ingest webhooks → near-realtime fan-out\n * - `'polling'` — the bridge supports incremental sync and a syncInterval is set\n * → smooth-but-bursty fan-out at the polling cadence\n * - `'unsupported'` — neither path is available, OR `rules.stream.modes`\n * explicitly excludes `'live'`. The Console Explorer disables the live tab\n * and the `subscribe` op returns a forbidden close code.\n */\nexport function deriveLiveTailMode(input: DeriveLiveTailModeInput): LiveTailMode {\n // Explicit opt-out via lens rules\n const streamRules = input.rules?.stream\n if (streamRules?.enabled === false) return 'unsupported'\n if (streamRules?.modes && !streamRules.modes.includes('live')) return 'unsupported'\n\n // Push mode — ingest webhook key exists\n if (input.acceptsIngestKey) return 'push'\n\n // Polling mode — incremental sync configured\n if (input.syncInterval && input.bridgeFeatures?.includes('incremental')) {\n return 'polling'\n }\n\n return 'unsupported'\n}\n","import type { DeploymentMode } from './constants.js'\n\nexport function getDeploymentMode(): DeploymentMode {\n return (process.env.DEPLOYMENT_MODE as DeploymentMode) ?? 'enterprise'\n}\n\nexport function isSaasMode(): boolean {\n return getDeploymentMode() === 'saas'\n}\n","import type { SemiLayerConfig } from './config.js'\nimport { validateConfig } from './validate.js'\n\nexport function defineConfig(config: SemiLayerConfig): SemiLayerConfig {\n validateConfig(config)\n return config\n}\n\nexport { validateConfig } from './validate.js'\n\nexport type {\n SemiLayerConfig,\n SourceConfig,\n LensConfig,\n FieldConfig,\n SearchFacetConfig,\n SimilarFacetConfig,\n DedupFacetConfig,\n ClassifyFacetConfig,\n FacetConfig,\n AuthConfig,\n JwtConfig,\n JwtClaims,\n AccessRule,\n AccessRuleResult,\n ClaimCheck,\n EnvironmentAuthConfig,\n LensRules,\n LensRuleKey,\n StreamRules,\n EmbeddingConfig,\n BuiltinTransform,\n TransformSpec,\n SyncInterval,\n} from './config.js'\n\nexport { resolveSourceColumns, resolveEmbeddingFields, resolveEmbeddingFieldNames } from './mapping.js'\nexport type { EmbeddingField } from './mapping.js'\nexport { canonicalHash } from './hash.js'\nexport { mapDbTypeToFieldType } from './type-mapper.js'\n\nexport type {\n WhereClause,\n OrderByClause,\n QueryOptions,\n QueryResult,\n} from './query.js'\n\nexport type {\n BridgeRow,\n ReadOptions,\n ReadResult,\n TargetColumnInfo,\n TargetSchema,\n Bridge,\n BridgeConstructor,\n BridgeFieldSchema,\n BridgeManifest,\n} from './bridge.js'\n\nexport type {\n TransportMode,\n TransportOptions,\n} from './transport.js'\n\nexport {\n STREAM_MODES,\n LIVE_TAIL_MODES,\n STREAM_OPS,\n STREAM_FRAME_TYPES,\n STREAM_EVENT_KINDS,\n STREAM_ERROR_CODES,\n STREAM_CLOSE_CODES,\n deriveLiveTailMode,\n isStreamingEnabled,\n isLiveTailModeEnabled,\n} from './stream.js'\n\nexport type {\n StreamMode,\n LiveTailMode,\n StreamOp,\n StreamFrameType,\n StreamEventKind,\n StreamErrorCode,\n StreamCloseCode,\n StreamSearchParams,\n StreamQueryParams,\n SubscribeParams,\n StreamOpFrame,\n StreamMeta,\n StreamRowFrame,\n StreamDoneFrame,\n StreamEventFrame,\n StreamErrorFrame,\n StreamPingFrame,\n StreamPongFrame,\n StreamFrame,\n StreamEvent,\n StreamSearchRow,\n DeriveLiveTailModeInput,\n} from './stream.js'\n\nexport type {\n IngestJobPayload,\n IngestJobData,\n IngestControl,\n RateLimitState,\n IngestErrorEntry,\n LensStatusInfo,\n QueueCounts,\n FailedJobInfo,\n} from './ingest.js'\n\nexport {\n FACET_NAMES,\n FUTURE_FACETS,\n FIELD_TYPES,\n INGEST_JOB_TYPES,\n LENS_STATUSES,\n INGEST_STATUSES,\n KEY_PREFIXES,\n DEPLOYMENT_MODES,\n SOURCE_FEATURES,\n TRANSFORM_TYPES,\n MERGE_STRATEGIES,\n} from './constants.js'\n\nexport type {\n FacetName,\n FieldType,\n IngestJobType,\n IngestStatus,\n LensStatus,\n DeploymentMode,\n SourceFeature,\n TransformType,\n MergeStrategy,\n} from './constants.js'\n\nexport type {\n ISODateString,\n Org,\n Project,\n Environment,\n Source,\n Lens,\n ApiKeyInfo,\n Member,\n IngestRun,\n Page,\n Tier,\n TierOverride,\n TierSummary,\n AuthUser,\n AuthOrg,\n MeResponse,\n NewKeyPair,\n CreateProjectResponse,\n CreateEnvResponse,\n PushLensSummary,\n PushIngestJob,\n PushResponse,\n StatusEnvironment,\n StatusResponse,\n PlatformAdmin,\n AuditLogEntry,\n PlatformStats,\n SystemHealth,\n InAppNotification,\n NotificationPreferenceSummary,\n OrgListItem,\n OrgDetailResponse,\n ProjectWithEnvs,\n InviteInfo,\n DriftLensInfo,\n DriftResponse,\n EnvsResponse,\n ConfigExportResponse,\n LensComparison,\n LensCreateResponse,\n DailyMetrics,\n MetricPoint,\n BannerData,\n FeedbackItem,\n FeedbackDetail,\n BannedIp,\n BannedUser,\n SearchParams,\n SearchResult,\n SearchResponse,\n SimilarParams,\n SimilarResponse,\n QueryParams,\n QueryResponse,\n AdminUserListItem,\n AdminUserListResponse,\n AdminUserOrgMembership,\n AdminUserDetail,\n AdminAssignUserBody,\n PendingInvite,\n PendingInvitesResponse,\n // Step 12 — Billing\n BillingSnapshot,\n BillingPlan,\n UsageMetricSnapshot,\n BillingCycleInfo,\n Invoice,\n TierFull,\n TiersResponse,\n CheckoutRequest,\n BillingRedirectResponse,\n CancelSubscriptionRequest,\n AdminMrrSnapshot,\n AdminCashSnapshot,\n AdminStripeEventRow,\n AdminOrgUsage,\n AdminTopConsumerRow,\n AdminTopConsumersResponse,\n TierOverrideRequest,\n QuotaErrorResponse,\n BridgeManifestsResponse,\n} from './models.js'\n\nexport { getDeploymentMode, isSaasMode } from './deployment.js'\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@semilayer/core",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "SemiLayer core — defineConfig, schema types, shared interfaces",
5
5
  "license": "MIT",
6
6
  "homepage": "https://semilayer.dev",
@@ -20,18 +20,18 @@
20
20
  "files": [
21
21
  "dist"
22
22
  ],
23
- "scripts": {
24
- "build": "tsup",
25
- "dev": "tsup --watch",
26
- "lint": "eslint src/",
27
- "typecheck": "tsc --noEmit",
28
- "test": "vitest run"
29
- },
30
23
  "dependencies": {},
31
24
  "devDependencies": {
32
25
  "@types/node": "^22.0.0",
33
26
  "tsup": "^8.0.0",
34
27
  "typescript": "^5.7.0",
35
28
  "vitest": "^3.0.0"
29
+ },
30
+ "scripts": {
31
+ "build": "tsup",
32
+ "dev": "tsup --watch",
33
+ "lint": "eslint src/",
34
+ "typecheck": "tsc --noEmit",
35
+ "test": "vitest run"
36
36
  }
37
- }
37
+ }