vona-module-a-orm 5.0.60 → 5.0.61
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.
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { IMetadataCustomGenerateOptions } from '@cabloy/cli';
|
|
2
2
|
import { types as t } from '@babel/core';
|
|
3
|
+
import { __parseMagics } from './magic.ts';
|
|
3
4
|
|
|
4
5
|
export default async function (options: IMetadataCustomGenerateOptions): Promise<string> {
|
|
5
6
|
const { sceneName, moduleName, globFiles, cli } = options;
|
|
@@ -13,6 +14,7 @@ export default async function (options: IMetadataCustomGenerateOptions): Promise
|
|
|
13
14
|
const astNodes = ast.find(`@Model<$$$0>({$$$1})export class ${className} extends $$$2 {}`).match.$$$1;
|
|
14
15
|
const entityName = __parseEntityName(__getAstNode(astNodes as any, 'entity'));
|
|
15
16
|
const relations = __parseRelations(__getAstNode(astNodes as any, 'relations'));
|
|
17
|
+
const magics = __parseMagics(cli, ast, globFile, entityName);
|
|
16
18
|
const entityMetaName = `${entityName}Meta`;
|
|
17
19
|
const opionsName = `IModelOptions${beanNameCapitalize}`;
|
|
18
20
|
if (relations && relations.length > 0) {
|
|
@@ -41,6 +43,7 @@ export default async function (options: IMetadataCustomGenerateOptions): Promise
|
|
|
41
43
|
count<T extends IModelSelectCountParams<${entityName},${className},ModelJoins>, ModelJoins extends TypeModelsClassLikeGeneral | undefined = undefined>(params?: T, options?: IModelMethodOptions, modelJoins?: ModelJoins): Promise<BigNumber | undefined>;
|
|
42
44
|
aggregate<T extends IModelSelectAggrParams<${entityName},${className},ModelJoins>, ModelJoins extends TypeModelsClassLikeGeneral | undefined = undefined>(params?: T, options?: IModelMethodOptions, modelJoins?: ModelJoins): Promise<TypeModelAggrRelationResult<T>>;
|
|
43
45
|
group<T extends IModelSelectGroupParams<${entityName},${className},ModelJoins>, ModelJoins extends TypeModelsClassLikeGeneral | undefined = undefined>(params?: T, options?: IModelMethodOptions, modelJoins?: ModelJoins): Promise<TypeModelGroupRelationResult<${entityName}, T>[]>;
|
|
46
|
+
${magics.join('\n')}
|
|
44
47
|
}`);
|
|
45
48
|
contentModels.push(`'${moduleName}:${beanName}': ${className};`);
|
|
46
49
|
// only override cache.keyAux which not enough
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import type { BeanCliBase } from '@cabloy/cli';
|
|
2
|
+
import type { IGlobBeanFile } from '@cabloy/module-info';
|
|
3
|
+
import type GoGoCode from 'gogocode';
|
|
4
|
+
import { readFileSync } from 'node:fs';
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
import { ensureArray } from '@cabloy/utils';
|
|
7
|
+
import { toUpperCaseFirstChar } from '@cabloy/word-utils';
|
|
8
|
+
|
|
9
|
+
type TypeMagicFieldMethod = 'getBy' | 'selectBy';
|
|
10
|
+
type TypeMagicFieldOp = '' | 'eqI';
|
|
11
|
+
interface IMagicField {
|
|
12
|
+
type: 'auto' | 'number' | 'TableIdentity' | 'string' | 'boolean';
|
|
13
|
+
methods: TypeMagicFieldMethod | Array<TypeMagicFieldMethod>;
|
|
14
|
+
ops?: TypeMagicFieldOp | Array<TypeMagicFieldOp>;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// id/name/enabled/disabled/closed/active/current/
|
|
18
|
+
const __MagicFields: Record<string, IMagicField> = {
|
|
19
|
+
id: {
|
|
20
|
+
type: 'auto',
|
|
21
|
+
methods: 'getBy',
|
|
22
|
+
},
|
|
23
|
+
name: {
|
|
24
|
+
type: 'string',
|
|
25
|
+
methods: ['getBy', 'selectBy'],
|
|
26
|
+
ops: ['', 'eqI'],
|
|
27
|
+
},
|
|
28
|
+
enabled: {
|
|
29
|
+
type: 'boolean',
|
|
30
|
+
methods: ['getBy', 'selectBy'],
|
|
31
|
+
},
|
|
32
|
+
disabled: {
|
|
33
|
+
type: 'boolean',
|
|
34
|
+
methods: ['getBy', 'selectBy'],
|
|
35
|
+
},
|
|
36
|
+
closed: {
|
|
37
|
+
type: 'boolean',
|
|
38
|
+
methods: ['getBy', 'selectBy'],
|
|
39
|
+
},
|
|
40
|
+
active: {
|
|
41
|
+
type: 'boolean',
|
|
42
|
+
methods: ['getBy', 'selectBy'],
|
|
43
|
+
},
|
|
44
|
+
current: {
|
|
45
|
+
type: 'boolean',
|
|
46
|
+
methods: ['getBy', 'selectBy'],
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export function __parseMagics(cli: BeanCliBase, ast: GoGoCode.GoGoAST, globFile: IGlobBeanFile, entityName: string) {
|
|
51
|
+
const { className, file } = globFile;
|
|
52
|
+
const astImportEntity = ast.find(`import { ${entityName} } from '$$$0'`);
|
|
53
|
+
const fileEntity = path.join(path.dirname(file), (astImportEntity as any).value.source.value);
|
|
54
|
+
const entityInfo = __parseEntityInfo(cli, fileEntity, entityName);
|
|
55
|
+
const modelInfo = __parseModelInfo(cli, file, className);
|
|
56
|
+
const contentRecords: string[] = [];
|
|
57
|
+
for (const fieldName in __MagicFields) {
|
|
58
|
+
const magicField = __MagicFields[fieldName];
|
|
59
|
+
if (fieldName === 'id') {
|
|
60
|
+
if (!modelInfo.fieldNames.includes('getById') && entityInfo.idType) {
|
|
61
|
+
contentRecords.push(`getById<T extends IModelGetOptions<${entityName},${className}>>(id: ${entityInfo.idType}, options?: T): Promise<TypeModelRelationResult<${entityName}, ${className}, T> | undefined>;`);
|
|
62
|
+
}
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
if (!entityInfo.fieldNames.includes(fieldName)) continue;
|
|
66
|
+
for (const method of ensureArray(magicField.methods)!) {
|
|
67
|
+
const ops = ensureArray(magicField.ops || [''])!;
|
|
68
|
+
for (const op of ops) {
|
|
69
|
+
const actionName = `${method}${toUpperCaseFirstChar(fieldName)}${toUpperCaseFirstChar(op)}`;
|
|
70
|
+
if (modelInfo.fieldNames.includes(actionName)) continue;
|
|
71
|
+
if (method === 'getBy') {
|
|
72
|
+
contentRecords.push(`${actionName}<T extends IModelGetOptions<${entityName},${className}>>(${fieldName}?: ${magicField.type}, options?: T): Promise<TypeModelRelationResult<${entityName}, ${className}, T> | undefined>;`);
|
|
73
|
+
} else if (method === 'selectBy') {
|
|
74
|
+
contentRecords.push(`${actionName}<T extends IModelSelectParams<${entityName},${className},ModelJoins>, ModelJoins extends TypeModelsClassLikeGeneral | undefined = undefined>(${fieldName}?: ${magicField.type}, params?: T, options?: IModelMethodOptions, modelJoins?: ModelJoins): Promise<TypeModelRelationResult<${entityName}, ${className}, T>[]>;`);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return contentRecords;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function __parseEntityInfo(cli: BeanCliBase, fileEntity: string, entityName: string) {
|
|
83
|
+
const content = readFileSync(fileEntity).toString();
|
|
84
|
+
const regexpSimple = new RegExp(`export class ${entityName} extends.*?EntityBaseSimple.*?{`);
|
|
85
|
+
const regexpBase = new RegExp(`export class ${entityName} extends.*?EntityBase.*?{`);
|
|
86
|
+
let idType;
|
|
87
|
+
if (content.match(regexpSimple)) {
|
|
88
|
+
idType = 'number';
|
|
89
|
+
} else if (content.match(regexpBase)) {
|
|
90
|
+
idType = 'TableIdentity';
|
|
91
|
+
}
|
|
92
|
+
const ast = cli.helper.gogocode(content);
|
|
93
|
+
const astNodes = ast.find(`export class ${entityName} extends $$$0 {$$$1}`).match.$$$1;
|
|
94
|
+
const fieldNames: string[] = [];
|
|
95
|
+
for (const astNode of astNodes) {
|
|
96
|
+
fieldNames.push((astNode as any).key.name);
|
|
97
|
+
}
|
|
98
|
+
return { idType, fieldNames };
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function __parseModelInfo(cli: BeanCliBase, fileModel: string, modelName: string) {
|
|
102
|
+
const content = readFileSync(fileModel).toString();
|
|
103
|
+
const ast = cli.helper.gogocode(content);
|
|
104
|
+
const astNodes = ast.find(`export class ${modelName} extends $$$0 {$$$1}`).match.$$$1;
|
|
105
|
+
const fieldNames: string[] = [];
|
|
106
|
+
for (const astNode of astNodes) {
|
|
107
|
+
fieldNames.push((astNode as any).key.name);
|
|
108
|
+
}
|
|
109
|
+
return { fieldNames };
|
|
110
|
+
}
|
|
@@ -58,5 +58,6 @@ export declare class BeanModelCache<TRecord extends {} = {}> extends BeanModelCr
|
|
|
58
58
|
protected _checkDisableCacheEntityByOptions(options?: IModelMethodOptionsGeneral): boolean;
|
|
59
59
|
private __checkIfOnlyKey;
|
|
60
60
|
private __checkCacheKeyValid;
|
|
61
|
+
protected __get__(prop: string): ((fieldValue?: any, options?: any) => Promise<Partial<TRecord> | undefined>) | ((fieldValue?: any, params?: any, options?: any, modelJoins?: any) => Promise<any[]>) | undefined;
|
|
61
62
|
}
|
|
62
63
|
export {};
|
package/dist/index.js
CHANGED
|
@@ -10,6 +10,7 @@ import { swapDeps } from '@cabloy/deps';
|
|
|
10
10
|
import { prepareClassType, getTargetDecoratorRules, getTargetDecoratorRuleColumnsMap, Api, v, OrderMaxBase, OrderCoreBase, getSchemaDynamic, SymbolSchemaDynamicRefId, addSchemaDynamic, mergeFieldsOpenapiMetadata } from 'vona-module-a-openapi';
|
|
11
11
|
import { ZodMetadata } from '@cabloy/zod-openapi';
|
|
12
12
|
import z from 'zod';
|
|
13
|
+
import { parseFirstWord, toLowerCaseFirstChar } from '@cabloy/word-utils';
|
|
13
14
|
import { Broadcast, BeanBroadcastBase } from 'vona-module-a-broadcast';
|
|
14
15
|
import { Event, BeanEventBase } from 'vona-module-a-event';
|
|
15
16
|
import { Queue, BeanQueueBase } from 'vona-module-a-queue';
|
|
@@ -3520,6 +3521,41 @@ class BeanModelCache extends BeanModelCrud {
|
|
|
3520
3521
|
if (!columnId) return undefined;
|
|
3521
3522
|
return ['number', 'string', 'bigint', 'array'].includes(typeof where[columnId]) ? where[columnId] : undefined;
|
|
3522
3523
|
}
|
|
3524
|
+
__get__(prop) {
|
|
3525
|
+
if (prop.startsWith('getBy')) {
|
|
3526
|
+
const [fieldName, op] = __parseMagicField(prop.substring('getBy'.length));
|
|
3527
|
+
if (!fieldName) throw new Error(`invalid magic method: ${prop}`);
|
|
3528
|
+
return (fieldValue, options) => {
|
|
3529
|
+
const where = __combineMagicWhere(fieldName, op, fieldValue);
|
|
3530
|
+
return this.get(where, options);
|
|
3531
|
+
};
|
|
3532
|
+
} else if (prop.startsWith('selectBy')) {
|
|
3533
|
+
const [fieldName, op] = __parseMagicField(prop.substring('selectBy'.length));
|
|
3534
|
+
if (!fieldName) throw new Error(`invalid magic method: ${prop}`);
|
|
3535
|
+
return (fieldValue, params, options, modelJoins) => {
|
|
3536
|
+
const where = __combineMagicWhere(fieldName, op, fieldValue);
|
|
3537
|
+
const params2 = params ? deepExtend({}, params, {
|
|
3538
|
+
where
|
|
3539
|
+
}) : {
|
|
3540
|
+
where
|
|
3541
|
+
};
|
|
3542
|
+
return this.select(params2, options, modelJoins);
|
|
3543
|
+
};
|
|
3544
|
+
}
|
|
3545
|
+
}
|
|
3546
|
+
}
|
|
3547
|
+
function __combineMagicWhere(fieldName, op, fieldValue) {
|
|
3548
|
+
return {
|
|
3549
|
+
[fieldName]: fieldValue === undefined ? undefined : {
|
|
3550
|
+
[`_${op}_`]: fieldValue
|
|
3551
|
+
}
|
|
3552
|
+
};
|
|
3553
|
+
}
|
|
3554
|
+
function __parseMagicField(str) {
|
|
3555
|
+
const fieldName = parseFirstWord(str, true);
|
|
3556
|
+
if (!fieldName) return [fieldName, undefined];
|
|
3557
|
+
const op = toLowerCaseFirstChar(str.substring(fieldName.length)) || 'eq';
|
|
3558
|
+
return [fieldName, op];
|
|
3523
3559
|
}
|
|
3524
3560
|
|
|
3525
3561
|
var _dec$8, _dec2$8, _dec3$2, _class$8;
|