@nocobase/database 0.9.1-alpha.2 → 0.9.2-alpha.2

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.
Files changed (168) hide show
  1. package/lib/collection-group-manager.d.ts +13 -0
  2. package/lib/collection-group-manager.js +91 -0
  3. package/lib/collection-importer.js +0 -24
  4. package/lib/collection.d.ts +24 -3
  5. package/lib/collection.js +176 -236
  6. package/lib/database-utils/index.js +3 -15
  7. package/lib/database.d.ts +3 -0
  8. package/lib/database.js +160 -298
  9. package/lib/decorators/must-have-filter-decorator.js +0 -7
  10. package/lib/decorators/transaction-decorator.js +5 -18
  11. package/lib/errors/identifier-error.js +0 -3
  12. package/lib/features/ReferencesMap.js +1 -14
  13. package/lib/features/referential-integrity-check.js +7 -21
  14. package/lib/field-repository/array-field-repository.js +5 -45
  15. package/lib/fields/array-field.js +0 -13
  16. package/lib/fields/belongs-to-field.js +24 -50
  17. package/lib/fields/belongs-to-many-field.js +23 -47
  18. package/lib/fields/boolean-field.js +0 -7
  19. package/lib/fields/context-field.js +2 -23
  20. package/lib/fields/date-field.d.ts +4 -0
  21. package/lib/fields/date-field.js +15 -7
  22. package/lib/fields/field.js +32 -85
  23. package/lib/fields/has-many-field.js +16 -49
  24. package/lib/fields/has-one-field.js +18 -52
  25. package/lib/fields/index.js +0 -44
  26. package/lib/fields/json-field.js +0 -12
  27. package/lib/fields/number-field.js +0 -23
  28. package/lib/fields/password-field.js +8 -35
  29. package/lib/fields/radio-field.js +0 -18
  30. package/lib/fields/relation-field.js +4 -16
  31. package/lib/fields/set-field.js +0 -8
  32. package/lib/fields/sort-field.js +84 -73
  33. package/lib/fields/string-field.js +0 -7
  34. package/lib/fields/text-field.js +0 -7
  35. package/lib/fields/time-field.js +0 -7
  36. package/lib/fields/uid-field.js +4 -22
  37. package/lib/fields/uuid-field.js +3 -12
  38. package/lib/fields/virtual-field.js +0 -7
  39. package/lib/filter-match.js +7 -22
  40. package/lib/filter-parser.js +37 -101
  41. package/lib/index.d.ts +3 -0
  42. package/lib/index.js +36 -42
  43. package/lib/inherited-collection.js +15 -62
  44. package/lib/inherited-map.js +7 -48
  45. package/lib/listeners/adjacency-list.d.ts +3 -0
  46. package/lib/listeners/adjacency-list.js +91 -0
  47. package/lib/listeners/index.d.ts +2 -0
  48. package/lib/listeners/index.js +12 -0
  49. package/lib/magic-attribute-model.js +58 -114
  50. package/lib/migration.js +7 -28
  51. package/lib/mock-database.d.ts +4 -4
  52. package/lib/mock-database.js +15 -18
  53. package/lib/model-hook.js +4 -35
  54. package/lib/model.js +12 -54
  55. package/lib/operators/array.js +2 -32
  56. package/lib/operators/association.js +0 -6
  57. package/lib/operators/boolean.js +0 -6
  58. package/lib/operators/child-collection.d.ts +2 -0
  59. package/lib/operators/child-collection.js +32 -0
  60. package/lib/operators/date.js +123 -60
  61. package/lib/operators/empty.js +3 -32
  62. package/lib/operators/eq.d.ts +2 -0
  63. package/lib/operators/eq.js +26 -0
  64. package/lib/operators/index.js +4 -7
  65. package/lib/operators/ne.js +5 -5
  66. package/lib/operators/notIn.js +0 -5
  67. package/lib/operators/string.js +0 -11
  68. package/lib/operators/utils.js +0 -6
  69. package/lib/options-parser.d.ts +1 -1
  70. package/lib/options-parser.js +47 -107
  71. package/lib/playground.js +0 -4
  72. package/lib/query-interface/mysql-query-interface.d.ts +11 -0
  73. package/lib/query-interface/mysql-query-interface.js +59 -10
  74. package/lib/query-interface/postgres-query-interface.d.ts +8 -0
  75. package/lib/query-interface/postgres-query-interface.js +70 -12
  76. package/lib/query-interface/query-interface-builder.js +0 -5
  77. package/lib/query-interface/query-interface.d.ts +12 -0
  78. package/lib/query-interface/query-interface.js +33 -3
  79. package/lib/query-interface/sqlite-query-interface.d.ts +11 -0
  80. package/lib/query-interface/sqlite-query-interface.js +61 -10
  81. package/lib/relation-repository/belongs-to-many-repository.js +21 -78
  82. package/lib/relation-repository/belongs-to-repository.js +0 -3
  83. package/lib/relation-repository/hasmany-repository.js +8 -44
  84. package/lib/relation-repository/hasone-repository.js +0 -3
  85. package/lib/relation-repository/multiple-relation-repository.js +14 -68
  86. package/lib/relation-repository/relation-repository.js +5 -42
  87. package/lib/relation-repository/single-relation-repository.js +5 -43
  88. package/lib/repository.d.ts +1 -0
  89. package/lib/repository.js +36 -182
  90. package/lib/sql-parser/index.js +10527 -0
  91. package/lib/sql-parser/sql.pegjs +1297 -0
  92. package/lib/sync-runner.js +19 -54
  93. package/lib/update-associations.js +58 -157
  94. package/lib/update-guard.js +10 -49
  95. package/lib/utils.js +6 -54
  96. package/lib/value-parsers/array-value-parser.js +3 -21
  97. package/lib/value-parsers/base-value-parser.js +0 -13
  98. package/lib/value-parsers/boolean-value-parser.js +4 -10
  99. package/lib/value-parsers/date-value-parser.js +0 -23
  100. package/lib/value-parsers/index.js +0 -10
  101. package/lib/value-parsers/json-value-parser.js +0 -7
  102. package/lib/value-parsers/number-value-parser.js +0 -9
  103. package/lib/value-parsers/string-value-parser.js +3 -20
  104. package/lib/value-parsers/to-many-value-parser.js +1 -42
  105. package/lib/value-parsers/to-one-value-parser.js +0 -14
  106. package/lib/view/field-type-map.d.ts +47 -0
  107. package/lib/view/field-type-map.js +56 -0
  108. package/lib/view/view-inference.d.ts +31 -0
  109. package/lib/view/view-inference.js +92 -0
  110. package/lib/view-collection.d.ts +6 -0
  111. package/lib/view-collection.js +24 -0
  112. package/package.json +4 -4
  113. package/src/__tests__/collection.test.ts +44 -0
  114. package/src/__tests__/fields/date.test.ts +75 -0
  115. package/src/__tests__/fields/sort-field.test.ts +100 -0
  116. package/src/__tests__/filter.test.ts +3 -3
  117. package/src/__tests__/group.test.ts +50 -0
  118. package/src/__tests__/inhertits/collection-inherits.test.ts +114 -0
  119. package/src/__tests__/operator/date-operator.test.ts +244 -98
  120. package/src/__tests__/operator/eq.test.ts +76 -0
  121. package/src/__tests__/operator/ne.test.ts +19 -1
  122. package/src/__tests__/relation-repository/belongs-to-many-repository.test.ts +82 -0
  123. package/src/__tests__/repository/find.test.ts +33 -0
  124. package/src/__tests__/repository.test.ts +88 -0
  125. package/src/__tests__/sql-parser.test.ts +13 -0
  126. package/src/__tests__/tree.test.ts +217 -0
  127. package/src/__tests__/view/list-view.test.ts +34 -0
  128. package/src/__tests__/view/view-collection.test.ts +199 -0
  129. package/src/__tests__/view/view-inference.test.ts +145 -0
  130. package/src/__tests__/view/view-repository.test.ts +67 -0
  131. package/src/collection-group-manager.ts +94 -0
  132. package/src/collection.ts +108 -14
  133. package/src/database-utils/index.ts +1 -0
  134. package/src/database.ts +79 -12
  135. package/src/features/ReferencesMap.ts +3 -2
  136. package/src/fields/belongs-to-many-field.ts +15 -2
  137. package/src/fields/date-field.ts +18 -0
  138. package/src/fields/field.ts +16 -8
  139. package/src/fields/json-field.ts +1 -0
  140. package/src/fields/sort-field.ts +90 -29
  141. package/src/filter-parser.ts +1 -0
  142. package/src/index.ts +3 -1
  143. package/src/listeners/adjacency-list.ts +60 -0
  144. package/src/listeners/index.ts +7 -0
  145. package/src/mock-database.ts +14 -2
  146. package/src/model.ts +4 -0
  147. package/src/operators/child-collection.ts +24 -0
  148. package/src/operators/date.ts +108 -24
  149. package/src/operators/eq.ts +14 -0
  150. package/src/operators/index.ts +2 -0
  151. package/src/operators/ne.ts +12 -7
  152. package/src/options-parser.ts +25 -11
  153. package/src/query-interface/mysql-query-interface.ts +53 -1
  154. package/src/query-interface/postgres-query-interface.ts +84 -3
  155. package/src/query-interface/query-interface.ts +31 -0
  156. package/src/query-interface/sqlite-query-interface.ts +62 -1
  157. package/src/relation-repository/belongs-to-many-repository.ts +20 -1
  158. package/src/relation-repository/hasmany-repository.ts +5 -3
  159. package/src/relation-repository/multiple-relation-repository.ts +9 -1
  160. package/src/repository.ts +6 -13
  161. package/src/sql-parser/index.js +10698 -0
  162. package/src/sql-parser/readme.md +2 -0
  163. package/src/sql-parser/sql.pegjs +1297 -0
  164. package/src/sync-runner.ts +13 -15
  165. package/src/update-associations.ts +26 -22
  166. package/src/view/field-type-map.ts +56 -0
  167. package/src/view/view-inference.ts +106 -0
  168. package/src/view-collection.ts +21 -0
