@autofleet/sadot 0.6.1-temp-2 → 0.6.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.
- package/dist/api/index.d.ts +2 -0
- package/dist/api/index.js +11 -0
- package/dist/api/v1/definition/index.d.ts +2 -0
- package/dist/api/v1/definition/index.js +118 -0
- package/dist/api/v1/definition/validations.d.ts +2 -0
- package/dist/api/v1/definition/validations.js +36 -0
- package/dist/api/v1/errors.d.ts +2 -0
- package/dist/api/v1/errors.js +15 -0
- package/dist/api/v1/index.d.ts +2 -0
- package/dist/api/v1/index.js +10 -0
- package/dist/errors/index.d.ts +16 -0
- package/dist/errors/index.js +45 -0
- package/dist/events/index.d.ts +4 -0
- package/dist/events/index.js +47 -0
- package/dist/hooks/create.d.ts +10 -0
- package/dist/hooks/create.js +74 -0
- package/dist/hooks/enrich.d.ts +7 -0
- package/dist/hooks/enrich.js +126 -0
- package/dist/hooks/find.d.ts +1 -0
- package/dist/hooks/find.js +29 -0
- package/dist/hooks/index.d.ts +6 -0
- package/dist/hooks/index.js +18 -0
- package/dist/hooks/update.d.ts +10 -0
- package/dist/hooks/update.js +59 -0
- package/dist/hooks/workaround.d.ts +10 -0
- package/dist/hooks/workaround.js +37 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.js +56 -0
- package/dist/models/CustomFieldDefinition.d.ts +23 -0
- package/dist/models/CustomFieldDefinition.js +165 -0
- package/dist/models/CustomFieldValue.d.ts +15 -0
- package/dist/models/CustomFieldValue.js +148 -0
- package/dist/models/index.d.ts +10 -0
- package/dist/models/index.js +93 -0
- package/dist/models/tests/AssociatedTestModel.d.ts +12 -0
- package/dist/models/tests/AssociatedTestModel.js +71 -0
- package/dist/models/tests/TestModel.d.ts +12 -0
- package/dist/models/tests/TestModel.js +69 -0
- package/dist/models/tests/contextAwareModels/ContextAwareTestModel.d.ts +10 -0
- package/dist/models/tests/contextAwareModels/ContextAwareTestModel.js +55 -0
- package/dist/models/tests/contextAwareModels/ContextTestModel.d.ts +13 -0
- package/dist/models/tests/contextAwareModels/ContextTestModel.js +47 -0
- package/dist/repository/definition.d.ts +20 -0
- package/dist/repository/definition.js +92 -0
- package/dist/repository/value.d.ts +28 -0
- package/dist/repository/value.js +117 -0
- package/dist/scopes/filter.d.ts +23 -0
- package/dist/scopes/filter.js +55 -0
- package/dist/scopes/index.d.ts +2 -0
- package/dist/scopes/index.js +6 -0
- package/dist/tests/api/test-api.d.ts +2 -0
- package/dist/tests/api/test-api.js +56 -0
- package/dist/tests/functional/searching/index.d.ts +8 -0
- package/dist/tests/functional/searching/index.js +44 -0
- package/dist/tests/helpers/database-config.d.ts +16 -0
- package/dist/tests/helpers/database-config.js +17 -0
- package/dist/tests/helpers/index.d.ts +2 -0
- package/dist/tests/helpers/index.js +20 -0
- package/dist/tests/mocks/definition.mock.d.ts +43 -0
- package/dist/tests/mocks/definition.mock.js +70 -0
- package/dist/tests/mocks/events.mock.d.ts +3 -0
- package/dist/tests/mocks/events.mock.js +19 -0
- package/dist/tests/mocks/testModel.d.ts +12 -0
- package/dist/tests/mocks/testModel.js +35 -0
- package/dist/types/definition/index.d.ts +23 -0
- package/dist/types/definition/index.js +2 -0
- package/dist/types/index.d.ts +31 -0
- package/dist/types/index.js +2 -0
- package/dist/types/value/index.d.ts +15 -0
- package/dist/types/value/index.js +2 -0
- package/dist/utils/constants/index.d.ts +5 -0
- package/dist/utils/constants/index.js +8 -0
- package/dist/utils/db/index.d.ts +4 -0
- package/dist/utils/db/index.js +24 -0
- package/dist/utils/helpers/index.d.ts +25 -0
- package/dist/utils/helpers/index.js +34 -0
- package/dist/utils/init.d.ts +5 -0
- package/dist/utils/init.js +106 -0
- package/dist/utils/logger/index.d.ts +2 -0
- package/dist/utils/logger/index.js +6 -0
- package/dist/utils/scopeAttributes.d.ts +2 -0
- package/dist/utils/scopeAttributes.js +11 -0
- package/dist/utils/validations/custom-fields.d.ts +3 -0
- package/dist/utils/validations/custom-fields.js +10 -0
- package/dist/utils/validations/custom.d.ts +15 -0
- package/dist/utils/validations/custom.js +42 -0
- package/dist/utils/validations/index.d.ts +2 -0
- package/dist/utils/validations/index.js +20 -0
- package/dist/utils/validations/type.d.ts +18 -0
- package/dist/utils/validations/type.js +50 -0
- package/dist/utils/validations/validators.d.ts +12 -0
- package/dist/utils/validations/validators.js +33 -0
- package/package.json +2 -2
- package/src/utils/validations/type.ts +0 -10
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
+
if (mod && mod.__esModule) return mod;
|
|
20
|
+
var result = {};
|
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
+
__setModuleDefault(result, mod);
|
|
23
|
+
return result;
|
|
24
|
+
};
|
|
25
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
+
};
|
|
28
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
+
exports.beforeUpdate = exports.beforeBulkUpdate = void 0;
|
|
30
|
+
const logger_1 = __importDefault(require("../utils/logger"));
|
|
31
|
+
const ValueRepo = __importStar(require("../repository/value"));
|
|
32
|
+
const scopeAttributes_1 = __importDefault(require("../utils/scopeAttributes"));
|
|
33
|
+
/**
|
|
34
|
+
* A hook to update the custom fields when updating a model (more then one instance).
|
|
35
|
+
*/
|
|
36
|
+
const beforeBulkUpdate = (options) => {
|
|
37
|
+
// This will activate the beforeUpdate hook on each updating instance.
|
|
38
|
+
// eslint-disable-next-line no-param-reassign
|
|
39
|
+
options.individualHooks = true;
|
|
40
|
+
};
|
|
41
|
+
exports.beforeBulkUpdate = beforeBulkUpdate;
|
|
42
|
+
/**
|
|
43
|
+
* A hook to update the custom fields when updating a model instance.
|
|
44
|
+
* TODO - cleanup if update fail
|
|
45
|
+
*/
|
|
46
|
+
const beforeUpdate = (scopeAttributes, modelOptions = {}) => async (instance, options) => {
|
|
47
|
+
logger_1.default.debug('sadot - before update hook');
|
|
48
|
+
const { fields } = options;
|
|
49
|
+
const modelType = instance.constructor.name;
|
|
50
|
+
const identifiers = (0, scopeAttributes_1.default)(instance, scopeAttributes);
|
|
51
|
+
const customFieldsIdx = fields.indexOf('customFields');
|
|
52
|
+
if (customFieldsIdx > -1) {
|
|
53
|
+
const { customFields } = instance;
|
|
54
|
+
await ValueRepo.updateValues(modelType, instance.id, identifiers, customFields, { transaction: options.transaction, modelOptions });
|
|
55
|
+
// eslint-disable-next-line no-param-reassign
|
|
56
|
+
fields.splice(customFieldsIdx, 1);
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
exports.beforeUpdate = beforeUpdate;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workaround to a bug in sequelize.🐛
|
|
3
|
+
*
|
|
4
|
+
* **afterFind hook** isn't working on nested (included) models.
|
|
5
|
+
* The solution here is to add a global afterFind hook,
|
|
6
|
+
* which manually calls the afterFind hook of each model, recursively
|
|
7
|
+
* https://github.com/sequelize/sequelize/issues/4627
|
|
8
|
+
*/
|
|
9
|
+
declare const handleChildrenAfterFindHook: (instances: any, options: any, level?: number) => any;
|
|
10
|
+
export default handleChildrenAfterFindHook;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Workaround to a bug in sequelize.🐛
|
|
4
|
+
*
|
|
5
|
+
* **afterFind hook** isn't working on nested (included) models.
|
|
6
|
+
* The solution here is to add a global afterFind hook,
|
|
7
|
+
* which manually calls the afterFind hook of each model, recursively
|
|
8
|
+
* https://github.com/sequelize/sequelize/issues/4627
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
const handleChildrenAfterFindHook = async (instances, options, level = 0) => {
|
|
12
|
+
if (!instances)
|
|
13
|
+
return Promise.resolve();
|
|
14
|
+
if (Array.isArray(instances)) {
|
|
15
|
+
return Promise.all(instances.map((instance) => {
|
|
16
|
+
const { options: instanceOptions } = instance.constructor;
|
|
17
|
+
return handleChildrenAfterFindHook(instance, instanceOptions, level);
|
|
18
|
+
}));
|
|
19
|
+
}
|
|
20
|
+
const instance = instances;
|
|
21
|
+
const { constructor } = instance;
|
|
22
|
+
/**
|
|
23
|
+
* Root model will have already run their "afterFind" hook.
|
|
24
|
+
* Only run children "afterFind" hooks.
|
|
25
|
+
*/
|
|
26
|
+
if (level >= 1) {
|
|
27
|
+
await constructor.runHooks('afterFind', instance, options);
|
|
28
|
+
}
|
|
29
|
+
const { associations } = constructor;
|
|
30
|
+
const associatedNames = Object.keys(instance).filter((attribute) => Object.keys(associations).includes(attribute));
|
|
31
|
+
if (associatedNames.length) {
|
|
32
|
+
const childInstances = associatedNames.map((name) => instance[name]);
|
|
33
|
+
return handleChildrenAfterFindHook(childInstances, options, level + 1);
|
|
34
|
+
}
|
|
35
|
+
return Promise.resolve();
|
|
36
|
+
};
|
|
37
|
+
exports.default = handleChildrenAfterFindHook;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Application } from 'express';
|
|
2
|
+
import { Sequelize } from 'sequelize-typescript';
|
|
3
|
+
import type { CustomFieldOptions, ModelFetcher } from './types';
|
|
4
|
+
export * from './utils/validations/custom-fields';
|
|
5
|
+
export * from './utils/constants';
|
|
6
|
+
export * from './utils/helpers';
|
|
7
|
+
export { CustomFieldDefinitionType } from './utils/validations/type';
|
|
8
|
+
/**
|
|
9
|
+
* Adding custom fields enrichment to the models inside the MODELS_FILE_NAME json file
|
|
10
|
+
* @see {@link 'custom-fields/config'} for configurations
|
|
11
|
+
*/
|
|
12
|
+
declare const useCustomFields: (app: Application | null, getModel: ModelFetcher, options: CustomFieldOptions) => Promise<Sequelize>;
|
|
13
|
+
export default useCustomFields;
|
|
14
|
+
export declare const disableCustomFields: (models: any, getModel: any) => void;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
17
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
18
|
+
};
|
|
19
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
exports.disableCustomFields = exports.CustomFieldDefinitionType = void 0;
|
|
21
|
+
const models_1 = require("./models");
|
|
22
|
+
const api_1 = __importDefault(require("./api"));
|
|
23
|
+
const db_1 = __importDefault(require("./utils/db"));
|
|
24
|
+
const logger_1 = __importDefault(require("./utils/logger"));
|
|
25
|
+
const init_1 = require("./utils/init");
|
|
26
|
+
__exportStar(require("./utils/validations/custom-fields"), exports);
|
|
27
|
+
__exportStar(require("./utils/constants"), exports);
|
|
28
|
+
__exportStar(require("./utils/helpers"), exports);
|
|
29
|
+
var type_1 = require("./utils/validations/type");
|
|
30
|
+
Object.defineProperty(exports, "CustomFieldDefinitionType", { enumerable: true, get: function () { return type_1.CustomFieldDefinitionType; } });
|
|
31
|
+
/**
|
|
32
|
+
* Adding custom fields enrichment to the models inside the MODELS_FILE_NAME json file
|
|
33
|
+
* @see {@link 'custom-fields/config'} for configurations
|
|
34
|
+
*/
|
|
35
|
+
const useCustomFields = async (app, getModel, options) => {
|
|
36
|
+
const { models } = options;
|
|
37
|
+
if (app) {
|
|
38
|
+
app.use('/api', api_1.default);
|
|
39
|
+
}
|
|
40
|
+
const sequelize = (0, db_1.default)(options.databaseConfig);
|
|
41
|
+
if (process.env.NODE_ENV === 'test') {
|
|
42
|
+
await (0, models_1.initTestModels)(sequelize);
|
|
43
|
+
}
|
|
44
|
+
// The order is important
|
|
45
|
+
(0, init_1.addHooks)(models, getModel);
|
|
46
|
+
await (0, models_1.initTables)(sequelize, options.getUser);
|
|
47
|
+
(0, init_1.addScopes)(models, getModel);
|
|
48
|
+
(0, init_1.applyCustomAssociation)(models);
|
|
49
|
+
logger_1.default.debug('sadot - custom fields finished initializing with models', models);
|
|
50
|
+
return sequelize;
|
|
51
|
+
};
|
|
52
|
+
exports.default = useCustomFields;
|
|
53
|
+
const disableCustomFields = (models, getModel) => {
|
|
54
|
+
(0, init_1.removeHooks)(models, getModel);
|
|
55
|
+
};
|
|
56
|
+
exports.disableCustomFields = disableCustomFields;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Model } from 'sequelize-typescript';
|
|
2
|
+
import { CustomFieldDefinitionType } from '../utils/validations/type';
|
|
3
|
+
import { CustomFieldValue } from '.';
|
|
4
|
+
declare class CustomFieldDefinition extends Model {
|
|
5
|
+
id: string;
|
|
6
|
+
name: string;
|
|
7
|
+
displayName?: string;
|
|
8
|
+
fieldType: CustomFieldDefinitionType;
|
|
9
|
+
validation?: any;
|
|
10
|
+
entityId: string; /** Client association entity id */
|
|
11
|
+
entityType: string; /** Client association entity type (demand source / fleet / etc.) */
|
|
12
|
+
modelType: string; /** Model type. e.g. Vehicle / StopPoint / etc. */
|
|
13
|
+
description?: string;
|
|
14
|
+
required?: boolean;
|
|
15
|
+
disabled?: boolean;
|
|
16
|
+
createdAt?: Date;
|
|
17
|
+
updatedAt?: Date;
|
|
18
|
+
deletedAt?: Date;
|
|
19
|
+
values: CustomFieldValue[];
|
|
20
|
+
static displayNameDefaultValue(instance: CustomFieldDefinition): void;
|
|
21
|
+
static afterSaveHandler(instance: CustomFieldDefinition, options: any): void;
|
|
22
|
+
}
|
|
23
|
+
export default CustomFieldDefinition;
|
|
@@ -0,0 +1,165 @@
|
|
|
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
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
13
|
+
/* eslint-disable indent */
|
|
14
|
+
const sequelize_typescript_1 = require("sequelize-typescript");
|
|
15
|
+
const custom_1 = require("../utils/validations/custom");
|
|
16
|
+
const type_1 = require("../utils/validations/type");
|
|
17
|
+
const _1 = require(".");
|
|
18
|
+
const events_1 = require("../events");
|
|
19
|
+
const errors_1 = require("../errors");
|
|
20
|
+
let CustomFieldDefinition = class CustomFieldDefinition extends sequelize_typescript_1.Model {
|
|
21
|
+
static displayNameDefaultValue(instance) {
|
|
22
|
+
if (!instance?.displayName) {
|
|
23
|
+
// eslint-disable-next-line no-param-reassign
|
|
24
|
+
instance.displayName = instance.name;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
static afterSaveHandler(instance, options) {
|
|
28
|
+
if (options.transaction) {
|
|
29
|
+
options.transaction.afterCommit(() => (0, events_1.sendDimEvent)(instance));
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
(0, events_1.sendDimEvent)(instance);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
__decorate([
|
|
37
|
+
sequelize_typescript_1.PrimaryKey,
|
|
38
|
+
(0, sequelize_typescript_1.Column)({
|
|
39
|
+
type: sequelize_typescript_1.DataType.UUID,
|
|
40
|
+
defaultValue: sequelize_typescript_1.DataType.UUIDV4,
|
|
41
|
+
allowNull: false,
|
|
42
|
+
}),
|
|
43
|
+
__metadata("design:type", String)
|
|
44
|
+
], CustomFieldDefinition.prototype, "id", void 0);
|
|
45
|
+
__decorate([
|
|
46
|
+
(0, sequelize_typescript_1.Column)({
|
|
47
|
+
type: sequelize_typescript_1.DataType.STRING,
|
|
48
|
+
allowNull: false,
|
|
49
|
+
}),
|
|
50
|
+
__metadata("design:type", String)
|
|
51
|
+
], CustomFieldDefinition.prototype, "name", void 0);
|
|
52
|
+
__decorate([
|
|
53
|
+
(0, sequelize_typescript_1.Column)({
|
|
54
|
+
type: sequelize_typescript_1.DataType.STRING,
|
|
55
|
+
}),
|
|
56
|
+
__metadata("design:type", String)
|
|
57
|
+
], CustomFieldDefinition.prototype, "displayName", void 0);
|
|
58
|
+
__decorate([
|
|
59
|
+
(0, sequelize_typescript_1.Is)('SupportedType', (value) => {
|
|
60
|
+
if (!Object.values(type_1.CustomFieldDefinitionType).includes(value)) {
|
|
61
|
+
throw new errors_1.UnsupportedCustomFieldTypeError(`"${value}" is not a supported type.`);
|
|
62
|
+
}
|
|
63
|
+
}),
|
|
64
|
+
(0, sequelize_typescript_1.Column)({
|
|
65
|
+
type: sequelize_typescript_1.DataType.STRING,
|
|
66
|
+
allowNull: false,
|
|
67
|
+
}),
|
|
68
|
+
__metadata("design:type", String)
|
|
69
|
+
], CustomFieldDefinition.prototype, "fieldType", void 0);
|
|
70
|
+
__decorate([
|
|
71
|
+
(0, sequelize_typescript_1.Column)({
|
|
72
|
+
type: sequelize_typescript_1.DataType.JSONB,
|
|
73
|
+
}),
|
|
74
|
+
__metadata("design:type", Object)
|
|
75
|
+
], CustomFieldDefinition.prototype, "validation", void 0);
|
|
76
|
+
__decorate([
|
|
77
|
+
(0, sequelize_typescript_1.Column)({
|
|
78
|
+
type: sequelize_typescript_1.DataType.UUID,
|
|
79
|
+
allowNull: false,
|
|
80
|
+
}),
|
|
81
|
+
__metadata("design:type", String)
|
|
82
|
+
], CustomFieldDefinition.prototype, "entityId", void 0);
|
|
83
|
+
__decorate([
|
|
84
|
+
(0, sequelize_typescript_1.Column)({
|
|
85
|
+
type: sequelize_typescript_1.DataType.STRING,
|
|
86
|
+
allowNull: false,
|
|
87
|
+
}),
|
|
88
|
+
__metadata("design:type", String)
|
|
89
|
+
], CustomFieldDefinition.prototype, "entityType", void 0);
|
|
90
|
+
__decorate([
|
|
91
|
+
(0, sequelize_typescript_1.Column)({
|
|
92
|
+
type: sequelize_typescript_1.DataType.STRING,
|
|
93
|
+
allowNull: false,
|
|
94
|
+
}),
|
|
95
|
+
__metadata("design:type", String)
|
|
96
|
+
], CustomFieldDefinition.prototype, "modelType", void 0);
|
|
97
|
+
__decorate([
|
|
98
|
+
(0, sequelize_typescript_1.Column)({
|
|
99
|
+
type: sequelize_typescript_1.DataType.TEXT,
|
|
100
|
+
}),
|
|
101
|
+
__metadata("design:type", String)
|
|
102
|
+
], CustomFieldDefinition.prototype, "description", void 0);
|
|
103
|
+
__decorate([
|
|
104
|
+
(0, sequelize_typescript_1.Column)({
|
|
105
|
+
type: sequelize_typescript_1.DataType.BOOLEAN,
|
|
106
|
+
defaultValue: false,
|
|
107
|
+
}),
|
|
108
|
+
__metadata("design:type", Boolean)
|
|
109
|
+
], CustomFieldDefinition.prototype, "required", void 0);
|
|
110
|
+
__decorate([
|
|
111
|
+
(0, sequelize_typescript_1.Column)({
|
|
112
|
+
type: sequelize_typescript_1.DataType.BOOLEAN,
|
|
113
|
+
defaultValue: false,
|
|
114
|
+
}),
|
|
115
|
+
__metadata("design:type", Boolean)
|
|
116
|
+
], CustomFieldDefinition.prototype, "disabled", void 0);
|
|
117
|
+
__decorate([
|
|
118
|
+
sequelize_typescript_1.Column,
|
|
119
|
+
__metadata("design:type", Date)
|
|
120
|
+
], CustomFieldDefinition.prototype, "createdAt", void 0);
|
|
121
|
+
__decorate([
|
|
122
|
+
sequelize_typescript_1.Column,
|
|
123
|
+
__metadata("design:type", Date)
|
|
124
|
+
], CustomFieldDefinition.prototype, "updatedAt", void 0);
|
|
125
|
+
__decorate([
|
|
126
|
+
sequelize_typescript_1.Column,
|
|
127
|
+
__metadata("design:type", Date)
|
|
128
|
+
], CustomFieldDefinition.prototype, "deletedAt", void 0);
|
|
129
|
+
__decorate([
|
|
130
|
+
(0, sequelize_typescript_1.HasMany)(() => _1.CustomFieldValue),
|
|
131
|
+
__metadata("design:type", Array)
|
|
132
|
+
], CustomFieldDefinition.prototype, "values", void 0);
|
|
133
|
+
__decorate([
|
|
134
|
+
sequelize_typescript_1.BeforeCreate,
|
|
135
|
+
__metadata("design:type", Function),
|
|
136
|
+
__metadata("design:paramtypes", [CustomFieldDefinition]),
|
|
137
|
+
__metadata("design:returntype", void 0)
|
|
138
|
+
], CustomFieldDefinition, "displayNameDefaultValue", null);
|
|
139
|
+
__decorate([
|
|
140
|
+
sequelize_typescript_1.AfterSave,
|
|
141
|
+
__metadata("design:type", Function),
|
|
142
|
+
__metadata("design:paramtypes", [CustomFieldDefinition, Object]),
|
|
143
|
+
__metadata("design:returntype", void 0)
|
|
144
|
+
], CustomFieldDefinition, "afterSaveHandler", null);
|
|
145
|
+
CustomFieldDefinition = __decorate([
|
|
146
|
+
(0, sequelize_typescript_1.DefaultScope)(() => ({ where: { disabled: false } })),
|
|
147
|
+
(0, sequelize_typescript_1.Table)({
|
|
148
|
+
indexes: [
|
|
149
|
+
{
|
|
150
|
+
name: 'unique_name_model_type',
|
|
151
|
+
fields: ['model_type', 'entity_id', 'name'],
|
|
152
|
+
unique: true,
|
|
153
|
+
},
|
|
154
|
+
],
|
|
155
|
+
timestamps: true,
|
|
156
|
+
validate: {
|
|
157
|
+
validationByType() {
|
|
158
|
+
if (!(0, custom_1.validateValidation)(this.fieldType, this.validation)) {
|
|
159
|
+
throw new errors_1.UnsupportedCustomValidationError(`Validation provided for "${this.fieldType}" is not supported`);
|
|
160
|
+
}
|
|
161
|
+
},
|
|
162
|
+
},
|
|
163
|
+
})
|
|
164
|
+
], CustomFieldDefinition);
|
|
165
|
+
exports.default = CustomFieldDefinition;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Model } from 'sequelize-typescript';
|
|
2
|
+
import { CustomFieldDefinition } from '.';
|
|
3
|
+
declare class CustomFieldValue extends Model {
|
|
4
|
+
modelId: string;
|
|
5
|
+
customFieldDefinitionId: string;
|
|
6
|
+
value: any;
|
|
7
|
+
createdAt?: Date;
|
|
8
|
+
updatedAt?: Date;
|
|
9
|
+
deletedAt?: Date;
|
|
10
|
+
customFieldDefinition: CustomFieldDefinition;
|
|
11
|
+
static validateValues(instances: CustomFieldValue[]): Promise<void>;
|
|
12
|
+
static validateValue(instance: CustomFieldValue): Promise<void>;
|
|
13
|
+
static afterSaveHandler(instance: CustomFieldValue, options: any): void;
|
|
14
|
+
}
|
|
15
|
+
export default CustomFieldValue;
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
19
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
20
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
21
|
+
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;
|
|
22
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
23
|
+
};
|
|
24
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
25
|
+
if (mod && mod.__esModule) return mod;
|
|
26
|
+
var result = {};
|
|
27
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
28
|
+
__setModuleDefault(result, mod);
|
|
29
|
+
return result;
|
|
30
|
+
};
|
|
31
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
32
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
33
|
+
};
|
|
34
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
35
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
36
|
+
};
|
|
37
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
38
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
39
|
+
/* eslint-disable indent */
|
|
40
|
+
const sequelize_typescript_1 = require("sequelize-typescript");
|
|
41
|
+
const events_1 = require("../events");
|
|
42
|
+
const _1 = require(".");
|
|
43
|
+
const validations_1 = __importDefault(require("../utils/validations"));
|
|
44
|
+
const CustomFieldDefinitionRepo = __importStar(require("../repository/definition"));
|
|
45
|
+
const errors_1 = require("../errors");
|
|
46
|
+
let CustomFieldValue = class CustomFieldValue extends sequelize_typescript_1.Model {
|
|
47
|
+
static async validateValues(instances) {
|
|
48
|
+
const ids = instances.map((instance) => instance.customFieldDefinitionId);
|
|
49
|
+
const uniqueIds = [...new Set(ids)];
|
|
50
|
+
const definitions = await CustomFieldDefinitionRepo.findByIds(uniqueIds, { withDisabled: true });
|
|
51
|
+
if (!definitions || definitions.length !== uniqueIds.length) {
|
|
52
|
+
throw new Error('Definitions not found');
|
|
53
|
+
}
|
|
54
|
+
instances.forEach((instance) => {
|
|
55
|
+
const { validation, fieldType, } = definitions
|
|
56
|
+
.find((definition) => definition.id === instance.customFieldDefinitionId);
|
|
57
|
+
const isValid = (0, validations_1.default)(instance.value, fieldType, validation);
|
|
58
|
+
if (!isValid) {
|
|
59
|
+
throw new errors_1.InvalidValueError(instance.value, fieldType);
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
static async validateValue(instance) {
|
|
64
|
+
const { customFieldDefinitionId } = instance;
|
|
65
|
+
// eslint-disable-next-line max-len
|
|
66
|
+
const cfd = await CustomFieldDefinitionRepo.findById(customFieldDefinitionId, { withDisabled: true });
|
|
67
|
+
const { validation, fieldType } = cfd;
|
|
68
|
+
const isValid = (0, validations_1.default)(instance.value, fieldType, validation);
|
|
69
|
+
if (!isValid) {
|
|
70
|
+
throw new errors_1.InvalidValueError(instance.value, fieldType);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
static afterSaveHandler(instance, options) {
|
|
74
|
+
if (options.transaction) {
|
|
75
|
+
options.transaction.afterCommit(() => (0, events_1.sendDimEvent)(instance[0]));
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
(0, events_1.sendDimEvent)(instance[0]);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
__decorate([
|
|
83
|
+
sequelize_typescript_1.PrimaryKey,
|
|
84
|
+
(0, sequelize_typescript_1.Column)({
|
|
85
|
+
type: sequelize_typescript_1.DataType.UUID,
|
|
86
|
+
allowNull: false,
|
|
87
|
+
}),
|
|
88
|
+
__metadata("design:type", String)
|
|
89
|
+
], CustomFieldValue.prototype, "modelId", void 0);
|
|
90
|
+
__decorate([
|
|
91
|
+
sequelize_typescript_1.PrimaryKey,
|
|
92
|
+
(0, sequelize_typescript_1.ForeignKey)(() => _1.CustomFieldDefinition),
|
|
93
|
+
(0, sequelize_typescript_1.Column)({
|
|
94
|
+
type: sequelize_typescript_1.DataType.UUID,
|
|
95
|
+
allowNull: false,
|
|
96
|
+
}),
|
|
97
|
+
__metadata("design:type", String)
|
|
98
|
+
], CustomFieldValue.prototype, "customFieldDefinitionId", void 0);
|
|
99
|
+
__decorate([
|
|
100
|
+
(0, sequelize_typescript_1.Column)({
|
|
101
|
+
type: sequelize_typescript_1.DataType.JSONB,
|
|
102
|
+
allowNull: true,
|
|
103
|
+
}),
|
|
104
|
+
__metadata("design:type", Object)
|
|
105
|
+
], CustomFieldValue.prototype, "value", void 0);
|
|
106
|
+
__decorate([
|
|
107
|
+
sequelize_typescript_1.Column,
|
|
108
|
+
__metadata("design:type", Date)
|
|
109
|
+
], CustomFieldValue.prototype, "createdAt", void 0);
|
|
110
|
+
__decorate([
|
|
111
|
+
sequelize_typescript_1.Column,
|
|
112
|
+
__metadata("design:type", Date)
|
|
113
|
+
], CustomFieldValue.prototype, "updatedAt", void 0);
|
|
114
|
+
__decorate([
|
|
115
|
+
sequelize_typescript_1.Column,
|
|
116
|
+
__metadata("design:type", Date)
|
|
117
|
+
], CustomFieldValue.prototype, "deletedAt", void 0);
|
|
118
|
+
__decorate([
|
|
119
|
+
(0, sequelize_typescript_1.BelongsTo)(() => _1.CustomFieldDefinition, { scope: { disabled: false } }),
|
|
120
|
+
__metadata("design:type", _1.CustomFieldDefinition)
|
|
121
|
+
], CustomFieldValue.prototype, "customFieldDefinition", void 0);
|
|
122
|
+
__decorate([
|
|
123
|
+
sequelize_typescript_1.BeforeBulkCreate,
|
|
124
|
+
sequelize_typescript_1.BeforeBulkUpdate,
|
|
125
|
+
__metadata("design:type", Function),
|
|
126
|
+
__metadata("design:paramtypes", [Array]),
|
|
127
|
+
__metadata("design:returntype", Promise)
|
|
128
|
+
], CustomFieldValue, "validateValues", null);
|
|
129
|
+
__decorate([
|
|
130
|
+
sequelize_typescript_1.BeforeUpdate,
|
|
131
|
+
sequelize_typescript_1.BeforeCreate,
|
|
132
|
+
sequelize_typescript_1.BeforeUpsert,
|
|
133
|
+
__metadata("design:type", Function),
|
|
134
|
+
__metadata("design:paramtypes", [CustomFieldValue]),
|
|
135
|
+
__metadata("design:returntype", Promise)
|
|
136
|
+
], CustomFieldValue, "validateValue", null);
|
|
137
|
+
__decorate([
|
|
138
|
+
sequelize_typescript_1.AfterUpsert,
|
|
139
|
+
__metadata("design:type", Function),
|
|
140
|
+
__metadata("design:paramtypes", [CustomFieldValue, Object]),
|
|
141
|
+
__metadata("design:returntype", void 0)
|
|
142
|
+
], CustomFieldValue, "afterSaveHandler", null);
|
|
143
|
+
CustomFieldValue = __decorate([
|
|
144
|
+
(0, sequelize_typescript_1.Table)({
|
|
145
|
+
timestamps: true,
|
|
146
|
+
})
|
|
147
|
+
], CustomFieldValue);
|
|
148
|
+
exports.default = CustomFieldValue;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Sequelize } from 'sequelize-typescript';
|
|
2
|
+
import CustomFieldDefinition from './CustomFieldDefinition';
|
|
3
|
+
import CustomFieldValue from './CustomFieldValue';
|
|
4
|
+
import TestModel from './tests/TestModel';
|
|
5
|
+
import ContextAwareTestModel from './tests/contextAwareModels/ContextAwareTestModel';
|
|
6
|
+
import ContextTestModel from './tests/contextAwareModels/ContextTestModel';
|
|
7
|
+
import AssociatedTestModel from './tests/AssociatedTestModel';
|
|
8
|
+
declare const initTables: (sequelize: Sequelize, getUser: any) => Promise<void>;
|
|
9
|
+
declare const initTestModels: (sequelize: Sequelize) => Promise<void>;
|
|
10
|
+
export { CustomFieldValue, CustomFieldDefinition, TestModel, AssociatedTestModel, ContextAwareTestModel, ContextTestModel, initTables, initTestModels, };
|
|
@@ -0,0 +1,93 @@
|
|
|
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.initTestModels = exports.initTables = exports.ContextTestModel = exports.ContextAwareTestModel = exports.AssociatedTestModel = exports.TestModel = exports.CustomFieldDefinition = exports.CustomFieldValue = void 0;
|
|
7
|
+
/* eslint-disable no-param-reassign */
|
|
8
|
+
const sequelize_1 = require("sequelize");
|
|
9
|
+
const logger_1 = __importDefault(require("../utils/logger"));
|
|
10
|
+
const CustomFieldDefinition_1 = __importDefault(require("./CustomFieldDefinition"));
|
|
11
|
+
exports.CustomFieldDefinition = CustomFieldDefinition_1.default;
|
|
12
|
+
const CustomFieldValue_1 = __importDefault(require("./CustomFieldValue"));
|
|
13
|
+
exports.CustomFieldValue = CustomFieldValue_1.default;
|
|
14
|
+
const TestModel_1 = __importDefault(require("./tests/TestModel"));
|
|
15
|
+
exports.TestModel = TestModel_1.default;
|
|
16
|
+
const ContextAwareTestModel_1 = __importDefault(require("./tests/contextAwareModels/ContextAwareTestModel"));
|
|
17
|
+
exports.ContextAwareTestModel = ContextAwareTestModel_1.default;
|
|
18
|
+
const ContextTestModel_1 = __importDefault(require("./tests/contextAwareModels/ContextTestModel"));
|
|
19
|
+
exports.ContextTestModel = ContextTestModel_1.default;
|
|
20
|
+
const AssociatedTestModel_1 = __importDefault(require("./tests/AssociatedTestModel"));
|
|
21
|
+
exports.AssociatedTestModel = AssociatedTestModel_1.default;
|
|
22
|
+
const productionModels = [CustomFieldDefinition_1.default, CustomFieldValue_1.default];
|
|
23
|
+
const testModels = [TestModel_1.default, AssociatedTestModel_1.default, ContextAwareTestModel_1.default, ContextTestModel_1.default];
|
|
24
|
+
const SADOT_MIGRATION_PREFIX = 'sadot-migration';
|
|
25
|
+
const SCHEMA_VERSION = 1;
|
|
26
|
+
const CUSTOM_FIELDS_SCHEMA_VERSION = `${SADOT_MIGRATION_PREFIX}_${SCHEMA_VERSION}`;
|
|
27
|
+
const initTables = async (sequelize, getUser) => {
|
|
28
|
+
logger_1.default.info('custom-fields: initialize custom-fields tables');
|
|
29
|
+
// Detect models and import them to the orm
|
|
30
|
+
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
|
31
|
+
if (!sequelize.addModels) {
|
|
32
|
+
throw new Error('sequelize instance must have addModels function');
|
|
33
|
+
}
|
|
34
|
+
sequelize.addModels(productionModels);
|
|
35
|
+
CustomFieldDefinition_1.default.addScope('userScope', () => {
|
|
36
|
+
const user = getUser();
|
|
37
|
+
if (user?.permissions) {
|
|
38
|
+
return {
|
|
39
|
+
where: {
|
|
40
|
+
entityId: [
|
|
41
|
+
...Object.keys(user.permissions.fleets),
|
|
42
|
+
...Object.keys(user.permissions.businessModels),
|
|
43
|
+
...Object.keys(user.permissions.demandSources),
|
|
44
|
+
],
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
return {};
|
|
49
|
+
});
|
|
50
|
+
logger_1.default.info('custom-fields: models added');
|
|
51
|
+
const SequelizeMeta = sequelize.define('SequelizeMeta', {
|
|
52
|
+
name: {
|
|
53
|
+
type: sequelize_1.DataTypes.STRING,
|
|
54
|
+
allowNull: false,
|
|
55
|
+
unique: true,
|
|
56
|
+
primaryKey: true,
|
|
57
|
+
autoIncrement: false,
|
|
58
|
+
},
|
|
59
|
+
}, {
|
|
60
|
+
tableName: 'SequelizeMeta',
|
|
61
|
+
timestamps: false,
|
|
62
|
+
schema: 'public',
|
|
63
|
+
});
|
|
64
|
+
const migrations = await SequelizeMeta.findAll({ raw: true });
|
|
65
|
+
const currentSadotSchemaVersion = migrations
|
|
66
|
+
.reverse().find((m) => m.name.includes(SADOT_MIGRATION_PREFIX));
|
|
67
|
+
if (!currentSadotSchemaVersion
|
|
68
|
+
|| currentSadotSchemaVersion.name !== CUSTOM_FIELDS_SCHEMA_VERSION) {
|
|
69
|
+
await CustomFieldDefinition_1.default.sync({ alter: true });
|
|
70
|
+
await CustomFieldValue_1.default.sync({ alter: true });
|
|
71
|
+
await SequelizeMeta.create({ name: CUSTOM_FIELDS_SCHEMA_VERSION });
|
|
72
|
+
logger_1.default.info('custom-fields: models synced');
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
exports.initTables = initTables;
|
|
76
|
+
const initTestModels = async (sequelize) => {
|
|
77
|
+
logger_1.default.info('custom-fields: initialize custom-fields test models');
|
|
78
|
+
// Detect models and import them to the orm
|
|
79
|
+
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
|
|
80
|
+
if (!sequelize.addModels) {
|
|
81
|
+
throw new Error('sequelize instance must have addModels function');
|
|
82
|
+
}
|
|
83
|
+
sequelize.addModels(testModels);
|
|
84
|
+
await sequelize.dropSchema('custom-fields', { logging: false });
|
|
85
|
+
await sequelize.createSchema('custom-fields', { logging: false });
|
|
86
|
+
logger_1.default.info('custom-fields: test models added');
|
|
87
|
+
await TestModel_1.default.sync({ alter: true });
|
|
88
|
+
await AssociatedTestModel_1.default.sync({ alter: true });
|
|
89
|
+
await ContextTestModel_1.default.sync({ alter: true });
|
|
90
|
+
await ContextAwareTestModel_1.default.sync({ alter: true });
|
|
91
|
+
logger_1.default.info('custom-fields: test models synced');
|
|
92
|
+
};
|
|
93
|
+
exports.initTestModels = initTestModels;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Model } from 'sequelize-typescript';
|
|
2
|
+
import TestModel from './TestModel';
|
|
3
|
+
declare class AssociatedTestModel extends Model {
|
|
4
|
+
id: string;
|
|
5
|
+
testModelId: string;
|
|
6
|
+
fleetId: string;
|
|
7
|
+
businessModelId: string;
|
|
8
|
+
demandSourceId: string;
|
|
9
|
+
anotherAttribute?: boolean;
|
|
10
|
+
testModel: TestModel;
|
|
11
|
+
}
|
|
12
|
+
export default AssociatedTestModel;
|