@nocobase/database 0.17.0-alpha.7 → 0.18.0-alpha.1

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.
@@ -31,11 +31,11 @@ __export(collection_importer_exports, {
31
31
  ImporterReader: () => ImporterReader
32
32
  });
33
33
  module.exports = __toCommonJS(collection_importer_exports);
34
- var import_path = __toESM(require("path"));
34
+ var import_utils = require("@nocobase/utils");
35
35
  var import_fs = require("fs");
36
36
  var import_promises = require("fs/promises");
37
37
  var import_lodash = require("lodash");
38
- var import_utils = require("@nocobase/utils");
38
+ var import_path = __toESM(require("path"));
39
39
  const _ImporterReader = class _ImporterReader {
40
40
  directory;
41
41
  extensions;
@@ -59,8 +59,8 @@ const _ImporterReader = class _ImporterReader {
59
59
  }
60
60
  const ext = import_path.default.parse(fileName).ext.replace(".", "");
61
61
  return this.extensions.has(ext);
62
- }).map((fileName) => {
63
- const mod = (0, import_utils.requireModule)(import_path.default.join(this.directory, fileName));
62
+ }).map(async (fileName) => {
63
+ const mod = await (0, import_utils.importModule)(import_path.default.join(this.directory, fileName));
64
64
  return typeof mod === "function" ? mod() : mod;
65
65
  });
66
66
  return (await Promise.all(modules)).filter((module2) => (0, import_lodash.isPlainObject)(module2)).map((module2) => (0, import_lodash.cloneDeep)(module2));
@@ -1,6 +1,6 @@
1
1
  /// <reference types="node" />
2
2
  import { EventEmitter } from 'events';
3
- import { ModelOptions, ModelStatic, QueryInterfaceDropTableOptions, SyncOptions, Transactionable } from 'sequelize';
3
+ import { ModelOptions, ModelStatic, QueryInterfaceDropTableOptions, QueryInterfaceOptions, SyncOptions, Transactionable } from 'sequelize';
4
4
  import { Database } from './database';
5
5
  import { BelongsToField, Field, FieldOptions, HasManyField } from './fields';
6
6
  import { Model } from './model';
@@ -82,6 +82,7 @@ export declare class Collection<TModelAttributes extends {} = any, TCreationAttr
82
82
  setFields(fields: FieldOptions[], resetFields?: boolean): void;
83
83
  resetFields(): void;
84
84
  remove(): Collection<any, any>;
85
+ removeFieldFromDb(name: string, options?: QueryInterfaceOptions): Promise<void>;
85
86
  removeFromDb(options?: QueryInterfaceDropTableOptions): Promise<Collection<any, any>>;
86
87
  existsInDb(options?: Transactionable): Promise<boolean>;
87
88
  removeField(name: string): void | Field;
