Comparing version 34.3.1 to 35.0.0
/* eslint-disable @typescript-eslint/no-explicit-any */ | ||
import { initKmoreEvent } from './config.js'; | ||
import { processJoinTableColumnAlias } from './smart-join.js'; | ||
export async function callCbOnStart(options) { | ||
const queryBuilder = processJoinTableColumnAlias(options.builder); | ||
const cb = options.cbs?.start; | ||
@@ -11,3 +13,3 @@ if (typeof cb === 'function') { | ||
queryUid: '', | ||
queryBuilder: options.builder, | ||
queryBuilder, | ||
}); | ||
@@ -14,0 +16,0 @@ event.dbId = options.dbId; |
@@ -10,2 +10,3 @@ /* eslint-disable max-lines-per-function */ | ||
import { postProcessResponse, wrapIdentifier } from './helper.js'; | ||
import { extRefTableFnPropertySmartJoin } from './smart-join.js'; | ||
import { CaseType, } from './types.js'; | ||
@@ -266,2 +267,3 @@ export class Kmore { | ||
refTable = this.extRefTableFnPropertyThen(refTable); | ||
refTable = extRefTableFnPropertySmartJoin(refTable); | ||
void Object.defineProperty(refTable, 'kmoreQueryId', { | ||
@@ -271,2 +273,10 @@ ...defaultPropDescriptor, | ||
}); | ||
void Object.defineProperty(refTable, 'dbDict', { | ||
...defaultPropDescriptor, | ||
value: this.dict, | ||
}); | ||
void Object.defineProperty(refTable, '_tablesJoin', { | ||
...defaultPropDescriptor, | ||
value: [], | ||
}); | ||
return refTable; | ||
@@ -273,0 +283,0 @@ } |
@@ -1,4 +0,6 @@ | ||
import { RecordCamelKeys, RecordPascalKeys, RecordSnakeKeys } from '@waiting/shared-types'; | ||
import { CaseConvertTable, CaseType, DbScopedColsByKey, DbScopedColsByTableType, JoinTableWithCaseConvert, SplitScopedColumn, StrKey, UnwrapArrayMember } from '@waiting/shared-types'; | ||
import { DbDict } from 'kmore-types'; | ||
import type { Knex } from 'knex'; | ||
import { Span } from 'opentracing'; | ||
import type { Span } from 'opentracing'; | ||
export { CaseType }; | ||
export declare type KnexConfig = Knex.Config; | ||
@@ -22,5 +24,2 @@ export declare type KmoreTransaction = Knex.Transaction & { | ||
}; | ||
export declare type KmoreQueryBuilder<TRecord extends {} = any, TResult = any> = Knex.QueryBuilder<TRecord, TResult> & { | ||
kmoreQueryId: symbol; | ||
}; | ||
export declare enum EnumClient { | ||
@@ -34,10 +33,11 @@ pg = "pg", | ||
} | ||
export declare enum CaseType { | ||
camel = "camel", | ||
pascal = "pascal", | ||
snake = "snake", | ||
none = "none" | ||
export declare enum SmartKey { | ||
join = "smartJoin", | ||
leftJoin = "smartLeftJoin", | ||
rightJoin = "smartRightJoin", | ||
innerJoin = "smartInnerJoin", | ||
crossJoin = "smartCrossJoin" | ||
} | ||
export declare type DbQueryBuilder<Context, D, Prefix extends string, CaseConvert extends CaseType> = { | ||
[tb in keyof D as `${Prefix}${tb & string}`]: CaseConvert extends CaseType.camel ? TbQueryBuilder<RecordCamelKeys<D[tb]>, Context> : CaseConvert extends CaseType.snake ? TbQueryBuilder<RecordSnakeKeys<D[tb]>, Context> : CaseConvert extends CaseType.pascal ? TbQueryBuilder<RecordPascalKeys<D[tb]>, Context> : TbQueryBuilder<D[tb], Context>; | ||
[tb in keyof D as `${Prefix}${tb & string}`]: TbQueryBuilder<D, CaseConvert, CaseConvertTable<D[tb], CaseConvert>, Context>; | ||
}; | ||
@@ -48,3 +48,27 @@ export interface BuilderInput { | ||
} | ||
export declare type TbQueryBuilder<TRecord, Context> = (ctx?: Context) => KmoreQueryBuilder<TRecord, TRecord[]>; | ||
export declare type TbQueryBuilder<D, CaseConvert extends CaseType, TRecord, Context> = (ctx?: Context) => KmoreQueryBuilder<D, CaseConvert, TRecord, TRecord[]>; | ||
export declare type KmoreQueryBuilder<D = {}, CaseConvert extends CaseType = CaseType, TRecord extends {} = any, TResult = any> = Knex.QueryBuilder<TRecord, TResult> & QueryBuilderExtMethod<D, CaseConvert, TRecord> & QueryBuilderExtName<D>; | ||
interface QueryBuilderExtName<D extends {} = {}> { | ||
kmoreQueryId: symbol; | ||
dbDict: DbDict<D>; | ||
_tablesJoin: string[]; | ||
} | ||
interface QueryBuilderExtMethod<D, CaseConvert extends CaseType, TRecord extends {} = any> { | ||
smartCrossJoin: SmartJoin<D, CaseConvert, TRecord>; | ||
smartInnerJoin: SmartJoin<D, CaseConvert, TRecord>; | ||
smartJoin: SmartJoin<D, CaseConvert, TRecord>; | ||
smartLeftJoin: SmartJoin<D, CaseConvert, TRecord>; | ||
smartRightJoin: SmartJoin<D, CaseConvert, TRecord>; | ||
} | ||
declare type SmartJoin<D extends {}, CaseConvert extends CaseType, TResult = unknown[]> = <TRecord1 = UnwrapArrayMember<TResult>, C2 extends DbScopedColsByKey<D> = DbScopedColsByKey<D>, C1 extends DbScopedColsByKey<D> = DbScopedColsByTableType<D, TRecord1>, TTable2 extends StrKey<D> = SplitScopedColumn<D, C2>[0], TRecord2 extends D[TTable2] = D[TTable2], TResult2 = JoinTableWithCaseConvert<TRecord1, TRecord2 extends any ? D[TTable2] : TRecord2, TTable2, CaseConvert>>( | ||
/** | ||
* scoped column name, e.g. 'tb_name.col_name', | ||
* <tb_name> is the table name be joined, <col_name> is the column name | ||
*/ | ||
scopedColumnBeJoined: C2, | ||
/** | ||
* scoped column name, e.g. 'tb_name.col_name', | ||
* <tb_name> is the upstream table name , <col_name> is the column name | ||
*/ | ||
scopedColumn: C1 extends C2 ? never : C1) => KmoreQueryBuilder<D, CaseConvert, TResult2, TResult2[]>; | ||
export declare type EventType = 'query' | 'queryError' | 'queryResponse' | 'start' | 'unknown'; | ||
@@ -51,0 +75,0 @@ export interface KmoreEvent<T = unknown> { |
@@ -0,1 +1,5 @@ | ||
/* eslint-disable @typescript-eslint/no-explicit-any */ | ||
/* eslint-disable @typescript-eslint/ban-types */ | ||
import { CaseType, } from '@waiting/shared-types'; | ||
export { CaseType }; | ||
export var EnumClient; | ||
@@ -10,9 +14,10 @@ (function (EnumClient) { | ||
})(EnumClient = EnumClient || (EnumClient = {})); | ||
export var CaseType; | ||
(function (CaseType) { | ||
CaseType["camel"] = "camel"; | ||
CaseType["pascal"] = "pascal"; | ||
CaseType["snake"] = "snake"; | ||
CaseType["none"] = "none"; | ||
})(CaseType = CaseType || (CaseType = {})); | ||
export var SmartKey; | ||
(function (SmartKey) { | ||
SmartKey["join"] = "smartJoin"; | ||
SmartKey["leftJoin"] = "smartLeftJoin"; | ||
SmartKey["rightJoin"] = "smartRightJoin"; | ||
SmartKey["innerJoin"] = "smartInnerJoin"; | ||
SmartKey["crossJoin"] = "smartCrossJoin"; | ||
})(SmartKey = SmartKey || (SmartKey = {})); | ||
//# sourceMappingURL=types.js.map |
{ | ||
"name": "kmore", | ||
"author": "waiting", | ||
"version": "34.3.1", | ||
"version": "35.0.0", | ||
"description": "A SQL query builder based on knex with powerful TypeScript type support", | ||
@@ -41,7 +41,8 @@ "keywords": [ | ||
"dependencies": { | ||
"@waiting/shared-core": "^20.3.0" | ||
"@waiting/shared-core": "^20.5.0" | ||
}, | ||
"devDependencies": { | ||
"cross-env": "7", | ||
"kmore-types": "^34.0.0", | ||
"kmore-cli": "^35.0.0", | ||
"kmore-types": "^35.0.0", | ||
"knex": "^2.2.0", | ||
@@ -77,3 +78,3 @@ "pg": "^8.7.3" | ||
}, | ||
"gitHead": "baa5ac4d7bb7c897206154c6be8ea03357eb6f4b" | ||
"gitHead": "82ea11a06cde2d2c1091073a3e5057767731562e" | ||
} |
@@ -23,3 +23,4 @@ # [kmore](https://waitingsong.github.io/kmore/) | ||
```sh | ||
npm install kmore kmore-cli | ||
// or | ||
npm i @mw-components/kmore | ||
@@ -151,53 +152,24 @@ # Then add one of the following: | ||
### Join tables | ||
### Smart Join tables with types hint and auto complete | ||
```ts | ||
const { refTables } = km | ||
const { tables, scoped } = km.dict | ||
const uid = 1 | ||
const ret = await refTables.ref_tb_user() | ||
.innerJoin<UserExtDo>( | ||
tables.tb_user_ext, | ||
scoped.tb_user.uid, | ||
scoped.tb_user_ext.uid, | ||
) | ||
// tb_user JOIN tb_user_ext ON tb_user_ext.uid = tb_user.uid | ||
const ret = await km.refTables.ref_tb_user() | ||
.smartJoin( | ||
'tb_user_ext.uid', | ||
'tb_user.uid', | ||
) | ||
.select('*') | ||
.where(scoped.tb_user.uid, 1) | ||
const cols = [ | ||
alias.tb_user.uid, // { tbUser: 'tb_user.uid' } | ||
alias.tb_user_ext.uid, // { tbUserExt: 'tb_user_ext.uid' } | ||
] | ||
// -------------- | ||
type CT = DbDictType<Db> | ||
type CT_USER = CT['tb_user'] | ||
type CT_USER_EXT = CT['tb_user_ext'] | ||
const ret = await camelTables.ref_tb_user() | ||
.innerJoin<CT_USER & CT_USER_EXT>( | ||
tables.tb_user_ext, | ||
scoped.tb_user.uid, | ||
scoped.tb_user_ext.uid, | ||
) | ||
.columns(cols) | ||
.where({ uid }) | ||
// .where('uid', uid) | ||
// .where('tb_user_ext_uid', uid) | ||
// .where(km.dict.scoped.tb_user.uid, 1) | ||
.then(rows => rows[0]) | ||
assert(ret) | ||
const cols = { | ||
uid: scoped.tb_user.uid, | ||
foo: scoped.tb_user_ext.uid, | ||
} | ||
const ret = await camelTables.ref_tb_user() | ||
.innerJoin<CT_USER & CT_USER_EXT>( | ||
tables.tb_user_ext, | ||
scoped.tb_user.uid, | ||
scoped.tb_user_ext.uid, | ||
) | ||
.columns(cols) | ||
.then(rows => rows[0]) | ||
``` | ||
More examples of join see [joint-table](https://github.com/waitingsong/kmore/blob/main/packages/kmore/test/join-table/71.advanced.test.ts) | ||
More examples of join see [joint-table](https://github.com/waitingsong/kmore/blob/main/packages/kmore/test/join-table/) | ||
@@ -204,0 +176,0 @@ |
@@ -23,3 +23,5 @@ # [kmore](https://waitingsong.github.io/kmore/) | ||
```sh | ||
npm install kmore kmore-cli | ||
npm i kmore | ||
// or | ||
npm i @mw-components/kmore | ||
@@ -150,50 +152,21 @@ # Then add one of the following: | ||
### 连表 | ||
### 智能连表 (类型提示和自动完成) | ||
```ts | ||
const { refTables } = km | ||
const { tables, scoped } = km.dict | ||
const uid = 1 | ||
const ret = await refTables.ref_tb_user() | ||
.innerJoin<UserExtDo>( | ||
tables.tb_user_ext, | ||
scoped.tb_user.uid, | ||
scoped.tb_user_ext.uid, | ||
) | ||
// tb_user JOIN tb_user_ext ON tb_user_ext.uid = tb_user.uid | ||
const ret = await km.refTables.ref_tb_user() | ||
.smartJoin( | ||
'tb_user_ext.uid', | ||
'tb_user.uid', | ||
) | ||
.select('*') | ||
.where(scoped.tb_user.uid, 1) | ||
const cols = [ | ||
alias.tb_user.uid, // { tbUser: 'tb_user.uid' } | ||
alias.tb_user_ext.uid, // { tbUserExt: 'tb_user_ext.uid' } | ||
] | ||
// -------------- | ||
type CT = DbDictType<Db> | ||
type CT_USER = CT['tb_user'] | ||
type CT_USER_EXT = CT['tb_user_ext'] | ||
const ret = await camelTables.ref_tb_user() | ||
.innerJoin<CT_USER & CT_USER_EXT>( | ||
tables.tb_user_ext, | ||
scoped.tb_user.uid, | ||
scoped.tb_user_ext.uid, | ||
) | ||
.columns(cols) | ||
.where({ uid }) | ||
// .where('uid', uid) | ||
// .where('tb_user_ext_uid', uid) | ||
// .where(km.dict.scoped.tb_user.uid, 1) | ||
.then(rows => rows[0]) | ||
assert(ret) | ||
const cols = { | ||
uid: scoped.tb_user.uid, | ||
foo: scoped.tb_user_ext.uid, | ||
} | ||
const ret = await camelTables.ref_tb_user() | ||
.innerJoin<CT_USER & CT_USER_EXT>( | ||
tables.tb_user_ext, | ||
scoped.tb_user.uid, | ||
scoped.tb_user_ext.uid, | ||
) | ||
.columns(cols) | ||
.then(rows => rows[0]) | ||
``` | ||
@@ -200,0 +173,0 @@ |
/* eslint-disable @typescript-eslint/no-explicit-any */ | ||
import { initKmoreEvent } from './config.js' | ||
import { processJoinTableColumnAlias } from './smart-join.js' | ||
import { | ||
@@ -28,2 +29,3 @@ EventCallbacks, | ||
export async function callCbOnStart(options: CallCbOnStartOptions): Promise<void> { | ||
const queryBuilder = processJoinTableColumnAlias(options.builder) | ||
const cb: EventCallbacks['start'] = options.cbs?.start | ||
@@ -37,3 +39,3 @@ | ||
queryUid: '', | ||
queryBuilder: options.builder, | ||
queryBuilder, | ||
}) | ||
@@ -40,0 +42,0 @@ event.dbId = options.dbId |
@@ -20,2 +20,3 @@ /* eslint-disable max-lines-per-function */ | ||
import { PostProcessInput, postProcessResponse, wrapIdentifier } from './helper.js' | ||
import { extRefTableFnPropertySmartJoin } from './smart-join.js' | ||
import { | ||
@@ -367,2 +368,3 @@ CaseType, | ||
refTable = this.extRefTableFnPropertyThen(refTable as KmoreQueryBuilder) | ||
refTable = extRefTableFnPropertySmartJoin(refTable as KmoreQueryBuilder) | ||
@@ -374,2 +376,12 @@ void Object.defineProperty(refTable, 'kmoreQueryId', { | ||
void Object.defineProperty(refTable, 'dbDict', { | ||
...defaultPropDescriptor, | ||
value: this.dict, | ||
}) | ||
void Object.defineProperty(refTable, '_tablesJoin', { | ||
...defaultPropDescriptor, | ||
value: [], | ||
}) | ||
return refTable as KmoreQueryBuilder | ||
@@ -447,3 +459,8 @@ } | ||
const ts = new Proxy(refTable.transacting, { | ||
apply: (target: KmoreQueryBuilder['transacting'], ctx2: KmoreQueryBuilder, args: [KmoreTransaction]) => { | ||
apply: ( | ||
target: KmoreQueryBuilder['transacting'], | ||
ctx2: KmoreQueryBuilder, | ||
args: [KmoreTransaction], | ||
) => { | ||
const [trx] = args | ||
@@ -471,3 +488,8 @@ assert(trx?.isTransaction === true, 'trx must be a transaction') | ||
const pm = new Proxy(refTable.then, { | ||
apply: (target: () => Promise<unknown>, ctx2: KmoreQueryBuilder, args: unknown[]) => { | ||
apply: ( | ||
target: () => Promise<unknown>, | ||
ctx2: KmoreQueryBuilder, | ||
args: unknown[], | ||
) => { | ||
const qid = ctx2.kmoreQueryId | ||
@@ -474,0 +496,0 @@ const trx = this.getTrxByKmoreQueryId(qid) |
/* eslint-disable @typescript-eslint/no-explicit-any */ | ||
/* eslint-disable import/no-extraneous-dependencies */ | ||
import { RecordCamelKeys, RecordPascalKeys, RecordSnakeKeys } from '@waiting/shared-types' | ||
/* eslint-disable @typescript-eslint/ban-types */ | ||
import { | ||
CaseConvertTable, | ||
CaseType, | ||
DbScopedColsByKey, | ||
DbScopedColsByTableType, | ||
JoinTableWithCaseConvert, | ||
SplitScopedColumn, | ||
StrKey, | ||
UnwrapArrayMember, | ||
} from '@waiting/shared-types' | ||
import { DbDict } from 'kmore-types' | ||
import type { Knex } from 'knex' | ||
import { Span } from 'opentracing' | ||
// eslint-disable-next-line import/no-extraneous-dependencies | ||
import type { Span } from 'opentracing' | ||
export { CaseType } | ||
export type KnexConfig = Knex.Config | ||
@@ -26,6 +39,2 @@ export type KmoreTransaction = Knex.Transaction & { | ||
} | ||
// eslint-disable-next-line @typescript-eslint/ban-types | ||
export type KmoreQueryBuilder<TRecord extends {} = any, TResult = any> = | ||
Knex.QueryBuilder<TRecord, TResult> & { kmoreQueryId: symbol } | ||
export enum EnumClient { | ||
@@ -40,7 +49,8 @@ pg = 'pg', | ||
export enum CaseType { | ||
camel = 'camel', | ||
pascal = 'pascal', | ||
snake = 'snake', | ||
none = 'none' | ||
export enum SmartKey { | ||
join = 'smartJoin', | ||
leftJoin = 'smartLeftJoin', | ||
rightJoin = 'smartRightJoin', | ||
innerJoin = 'smartInnerJoin', | ||
crossJoin = 'smartCrossJoin', | ||
} | ||
@@ -55,10 +65,4 @@ | ||
/** ref_tb_name: () => knex('tb_name') */ | ||
// [tb in keyof D as `${Prefix}${tb & string}`]: TbQueryBuilder<D[tb]> | ||
[tb in keyof D as `${Prefix}${tb & string}`]: CaseConvert extends CaseType.camel | ||
? TbQueryBuilder<RecordCamelKeys<D[tb]>, Context> | ||
: CaseConvert extends CaseType.snake | ||
? TbQueryBuilder<RecordSnakeKeys<D[tb]>, Context> | ||
: CaseConvert extends CaseType.pascal | ||
? TbQueryBuilder<RecordPascalKeys<D[tb]>, Context> | ||
: TbQueryBuilder<D[tb], Context> | ||
[tb in keyof D as `${Prefix}${tb & string}`]: | ||
TbQueryBuilder<D, CaseConvert, CaseConvertTable<D[tb], CaseConvert>, Context> | ||
} | ||
@@ -71,22 +75,47 @@ | ||
export type TbQueryBuilder<TRecord, Context> = (ctx?: Context) => KmoreQueryBuilder<TRecord, TRecord[]> | ||
// export type TbQueryBuilder<TRecord> | ||
// = <CaseConvert extends CaseType = CaseType.none>(caseConvert?: CaseConvert) | ||
// => CaseConvert extends CaseType.camel | ||
// ? Knex.QueryBuilder<RecordCamelKeys<TRecord>, TRecord[]> | ||
// : CaseConvert extends CaseType.snake | ||
// ? Knex.QueryBuilder<RecordSnakeKeys<TRecord>, TRecord[]> | ||
// : CaseConvert extends CaseType.pascal | ||
// ? Knex.QueryBuilder<RecordPascalKeys<TRecord>, TRecord[]> | ||
// : Knex.QueryBuilder<TRecord, TRecord[]> | ||
export type TbQueryBuilder<D, CaseConvert extends CaseType, TRecord, Context> | ||
= (ctx?: Context) => KmoreQueryBuilder<D, CaseConvert, TRecord, TRecord[]> | ||
export type KmoreQueryBuilder< | ||
D = {}, CaseConvert extends CaseType = CaseType, TRecord extends {} = any, TResult = any> = | ||
Knex.QueryBuilder<TRecord, TResult> | ||
& QueryBuilderExtMethod<D, CaseConvert, TRecord> | ||
& QueryBuilderExtName<D> | ||
// export type QueryBuilderExt<TRecord, TResult = TRecord[]> | ||
// = Knex.QueryBuilder<TRecord, TResult> | ||
// export type TbQueryBuilder<TRecord> | ||
// = <KeyExcludeOptional extends keyof TRecord | void = void> | ||
// () => KeyExcludeOptional extends void | ||
// ? QueryBuilderExt<TRecord> | ||
// : QueryBuilderExt<Omit<TRecord, KeyExcludeOptional extends void ? never : KeyExcludeOptional>> | ||
interface QueryBuilderExtName<D extends {} = {}> { | ||
kmoreQueryId: symbol | ||
dbDict: DbDict<D> | ||
_tablesJoin: string[] | ||
} | ||
interface QueryBuilderExtMethod<D, CaseConvert extends CaseType, TRecord extends {} = any> { | ||
smartCrossJoin: SmartJoin<D, CaseConvert, TRecord> | ||
smartInnerJoin: SmartJoin<D, CaseConvert, TRecord> | ||
smartJoin: SmartJoin<D, CaseConvert, TRecord> | ||
smartLeftJoin: SmartJoin<D, CaseConvert, TRecord> | ||
smartRightJoin: SmartJoin<D, CaseConvert, TRecord> | ||
} | ||
type SmartJoin<D extends {}, CaseConvert extends CaseType, TResult = unknown[]> = < | ||
TRecord1 = UnwrapArrayMember<TResult>, | ||
C2 extends DbScopedColsByKey<D> = DbScopedColsByKey<D>, | ||
C1 extends DbScopedColsByKey<D> = DbScopedColsByTableType<D, TRecord1>, | ||
TTable2 extends StrKey<D> = SplitScopedColumn<D, C2>[0], | ||
TRecord2 extends D[TTable2] = D[TTable2], | ||
TResult2 = JoinTableWithCaseConvert<TRecord1, TRecord2 extends any ? D[TTable2] : TRecord2, TTable2, CaseConvert>, | ||
>( | ||
/** | ||
* scoped column name, e.g. 'tb_name.col_name', | ||
* <tb_name> is the table name be joined, <col_name> is the column name | ||
*/ | ||
scopedColumnBeJoined: C2, | ||
/** | ||
* scoped column name, e.g. 'tb_name.col_name', | ||
* <tb_name> is the upstream table name , <col_name> is the column name | ||
*/ | ||
scopedColumn: C1 extends C2 ? never : C1, | ||
) => KmoreQueryBuilder<D, CaseConvert, TResult2, TResult2[]> | ||
export type EventType = 'query' | 'queryError' | 'queryResponse' | 'start' | 'unknown' | ||
@@ -93,0 +122,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
195924
47
3274
5
268
Updated@waiting/shared-core@^20.5.0