@@ -1,6 +1,7 @@
1
1
  import QueryInterface from './query-interface';
2
2
  import { Collection } from '../collection';
3
3
  import { Transactionable } from 'sequelize';
4
+ import sqlParser from '../sql-parser';
4
5
 
5
6
  export default class MysqlQueryInterface extends QueryInterface {
6
7
  constructor(db) {
@@ -12,9 +13,60 @@ export default class MysqlQueryInterface extends QueryInterface {
12
13
 
13
14
  const tableName = collection.model.tableName;
14
15
  const databaseName = this.db.options.database;
15
- const sql = `SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = '${databaseName}' AND TABLE_NAME = '${tableName}'`;
16
+ const sql = `SELECT TABLE_NAME
17
+ FROM INFORMATION_SCHEMA.TABLES
18
+ WHERE TABLE_SCHEMA = '${databaseName}'
19
+ AND TABLE_NAME = '${tableName}'`;
16
20
 
17
21
  const results = await this.db.sequelize.query(sql, { type: 'SELECT', transaction });
18
22
  return results.length > 0;
19
23
  }
24
+
25
+ async listViews() {
26
+ const sql = `SELECT TABLE_NAME as name, VIEW_DEFINITION as definition
27
+ FROM information_schema.views
28
+ WHERE TABLE_SCHEMA = DATABASE()
29
+ ORDER BY TABLE_NAME;`;
30
+
31
+ return await this.db.sequelize.query(sql, { type: 'SELECT' });
32
+ }
33
+
34
+ async viewColumnUsage(options: { viewName: string; schema?: string }): Promise<{
35
+ [view_column_name: string]: {
36
+ column_name: string;
37
+ table_name: string;
38
+ table_schema?: string;
39
+ };
40
+ }> {
41
+ try {
42
+ const viewDefinition = await this.db.sequelize.query(`SHOW CREATE VIEW ${options.viewName}`, { type: 'SELECT' });
43
+ const createView = viewDefinition[0]['Create View'];
44
+ const regex = /(?<=AS\s)([\s\S]*)/i;
45
+ const match = createView.match(regex);
46
+ const sql = match[0];
47
+
48
+ const { ast } = sqlParser.parse(sql);
49
+
50
+ const columns = ast.columns;
51
+
52
+ const results = [];
53
+ for (const column of columns) {
54
+ if (column.expr.type === 'column_ref') {
55
+ results.push([
56
+ column.as || column.expr.column,
57
+ {
58
+ column_name: column.expr.column,
59
+ table_name: column.expr.table,
60
+ },
61
+ ]);
62
+ }
63
+ }
64
+
65
+ return Object.fromEntries(results);
66
+ } catch (e) {
67
+ this.db.logger.warn(e);
68
+
69
+ return {};
70
+ }
71
+ }
20
72
  }
@@ -1,5 +1,6 @@
1
1
  import QueryInterface from './query-interface';
2
2
  import { Collection } from '../collection';
3
+ import sqlParser from '../sql-parser';
3
4
 
4
5
  export default class PostgresQueryInterface extends QueryInterface {
5
6
  constructor(db) {
@@ -12,11 +13,91 @@ export default class PostgresQueryInterface extends QueryInterface {
12
13
  const tableName = collection.model.tableName;
13
14
  const schema = collection.collectionSchema() || 'public';
14
15
 
15
- const sql = `SELECT EXISTS(SELECT 1 FROM information_schema.tables
16
- WHERE table_schema = '${schema}'
17
- AND table_name = '${tableName}')`;
16
+ const sql = `SELECT EXISTS(SELECT 1
17
+ FROM information_schema.tables
18
+ WHERE table_schema = '${schema}'
19
+ AND table_name = '${tableName}')`;
18
20
 
19
21
  const results = await this.db.sequelize.query(sql, { type: 'SELECT', transaction });
20
22
  return results[0]['exists'];
21
23
  }
24
+
25
+ async listViews() {
26
+ const sql = `
27
+ SELECT viewname as name, definition, schemaname as schema
28
+ FROM pg_views
29
+ WHERE schemaname NOT IN ('pg_catalog', 'information_schema')
30
+ ORDER BY viewname;
31
+ `;
32
+
33
+ return await this.db.sequelize.query(sql, { type: 'SELECT' });
34
+ }
35
+
36
+ async viewColumnUsage(options): Promise<{
37
+ [view_column_name: string]: {
38
+ column_name: string;
39
+ table_name: string;
40
+ table_schema?: string;
41
+ };
42
+ }> {
43
+ const { viewName, schema = 'public' } = options;
44
+ const sql = `
45
+ SELECT *
46
+ FROM information_schema.view_column_usage
47
+ WHERE view_schema = '${schema}'
48
+ AND view_name = '${viewName}';
49
+ `;
50
+
51
+ const columnUsages = (await this.db.sequelize.query(sql, { type: 'SELECT' })) as Array<{
52
+ column_name: string;
53
+ table_name: string;
54
+ table_schema: string;
55
+ }>;
56
+
57
+ const viewDefQuery = await this.db.sequelize.query(
58
+ `
59
+ select pg_get_viewdef(format('%I.%I', '${schema}', '${viewName}')::regclass, true) as definition
60
+ `,
61
+ { type: 'SELECT' },
62
+ );
63
+
64
+ const def = viewDefQuery[0]['definition'];
65
+ try {
66
+ const { ast } = sqlParser.parse(def);
67
+ const columns = ast[0].columns;
68
+
69
+ const usages = columns
70
+ .map((column) => {
71
+ const fieldAlias = column.as || column.expr.column;
72
+ const columnUsage = columnUsages.find((columnUsage) => {
73
+ let columnExprTable = column.expr.table;
74
+
75
+ // handle column alias
76
+ const from = ast[0].from;
77
+ const findAs = from.find((from) => from.as === columnExprTable);
78
+
79
+ if (findAs) {
80
+ columnExprTable = findAs.table;
81
+ }
82
+
83
+ return columnUsage.column_name === column.expr.column && columnUsage.table_name === columnExprTable;
84
+ });
85
+
86
+ return [
87
+ fieldAlias,
88
+ columnUsage
89
+ ? {
90
+ ...columnUsage,
91
+ }
92
+ : null,
93
+ ];
94
+ })
95
+ .filter(([, columnUsage]) => columnUsage !== null);
96
+
97
+ return Object.fromEntries(usages);
98
+ } catch (e) {
99
+ this.db.logger.warn(e);
100
+ return {};
101
+ }
102
+ }
22
103
  }
@@ -4,9 +4,40 @@ import { QueryInterface as SequelizeQueryInterface, Transactionable } from 'sequ
4
4
 
5
5
  export default abstract class QueryInterface {
6
6
  sequelizeQueryInterface: SequelizeQueryInterface;
7
+
7
8
  protected constructor(public db: Database) {
8
9
  this.sequelizeQueryInterface = db.sequelize.getQueryInterface();
9
10
  }
10
11
 
11
12
  abstract collectionTableExists(collection: Collection, options?: Transactionable): Promise<boolean>;
13
+
14
+ abstract listViews();
15
+
16
+ abstract viewColumnUsage(options: { viewName: string; schema?: string }): Promise<{
17
+ [view_column_name: string]: {
18
+ column_name: string;
19
+ table_name: string;
20
+ table_schema?: string;
21
+ };
22
+ }>;
23
+
24
+ async dropAll(options) {
25
+ if (options.drop !== true) return;
26
+
27
+ const views = await this.listViews();
28
+
29
+ for (const view of views) {
30
+ let removeSql;
31
+
32
+ if (view.schema) {
33
+ removeSql = `DROP VIEW IF EXISTS "${view.schema}"."${view.name}"`;
34
+ } else {
35
+ removeSql = `DROP VIEW IF EXISTS ${view.name}`;
36
+ }
37
+
38
+ await this.db.sequelize.query(removeSql, { transaction: options.transaction });
39
+ }
40
+
41
+ await this.db.sequelize.getQueryInterface().dropAllTables(options);
42
+ }
12
43
  }
@@ -1,5 +1,6 @@
1
1
  import QueryInterface from './query-interface';
2
2
  import { Collection } from '../collection';
3
+ import sqlParser from '../sql-parser';
3
4
 
4
5
  export default class SqliteQueryInterface extends QueryInterface {
5
6
  constructor(db) {
@@ -11,8 +12,68 @@ export default class SqliteQueryInterface extends QueryInterface {
11
12
 
12
13
  const tableName = collection.model.tableName;
13
14
 
14
- const sql = `SELECT name FROM sqlite_master WHERE type='table' AND name='${tableName}';`;
15
+ const sql = `SELECT name
16
+ FROM sqlite_master
17
+ WHERE type = 'table'
18
+ AND name = '${tableName}';`;
15
19
  const results = await this.db.sequelize.query(sql, { type: 'SELECT', transaction });
16
20
  return results.length > 0;
17
21
  }
22
+
23
+ async listViews() {
24
+ const sql = `
25
+ SELECT name , sql as definition
26
+ FROM sqlite_master
27
+ WHERE type = 'view'
28
+ ORDER BY name;
29
+ `;
30
+
31
+ return await this.db.sequelize.query(sql, {
32
+ type: 'SELECT',
33
+ });
34
+ }
35
+
36
+ async viewColumnUsage(options: { viewName: string; schema?: string }): Promise<{
37
+ [view_column_name: string]: {
38
+ column_name: string;
39
+ table_name: string;
40
+ table_schema?: string;
41
+ };
42
+ }> {
43
+ try {
44
+ const viewDefinition = await this.db.sequelize.query(
45
+ `SELECT sql FROM sqlite_master WHERE name = '${options.viewName}' AND type = 'view'`,
46
+ {
47
+ type: 'SELECT',
48
+ },
49
+ );
50
+
51
+ const createView = viewDefinition[0]['sql'];
52
+ const regex = /(?<=AS\s)([\s\S]*)/i;
53
+ const match = createView.match(regex);
54
+ const sql = match[0];
55
+
56
+ const { ast } = sqlParser.parse(sql);
57
+
58
+ const columns = ast.columns;
59
+
60
+ const results = [];
61
+ for (const column of columns) {
62
+ if (column.expr.type === 'column_ref') {
63
+ results.push([
64
+ column.as || column.expr.column,
65
+ {
66
+ column_name: column.expr.column,
67
+ table_name: column.expr.table,
68
+ },
69
+ ]);
70
+ }
71
+ }
72
+
73
+ return Object.fromEntries(results);
74
+ } catch (e) {
75
+ this.db.logger.warn(e);
76
+ return {};
77
+ }
78
+ }
18
79
  }
@@ -11,20 +11,29 @@ type CreateBelongsToManyOptions = CreateOptions;
11
11
 
12
12
  interface IBelongsToManyRepository<M extends Model> {
13
13
  find(options?: FindOptions): Promise<M[]>;
14
+
14
15
  findAndCount(options?: FindAndCountOptions): Promise<[M[], number]>;
16
+
15
17
  findOne(options?: FindOneOptions): Promise<M>;
18
+
16
19
  // 新增并关联,存在中间表数据
17
20
  create(options?: CreateOptions): Promise<M>;
21
+
18
22
  // 更新,存在中间表数据
19
23
  update(options?: UpdateOptions): Promise<M>;
24
+
20
25
  // 删除
21
26
  destroy(options?: number | string | number[] | string[] | DestroyOptions): Promise<Boolean>;
27
+
22
28
  // 建立关联
23
29
  set(options: TargetKey | TargetKey[] | AssociatedOptions): Promise<void>;
30
+
24
31
  // 附加关联,存在中间表数据
25
32
  add(options: TargetKey | TargetKey[] | AssociatedOptions): Promise<void>;
33
+
26
34
  // 移除关联
27
35
  remove(options: TargetKey | TargetKey[] | AssociatedOptions): Promise<void>;
36
+
28
37
  toggle(options: TargetKey | { pk?: TargetKey; transaction?: Transaction }): Promise<void>;
29
38
  }
30
39
 
@@ -157,7 +166,17 @@ export class BelongsToManyRepository extends MultipleRelationRepository implemen
157
166
  return carry;
158
167
  }, {});
159
168
 
160
- await sourceModel[this.accessors()[call]](Object.keys(setObj), {
169
+ const targetKeys = Object.keys(setObj);
170
+ const association = this.association;
171
+
172
+ const targetObjects = await this.targetModel.findAll({
173
+ where: {
174
+ [association['targetKey']]: targetKeys,
175
+ },
176
+ transaction,
177
+ });
178
+
179
+ await sourceModel[this.accessors()[call]](targetObjects, {
161
180
  transaction,
162
181
  });
163
182
 
@@ -43,12 +43,14 @@ export class HasManyRepository extends MultipleRelationRepository implements IHa
43
43
  addFilter[this.associationField.targetKey] = options.filterByTk;
44
44
  }
45
45
 
46
- return await targetRepository.find({
47
- ...omit(options, ['filterByTk']),
46
+ const findOptions = {
47
+ ...omit(options, ['filterByTk', 'where', 'values', 'attributes']),
48
48
  filter: {
49
49
  $and: [options.filter || {}, addFilter],
50
50
  },
51
- });
51
+ };
52
+
53
+ return await targetRepository.find(findOptions);
52
54
  }
53
55
 
54
56
  @transaction((args, transaction) => {
@@ -80,10 +80,18 @@ export abstract class MultipleRelationRepository extends RelationRepository {
80
80
  });
81
81
  }
82
82
 
83
- return await sourceModel[getAccessor]({
83
+ const data = await sourceModel[getAccessor]({
84
84
  ...findOptions,
85
85
  transaction,
86
86
  });
87
+
88
+ await this.collection.db.emitAsync('afterRepositoryFind', {
89
+ findOptions: options,
90
+ dataCollection: this.collection,
91
+ data,
92
+ });
93
+
94
+ return data;
87
95
  }
88
96
 
89
97
  async findAndCount(options?: FindAndCountOptions): Promise<[any[], number]> {
package/src/repository.ts CHANGED
@@ -106,6 +106,7 @@ export interface CommonFindOptions extends Transactionable {
106
106
  except?: Except;
107
107
  sort?: Sort;
108
108
  context?: any;
109
+ tree?: boolean;
109
110
  }
110
111
 
111
112
  export type FindOneOptions = Omit<FindOptions, 'limit'>;
@@ -336,19 +337,11 @@ export class Repository<TModelAttributes extends {} = any, TCreationAttributes e
336
337
  });
337
338
  }
338
339
 
339
- if (this.collection.isParent()) {
340
- for (const row of rows) {
341
- const rowCollectionName = this.database.tableNameCollectionMap.get(
342
- options.raw ? row['__tableName'] : row.get('__tableName'),
343
- ).name;
344
-
345
- options.raw
346
- ? (row['__collection'] = rowCollectionName)
347
- : row.set('__collection', rowCollectionName, {
348
- raw: true,
349
- });
350
- }
351
- }
340
+ await this.collection.db.emitAsync('afterRepositoryFind', {
341
+ findOptions: options,
342
+ dataCollection: this.collection,
343
+ data: rows,
344
+ });
352
345
 
353
346
  return rows;
354
347
  }