@tachybase/database 0.23.8

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 (226) hide show
  1. package/.turbo/turbo-build.log +10 -0
  2. package/LICENSE +201 -0
  3. package/lib/collection-factory.d.ts +17 -0
  4. package/lib/collection-factory.js +52 -0
  5. package/lib/collection-group-manager.d.ts +26 -0
  6. package/lib/collection-group-manager.js +57 -0
  7. package/lib/collection-importer.d.ts +7 -0
  8. package/lib/collection-importer.js +74 -0
  9. package/lib/collection.d.ts +138 -0
  10. package/lib/collection.js +686 -0
  11. package/lib/database-utils/index.d.ts +9 -0
  12. package/lib/database-utils/index.js +71 -0
  13. package/lib/database-utils/traverseJSON.d.ts +10 -0
  14. package/lib/database-utils/traverseJSON.js +126 -0
  15. package/lib/database.d.ts +201 -0
  16. package/lib/database.js +765 -0
  17. package/lib/decorators/must-have-filter-decorator.d.ts +2 -0
  18. package/lib/decorators/must-have-filter-decorator.js +38 -0
  19. package/lib/decorators/target-collection-decorator.d.ts +2 -0
  20. package/lib/decorators/target-collection-decorator.js +47 -0
  21. package/lib/decorators/transaction-decorator.d.ts +1 -0
  22. package/lib/decorators/transaction-decorator.js +88 -0
  23. package/lib/eager-loading/eager-loading-tree.d.ts +31 -0
  24. package/lib/eager-loading/eager-loading-tree.js +439 -0
  25. package/lib/errors/identifier-error.d.ts +3 -0
  26. package/lib/errors/identifier-error.js +35 -0
  27. package/lib/errors/zero-column-table-error.d.ts +2 -0
  28. package/lib/errors/zero-column-table-error.js +31 -0
  29. package/lib/features/references-map.d.ts +18 -0
  30. package/lib/features/references-map.js +109 -0
  31. package/lib/features/referential-integrity-check.d.ts +8 -0
  32. package/lib/features/referential-integrity-check.js +83 -0
  33. package/lib/field-repository/array-field-repository.d.ts +28 -0
  34. package/lib/field-repository/array-field-repository.js +197 -0
  35. package/lib/fields/array-field.d.ts +11 -0
  36. package/lib/fields/array-field.js +57 -0
  37. package/lib/fields/belongs-to-field.d.ts +17 -0
  38. package/lib/fields/belongs-to-field.js +154 -0
  39. package/lib/fields/belongs-to-many-field.d.ts +20 -0
  40. package/lib/fields/belongs-to-many-field.js +187 -0
  41. package/lib/fields/boolean-field.d.ts +8 -0
  42. package/lib/fields/boolean-field.js +36 -0
  43. package/lib/fields/context-field.d.ts +14 -0
  44. package/lib/fields/context-field.js +70 -0
  45. package/lib/fields/date-field.d.ts +13 -0
  46. package/lib/fields/date-field.js +64 -0
  47. package/lib/fields/field.d.ts +43 -0
  48. package/lib/fields/field.js +156 -0
  49. package/lib/fields/has-inverse-field.d.ts +4 -0
  50. package/lib/fields/has-inverse-field.js +15 -0
  51. package/lib/fields/has-many-field.d.ts +68 -0
  52. package/lib/fields/has-many-field.js +156 -0
  53. package/lib/fields/has-one-field.d.ts +68 -0
  54. package/lib/fields/has-one-field.js +150 -0
  55. package/lib/fields/index.d.ts +46 -0
  56. package/lib/fields/index.js +65 -0
  57. package/lib/fields/json-field.d.ts +14 -0
  58. package/lib/fields/json-field.js +54 -0
  59. package/lib/fields/nanoid-field.d.ts +13 -0
  60. package/lib/fields/nanoid-field.js +58 -0
  61. package/lib/fields/number-field.d.ts +41 -0
  62. package/lib/fields/number-field.js +85 -0
  63. package/lib/fields/password-field.d.ts +21 -0
  64. package/lib/fields/password-field.js +95 -0
  65. package/lib/fields/radio-field.d.ts +16 -0
  66. package/lib/fields/radio-field.js +66 -0
  67. package/lib/fields/relation-field.d.ts +21 -0
  68. package/lib/fields/relation-field.js +79 -0
  69. package/lib/fields/set-field.d.ts +10 -0
  70. package/lib/fields/set-field.js +46 -0
  71. package/lib/fields/sort-field.d.ts +16 -0
  72. package/lib/fields/sort-field.js +187 -0
  73. package/lib/fields/string-field.d.ts +8 -0
  74. package/lib/fields/string-field.js +36 -0
  75. package/lib/fields/text-field.d.ts +8 -0
  76. package/lib/fields/text-field.js +36 -0
  77. package/lib/fields/time-field.d.ts +8 -0
  78. package/lib/fields/time-field.js +36 -0
  79. package/lib/fields/uid-field.d.ts +13 -0
  80. package/lib/fields/uid-field.js +63 -0
  81. package/lib/fields/uuid-field.d.ts +9 -0
  82. package/lib/fields/uuid-field.js +45 -0
  83. package/lib/fields/virtual-field.d.ts +8 -0
  84. package/lib/fields/virtual-field.js +36 -0
  85. package/lib/filter-match.d.ts +1 -0
  86. package/lib/filter-match.js +66 -0
  87. package/lib/filter-parser.d.ts +21 -0
  88. package/lib/filter-parser.js +230 -0
  89. package/lib/helpers.d.ts +3 -0
  90. package/lib/helpers.js +167 -0
  91. package/lib/index.d.ts +30 -0
  92. package/lib/index.js +114 -0
  93. package/lib/inherited-collection.d.ts +14 -0
  94. package/lib/inherited-collection.js +138 -0
  95. package/lib/inherited-map.d.ts +21 -0
  96. package/lib/inherited-map.js +113 -0
  97. package/lib/inherited-sync-runner.d.ts +4 -0
  98. package/lib/inherited-sync-runner.js +175 -0
  99. package/lib/listeners/adjacency-list.d.ts +2 -0
  100. package/lib/listeners/adjacency-list.js +42 -0
  101. package/lib/listeners/append-child-collection-name-after-repository-find.d.ts +6 -0
  102. package/lib/listeners/append-child-collection-name-after-repository-find.js +66 -0
  103. package/lib/listeners/index.d.ts +2 -0
  104. package/lib/listeners/index.js +33 -0
  105. package/lib/magic-attribute-model.d.ts +8 -0
  106. package/lib/magic-attribute-model.js +203 -0
  107. package/lib/migration.d.ts +35 -0
  108. package/lib/migration.js +103 -0
  109. package/lib/mock-database.d.ts +25 -0
  110. package/lib/mock-database.js +126 -0
  111. package/lib/model-hook.d.ts +12 -0
  112. package/lib/model-hook.js +92 -0
  113. package/lib/model.d.ts +23 -0
  114. package/lib/model.js +152 -0
  115. package/lib/operators/array.d.ts +2 -0
  116. package/lib/operators/array.js +158 -0
  117. package/lib/operators/association.d.ts +2 -0
  118. package/lib/operators/association.js +35 -0
  119. package/lib/operators/boolean.d.ts +2 -0
  120. package/lib/operators/boolean.js +38 -0
  121. package/lib/operators/child-collection.d.ts +2 -0
  122. package/lib/operators/child-collection.js +67 -0
  123. package/lib/operators/date.d.ts +2 -0
  124. package/lib/operators/date.js +140 -0
  125. package/lib/operators/empty.d.ts +5 -0
  126. package/lib/operators/empty.js +89 -0
  127. package/lib/operators/eq.d.ts +2 -0
  128. package/lib/operators/eq.js +35 -0
  129. package/lib/operators/index.d.ts +5 -0
  130. package/lib/operators/index.js +56 -0
  131. package/lib/operators/jsonb.d.ts +2 -0
  132. package/lib/operators/jsonb.js +50 -0
  133. package/lib/operators/ne.d.ts +2 -0
  134. package/lib/operators/ne.js +40 -0
  135. package/lib/operators/notIn.d.ts +2 -0
  136. package/lib/operators/notIn.js +33 -0
  137. package/lib/operators/string.d.ts +2 -0
  138. package/lib/operators/string.js +109 -0
  139. package/lib/operators/utils.d.ts +4 -0
  140. package/lib/operators/utils.js +40 -0
  141. package/lib/options-parser.d.ts +37 -0
  142. package/lib/options-parser.js +332 -0
  143. package/lib/playground.d.ts +1 -0
  144. package/lib/playground.js +43 -0
  145. package/lib/query-interface/mysql-query-interface.d.ts +35 -0
  146. package/lib/query-interface/mysql-query-interface.js +122 -0
  147. package/lib/query-interface/postgres-query-interface.d.ts +32 -0
  148. package/lib/query-interface/postgres-query-interface.js +189 -0
  149. package/lib/query-interface/query-interface-builder.d.ts +2 -0
  150. package/lib/query-interface/query-interface-builder.js +46 -0
  151. package/lib/query-interface/query-interface.d.ts +42 -0
  152. package/lib/query-interface/query-interface.js +46 -0
  153. package/lib/query-interface/sqlite-query-interface.d.ts +35 -0
  154. package/lib/query-interface/sqlite-query-interface.js +131 -0
  155. package/lib/relation-repository/belongs-to-many-repository.d.ts +21 -0
  156. package/lib/relation-repository/belongs-to-many-repository.js +280 -0
  157. package/lib/relation-repository/belongs-to-repository.d.ts +6 -0
  158. package/lib/relation-repository/belongs-to-repository.js +39 -0
  159. package/lib/relation-repository/hasmany-repository.d.ts +10 -0
  160. package/lib/relation-repository/hasmany-repository.js +182 -0
  161. package/lib/relation-repository/hasone-repository.d.ts +6 -0
  162. package/lib/relation-repository/hasone-repository.js +39 -0
  163. package/lib/relation-repository/multiple-relation-repository.d.ts +20 -0
  164. package/lib/relation-repository/multiple-relation-repository.js +229 -0
  165. package/lib/relation-repository/relation-repository.d.ts +29 -0
  166. package/lib/relation-repository/relation-repository.js +202 -0
  167. package/lib/relation-repository/single-relation-repository.d.ts +25 -0
  168. package/lib/relation-repository/single-relation-repository.js +162 -0
  169. package/lib/relation-repository/types.d.ts +7 -0
  170. package/lib/relation-repository/types.js +15 -0
  171. package/lib/repositories/tree-repository/adjacency-list-repository.d.ts +18 -0
  172. package/lib/repositories/tree-repository/adjacency-list-repository.js +183 -0
  173. package/lib/repositories/view-repository.d.ts +3 -0
  174. package/lib/repositories/view-repository.js +32 -0
  175. package/lib/repository.d.ts +206 -0
  176. package/lib/repository.js +597 -0
  177. package/lib/sql-collection/index.d.ts +2 -0
  178. package/lib/sql-collection/index.js +23 -0
  179. package/lib/sql-collection/query-generator.d.ts +10 -0
  180. package/lib/sql-collection/query-generator.js +70 -0
  181. package/lib/sql-collection/sql-collection.d.ts +7 -0
  182. package/lib/sql-collection/sql-collection.js +69 -0
  183. package/lib/sql-collection/sql-model.d.ts +16 -0
  184. package/lib/sql-collection/sql-model.js +168 -0
  185. package/lib/sql-parser/index.d.ts +10 -0
  186. package/lib/sql-parser/index.js +10699 -0
  187. package/lib/sql-parser/postgres.d.ts +10 -0
  188. package/lib/sql-parser/postgres.js +31506 -0
  189. package/lib/sql-parser/sql.pegjs +1297 -0
  190. package/lib/sync-runner.d.ts +30 -0
  191. package/lib/sync-runner.js +277 -0
  192. package/lib/types.d.ts +49 -0
  193. package/lib/types.js +15 -0
  194. package/lib/update-associations.d.ts +60 -0
  195. package/lib/update-associations.js +405 -0
  196. package/lib/update-guard.d.ts +28 -0
  197. package/lib/update-guard.js +202 -0
  198. package/lib/utils.d.ts +7 -0
  199. package/lib/utils.js +127 -0
  200. package/lib/value-parsers/array-value-parser.d.ts +8 -0
  201. package/lib/value-parsers/array-value-parser.js +58 -0
  202. package/lib/value-parsers/base-value-parser.d.ts +12 -0
  203. package/lib/value-parsers/base-value-parser.js +63 -0
  204. package/lib/value-parsers/boolean-value-parser.d.ts +4 -0
  205. package/lib/value-parsers/boolean-value-parser.js +52 -0
  206. package/lib/value-parsers/date-value-parser.d.ts +5 -0
  207. package/lib/value-parsers/date-value-parser.js +88 -0
  208. package/lib/value-parsers/index.d.ts +12 -0
  209. package/lib/value-parsers/index.js +78 -0
  210. package/lib/value-parsers/json-value-parser.d.ts +4 -0
  211. package/lib/value-parsers/json-value-parser.js +47 -0
  212. package/lib/value-parsers/number-value-parser.d.ts +4 -0
  213. package/lib/value-parsers/number-value-parser.js +58 -0
  214. package/lib/value-parsers/string-value-parser.d.ts +8 -0
  215. package/lib/value-parsers/string-value-parser.js +64 -0
  216. package/lib/value-parsers/to-many-value-parser.d.ts +13 -0
  217. package/lib/value-parsers/to-many-value-parser.js +108 -0
  218. package/lib/value-parsers/to-one-value-parser.d.ts +4 -0
  219. package/lib/value-parsers/to-one-value-parser.js +48 -0
  220. package/lib/view/field-type-map.d.ts +97 -0
  221. package/lib/view/field-type-map.js +90 -0
  222. package/lib/view/view-inference.d.ts +32 -0
  223. package/lib/view/view-inference.js +146 -0
  224. package/lib/view-collection.d.ts +6 -0
  225. package/lib/view-collection.js +45 -0
  226. package/package.json +38 -0
