@companix/xeo-server 0.0.2 → 0.0.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.
- package/package.json +4 -1
- package/.eslintrc +0 -54
- package/jest.cases.config.cjs +0 -14
- package/lib/common/decorators.ts +0 -17
- package/lib/common/index.ts +0 -3
- package/lib/common/tokens.ts +0 -17
- package/lib/common/utils.ts +0 -29
- package/lib/constants.ts +0 -4
- package/lib/driver.module.ts +0 -37
- package/lib/drivers/collection.driver.ts +0 -157
- package/lib/drivers/table.driver.ts +0 -109
- package/lib/factories/definitions.factory.ts +0 -129
- package/lib/index.ts +0 -3
- package/lib/mongoose-options.interface.ts +0 -19
- package/lib/mongoose.module.ts +0 -95
- package/lib/storages/data-source.ts +0 -37
- package/tests/app/bootstrap.ts +0 -16
- package/tests/app/db.ts +0 -22
- package/tests/app/filters.ts +0 -25
- package/tests/app/helpers/is-one-of.ts +0 -58
- package/tests/app/main.ts +0 -3
- package/tests/app/module/app.controller.ts +0 -67
- package/tests/app/module/app.dto.ts +0 -394
- package/tests/app/module/app.module.ts +0 -12
- package/tests/app/module/app.service.ts +0 -76
- package/tests/app/root.module.ts +0 -12
- package/tests/globals.d.ts +0 -6
- package/tests/integrations/cases.test.ts +0 -154
- package/tests/integrations/custom.test.ts +0 -69
- package/tests/unit/definitions.test.ts +0 -31
- package/tsconfig.build.json +0 -9
- package/tsconfig.json +0 -17
- package/tsconfig.test-app.json +0 -10
package/package.json
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@companix/xeo-server",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "./dist/index.d.ts",
|
|
6
|
+
"files": [
|
|
7
|
+
"dist"
|
|
8
|
+
],
|
|
6
9
|
"scripts": {
|
|
7
10
|
"echo": "echo \"@companix/xeo-server\"",
|
|
8
11
|
"build": "rm -rf dist && tsc -p tsconfig.build.json",
|
package/.eslintrc
DELETED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"env": {
|
|
3
|
-
"node": true,
|
|
4
|
-
"browser": true,
|
|
5
|
-
"es6": true
|
|
6
|
-
},
|
|
7
|
-
"extends": [
|
|
8
|
-
"plugin:react/recommended",
|
|
9
|
-
"plugin:react-hooks/recommended",
|
|
10
|
-
"react-app"
|
|
11
|
-
],
|
|
12
|
-
"parser": "@typescript-eslint/parser",
|
|
13
|
-
"plugins": ["react"],
|
|
14
|
-
"parserOptions": {
|
|
15
|
-
"sourceType": "module",
|
|
16
|
-
"requireConfigFile": false,
|
|
17
|
-
"ecmaFeatures": {
|
|
18
|
-
"jsx": true
|
|
19
|
-
}
|
|
20
|
-
},
|
|
21
|
-
"settings": {
|
|
22
|
-
"react": {
|
|
23
|
-
"version": "detect"
|
|
24
|
-
}
|
|
25
|
-
},
|
|
26
|
-
"rules": {
|
|
27
|
-
"no-var": "error",
|
|
28
|
-
"typescript-eslint/typescript-estree": "off",
|
|
29
|
-
"react-hooks/exhaustive-deps": "off",
|
|
30
|
-
"react/react-in-jsx-scope": "off",
|
|
31
|
-
"react/no-children-prop": "off",
|
|
32
|
-
"react/display-name": "off",
|
|
33
|
-
"jsx-a11y/aria-role": "off",
|
|
34
|
-
"react/prop-types": "off",
|
|
35
|
-
"react/jsx-no-target-blank": "off",
|
|
36
|
-
"import/no-anonymous-default-export": "off",
|
|
37
|
-
"import/no-extraneous-dependencies": [
|
|
38
|
-
"error",
|
|
39
|
-
{
|
|
40
|
-
"devDependencies": true,
|
|
41
|
-
"peerDependencies": false
|
|
42
|
-
}
|
|
43
|
-
],
|
|
44
|
-
"no-throw-literal": "off",
|
|
45
|
-
"react/no-multi-comp": [2, { "ignoreStateless": true }],
|
|
46
|
-
"no-restricted-syntax": [
|
|
47
|
-
"error",
|
|
48
|
-
{
|
|
49
|
-
"selector": "CallExpression[arguments.length=1][callee.property.name='reduce']",
|
|
50
|
-
"message": "Provide initialValue to .reduce()."
|
|
51
|
-
}
|
|
52
|
-
]
|
|
53
|
-
}
|
|
54
|
-
}
|
package/jest.cases.config.cjs
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
module.exports = {
|
|
2
|
-
testEnvironment: 'node',
|
|
3
|
-
roots: ['<rootDir>/tests/integrations'],
|
|
4
|
-
testMatch: ['**/cases.test.ts'],
|
|
5
|
-
moduleFileExtensions: ['ts', 'js', 'json'],
|
|
6
|
-
transform: {
|
|
7
|
-
'^.+\\.ts$': [
|
|
8
|
-
'ts-jest',
|
|
9
|
-
{
|
|
10
|
-
tsconfig: '<rootDir>/tsconfig.test-app.json'
|
|
11
|
-
}
|
|
12
|
-
]
|
|
13
|
-
}
|
|
14
|
-
}
|
package/lib/common/decorators.ts
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { Inject } from '@nestjs/common'
|
|
2
|
-
import { getConnectionToken, getDataSourceToken } from './tokens'
|
|
3
|
-
import { CollectionScheme, DataScheme } from '@companix/xeo-scheme'
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* @publicApi
|
|
7
|
-
*/
|
|
8
|
-
export const InjectDataSource = (dataSource: DataScheme<CollectionScheme>) => {
|
|
9
|
-
return Inject(getDataSourceToken(dataSource))
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* @publicApi
|
|
14
|
-
*/
|
|
15
|
-
export const InjectConnection = () => {
|
|
16
|
-
return Inject(getConnectionToken())
|
|
17
|
-
}
|
package/lib/common/index.ts
DELETED
package/lib/common/tokens.ts
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { DEFAULT_DB_CONNECTION } from '../constants'
|
|
2
|
-
import { CollectionScheme, DataScheme } from '@companix/xeo-scheme'
|
|
3
|
-
import { DataSourceStorage } from '../storages/data-source'
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* @publicApi
|
|
7
|
-
*/
|
|
8
|
-
export const getConnectionToken = (name?: string) => {
|
|
9
|
-
return name && name !== DEFAULT_DB_CONNECTION ? `${name}Connection` : DEFAULT_DB_CONNECTION
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* @publicApi
|
|
14
|
-
*/
|
|
15
|
-
export const getDataSourceToken = (dataScheme: DataScheme<CollectionScheme>) => {
|
|
16
|
-
return DataSourceStorage.getProviderToken(dataScheme)
|
|
17
|
-
}
|
package/lib/common/utils.ts
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { Logger } from '@nestjs/common'
|
|
2
|
-
import { Observable } from 'rxjs'
|
|
3
|
-
import { delay, retryWhen, scan } from 'rxjs/operators'
|
|
4
|
-
|
|
5
|
-
export const handleRetry = (retryAttempts = 9, retryDelay = 3000, verboseRetryLog = false) => {
|
|
6
|
-
const logger = new Logger('MongooseModule')
|
|
7
|
-
|
|
8
|
-
return <T>(source: Observable<T>) =>
|
|
9
|
-
source.pipe(
|
|
10
|
-
retryWhen((e) =>
|
|
11
|
-
e.pipe(
|
|
12
|
-
scan((errorCount, error) => {
|
|
13
|
-
const verboseMessage = verboseRetryLog ? ` Message: ${error.message}.` : ''
|
|
14
|
-
const retryMessage = retryAttempts > 0 ? ` Retrying (${errorCount + 1})...` : ''
|
|
15
|
-
|
|
16
|
-
logger.error(
|
|
17
|
-
['Unable to connect to the database.', verboseMessage, retryMessage].join(''),
|
|
18
|
-
error.stack
|
|
19
|
-
)
|
|
20
|
-
if (errorCount + 1 >= retryAttempts) {
|
|
21
|
-
throw error
|
|
22
|
-
}
|
|
23
|
-
return errorCount + 1
|
|
24
|
-
}, 0),
|
|
25
|
-
delay(retryDelay)
|
|
26
|
-
)
|
|
27
|
-
)
|
|
28
|
-
)
|
|
29
|
-
}
|
package/lib/constants.ts
DELETED
package/lib/driver.module.ts
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import { Provider } from '@nestjs/common'
|
|
2
|
-
import { DynamicModule, Module } from '@nestjs/common'
|
|
3
|
-
import { getConnectionToken, getDataSourceToken } from './common/tokens'
|
|
4
|
-
import { Connection } from 'mongoose'
|
|
5
|
-
import { CollectionScheme, DataScheme, DataSource } from '@companix/xeo-scheme'
|
|
6
|
-
import { MongooseCoreModule } from './mongoose.module'
|
|
7
|
-
import { MongooseModuleOptions } from './mongoose-options.interface'
|
|
8
|
-
import { DataSourceStorage } from './storages/data-source'
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* @publicApi
|
|
12
|
-
*/
|
|
13
|
-
@Module({})
|
|
14
|
-
export class MongooseDriverModule {
|
|
15
|
-
static forRoot(uri: string, options: MongooseModuleOptions = {}): DynamicModule {
|
|
16
|
-
return {
|
|
17
|
-
module: MongooseDriverModule,
|
|
18
|
-
imports: [MongooseCoreModule.forRoot(uri, options)]
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
static forFeature(dataSource: DataScheme<CollectionScheme>, connectionName?: string): DynamicModule {
|
|
23
|
-
const provider: Provider = {
|
|
24
|
-
provide: getDataSourceToken(dataSource),
|
|
25
|
-
useFactory: (connection: Connection): DataSource<CollectionScheme> => {
|
|
26
|
-
return DataSourceStorage.getSource(dataSource, connection)
|
|
27
|
-
},
|
|
28
|
-
inject: [getConnectionToken(connectionName)]
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
return {
|
|
32
|
-
module: MongooseDriverModule,
|
|
33
|
-
providers: [provider],
|
|
34
|
-
exports: [provider]
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
@@ -1,157 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
CollectionDriver,
|
|
3
|
-
CollectionDriverParams,
|
|
4
|
-
CollectionScheme,
|
|
5
|
-
DataScheme
|
|
6
|
-
} from '@companix/xeo-scheme'
|
|
7
|
-
import { MongoRelationsTable } from './table.driver'
|
|
8
|
-
import { Connection, Model, Schema } from 'mongoose'
|
|
9
|
-
import { DefinitionsFactory } from '../factories/definitions.factory'
|
|
10
|
-
import { Logger } from '@nestjs/common'
|
|
11
|
-
|
|
12
|
-
interface DiscriminatedModels {
|
|
13
|
-
[model: string]: {
|
|
14
|
-
discriminatorKey: string
|
|
15
|
-
models: {
|
|
16
|
-
[value: string]: Model<any>
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export class MongoCollectionDriver<T extends CollectionScheme> implements CollectionDriver {
|
|
22
|
-
private collections: { [model: string]: Model<any> } = {}
|
|
23
|
-
private discriminatedModels: DiscriminatedModels = {}
|
|
24
|
-
|
|
25
|
-
public tables: MongoRelationsTable<T>
|
|
26
|
-
|
|
27
|
-
constructor(private dataScheme: DataScheme<T>, private connection: Connection) {
|
|
28
|
-
Logger.log('Driver bootstrap', 'MongoDriver')
|
|
29
|
-
|
|
30
|
-
this.tables = new MongoRelationsTable(dataScheme, connection)
|
|
31
|
-
|
|
32
|
-
const factory = new DefinitionsFactory(dataScheme)
|
|
33
|
-
|
|
34
|
-
for (const name in dataScheme.collections) {
|
|
35
|
-
const model = dataScheme.collections[name].name
|
|
36
|
-
const scheme = dataScheme.models[model].scheme
|
|
37
|
-
|
|
38
|
-
const baseDefinition = factory.createForScheme(scheme)
|
|
39
|
-
|
|
40
|
-
if (scheme.type === 'base') {
|
|
41
|
-
this.collections[model] = this.useModel(model, new Schema(baseDefinition))
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
if (scheme.type === 'discriminated') {
|
|
45
|
-
this.collections[model] = this.useModel(
|
|
46
|
-
model,
|
|
47
|
-
new Schema(baseDefinition, {
|
|
48
|
-
discriminatorKey: scheme.discriminatorKey
|
|
49
|
-
})
|
|
50
|
-
)
|
|
51
|
-
|
|
52
|
-
this.discriminatedModels[model] = {
|
|
53
|
-
discriminatorKey: scheme.discriminatorKey,
|
|
54
|
-
models: {}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
for (const discriminator of scheme.discriminators) {
|
|
58
|
-
const discriminatedModel = this.collections[model].discriminator(
|
|
59
|
-
discriminator.name,
|
|
60
|
-
new Schema(factory.createDefinitionScheme(discriminator)),
|
|
61
|
-
discriminator.value
|
|
62
|
-
)
|
|
63
|
-
|
|
64
|
-
this.discriminatedModels[model].models[discriminator.value] = discriminatedModel
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
async getAll({ model }: CollectionDriverParams.Model) {
|
|
71
|
-
return this.collections[model].find().lean().exec()
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
async get({ model, id }: CollectionDriverParams.Record) {
|
|
75
|
-
return this.collections[model].findOne({ [this.getIdentifierKey(model)]: id }).lean()
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
async create({ model, data }: CollectionDriverParams.Create) {
|
|
79
|
-
await new this.collections[model](data).save()
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
async remove({ model, id }: CollectionDriverParams.Record) {
|
|
83
|
-
await this.collections[model].deleteOne({ [this.getIdentifierKey(model)]: id }).exec()
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
// при update для discriminated collection нельзя всегда использовать только this.collections[model]
|
|
87
|
-
// нужно сначала получить документ по id, узнать его discriminatorKey (type), и если это дискриминатор, выполнять updateOne() через соответствующую discriminator model
|
|
88
|
-
async update({ model, id, patches }: CollectionDriverParams.Update) {
|
|
89
|
-
const identifierKey = this.getIdentifierKey(model)
|
|
90
|
-
const collection = await this.getCollection({ model, id })
|
|
91
|
-
|
|
92
|
-
const responses = await Promise.all(
|
|
93
|
-
patches.map(async (patch) => {
|
|
94
|
-
switch (patch.type) {
|
|
95
|
-
case 'set': {
|
|
96
|
-
return collection.updateOne(
|
|
97
|
-
{ [identifierKey]: id },
|
|
98
|
-
{ $set: { [patch.address]: patch.value } }
|
|
99
|
-
)
|
|
100
|
-
}
|
|
101
|
-
case 'push': {
|
|
102
|
-
return collection.updateOne(
|
|
103
|
-
{ [identifierKey]: id },
|
|
104
|
-
{ $push: { [patch.address]: { $each: patch.items } } }
|
|
105
|
-
)
|
|
106
|
-
}
|
|
107
|
-
case 'pull': {
|
|
108
|
-
return collection.updateOne(
|
|
109
|
-
{ [identifierKey]: id },
|
|
110
|
-
{ $pull: { [patch.address]: { $in: patch.items } } }
|
|
111
|
-
)
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
})
|
|
115
|
-
)
|
|
116
|
-
|
|
117
|
-
// check transaction
|
|
118
|
-
for (const response of responses) {
|
|
119
|
-
if (!response.acknowledged) {
|
|
120
|
-
console.log('MongoDB Write Warning', { model, id, patches }, responses)
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
private async getCollection({ model, id }: CollectionDriverParams.Record) {
|
|
126
|
-
if (this.discriminatedModels[model]) {
|
|
127
|
-
const target = await this.get({ model, id })
|
|
128
|
-
const discriminatorValue = target[this.discriminatedModels[model].discriminatorKey] as string
|
|
129
|
-
|
|
130
|
-
return this.discriminatedModels[model].models[discriminatorValue]
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
return this.collections[model]
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
async exists({ model, id }: CollectionDriverParams.Record) {
|
|
137
|
-
const result = await this.collections[model].exists({
|
|
138
|
-
[this.getIdentifierKey(model)]: id
|
|
139
|
-
})
|
|
140
|
-
|
|
141
|
-
return result !== null
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
private getIdentifierKey(model: string) {
|
|
145
|
-
return this.dataScheme.models[model].scheme.identifier.propertyKey
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
private useModel<T>(model: string, schema: Schema): Model<T> {
|
|
149
|
-
return this.connection.models[model] ?? this.connection.model(model, schema)
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
export const createMongoDriver = (connection: Connection) => {
|
|
154
|
-
return <T extends CollectionScheme>(dataScheme: DataScheme<T>) => {
|
|
155
|
-
return new MongoCollectionDriver(dataScheme, connection)
|
|
156
|
-
}
|
|
157
|
-
}
|
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
CollectionScheme,
|
|
3
|
-
DataScheme,
|
|
4
|
-
IType,
|
|
5
|
-
RelationRecord,
|
|
6
|
-
RelationsTableInfo,
|
|
7
|
-
TableDriver,
|
|
8
|
-
TableRow,
|
|
9
|
-
TableRelationSlice
|
|
10
|
-
} from '@companix/xeo-scheme'
|
|
11
|
-
import { Connection, Model, Schema, SchemaDefinition } from 'mongoose'
|
|
12
|
-
|
|
13
|
-
class MongoTableStore {
|
|
14
|
-
private modelKey: { [model: string]: 'm1' | 'm2' } = {}
|
|
15
|
-
private keyMirror = { m1: 'm2' as 'm2', m2: 'm1' as 'm1' }
|
|
16
|
-
|
|
17
|
-
private model: Model<TableRow>
|
|
18
|
-
|
|
19
|
-
constructor({ rules, tableName }: RelationsTableInfo, private connection: Connection) {
|
|
20
|
-
this.modelKey[rules.m1] = 'm1'
|
|
21
|
-
this.modelKey[rules.m2] = 'm2'
|
|
22
|
-
this.model = this.useModel<TableRow>(tableName, new Schema(this.getSchemeDefinition()))
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
private getSchemeDefinition(): SchemaDefinition {
|
|
26
|
-
return {
|
|
27
|
-
m1: { type: Schema.Types.Mixed, index: true, required: true },
|
|
28
|
-
m2: { type: Schema.Types.Mixed, index: true, required: true }
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
private getRow({ modelId, modelSide, oppositeId }: RelationRecord) {
|
|
33
|
-
const key = this.modelKey[modelSide]
|
|
34
|
-
const row = { [key]: modelId, [this.keyMirror[key]]: oppositeId } as unknown as TableRow
|
|
35
|
-
|
|
36
|
-
return row
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
async addRow(row: RelationRecord) {
|
|
40
|
-
await this.model.create(this.getRow(row))
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
async removeRow(row: RelationRecord) {
|
|
44
|
-
await this.model.deleteOne(this.getRow(row)).exec()
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
async removeModel(model: string, modelId: IType) {
|
|
48
|
-
await this.model.deleteMany({ [this.modelKey[model]]: modelId }).exec()
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
async getRelations(model: string, modelId: IType) {
|
|
52
|
-
const key = this.modelKey[model]
|
|
53
|
-
const oppositeKey = this.keyMirror[key]
|
|
54
|
-
|
|
55
|
-
const rows = await this.model
|
|
56
|
-
.find({ [key]: modelId })
|
|
57
|
-
.select({ [oppositeKey]: 1, _id: 0 })
|
|
58
|
-
.lean()
|
|
59
|
-
.exec()
|
|
60
|
-
|
|
61
|
-
return rows.map((row) => row[oppositeKey] as IType)
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
private useModel<T>(model: string, schema: Schema): Model<T> {
|
|
65
|
-
return this.connection.models[model] ?? this.connection.model(model, schema)
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
getStore() {
|
|
69
|
-
return this.model.find().lean().exec()
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
export class MongoRelationsTable<T extends CollectionScheme> implements TableDriver {
|
|
74
|
-
private readonly tables: { [tableName: string]: MongoTableStore } = {}
|
|
75
|
-
|
|
76
|
-
constructor(dataScheme: DataScheme<T>, connection: Connection) {
|
|
77
|
-
for (const table of dataScheme.tables) {
|
|
78
|
-
this.tables[table.tableName] = new MongoTableStore(table, connection)
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
async createRecord(row: RelationRecord) {
|
|
83
|
-
await this.tables[row.tableName].addRow(row)
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
async removeRecord(row: RelationRecord) {
|
|
87
|
-
await this.tables[row.tableName].removeRow(row)
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
async removeRecordsByModel(row: TableRelationSlice) {
|
|
91
|
-
await this.tables[row.tableName].removeModel(row.modelSide, row.modelId)
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
async getRecords({ tableName, modelSide, modelId }: TableRelationSlice) {
|
|
95
|
-
return this.tables[tableName].getRelations(modelSide, modelId)
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
// development
|
|
99
|
-
|
|
100
|
-
async getTables() {
|
|
101
|
-
const state: { [name: string]: TableRow[] } = {}
|
|
102
|
-
|
|
103
|
-
for (const tableName in this.tables) {
|
|
104
|
-
state[tableName] = await this.tables[tableName].getStore()
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
return state
|
|
108
|
-
}
|
|
109
|
-
}
|
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
CollectionScheme,
|
|
3
|
-
DataScheme,
|
|
4
|
-
ModelProperties,
|
|
5
|
-
PropertyRelation,
|
|
6
|
-
PropertyMetadata,
|
|
7
|
-
ModelScheme
|
|
8
|
-
} from '@companix/xeo-scheme'
|
|
9
|
-
import type { SchemaDefinition, SchemaDefinitionProperty } from 'mongoose'
|
|
10
|
-
import { Schema } from 'mongoose'
|
|
11
|
-
|
|
12
|
-
const TypesTranslator = {
|
|
13
|
-
string: String,
|
|
14
|
-
number: Number,
|
|
15
|
-
json: Object,
|
|
16
|
-
boolean: Boolean
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export class DefinitionsFactory<T extends CollectionScheme> {
|
|
20
|
-
constructor(private dataScheme: DataScheme<T>) {}
|
|
21
|
-
|
|
22
|
-
createForCollection(name: keyof T): SchemaDefinition {
|
|
23
|
-
return this.createForScheme(this.dataScheme.models[this.dataScheme.collections[name].name].scheme)
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
createForScheme(scheme: ModelScheme): SchemaDefinition {
|
|
27
|
-
return {
|
|
28
|
-
[scheme.identifier.propertyKey]: {
|
|
29
|
-
index: true,
|
|
30
|
-
type: TypesTranslator[scheme.identifier.options.type],
|
|
31
|
-
unique: true
|
|
32
|
-
},
|
|
33
|
-
...this.createDefinitionScheme(scheme)
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
createDefinitionScheme({ properties, references }: ModelProperties): SchemaDefinition {
|
|
38
|
-
const map: SchemaDefinition = {}
|
|
39
|
-
|
|
40
|
-
for (const property of properties) {
|
|
41
|
-
map[property.propertyKey] = this.getPropertyDefinition(property)
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
for (const reference of references) {
|
|
45
|
-
map[reference.propertyKey] = this.getRelationDefinition(reference)
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
return map
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
private getPropertyDefinition({ primitive }: PropertyMetadata): SchemaDefinitionProperty {
|
|
52
|
-
switch (primitive.type) {
|
|
53
|
-
case 'embedded': {
|
|
54
|
-
return {
|
|
55
|
-
_id: false, // prevent creating _id (без указания mongodb создавал бы _id для всех вложенных объектов)
|
|
56
|
-
type: this.createDefinitionScheme(primitive),
|
|
57
|
-
required: true
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
case 'array': {
|
|
61
|
-
return {
|
|
62
|
-
type: [TypesTranslator[primitive.itemType]],
|
|
63
|
-
required: true
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
case 'literal': {
|
|
67
|
-
return {
|
|
68
|
-
type: Schema.Types.Mixed, // сузить до String и Number
|
|
69
|
-
enum: primitive.values,
|
|
70
|
-
required: !primitive.nullable
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
case 'enum': {
|
|
74
|
-
return {
|
|
75
|
-
type: [String], // может быть и Number
|
|
76
|
-
enum: primitive.values,
|
|
77
|
-
required: !primitive.nullable
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
default: {
|
|
81
|
-
return {
|
|
82
|
-
type: TypesTranslator[primitive.type]
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
private getRelationDefinition(reference: PropertyRelation): SchemaDefinitionProperty {
|
|
89
|
-
const refModel = this.dataScheme.metadata.getModelSchemaByTarget(reference.referenceModel)
|
|
90
|
-
|
|
91
|
-
switch (reference.refType) {
|
|
92
|
-
case 'reference-to': {
|
|
93
|
-
return {
|
|
94
|
-
type: TypesTranslator[refModel.identifier.options.type],
|
|
95
|
-
required: (reference.options?.onRefDeleting ?? 'restrict') === 'restrict'
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
case 'reference-set': {
|
|
99
|
-
return {
|
|
100
|
-
type: [TypesTranslator[refModel.identifier.options.type]]
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
case 'belongs-to': {
|
|
104
|
-
return {
|
|
105
|
-
type: TypesTranslator[refModel.identifier.options.type],
|
|
106
|
-
required: true
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
case 'has-many': {
|
|
110
|
-
return {
|
|
111
|
-
type: [TypesTranslator[refModel.identifier.options.type]],
|
|
112
|
-
required: true
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
case 'owner': {
|
|
116
|
-
return {
|
|
117
|
-
type: TypesTranslator[refModel.identifier.options.type],
|
|
118
|
-
required: true
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
case 'owner-fallback': {
|
|
122
|
-
return {
|
|
123
|
-
type: TypesTranslator[refModel.identifier.options.type],
|
|
124
|
-
refType: 'owner-fallback'
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
}
|
package/lib/index.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { ConnectOptions, Connection, MongooseError } from 'mongoose'
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* @publicApi
|
|
5
|
-
*/
|
|
6
|
-
export interface MongooseModuleOptions extends ConnectOptions {
|
|
7
|
-
uri?: string
|
|
8
|
-
retryAttempts?: number
|
|
9
|
-
retryDelay?: number
|
|
10
|
-
connectionName?: string
|
|
11
|
-
connectionFactory?: (connection: any, name: string) => any
|
|
12
|
-
connectionErrorFactory?: (error: MongooseError) => MongooseError
|
|
13
|
-
lazyConnection?: boolean
|
|
14
|
-
onConnectionCreate?: (connection: Connection) => void
|
|
15
|
-
/**
|
|
16
|
-
* If `true`, will show verbose error messages on each connection retry.
|
|
17
|
-
*/
|
|
18
|
-
verboseRetryLog?: boolean
|
|
19
|
-
}
|