drizzle-cube 0.1.35 → 0.1.37

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.
@@ -145,7 +145,7 @@ declare interface CubeJoin {
145
145
  /** Target cube reference - lazy loaded to avoid circular dependencies */
146
146
  targetCube: Cube | (() => Cube);
147
147
  /** Semantic relationship - determines join behavior */
148
- relationship: 'belongsTo' | 'hasOne' | 'hasMany';
148
+ relationship: CubeRelationship;
149
149
  /** Array of join conditions - supports multi-column joins */
150
150
  on: Array<{
151
151
  /** Column from source cube */
@@ -157,6 +157,28 @@ declare interface CubeJoin {
157
157
  }>;
158
158
  /** Override default SQL join type (derived from relationship) */
159
159
  sqlJoinType?: 'inner' | 'left' | 'right' | 'full';
160
+ /**
161
+ * Many-to-many relationship configuration through a junction table
162
+ * Only used when relationship is 'belongsToMany'
163
+ */
164
+ through?: {
165
+ /** Junction/join table (Drizzle table reference) */
166
+ table: Table;
167
+ /** Join conditions from source cube to junction table */
168
+ sourceKey: Array<{
169
+ source: AnyColumn;
170
+ target: AnyColumn;
171
+ as?: (source: AnyColumn, target: AnyColumn) => SQL;
172
+ }>;
173
+ /** Join conditions from junction table to target cube */
174
+ targetKey: Array<{
175
+ source: AnyColumn;
176
+ target: AnyColumn;
177
+ as?: (source: AnyColumn, target: AnyColumn) => SQL;
178
+ }>;
179
+ /** Optional security context SQL for junction table */
180
+ securitySql?: (securityContext: SecurityContext) => SQL | SQL[];
181
+ };
160
182
  }
161
183
  export { CubeJoin }
162
184
  export { CubeJoin as SemanticJoin }
@@ -174,12 +196,17 @@ export declare interface CubeMetadata {
174
196
  relationships?: CubeRelationshipMetadata[];
175
197
  }
176
198
 
199
+ /**
200
+ * Relationship types supported by cube joins
201
+ */
202
+ export declare type CubeRelationship = 'belongsTo' | 'hasOne' | 'hasMany' | 'belongsToMany';
203
+
177
204
  /**
178
205
  * Cube relationship metadata for ERD visualization
179
206
  */
180
207
  export declare interface CubeRelationshipMetadata {
181
208
  targetCube: string;
182
- relationship: 'belongsTo' | 'hasOne' | 'hasMany';
209
+ relationship: 'belongsTo' | 'hasOne' | 'hasMany' | 'belongsToMany';
183
210
  joinFields: Array<{
184
211
  sourceField: string;
185
212
  targetField: string;
@@ -662,6 +689,15 @@ export declare interface QueryPlan {
662
689
  alias: string;
663
690
  joinType: 'inner' | 'left' | 'right' | 'full';
664
691
  joinCondition: SQL;
692
+ /** Junction table information for belongsToMany relationships */
693
+ junctionTable?: {
694
+ table: Table;
695
+ alias: string;
696
+ joinType: 'inner' | 'left' | 'right' | 'full';
697
+ joinCondition: SQL;
698
+ /** Optional security SQL function to apply to junction table */
699
+ securitySql?: (securityContext: SecurityContext) => SQL | SQL[];
700
+ };
665
701
  }>;
666
702
  /** Combined field selections across all cubes (built by QueryBuilder) */
667
703
  selections: Record<string, SQL | AnyColumn>;
@@ -707,7 +743,7 @@ export declare class QueryPlanner {
707
743
  /**
708
744
  * Create a unified query plan that works for both single and multi-cube queries
709
745
  */
710
- createQueryPlan(cubes: Map<string, Cube>, query: SemanticQuery, _ctx: QueryContext): QueryPlan;
746
+ createQueryPlan(cubes: Map<string, Cube>, query: SemanticQuery, ctx: QueryContext): QueryPlan;
711
747
  /**
712
748
  * Choose the primary cube based on query analysis
713
749
  * Uses a consistent strategy to avoid measure order dependencies
@@ -733,6 +769,8 @@ export declare class QueryPlanner {
733
769
  private findJoinPath;
734
770
  /**
735
771
  * Plan pre-aggregation CTEs for hasMany relationships to prevent fan-out
772
+ * Note: belongsToMany relationships handle fan-out differently through their junction table structure
773
+ * and don't require CTEs - the two-hop join with the junction table provides natural grouping
736
774
  */
737
775
  private planPreAggregationCTEs;
738
776
  /**