@@ -0,0 +1,765 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var database_exports = {};
30
+ __export(database_exports, {
31
+ Database: () => Database,
32
+ DialectVersionAccessors: () => DialectVersionAccessors,
33
+ default: () => database_default,
34
+ defineCollection: () => defineCollection,
35
+ extend: () => extend,
36
+ extendCollection: () => extendCollection
37
+ });
38
+ module.exports = __toCommonJS(database_exports);
39
+ var import_events = require("events");
40
+ var import_path = require("path");
41
+ var import_logger = require("@tachybase/logger");
42
+ var import_utils = require("@tachybase/utils");
43
+ var import_chalk = __toESM(require("chalk"));
44
+ var import_exponential_backoff = require("exponential-backoff");
45
+ var import_glob = require("glob");
46
+ var import_lodash = __toESM(require("lodash"));
47
+ var import_nanoid = require("nanoid");
48
+ var import_semver = __toESM(require("semver"));
49
+ var import_sequelize = require("sequelize");
50
+ var import_umzug = require("umzug");
51
+ var import_collection_factory = require("./collection-factory");
52
+ var import_collection_group_manager = require("./collection-group-manager");
53
+ var import_collection_importer = require("./collection-importer");
54
+ var import_database_utils = __toESM(require("./database-utils"));
55
+ var import_references_map = __toESM(require("./features/references-map"));
56
+ var import_referential_integrity_check = require("./features/referential-integrity-check");
57
+ var FieldTypes = __toESM(require("./fields"));
58
+ var import_helpers = require("./helpers");
59
+ var import_inherited_collection = require("./inherited-collection");
60
+ var import_inherited_map = __toESM(require("./inherited-map"));
61
+ var import_listeners = require("./listeners");
62
+ var import_migration = require("./migration");
63
+ var import_model_hook = require("./model-hook");
64
+ var import_operators = __toESM(require("./operators"));
65
+ var import_query_interface_builder = __toESM(require("./query-interface/query-interface-builder"));
66
+ var import_sql_collection = require("./sql-collection/sql-collection");
67
+ var import_utils2 = require("./utils");
68
+ var import_value_parsers = require("./value-parsers");
69
+ var import_view_collection = require("./view-collection");
70
+ const DialectVersionAccessors = {
71
+ sqlite: {
72
+ sql: "select sqlite_version() as version",
73
+ get: /* @__PURE__ */ __name((v) => v, "get")
74
+ },
75
+ mysql: {
76
+ sql: "select version() as version",
77
+ get: /* @__PURE__ */ __name((v) => {
78
+ const m = /([\d+.]+)/.exec(v);
79
+ return m[0];
80
+ }, "get")
81
+ },
82
+ mariadb: {
83
+ sql: "select version() as version",
84
+ get: /* @__PURE__ */ __name((v) => {
85
+ const m = /([\d+.]+)/.exec(v);
86
+ return m[0];
87
+ }, "get")
88
+ },
89
+ postgres: {
90
+ sql: "select version() as version",
91
+ get: /* @__PURE__ */ __name((v) => {
92
+ const m = /([\d+.]+)/.exec(v);
93
+ return import_semver.default.minVersion(m[0]).version;
94
+ }, "get")
95
+ }
96
+ };
97
+ const _DatabaseVersion = class _DatabaseVersion {
98
+ db;
99
+ constructor(db) {
100
+ this.db = db;
101
+ }
102
+ async satisfies(versions) {
103
+ var _a;
104
+ const accessors = DialectVersionAccessors;
105
+ for (const dialect of Object.keys(accessors)) {
106
+ if (this.db.inDialect(dialect)) {
107
+ if (!(versions == null ? void 0 : versions[dialect])) {
108
+ return false;
109
+ }
110
+ const [result] = await this.db.sequelize.query(accessors[dialect].sql);
111
+ const versionResult = accessors[dialect].get((_a = result == null ? void 0 : result[0]) == null ? void 0 : _a.version);
112
+ if (import_lodash.default.isPlainObject(versionResult) && versionResult.dialect) {
113
+ return import_semver.default.satisfies(versionResult.version, versions[versionResult.dialect]);
114
+ }
115
+ return import_semver.default.satisfies(versionResult, versions[dialect]);
116
+ }
117
+ }
118
+ return false;
119
+ }
120
+ };
121
+ __name(_DatabaseVersion, "DatabaseVersion");
122
+ let DatabaseVersion = _DatabaseVersion;
123
+ const _Database = class _Database extends import_events.EventEmitter {
124
+ sequelize;
125
+ migrator;
126
+ migrations;
127
+ fieldTypes = /* @__PURE__ */ new Map();
128
+ fieldValueParsers = /* @__PURE__ */ new Map();
129
+ options;
130
+ models = /* @__PURE__ */ new Map();
131
+ repositories = /* @__PURE__ */ new Map();
132
+ operators = /* @__PURE__ */ new Map();
133
+ collections = /* @__PURE__ */ new Map();
134
+ pendingFields = /* @__PURE__ */ new Map();
135
+ modelCollection = /* @__PURE__ */ new Map();
136
+ tableNameCollectionMap = /* @__PURE__ */ new Map();
137
+ context = {};
138
+ queryInterface;
139
+ utils = new import_database_utils.default(this);
140
+ referenceMap = new import_references_map.default();
141
+ inheritanceMap = new import_inherited_map.default();
142
+ importedFrom = /* @__PURE__ */ new Map();
143
+ modelHook;
144
+ version;
145
+ delayCollectionExtend = /* @__PURE__ */ new Map();
146
+ logger;
147
+ collectionGroupManager = new import_collection_group_manager.CollectionGroupManager(this);
148
+ collectionFactory = new import_collection_factory.CollectionFactory(this);
149
+ constructor(options) {
150
+ super();
151
+ this.setMaxListeners(50);
152
+ this.version = new DatabaseVersion(this);
153
+ const opts = {
154
+ sync: {
155
+ alter: {
156
+ drop: false
157
+ },
158
+ force: false
159
+ },
160
+ ...import_lodash.default.clone(options)
161
+ };
162
+ if (options.logger) {
163
+ if (typeof options.logger["log"] === "function") {
164
+ this.logger = options.logger;
165
+ } else {
166
+ this.logger = (0, import_logger.createLogger)(options.logger);
167
+ }
168
+ } else {
169
+ this.logger = (0, import_logger.createConsoleLogger)();
170
+ }
171
+ if (!options.instanceId) {
172
+ this._instanceId = (0, import_nanoid.nanoid)();
173
+ } else {
174
+ this._instanceId = options.instanceId;
175
+ }
176
+ if (options.storage && options.storage !== ":memory:") {
177
+ if (!(0, import_path.isAbsolute)(options.storage)) {
178
+ opts.storage = (0, import_path.resolve)(process.cwd(), options.storage);
179
+ }
180
+ }
181
+ if (options.dialect === "sqlite") {
182
+ delete opts.timezone;
183
+ } else if (!opts.timezone) {
184
+ opts.timezone = "+00:00";
185
+ }
186
+ if (options.dialect === "postgres") {
187
+ require("pg").defaults.parseInt8 = true;
188
+ }
189
+ this.options = opts;
190
+ const sequelizeOptions = this.sequelizeOptions(this.options);
191
+ this.sequelize = new import_sequelize.Sequelize(sequelizeOptions);
192
+ this.queryInterface = (0, import_query_interface_builder.default)(this);
193
+ this.collections = /* @__PURE__ */ new Map();
194
+ this.modelHook = new import_model_hook.ModelHook(this);
195
+ this.on("afterDefineCollection", (collection) => {
196
+ var _a, _b;
197
+ (_a = this.pendingFields.get(collection.name)) == null ? void 0 : _a.forEach((field) => field.bind());
198
+ (_b = this.delayCollectionExtend.get(collection.name)) == null ? void 0 : _b.forEach((collectionExtend) => {
199
+ collection.updateOptions(collectionExtend.collectionOptions, collectionExtend.mergeOptions);
200
+ });
201
+ });
202
+ for (const [name, field] of Object.entries(FieldTypes)) {
203
+ if (["Field", "RelationField"].includes(name)) {
204
+ continue;
205
+ }
206
+ let key = name.replace(/Field$/g, "");
207
+ key = key.substring(0, 1).toLowerCase() + key.substring(1);
208
+ this.registerFieldTypes({
209
+ [key]: field
210
+ });
211
+ }
212
+ (0, import_value_parsers.registerFieldValueParsers)(this);
213
+ this.initOperators();
214
+ const migratorOptions = this.options.migrator || {};
215
+ const context = {
216
+ db: this,
217
+ sequelize: this.sequelize,
218
+ queryInterface: this.sequelize.getQueryInterface(),
219
+ ...migratorOptions.context
220
+ };
221
+ this.migrations = new import_migration.Migrations(context);
222
+ this.sequelize.beforeDefine((model, opts2) => {
223
+ if (this.options.tablePrefix) {
224
+ if (opts2.tableName && opts2.tableName.startsWith(this.options.tablePrefix)) {
225
+ return;
226
+ }
227
+ opts2.tableName = `${this.options.tablePrefix}${opts2.tableName || opts2.modelName || opts2.name.plural}`;
228
+ }
229
+ });
230
+ this.collection({
231
+ name: "migrations",
232
+ autoGenId: false,
233
+ timestamps: false,
234
+ dumpRules: "required",
235
+ origin: "@tachybase/database",
236
+ fields: [{ type: "string", name: "name", primaryKey: true }]
237
+ });
238
+ this.migrator = new import_umzug.Umzug({
239
+ logger: migratorOptions.logger || console,
240
+ migrations: this.migrations.callback(),
241
+ context,
242
+ storage: new import_umzug.SequelizeStorage({
243
+ tableName: `${this.options.tablePrefix || ""}migrations`,
244
+ modelName: "migrations",
245
+ ...migratorOptions.storage,
246
+ sequelize: this.sequelize
247
+ })
248
+ });
249
+ this.initListener();
250
+ (0, import_utils2.patchSequelizeQueryInterface)(this);
251
+ this.registerCollectionType();
252
+ }
253
+ _instanceId;
254
+ get instanceId() {
255
+ return this._instanceId;
256
+ }
257
+ createMigrator({ migrations }) {
258
+ const migratorOptions = this.options.migrator || {};
259
+ const context = {
260
+ db: this,
261
+ sequelize: this.sequelize,
262
+ queryInterface: this.sequelize.getQueryInterface(),
263
+ ...migratorOptions.context
264
+ };
265
+ return new import_umzug.Umzug({
266
+ logger: migratorOptions.logger || console,
267
+ migrations: Array.isArray(migrations) ? import_lodash.default.sortBy(migrations, (m) => m.name) : migrations,
268
+ context,
269
+ storage: new import_umzug.SequelizeStorage({
270
+ tableName: `${this.options.tablePrefix || ""}migrations`,
271
+ modelName: "migrations",
272
+ ...migratorOptions.storage,
273
+ sequelize: this.sequelize
274
+ })
275
+ });
276
+ }
277
+ setContext(context) {
278
+ this.context = context;
279
+ }
280
+ sequelizeOptions(options) {
281
+ if (options.dialect === "postgres") {
282
+ if (!options.hooks) {
283
+ options.hooks = {};
284
+ }
285
+ if (!options.hooks["afterConnect"]) {
286
+ options.hooks["afterConnect"] = [];
287
+ }
288
+ options.hooks["afterConnect"].push(async (connection) => {
289
+ await connection.query("SET search_path TO public;");
290
+ });
291
+ }
292
+ return options;
293
+ }
294
+ initListener() {
295
+ this.on("afterConnect", async (client) => {
296
+ if (this.inDialect("postgres")) {
297
+ await client.query("SET search_path = public");
298
+ }
299
+ });
300
+ this.on("beforeDefine", (model, options) => {
301
+ if (this.options.underscored && options.underscored === void 0) {
302
+ options.underscored = true;
303
+ }
304
+ });
305
+ this.on("afterCreate", async (instance) => {
306
+ var _a;
307
+ (_a = instance == null ? void 0 : instance.toChangedWithAssociations) == null ? void 0 : _a.call(instance);
308
+ });
309
+ this.on("afterUpdate", async (instance) => {
310
+ var _a;
311
+ (_a = instance == null ? void 0 : instance.toChangedWithAssociations) == null ? void 0 : _a.call(instance);
312
+ });
313
+ this.on("beforeDestroy", async (instance, options) => {
314
+ await (0, import_referential_integrity_check.referentialIntegrityCheck)({
315
+ db: this,
316
+ referencedInstance: instance,
317
+ transaction: options.transaction
318
+ });
319
+ });
320
+ this.on("afterRemoveCollection", (collection) => {
321
+ this.inheritanceMap.removeNode(collection.name);
322
+ });
323
+ this.on("afterDefine", (model) => {
324
+ if (import_lodash.default.get(this.options, "usingBigIntForId", true)) {
325
+ const idAttribute = model.rawAttributes["id"];
326
+ if (idAttribute && idAttribute.primaryKey) {
327
+ model.rawAttributes["id"].type = import_sequelize.DataTypes.BIGINT;
328
+ model.refreshAttributes();
329
+ }
330
+ }
331
+ });
332
+ this.on("afterUpdateCollection", (collection, options) => {
333
+ if (collection.options.schema) {
334
+ collection.model._schema = collection.options.schema;
335
+ }
336
+ if (collection.options.sql) {
337
+ collection.modelInit();
338
+ }
339
+ });
340
+ this.on("beforeDefineCollection", (options) => {
341
+ if (this.options.underscored && options.underscored === void 0) {
342
+ options.underscored = true;
343
+ }
344
+ if (options.underscored) {
345
+ if (import_lodash.default.get(options, "sortable.scopeKey")) {
346
+ options.sortable.scopeKey = (0, import_utils2.snakeCase)(options.sortable.scopeKey);
347
+ }
348
+ if (import_lodash.default.get(options, "indexes")) {
349
+ options.indexes = options.indexes.map((index) => {
350
+ if (index.fields) {
351
+ index.fields = index.fields.map((field) => {
352
+ return (0, import_utils2.snakeCase)(field);
353
+ });
354
+ }
355
+ return index;
356
+ });
357
+ }
358
+ }
359
+ if (this.options.schema && !options.schema) {
360
+ options.schema = this.options.schema;
361
+ }
362
+ });
363
+ this.on("afterDefineCollection", async (collection) => {
364
+ const options = collection.options;
365
+ if (options.origin) {
366
+ const existsSet = this.importedFrom.get(options.origin) || /* @__PURE__ */ new Set();
367
+ existsSet.add(collection.name);
368
+ this.importedFrom.set(options.origin, existsSet);
369
+ }
370
+ });
371
+ (0, import_listeners.registerBuiltInListeners)(this);
372
+ }
373
+ addMigration(item) {
374
+ return this.migrations.add(item);
375
+ }
376
+ addMigrations(options) {
377
+ const { namespace, context, extensions = ["js", "ts"], directory } = options;
378
+ const patten = `${directory}/*.{${extensions.join(",")}}`;
379
+ const files = (0, import_glob.globSync)(patten, {
380
+ ignore: ["**/*.d.ts"]
381
+ });
382
+ for (const file of files) {
383
+ let filename = (0, import_path.basename)(file);
384
+ filename = filename.substring(0, filename.lastIndexOf(".")) || filename;
385
+ this.migrations.add({
386
+ name: namespace ? `${namespace}/${filename}` : filename,
387
+ migration: file,
388
+ context
389
+ });
390
+ }
391
+ }
392
+ inDialect(...dialect) {
393
+ return dialect.includes(this.sequelize.getDialect());
394
+ }
395
+ isMySQLCompatibleDialect() {
396
+ return this.inDialect("mysql", "mariadb");
397
+ }
398
+ /**
399
+ * Add collection to database
400
+ * @param options
401
+ */
402
+ collection(options) {
403
+ options = import_lodash.default.cloneDeep(options);
404
+ if (this.options.underscored) {
405
+ options.underscored = true;
406
+ }
407
+ this.emit("beforeDefineCollection", options);
408
+ const collection = this.collectionFactory.createCollection(options);
409
+ this.collections.set(collection.name, collection);
410
+ this.emit("afterDefineCollection", collection);
411
+ return collection;
412
+ }
413
+ getTablePrefix() {
414
+ return this.options.tablePrefix || "";
415
+ }
416
+ getFieldByPath(path) {
417
+ if (!path) {
418
+ return;
419
+ }
420
+ const [collectionName, associationName, ...args] = path.split(".");
421
+ const collection = this.getCollection(collectionName);
422
+ if (!collection) {
423
+ return;
424
+ }
425
+ const field = collection.getField(associationName);
426
+ if (!field) {
427
+ return;
428
+ }
429
+ if (args.length > 0) {
430
+ return this.getFieldByPath(`${field == null ? void 0 : field.target}.${args.join(".")}`);
431
+ }
432
+ return field;
433
+ }
434
+ /**
435
+ * get exists collection by its name
436
+ * @param name
437
+ */
438
+ getCollection(name) {
439
+ var _a;
440
+ if (!name) {
441
+ return null;
442
+ }
443
+ const [collectionName, associationName] = name.split(".");
444
+ const collection = this.collections.get(collectionName);
445
+ if (associationName) {
446
+ const target = (_a = collection.getField(associationName)) == null ? void 0 : _a.target;
447
+ return target ? this.collections.get(target) : null;
448
+ }
449
+ return collection;
450
+ }
451
+ hasCollection(name) {
452
+ return !!this.getCollection(name);
453
+ }
454
+ removeCollection(name) {
455
+ const collection = this.collections.get(name);
456
+ this.emit("beforeRemoveCollection", collection);
457
+ collection.resetFields();
458
+ const result = this.collections.delete(name);
459
+ this.sequelize.modelManager.removeModel(collection.model);
460
+ if (result) {
461
+ this.emit("afterRemoveCollection", collection);
462
+ }
463
+ return collection;
464
+ }
465
+ getModel(name) {
466
+ return this.getCollection(name).model;
467
+ }
468
+ getRepository(name, relationId) {
469
+ var _a, _b, _c;
470
+ const [collection, relation] = name.split(".");
471
+ if (relation) {
472
+ return (_b = (_a = this.getRepository(collection)) == null ? void 0 : _a.relation(relation)) == null ? void 0 : _b.of(relationId);
473
+ }
474
+ return (_c = this.getCollection(name)) == null ? void 0 : _c.repository;
475
+ }
476
+ addPendingField(field) {
477
+ const associating = this.pendingFields;
478
+ const items = this.pendingFields.get(field.target) || [];
479
+ items.push(field);
480
+ associating.set(field.target, items);
481
+ }
482
+ removePendingField(field) {
483
+ const items = this.pendingFields.get(field.target) || [];
484
+ const index = items.indexOf(field);
485
+ if (index !== -1) {
486
+ delete items[index];
487
+ this.pendingFields.set(field.target, items);
488
+ }
489
+ }
490
+ registerFieldTypes(fieldTypes) {
491
+ for (const [type, fieldType] of Object.entries(fieldTypes)) {
492
+ this.fieldTypes.set(type, fieldType);
493
+ }
494
+ }
495
+ registerFieldValueParsers(parsers) {
496
+ for (const [type, parser] of Object.entries(parsers)) {
497
+ this.fieldValueParsers.set(type, parser);
498
+ }
499
+ }
500
+ buildFieldValueParser(field, ctx) {
501
+ const Parser = field && this.fieldValueParsers.has(field.type) ? this.fieldValueParsers.get(field.type) : this.fieldValueParsers.get("default");
502
+ const parser = new Parser(field, ctx);
503
+ return parser;
504
+ }
505
+ registerModels(models) {
506
+ for (const [type, schemaType] of Object.entries(models)) {
507
+ this.models.set(type, schemaType);
508
+ }
509
+ }
510
+ registerRepositories(repositories) {
511
+ for (const [type, schemaType] of Object.entries(repositories)) {
512
+ this.repositories.set(type, schemaType);
513
+ }
514
+ }
515
+ initOperators() {
516
+ const operators = /* @__PURE__ */ new Map();
517
+ for (const key in import_sequelize.Op) {
518
+ operators.set("$" + key, import_sequelize.Op[key]);
519
+ const val = import_sequelize.Utils.underscoredIf(key, true);
520
+ operators.set("$" + val, import_sequelize.Op[key]);
521
+ operators.set("$" + val.replace(/_/g, ""), import_sequelize.Op[key]);
522
+ }
523
+ this.operators = operators;
524
+ this.registerOperators({
525
+ ...import_operators.default
526
+ });
527
+ }
528
+ registerOperators(operators) {
529
+ for (const [key, operator] of Object.entries(operators)) {
530
+ this.operators.set(key, operator);
531
+ }
532
+ }
533
+ buildField(options, context) {
534
+ const { type } = options;
535
+ const Field2 = this.fieldTypes.get(type);
536
+ if (!Field2) {
537
+ throw Error(`unsupported field type ${type}`);
538
+ }
539
+ const { collection } = context;
540
+ if (options.field && collection.options.underscored && !collection.isView()) {
541
+ options.field = (0, import_utils2.snakeCase)(options.field);
542
+ }
543
+ if (Object.prototype.hasOwnProperty.call(options, "defaultValue") && options.defaultValue === null) {
544
+ delete options.defaultValue;
545
+ }
546
+ return new Field2(options, context);
547
+ }
548
+ async sync(options) {
549
+ const isMySQL = this.isMySQLCompatibleDialect();
550
+ if (isMySQL) {
551
+ await this.sequelize.query("SET FOREIGN_KEY_CHECKS = 0", null);
552
+ }
553
+ if (this.options.schema && this.inDialect("postgres")) {
554
+ await this.sequelize.query(`CREATE SCHEMA IF NOT EXISTS "${this.options.schema}"`, null);
555
+ }
556
+ const result = await this.sequelize.sync(options);
557
+ if (isMySQL) {
558
+ await this.sequelize.query("SET FOREIGN_KEY_CHECKS = 1", null);
559
+ }
560
+ return result;
561
+ }
562
+ async clean(options) {
563
+ const { drop, ...others } = options || {};
564
+ if (drop !== true) {
565
+ return;
566
+ }
567
+ if (this.options.schema) {
568
+ const tableNames = (await this.sequelize.getQueryInterface().showAllTables()).map((table) => {
569
+ return `"${this.options.schema}"."${table}"`;
570
+ });
571
+ const skip = options.skip || [];
572
+ for (const tableName of tableNames) {
573
+ if (skip.includes(tableName)) {
574
+ continue;
575
+ }
576
+ await this.sequelize.query(`DROP TABLE IF EXISTS ${tableName} CASCADE`);
577
+ }
578
+ return;
579
+ }
580
+ await this.queryInterface.dropAll(options);
581
+ }
582
+ async collectionExistsInDb(name, options) {
583
+ const collection = this.getCollection(name);
584
+ if (!collection) {
585
+ return false;
586
+ }
587
+ return await this.queryInterface.collectionTableExists(collection, options);
588
+ }
589
+ isSqliteMemory() {
590
+ return this.sequelize.getDialect() === "sqlite" && import_lodash.default.get(this.options, "storage") === ":memory:";
591
+ }
592
+ async auth(options = {}) {
593
+ const { retry = 10, ...others } = options;
594
+ const startingDelay = 50;
595
+ const timeMultiple = 2;
596
+ let attemptNumber = 1;
597
+ const authenticate = /* @__PURE__ */ __name(async () => {
598
+ try {
599
+ await this.sequelize.authenticate(others);
600
+ this.logger.info("connection has been established successfully.", { method: "auth" });
601
+ } catch (error) {
602
+ this.logger.warn(`attempt ${attemptNumber}/${retry}: Unable to connect to the database: ${error.message}`, {
603
+ method: "auth"
604
+ });
605
+ const nextDelay = startingDelay * Math.pow(timeMultiple, attemptNumber - 1);
606
+ attemptNumber++;
607
+ if (attemptNumber < retry) {
608
+ this.logger.warn(`will retry in ${nextDelay}ms...`, { method: "auth" });
609
+ }
610
+ throw error;
611
+ }
612
+ }, "authenticate");
613
+ try {
614
+ await (0, import_exponential_backoff.backOff)(authenticate, {
615
+ numOfAttempts: retry,
616
+ startingDelay,
617
+ timeMultiple
618
+ });
619
+ } catch (error) {
620
+ throw new Error("Connection failed, please check your database connection credentials and try again.");
621
+ }
622
+ }
623
+ async checkVersion() {
624
+ return await (0, import_helpers.checkDatabaseVersion)(this);
625
+ }
626
+ async prepare() {
627
+ if (this.isMySQLCompatibleDialect()) {
628
+ const result = await this.sequelize.query(`SHOW VARIABLES LIKE 'lower_case_table_names'`, { plain: true });
629
+ if ((result == null ? void 0 : result.Value) === "1" && !this.options.underscored) {
630
+ console.log(
631
+ `Your database lower_case_table_names=1, please add ${import_chalk.default.yellow("DB_UNDERSCORED=true")} to the .env file`
632
+ );
633
+ process.exit();
634
+ }
635
+ }
636
+ if (this.inDialect("postgres") && this.options.schema && this.options.schema !== "public") {
637
+ await this.sequelize.query(`CREATE SCHEMA IF NOT EXISTS "${this.options.schema}"`, null);
638
+ }
639
+ }
640
+ async reconnect() {
641
+ if (this.isSqliteMemory()) {
642
+ return;
643
+ }
644
+ const ConnectionManager2 = this.sequelize.dialect.connectionManager.constructor;
645
+ const connectionManager = new ConnectionManager2(this.sequelize.dialect, this.sequelize);
646
+ this.sequelize.dialect.connectionManager = connectionManager;
647
+ this.sequelize.connectionManager = connectionManager;
648
+ }
649
+ closed() {
650
+ return this.sequelize.connectionManager.pool._draining;
651
+ }
652
+ async close() {
653
+ var _a, _b;
654
+ if (this.isSqliteMemory()) {
655
+ return;
656
+ }
657
+ await this.emitAsync("beforeClose", this);
658
+ const closeResult = this.sequelize.close();
659
+ if ((_b = (_a = this.options) == null ? void 0 : _a.customHooks) == null ? void 0 : _b["afterClose"]) {
660
+ await this.options.customHooks["afterClose"](this);
661
+ }
662
+ return closeResult;
663
+ }
664
+ on(event, listener) {
665
+ const type = this.modelHook.match(event);
666
+ if (type && !this.modelHook.hasBoundEvent(type)) {
667
+ this.sequelize.addHook(type, this.modelHook.buildSequelizeHook(type));
668
+ this.modelHook.bindEvent(type);
669
+ }
670
+ return super.on(event, listener);
671
+ }
672
+ extendCollection(collectionOptions, mergeOptions) {
673
+ collectionOptions = import_lodash.default.cloneDeep(collectionOptions);
674
+ const collectionName = collectionOptions.name;
675
+ const existCollection = this.getCollection(collectionName);
676
+ if (existCollection) {
677
+ existCollection.updateOptions(collectionOptions, mergeOptions);
678
+ } else {
679
+ const existDelayExtends = this.delayCollectionExtend.get(collectionName) || [];
680
+ this.delayCollectionExtend.set(collectionName, [...existDelayExtends, { collectionOptions, mergeOptions }]);
681
+ }
682
+ }
683
+ async import(options) {
684
+ const reader = new import_collection_importer.ImporterReader(options.directory, options.extensions);
685
+ const modules = await reader.read();
686
+ const result = /* @__PURE__ */ new Map();
687
+ for (const module2 of modules) {
688
+ if (module2.extend) {
689
+ this.extendCollection(module2.collectionOptions, module2.mergeOptions);
690
+ } else {
691
+ const collection = this.collection({
692
+ ...module2,
693
+ origin: options.from
694
+ });
695
+ result.set(collection.name, collection);
696
+ }
697
+ }
698
+ return result;
699
+ }
700
+ registerCollectionType() {
701
+ this.collectionFactory.registerCollectionType(import_inherited_collection.InheritedCollection, {
702
+ condition: /* @__PURE__ */ __name((options) => {
703
+ return options.inherits && import_lodash.default.castArray(options.inherits).length > 0;
704
+ }, "condition")
705
+ });
706
+ this.collectionFactory.registerCollectionType(import_view_collection.ViewCollection, {
707
+ condition: /* @__PURE__ */ __name((options) => {
708
+ return options.viewName || options.view;
709
+ }, "condition"),
710
+ async onSync() {
711
+ return;
712
+ },
713
+ async onDump(dumper, collection) {
714
+ try {
715
+ const viewDef = await collection.db.queryInterface.viewDef(collection.getTableNameWithSchemaAsString());
716
+ dumper.writeSQLContent(`view-${collection.name}`, {
717
+ sql: [
718
+ `DROP VIEW IF EXISTS ${collection.getTableNameWithSchemaAsString()}`,
719
+ `CREATE VIEW ${collection.getTableNameWithSchemaAsString()} AS ${viewDef}`
720
+ ],
721
+ group: "required"
722
+ });
723
+ } catch (e) {
724
+ return;
725
+ }
726
+ return;
727
+ }
728
+ });
729
+ this.collectionFactory.registerCollectionType(import_sql_collection.SqlCollection, {
730
+ condition: /* @__PURE__ */ __name((options) => {
731
+ return options.sql;
732
+ }, "condition"),
733
+ async onSync() {
734
+ return;
735
+ },
736
+ async onDump(dumper, collection) {
737
+ return;
738
+ }
739
+ });
740
+ }
741
+ };
742
+ __name(_Database, "Database");
743
+ let Database = _Database;
744
+ function extendCollection(collectionOptions, mergeOptions) {
745
+ return {
746
+ collectionOptions,
747
+ mergeOptions,
748
+ extend: true
749
+ };
750
+ }
751
+ __name(extendCollection, "extendCollection");
752
+ const extend = extendCollection;
753
+ const defineCollection = /* @__PURE__ */ __name((collectionOptions) => {
754
+ return collectionOptions;
755
+ }, "defineCollection");
756
+ (0, import_utils.applyMixins)(Database, [import_utils.AsyncEmitter]);
757
+ var database_default = Database;
758
+ // Annotate the CommonJS export names for ESM import in node:
759
+ 0 && (module.exports = {
760
+ Database,
761
+ DialectVersionAccessors,
762
+ defineCollection,
763
+ extend,
764
+ extendCollection
765
+ });