package/lib/collection.js CHANGED
@@ -286,6 +286,63 @@ const _Collection = class _Collection extends import_events.EventEmitter {
286
286
  remove() {
287
287
  return this.context.database.removeCollection(this.name);
288
288
  }
289
+ async removeFieldFromDb(name, options) {
290
+ const field = this.getField(name);
291
+ if (!field) {
292
+ return;
293
+ }
294
+ const attribute = this.model.rawAttributes[name];
295
+ if (!attribute) {
296
+ field.remove();
297
+ return;
298
+ }
299
+ if (this.isInherited() && this.parentFields().has(name)) {
300
+ return;
301
+ }
302
+ if (this.model._virtualAttributes.has(this.name)) {
303
+ field.remove();
304
+ return;
305
+ }
306
+ if (this.model.primaryKeyAttributes.includes(this.name)) {
307
+ return;
308
+ }
309
+ if (this.model.options.timestamps !== false) {
310
+ let timestampsFields = ["createdAt", "updatedAt", "deletedAt"];
311
+ if (this.db.options.underscored) {
312
+ timestampsFields = timestampsFields.map((fieldName) => (0, import_utils.snakeCase)(fieldName));
313
+ }
314
+ if (timestampsFields.includes(field.columnName())) {
315
+ this.fields.delete(name);
316
+ return;
317
+ }
318
+ }
319
+ const sortable = this.options.sortable;
320
+ if (sortable) {
321
+ let sortField;
322
+ if (sortable === true) {
323
+ sortField = "sort";
324
+ } else if (typeof sortable === "string") {
325
+ sortField = sortable;
326
+ } else if (sortable.name) {
327
+ sortField = sortable.name || "sort";
328
+ }
329
+ if (field.name === sortField) {
330
+ return;
331
+ }
332
+ }
333
+ if (this.isView()) {
334
+ field.remove();
335
+ return;
336
+ }
337
+ const columnReferencesCount = import_lodash.default.filter(this.model.rawAttributes, (attr) => attr.field == field.columnName()).length;
338
+ if (await field.existsInDb({
339
+ transaction: options == null ? void 0 : options.transaction
340
+ }) && columnReferencesCount == 1) {
341
+ const queryInterface = this.db.sequelize.getQueryInterface();
342
+ await queryInterface.removeColumn(this.getTableNameWithSchema(), field.columnName(), options);
343
+ }
344
+ field.remove();
345
+ }
289
346
  async removeFromDb(options) {
290
347
  if (!this.isView() && await this.existsInDb({
291
348
  transaction: options == null ? void 0 : options.transaction
package/lib/database.js CHANGED
@@ -362,7 +362,7 @@ const _Database = class _Database extends import_events.EventEmitter {
362
362
  filename = filename.substring(0, filename.lastIndexOf(".")) || filename;
363
363
  this.migrations.add({
364
364
  name: namespace ? `${namespace}/${filename}` : filename,
365
- migration: (0, import_utils.requireModule)(file),
365
+ migration: file,
366
366
  context
367
367
  });
368
368
  }
@@ -1,4 +1,4 @@
1
- import { DataType, ModelAttributeColumnOptions, ModelIndexesOptions, QueryInterfaceOptions, SyncOptions, Transactionable } from 'sequelize';
1
+ import { DataType, ModelAttributeColumnOptions, ModelIndexesOptions, SyncOptions, Transactionable } from 'sequelize';
2
2
  import { Collection } from '../collection';
3
3
  import { Database } from '../database';
4
4
  import { ModelEventTypes } from '../types';
@@ -33,7 +33,6 @@ export declare abstract class Field {
33
33
  get(name: string): any;
34
34
  remove(): void | Field;
35
35
  columnName(): any;
36
- removeFromDb(options?: QueryInterfaceOptions): Promise<void>;
37
36
  existsInDb(options?: Transactionable): Promise<boolean>;
38
37
  merge(obj: any): void;
39
38
  bind(): void;
@@ -86,62 +86,6 @@ const _Field = class _Field {
86
86
  }
87
87
  return this.name;
88
88
  }
89
- async removeFromDb(options) {
90
- const attribute = this.collection.model.rawAttributes[this.name];
91
- if (!attribute) {
92
- this.remove();
93
- return;
94
- }
95
- if (this.collection.isInherited() && this.collection.parentFields().has(this.name)) {
96
- return;
97
- }
98
- if (this.collection.model._virtualAttributes.has(this.name)) {
99
- this.remove();
100
- return;
101
- }
102
- if (this.collection.model.primaryKeyAttributes.includes(this.name)) {
103
- return;
104
- }
105
- if (this.collection.model.options.timestamps !== false) {
106
- let timestampsFields = ["createdAt", "updatedAt", "deletedAt"];
107
- if (this.database.options.underscored) {
108
- timestampsFields = timestampsFields.map((field) => (0, import_utils.snakeCase)(field));
109
- }
110
- if (timestampsFields.includes(this.columnName())) {
111
- this.collection.fields.delete(this.name);
112
- return;
113
- }
114
- }
115
- const sortable = this.collection.options.sortable;
116
- if (sortable) {
117
- let sortField;
118
- if (sortable === true) {
119
- sortField = "sort";
120
- } else if (typeof sortable === "string") {
121
- sortField = sortable;
122
- } else if (sortable.name) {
123
- sortField = sortable.name || "sort";
124
- }
125
- if (this.name === sortField) {
126
- return;
127
- }
128
- }
129
- if (this.collection.isView()) {
130
- this.remove();
131
- return;
132
- }
133
- const columnReferencesCount = import_lodash.default.filter(
134
- this.collection.model.rawAttributes,
135
- (attr) => attr.field == this.columnName()
136
- ).length;
137
- if (await this.existsInDb({
138
- transaction: options == null ? void 0 : options.transaction
139
- }) && columnReferencesCount == 1) {
140
- const queryInterface = this.database.sequelize.getQueryInterface();
141
- await queryInterface.removeColumn(this.collection.getTableNameWithSchema(), this.columnName(), options);
142
- }
143
- this.remove();
144
- }
145
89
  async existsInDb(options) {
146
90
  const opts = {
147
91
  transaction: options == null ? void 0 : options.transaction
@@ -20,7 +20,7 @@ export declare class Migration {
20
20
  }
21
21
  export interface MigrationItem {
22
22
  name: string;
23
- migration?: typeof Migration;
23
+ migration?: typeof Migration | string;
24
24
  context?: any;
25
25
  up?: any;
26
26
  down?: any;
package/lib/migration.js CHANGED
@@ -1,6 +1,8 @@
1
+ var __create = Object.create;
1
2
  var __defProp = Object.defineProperty;
2
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
4
6
  var __hasOwnProp = Object.prototype.hasOwnProperty;
5
7
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
6
8
  var __export = (target, all) => {
@@ -15,6 +17,14 @@ var __copyProps = (to, from, except, desc) => {
15
17
  }
16
18
  return to;
17
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
+ ));
18
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
29
  var migration_exports = {};
20
30
  __export(migration_exports, {
@@ -22,6 +32,8 @@ __export(migration_exports, {
22
32
  Migrations: () => Migrations
23
33
  });
24
34
  module.exports = __toCommonJS(migration_exports);
35
+ var import_utils = require("@nocobase/utils");
36
+ var import_lodash = __toESM(require("lodash"));
25
37
  const _Migration = class _Migration {
26
38
  name;
27
39
  context;
@@ -55,7 +67,7 @@ const _Migrations = class _Migrations {
55
67
  }
56
68
  add(item) {
57
69
  const Migration2 = item.migration;
58
- if (Migration2) {
70
+ if (Migration2 && typeof Migration2 === "function") {
59
71
  const migration = new Migration2({ ...this.context, ...item.context });
60
72
  migration.name = item.name;
61
73
  this.items.push(migration);
@@ -65,7 +77,20 @@ const _Migrations = class _Migrations {
65
77
  }
66
78
  callback() {
67
79
  return async (ctx) => {
68
- return this.items;
80
+ return await Promise.all(
81
+ import_lodash.default.sortBy(this.items, (item) => {
82
+ const keys = item.name.split("/");
83
+ return keys.pop() || item.name;
84
+ }).map(async (item) => {
85
+ if (typeof item.migration === "string") {
86
+ const Migration2 = await (0, import_utils.importModule)(item.migration);
87
+ const migration = new Migration2({ ...this.context, ...item.context });
88
+ migration.name = item.name;
89
+ return migration;
90
+ }
91
+ return item;
92
+ })
93
+ );
69
94
  };
70
95
  }
71
96
  };
@@ -34,11 +34,10 @@ __export(mock_database_exports, {
34
34
  });
35
35
  module.exports = __toCommonJS(mock_database_exports);
36
36
  var import_utils = require("@nocobase/utils");
37
- var import_path = require("path");
38
- var import_database = require("./database");
39
- var import_node_fetch = __toESM(require("node-fetch"));
40
- var import_path2 = __toESM(require("path"));
41
37
  var import_nanoid = require("nanoid");
38
+ var import_node_fetch = __toESM(require("node-fetch"));
39
+ var import_path = __toESM(require("path"));
40
+ var import_database = require("./database");
42
41
  const _MockDatabase = class _MockDatabase extends import_database.Database {
43
42
  constructor(options) {
44
43
  super({
@@ -59,7 +58,7 @@ function getConfigByEnv() {
59
58
  port: process.env.DB_PORT,
60
59
  dialect: process.env.DB_DIALECT || "sqlite",
61
60
  logging: process.env.DB_LOGGING === "on" ? customLogger : false,
62
- storage: process.env.DB_STORAGE && process.env.DB_STORAGE !== ":memory:" ? (0, import_path.resolve)(process.cwd(), process.env.DB_STORAGE) : ":memory:",
61
+ storage: (0, import_path.resolve)(process.cwd(), `storage/db-test/db-${(0, import_utils.uid)()}.sqlite`),
63
62
  define: {
64
63
  charset: "utf8mb4",
65
64
  collate: "utf8mb4_unicode_ci"
@@ -102,7 +101,7 @@ function mockDatabase(options = {}) {
102
101
  const instanceId = `d_${nanoid()}`;
103
102
  const databaseName = `${process.env["DB_TEST_PREFIX"]}_${instanceId}`;
104
103
  if (dbOptions.dialect === "sqlite") {
105
- dbOptions.storage = import_path2.default.resolve(import_path2.default.dirname(dbOptions.storage), databaseName);
104
+ dbOptions.storage = import_path.default.resolve(import_path.default.dirname(dbOptions.storage), databaseName);
106
105
  } else {
107
106
  dbOptions.database = databaseName;
108
107
  }
@@ -7,7 +7,6 @@ export declare class BelongsToManyRepository extends MultipleRelationRepository
7
7
  aggregate(options: AggregateOptions): Promise<any>;
8
8
  create(options?: CreateBelongsToManyOptions): Promise<any>;
9
9
  destroy(options?: TargetKey | TargetKey[] | DestroyOptions): Promise<boolean>;
10
- protected setTargets(call: 'add' | 'set', options: TargetKey | TargetKey[] | PrimaryKeyWithThroughValues | PrimaryKeyWithThroughValues[] | AssociatedOptions): Promise<void>;
11
10
  add(options: TargetKey | TargetKey[] | PrimaryKeyWithThroughValues | PrimaryKeyWithThroughValues[] | AssociatedOptions): Promise<void>;
12
11
  set(options: TargetKey | TargetKey[] | PrimaryKeyWithThroughValues | PrimaryKeyWithThroughValues[] | AssociatedOptions): Promise<void>;
13
12
  toggle(options: TargetKey | {
@@ -17,5 +16,6 @@ export declare class BelongsToManyRepository extends MultipleRelationRepository
17
16
  extendFindOptions(findOptions: any): any;
18
17
  throughName(): any;
19
18
  throughModel(): any;
19
+ protected setTargets(call: 'add' | 'set', options: TargetKey | TargetKey[] | PrimaryKeyWithThroughValues | PrimaryKeyWithThroughValues[] | AssociatedOptions): Promise<void>;
20
20
  }
21
21
  export {};
@@ -78,7 +78,9 @@ const _BelongsToManyRepository = class _BelongsToManyRepository extends import_m
78
78
  through: values[this.throughName()],
79
79
  transaction: transaction2
80
80
  };
81
- return sourceModel[createAccessor](values, createOptions);
81
+ const instance = await sourceModel[createAccessor](values, createOptions);
82
+ await (0, import_update_associations.updateAssociations)(instance, values, { ...options, transaction: transaction2 });
83
+ return instance;
82
84
  }
83
85
  async destroy(options) {
84
86
  const transaction2 = await this.getTransaction(options);
@@ -130,38 +132,6 @@ const _BelongsToManyRepository = class _BelongsToManyRepository extends import_m
130
132
  });
131
133
  return true;
132
134
  }
133
- async setTargets(call, options) {
134
- const handleKeys = this.convertTks(options);
135
- const transaction2 = await this.getTransaction(options, false);
136
- const sourceModel = await this.getSourceModel(transaction2);
137
- const setObj = handleKeys.reduce((carry, item) => {
138
- if (Array.isArray(item)) {
139
- carry[item[0]] = item[1];
140
- } else {
141
- carry[item] = true;
142
- }
143
- return carry;
144
- }, {});
145
- const targetKeys = Object.keys(setObj);
146
- const association = this.association;
147
- const targetObjects = await this.targetModel.findAll({
148
- where: {
149
- [association["targetKey"]]: targetKeys
150
- },
151
- transaction: transaction2
152
- });
153
- await sourceModel[this.accessors()[call]](targetObjects, {
154
- transaction: transaction2
155
- });
156
- for (const [id, throughValues] of Object.entries(setObj)) {
157
- if (typeof throughValues === "object") {
158
- const instance = await this.targetModel.findByPk(id, {
159
- transaction: transaction2
160
- });
161
- await (0, import_update_associations.updateThroughTableValue)(instance, this.throughName(), throughValues, sourceModel, transaction2);
162
- }
163
- }
164
- }
165
135
  async add(options) {
166
136
  await this.setTargets("add", options);
167
137
  }
@@ -203,6 +173,38 @@ const _BelongsToManyRepository = class _BelongsToManyRepository extends import_m
203
173
  throughModel() {
204
174
  return this.association.through.model;
205
175
  }
176
+ async setTargets(call, options) {
177
+ const handleKeys = this.convertTks(options);
178
+ const transaction2 = await this.getTransaction(options, false);
179
+ const sourceModel = await this.getSourceModel(transaction2);
180
+ const setObj = handleKeys.reduce((carry, item) => {
181
+ if (Array.isArray(item)) {
182
+ carry[item[0]] = item[1];
183
+ } else {
184
+ carry[item] = true;
185
+ }
186
+ return carry;
187
+ }, {});
188
+ const targetKeys = Object.keys(setObj);
189
+ const association = this.association;
190
+ const targetObjects = await this.targetModel.findAll({
191
+ where: {
192
+ [association["targetKey"]]: targetKeys
193
+ },
194
+ transaction: transaction2
195
+ });
196
+ await sourceModel[this.accessors()[call]](targetObjects, {
197
+ transaction: transaction2
198
+ });
199
+ for (const [id, throughValues] of Object.entries(setObj)) {
200
+ if (typeof throughValues === "object") {
201
+ const instance = await this.targetModel.findByPk(id, {
202
+ transaction: transaction2
203
+ });
204
+ await (0, import_update_associations.updateThroughTableValue)(instance, this.throughName(), throughValues, sourceModel, transaction2);
205
+ }
206
+ }
207
+ }
206
208
  };
207
209
  __name(_BelongsToManyRepository, "BelongsToManyRepository");
208
210
  __decorateClass([
package/lib/repository.js CHANGED
@@ -310,7 +310,6 @@ const _Repository = class _Repository {
310
310
  const filter = _Repository.valuesToFilter(values, filterKeys);
311
311
  const instance = await this.findOne({ filter, transaction: transaction2 });
312
312
  if (instance) {
313
- console.log(filter, instance.toJSON(), instance.get(this.collection.model.primaryKeyAttribute));
314
313
  return await this.update({
315
314
  filterByTk: instance.get(this.collection.filterTargetKey || this.collection.model.primaryKeyAttribute),
316
315
  values,
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@nocobase/database",
3
- "version": "0.17.0-alpha.7",
3
+ "version": "0.18.0-alpha.1",
4
4
  "description": "",
5
5
  "main": "./lib/index.js",
6
6
  "types": "./lib/index.d.ts",
7
7
  "license": "Apache-2.0",
8
8
  "dependencies": {
9
- "@nocobase/logger": "0.17.0-alpha.7",
10
- "@nocobase/utils": "0.17.0-alpha.7",
9
+ "@nocobase/logger": "0.18.0-alpha.1",
10
+ "@nocobase/utils": "0.18.0-alpha.1",
11
11
  "async-mutex": "^0.3.2",
12
12
  "chalk": "^4.1.1",
13
13
  "cron-parser": "4.4.0",
@@ -34,5 +34,5 @@
34
34
  "url": "git+https://github.com/nocobase/nocobase.git",
35
35
  "directory": "packages/database"
36
36
  },
37
- "gitHead": "91377a3abd1124f79fb3819f2d0e80905e091a32"
37
+ "gitHead": "0f5f1c0a37dc397a9dc4c8eec0c4ec20fd8107b0"
38
38
  }