@strapi/database 4.2.0-beta.0 → 4.2.0-beta.3

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.
@@ -0,0 +1,55 @@
1
+ 'use strict';
2
+
3
+ const { createLifecyclesProvider } = require('../lifecycles');
4
+
5
+ describe('LifecycleProvider', () => {
6
+ describe('run', () => {
7
+ /** @type {import("../lifecycles").LifecycleProvider} */
8
+ let provider;
9
+ let dbMetadataGetStub = jest.fn(uid => ({ uid, name: 'TestModel' }));
10
+
11
+ beforeEach(() => {
12
+ const db = {
13
+ metadata: {
14
+ get: dbMetadataGetStub,
15
+ },
16
+ };
17
+ provider = createLifecyclesProvider(db);
18
+ provider.clear();
19
+ });
20
+
21
+ it('store state', async () => {
22
+ const expectedState = new Date().toISOString();
23
+
24
+ const subscriber = {
25
+ async beforeEvent(event) {
26
+ event.state = expectedState;
27
+ },
28
+ };
29
+ provider.subscribe(subscriber);
30
+
31
+ const stateBefore = await provider.run('beforeEvent', 'test-model', { id: 'instance-id' });
32
+
33
+ expect(stateBefore.get(subscriber)).toEqual(expectedState);
34
+ });
35
+
36
+ it('use shared state', async () => {
37
+ const expectedState = { value: new Date().toISOString() };
38
+ let receivedState;
39
+
40
+ provider.subscribe({
41
+ async beforeEvent(event) {
42
+ event.state.value = expectedState.value;
43
+ },
44
+ async afterEvent(event) {
45
+ receivedState = event.state;
46
+ },
47
+ });
48
+
49
+ const stateBefore = await provider.run('beforeEvent', 'test-model', { id: 'instance-id' });
50
+ await provider.run('afterEvent', 'test-model', { id: 'instance-id' }, stateBefore);
51
+
52
+ expect(receivedState).toEqual(expectedState);
53
+ });
54
+ });
55
+ });
@@ -0,0 +1,64 @@
1
+ /* eslint-disable node/no-missing-require */
2
+ /* eslint-disable node/no-extraneous-require */
3
+ 'use strict';
4
+
5
+ const knex = require('knex');
6
+
7
+ const SqliteClient = require('knex/lib/dialects/sqlite3/index');
8
+
9
+ const trySqlitePackage = packageName => {
10
+ try {
11
+ require.resolve(packageName);
12
+ return packageName;
13
+ } catch (error) {
14
+ if (error.code === 'MODULE_NOT_FOUND') {
15
+ return false;
16
+ }
17
+ throw error;
18
+ }
19
+ };
20
+ class LegacySqliteClient extends SqliteClient {
21
+ _driver() {
22
+ return require('sqlite3');
23
+ }
24
+ }
25
+
26
+ const clientMap = {
27
+ 'better-sqlite3': 'better-sqlite3',
28
+ '@vscode/sqlite3': 'sqlite',
29
+ sqlite3: LegacySqliteClient,
30
+ };
31
+
32
+ const getSqlitePackageName = () => {
33
+ // NOTE: allow forcing the package to use (mostly used for testing purposes)
34
+ if (typeof process.env.SQLITE_PKG !== 'undefined') {
35
+ return process.env.SQLITE_PKG;
36
+ }
37
+
38
+ // NOTE: this tries to find the best sqlite module possible to use
39
+ // while keeping retro compatibility
40
+ return (
41
+ trySqlitePackage('better-sqlite3') ||
42
+ trySqlitePackage('@vscode/sqlite3') ||
43
+ trySqlitePackage('sqlite3')
44
+ );
45
+ };
46
+
47
+ const createConnection = config => {
48
+ const knexConfig = { ...config };
49
+ if (knexConfig.client === 'sqlite') {
50
+ const sqlitePackageName = getSqlitePackageName();
51
+
52
+ knexConfig.client = clientMap[sqlitePackageName];
53
+ }
54
+
55
+ const knexInstance = knex(knexConfig);
56
+
57
+ return Object.assign(knexInstance, {
58
+ getSchemaName() {
59
+ return this.client.connectionSettings.schema;
60
+ },
61
+ });
62
+ };
63
+
64
+ module.exports = createConnection;
@@ -48,7 +48,7 @@ const toStrapiType = column => {
48
48
  switch (rootType) {
49
49
  case 'int': {
50
50
  if (column.column_key === 'PRI') {
51
- return { type: 'increments', args: [{ primary: true }], unsigned: false };
51
+ return { type: 'increments', args: [{ primary: true, primaryKey: true }], unsigned: false };
52
52
  }
53
53
 
54
54
  return { type: 'integer' };
@@ -16,7 +16,7 @@ const toStrapiType = column => {
16
16
  switch (rootType) {
17
17
  case 'integer': {
18
18
  if (column.pk) {
19
- return { type: 'increments', args: [{ primary: true }] };
19
+ return { type: 'increments', args: [{ primary: true, primaryKey: true }] };
20
20
  }
21
21
 
22
22
  return { type: 'integer' };
@@ -113,33 +113,33 @@ const createEntityManager = db => {
113
113
 
114
114
  return {
115
115
  async findOne(uid, params) {
116
- await db.lifecycles.run('beforeFindOne', uid, { params });
116
+ const states = await db.lifecycles.run('beforeFindOne', uid, { params });
117
117
 
118
118
  const result = await this.createQueryBuilder(uid)
119
119
  .init(params)
120
120
  .first()
121
121
  .execute();
122
122
 
123
- await db.lifecycles.run('afterFindOne', uid, { params, result });
123
+ await db.lifecycles.run('afterFindOne', uid, { params, result }, states);
124
124
 
125
125
  return result;
126
126
  },
127
127
 
128
128
  // should we name it findOne because people are used to it ?
129
129
  async findMany(uid, params) {
130
- await db.lifecycles.run('beforeFindMany', uid, { params });
130
+ const states = await db.lifecycles.run('beforeFindMany', uid, { params });
131
131
 
132
132
  const result = await this.createQueryBuilder(uid)
133
133
  .init(params)
134
134
  .execute();
135
135
 
136
- await db.lifecycles.run('afterFindMany', uid, { params, result });
136
+ await db.lifecycles.run('afterFindMany', uid, { params, result }, states);
137
137
 
138
138
  return result;
139
139
  },
140
140
 
141
- async count(uid, params = {}) {
142
- await db.lifecycles.run('beforeCount', uid, { params });
141
+ async count(uid, params) {
142
+ const states = await db.lifecycles.run('beforeCount', uid, { params });
143
143
 
144
144
  const res = await this.createQueryBuilder(uid)
145
145
  .init(_.pick(['_q', 'where', 'filters'], params))
@@ -149,13 +149,13 @@ const createEntityManager = db => {
149
149
 
150
150
  const result = Number(res.count);
151
151
 
152
- await db.lifecycles.run('afterCount', uid, { params, result });
152
+ await db.lifecycles.run('afterCount', uid, { params, result }, states);
153
153
 
154
154
  return result;
155
155
  },
156
156
 
157
157
  async create(uid, params = {}) {
158
- await db.lifecycles.run('beforeCreate', uid, { params });
158
+ const states = await db.lifecycles.run('beforeCreate', uid, { params });
159
159
 
160
160
  const metadata = db.metadata.get(uid);
161
161
  const { data } = params;
@@ -166,10 +166,12 @@ const createEntityManager = db => {
166
166
 
167
167
  const dataToInsert = processData(metadata, data, { withDefaults: true });
168
168
 
169
- const [id] = await this.createQueryBuilder(uid)
169
+ const res = await this.createQueryBuilder(uid)
170
170
  .insert(dataToInsert)
171
171
  .execute();
172
172
 
173
+ const id = res[0].id || res[0];
174
+
173
175
  await this.attachRelations(uid, id, data);
174
176
 
175
177
  // TODO: in case there is no select or populate specified return the inserted data ?
@@ -180,14 +182,14 @@ const createEntityManager = db => {
180
182
  populate: params.populate,
181
183
  });
182
184
 
183
- await db.lifecycles.run('afterCreate', uid, { params, result });
185
+ await db.lifecycles.run('afterCreate', uid, { params, result }, states);
184
186
 
185
187
  return result;
186
188
  },
187
189
 
188
190
  // TODO: where do we handle relation processing for many queries ?
189
191
  async createMany(uid, params = {}) {
190
- await db.lifecycles.run('beforeCreateMany', uid, { params });
192
+ const states = await db.lifecycles.run('beforeCreateMany', uid, { params });
191
193
 
192
194
  const metadata = db.metadata.get(uid);
193
195
  const { data } = params;
@@ -208,13 +210,13 @@ const createEntityManager = db => {
208
210
 
209
211
  const result = { count: data.length };
210
212
 
211
- await db.lifecycles.run('afterCreateMany', uid, { params, result });
213
+ await db.lifecycles.run('afterCreateMany', uid, { params, result }, states);
212
214
 
213
215
  return result;
214
216
  },
215
217
 
216
218
  async update(uid, params = {}) {
217
- await db.lifecycles.run('beforeUpdate', uid, { params });
219
+ const states = await db.lifecycles.run('beforeUpdate', uid, { params });
218
220
 
219
221
  const metadata = db.metadata.get(uid);
220
222
  const { where, data } = params;
@@ -257,14 +259,14 @@ const createEntityManager = db => {
257
259
  populate: params.populate,
258
260
  });
259
261
 
260
- await db.lifecycles.run('afterUpdate', uid, { params, result });
262
+ await db.lifecycles.run('afterUpdate', uid, { params, result }, states);
261
263
 
262
264
  return result;
263
265
  },
264
266
 
265
267
  // TODO: where do we handle relation processing for many queries ?
266
268
  async updateMany(uid, params = {}) {
267
- await db.lifecycles.run('beforeUpdateMany', uid, { params });
269
+ const states = await db.lifecycles.run('beforeUpdateMany', uid, { params });
268
270
 
269
271
  const metadata = db.metadata.get(uid);
270
272
  const { where, data } = params;
@@ -282,13 +284,13 @@ const createEntityManager = db => {
282
284
 
283
285
  const result = { count: updatedRows };
284
286
 
285
- await db.lifecycles.run('afterUpdateMany', uid, { params, result });
287
+ await db.lifecycles.run('afterUpdateMany', uid, { params, result }, states);
286
288
 
287
289
  return result;
288
290
  },
289
291
 
290
292
  async delete(uid, params = {}) {
291
- await db.lifecycles.run('beforeDelete', uid, { params });
293
+ const states = await db.lifecycles.run('beforeDelete', uid, { params });
292
294
 
293
295
  const { where, select, populate } = params;
294
296
 
@@ -316,14 +318,14 @@ const createEntityManager = db => {
316
318
 
317
319
  await this.deleteRelations(uid, id);
318
320
 
319
- await db.lifecycles.run('afterDelete', uid, { params, result: entity });
321
+ await db.lifecycles.run('afterDelete', uid, { params, result: entity }, states);
320
322
 
321
323
  return entity;
322
324
  },
323
325
 
324
326
  // TODO: where do we handle relation processing for many queries ?
325
327
  async deleteMany(uid, params = {}) {
326
- await db.lifecycles.run('beforeDeleteMany', uid, { params });
328
+ const states = await db.lifecycles.run('beforeDeleteMany', uid, { params });
327
329
 
328
330
  const { where } = params;
329
331
 
@@ -334,7 +336,7 @@ const createEntityManager = db => {
334
336
 
335
337
  const result = { count: deletedRows };
336
338
 
337
- await db.lifecycles.run('afterDelete', uid, { params, result });
339
+ await db.lifecycles.run('afterDeleteMany', uid, { params, result }, states);
338
340
 
339
341
  return result;
340
342
  },
package/lib/index.d.ts CHANGED
@@ -2,16 +2,37 @@ import { LifecycleProvider } from './lifecycles';
2
2
  import { MigrationProvider } from './migrations';
3
3
  import { SchemaProvideer } from './schema';
4
4
 
5
- type BooleanWhere<T> = {
5
+ type LogicOperators<T> = {
6
6
  $and?: WhereParams<T>[];
7
7
  $or?: WhereParams<T>[];
8
8
  $not?: WhereParams<T>;
9
- };
9
+ }
10
+
11
+ type AttributeOperators<T, K extends keyof T> = {
12
+ $eq?: T[K];
13
+ $ne?: T[K];
14
+ $in?: T[K][];
15
+ $notIn?: T[K][];
16
+ $lt?: T[K];
17
+ $lte?: T[K];
18
+ $gt?: T[K];
19
+ $gte?: T[K];
20
+ $between?: [T[K], T[K]];
21
+ $contains?: T[K];
22
+ $notContains?: T[K];
23
+ $containsi?: T[K];
24
+ $notContainsi?: T[K];
25
+ $startsWith?: T[K];
26
+ $endsWith?: T[K];
27
+ $null?: boolean;
28
+ $notNull?: boolean;
29
+ $not?: WhereParams<T> | AttributeOperators<T, K>;
30
+ }
10
31
 
11
- type WhereParams<T> = {
12
- [K in keyof T]?: T[K];
32
+ export type WhereParams<T> = {
33
+ [K in keyof T]?: T[K] | T[K][] | AttributeOperators<T, K>;
13
34
  } &
14
- BooleanWhere<T>;
35
+ LogicOperators<T>;
15
36
 
16
37
  type Sortables<T> = {
17
38
  // check sortable
package/lib/index.js CHANGED
@@ -1,28 +1,17 @@
1
1
  'use strict';
2
2
 
3
- const knex = require('knex');
4
-
5
3
  const { getDialect } = require('./dialects');
6
4
  const createSchemaProvider = require('./schema');
7
5
  const createMetadata = require('./metadata');
8
6
  const { createEntityManager } = require('./entity-manager');
9
7
  const { createMigrationsProvider } = require('./migrations');
10
8
  const { createLifecyclesProvider } = require('./lifecycles');
9
+ const createConnection = require('./connection');
11
10
  const errors = require('./errors');
12
11
 
13
12
  // TODO: move back into strapi
14
13
  const { transformContentTypes } = require('./utils/content-types');
15
14
 
16
- const createConnection = config => {
17
- const knexInstance = knex(config);
18
-
19
- return Object.assign(knexInstance, {
20
- getSchemaName() {
21
- return this.client.connectionSettings.schema;
22
- },
23
- });
24
- };
25
-
26
15
  class Database {
27
16
  constructor(config) {
28
17
  this.metadata = createMetadata(config.models);
@@ -43,7 +43,8 @@ export interface Event {
43
43
  export interface LifecycleProvider {
44
44
  subscribe(subscriber: Subscriber): () => void;
45
45
  clear(): void;
46
- run(action: Action, uid: string, properties: any): Promise<void>;
46
+ run(action: Action, uid: string, properties: any): Promise<Map<any, any>>;
47
+ run(action: Action, uid: string, properties: any, states: Map<any, any>): Promise<Map<any, any>>;
47
48
  createEvent(action: Action, uid: string, properties: any): Event;
48
49
  }
49
50
 
@@ -30,21 +30,39 @@ const createLifecyclesProvider = db => {
30
30
  subscribers = [];
31
31
  },
32
32
 
33
- createEvent(action, uid, properties) {
33
+ /**
34
+ * @param {string} action
35
+ * @param {string} uid
36
+ * @param {{ params?: any, result?: any }} properties
37
+ * @param {Map<any, any>} state
38
+ */
39
+ createEvent(action, uid, properties, state) {
34
40
  const model = db.metadata.get(uid);
35
41
 
36
42
  return {
37
43
  action,
38
44
  model,
45
+ state,
39
46
  ...properties,
40
47
  };
41
48
  },
42
49
 
43
- async run(action, uid, properties) {
44
- for (const subscriber of subscribers) {
50
+ /**
51
+ * @param {string} action
52
+ * @param {string} uid
53
+ * @param {{ params?: any, result?: any }} properties
54
+ * @param {Map<any, any>} states
55
+ */
56
+ async run(action, uid, properties, states = new Map()) {
57
+ for (let i = 0; i < subscribers.length; i++) {
58
+ const subscriber = subscribers[i];
45
59
  if (typeof subscriber === 'function') {
46
- const event = this.createEvent(action, uid, properties);
60
+ const state = states.get(subscriber) || {};
61
+ const event = this.createEvent(action, uid, properties, state);
47
62
  await subscriber(event);
63
+ if (event.state) {
64
+ states.set(subscriber, event.state || state);
65
+ }
48
66
  continue;
49
67
  }
50
68
 
@@ -52,11 +70,17 @@ const createLifecyclesProvider = db => {
52
70
  const hasModel = !subscriber.models || subscriber.models.includes(uid);
53
71
 
54
72
  if (hasAction && hasModel) {
55
- const event = this.createEvent(action, uid, properties);
73
+ const state = states.get(subscriber) || {};
74
+ const event = this.createEvent(action, uid, properties, state);
56
75
 
57
76
  await subscriber[action](event);
77
+ if (event.state) {
78
+ states.set(subscriber, event.state);
79
+ }
58
80
  }
59
81
  }
82
+
83
+ return states;
60
84
  },
61
85
  };
62
86
  };
@@ -2,24 +2,35 @@
2
2
 
3
3
  const path = require('path');
4
4
  const fse = require('fs-extra');
5
- const Umzug = require('umzug');
5
+ const { Umzug } = require('umzug');
6
6
 
7
7
  const createStorage = require('./storage');
8
8
 
9
+ const wrapTransaction = db => fn => () =>
10
+ db.getConnection().transaction(trx => Promise.resolve(fn(trx)));
11
+
9
12
  // TODO: check multiple commands in one sql statement
10
- const migrationResolver = path => {
13
+ const migrationResolver = ({ name, path, context }) => {
14
+ const { db } = context;
15
+
11
16
  // if sql file run with knex raw
12
17
  if (path.match(/\.sql$/)) {
13
18
  const sql = fse.readFileSync(path, 'utf8');
14
19
 
15
20
  return {
16
- up: knex => knex.raw(sql),
21
+ name,
22
+ up: wrapTransaction(db)(knex => knex.raw(sql)),
17
23
  down() {},
18
24
  };
19
25
  }
20
26
 
21
27
  // NOTE: we can add some ts register if we want to handle ts migration files at some point
22
- return require(path);
28
+ const migration = require(path);
29
+ return {
30
+ name,
31
+ up: wrapTransaction(db)(migration.up),
32
+ down: wrapTransaction(db)(migration.down),
33
+ };
23
34
  };
24
35
 
25
36
  const createUmzugProvider = db => {
@@ -27,17 +38,12 @@ const createUmzugProvider = db => {
27
38
 
28
39
  fse.ensureDirSync(migrationDir);
29
40
 
30
- const wrapFn = fn => db => db.getConnection().transaction(trx => Promise.resolve(fn(trx)));
31
- const storage = createStorage({ db, tableName: 'strapi_migrations' });
32
-
33
41
  return new Umzug({
34
- storage,
42
+ storage: createStorage({ db, tableName: 'strapi_migrations' }),
43
+ context: { db },
35
44
  migrations: {
36
- path: migrationDir,
37
- pattern: /\.(js|sql)$/,
38
- params: [db],
39
- wrap: wrapFn,
40
- customResolver: migrationResolver,
45
+ glob: ['*.{js,sql}', { cwd: migrationDir }],
46
+ resolve: migrationResolver,
41
47
  },
42
48
  });
43
49
  };
@@ -14,21 +14,21 @@ const createStorage = (opts = {}) => {
14
14
  };
15
15
 
16
16
  return {
17
- async logMigration(migrationName) {
17
+ async logMigration({ name }) {
18
18
  await db
19
19
  .getConnection()
20
20
  .insert({
21
- name: migrationName,
21
+ name,
22
22
  time: new Date(),
23
23
  })
24
24
  .into(tableName);
25
25
  },
26
26
 
27
- async unlogMigration(migrationName) {
27
+ async unlogMigration({ name }) {
28
28
  await db
29
29
  .getConnection(tableName)
30
30
  .del()
31
- .where({ name: migrationName });
31
+ .where({ name });
32
32
  },
33
33
 
34
34
  async executed() {
@@ -105,7 +105,7 @@ const getColumnType = attribute => {
105
105
  case 'increments': {
106
106
  return {
107
107
  type: 'increments',
108
- args: [{ primary: true }],
108
+ args: [{ primary: true, primaryKey: true }],
109
109
  notNullable: true,
110
110
  };
111
111
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@strapi/database",
3
- "version": "4.2.0-beta.0",
3
+ "version": "4.2.0-beta.3",
4
4
  "description": "Strapi's database layer",
5
5
  "homepage": "https://strapi.io",
6
6
  "bugs": {
@@ -34,13 +34,13 @@
34
34
  "date-fns": "2.22.1",
35
35
  "debug": "4.3.1",
36
36
  "fs-extra": "10.0.0",
37
- "knex": "0.95.6",
37
+ "knex": "1.0.4",
38
38
  "lodash": "4.17.21",
39
- "umzug": "2.3.0"
39
+ "umzug": "3.1.1"
40
40
  },
41
41
  "engines": {
42
42
  "node": ">=12.22.0 <=16.x.x",
43
43
  "npm": ">=6.0.0"
44
44
  },
45
- "gitHead": "db70f0de7cc73fb469c8a076b89530729cf14142"
45
+ "gitHead": "c4addbad6ecbc8ef7633bbba3806f3b0a2ae5f49"
46
46
  }
@@ -1,36 +0,0 @@
1
- 'use strict';
2
-
3
- const postgres = {
4
- client: 'postgres',
5
- connection: {
6
- database: 'strapi',
7
- user: 'strapi',
8
- password: 'strapi',
9
- },
10
- // debug: true,
11
- };
12
-
13
- const mysql = {
14
- client: 'mysql',
15
- connection: {
16
- database: 'strapi',
17
- user: 'strapi',
18
- password: 'strapi',
19
- },
20
- // debug: true,
21
- };
22
-
23
- const sqlite = {
24
- client: 'sqlite',
25
- connection: {
26
- filename: 'data.sqlite',
27
- },
28
- useNullAsDefault: true,
29
- // debug: true,
30
- };
31
-
32
- module.exports = {
33
- sqlite,
34
- postgres,
35
- mysql,
36
- };
@@ -1,29 +0,0 @@
1
- version: '3'
2
-
3
- services:
4
- postgres:
5
- image: postgres
6
- restart: always
7
- volumes:
8
- - ./data/postgresql:/var/lib/postgresql/data
9
- environment:
10
- POSTGRES_USER: strapi
11
- POSTGRES_PASSWORD: strapi
12
- POSTGRES_DB: strapi
13
- ports:
14
- - '5432:5432'
15
-
16
- mysql:
17
- image: mysql
18
- restart: always
19
- command: --default-authentication-plugin=mysql_native_password
20
- environment:
21
- MYSQL_DATABASE: strapi
22
- MYSQL_USER: strapi
23
- MYSQL_PASSWORD: strapi
24
- MYSQL_ROOT_HOST: '%'
25
- MYSQL_ROOT_PASSWORD: strapi
26
- volumes:
27
- - ./data/mysql:/var/lib/mysql
28
- ports:
29
- - '3306:3306'
package/examples/index.js DELETED
@@ -1,73 +0,0 @@
1
- 'use strict';
2
-
3
- const util = require('util');
4
-
5
- const { Database } = require('../lib/index');
6
- const models = require('./models');
7
- const connections = require('./connections');
8
-
9
- async function main(connection) {
10
- const orm = await Database.init({
11
- connection,
12
- models: Database.transformContentTypes(models),
13
- });
14
-
15
- try {
16
- // await orm.schema.drop();
17
- // await orm.schema.create();
18
-
19
- await orm.schema.reset();
20
-
21
- let res;
22
-
23
- const c1 = await orm.query('comment').create({
24
- data: {
25
- title: 'coucou',
26
- },
27
- });
28
-
29
- const c2 = await orm.query('video-comment').create({
30
- data: {
31
- title: 'coucou',
32
- },
33
- });
34
-
35
- res = await orm.query('article').create({
36
- data: {
37
- dz: [
38
- {
39
- __type: 'comment',
40
- id: c1.id,
41
- },
42
- {
43
- __type: 'video-comment',
44
- id: c2.id,
45
- },
46
- ],
47
- },
48
- populate: {
49
- dz: true,
50
- },
51
- });
52
-
53
- log(res);
54
-
55
- res = await orm.query('article').findMany({
56
- populate: {
57
- dz: true,
58
- },
59
- });
60
-
61
- log(res);
62
-
63
- // await tests(orm);
64
- } finally {
65
- orm.destroy();
66
- }
67
- }
68
-
69
- function log(res) {
70
- console.log(util.inspect(res, null, null, true));
71
- }
72
-
73
- main(connections.sqlite);
@@ -1,341 +0,0 @@
1
- 'use strict';
2
-
3
- const category = {
4
- modelName: 'category',
5
- uid: 'category',
6
- collectionName: 'categories',
7
- attributes: {
8
- title: {
9
- type: 'string',
10
- },
11
- price: {
12
- type: 'integer',
13
- required: true,
14
- default: 12,
15
-
16
- column: {
17
- unique: true,
18
- nonNullable: true,
19
- unsigned: true,
20
- defaultTo: 12,
21
- },
22
- },
23
- articles: {
24
- type: 'relation',
25
- relation: 'oneToMany',
26
- target: 'article',
27
- mappedBy: 'category',
28
- },
29
- compo: {
30
- type: 'component',
31
- component: 'compo',
32
- },
33
- },
34
- };
35
-
36
- const article = {
37
- modelName: 'article',
38
- uid: 'article',
39
- collectionName: 'articles',
40
- attributes: {
41
- title: {
42
- type: 'string',
43
- },
44
- category: {
45
- type: 'relation',
46
- relation: 'manyToOne',
47
- target: 'category',
48
- inversedBy: 'articles',
49
- // useJoinTable: false,
50
- },
51
- // tags: {
52
- // type: 'relation',
53
- // relation: 'manyToMany',
54
- // target: 'tag',
55
- // inversedBy: 'articles',
56
- // },
57
- // compo: {
58
- // type: 'component',
59
- // component: 'compo',
60
- // // repeatable: true,
61
- // },
62
- // cover: {
63
- // type: 'media',
64
- // single: true,
65
- // },
66
- // gallery: {
67
- // type: 'media',
68
- // multiple: true,
69
- // },
70
- },
71
- };
72
-
73
- const tags = {
74
- modelName: 'tag',
75
- uid: 'tag',
76
- collectionName: 'tags',
77
- attributes: {
78
- name: {
79
- type: 'string',
80
- },
81
- articles: {
82
- type: 'relation',
83
- relation: 'manyToMany',
84
- target: 'article',
85
- mappedBy: 'tag',
86
- },
87
- },
88
- };
89
-
90
- const compo = {
91
- modelName: 'compo',
92
- uid: 'compo',
93
- collectionName: 'compos',
94
- attributes: {
95
- key: {
96
- type: 'string',
97
- },
98
- value: {
99
- type: 'string',
100
- },
101
- },
102
- };
103
-
104
- const user = {
105
- modelName: 'user',
106
- uid: 'user',
107
- collectionName: 'users',
108
- attributes: {
109
- address: {
110
- type: 'relation',
111
- relation: 'oneToOne',
112
- target: 'address',
113
- inversedBy: 'user',
114
- // useJoinTable: false,
115
- },
116
- },
117
- };
118
-
119
- const address = {
120
- modelName: 'address',
121
- uid: 'address',
122
- collectionName: 'addresses',
123
- attributes: {
124
- name: {
125
- type: 'string',
126
- },
127
- user: {
128
- type: 'relation',
129
- relation: 'oneToOne',
130
- target: 'user',
131
- mappedBy: 'address',
132
- },
133
- },
134
- };
135
-
136
- const file = {
137
- modelName: 'file',
138
- uid: 'file',
139
- collectionName: 'files',
140
- attributes: {
141
- name: {
142
- type: 'string',
143
- },
144
- alternativeText: {
145
- type: 'string',
146
- },
147
- caption: {
148
- type: 'string',
149
- },
150
- width: {
151
- type: 'integer',
152
- },
153
- height: {
154
- type: 'integer',
155
- },
156
- formats: {
157
- type: 'json',
158
- },
159
- hash: {
160
- type: 'string',
161
- },
162
- ext: {
163
- type: 'string',
164
- },
165
- mime: {
166
- type: 'string',
167
- },
168
- size: {
169
- type: 'decimal',
170
- },
171
- url: {
172
- type: 'string',
173
- },
174
- previewUrl: {
175
- type: 'string',
176
- },
177
- provider: {
178
- type: 'string',
179
- },
180
- provider_metadata: {
181
- type: 'json',
182
- },
183
- // related: {
184
- // type: 'relation',
185
- // relation: 'oneToMany',
186
- // target: 'file_morph',
187
- // mappedBy: 'file',
188
- // },
189
- // related: {
190
- // type: 'relation',
191
- // realtion: 'morphTo',
192
- // },
193
- },
194
- };
195
-
196
- const fileMorph = {
197
- modelName: 'file-morph',
198
- uid: 'file-morph',
199
- collectionName: 'file_morphs',
200
- attributes: {
201
- // file: {
202
- // type: 'relation',
203
- // relation: 'manyToOne',
204
- // target: 'file',
205
- // inversedBy: 'related',
206
- // useJoinTable: false,
207
- // },
208
- },
209
- };
210
-
211
- const blogPost = {
212
- modelName: 'blogPost',
213
- uid: 'blogPost',
214
- collectionName: 'blog_posts',
215
- attributes: {
216
- passwordField: {
217
- type: 'password',
218
- },
219
- emailField: {
220
- type: 'email',
221
- },
222
- stringField: {
223
- type: 'string',
224
- },
225
- uidField: {
226
- type: 'uid',
227
- },
228
- richtextField: {
229
- type: 'richtext',
230
- },
231
- textField: {
232
- type: 'text',
233
- },
234
- enumerationField: {
235
- type: 'enumeration',
236
- enum: ['A', 'B'],
237
- },
238
- jsonField: {
239
- type: 'json',
240
- },
241
- bigintegerField: {
242
- type: 'biginteger',
243
- },
244
- integerField: {
245
- type: 'integer',
246
- },
247
- floatField: {
248
- type: 'float',
249
- },
250
- decimalField: {
251
- type: 'decimal',
252
- },
253
- dateField: {
254
- type: 'date',
255
- },
256
- timeField: {
257
- type: 'time',
258
- },
259
- datetimeField: {
260
- type: 'datetime',
261
- },
262
- timestampField: {
263
- type: 'timestamp',
264
- },
265
- booleanField: {
266
- type: 'boolean',
267
- },
268
- },
269
- };
270
-
271
- module.exports = [category, article, tags, compo, user, address, file, fileMorph, blogPost];
272
-
273
- // const article = {
274
- // modelName: 'article',
275
- // uid: 'article',
276
- // collectionName: 'articles',
277
- // attributes: {
278
- // commentable: {
279
- // type: 'relation',
280
- // relation: 'morphToOne',
281
- // },
282
- // reportables: {
283
- // type: 'relation',
284
- // relation: 'morphToMany',
285
- // },
286
- // dz: {
287
- // type: 'dynamiczone',
288
- // components: ['comment', 'video-comment'],
289
- // },
290
- // },
291
- // };
292
-
293
- // const comment = {
294
- // modelName: 'comment',
295
- // uid: 'comment',
296
- // collectionName: 'comments',
297
- // attributes: {
298
- // article: {
299
- // type: 'relation',
300
- // relation: 'morphOne',
301
- // target: 'article',
302
- // morphBy: 'commentable',
303
- // },
304
- // title: {
305
- // type: 'string',
306
- // },
307
- // },
308
- // };
309
-
310
- // const videoComment = {
311
- // modelName: 'video-comment',
312
- // uid: 'video-comment',
313
- // collectionName: 'video_comments',
314
- // attributes: {
315
- // articles: {
316
- // type: 'relation',
317
- // relation: 'morphMany',
318
- // target: 'article',
319
- // morphBy: 'commentable',
320
- // },
321
- // title: {
322
- // type: 'string',
323
- // },
324
- // },
325
- // };
326
-
327
- // const folder = {
328
- // modelName: 'folder',
329
- // uid: 'folder',
330
- // collectionName: 'folders',
331
- // attributes: {
332
- // articles: {
333
- // type: 'relation',
334
- // relation: 'morphMany',
335
- // target: 'article',
336
- // morphBy: 'reportables',
337
- // },
338
- // },
339
- // };
340
-
341
- // module.exports = [article, comment, videoComment, folder];
@@ -1,17 +0,0 @@
1
- type ID = number | string;
2
-
3
- interface Category {
4
- id: ID;
5
- title: string;
6
- }
7
-
8
- interface Article {
9
- id: ID;
10
- title: string;
11
- category: Category | ID;
12
- }
13
-
14
- interface AllTypes {
15
- article: Article;
16
- category: Category;
17
- }