imodel 0.15.0 → 0.16.0

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/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * imodel v0.15.0
2
+ * imodel v0.16.0
3
3
  * (c) 2019-2026 undefined
4
4
  * @license undefined
5
5
  */
@@ -566,7 +566,7 @@ declare namespace SetValue {
566
566
  }
567
567
 
568
568
  interface VirtualTable<E extends object = object> {
569
- insert(environment: Environment<E>, conn: IConnection<E>, columns: Record<string, DBColumn>, data: object[], key: string[]): PromiseLike<any[]>;
569
+ insert(environment: Environment<E>, conn: IConnection<E>, columns: Record<string, DBColumn>, data: object[], key: string[], ignoreConflict?: boolean): PromiseLike<any[]>;
570
570
  upsert(environment: Environment<E>, conn: IConnection<E>, columns: Record<string, DBColumn>, data: object[], key: string[], conflict: true | string[], conflictSet?: Record<string, SetValue>): PromiseLike<any[]>;
571
571
  update(environment: Environment<E>, conn: IConnection<E>, columns: Record<string, DBColumn>, update: Record<string, SetValue>, where?: WhereValue[] | null): PromiseLike<number>;
572
572
  updateReturn(environment: Environment<E>, conn: IConnection<E>, returning: string[], columns: Record<string, DBColumn>, update: Record<string, SetValue>, where?: WhereValue[] | null): PromiseLike<any[]>;
@@ -574,6 +574,7 @@ interface VirtualTable<E extends object = object> {
574
574
  updateManyReturn(environment: Environment<E>, conn: IConnection<E>, fields: Fields<keyof FieldType>, update: Record<string, any>, pKeys: string[], setKeys: string[], list: Record<string, any>[], where: WhereValue[], returning: string[]): PromiseLike<any[]>;
575
575
  count(environment: Environment<E>, conn: IConnection<E>, columns: Record<string, DBColumn>, where: WhereValue[]): PromiseLike<number>;
576
576
  find(environment: Environment<E>, conn: IConnection<E>, columns: Record<string, DBColumn>, argv: FindArg): PromiseLike<any[]>;
577
+ select(environment: Environment<E>, conn: IConnection<E>, select: SelectItem[]): PromiseLike<any[]>;
577
578
  delete(environment: Environment<E>, conn: IConnection<E>, columns: Record<string, DBColumn>, where?: WhereValue[] | null): PromiseLike<number>;
578
579
  deleteReturn(environment: Environment<E>, conn: IConnection<E>, returning: string[], columns: Record<string, DBColumn>, where?: WhereValue[] | null): PromiseLike<any[]>;
579
580
  }
@@ -629,7 +630,7 @@ type MainFieldType = keyof FieldType | TableDefine | null;
629
630
  type ToFieldType<T> = T extends keyof FieldType ? FieldType[T] : unknown;
630
631
  type FieldSpecificValue = (string | number | bigint | boolean)[] | string | number | bigint | boolean | null | typeof now | typeof uuid;
631
632
  type FieldSpecific = FieldSpecificValue | {
632
- value: FieldSpecificValue;
633
+ value?: FieldSpecificValue;
633
634
  computed?(): PromiseLike<FieldSpecificValue> | FieldSpecificValue;
634
635
  };
635
636
  interface FieldDefineOption {
@@ -754,6 +755,7 @@ interface Options {
754
755
  limit?: number;
755
756
  update?: Record<string, SetValue>;
756
757
  alias?: string;
758
+ group?: string[];
757
759
  }
758
760
  interface Queryable<T extends Fields = Fields> extends TableDefine<T> {
759
761
  readonly options: Options;
@@ -787,6 +789,30 @@ interface FindArg {
787
789
  /** 最大返回数 */
788
790
  limit?: number;
789
791
  }
792
+ interface JOIN {
793
+ type?: 'INNER' | 'LEFT' | 'RIGHT' | 'FULL' | 'CROSS';
794
+ table: string;
795
+ columns: Record<string, DBColumn>;
796
+ alias?: string;
797
+ condition?: WhereValue[];
798
+ }
799
+ interface SelectItem {
800
+ distinct?: boolean;
801
+ select: [string, Select][];
802
+ table: string;
803
+ columns: Record<string, DBColumn>;
804
+ alias?: string;
805
+ /** 匹配信息 */
806
+ where: WhereValue[];
807
+ group: string[];
808
+ having: WhereValue[];
809
+ /** 排序配置,true 表示逆序 */
810
+ sort: [field: string, desc: boolean][];
811
+ /** 偏移量 */
812
+ offset?: number;
813
+ /** 最大返回数 */
814
+ limit?: number;
815
+ }
790
816
  type GetName = (table?: string) => string;
791
817
  interface DBColumn {
792
818
  type: string;
@@ -821,7 +847,7 @@ interface IConnection<E extends object = object> {
821
847
  */
822
848
  query(environment: Environment<E>, ...values: any): PromiseLike<any[]>;
823
849
  type(environment: Environment<E>, table: string): PromiseLike<TableType | null>;
824
- insert(environment: Environment<E>, table: string, columns: Record<string, DBColumn>, data: object[], key: string[]): PromiseLike<any[]>;
850
+ insert(environment: Environment<E>, table: string, columns: Record<string, DBColumn>, data: object[], key: string[], ignoreConflict?: boolean): PromiseLike<any[]>;
825
851
  upsert(environment: Environment<E>, table: string, columns: Record<string, DBColumn>, data: object[], key: string[], conflict: true | string[], conflictSet?: Record<string, SetValue>): PromiseLike<any[]>;
826
852
  update(environment: Environment<E>, table: string, columns: Record<string, DBColumn>, update: Record<string, SetValue>, where?: WhereValue[] | null): PromiseLike<number>;
827
853
  updateReturn(environment: Environment<E>, returning: string[], table: string, columns: Record<string, DBColumn>, update: Record<string, SetValue>, where?: WhereValue[] | null): PromiseLike<any[]>;
@@ -829,6 +855,7 @@ interface IConnection<E extends object = object> {
829
855
  updateManyReturn(environment: Environment<E>, table: string, columns: Record<string, DBColumn>, update: Record<string, any>, pKeys: string[], setKeys: string[], list: Record<string, any>[], where: WhereValue[], returning: string[]): PromiseLike<any[]>;
830
856
  count(environment: Environment<E>, table: string, columns: Record<string, DBColumn>, where?: WhereValue[] | null): PromiseLike<number>;
831
857
  find(environment: Environment<E>, table: string, columns: Record<string, DBColumn>, argv: FindArg): PromiseLike<any[]>;
858
+ select(environment: Environment<E>, select: SelectItem[]): PromiseLike<any[]>;
832
859
  delete(environment: Environment<E>, table: string, columns: Record<string, DBColumn>, where?: WhereValue[] | null): PromiseLike<number>;
833
860
  deleteReturn(environment: Environment<E>, returning: string[], table: string, columns: Record<string, DBColumn>, where?: WhereValue[] | null): PromiseLike<any[]>;
834
861
  createTable(environment: Environment<E>, table: string, columns: Column<any>[]): PromiseLike<number>;
@@ -1533,42 +1560,166 @@ declare class Connection<E extends {} = {}> {
1533
1560
  */
1534
1561
  destroyMany(queryable: Queryable, update?: Record<string, SetValue> | boolean): Promise<number>;
1535
1562
  /**
1536
- * @template {object | object[]} T
1563
+ * @template {object} T
1564
+ * @overload
1565
+ * @param {TableDefine} tableDefine
1566
+ * @param {T} data
1567
+ * @param {boolean} [ignoreConflict]
1568
+ * @returns {Promise<T>}
1569
+ */
1570
+ insert<T extends unknown>(tableDefine: TableDefine, data: T, ignoreConflict?: boolean | undefined): Promise<T>;
1571
+ /**
1572
+ * @template {object} T
1573
+ * @overload
1574
+ * @param {TableDefine} tableDefine
1575
+ * @param {T[]} data
1576
+ * @param {boolean} [ignoreConflict]
1577
+ * @returns {Promise<T[]>}
1578
+ */
1579
+ insert<T extends unknown>(tableDefine: TableDefine, data: T[], ignoreConflict?: boolean | undefined): Promise<T[]>;
1580
+ /**
1581
+ * @template {object} T
1582
+ * @overload
1537
1583
  * @param {TableDefine} tableDefine
1538
1584
  * @param {T} data
1539
1585
  * @param {string[]} [keys]
1540
- * @returns {Promise<T extends object[] ? object[] : object>}
1586
+ * @param {boolean} [ignoreConflict]
1587
+ * @returns {Promise<T>}
1588
+ */
1589
+ insert<T extends unknown>(tableDefine: TableDefine, data: T, keys?: string[] | undefined, ignoreConflict?: boolean | undefined): Promise<T>;
1590
+ /**
1591
+ * @template {object} T
1592
+ * @overload
1593
+ * @param {TableDefine} tableDefine
1594
+ * @param {T[]} data
1595
+ * @param {string[]} [keys]
1596
+ * @param {boolean} [ignoreConflict]
1597
+ * @returns {Promise<T[]>}
1598
+ */
1599
+ insert<T extends unknown>(tableDefine: TableDefine, data: T[], keys?: string[] | undefined, ignoreConflict?: boolean | undefined): Promise<T[]>;
1600
+ /**
1601
+ * @template {object} T
1602
+ * @overload
1603
+ * @param {TableDefine} tableDefine
1604
+ * @param {T} data
1605
+ * @param {string[] | boolean} [keys]
1606
+ * @param {boolean} [ignoreConflict]
1607
+ * @returns {Promise<T>}
1608
+ */
1609
+ insert<T extends unknown>(tableDefine: TableDefine, data: T, keys?: boolean | string[] | undefined, ignoreConflict?: boolean | undefined): Promise<T>;
1610
+ /**
1611
+ * @template {object} T
1612
+ * @overload
1613
+ * @param {TableDefine} tableDefine
1614
+ * @param {T[]} data
1615
+ * @param {string[] | boolean} [keys]
1616
+ * @param {boolean} [ignoreConflict]
1617
+ * @returns {Promise<T[]>}
1618
+ */
1619
+ insert<T extends unknown>(tableDefine: TableDefine, data: T[], keys?: boolean | string[] | undefined, ignoreConflict?: boolean | undefined): Promise<T[]>;
1620
+ /**
1621
+ * @template {object} T
1622
+ * @overload
1623
+ * @param {TableDefine} tableDefine
1624
+ * @param {T | T[]} data
1625
+ * @param {string[] | boolean} [keys]
1626
+ * @param {boolean} [ignoreConflict]
1627
+ * @returns {Promise<T | T[]>}
1541
1628
  */
1542
- insert<T extends unknown>({ table, fields }: TableDefine, data: T, keys?: string[]): Promise<T extends object[] ? object[] : object>;
1629
+ insert<T extends unknown>(tableDefine: TableDefine, data: T | T[], keys?: boolean | string[] | undefined, ignoreConflict?: boolean | undefined): Promise<T | T[]>;
1543
1630
  /**
1544
- * @template {object | object[]} T
1631
+ * @template {object} T
1545
1632
  * @overload
1546
1633
  * @param {TableDefine} tableDefine
1547
1634
  * @param {T} data
1548
1635
  * @param {Record<string, SetValue>} [conflictSet]
1549
- * @returns {Promise<T extends object[] ? object[] : object>}
1636
+ * @returns {Promise<T>}
1550
1637
  */
1551
- upsert<T extends unknown>(tableDefine: TableDefine, data: T, conflictSet?: Record<string, SetValue> | undefined): Promise<T extends object[] ? object[] : object>;
1638
+ upsert<T extends unknown>(tableDefine: TableDefine, data: T, conflictSet?: Record<string, SetValue> | undefined): Promise<T>;
1552
1639
  /**
1553
- * @template {object | object[]} T
1640
+ * @template {object} T
1641
+ * @overload
1642
+ * @param {TableDefine} tableDefine
1643
+ * @param {T[]} data
1644
+ * @param {Record<string, SetValue>} [conflictSet]
1645
+ * @returns {Promise<T[]>}
1646
+ */
1647
+ upsert<T extends unknown>(tableDefine: TableDefine, data: T[], conflictSet?: Record<string, SetValue> | undefined): Promise<T[]>;
1648
+ /**
1649
+ * @template {object} T
1554
1650
  * @overload
1555
1651
  * @param {TableDefine} tableDefine
1556
1652
  * @param {T} data
1557
- * @param {string[]} [keys]
1653
+ * @param {null | string[]} [keys]
1654
+ * @param {Record<string, SetValue>} [conflictSet]
1655
+ * @returns {Promise<T>}
1656
+ */
1657
+ upsert<T extends unknown>(tableDefine: TableDefine, data: T, keys?: string[] | null | undefined, conflictSet?: Record<string, SetValue> | undefined): Promise<T>;
1658
+ /**
1659
+ * @template {object} T
1660
+ * @overload
1661
+ * @param {TableDefine} tableDefine
1662
+ * @param {T[]} data
1663
+ * @param {null | string[]} [keys]
1664
+ * @param {Record<string, SetValue>} [conflictSet]
1665
+ * @returns {Promise<T[]>}
1666
+ */
1667
+ upsert<T extends unknown>(tableDefine: TableDefine, data: T[], keys?: string[] | null | undefined, conflictSet?: Record<string, SetValue> | undefined): Promise<T[]>;
1668
+ /**
1669
+ * @template {object} T
1670
+ * @overload
1671
+ * @param {TableDefine} tableDefine
1672
+ * @param {T} data
1673
+ * @param {null | string[]} [keys]
1674
+ * @param {string[] | boolean} [conflictKeys]
1558
1675
  * @param {Record<string, SetValue>} [conflictSet]
1559
- * @returns {Promise<T extends object[] ? object[] : object>}
1676
+ * @returns {Promise<T>}
1560
1677
  */
1561
- upsert<T extends unknown>(tableDefine: TableDefine, data: T, keys?: string[] | undefined, conflictSet?: Record<string, SetValue> | undefined): Promise<T extends object[] ? object[] : object>;
1678
+ upsert<T extends unknown>(tableDefine: TableDefine, data: T, keys?: string[] | null | undefined, conflictKeys?: boolean | string[] | undefined, conflictSet?: Record<string, SetValue> | undefined): Promise<T>;
1562
1679
  /**
1563
- * @template {object | object[]} T
1680
+ * @template {object} T
1681
+ * @overload
1682
+ * @param {TableDefine} tableDefine
1683
+ * @param {T[]} data
1684
+ * @param {null | string[]} [keys]
1685
+ * @param {string[] | boolean} [conflictKeys]
1686
+ * @param {Record<string, SetValue>} [conflictSet]
1687
+ * @returns {Promise<T[]>}
1688
+ */
1689
+ upsert<T extends unknown>(tableDefine: TableDefine, data: T[], keys?: string[] | null | undefined, conflictKeys?: boolean | string[] | undefined, conflictSet?: Record<string, SetValue> | undefined): Promise<T[]>;
1690
+ /**
1691
+ * @template {object} T
1564
1692
  * @overload
1565
1693
  * @param {TableDefine} tableDefine
1566
1694
  * @param {T} data
1567
- * @param {string[] | Record<string, SetValue>} [keys]
1695
+ * @param {null | string[] | boolean | Record<string, SetValue>} [keys]
1696
+ * @param {string[] | boolean | Record<string, SetValue>} [conflictKeys]
1568
1697
  * @param {Record<string, SetValue>} [conflictSet]
1569
- * @returns {Promise<T extends object[] ? object[] : object>}
1698
+ * @returns {Promise<T>}
1570
1699
  */
1571
- upsert<T extends unknown>(tableDefine: TableDefine, data: T, keys?: string[] | Record<string, SetValue> | undefined, conflictSet?: Record<string, SetValue> | undefined): Promise<T extends object[] ? object[] : object>;
1700
+ upsert<T extends unknown>(tableDefine: TableDefine, data: T, keys?: boolean | string[] | Record<string, SetValue> | null | undefined, conflictKeys?: boolean | string[] | Record<string, SetValue> | undefined, conflictSet?: Record<string, SetValue> | undefined): Promise<T>;
1701
+ /**
1702
+ * @template {object} T
1703
+ * @overload
1704
+ * @param {TableDefine} tableDefine
1705
+ * @param {T[]} data
1706
+ * @param {null | string[] | boolean | Record<string, SetValue>} [keys]
1707
+ * @param {string[] | boolean | Record<string, SetValue>} [conflictKeys]
1708
+ * @param {Record<string, SetValue>} [conflictSet]
1709
+ * @returns {Promise<T[]>}
1710
+ */
1711
+ upsert<T extends unknown>(tableDefine: TableDefine, data: T[], keys?: boolean | string[] | Record<string, SetValue> | null | undefined, conflictKeys?: boolean | string[] | Record<string, SetValue> | undefined, conflictSet?: Record<string, SetValue> | undefined): Promise<T[]>;
1712
+ /**
1713
+ * @template {object} T
1714
+ * @overload
1715
+ * @param {TableDefine} tableDefine
1716
+ * @param {T | T[]} data
1717
+ * @param {null | string[] | boolean | Record<string, SetValue>} [keys]
1718
+ * @param {string[] | boolean | Record<string, SetValue>} [conflictKeys]
1719
+ * @param {Record<string, SetValue>} [conflictSet]
1720
+ * @returns {Promise<T | T[]>}
1721
+ */
1722
+ upsert<T extends unknown>(tableDefine: TableDefine, data: T | T[], keys?: boolean | string[] | Record<string, SetValue> | null | undefined, conflictKeys?: boolean | string[] | Record<string, SetValue> | undefined, conflictSet?: Record<string, SetValue> | undefined): Promise<T | T[]>;
1572
1723
  /**
1573
1724
  * @param {TableDefine} tableDefine
1574
1725
  * @param {Record<string, any>} update
@@ -1937,6 +2088,11 @@ declare class Query<T extends Fields, TB extends unknown = any> implements Query
1937
2088
  * @returns {this}
1938
2089
  */
1939
2090
  primary(primary?: any, ...args: any[]): this;
2091
+ /**
2092
+ *
2093
+ * @param {...string | string[]} groups
2094
+ */
2095
+ groupBy(...groups: (string | string[])[]): this;
1940
2096
  /**
1941
2097
  *
1942
2098
  * @param {object} a
@@ -2362,4 +2518,4 @@ declare function field<T extends MainFieldType>(type: T, options: {
2362
2518
  declare function setDevelopment(d?: boolean): void;
2363
2519
  declare let isDevelopment: boolean;
2364
2520
 
2365
- export { Build, type ClassDecorator, type Column, type ColumnOptions, Connection, type Constraint, Create, type DBColumn, type DBIndex, type DBTable, Destroy, type Environment, type FieldDecorator, type FieldDefine, type FieldDefineOption, type FieldDefineType, type FieldSpecific, type FieldSpecificValue, type FieldType, type FieldTypeDefine, type FieldValue, type Fields, type FindArg, type FindRange, type GetName, type Hook, type Hooks, type IConnection, type Index, type IndexInfo, type IndexOptions, type Join, type JoinType, type MainFieldType, type MaybePromise, type MethodDecorator, Model, type Options, PseudoDestroy, Query, type QueryOptions, type Queryable, Save, Scene, Select, SetValue, type Skip, Submodel, type Support, type TableDefine, type TableType, type ToFieldType, type ToType, type TransactionFn, type VirtualTable, Where, type WhereItem, type WhereLike, type WhereOr, type WhereRaw, type WhereValue, type Wheres, afterCreate, afterCreateMany, afterDelete, afterUpdate, beforeCreate, beforeCreateMany, beforeDelete, beforeUpdate, coefficient, column, creating, decrement, defaultValue, field as define, deleted, deleting, divide, field$1 as field, getPrimaryFields, getPrimaryKeys, immutable, increment, index, isDevelopment, isPseudo, model, multiply, now, primary, prop, pseudo, setDevelopment, sort, model as submodel, toNot, toPrimaries, toPrimary, uncreatable, undeleted, updating, uuid, values, where, withDeleted };
2521
+ export { Build, type ClassDecorator, type Column, type ColumnOptions, Connection, type Constraint, Create, type DBColumn, type DBIndex, type DBTable, Destroy, type Environment, type FieldDecorator, type FieldDefine, type FieldDefineOption, type FieldDefineType, type FieldSpecific, type FieldSpecificValue, type FieldType, type FieldTypeDefine, type FieldValue, type Fields, type FindArg, type FindRange, type GetName, type Hook, type Hooks, type IConnection, type Index, type IndexInfo, type IndexOptions, type JOIN, type Join, type JoinType, type MainFieldType, type MaybePromise, type MethodDecorator, Model, type Options, PseudoDestroy, Query, type QueryOptions, type Queryable, Save, Scene, Select, type SelectItem, SetValue, type Skip, Submodel, type Support, type TableDefine, type TableType, type ToFieldType, type ToType, type TransactionFn, type VirtualTable, Where, type WhereItem, type WhereLike, type WhereOr, type WhereRaw, type WhereValue, type Wheres, afterCreate, afterCreateMany, afterDelete, afterUpdate, beforeCreate, beforeCreateMany, beforeDelete, beforeUpdate, coefficient, column, creating, decrement, defaultValue, field as define, deleted, deleting, divide, field$1 as field, getPrimaryFields, getPrimaryKeys, immutable, increment, index, isDevelopment, isPseudo, model, multiply, now, primary, prop, pseudo, setDevelopment, sort, model as submodel, toNot, toPrimaries, toPrimary, uncreatable, undeleted, updating, uuid, values, where, withDeleted };
package/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * imodel v0.15.0
2
+ * imodel v0.16.0
3
3
  * (c) 2019-2026 undefined
4
4
  * @license undefined
5
5
  */
@@ -733,13 +733,10 @@ async function getSpecificValue(val) {
733
733
  computed,
734
734
  value
735
735
  } = val;
736
- if (value === void 0) {
737
- return;
738
- }
739
736
  if (typeof computed === 'function') {
740
737
  const value = await computed();
741
738
  if (value !== void 0) {
742
- return;
739
+ return value;
743
740
  }
744
741
  }
745
742
  return value;
@@ -2937,84 +2934,211 @@ class Connection {
2937
2934
  return pseudoDeleteMany(conn, queryable, update, this.#env);
2938
2935
  }
2939
2936
  /**
2940
- * @template {object | object[]} T
2937
+ * @template {object} T
2938
+ * @overload
2941
2939
  * @param {TableDefine} tableDefine
2942
2940
  * @param {T} data
2941
+ * @param {boolean} [ignoreConflict]
2942
+ * @returns {Promise<T>}
2943
+ */
2944
+ /**
2945
+ * @template {object} T
2946
+ * @overload
2947
+ * @param {TableDefine} tableDefine
2948
+ * @param {T[]} data
2949
+ * @param {boolean} [ignoreConflict]
2950
+ * @returns {Promise<T[]>}
2951
+ */
2952
+ /**
2953
+ * @template {object} T
2954
+ * @overload
2955
+ * @param {TableDefine} tableDefine
2956
+ * @param {T} data
2957
+ * @param {string[]} [keys]
2958
+ * @param {boolean} [ignoreConflict]
2959
+ * @returns {Promise<T>}
2960
+ */
2961
+ /**
2962
+ * @template {object} T
2963
+ * @overload
2964
+ * @param {TableDefine} tableDefine
2965
+ * @param {T[]} data
2943
2966
  * @param {string[]} [keys]
2944
- * @returns {Promise<T extends object[] ? object[] : object>}
2967
+ * @param {boolean} [ignoreConflict]
2968
+ * @returns {Promise<T[]>}
2969
+ */
2970
+ /**
2971
+ * @template {object} T
2972
+ * @overload
2973
+ * @param {TableDefine} tableDefine
2974
+ * @param {T} data
2975
+ * @param {string[] | boolean} [keys]
2976
+ * @param {boolean} [ignoreConflict]
2977
+ * @returns {Promise<T>}
2978
+ */
2979
+ /**
2980
+ * @template {object} T
2981
+ * @overload
2982
+ * @param {TableDefine} tableDefine
2983
+ * @param {T[]} data
2984
+ * @param {string[] | boolean} [keys]
2985
+ * @param {boolean} [ignoreConflict]
2986
+ * @returns {Promise<T[]>}
2987
+ */
2988
+ /**
2989
+ * @template {object} T
2990
+ * @overload
2991
+ * @param {TableDefine} tableDefine
2992
+ * @param {T | T[]} data
2993
+ * @param {string[] | boolean} [keys]
2994
+ * @param {boolean} [ignoreConflict]
2995
+ * @returns {Promise<T | T[]>}
2996
+ */
2997
+ /**
2998
+ * @template {object} T
2999
+ * @param {TableDefine} tableDefine
3000
+ * @param {T | T[]} data
3001
+ * @param {string[] | boolean} [keys]
3002
+ * @param {boolean} [ignoreConflict]
3003
+ * @returns {Promise<T | T[]>}
2945
3004
  */
2946
3005
  async insert({
2947
3006
  table,
2948
3007
  fields
2949
- }, data, keys) {
3008
+ }, data, keys, ignoreConflict) {
2950
3009
  const [columns, fieldColumns] = toColumns(fields);
2951
3010
  const isArray = Array.isArray(data);
2952
- const insertValues = (isArray ? data : [data]).map(d => getInsertValue(d, columns, fieldColumns, {
3011
+ const insertValues = (isArray ? data : [data]
3012
+ // @ts-ignore
3013
+ ).map(d => getInsertValue(d, columns, fieldColumns, {
2953
3014
  uncreatable: true
2954
3015
  }));
2955
3016
  if (!insertValues.length) {
2956
3017
  throw new Error();
2957
3018
  }
2958
- let insertKeys = fieldColumns ? [...new Set(keys || [])].map(k => fieldColumns[k]).filter(Boolean) : [...new Set(keys || [])].filter(k => k in columns);
3019
+ const allKeys = Array.isArray(keys) ? [...new Set(keys || [])] : [];
3020
+ let insertKeys = fieldColumns ? allKeys.map(k => fieldColumns[k]).filter(Boolean) : allKeys.filter(k => k in columns);
2959
3021
  if (!insertKeys.length && !isArray) {
2960
3022
  insertKeys = Object.entries(insertValues[0]).filter(([k, v]) => v !== undefined && k in columns).map(([k]) => k);
2961
3023
  }
2962
3024
  if (!insertKeys.length) {
2963
3025
  insertKeys = Object.entries(columns).map(v => v[0]);
2964
3026
  }
3027
+ const ignore = Boolean(Array.isArray(keys) ? ignoreConflict : keys);
2965
3028
  const conn = await this.#getConnection();
2966
- const result = table && typeof table === 'object' ? await table.insert(this.#env, conn, columns, insertValues, insertKeys) : await conn.insert(this.#env, table || '', columns, insertValues, insertKeys);
3029
+ const result = table && typeof table === 'object' ? await table.insert(this.#env, conn, columns, insertValues, insertKeys, ignore) : await conn.insert(this.#env, table || '', columns, insertValues, insertKeys, ignore);
2967
3030
  const list = toFieldList(result, fieldColumns);
2968
3031
  // @ts-ignore
2969
3032
  return isArray ? list : list[0];
2970
3033
  }
2971
3034
  /**
2972
- * @template {object | object[]} T
3035
+ * @template {object} T
2973
3036
  * @overload
2974
3037
  * @param {TableDefine} tableDefine
2975
3038
  * @param {T} data
2976
3039
  * @param {Record<string, SetValue>} [conflictSet]
2977
- * @returns {Promise<T extends object[] ? object[] : object>}
3040
+ * @returns {Promise<T>}
2978
3041
  */
2979
3042
  /**
2980
- * @template {object | object[]} T
3043
+ * @template {object} T
3044
+ * @overload
3045
+ * @param {TableDefine} tableDefine
3046
+ * @param {T[]} data
3047
+ * @param {Record<string, SetValue>} [conflictSet]
3048
+ * @returns {Promise<T[]>}
3049
+ */
3050
+ /**
3051
+ * @template {object} T
2981
3052
  * @overload
2982
3053
  * @param {TableDefine} tableDefine
2983
3054
  * @param {T} data
2984
- * @param {string[]} [keys]
3055
+ * @param {null | string[]} [keys]
2985
3056
  * @param {Record<string, SetValue>} [conflictSet]
2986
- * @returns {Promise<T extends object[] ? object[] : object>}
3057
+ * @returns {Promise<T>}
2987
3058
  */
2988
3059
  /**
2989
- * @template {object | object[]} T
3060
+ * @template {object} T
3061
+ * @overload
3062
+ * @param {TableDefine} tableDefine
3063
+ * @param {T[]} data
3064
+ * @param {null | string[]} [keys]
3065
+ * @param {Record<string, SetValue>} [conflictSet]
3066
+ * @returns {Promise<T[]>}
3067
+ */
3068
+ /**
3069
+ * @template {object} T
2990
3070
  * @overload
2991
3071
  * @param {TableDefine} tableDefine
2992
3072
  * @param {T} data
2993
- * @param {string[] | Record<string, SetValue>} [keys]
3073
+ * @param {null | string[]} [keys]
3074
+ * @param {string[] | boolean} [conflictKeys]
3075
+ * @param {Record<string, SetValue>} [conflictSet]
3076
+ * @returns {Promise<T>}
3077
+ */
3078
+ /**
3079
+ * @template {object} T
3080
+ * @overload
3081
+ * @param {TableDefine} tableDefine
3082
+ * @param {T[]} data
3083
+ * @param {null | string[]} [keys]
3084
+ * @param {string[] | boolean} [conflictKeys]
2994
3085
  * @param {Record<string, SetValue>} [conflictSet]
2995
- * @returns {Promise<T extends object[] ? object[] : object>}
3086
+ * @returns {Promise<T[]>}
2996
3087
  */
2997
3088
  /**
2998
- * @template {object | object[]} T
3089
+ * @template {object} T
3090
+ * @overload
2999
3091
  * @param {TableDefine} tableDefine
3000
3092
  * @param {T} data
3001
- * @param {string[] | Record<string, SetValue>} [keys]
3093
+ * @param {null | string[] | boolean | Record<string, SetValue>} [keys]
3094
+ * @param {string[] | boolean | Record<string, SetValue>} [conflictKeys]
3002
3095
  * @param {Record<string, SetValue>} [conflictSet]
3003
- * @returns {Promise<T extends object[] ? object[] : object>}
3096
+ * @returns {Promise<T>}
3097
+ */
3098
+ /**
3099
+ * @template {object} T
3100
+ * @overload
3101
+ * @param {TableDefine} tableDefine
3102
+ * @param {T[]} data
3103
+ * @param {null | string[] | boolean | Record<string, SetValue>} [keys]
3104
+ * @param {string[] | boolean | Record<string, SetValue>} [conflictKeys]
3105
+ * @param {Record<string, SetValue>} [conflictSet]
3106
+ * @returns {Promise<T[]>}
3107
+ */
3108
+ /**
3109
+ * @template {object} T
3110
+ * @overload
3111
+ * @param {TableDefine} tableDefine
3112
+ * @param {T | T[]} data
3113
+ * @param {null | string[] | boolean | Record<string, SetValue>} [keys]
3114
+ * @param {string[] | boolean | Record<string, SetValue>} [conflictKeys]
3115
+ * @param {Record<string, SetValue>} [conflictSet]
3116
+ * @returns {Promise<T | T[]>}
3117
+ */
3118
+ /**
3119
+ * @template {object} T
3120
+ * @param {TableDefine} tableDefine
3121
+ * @param {T | T[]} data
3122
+ * @param {null | string[] | boolean | Record<string, SetValue>} [keys]
3123
+ * @param {string[] | boolean | Record<string, SetValue>} [conflictKeys]
3124
+ * @param {Record<string, SetValue>} [conflictSet]
3125
+ * @returns {Promise<T | T[]>}
3004
3126
  */
3005
3127
  async upsert({
3006
3128
  table,
3007
3129
  fields
3008
- }, data, keys, conflictSet) {
3130
+ }, data, keys, conflictKeys, conflictSet) {
3009
3131
  const [columns, fieldColumns, baseFields] = toColumns(fields);
3010
3132
  const isArray = Array.isArray(data);
3011
- const insertValues = (isArray ? data : [data]).map(d => getInsertValue(d, columns, fieldColumns, {
3133
+ const insertValues = (isArray ? data : [data]
3134
+ // @ts-ignore
3135
+ ).map(d => getInsertValue(d, columns, fieldColumns, {
3012
3136
  uncreatable: true
3013
3137
  }));
3014
3138
  if (!insertValues.length) {
3015
3139
  throw new Error();
3016
3140
  }
3017
- const set = Array.isArray(keys) ? conflictSet : keys;
3141
+ const set = [keys, conflictKeys, conflictSet].find(/** @type {(v: any) => v is Record<string, SetValue>} */v => v && !Array.isArray(v) && typeof v === 'object');
3018
3142
  const saveKeys = Array.isArray(keys) ? [...new Set(keys)] : [];
3019
3143
  let insertKeys = fieldColumns ? saveKeys.map(k => fieldColumns[k]).filter(Boolean) : saveKeys.filter(k => k in columns);
3020
3144
  if (!insertKeys.length && !isArray) {
@@ -3023,9 +3147,9 @@ class Connection {
3023
3147
  if (!insertKeys.length) {
3024
3148
  insertKeys = Object.entries(columns).map(v => v[0]);
3025
3149
  }
3026
- const primaryFields = baseFields.filter(([, v]) => v.primary).sort(([, a], [, b]) => Number(a.primary) - Number(b.primary)).map(([v]) => v);
3150
+ const conflict = Array.isArray(conflictKeys) || conflictKeys === true ? conflictKeys : baseFields.filter(([, v]) => v.primary).sort(([, a], [, b]) => Number(a.primary) - Number(b.primary)).map(([v]) => v);
3027
3151
  const conn = await this.#getConnection();
3028
- const result = table && typeof table === 'object' ? await table.upsert(this.#env, conn, columns, insertValues, insertKeys, primaryFields, set) : await conn.upsert(this.#env, table || '', columns, insertValues, insertKeys, primaryFields, set);
3152
+ const result = table && typeof table === 'object' ? await table.upsert(this.#env, conn, columns, insertValues, insertKeys, conflict, set) : await conn.upsert(this.#env, table || '', columns, insertValues, insertKeys, conflict, set);
3029
3153
  const list = toFieldList(result, fieldColumns);
3030
3154
  // @ts-ignore
3031
3155
  return isArray ? list : list[0];
@@ -3176,19 +3300,27 @@ class Connection {
3176
3300
  const {
3177
3301
  sort
3178
3302
  } = options;
3179
- const result = table && typeof table === 'object' ? await table.find(this.#env, conn, columns, {
3303
+ const result = table && typeof table === 'object' ? await table.select(this.#env, conn, [{
3304
+ table: '',
3305
+ columns,
3180
3306
  offset,
3181
3307
  limit,
3182
3308
  where,
3183
3309
  select,
3184
- sort: sort?.length ? sort2column(sort, fieldColumns) : getDefaultSort(columns)
3185
- }) : await conn.find(this.#env, table || '', columns, {
3310
+ sort: sort?.length ? sort2column(sort, fieldColumns) : getDefaultSort(columns),
3311
+ group: options.group || [],
3312
+ having: []
3313
+ }]) : await conn.select(this.#env, [{
3314
+ table: table || '',
3315
+ columns,
3186
3316
  offset,
3187
3317
  limit,
3188
3318
  where,
3189
3319
  select,
3190
- sort: sort?.length ? sort2column(sort, fieldColumns) : getDefaultSort(columns)
3191
- });
3320
+ sort: sort?.length ? sort2column(sort, fieldColumns) : getDefaultSort(columns),
3321
+ group: options.group || [],
3322
+ having: []
3323
+ }]);
3192
3324
  return result;
3193
3325
  }
3194
3326
  /**
@@ -4641,7 +4773,7 @@ function selectFn(fn, select, newSelect) {
4641
4773
  if (typeof s === 'string') {
4642
4774
  select[s] = {
4643
4775
  field: s,
4644
- fn: 'sum'
4776
+ fn
4645
4777
  };
4646
4778
  continue;
4647
4779
  }
@@ -5116,6 +5248,14 @@ class Query {
5116
5248
  m.#primary = primary;
5117
5249
  return m;
5118
5250
  }
5251
+ /**
5252
+ *
5253
+ * @param {...string | string[]} groups
5254
+ */
5255
+ groupBy(...groups) {
5256
+ this.#options.group = [this.#options.group || [], groups].flat(2);
5257
+ return this;
5258
+ }
5119
5259
  }
5120
5260
 
5121
5261
  /** @import { Fields, IndexInfo, FieldDefine } from './types' */
package/migrate.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * imodel v0.15.0
2
+ * imodel v0.16.0
3
3
  * (c) 2019-2026 undefined
4
4
  * @license undefined
5
5
  */
package/migrate.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * imodel v0.15.0
2
+ * imodel v0.16.0
3
3
  * (c) 2019-2026 undefined
4
4
  * @license undefined
5
5
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "imodel",
3
- "version": "0.15.0",
3
+ "version": "0.16.0",
4
4
  "main": "index.mjs",
5
5
  "type": "module",
6
6
  "repository": {