@rws-framework/db 2.4.5 → 3.0.0
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/.bin/add-v.sh +9 -9
- package/.bin/emerge.sh +10 -10
- package/.eslintrc.json +53 -53
- package/README.md +404 -404
- package/dist/decorators/IdType.d.ts +8 -0
- package/dist/decorators/IdType.js +10 -0
- package/dist/decorators/InverseRelation.d.ts +2 -2
- package/dist/decorators/InverseRelation.js +5 -1
- package/dist/decorators/InverseTimeSeries.d.ts +0 -0
- package/dist/decorators/InverseTimeSeries.js +0 -0
- package/dist/decorators/RWSCollection.d.ts +7 -0
- package/dist/decorators/RWSCollection.js +6 -0
- package/dist/decorators/Relation.d.ts +8 -6
- package/dist/decorators/Relation.js +8 -1
- package/dist/decorators/TrackType.d.ts +2 -14
- package/dist/decorators/TrackType.js +7 -0
- package/dist/decorators/TypeFunctions.d.ts +44 -0
- package/dist/decorators/TypeFunctions.js +174 -0
- package/dist/decorators/index.d.ts +4 -2
- package/dist/decorators/index.js +3 -1
- package/dist/helper/DbHelper.d.ts +76 -5
- package/dist/helper/DbHelper.js +93 -154
- package/dist/helper/FieldsHelper.d.ts +0 -0
- package/dist/helper/FieldsHelper.js +0 -0
- package/dist/helper/db/index.d.ts +9 -0
- package/dist/helper/db/index.js +18 -0
- package/dist/helper/db/relation-manager.d.ts +45 -0
- package/dist/helper/db/relation-manager.js +105 -0
- package/dist/helper/db/schema-generator.d.ts +37 -0
- package/dist/helper/db/schema-generator.js +243 -0
- package/dist/helper/db/type-converter.d.ts +22 -0
- package/dist/helper/db/type-converter.js +106 -0
- package/dist/helper/db/utils.d.ts +24 -0
- package/dist/helper/db/utils.js +99 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.js +2 -1
- package/dist/models/TimeSeriesModel.d.ts +7 -7
- package/dist/models/TimeSeriesModel.js +33 -33
- package/dist/models/_model.d.ts +2 -2
- package/dist/models/_model.js +0 -0
- package/dist/models/core/RWSModel.d.ts +4 -1
- package/dist/models/core/RWSModel.js +6 -4
- package/dist/models/core/TimeSeriesModel.d.ts +0 -0
- package/dist/models/core/TimeSeriesModel.js +0 -0
- package/dist/models/index.d.ts +2 -2
- package/dist/models/index.js +0 -0
- package/dist/models/interfaces/IDbOpts.d.ts +17 -0
- package/dist/models/interfaces/IDbOpts.js +2 -0
- package/dist/models/interfaces/IIdOpts.d.ts +0 -0
- package/dist/models/interfaces/IIdOpts.js +1 -0
- package/dist/models/interfaces/IIdTypeOpts.d.ts +3 -0
- package/dist/models/interfaces/IIdTypeOpts.js +2 -0
- package/dist/models/interfaces/IModel.d.ts +0 -0
- package/dist/models/interfaces/IModel.js +0 -0
- package/dist/models/interfaces/IRWSModelServices.d.ts +0 -0
- package/dist/models/interfaces/IRWSModelServices.js +0 -0
- package/dist/models/interfaces/ITrackerOpts.d.ts +12 -0
- package/dist/models/interfaces/ITrackerOpts.js +2 -0
- package/dist/models/interfaces/OpModelType.d.ts +3 -0
- package/dist/models/interfaces/OpModelType.js +0 -0
- package/dist/models/types/RelationTypes.d.ts +0 -0
- package/dist/models/types/RelationTypes.js +0 -0
- package/dist/models/utils/ModelUtils.d.ts +0 -0
- package/dist/models/utils/ModelUtils.js +0 -0
- package/dist/models/utils/PaginationUtils.d.ts +0 -0
- package/dist/models/utils/PaginationUtils.js +0 -0
- package/dist/models/utils/RelationUtils.d.ts +1 -1
- package/dist/models/utils/RelationUtils.js +2 -2
- package/dist/models/utils/TimeSeriesUtils.d.ts +0 -0
- package/dist/models/utils/TimeSeriesUtils.js +0 -0
- package/dist/services/DBService.d.ts +0 -0
- package/dist/services/DBService.js +0 -0
- package/dist/types/DbConfigHandler.d.ts +1 -1
- package/dist/types/DbConfigHandler.js +0 -0
- package/dist/types/FindParams.d.ts +0 -0
- package/dist/types/FindParams.js +0 -0
- package/dist/types/IRWSModel.d.ts +1 -1
- package/dist/types/IRWSModel.js +0 -0
- package/dist/types/ITimeSeries.d.ts +0 -0
- package/dist/types/ITimeSeries.js +0 -0
- package/exec/console.js +110 -110
- package/exec/db.rws.webpack.config.js +168 -168
- package/exec/src/cli.ts +73 -75
- package/exec/tsconfig.json +32 -32
- package/exec/webpackFilters.js +17 -17
- package/package.json +36 -36
- package/src/decorators/IdType.ts +17 -0
- package/src/decorators/InverseRelation.ts +41 -37
- package/src/decorators/InverseTimeSeries.ts +21 -21
- package/src/decorators/RWSCollection.ts +45 -27
- package/src/decorators/Relation.ts +61 -48
- package/src/decorators/TrackType.ts +65 -69
- package/src/decorators/index.ts +16 -8
- package/src/empty.js +0 -0
- package/src/helper/DbHelper.ts +133 -223
- package/src/helper/FieldsHelper.ts +34 -34
- package/src/helper/db/index.ts +10 -0
- package/src/helper/db/relation-manager.ts +119 -0
- package/src/helper/db/schema-generator.ts +302 -0
- package/src/helper/db/type-converter.ts +119 -0
- package/src/helper/db/utils.ts +120 -0
- package/src/index.ts +47 -38
- package/src/models/_model.ts +29 -29
- package/src/models/core/RWSModel.ts +523 -520
- package/src/models/core/TimeSeriesModel.ts +19 -19
- package/src/models/index.ts +20 -20
- package/src/models/interfaces/IDbOpts.ts +17 -0
- package/src/models/interfaces/IIdTypeOpts.ts +4 -0
- package/src/models/interfaces/IModel.ts +12 -12
- package/src/models/interfaces/IRWSModelServices.ts +7 -7
- package/src/models/interfaces/ITrackerOpts.ts +13 -0
- package/src/models/interfaces/OpModelType.ts +52 -49
- package/src/models/types/RelationTypes.ts +25 -25
- package/src/models/utils/ModelUtils.ts +65 -65
- package/src/models/utils/PaginationUtils.ts +42 -42
- package/src/models/utils/RelationUtils.ts +76 -76
- package/src/models/utils/TimeSeriesUtils.ts +38 -38
- package/src/services/DBService.ts +277 -277
- package/src/types/DbConfigHandler.ts +17 -17
- package/src/types/FindParams.ts +13 -13
- package/src/types/IRWSModel.ts +2 -2
- package/src/types/ITimeSeries.ts +5 -5
- package/tsconfig.json +22 -22
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.SchemaGenerator = void 0;
|
|
7
|
+
const console_1 = require("@rws-framework/console");
|
|
8
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
9
|
+
const fs_1 = __importDefault(require("fs"));
|
|
10
|
+
const _model_1 = require("../../models/_model");
|
|
11
|
+
const utils_1 = require("./utils");
|
|
12
|
+
const type_converter_1 = require("./type-converter");
|
|
13
|
+
const relation_manager_1 = require("./relation-manager");
|
|
14
|
+
const log = console.log;
|
|
15
|
+
/**
|
|
16
|
+
* Handles Prisma schema generation
|
|
17
|
+
*/
|
|
18
|
+
class SchemaGenerator {
|
|
19
|
+
/**
|
|
20
|
+
* Generate the base schema for Prisma
|
|
21
|
+
* @param dbType The database type
|
|
22
|
+
* @param dbUrl The database URL
|
|
23
|
+
* @returns The base schema
|
|
24
|
+
*/
|
|
25
|
+
static generateBaseSchema(dbType, dbUrl) {
|
|
26
|
+
process.env = { ...process.env, [this.dbUrlVarName]: dbUrl };
|
|
27
|
+
return `generator client {
|
|
28
|
+
provider = "prisma-client-js"
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
datasource db {
|
|
32
|
+
provider = "${dbType}"
|
|
33
|
+
url = env("${this.dbUrlVarName}")
|
|
34
|
+
}`;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Generate model sections for the schema
|
|
38
|
+
* @param model The model to generate a section for
|
|
39
|
+
* @param configService The configuration service
|
|
40
|
+
* @returns The model section
|
|
41
|
+
*/
|
|
42
|
+
static async generateModelSections(model, configService) {
|
|
43
|
+
var _a, _b;
|
|
44
|
+
let section = '';
|
|
45
|
+
const modelMetadatas = await _model_1.RWSModel.getModelAnnotations(model);
|
|
46
|
+
const dbType = configService.get('db_type') || 'mongodb';
|
|
47
|
+
const modelName = model._collection;
|
|
48
|
+
section += `model ${modelName} {\n`;
|
|
49
|
+
if (!model._NO_ID) {
|
|
50
|
+
section += `\t${utils_1.DbUtils.generateId(dbType, modelMetadatas, false)}\n`;
|
|
51
|
+
}
|
|
52
|
+
for (const key in modelMetadatas) {
|
|
53
|
+
const modelMetadata = modelMetadatas[key].metadata;
|
|
54
|
+
let requiredString = modelMetadata.required ? '' : '?';
|
|
55
|
+
const annotationType = modelMetadatas[key].annotationType;
|
|
56
|
+
let indexedId = false;
|
|
57
|
+
if (model._NO_ID) {
|
|
58
|
+
indexedId = true;
|
|
59
|
+
requiredString = '';
|
|
60
|
+
}
|
|
61
|
+
if (key === 'id' && !indexedId) {
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
if (annotationType === 'Relation') {
|
|
65
|
+
const relationMeta = modelMetadata;
|
|
66
|
+
const relatedModel = relationMeta.relatedTo;
|
|
67
|
+
const isMany = relationMeta.many;
|
|
68
|
+
const cascadeOpts = [];
|
|
69
|
+
if ((_a = relationMeta.cascade) === null || _a === void 0 ? void 0 : _a.onDelete) {
|
|
70
|
+
cascadeOpts.push(`onDelete: ${relationMeta.cascade.onDelete}`);
|
|
71
|
+
}
|
|
72
|
+
if ((_b = relationMeta.cascade) === null || _b === void 0 ? void 0 : _b.onUpdate) {
|
|
73
|
+
cascadeOpts.push(`onUpdate: ${relationMeta.cascade.onUpdate}`);
|
|
74
|
+
}
|
|
75
|
+
const relatedModelName = relatedModel._collection;
|
|
76
|
+
const relationKey = [modelName, relatedModelName].join('_');
|
|
77
|
+
const relationIndex = relation_manager_1.RelationManager.getRelationCounter(relationKey);
|
|
78
|
+
const relationName = relation_manager_1.RelationManager.getShortenedRelationName(modelName, relatedModelName, relationIndex);
|
|
79
|
+
const mapName = relationName;
|
|
80
|
+
const relatedModelMetadatas = await _model_1.RWSModel.getModelAnnotations(relatedModel);
|
|
81
|
+
const relationFieldName = modelMetadata.relationField ? modelMetadata.relationField : key.toLowerCase() + '_' + modelMetadata.relationField.toLowerCase();
|
|
82
|
+
const relatedToField = modelMetadata.relatedToField || 'id';
|
|
83
|
+
const bindingFieldExists = !!modelMetadatas[relationFieldName];
|
|
84
|
+
if (isMany) {
|
|
85
|
+
// Add an inverse field to the related model if it doesn't exist
|
|
86
|
+
section += `\t${key} ${relatedModel._collection}[] @relation("${relationName}", fields: [${relationFieldName}], references: [${relatedToField}], map: "${mapName}", ${cascadeOpts.join(', ')})\n`;
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
section += `\t${key} ${relatedModel._collection}${requiredString} @relation("${relationName}", fields: [${relationFieldName}], references: [${relatedToField}], map: "${mapName}", ${cascadeOpts.join(', ')})\n`;
|
|
90
|
+
if (!bindingFieldExists) {
|
|
91
|
+
const relatedFieldMeta = relatedModelMetadatas[relatedToField];
|
|
92
|
+
if (!relatedFieldMeta.metadata.required) {
|
|
93
|
+
requiredString = '';
|
|
94
|
+
}
|
|
95
|
+
let relatedFieldType = type_converter_1.TypeConverter.toConfigCase(relatedFieldMeta.metadata, dbType, true);
|
|
96
|
+
if (relatedToField === 'id' && dbType !== 'mongodb') {
|
|
97
|
+
relatedFieldType = 'Int';
|
|
98
|
+
}
|
|
99
|
+
// Add relation field with appropriate type based on database
|
|
100
|
+
if (dbType === 'mongodb') {
|
|
101
|
+
section += `\t${relationFieldName} String${requiredString} @db.ObjectId\n`;
|
|
102
|
+
}
|
|
103
|
+
else if (dbType === 'mysql') {
|
|
104
|
+
// For MySQL, determine the type based on the related model's ID type
|
|
105
|
+
section += `\t${relationFieldName} ${relatedFieldType}${requiredString}\n`;
|
|
106
|
+
}
|
|
107
|
+
else if (dbType === 'postgresql' || dbType === 'postgres') {
|
|
108
|
+
if (relatedFieldType === 'String') {
|
|
109
|
+
section += `\t${relationFieldName} ${relatedFieldType}${requiredString} @db.Uuid\n`;
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
section += `\t${relationFieldName} ${relatedFieldType}${requiredString}\n`;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
section += `\t${relationFieldName} String${requiredString}\n`;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
relation_manager_1.RelationManager.completeRelation(relationKey, relationIndex);
|
|
121
|
+
}
|
|
122
|
+
else if (annotationType === 'InverseRelation') {
|
|
123
|
+
const relationMeta = modelMetadata;
|
|
124
|
+
// Check if we need a custom relation name (if there are multiple relations to the same model)
|
|
125
|
+
const relatedModelName = relationMeta.inversionModel._collection;
|
|
126
|
+
// Generate a very short relation name using a counter
|
|
127
|
+
// Use a consistent key for both sides of the relation to ensure the same name is used
|
|
128
|
+
const relationKey = [relatedModelName, modelName].join('_');
|
|
129
|
+
const relationIndex = relation_manager_1.RelationManager.getRelationCounter(relationKey, true);
|
|
130
|
+
const relationName = relation_manager_1.RelationManager.getShortenedRelationName(relatedModelName, modelName, relationIndex);
|
|
131
|
+
const mapName = relationName;
|
|
132
|
+
section += `\t${key} ${relationMeta.inversionModel._collection}[] @relation("${relationName}", map: "${mapName}")\n`;
|
|
133
|
+
relation_manager_1.RelationManager.completeRelation(relationKey, relationIndex, true);
|
|
134
|
+
}
|
|
135
|
+
else if (annotationType === 'InverseTimeSeries') {
|
|
136
|
+
if (dbType === 'mongodb') {
|
|
137
|
+
section += `\t${key} String[] @db.ObjectId\n`;
|
|
138
|
+
}
|
|
139
|
+
else if (dbType === 'mysql') {
|
|
140
|
+
// For MySQL, we need a different approach for arrays
|
|
141
|
+
section += `\t${key} Json\n`;
|
|
142
|
+
}
|
|
143
|
+
else if (dbType === 'postgresql' || dbType === 'postgres') {
|
|
144
|
+
// PostgreSQL supports arrays natively
|
|
145
|
+
section += `\t${key} String[]\n`;
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
section += `\t${key} String[]\n`;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
else if (annotationType === 'TrackType') {
|
|
152
|
+
const trackMeta = modelMetadata;
|
|
153
|
+
const tags = trackMeta.tags.map((item) => '@' + item);
|
|
154
|
+
if (trackMeta.unique) {
|
|
155
|
+
const fieldDetail = typeof trackMeta.unique === 'string' ? trackMeta.unique : null;
|
|
156
|
+
tags.push(`@unique(${fieldDetail ? `map: "${fieldDetail}"` : ''})`);
|
|
157
|
+
}
|
|
158
|
+
if (trackMeta.isArray || trackMeta.type.name === 'Array') {
|
|
159
|
+
requiredString = '';
|
|
160
|
+
}
|
|
161
|
+
// Process any database-specific options from the metadata
|
|
162
|
+
const dbSpecificTags = type_converter_1.TypeConverter.processTypeOptions(trackMeta, dbType);
|
|
163
|
+
tags.push(...dbSpecificTags);
|
|
164
|
+
section += `\t${key} ${type_converter_1.TypeConverter.toConfigCase(trackMeta, dbType, key === 'id')}${requiredString} ${tags.join(' ')}\n`;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
for (const superTag of model._SUPER_TAGS) {
|
|
168
|
+
const mapStr = superTag.map ? `, map: "${superTag.map}"` : '';
|
|
169
|
+
section += `\t@@${superTag.tagType}([${superTag.fields.join(', ')}]${mapStr})\n`;
|
|
170
|
+
}
|
|
171
|
+
section += '}\n';
|
|
172
|
+
return section;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Install Prisma with the generated schema
|
|
176
|
+
* @param configService The configuration service
|
|
177
|
+
* @param dbService The database service
|
|
178
|
+
* @param leaveFile Whether to leave the schema file after generation
|
|
179
|
+
*/
|
|
180
|
+
static async installPrisma(configService, dbService, leaveFile = false) {
|
|
181
|
+
const dbUrl = configService.get('db_url');
|
|
182
|
+
const dbType = configService.get('db_type') || 'mongodb';
|
|
183
|
+
let template = this.generateBaseSchema(dbType, dbUrl);
|
|
184
|
+
const dbModels = configService.get('db_models');
|
|
185
|
+
if (dbModels) {
|
|
186
|
+
for (const model of dbModels) {
|
|
187
|
+
const modelName = model._collection;
|
|
188
|
+
const modelMetadatas = await _model_1.RWSModel.getModelAnnotations(model);
|
|
189
|
+
for (const key in modelMetadatas) {
|
|
190
|
+
const annotationType = modelMetadatas[key].annotationType;
|
|
191
|
+
if (annotationType === 'Relation') {
|
|
192
|
+
const relationMeta = modelMetadatas[key].metadata;
|
|
193
|
+
const relatedModel = relationMeta.relatedTo;
|
|
194
|
+
const relatedModelName = relatedModel._collection;
|
|
195
|
+
const relationKey = [modelName, relatedModelName].join('_');
|
|
196
|
+
// Add this relation to the map
|
|
197
|
+
relation_manager_1.RelationManager.markRelation(relationKey);
|
|
198
|
+
}
|
|
199
|
+
if (annotationType === 'InverseRelation') {
|
|
200
|
+
const relationMeta = modelMetadatas[key].metadata;
|
|
201
|
+
const relatedModel = relationMeta.inversionModel;
|
|
202
|
+
const relatedModelName = relatedModel._collection;
|
|
203
|
+
const relationKey = [relatedModelName, modelName].join('_');
|
|
204
|
+
relation_manager_1.RelationManager.markRelation(relationKey, true);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
// Now generate the model sections with all relations
|
|
209
|
+
for (const model of dbModels) {
|
|
210
|
+
const modelSection = await SchemaGenerator.generateModelSections(model, configService);
|
|
211
|
+
template += '\n\n' + modelSection;
|
|
212
|
+
log(chalk_1.default.green('[RWS]'), chalk_1.default.blue('Building DB Model'), model.name);
|
|
213
|
+
}
|
|
214
|
+
const [schemaDir, schemaPath] = utils_1.DbUtils.getSchemaDir();
|
|
215
|
+
if (!fs_1.default.existsSync(schemaDir)) {
|
|
216
|
+
fs_1.default.mkdirSync(schemaDir);
|
|
217
|
+
}
|
|
218
|
+
if (fs_1.default.existsSync(schemaPath)) {
|
|
219
|
+
fs_1.default.unlinkSync(schemaPath);
|
|
220
|
+
}
|
|
221
|
+
fs_1.default.writeFileSync(schemaPath, template);
|
|
222
|
+
await console_1.rwsShell.runCommand(`${utils_1.DbUtils.detectInstaller()} prisma generate --schema=${schemaPath}`, process.cwd());
|
|
223
|
+
leaveFile = false;
|
|
224
|
+
log(chalk_1.default.green('[RWS Init]') + ' prisma schema generated from ', schemaPath);
|
|
225
|
+
if (!leaveFile) {
|
|
226
|
+
// fs.unlinkSync(schemaPath);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Push database models to the database
|
|
232
|
+
* @param configService The configuration service
|
|
233
|
+
* @param dbService The database service
|
|
234
|
+
* @param leaveFile Whether to leave the schema file after generation
|
|
235
|
+
*/
|
|
236
|
+
static async pushDBModels(configService, dbService, leaveFile = false) {
|
|
237
|
+
process.env = { ...process.env, [this.dbUrlVarName]: configService.get('db_url') };
|
|
238
|
+
const [_, schemaPath] = utils_1.DbUtils.getSchemaDir();
|
|
239
|
+
await console_1.rwsShell.runCommand(`${utils_1.DbUtils.detectInstaller()} prisma db push --schema=${schemaPath}`, process.cwd());
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
exports.SchemaGenerator = SchemaGenerator;
|
|
243
|
+
SchemaGenerator.dbUrlVarName = 'PRISMA_DB_URL';
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { IDbOpts } from '../../models/interfaces/IDbOpts';
|
|
2
|
+
import { ITrackerMetaOpts } from '../../models/_model';
|
|
3
|
+
import { IIdMetaOpts } from 'src/decorators/IdType';
|
|
4
|
+
/**
|
|
5
|
+
* Handles type conversion for database schema generation
|
|
6
|
+
*/
|
|
7
|
+
export declare class TypeConverter {
|
|
8
|
+
/**
|
|
9
|
+
* Convert a JavaScript type to a Prisma schema type
|
|
10
|
+
*/
|
|
11
|
+
static toConfigCase(modelType: ITrackerMetaOpts | IIdMetaOpts, dbType?: string, isId?: boolean): string;
|
|
12
|
+
/**
|
|
13
|
+
* Process type functions metadata to extract database-specific options
|
|
14
|
+
* @param metadata The metadata from a type function
|
|
15
|
+
* @param dbType The database type
|
|
16
|
+
* @returns Array of tags to apply to the field
|
|
17
|
+
*/
|
|
18
|
+
static processTypeOptions(metadata: {
|
|
19
|
+
tags: string[];
|
|
20
|
+
dbOptions: IDbOpts['dbOptions'];
|
|
21
|
+
}, dbType: string): string[];
|
|
22
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TypeConverter = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Handles type conversion for database schema generation
|
|
6
|
+
*/
|
|
7
|
+
class TypeConverter {
|
|
8
|
+
/**
|
|
9
|
+
* Convert a JavaScript type to a Prisma schema type
|
|
10
|
+
*/
|
|
11
|
+
static toConfigCase(modelType, dbType = 'mongodb', isId = false) {
|
|
12
|
+
const type = modelType.type;
|
|
13
|
+
let input = type.name;
|
|
14
|
+
// Handle basic types
|
|
15
|
+
if (input == 'Number') {
|
|
16
|
+
input = 'Int';
|
|
17
|
+
}
|
|
18
|
+
if (input == 'Object') {
|
|
19
|
+
input = 'Json';
|
|
20
|
+
}
|
|
21
|
+
if (input == 'Date') {
|
|
22
|
+
input = 'DateTime';
|
|
23
|
+
}
|
|
24
|
+
if (input == 'Boolean') {
|
|
25
|
+
// Ensure Boolean is properly handled for all database types
|
|
26
|
+
input = 'Boolean';
|
|
27
|
+
}
|
|
28
|
+
if (input == 'Array') {
|
|
29
|
+
// Handle arrays differently based on database type
|
|
30
|
+
if (dbType === 'mysql') {
|
|
31
|
+
// MySQL doesn't support native arrays, use Json instead
|
|
32
|
+
input = 'Json';
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
input = 'Json[]';
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
const firstChar = input.charAt(0).toUpperCase();
|
|
39
|
+
const restOfString = input.slice(1);
|
|
40
|
+
let resultField = firstChar + restOfString;
|
|
41
|
+
if (isId) {
|
|
42
|
+
return dbType === 'mongodb' ? 'String' : 'Int';
|
|
43
|
+
}
|
|
44
|
+
const trackerModelType = modelType;
|
|
45
|
+
if (trackerModelType.isArray) {
|
|
46
|
+
// Handle arrays differently based on database type
|
|
47
|
+
if (dbType === 'mysql') {
|
|
48
|
+
// For MySQL, we don't append [] as it doesn't support native arrays
|
|
49
|
+
// Instead, we'll store arrays as JSON
|
|
50
|
+
resultField = 'Json';
|
|
51
|
+
}
|
|
52
|
+
else if (dbType === 'postgresql' || dbType === 'postgres') {
|
|
53
|
+
// PostgreSQL supports arrays natively
|
|
54
|
+
resultField += '[]';
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
resultField += '[]';
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return resultField;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Process type functions metadata to extract database-specific options
|
|
64
|
+
* @param metadata The metadata from a type function
|
|
65
|
+
* @param dbType The database type
|
|
66
|
+
* @returns Array of tags to apply to the field
|
|
67
|
+
*/
|
|
68
|
+
static processTypeOptions(metadata, dbType) {
|
|
69
|
+
var _a, _b;
|
|
70
|
+
const tags = [...(metadata.tags || [])];
|
|
71
|
+
// Extract any database-specific options from the metadata
|
|
72
|
+
// and convert them to appropriate Prisma schema tags
|
|
73
|
+
if (metadata.dbOptions) {
|
|
74
|
+
// Handle MySQL-specific options
|
|
75
|
+
if (dbType === 'mysql' && metadata.dbOptions.mysql) {
|
|
76
|
+
if (metadata.dbOptions.mysql.useText) {
|
|
77
|
+
tags.push('@db.Text');
|
|
78
|
+
}
|
|
79
|
+
else if (metadata.dbOptions.mysql.maxLength) {
|
|
80
|
+
tags.push(`@db.VarChar(${metadata.dbOptions.mysql.maxLength})`);
|
|
81
|
+
}
|
|
82
|
+
if (metadata.dbOptions.mysql.useUuid && ((_a = metadata.tags) === null || _a === void 0 ? void 0 : _a.includes('id'))) {
|
|
83
|
+
tags.push('default(uuid())');
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
// Handle PostgreSQL-specific options
|
|
87
|
+
if ((dbType === 'postgresql' || dbType === 'postgres') && metadata.dbOptions.postgres) {
|
|
88
|
+
if (metadata.dbOptions.postgres.useText) {
|
|
89
|
+
tags.push('@db.Text');
|
|
90
|
+
}
|
|
91
|
+
if (metadata.dbOptions.postgres.useUuid && ((_b = metadata.tags) === null || _b === void 0 ? void 0 : _b.includes('id'))) {
|
|
92
|
+
tags.push('@default(uuid())');
|
|
93
|
+
tags.push('@db.Uuid');
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
// Handle MongoDB-specific options
|
|
97
|
+
if (dbType === 'mongodb' && metadata.dbOptions.mongodb) {
|
|
98
|
+
if (metadata.dbOptions.mongodb.customType) {
|
|
99
|
+
tags.push(`@db.${metadata.dbOptions.mongodb.customType}`);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return tags;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
exports.TypeConverter = TypeConverter;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { IDbConfigParams } from '../../types/DbConfigHandler';
|
|
2
|
+
import { IIdMetaOpts } from '../../decorators/IdType';
|
|
3
|
+
/**
|
|
4
|
+
* Utility functions for database operations
|
|
5
|
+
*/
|
|
6
|
+
export declare class DbUtils {
|
|
7
|
+
/**
|
|
8
|
+
* Get the directory and path for the Prisma schema file
|
|
9
|
+
*/
|
|
10
|
+
static getSchemaDir(): [string, string];
|
|
11
|
+
/**
|
|
12
|
+
* Detect the package installer (yarn or npx)
|
|
13
|
+
*/
|
|
14
|
+
static detectInstaller(): string;
|
|
15
|
+
/**
|
|
16
|
+
* Generate an ID field based on the database type
|
|
17
|
+
*/
|
|
18
|
+
static generateId(dbType: IDbConfigParams['db_type'], modelMeta: Record<string, {
|
|
19
|
+
annotationType: string;
|
|
20
|
+
metadata: IIdMetaOpts;
|
|
21
|
+
}>, debug?: boolean): string;
|
|
22
|
+
}
|
|
23
|
+
export declare const workspaceRootPath: string;
|
|
24
|
+
export declare const moduleDirPath: string;
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.moduleDirPath = exports.workspaceRootPath = exports.DbUtils = void 0;
|
|
7
|
+
const console_1 = require("@rws-framework/console");
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const fs_1 = __importDefault(require("fs"));
|
|
10
|
+
const type_converter_1 = require("./type-converter");
|
|
11
|
+
const workspaceRoot = console_1.rwsPath.findRootWorkspacePath();
|
|
12
|
+
const moduleDir = path_1.default.resolve(workspaceRoot, 'node_modules', '@rws-framework', 'db');
|
|
13
|
+
/**
|
|
14
|
+
* Utility functions for database operations
|
|
15
|
+
*/
|
|
16
|
+
class DbUtils {
|
|
17
|
+
/**
|
|
18
|
+
* Get the directory and path for the Prisma schema file
|
|
19
|
+
*/
|
|
20
|
+
static getSchemaDir() {
|
|
21
|
+
const schemaDir = path_1.default.join(moduleDir, 'prisma');
|
|
22
|
+
const schemaPath = path_1.default.join(schemaDir, 'schema.prisma');
|
|
23
|
+
return [schemaDir, schemaPath];
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Detect the package installer (yarn or npx)
|
|
27
|
+
*/
|
|
28
|
+
static detectInstaller() {
|
|
29
|
+
if (fs_1.default.existsSync(path_1.default.join(workspaceRoot, 'yarn.lock'))) {
|
|
30
|
+
return 'yarn';
|
|
31
|
+
}
|
|
32
|
+
return 'npx';
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Generate an ID field based on the database type
|
|
36
|
+
*/
|
|
37
|
+
static generateId(dbType, modelMeta, debug = false) {
|
|
38
|
+
var _a, _b, _c, _d;
|
|
39
|
+
let useUuid = false;
|
|
40
|
+
let field = 'id';
|
|
41
|
+
const tags = [];
|
|
42
|
+
for (const key in modelMeta) {
|
|
43
|
+
const modelMetadata = modelMeta[key].metadata;
|
|
44
|
+
const annotationType = modelMeta[key].annotationType;
|
|
45
|
+
if (key !== 'id') {
|
|
46
|
+
if (annotationType == 'IdType') {
|
|
47
|
+
const dbSpecificTags = type_converter_1.TypeConverter.processTypeOptions({ tags: [], dbOptions: modelMetadata.dbOptions }, dbType);
|
|
48
|
+
tags.push(...dbSpecificTags);
|
|
49
|
+
if (debug) {
|
|
50
|
+
console.log({ modelMetadata: modelMetadata.dbOptions });
|
|
51
|
+
}
|
|
52
|
+
field = key;
|
|
53
|
+
if ((_b = (_a = modelMetadata.dbOptions) === null || _a === void 0 ? void 0 : _a.mysql) === null || _b === void 0 ? void 0 : _b.useUuid) {
|
|
54
|
+
useUuid = true;
|
|
55
|
+
}
|
|
56
|
+
if ((_d = (_c = modelMetadata.dbOptions) === null || _c === void 0 ? void 0 : _c.postgres) === null || _d === void 0 ? void 0 : _d.useUuid) {
|
|
57
|
+
useUuid = true;
|
|
58
|
+
}
|
|
59
|
+
if (modelMetadata.type.name === 'String') {
|
|
60
|
+
useUuid = true;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
let idString;
|
|
66
|
+
switch (dbType) {
|
|
67
|
+
case 'mongodb':
|
|
68
|
+
idString = `${field} String @id @default(auto()) @map("_id") @db.ObjectId`;
|
|
69
|
+
break;
|
|
70
|
+
case 'mysql':
|
|
71
|
+
idString = useUuid
|
|
72
|
+
? `${field} String @id @default(uuid())`
|
|
73
|
+
: `${field} Int @id @default(autoincrement())`;
|
|
74
|
+
break;
|
|
75
|
+
case 'postgresql':
|
|
76
|
+
case 'postgres':
|
|
77
|
+
idString = useUuid
|
|
78
|
+
? `${field} String @id @default(uuid())`
|
|
79
|
+
: `${field} Int @id @default(autoincrement())`;
|
|
80
|
+
break;
|
|
81
|
+
case 'sqlite':
|
|
82
|
+
idString = `${field} Int @id @default(autoincrement())`;
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
if (tags.length) {
|
|
86
|
+
idString += ' ' + tags.join(' ');
|
|
87
|
+
}
|
|
88
|
+
if (!idString) {
|
|
89
|
+
throw new Error(`DB type "${dbType}" is not supported!`);
|
|
90
|
+
}
|
|
91
|
+
if (debug) {
|
|
92
|
+
console.log({ idString, useUuid });
|
|
93
|
+
}
|
|
94
|
+
return idString;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
exports.DbUtils = DbUtils;
|
|
98
|
+
exports.workspaceRootPath = workspaceRoot;
|
|
99
|
+
exports.moduleDirPath = moduleDir;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { DBService } from "./services/DBService";
|
|
2
2
|
import { RWSModel, OpModelType } from "./models/_model";
|
|
3
|
-
import { InverseRelation, Relation, TrackType, InverseTimeSeries,
|
|
3
|
+
import { InverseRelation, Relation, TrackType, IdType, InverseTimeSeries, ITrackerMetaOpts, ITrackerOpts } from './decorators';
|
|
4
4
|
import { DbHelper } from './helper/DbHelper';
|
|
5
5
|
import { FieldsHelper } from './helper/FieldsHelper';
|
|
6
6
|
import type { FindByType } from './types/FindParams';
|
|
@@ -8,5 +8,5 @@ import type { ITimeSeries } from './types/ITimeSeries';
|
|
|
8
8
|
import type { IDbConfigHandler, IDbConfigParams } from './types/DbConfigHandler';
|
|
9
9
|
import type { IRWSModel } from './types/IRWSModel';
|
|
10
10
|
import { RWSCollection, IRWSCollectionMeta, IRWSCollectionOpts } from "./decorators/RWSCollection";
|
|
11
|
-
export type { IRWSCollectionMeta, IRWSCollectionOpts, IRWSModel,
|
|
12
|
-
export { RWSModel, RWSCollection, DBService, FindByType, InverseRelation, Relation, TrackType, InverseTimeSeries, DbHelper, FieldsHelper };
|
|
11
|
+
export type { IRWSCollectionMeta, IRWSCollectionOpts, IRWSModel, ITrackerMetaOpts, ITrackerOpts, OpModelType, IDbConfigHandler, IDbConfigParams, ITimeSeries, };
|
|
12
|
+
export { RWSModel, RWSCollection, DBService, FindByType, InverseRelation, Relation, TrackType, InverseTimeSeries, IdType, DbHelper, FieldsHelper };
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.FieldsHelper = exports.DbHelper = exports.InverseTimeSeries = exports.TrackType = exports.Relation = exports.InverseRelation = exports.DBService = exports.RWSCollection = exports.RWSModel = void 0;
|
|
3
|
+
exports.FieldsHelper = exports.DbHelper = exports.IdType = exports.InverseTimeSeries = exports.TrackType = exports.Relation = exports.InverseRelation = exports.DBService = exports.RWSCollection = exports.RWSModel = void 0;
|
|
4
4
|
const DBService_1 = require("./services/DBService");
|
|
5
5
|
Object.defineProperty(exports, "DBService", { enumerable: true, get: function () { return DBService_1.DBService; } });
|
|
6
6
|
const _model_1 = require("./models/_model");
|
|
@@ -10,6 +10,7 @@ const decorators_1 = require("./decorators");
|
|
|
10
10
|
Object.defineProperty(exports, "InverseRelation", { enumerable: true, get: function () { return decorators_1.InverseRelation; } });
|
|
11
11
|
Object.defineProperty(exports, "Relation", { enumerable: true, get: function () { return decorators_1.Relation; } });
|
|
12
12
|
Object.defineProperty(exports, "TrackType", { enumerable: true, get: function () { return decorators_1.TrackType; } });
|
|
13
|
+
Object.defineProperty(exports, "IdType", { enumerable: true, get: function () { return decorators_1.IdType; } });
|
|
13
14
|
Object.defineProperty(exports, "InverseTimeSeries", { enumerable: true, get: function () { return decorators_1.InverseTimeSeries; } });
|
|
14
15
|
const DbHelper_1 = require("./helper/DbHelper");
|
|
15
16
|
Object.defineProperty(exports, "DbHelper", { enumerable: true, get: function () { return DbHelper_1.DbHelper; } });
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { RWSModel } from './_model';
|
|
2
|
-
export default class TimeSeriesModel<ChildClass> extends RWSModel<TimeSeriesModel<ChildClass>> {
|
|
3
|
-
value: number;
|
|
4
|
-
timestamp: Date;
|
|
5
|
-
params: any;
|
|
6
|
-
constructor(data?: any);
|
|
7
|
-
}
|
|
1
|
+
import { RWSModel } from './_model';
|
|
2
|
+
export default class TimeSeriesModel<ChildClass> extends RWSModel<TimeSeriesModel<ChildClass>> {
|
|
3
|
+
value: number;
|
|
4
|
+
timestamp: Date;
|
|
5
|
+
params: any;
|
|
6
|
+
constructor(data?: any);
|
|
7
|
+
}
|
|
@@ -1,33 +1,33 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
-
};
|
|
8
|
-
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
-
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
-
};
|
|
11
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
const _model_1 = require("./_model");
|
|
13
|
-
class TimeSeriesModel extends _model_1.RWSModel {
|
|
14
|
-
constructor(data) {
|
|
15
|
-
super(data);
|
|
16
|
-
if (!this.timestamp) {
|
|
17
|
-
this.timestamp = new Date();
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
exports.default = TimeSeriesModel;
|
|
22
|
-
__decorate([
|
|
23
|
-
(0, _model_1.TrackType)(Number),
|
|
24
|
-
__metadata("design:type", Number)
|
|
25
|
-
], TimeSeriesModel.prototype, "value", void 0);
|
|
26
|
-
__decorate([
|
|
27
|
-
(0, _model_1.TrackType)(Date),
|
|
28
|
-
__metadata("design:type", Date)
|
|
29
|
-
], TimeSeriesModel.prototype, "timestamp", void 0);
|
|
30
|
-
__decorate([
|
|
31
|
-
(0, _model_1.TrackType)(Object),
|
|
32
|
-
__metadata("design:type", Object)
|
|
33
|
-
], TimeSeriesModel.prototype, "params", void 0);
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
const _model_1 = require("./_model");
|
|
13
|
+
class TimeSeriesModel extends _model_1.RWSModel {
|
|
14
|
+
constructor(data) {
|
|
15
|
+
super(data);
|
|
16
|
+
if (!this.timestamp) {
|
|
17
|
+
this.timestamp = new Date();
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
exports.default = TimeSeriesModel;
|
|
22
|
+
__decorate([
|
|
23
|
+
(0, _model_1.TrackType)(Number),
|
|
24
|
+
__metadata("design:type", Number)
|
|
25
|
+
], TimeSeriesModel.prototype, "value", void 0);
|
|
26
|
+
__decorate([
|
|
27
|
+
(0, _model_1.TrackType)(Date),
|
|
28
|
+
__metadata("design:type", Date)
|
|
29
|
+
], TimeSeriesModel.prototype, "timestamp", void 0);
|
|
30
|
+
__decorate([
|
|
31
|
+
(0, _model_1.TrackType)(Object),
|
|
32
|
+
__metadata("design:type", Object)
|
|
33
|
+
], TimeSeriesModel.prototype, "params", void 0);
|
package/dist/models/_model.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @deprecated This file is deprecated. Import from 'models' directory instead.
|
|
3
3
|
*/
|
|
4
|
-
import { IModel, IRWSModelServices, OpModelType, RelationBindType, RelOneMetaType, RelManyMetaType, RWSModel, TrackType,
|
|
4
|
+
import { IModel, IRWSModelServices, OpModelType, RelationBindType, RelOneMetaType, RelManyMetaType, RWSModel, TrackType, ITrackerMetaOpts } from './index';
|
|
5
5
|
export { RWSModel, TrackType };
|
|
6
|
-
export type { IModel, IRWSModelServices, OpModelType, RelationBindType, RelOneMetaType, RelManyMetaType,
|
|
6
|
+
export type { IModel, IRWSModelServices, OpModelType, RelationBindType, RelOneMetaType, RelManyMetaType, ITrackerMetaOpts };
|
package/dist/models/_model.js
CHANGED
|
File without changes
|
|
@@ -3,12 +3,15 @@ import { IRWSModelServices } from '../interfaces/IRWSModelServices';
|
|
|
3
3
|
import { OpModelType } from '../interfaces/OpModelType';
|
|
4
4
|
import { FindByType, IPaginationParams } from '../../types/FindParams';
|
|
5
5
|
import { DBService } from '../../services/DBService';
|
|
6
|
+
import { ISuperTagData } from '../../decorators/RWSCollection';
|
|
6
7
|
declare class RWSModel<T> implements IModel {
|
|
7
8
|
static services: IRWSModelServices;
|
|
8
9
|
[key: string]: any;
|
|
9
10
|
id: string | number;
|
|
10
11
|
static _collection: string;
|
|
11
12
|
static _RELATIONS: {};
|
|
13
|
+
static _NO_ID: boolean;
|
|
14
|
+
static _SUPER_TAGS: ISuperTagData[];
|
|
12
15
|
static _BANNED_KEYS: string[];
|
|
13
16
|
static allModels: OpModelType<any>[];
|
|
14
17
|
static _CUT_KEYS: string[];
|
|
@@ -58,7 +61,7 @@ declare class RWSModel<T> implements IModel {
|
|
|
58
61
|
static create<T extends RWSModel<T>>(this: new () => T, data: any): Promise<T>;
|
|
59
62
|
static loadModels(): OpModelType<any>[];
|
|
60
63
|
loadModels(): OpModelType<any>[];
|
|
61
|
-
private
|
|
64
|
+
private checkRelDisabled;
|
|
62
65
|
static setServices(services: IRWSModelServices): void;
|
|
63
66
|
getDb(): DBService;
|
|
64
67
|
static getDb(): DBService;
|