@dbsp/core 1.0.1 → 1.0.3

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/dist/index.d.ts CHANGED
@@ -2213,7 +2213,10 @@ declare class WindowBuilder {
2213
2213
  */
2214
2214
  as(alias: string): ExpressionSpec;
2215
2215
  /**
2216
- * Convert builder state to WindowIntent
2216
+ * Convert builder state to WindowIntent — produces the correct discriminated branch.
2217
+ * - ranking → RankingWindowIntent (no field)
2218
+ * - aggregate → AggregateWindowIntent (field required; COUNT uses '*' when omitted)
2219
+ * - offset → OffsetWindowIntent (field required)
2217
2220
  */
2218
2221
  private toWindowIntent;
2219
2222
  }
@@ -4872,6 +4875,12 @@ declare class UpsertBuilder<T = void> extends MutationBuilderBase<T, UpsertInten
4872
4875
  * const users = await orm.nql<{ name: string; email: string }>`users | select name, email`.all();
4873
4876
  * ```
4874
4877
  *
4878
+ * Each `${value}` interpolation is escaped into a safe NQL literal (string/number/boolean/null).
4879
+ * Untrusted string input cannot inject NQL structure because it is always quoted and
4880
+ * single-quotes inside are doubled (`''`). For dynamic structural fragments (table names,
4881
+ * column names, ORDER BY direction) use the builder API (`orm.select()`). See #134 for
4882
+ * upcoming `:param` binding and a `nqlRaw()` escape hatch.
4883
+ *
4875
4884
  * @module nql
4876
4885
  * @since DX-040
4877
4886
  */
@@ -4905,6 +4914,13 @@ type NqlTag = <T>(strings: TemplateStringsArray, ...values: unknown[]) => NqlBui
4905
4914
  /**
4906
4915
  * Create an NQL template tag function.
4907
4916
  *
4917
+ * Each `${value}` in the template is escaped into a safe NQL literal before parsing.
4918
+ * Supported interpolation types: `string`, `number`, `boolean`, `null`.
4919
+ * Untrusted string input is therefore safe from NQL-syntax injection — it is always
4920
+ * wrapped in single-quotes with embedded quotes doubled (`''`).
4921
+ * For dynamic structural fragments (table names, column names, ORDER BY direction)
4922
+ * use the builder API (`orm.select()`). See issue #134 for upcoming `:param` binding.
4923
+ *
4908
4924
  * @param schemaDefinition - Schema definition for validation
4909
4925
  * @param model - ModelIR for plan execution
4910
4926
  * @param adapter - Optional adapter for query execution
@@ -6957,7 +6973,7 @@ interface FeatureUsage {
6957
6973
  readonly detail: string;
6958
6974
  }
6959
6975
  /**
6960
- * Default feature checkers -- mirrors the 15 supportsDDL* flags that
6976
+ * Default feature checkers -- mirrors the 16 supportsDDL* flags that
6961
6977
  * negotiateFeatures() previously checked inline.
6962
6978
  *
6963
6979
  * Each checker preserves exactly the same detection logic (same guards,
@@ -7401,6 +7417,14 @@ declare function getLogger(): Logger;
7401
7417
  */
7402
7418
  declare function resetLogger(): void;
7403
7419
 
7420
+ /** Error thrown when behavior = 'error' and unsupported feature detected */
7421
+ declare class UnsupportedFeatureError extends Error {
7422
+ readonly feature: string;
7423
+ readonly adapter: string;
7424
+ readonly element: string;
7425
+ constructor(feature: string, adapter: string, element: string);
7426
+ }
7427
+
7404
7428
  interface NegotiationResult {
7405
7429
  readonly warnings: readonly FeatureWarning[];
7406
7430
  }
@@ -8120,4 +8144,4 @@ declare const assertIntentHasOrderBy: (result: AssertionQueryResult, expected: b
8120
8144
  */
8121
8145
  declare function runAssertions(blocks: AssertionBlock[], results: AssertionQueryResult[], queries: string[], hasDb?: boolean): AssertionSummary;
8122
8146
 
8123
- export { ASSERTION_TYPES, AdapterRequiredError, type AdjacencyOptions, type AfterMutationHook, type AfterQueryHook, type AggregateOptions, type AliasedColumn, type AliasedExprColumn, type AllColumns, AmbiguousPlanError, AmbiguousRelationError, type Assertion, type AssertionBlock, type AssertionOutcome, type AssertionQueryResult, type AssertionSummary, type AssertionType, BRAND, type BatchValuesOptions, type BatchValuesRef, type BeforeMutationHook, type BeforeQueryHook, type BrandKey, COLUMN_META, type CardinalityShorthand, CaseBuilder, type CaseValue, type ColumnDef, type ColumnMetaKey, ColumnNotFoundError, type ColumnRef, type ColumnSpec, type ColumnTypeToTS, CteBuilder, type CteDump, CteQueryBuilder, type CursorPaginateOptions, type CursorPaginatedResult, DEFAULT_CONVENTIONS, DEFAULT_FEATURE_CHECKERS, DUCKDB_CAPABILITIES, type DefaultFilters, type DefineModelOptions, DeleteBuilder, type DistinctField, type DumpMetaInput, type EdgeTableOptions, ErrorCode, type ErrorHookContext, Errors, ExecutionError, type ExprInput, ExpressionRef, type ExpressionSpec, type FeatureChecker, type FeatureUsage, type FilterOperators, type FilterValue, type FullTextSearchField, type FullTextSearchOptions, type GeneratedBelongsTo, type GeneratedColumn, type GeneratedColumnType, type GeneratedConventions, type GeneratedHasMany, type GeneratedHint, type GeneratedManyToMany, type GeneratedRelation, type GeneratedRelationKind, type GeneratedSchema, type GeneratedTable, type GetSchemaFromDbOptions, type HierarchyOptions, type HookErrorHandler, type HookManager, type HookPriority, type HydrateOptions, IRREGULAR_PLURALS, type IncludeOptions, type IncludeOptionsWithRecursive, type InferColumn, type InferColumnType, type InferColumnTypes, type InferDB, type InferDBFromSchema, type InferRefColumn, type InferRow, type InferRowType, type InferSchemaDB, type InferTableRow, type InferTables, type InferredRangeValue, InsertBuilder, IntentBuilder, type IntentBuilderState, type IntentSummary, InvalidOperationError, InvalidRelationDefinitionError, type JoinOptions, type JsonValue, type LightweightRelationsDef, type ListHierarchyOptions, type ListIndexOptions, type Logger, MSSQL_CAPABILITIES, MYSQL_CAPABILITIES, ModelIRImpl, type MutationDump, type MutationHookContext, type MutationOperation, NamingConventionMismatchError, type NegotiationResult, type NestedInclude, type SchemaColumnType$1 as NewSchemaColumnType, NotFoundError, type NqlBuilder, type NqlTag, type OnErrorHook, type OrderByInput, type OrderByRecord, type OrderBySpec, type OrmInstance, type OrmOf, type OrmOptions, type OrmOptionsWithAdapter, type OrmOptionsWithModel, type OrmOptionsWithSchema, POSTGRESQL_CAPABILITIES, type PaginateOptions, type PaginatedResult, type ParseError, type ParseResult, type ParsedRelationDef, type ParsedRelationKey, type PathOptions, type PrioritizedHook, type QueryAssertionResult, type QueryBuilder, type QueryHookContext, type QueryResultType, RELATION_META, type RangeType, RawCteQueryBuilder, type RecursiveDump, type RecursiveIncludeConfig, type RecursiveOptions, RecursiveShapeMismatchError, type RefDefinition, type RefOptions, type RelationHints, type RelationKey, type RelationMetaKey, RelationNotFoundError, type RelationObjectDef, type RelationRef, type RelationShorthand, type RelationTupleDef, type ResolvedSchema, ResolvedSchemaValidation, ResultHydrator, SQLITE_CAPABILITIES, SQL_RAW_MARKER, type Schema, type SchemaBelongsToRelation, type SchemaCardinality, type SchemaColumnDefinition, type SchemaColumnType, type SchemaConfigInput, type SchemaConstraints, type SchemaConventionsDefinition, type SchemaConversionResult, type SchemaDefinition, type SchemaDefinitionInput, SchemaValidationError$1 as SchemaError, type SchemaExtras, type SchemaFilterStrategy, type SchemaForeignKeyReference, type SchemaHasManyRelation, type SchemaHintDefinition, type SchemaHintsDefinition, type SchemaIndexDefinition, type SchemaIndexOptions, type SchemaIndexesDefinition, type SchemaManyToManyRelation, type SchemaOnDeleteAction, type SchemaOptions, type SchemaRelationDefinition, type SchemaRelationKind, type SchemaRelationsDefinition, type SchemaTableDefinition, type SchemaTableOptions, type SchemaTablesDefinition, SchemaValidationError, type SelectField, type SelfRefRoles, type SetOperationBuilder, type SimplifiedOrmOptions, type SqlRawExpression, type StreamOptions, SubqueryBuilder, SubqueryExpression, TABLE_META, type TableAssertionData, type TableDDL, type TableDef, type TableIndexes, type TableMetaKey, TableNotFoundError, type TableRef, type TraversalDirection, UnhandledTypeInDialect, UnknownDialectError, UnsafeOperationError, UnsupportedCapabilityError, UnsupportedStrategyError, UpdateBuilder, UpsertBuilder, type ValidatedResolvedSchema, type WhereFilter, WindowBuilder, aggOrderBy, and, any, array, arrayAgg, assertCapability, assertContains, assertDbColumnExists, assertDbOutput, assertDbRowsEquals, assertDbRowsMax, assertDbRowsMin, assertDbValueEquals, assertEquals, assertIntentHasGroupBy, assertIntentHasOrderBy, assertIntentHasWhere, assertIntentTable, assertIntentType, assertIntentWith, assertMatches, assertParamsEquals, assertParamsLength, assertParamsType, assertParamsValue, assertResolvedSchemaToGeneratedSchema, assertSQLColumn, assertSQLEquals, assertSQLJoin, assertSQLTable, assertSuccess, assertTypeSupported, batchValues, buildModelFromResolvedSchema, buildModelFromSchema, capitalize, caseWhen, cast, coalesce, col, composeAfterMutationHooks, composeAfterQueryHooks, composeBeforeMutationHooks, composeBeforeQueryHooks, composeOnErrorHooks, createDialectCapabilities, createHookManager, createNqlTag, createOrm, createPseudoColumnMetadata, createRawCteBuilder, createRecursiveMetadata, decapitalize, defaultLogger, defineModel, defineSchema, denseRank, detectForeignKeys, detectManyToMany, distinct, eq, every, exists, ref as exprRef, extendDialect, extractPseudoColumnKeywords, findClosestMatch, fn, fullTextSearch, getAvailableDialects, getDialectCapabilities, getLogger, getRelationKind, getSchemaFromDb, gt, gte, inArray, inSubquery, inferForeignKey, inferRelationsFromSchema, isAliasedColumn, isAllColumns, isBatchValuesRef, isBelongsTo, isCardinalityShorthand, isColumnRef, isDistinctField, isDistinctFrom, isExpressionSpec, isGeneratedSchema, isHasMany, isKnownDialect, isManyToMany, isNotNull, isNull, isOverallSuccess, isRecursiveIncludeOptions, isRecursiveRelation, isRef, isRelationObjectDef, isRelationRef, isRelationTupleDef, isResolvedSchema, isSelfReferential, isSqlRaw, isSubqueryExpression, isTableRef, isWhereIntent, lag, lead, like, literal, lt, lte, namedArg, negotiateFeatures, neq, none, normalizeSQL, normalizeSchema, not, notExists, objectToWhereIntent, op, or, outerRef, param, parseAssertionFile, parseRelationDef, parseRelationKey, pipeAfterMutationHooks, pipeAfterQueryHooks, pipeBeforeMutationHooks, pipeBeforeQueryHooks, pipeOnErrorHooks, plan, planRecursive, pluralize, rangeContainedBy, rangeContains, rangeOverlaps, rank, raw, rawExists, rawNotExists, ref$1 as ref, registerDialect, relationColumn, requiresDatabase, resetLogger, resolveQueryIndex, resolvedSchemaToGeneratedSchema, rowNumber, runAssertions, schema, schemaToModelIR, setLogger, silentLogger, singularize, some, sortByPriority, sql, star, stringAgg, subquery, supportsDDLGeneration, supportsExecution, supportsIntrospection, supportsRawSql, supportsStreaming, supportsTransactions, textScore, unary, validateAssertionBlocks, validateRecursiveInclude, validateRecursiveShape, wAvg, wCount, wMax, wMin, wSum, withPriority };
8147
+ export { ASSERTION_TYPES, AdapterRequiredError, type AdjacencyOptions, type AfterMutationHook, type AfterQueryHook, type AggregateOptions, type AliasedColumn, type AliasedExprColumn, type AllColumns, AmbiguousPlanError, AmbiguousRelationError, type Assertion, type AssertionBlock, type AssertionOutcome, type AssertionQueryResult, type AssertionSummary, type AssertionType, BRAND, type BatchValuesOptions, type BatchValuesRef, type BeforeMutationHook, type BeforeQueryHook, type BrandKey, COLUMN_META, type CardinalityShorthand, CaseBuilder, type CaseValue, type ColumnDef, type ColumnMetaKey, ColumnNotFoundError, type ColumnRef, type ColumnSpec, type ColumnTypeToTS, CteBuilder, type CteDump, CteQueryBuilder, type CursorPaginateOptions, type CursorPaginatedResult, DEFAULT_CONVENTIONS, DEFAULT_FEATURE_CHECKERS, DUCKDB_CAPABILITIES, type DefaultFilters, type DefineModelOptions, DeleteBuilder, type DistinctField, type DumpMetaInput, type EdgeTableOptions, ErrorCode, type ErrorHookContext, Errors, ExecutionError, type ExprInput, ExpressionRef, type ExpressionSpec, type FeatureChecker, type FeatureUsage, type FilterOperators, type FilterValue, type FullTextSearchField, type FullTextSearchOptions, type GeneratedBelongsTo, type GeneratedColumn, type GeneratedColumnType, type GeneratedConventions, type GeneratedHasMany, type GeneratedHint, type GeneratedManyToMany, type GeneratedRelation, type GeneratedRelationKind, type GeneratedSchema, type GeneratedTable, type GetSchemaFromDbOptions, type HierarchyOptions, type HookErrorHandler, type HookManager, type HookPriority, type HydrateOptions, IRREGULAR_PLURALS, type IncludeOptions, type IncludeOptionsWithRecursive, type InferColumn, type InferColumnType, type InferColumnTypes, type InferDB, type InferDBFromSchema, type InferRefColumn, type InferRow, type InferRowType, type InferSchemaDB, type InferTableRow, type InferTables, type InferredRangeValue, InsertBuilder, IntentBuilder, type IntentBuilderState, type IntentSummary, InvalidOperationError, InvalidRelationDefinitionError, type JoinOptions, type JsonValue, type LightweightRelationsDef, type ListHierarchyOptions, type ListIndexOptions, type Logger, MSSQL_CAPABILITIES, MYSQL_CAPABILITIES, ModelIRImpl, type MutationDump, type MutationHookContext, type MutationOperation, NamingConventionMismatchError, type NegotiationResult, type NestedInclude, type SchemaColumnType$1 as NewSchemaColumnType, NotFoundError, type NqlBuilder, type NqlTag, type OnErrorHook, type OrderByInput, type OrderByRecord, type OrderBySpec, type OrmInstance, type OrmOf, type OrmOptions, type OrmOptionsWithAdapter, type OrmOptionsWithModel, type OrmOptionsWithSchema, POSTGRESQL_CAPABILITIES, type PaginateOptions, type PaginatedResult, type ParseError, type ParseResult, type ParsedRelationDef, type ParsedRelationKey, type PathOptions, type PrioritizedHook, type QueryAssertionResult, type QueryBuilder, type QueryHookContext, type QueryResultType, RELATION_META, type RangeType, RawCteQueryBuilder, type RecursiveDump, type RecursiveIncludeConfig, type RecursiveOptions, RecursiveShapeMismatchError, type RefDefinition, type RefOptions, type RelationHints, type RelationKey, type RelationMetaKey, RelationNotFoundError, type RelationObjectDef, type RelationRef, type RelationShorthand, type RelationTupleDef, type ResolvedSchema, ResolvedSchemaValidation, ResultHydrator, SQLITE_CAPABILITIES, SQL_RAW_MARKER, type Schema, type SchemaBelongsToRelation, type SchemaCardinality, type SchemaColumnDefinition, type SchemaColumnType, type SchemaConfigInput, type SchemaConstraints, type SchemaConventionsDefinition, type SchemaConversionResult, type SchemaDefinition, type SchemaDefinitionInput, SchemaValidationError$1 as SchemaError, type SchemaExtras, type SchemaFilterStrategy, type SchemaForeignKeyReference, type SchemaHasManyRelation, type SchemaHintDefinition, type SchemaHintsDefinition, type SchemaIndexDefinition, type SchemaIndexOptions, type SchemaIndexesDefinition, type SchemaManyToManyRelation, type SchemaOnDeleteAction, type SchemaOptions, type SchemaRelationDefinition, type SchemaRelationKind, type SchemaRelationsDefinition, type SchemaTableDefinition, type SchemaTableOptions, type SchemaTablesDefinition, SchemaValidationError, type SelectField, type SelfRefRoles, type SetOperationBuilder, type SimplifiedOrmOptions, type SqlRawExpression, type StreamOptions, SubqueryBuilder, SubqueryExpression, TABLE_META, type TableAssertionData, type TableDDL, type TableDef, type TableIndexes, type TableMetaKey, TableNotFoundError, type TableRef, type TraversalDirection, UnhandledTypeInDialect, UnknownDialectError, UnsafeOperationError, UnsupportedCapabilityError, UnsupportedFeatureError, UnsupportedStrategyError, UpdateBuilder, UpsertBuilder, type ValidatedResolvedSchema, type WhereFilter, WindowBuilder, aggOrderBy, and, any, array, arrayAgg, assertCapability, assertContains, assertDbColumnExists, assertDbOutput, assertDbRowsEquals, assertDbRowsMax, assertDbRowsMin, assertDbValueEquals, assertEquals, assertIntentHasGroupBy, assertIntentHasOrderBy, assertIntentHasWhere, assertIntentTable, assertIntentType, assertIntentWith, assertMatches, assertParamsEquals, assertParamsLength, assertParamsType, assertParamsValue, assertResolvedSchemaToGeneratedSchema, assertSQLColumn, assertSQLEquals, assertSQLJoin, assertSQLTable, assertSuccess, assertTypeSupported, batchValues, buildModelFromResolvedSchema, buildModelFromSchema, capitalize, caseWhen, cast, coalesce, col, composeAfterMutationHooks, composeAfterQueryHooks, composeBeforeMutationHooks, composeBeforeQueryHooks, composeOnErrorHooks, createDialectCapabilities, createHookManager, createNqlTag, createOrm, createPseudoColumnMetadata, createRawCteBuilder, createRecursiveMetadata, decapitalize, defaultLogger, defineModel, defineSchema, denseRank, detectForeignKeys, detectManyToMany, distinct, eq, every, exists, ref as exprRef, extendDialect, extractPseudoColumnKeywords, findClosestMatch, fn, fullTextSearch, getAvailableDialects, getDialectCapabilities, getLogger, getRelationKind, getSchemaFromDb, gt, gte, inArray, inSubquery, inferForeignKey, inferRelationsFromSchema, isAliasedColumn, isAllColumns, isBatchValuesRef, isBelongsTo, isCardinalityShorthand, isColumnRef, isDistinctField, isDistinctFrom, isExpressionSpec, isGeneratedSchema, isHasMany, isKnownDialect, isManyToMany, isNotNull, isNull, isOverallSuccess, isRecursiveIncludeOptions, isRecursiveRelation, isRef, isRelationObjectDef, isRelationRef, isRelationTupleDef, isResolvedSchema, isSelfReferential, isSqlRaw, isSubqueryExpression, isTableRef, isWhereIntent, lag, lead, like, literal, lt, lte, namedArg, negotiateFeatures, neq, none, normalizeSQL, normalizeSchema, not, notExists, objectToWhereIntent, op, or, outerRef, param, parseAssertionFile, parseRelationDef, parseRelationKey, pipeAfterMutationHooks, pipeAfterQueryHooks, pipeBeforeMutationHooks, pipeBeforeQueryHooks, pipeOnErrorHooks, plan, planRecursive, pluralize, rangeContainedBy, rangeContains, rangeOverlaps, rank, raw, rawExists, rawNotExists, ref$1 as ref, registerDialect, relationColumn, requiresDatabase, resetLogger, resolveQueryIndex, resolvedSchemaToGeneratedSchema, rowNumber, runAssertions, schema, schemaToModelIR, setLogger, silentLogger, singularize, some, sortByPriority, sql, star, stringAgg, subquery, supportsDDLGeneration, supportsExecution, supportsIntrospection, supportsRawSql, supportsStreaming, supportsTransactions, textScore, unary, validateAssertionBlocks, validateRecursiveInclude, validateRecursiveShape, wAvg, wCount, wMax, wMin, wSum, withPriority };
package/dist/index.js CHANGED
@@ -3662,6 +3662,23 @@ var DEFAULT_FEATURE_CHECKERS = Object.freeze([
3662
3662
  }
3663
3663
  return usages;
3664
3664
  }
3665
+ },
3666
+ // -----------------------------------------------------------------------
3667
+ // Row-Level Security
3668
+ // -----------------------------------------------------------------------
3669
+ {
3670
+ capability: "supportsDDLRowLevelSecurity",
3671
+ feature: "rowLevelSecurity",
3672
+ detectUsage(model) {
3673
+ if (!model.tables) return [];
3674
+ const usages = [];
3675
+ for (const [tableName, table] of model.tables) {
3676
+ if (table.rlsEnabled || table.policies?.length) {
3677
+ usages.push({ table: tableName, detail: tableName });
3678
+ }
3679
+ }
3680
+ return usages;
3681
+ }
3665
3682
  }
3666
3683
  ]);
3667
3684
 
@@ -3772,11 +3789,12 @@ var WindowBuilder = class _WindowBuilder {
3772
3789
  };
3773
3790
  }
3774
3791
  /**
3775
- * Convert builder state to WindowIntent
3792
+ * Convert builder state to WindowIntent — produces the correct discriminated branch.
3793
+ * - ranking → RankingWindowIntent (no field)
3794
+ * - aggregate → AggregateWindowIntent (field required; COUNT uses '*' when omitted)
3795
+ * - offset → OffsetWindowIntent (field required)
3776
3796
  */
3777
3797
  toWindowIntent(alias) {
3778
- const fn2 = this.fnKind.fn;
3779
- const field = this.fnKind.type === "aggregate" || this.fnKind.type === "offset" ? this.fnKind.field : void 0;
3780
3798
  const over = {};
3781
3799
  if (this.partitions.length > 0) {
3782
3800
  over.partitionBy = this.partitions;
@@ -3784,16 +3802,31 @@ var WindowBuilder = class _WindowBuilder {
3784
3802
  if (this.orders.length > 0) {
3785
3803
  over.orderBy = this.orders;
3786
3804
  }
3787
- const intent = {
3805
+ if (this.fnKind.type === "ranking") {
3806
+ return {
3807
+ kind: "window",
3808
+ function: this.fnKind.fn,
3809
+ alias,
3810
+ over
3811
+ };
3812
+ }
3813
+ if (this.fnKind.type === "offset") {
3814
+ return {
3815
+ kind: "window",
3816
+ function: this.fnKind.fn,
3817
+ field: this.fnKind.field,
3818
+ alias,
3819
+ over
3820
+ };
3821
+ }
3822
+ const { field } = this.fnKind;
3823
+ return {
3788
3824
  kind: "window",
3789
- function: fn2,
3825
+ function: this.fnKind.fn,
3826
+ ...field !== void 0 && { field },
3790
3827
  alias,
3791
3828
  over
3792
3829
  };
3793
- if (field !== void 0) {
3794
- return { ...intent, field };
3795
- }
3796
- return intent;
3797
3830
  }
3798
3831
  };
3799
3832
  function rowNumber() {
@@ -3871,7 +3904,6 @@ function inSubquery(field, query) {
3871
3904
  return {
3872
3905
  kind: "in",
3873
3906
  field: getColumnName(field),
3874
- values: [],
3875
3907
  subquery: expr.toIntent()
3876
3908
  };
3877
3909
  }
@@ -4901,17 +4933,24 @@ var IntentBuilder = class _IntentBuilder {
4901
4933
  * DX-034: Now supports distinct flag for COUNT(DISTINCT field), etc.
4902
4934
  */
4903
4935
  addAggregate(func, field, options) {
4904
- const agg = { function: func };
4905
- if (field !== void 0) {
4906
- agg.field = field;
4907
- } else if (options?.field !== void 0) {
4908
- agg.field = options.field;
4909
- }
4910
- if (options?.as !== void 0) {
4911
- agg.as = options.as;
4912
- }
4913
- if (options?.distinct) {
4914
- agg.distinct = true;
4936
+ const resolvedField = field ?? options?.field;
4937
+ const as = options?.as;
4938
+ const distinct2 = options?.distinct ? true : void 0;
4939
+ let agg;
4940
+ if (func === "count") {
4941
+ agg = {
4942
+ function: "count",
4943
+ ...resolvedField !== void 0 && { field: resolvedField },
4944
+ ...as !== void 0 && { as },
4945
+ ...distinct2 !== void 0 && { distinct: distinct2 }
4946
+ };
4947
+ } else {
4948
+ agg = {
4949
+ function: func,
4950
+ field: resolvedField ?? "",
4951
+ ...as !== void 0 && { as },
4952
+ ...distinct2 !== void 0 && { distinct: distinct2 }
4953
+ };
4915
4954
  }
4916
4955
  this.state.aggregates.push(agg);
4917
4956
  }
@@ -5956,7 +5995,20 @@ var UpsertBuilder = class _UpsertBuilder extends MutationBuilderBase {
5956
5995
  };
5957
5996
 
5958
5997
  // src/dx/negotiate-features.ts
5959
- import { UnsupportedFeatureError } from "@dbsp/types";
5998
+ var UnsupportedFeatureError = class extends Error {
5999
+ constructor(feature, adapter, element) {
6000
+ super(
6001
+ `Unsupported feature "${feature}" on adapter "${adapter}" for "${element}"`
6002
+ );
6003
+ this.feature = feature;
6004
+ this.adapter = adapter;
6005
+ this.element = element;
6006
+ this.name = "UnsupportedFeatureError";
6007
+ }
6008
+ feature;
6009
+ adapter;
6010
+ element;
6011
+ };
5960
6012
  function resolveBehavior(feature, config) {
5961
6013
  if (typeof config === "string") return config;
5962
6014
  return config.overrides?.[feature] ?? config.default;
@@ -5992,11 +6044,49 @@ function negotiateFeatures(model, capabilities, behavior = "warning", checkers =
5992
6044
 
5993
6045
  // src/dx/nql.ts
5994
6046
  import { compile as nqlCompile } from "@dbsp/nql";
6047
+ function toNqlLiteral(value, index) {
6048
+ if (value === null) {
6049
+ return "null";
6050
+ }
6051
+ switch (typeof value) {
6052
+ case "boolean":
6053
+ return value ? "true" : "false";
6054
+ case "number": {
6055
+ if (!Number.isFinite(value)) {
6056
+ throw new Error(
6057
+ `nql\`...\`: cannot interpolate non-finite number (${value}) at position ${index}. Only finite numbers are supported. For dynamic NQL structure use the builder API (orm.select()). See issue #134.`
6058
+ );
6059
+ }
6060
+ const s = value < 0 ? `-${Math.abs(value)}` : String(value);
6061
+ if (/[eE]/.test(s)) {
6062
+ throw new Error(
6063
+ `nql\`...\`: number ${value} at position ${index} has no exact NQL numeric literal form (exponential notation). Convert it yourself or use the builder API (orm.select()). See issue #134.`
6064
+ );
6065
+ }
6066
+ return s;
6067
+ }
6068
+ case "string": {
6069
+ if (value.includes("\n") || value.includes("\r")) {
6070
+ throw new Error(
6071
+ `nql\`...\`: cannot interpolate a string containing a newline at position ${index}. NQL string literals do not support raw newline characters. For dynamic NQL structure use the builder API (orm.select()). See issue #134.`
6072
+ );
6073
+ }
6074
+ const escaped = value.replaceAll("'", "''");
6075
+ return `'${escaped}'`;
6076
+ }
6077
+ default: {
6078
+ const typeName = value === void 0 ? "undefined" : typeof value;
6079
+ throw new Error(
6080
+ `nql\`...\`: cannot interpolate value of type "${typeName}" at position ${index}. Only string, number, boolean, and null are supported; for dynamic NQL fragments use the builder API (orm.select()). See issue #134.`
6081
+ );
6082
+ }
6083
+ }
6084
+ }
5995
6085
  function createNqlTag(schemaDefinition, model, adapter, schemaName) {
5996
6086
  return function nql(strings, ...values) {
5997
6087
  let query = strings[0] ?? "";
5998
6088
  for (let i = 0; i < values.length; i++) {
5999
- query += String(values[i]) + (strings[i + 1] ?? "");
6089
+ query += toNqlLiteral(values[i], i) + (strings[i + 1] ?? "");
6000
6090
  }
6001
6091
  return new NqlBuilderImpl(
6002
6092
  query,
@@ -7172,27 +7262,25 @@ var QueryBuilderImpl = class _QueryBuilderImpl {
7172
7262
  }
7173
7263
  count(fieldOrOptions, as) {
7174
7264
  const builder = this.clone();
7175
- const agg = { function: "count" };
7265
+ let field;
7266
+ let alias = as;
7267
+ let distinct2;
7176
7268
  if (fieldOrOptions === void 0) {
7177
7269
  } else if (typeof fieldOrOptions === "string") {
7178
- agg.field = fieldOrOptions;
7179
- if (as !== void 0) {
7180
- agg.as = as;
7181
- }
7270
+ field = fieldOrOptions;
7182
7271
  } else if (isDistinctField(fieldOrOptions)) {
7183
- agg.field = fieldOrOptions.field;
7184
- agg.distinct = true;
7185
- if (as !== void 0) {
7186
- agg.as = as;
7187
- }
7272
+ field = fieldOrOptions.field;
7273
+ distinct2 = true;
7188
7274
  } else {
7189
- if (fieldOrOptions.field !== void 0) {
7190
- agg.field = fieldOrOptions.field;
7191
- }
7192
- if (fieldOrOptions.as !== void 0) {
7193
- agg.as = fieldOrOptions.as;
7194
- }
7195
- }
7275
+ field = fieldOrOptions.field;
7276
+ alias = fieldOrOptions.as ?? as;
7277
+ }
7278
+ const agg = {
7279
+ function: "count",
7280
+ ...field !== void 0 && { field },
7281
+ ...alias !== void 0 && { as: alias },
7282
+ ...distinct2 !== void 0 && { distinct: distinct2 }
7283
+ };
7196
7284
  builder.aggregates.push(agg);
7197
7285
  return builder;
7198
7286
  }
@@ -7200,13 +7288,12 @@ var QueryBuilderImpl = class _QueryBuilderImpl {
7200
7288
  const builder = this.clone();
7201
7289
  const isDistinct = isDistinctField(field);
7202
7290
  const fieldName = isDistinct ? field.field : field;
7203
- const agg = { function: "sum", field: fieldName };
7204
- if (isDistinct) {
7205
- agg.distinct = true;
7206
- }
7207
- if (as !== void 0) {
7208
- agg.as = as;
7209
- }
7291
+ const agg = {
7292
+ function: "sum",
7293
+ field: fieldName,
7294
+ ...isDistinct && { distinct: true },
7295
+ ...as !== void 0 && { as }
7296
+ };
7210
7297
  builder.aggregates.push(agg);
7211
7298
  return builder;
7212
7299
  }
@@ -7214,31 +7301,32 @@ var QueryBuilderImpl = class _QueryBuilderImpl {
7214
7301
  const builder = this.clone();
7215
7302
  const isDistinct = isDistinctField(field);
7216
7303
  const fieldName = isDistinct ? field.field : field;
7217
- const agg = { function: "avg", field: fieldName };
7218
- if (isDistinct) {
7219
- agg.distinct = true;
7220
- }
7221
- if (as !== void 0) {
7222
- agg.as = as;
7223
- }
7304
+ const agg = {
7305
+ function: "avg",
7306
+ field: fieldName,
7307
+ ...isDistinct && { distinct: true },
7308
+ ...as !== void 0 && { as }
7309
+ };
7224
7310
  builder.aggregates.push(agg);
7225
7311
  return builder;
7226
7312
  }
7227
7313
  min(field, as) {
7228
7314
  const builder = this.clone();
7229
- const agg = { function: "min", field };
7230
- if (as !== void 0) {
7231
- agg.as = as;
7232
- }
7315
+ const agg = {
7316
+ function: "min",
7317
+ field,
7318
+ ...as !== void 0 && { as }
7319
+ };
7233
7320
  builder.aggregates.push(agg);
7234
7321
  return builder;
7235
7322
  }
7236
7323
  max(field, as) {
7237
7324
  const builder = this.clone();
7238
- const agg = { function: "max", field };
7239
- if (as !== void 0) {
7240
- agg.as = as;
7241
- }
7325
+ const agg = {
7326
+ function: "max",
7327
+ field,
7328
+ ...as !== void 0 && { as }
7329
+ };
7242
7330
  builder.aggregates.push(agg);
7243
7331
  return builder;
7244
7332
  }
@@ -8243,7 +8331,9 @@ var QueryBuilderImpl = class _QueryBuilderImpl {
8243
8331
  const builder = new _QueryBuilderImpl(
8244
8332
  { ...this.ctx, ...ctxOverride },
8245
8333
  this.from,
8246
- { ...this.relationHints }
8334
+ {
8335
+ ...this.relationHints
8336
+ }
8247
8337
  );
8248
8338
  builder.includes.push(...this.includes);
8249
8339
  builder.recursiveIncludes.push(...this.recursiveIncludes);
@@ -9217,6 +9307,7 @@ function rangeOverlaps(fieldOrColumn, valueOrRange, rangeType = "daterange") {
9217
9307
  kind: "range",
9218
9308
  field: fieldOrColumn,
9219
9309
  operator: "overlaps",
9310
+ // Cast: non-array branch is RangeOperand (tuple path already returned above)
9220
9311
  value: valueOrRange
9221
9312
  };
9222
9313
  }
@@ -10026,7 +10117,8 @@ var FEATURE_TO_FLAG = {
10026
10117
  indexOpclass: "supportsDDLIndexOpclass",
10027
10118
  indexInclude: "supportsDDLIndexInclude",
10028
10119
  partialIndex: "supportsDDLPartialIndexes",
10029
- expressionIndex: "supportsDDLExpressionIndexes"
10120
+ expressionIndex: "supportsDDLExpressionIndexes",
10121
+ rowLevelSecurity: "supportsDDLRowLevelSecurity"
10030
10122
  };
10031
10123
  function createDialectCapabilities(overrides, options) {
10032
10124
  const result = {
@@ -11240,6 +11332,7 @@ export {
11240
11332
  UnknownDialectError,
11241
11333
  UnsafeOperationError,
11242
11334
  UnsupportedCapabilityError,
11335
+ UnsupportedFeatureError,
11243
11336
  UnsupportedStrategyError,
11244
11337
  UpdateBuilder,
11245
11338
  UpsertBuilder,