@autofleet/sadot 1.6.18-beta.2 → 1.6.18-beta.21
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/_virtual/_@oxc-project_runtime@0.103.0/helpers/decorate.cjs +11 -0
- package/dist/_virtual/_@oxc-project_runtime@0.103.0/helpers/decorate.js +10 -0
- package/dist/_virtual/_@oxc-project_runtime@0.103.0/helpers/decorateMetadata.cjs +8 -0
- package/dist/_virtual/_@oxc-project_runtime@0.103.0/helpers/decorateMetadata.js +7 -0
- package/dist/_virtual/rolldown_runtime.cjs +43 -0
- package/dist/{chunk-DJulfCLt.js → _virtual/rolldown_runtime.js} +1 -2
- package/dist/api/index.cjs +12 -0
- package/dist/api/index.js +11 -0
- package/dist/api/v1/definition/index.cjs +113 -0
- package/dist/api/v1/definition/index.js +112 -0
- package/dist/api/v1/definition/validations.cjs +128 -0
- package/dist/api/v1/definition/validations.js +125 -0
- package/dist/api/v1/errors.cjs +14 -0
- package/dist/api/v1/errors.js +13 -0
- package/dist/api/v1/field-policies/index.cjs +104 -0
- package/dist/api/v1/field-policies/index.js +103 -0
- package/dist/api/v1/index.cjs +16 -0
- package/dist/api/v1/index.js +15 -0
- package/dist/api/v1/validator/index.cjs +132 -0
- package/dist/api/v1/validator/index.js +131 -0
- package/dist/api/v1/validator/validations.cjs +40 -0
- package/dist/api/v1/validator/validations.d.cts +22 -0
- package/dist/api/v1/validator/validations.d.ts +22 -0
- package/dist/api/v1/validator/validations.js +38 -0
- package/dist/errors/index.cjs +62 -0
- package/dist/errors/index.js +55 -0
- package/dist/events/index.cjs +52 -0
- package/dist/events/index.js +50 -0
- package/dist/hooks/enrich.cjs +175 -0
- package/dist/hooks/enrich.js +175 -0
- package/dist/hooks/find.cjs +22 -0
- package/dist/hooks/find.js +22 -0
- package/dist/hooks/hooks.cjs +310 -0
- package/dist/hooks/hooks.js +302 -0
- package/dist/hooks/index.cjs +3 -0
- package/dist/hooks/index.js +5 -0
- package/dist/hooks/utils/updateInstanceValues.cjs +27 -0
- package/dist/hooks/utils/updateInstanceValues.js +27 -0
- package/dist/index.cjs +48 -33508
- package/dist/index.d.cts +13 -396
- package/dist/index.d.ts +14 -394
- package/dist/index.js +21 -33435
- package/dist/init-state.cjs +56 -0
- package/dist/init-state.d.cts +35 -0
- package/dist/init-state.d.ts +35 -0
- package/dist/init-state.js +55 -0
- package/dist/mat-path-state.cjs +10 -0
- package/dist/mat-path-state.js +9 -0
- package/dist/migrations/001-create-core-tables.cjs +70 -0
- package/dist/migrations/001-create-core-tables.js +68 -0
- package/dist/migrations/002-create-custom-field-entries.cjs +27 -0
- package/dist/migrations/002-create-custom-field-entries.js +25 -0
- package/dist/migrations/003-create-custom-field-model-type-map.cjs +35 -0
- package/dist/migrations/003-create-custom-field-model-type-map.js +33 -0
- package/dist/migrations/004-create-field-policy-tables.cjs +29 -0
- package/dist/migrations/004-create-field-policy-tables.js +27 -0
- package/dist/migrations/005-add-entity-type-to-field-policies.cjs +20 -0
- package/dist/migrations/005-add-entity-type-to-field-policies.js +18 -0
- package/dist/migrations/index.cjs +94 -0
- package/dist/migrations/index.js +95 -0
- package/dist/models/CustomFieldDefinition.cjs +147 -0
- package/dist/models/CustomFieldDefinition.d.cts +40 -0
- package/dist/models/CustomFieldDefinition.d.ts +40 -0
- package/dist/models/CustomFieldDefinition.js +146 -0
- package/dist/models/CustomFieldEntries.cjs +71 -0
- package/dist/models/CustomFieldEntries.d.cts +15 -0
- package/dist/models/CustomFieldEntries.d.ts +15 -0
- package/dist/models/CustomFieldEntries.js +70 -0
- package/dist/models/CustomFieldModelTypeMap.cjs +62 -0
- package/dist/models/CustomFieldModelTypeMap.d.cts +14 -0
- package/dist/models/CustomFieldModelTypeMap.d.ts +14 -0
- package/dist/models/CustomFieldModelTypeMap.js +61 -0
- package/dist/models/CustomFieldValue.cjs +109 -0
- package/dist/models/CustomFieldValue.d.cts +20 -0
- package/dist/models/CustomFieldValue.d.ts +20 -0
- package/dist/models/CustomFieldValue.js +108 -0
- package/dist/models/CustomValidator.cjs +68 -0
- package/dist/models/CustomValidator.d.cts +18 -0
- package/dist/models/CustomValidator.d.ts +18 -0
- package/dist/models/CustomValidator.js +67 -0
- package/dist/models/FieldPolicy.cjs +54 -0
- package/dist/models/FieldPolicy.d.cts +25 -0
- package/dist/models/FieldPolicy.d.ts +25 -0
- package/dist/models/FieldPolicy.js +53 -0
- package/dist/models/index.cjs +163 -0
- package/dist/models/index.d.ts +11 -0
- package/dist/models/index.js +161 -0
- package/dist/models/tests/AssociatedTestModel.cjs +51 -0
- package/dist/models/tests/AssociatedTestModel.d.ts +2 -0
- package/dist/models/tests/AssociatedTestModel.js +50 -0
- package/dist/models/tests/TestModel.cjs +43 -0
- package/dist/models/tests/TestModel.d.ts +2 -0
- package/dist/models/tests/TestModel.js +42 -0
- package/dist/models/tests/contextAwareModels/ContextAwareTestModel.cjs +35 -0
- package/dist/models/tests/contextAwareModels/ContextAwareTestModel.d.ts +2 -0
- package/dist/models/tests/contextAwareModels/ContextAwareTestModel.js +34 -0
- package/dist/models/tests/contextAwareModels/ContextTestModel.cjs +33 -0
- package/dist/models/tests/contextAwareModels/ContextTestModel.d.ts +1 -0
- package/dist/models/tests/contextAwareModels/ContextTestModel.js +32 -0
- package/dist/repository/definition.cjs +221 -0
- package/dist/repository/definition.js +212 -0
- package/dist/repository/entries.cjs +69 -0
- package/dist/repository/entries.js +67 -0
- package/dist/repository/field-policy.cjs +69 -0
- package/dist/repository/field-policy.d.cts +35 -0
- package/dist/repository/field-policy.d.ts +35 -0
- package/dist/repository/field-policy.js +59 -0
- package/dist/repository/utils/formatValues.cjs +14 -0
- package/dist/repository/utils/formatValues.js +14 -0
- package/dist/repository/validator.cjs +85 -0
- package/dist/repository/validator.js +78 -0
- package/dist/repository/value.cjs +77 -0
- package/dist/repository/value.js +76 -0
- package/dist/scopes/filter.cjs +56 -0
- package/dist/scopes/filter.d.cts +22 -0
- package/dist/scopes/filter.d.ts +22 -0
- package/dist/scopes/filter.js +54 -0
- package/dist/scopes/helpers/filter.helpers.cjs +152 -0
- package/dist/scopes/helpers/filter.helpers.d.cts +16 -0
- package/dist/scopes/helpers/filter.helpers.d.ts +16 -0
- package/dist/scopes/helpers/filter.helpers.js +147 -0
- package/dist/scopes/index.cjs +1 -0
- package/dist/scopes/index.js +3 -0
- package/dist/types/index.d.cts +75 -0
- package/dist/types/index.d.ts +76 -0
- package/dist/utils/constants/index.cjs +32 -0
- package/dist/utils/constants/index.d.cts +23 -0
- package/dist/utils/constants/index.d.ts +23 -0
- package/dist/utils/constants/index.js +29 -0
- package/dist/utils/db/index.cjs +15 -0
- package/dist/utils/db/index.js +14 -0
- package/dist/utils/helpers/index.cjs +23 -0
- package/dist/utils/helpers/index.d.cts +30 -0
- package/dist/utils/helpers/index.d.ts +30 -0
- package/dist/utils/helpers/index.js +21 -0
- package/dist/utils/init.cjs +115 -0
- package/dist/utils/init.js +111 -0
- package/dist/utils/logger/index.cjs +15 -0
- package/dist/utils/logger/index.js +12 -0
- package/dist/utils/scopeAttributes.cjs +12 -0
- package/dist/utils/scopeAttributes.js +11 -0
- package/dist/utils/validations/index.cjs +34 -0
- package/dist/utils/validations/index.js +32 -0
- package/dist/utils/validations/schema/custom-fields.cjs +9 -0
- package/dist/utils/validations/schema/custom-fields.d.cts +6 -0
- package/dist/utils/validations/schema/custom-fields.d.ts +6 -0
- package/dist/utils/validations/schema/custom-fields.js +7 -0
- package/dist/utils/validations/schema/validator-schema.cjs +102 -0
- package/dist/utils/validations/schema/validator-schema.js +99 -0
- package/dist/utils/validations/validators/index.cjs +45 -0
- package/dist/utils/validations/validators/index.js +42 -0
- package/dist/utils/validations/validators/multi-select-dropdown.validator.cjs +7 -0
- package/dist/utils/validations/validators/multi-select-dropdown.validator.js +7 -0
- package/dist/utils/validations/validators/multi-select-status.validator.cjs +10 -0
- package/dist/utils/validations/validators/multi-select-status.validator.js +10 -0
- package/dist/utils/validations/validators/multi-select.helpers.cjs +12 -0
- package/dist/utils/validations/validators/multi-select.helpers.js +10 -0
- package/dist/utils/validations/validators/select.validator.cjs +12 -0
- package/dist/utils/validations/validators/select.validator.js +10 -0
- package/dist/utils/validations/validators/status.validator.cjs +12 -0
- package/dist/utils/validations/validators/status.validator.js +10 -0
- package/package.json +4 -4
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { BadRequest } from "@autofleet/errors";
|
|
2
|
+
|
|
3
|
+
//#region src/errors/index.ts
|
|
4
|
+
var MissingRequiredCustomFieldError = class extends BadRequest {
|
|
5
|
+
constructor(missingFields) {
|
|
6
|
+
const err = /* @__PURE__ */ new Error(`The following custom fields are required: ${missingFields.join(",")}`);
|
|
7
|
+
super([err], void 0, missingFields);
|
|
8
|
+
this.message = "MISSING_REQUIRED_CUSTOM_FIELDS";
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
var UnsupportedCustomFieldTypeError = class extends BadRequest {
|
|
12
|
+
constructor(fieldType) {
|
|
13
|
+
const err = /* @__PURE__ */ new Error(`Type "${fieldType}" is not supported`);
|
|
14
|
+
super([err], void 0, null);
|
|
15
|
+
this.message = "UNSUPPORTED_CUSTOM_FIELD_TYPE";
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
var UnsupportedCustomValidationError = class extends BadRequest {
|
|
19
|
+
constructor(fieldType) {
|
|
20
|
+
const err = /* @__PURE__ */ new Error(`Validation for "${fieldType}" is not supported`);
|
|
21
|
+
super([err], void 0, null);
|
|
22
|
+
this.message = "UNSUPPORTED_CUSTOM_VALIDATION_TYPE";
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
var InvalidFieldTypeError = class extends BadRequest {
|
|
26
|
+
constructor(fieldType) {
|
|
27
|
+
const err = /* @__PURE__ */ new Error(`Invalid field type ${fieldType}`);
|
|
28
|
+
super([err], void 0, null);
|
|
29
|
+
this.message = "INVALID_FIELD_TYPE";
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
var InvalidValueError = class extends BadRequest {
|
|
33
|
+
constructor(value, fieldDefinitionName, joiValidationError) {
|
|
34
|
+
const invalidValueMessage = `Invalid Value on field '${fieldDefinitionName}'. ${joiValidationError.message.replace(/"/g, "").replace("value", `'${fieldDefinitionName}'`)}. received: '${typeof value === "object" ? JSON.stringify(value) : value}'`;
|
|
35
|
+
super([new Error(invalidValueMessage)], void 0, null);
|
|
36
|
+
this.message = invalidValueMessage;
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
var InvalidEntriesError = class extends BadRequest {
|
|
40
|
+
constructor(modelId, validationErrors) {
|
|
41
|
+
const errors = validationErrors.map((validationError) => new InvalidValueError(validationError.value, validationError.fieldDefinitionName, validationError.joiValidationError));
|
|
42
|
+
super(errors, void 0, null);
|
|
43
|
+
this.message = `Invalid entries on ${modelId}\n${validationErrors.map((validationError) => `${validationError.fieldDefinitionName} - ${validationError.joiValidationError.message}`).join("\n")}`;
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
var MissingDefinitionError = class extends BadRequest {
|
|
47
|
+
constructor(fieldNames) {
|
|
48
|
+
const err = /* @__PURE__ */ new Error(`Missing custom field definition for field ${fieldNames.join(",")}`);
|
|
49
|
+
super([err], void 0, null);
|
|
50
|
+
this.message = "MISSING_DEFINITION";
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
//#endregion
|
|
55
|
+
export { InvalidEntriesError, InvalidFieldTypeError, InvalidValueError, MissingDefinitionError, MissingRequiredCustomFieldError, UnsupportedCustomFieldTypeError, UnsupportedCustomValidationError };
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
const require_rolldown_runtime = require('../_virtual/rolldown_runtime.cjs');
|
|
2
|
+
const require_index = require('../utils/logger/index.cjs');
|
|
3
|
+
let _autofleet_zehut = require("@autofleet/zehut");
|
|
4
|
+
let _autofleet_events = require("@autofleet/events");
|
|
5
|
+
_autofleet_events = require_rolldown_runtime.__toESM(_autofleet_events);
|
|
6
|
+
|
|
7
|
+
//#region src/events/index.ts
|
|
8
|
+
const events = new _autofleet_events.default({
|
|
9
|
+
logger: require_index.default,
|
|
10
|
+
getUserId: (payload) => payload?.user_id ?? (0, _autofleet_zehut.getUser)()?.id ?? null
|
|
11
|
+
});
|
|
12
|
+
const KEYS_TO_CONVERT = [
|
|
13
|
+
"value",
|
|
14
|
+
"defaultValue",
|
|
15
|
+
"blockEditingFromUI"
|
|
16
|
+
];
|
|
17
|
+
const stringifyBooleans = (savedObject, keysToConvert) => {
|
|
18
|
+
const savedObjectKeySet = new Set(Object.keys(savedObject));
|
|
19
|
+
if (keysToConvert.every((key) => !savedObjectKeySet.has(key))) return savedObject;
|
|
20
|
+
return {
|
|
21
|
+
...savedObject,
|
|
22
|
+
...Object.fromEntries(keysToConvert.map((key) => [key, typeof savedObject[key] === "boolean" ? savedObject[key].toString() : savedObject[key]]))
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
const modelTableMapping = {
|
|
26
|
+
CustomFieldDefinition: {
|
|
27
|
+
tableName: "dim_custom_field_definition",
|
|
28
|
+
eventVersion: "1"
|
|
29
|
+
},
|
|
30
|
+
CustomFieldValue: {
|
|
31
|
+
tableName: "dim_custom_field_value",
|
|
32
|
+
eventVersion: "1"
|
|
33
|
+
},
|
|
34
|
+
CustomFieldEntries: {
|
|
35
|
+
tableName: "dim_custom_field_entries",
|
|
36
|
+
eventVersion: "1"
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
const sendDimEvent = (instance) => {
|
|
40
|
+
const mapping = modelTableMapping[instance.constructor.name];
|
|
41
|
+
if (!mapping) return;
|
|
42
|
+
let objectToSend = instance.get();
|
|
43
|
+
try {
|
|
44
|
+
objectToSend = stringifyBooleans(instance.get(), KEYS_TO_CONVERT);
|
|
45
|
+
} catch (err) {
|
|
46
|
+
require_index.default.error("Failed to convert booleans in dim event payload", err);
|
|
47
|
+
}
|
|
48
|
+
events.sendObject(mapping.tableName, mapping.eventVersion, objectToSend).catch(() => null);
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
//#endregion
|
|
52
|
+
exports.sendDimEvent = sendDimEvent;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import logger_default from "../utils/logger/index.js";
|
|
2
|
+
import { getUser } from "@autofleet/zehut";
|
|
3
|
+
import Events from "@autofleet/events";
|
|
4
|
+
|
|
5
|
+
//#region src/events/index.ts
|
|
6
|
+
const events = new Events({
|
|
7
|
+
logger: logger_default,
|
|
8
|
+
getUserId: (payload) => payload?.user_id ?? getUser()?.id ?? null
|
|
9
|
+
});
|
|
10
|
+
const KEYS_TO_CONVERT = [
|
|
11
|
+
"value",
|
|
12
|
+
"defaultValue",
|
|
13
|
+
"blockEditingFromUI"
|
|
14
|
+
];
|
|
15
|
+
const stringifyBooleans = (savedObject, keysToConvert) => {
|
|
16
|
+
const savedObjectKeySet = new Set(Object.keys(savedObject));
|
|
17
|
+
if (keysToConvert.every((key) => !savedObjectKeySet.has(key))) return savedObject;
|
|
18
|
+
return {
|
|
19
|
+
...savedObject,
|
|
20
|
+
...Object.fromEntries(keysToConvert.map((key) => [key, typeof savedObject[key] === "boolean" ? savedObject[key].toString() : savedObject[key]]))
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
const modelTableMapping = {
|
|
24
|
+
CustomFieldDefinition: {
|
|
25
|
+
tableName: "dim_custom_field_definition",
|
|
26
|
+
eventVersion: "1"
|
|
27
|
+
},
|
|
28
|
+
CustomFieldValue: {
|
|
29
|
+
tableName: "dim_custom_field_value",
|
|
30
|
+
eventVersion: "1"
|
|
31
|
+
},
|
|
32
|
+
CustomFieldEntries: {
|
|
33
|
+
tableName: "dim_custom_field_entries",
|
|
34
|
+
eventVersion: "1"
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
const sendDimEvent = (instance) => {
|
|
38
|
+
const mapping = modelTableMapping[instance.constructor.name];
|
|
39
|
+
if (!mapping) return;
|
|
40
|
+
let objectToSend = instance.get();
|
|
41
|
+
try {
|
|
42
|
+
objectToSend = stringifyBooleans(instance.get(), KEYS_TO_CONVERT);
|
|
43
|
+
} catch (err) {
|
|
44
|
+
logger_default.error("Failed to convert booleans in dim event payload", err);
|
|
45
|
+
}
|
|
46
|
+
events.sendObject(mapping.tableName, mapping.eventVersion, objectToSend).catch(() => null);
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
//#endregion
|
|
50
|
+
export { sendDimEvent };
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
const require_definition = require('../repository/definition.cjs');
|
|
2
|
+
const require_value = require('../repository/value.cjs');
|
|
3
|
+
const require_entries = require('../repository/entries.cjs');
|
|
4
|
+
const require_scopeAttributes = require('../utils/scopeAttributes.cjs');
|
|
5
|
+
|
|
6
|
+
//#region src/hooks/enrich.ts
|
|
7
|
+
const CUSTOM_FIELD_DEFINITION_ATTRIBUTES_TO_PULL = [
|
|
8
|
+
"id",
|
|
9
|
+
"name",
|
|
10
|
+
"entityId",
|
|
11
|
+
"fieldType",
|
|
12
|
+
"displayName",
|
|
13
|
+
"validation",
|
|
14
|
+
"entityType",
|
|
15
|
+
"modelType",
|
|
16
|
+
"required",
|
|
17
|
+
"disabled",
|
|
18
|
+
"defaultValue"
|
|
19
|
+
];
|
|
20
|
+
const getCustomFieldEntriesByInstanceId = async ({ instancesIds, options, sadotOptions }) => {
|
|
21
|
+
if (!sadotOptions.useCustomFieldsEntries) return {};
|
|
22
|
+
const customFieldEntries = await require_entries.findEntriesByModelIds(instancesIds, options ?? {});
|
|
23
|
+
const customFieldEntriesByInstanceId = Object.fromEntries(customFieldEntries.map((instanceEntries) => {
|
|
24
|
+
const { modelId, customFields } = instanceEntries?.dataValues ?? {};
|
|
25
|
+
if (!modelId) return;
|
|
26
|
+
return [modelId, customFields];
|
|
27
|
+
}).filter((v) => v !== void 0));
|
|
28
|
+
instancesIds.forEach((instanceId) => {
|
|
29
|
+
customFieldEntriesByInstanceId[instanceId] ??= {};
|
|
30
|
+
});
|
|
31
|
+
return customFieldEntriesByInstanceId;
|
|
32
|
+
};
|
|
33
|
+
const getValuesGroupByInstance = async ({ instancesIds, options, sadotOptions }) => {
|
|
34
|
+
if (sadotOptions.useCustomFieldsEntries) return {};
|
|
35
|
+
return (await require_value.findValuesByModelIds(instancesIds, options ?? {})).reduce((acc, v) => {
|
|
36
|
+
const { modelId } = v;
|
|
37
|
+
acc[modelId] ??= [];
|
|
38
|
+
acc[modelId].push(v);
|
|
39
|
+
return acc;
|
|
40
|
+
}, {});
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* Serialize custom fields value into the format of {[name] -> [fieldData]}
|
|
44
|
+
*/
|
|
45
|
+
const serializeCustomFields = (customFieldValues, customFieldDefinitionsHash) => {
|
|
46
|
+
return customFieldValues.reduce((acc, cfv) => ({
|
|
47
|
+
...acc,
|
|
48
|
+
...customFieldDefinitionsHash[cfv.customFieldDefinitionId] && { [customFieldDefinitionsHash[cfv.customFieldDefinitionId].name]: cfv.value }
|
|
49
|
+
}), {});
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* A hook to attach the custom fields when fetching a model instances.
|
|
53
|
+
*/
|
|
54
|
+
const enrichResults = (modelType, scopeAttributes, hookType, modelOptions = {}, sadotOptions = {
|
|
55
|
+
useCustomFieldsEntries: false,
|
|
56
|
+
hasTypeId: false
|
|
57
|
+
}) => async (instancesOrInstance, options) => {
|
|
58
|
+
if (options.originalAttributes?.length > 0 && !options.originalAttributes?.includes?.("customFields")) return;
|
|
59
|
+
const primaryKey = "id";
|
|
60
|
+
let instances = Array.isArray(instancesOrInstance) ? instancesOrInstance : [instancesOrInstance];
|
|
61
|
+
instances = instances.filter(Boolean);
|
|
62
|
+
const identifiers = require_scopeAttributes.default(instances, scopeAttributes);
|
|
63
|
+
const uniqueIdentifiers = [...new Set(identifiers)].filter(Boolean);
|
|
64
|
+
const identifierCustomFieldDefinitionsMapping = uniqueIdentifiers.reduce((map, identifier) => ({
|
|
65
|
+
...map,
|
|
66
|
+
[identifier]: []
|
|
67
|
+
}), {});
|
|
68
|
+
let customFieldDefinitionsPromise;
|
|
69
|
+
let cacheKey;
|
|
70
|
+
if (options.transaction) {
|
|
71
|
+
options.transaction.definitionCache ??= /* @__PURE__ */ new Map();
|
|
72
|
+
cacheKey = `${modelType}:${uniqueIdentifiers.slice().sort().join(",")}`;
|
|
73
|
+
customFieldDefinitionsPromise = options.transaction.definitionCache.get(cacheKey);
|
|
74
|
+
}
|
|
75
|
+
let modelTypeDefinitionsMap;
|
|
76
|
+
if (!customFieldDefinitionsPromise) {
|
|
77
|
+
const shouldApplyTypeFiltering = sadotOptions.hasTypeId && instances.length > 0 && instances[0].typeId;
|
|
78
|
+
const fetchDefinitions = async (transaction = options.transaction) => {
|
|
79
|
+
if (shouldApplyTypeFiltering) {
|
|
80
|
+
const uniqueTypeIds = [...new Set(instances.map((instance) => instance.typeId).filter(Boolean))];
|
|
81
|
+
modelTypeDefinitionsMap = /* @__PURE__ */ new Map();
|
|
82
|
+
uniqueTypeIds.forEach((typeId) => modelTypeDefinitionsMap.set(typeId, /* @__PURE__ */ new Set()));
|
|
83
|
+
const allDefinitions = (await Promise.all(uniqueTypeIds.map(async (typeId) => {
|
|
84
|
+
const defs = await require_definition.findByModelTypeId(typeId, {
|
|
85
|
+
withDisabled: false,
|
|
86
|
+
entityIds: uniqueIdentifiers,
|
|
87
|
+
modelType,
|
|
88
|
+
modelOptions,
|
|
89
|
+
transaction
|
|
90
|
+
});
|
|
91
|
+
defs.forEach((def) => modelTypeDefinitionsMap.get(typeId).add(def.id));
|
|
92
|
+
return defs;
|
|
93
|
+
}))).flat();
|
|
94
|
+
const uniqueDefinitionsMap = /* @__PURE__ */ new Map();
|
|
95
|
+
allDefinitions.forEach((def) => {
|
|
96
|
+
uniqueDefinitionsMap.set(def.id, def);
|
|
97
|
+
});
|
|
98
|
+
return Array.from(uniqueDefinitionsMap.values());
|
|
99
|
+
}
|
|
100
|
+
return require_definition.findByEntityIds(modelType, uniqueIdentifiers, {
|
|
101
|
+
transaction,
|
|
102
|
+
modelOptions,
|
|
103
|
+
attributes: CUSTOM_FIELD_DEFINITION_ATTRIBUTES_TO_PULL
|
|
104
|
+
});
|
|
105
|
+
};
|
|
106
|
+
customFieldDefinitionsPromise = fetchDefinitions();
|
|
107
|
+
if (!shouldApplyTypeFiltering) options.transaction?.definitionCache?.set(cacheKey, customFieldDefinitionsPromise);
|
|
108
|
+
}
|
|
109
|
+
const customFieldDefinitions = await customFieldDefinitionsPromise;
|
|
110
|
+
if (customFieldDefinitions.length === 0) {
|
|
111
|
+
instances.forEach((instance) => {
|
|
112
|
+
instance.customFields = {};
|
|
113
|
+
});
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
if (modelOptions?.include && modelOptions.useEntityIdFromInclude) modelOptions.include(identifiers).forEach(({ model }) => {
|
|
117
|
+
customFieldDefinitions.forEach((cfd) => {
|
|
118
|
+
const entityId = cfd[model.name]?.entityId || cfd[`${model.name}.entityId`];
|
|
119
|
+
if (entityId && !identifierCustomFieldDefinitionsMapping[entityId]) identifierCustomFieldDefinitionsMapping[entityId] = [];
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
const definitionsMap = customFieldDefinitions.reduce((map, definition) => ({
|
|
123
|
+
...map,
|
|
124
|
+
[definition.id]: definition
|
|
125
|
+
}), {});
|
|
126
|
+
customFieldDefinitions.forEach((cfd) => {
|
|
127
|
+
let entityIdToUse = cfd.entityId;
|
|
128
|
+
if (modelOptions?.useEntityIdFromInclude && modelOptions.include) {
|
|
129
|
+
const contextIncludes = modelOptions.include(identifiers);
|
|
130
|
+
for (const { model } of contextIncludes) {
|
|
131
|
+
const joinedEntityId = cfd[model.name]?.entityId || cfd[`${model.name}.entityId`];
|
|
132
|
+
if (joinedEntityId) {
|
|
133
|
+
entityIdToUse = joinedEntityId;
|
|
134
|
+
break;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
if (identifierCustomFieldDefinitionsMapping[entityIdToUse]) identifierCustomFieldDefinitionsMapping[entityIdToUse].push(cfd);
|
|
139
|
+
});
|
|
140
|
+
const instancesIds = instances.map((i) => i[primaryKey]);
|
|
141
|
+
const [valuesGroupByInstance, customFieldEntriesByInstanceId] = await Promise.all([getValuesGroupByInstance({
|
|
142
|
+
instancesIds,
|
|
143
|
+
options,
|
|
144
|
+
sadotOptions
|
|
145
|
+
}), getCustomFieldEntriesByInstanceId({
|
|
146
|
+
instancesIds,
|
|
147
|
+
options,
|
|
148
|
+
sadotOptions
|
|
149
|
+
})]);
|
|
150
|
+
instances.forEach((instance) => {
|
|
151
|
+
const { id } = instance;
|
|
152
|
+
const instanceValues = valuesGroupByInstance[id];
|
|
153
|
+
const serializedCustomFieldsValues = instanceValues ? serializeCustomFields(instanceValues, definitionsMap) : {};
|
|
154
|
+
const customFields = sadotOptions.useCustomFieldsEntries ? customFieldEntriesByInstanceId[id] : serializedCustomFieldsValues;
|
|
155
|
+
scopeAttributes.forEach((attribute) => {
|
|
156
|
+
const entityCustomFieldDefinitions = identifierCustomFieldDefinitionsMapping[instance[attribute]];
|
|
157
|
+
if (entityCustomFieldDefinitions && entityCustomFieldDefinitions.length > 0) entityCustomFieldDefinitions.forEach((customFieldDefinition) => {
|
|
158
|
+
if (modelTypeDefinitionsMap) {
|
|
159
|
+
if (!modelTypeDefinitionsMap.get(instance.typeId)?.has(customFieldDefinition.id)) return;
|
|
160
|
+
}
|
|
161
|
+
if (customFields[customFieldDefinition.name] === void 0) customFields[customFieldDefinition.name] = null;
|
|
162
|
+
});
|
|
163
|
+
});
|
|
164
|
+
instance.customFields = customFields;
|
|
165
|
+
options.attributesToRemove?.forEach?.((attribute) => {
|
|
166
|
+
delete instance.dataValues?.[attribute];
|
|
167
|
+
delete instance?.[attribute];
|
|
168
|
+
});
|
|
169
|
+
if (hookType === "afterFind") instance?.changed?.("customFields", false);
|
|
170
|
+
});
|
|
171
|
+
};
|
|
172
|
+
var enrich_default = enrichResults;
|
|
173
|
+
|
|
174
|
+
//#endregion
|
|
175
|
+
exports.default = enrich_default;
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import { findByEntityIds, findByModelTypeId } from "../repository/definition.js";
|
|
2
|
+
import { findValuesByModelIds } from "../repository/value.js";
|
|
3
|
+
import { findEntriesByModelIds } from "../repository/entries.js";
|
|
4
|
+
import scopeAttributes_default from "../utils/scopeAttributes.js";
|
|
5
|
+
|
|
6
|
+
//#region src/hooks/enrich.ts
|
|
7
|
+
const CUSTOM_FIELD_DEFINITION_ATTRIBUTES_TO_PULL = [
|
|
8
|
+
"id",
|
|
9
|
+
"name",
|
|
10
|
+
"entityId",
|
|
11
|
+
"fieldType",
|
|
12
|
+
"displayName",
|
|
13
|
+
"validation",
|
|
14
|
+
"entityType",
|
|
15
|
+
"modelType",
|
|
16
|
+
"required",
|
|
17
|
+
"disabled",
|
|
18
|
+
"defaultValue"
|
|
19
|
+
];
|
|
20
|
+
const getCustomFieldEntriesByInstanceId = async ({ instancesIds, options, sadotOptions }) => {
|
|
21
|
+
if (!sadotOptions.useCustomFieldsEntries) return {};
|
|
22
|
+
const customFieldEntries = await findEntriesByModelIds(instancesIds, options ?? {});
|
|
23
|
+
const customFieldEntriesByInstanceId = Object.fromEntries(customFieldEntries.map((instanceEntries) => {
|
|
24
|
+
const { modelId, customFields } = instanceEntries?.dataValues ?? {};
|
|
25
|
+
if (!modelId) return;
|
|
26
|
+
return [modelId, customFields];
|
|
27
|
+
}).filter((v) => v !== void 0));
|
|
28
|
+
instancesIds.forEach((instanceId) => {
|
|
29
|
+
customFieldEntriesByInstanceId[instanceId] ??= {};
|
|
30
|
+
});
|
|
31
|
+
return customFieldEntriesByInstanceId;
|
|
32
|
+
};
|
|
33
|
+
const getValuesGroupByInstance = async ({ instancesIds, options, sadotOptions }) => {
|
|
34
|
+
if (sadotOptions.useCustomFieldsEntries) return {};
|
|
35
|
+
return (await findValuesByModelIds(instancesIds, options ?? {})).reduce((acc, v) => {
|
|
36
|
+
const { modelId } = v;
|
|
37
|
+
acc[modelId] ??= [];
|
|
38
|
+
acc[modelId].push(v);
|
|
39
|
+
return acc;
|
|
40
|
+
}, {});
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* Serialize custom fields value into the format of {[name] -> [fieldData]}
|
|
44
|
+
*/
|
|
45
|
+
const serializeCustomFields = (customFieldValues, customFieldDefinitionsHash) => {
|
|
46
|
+
return customFieldValues.reduce((acc, cfv) => ({
|
|
47
|
+
...acc,
|
|
48
|
+
...customFieldDefinitionsHash[cfv.customFieldDefinitionId] && { [customFieldDefinitionsHash[cfv.customFieldDefinitionId].name]: cfv.value }
|
|
49
|
+
}), {});
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* A hook to attach the custom fields when fetching a model instances.
|
|
53
|
+
*/
|
|
54
|
+
const enrichResults = (modelType, scopeAttributes, hookType, modelOptions = {}, sadotOptions = {
|
|
55
|
+
useCustomFieldsEntries: false,
|
|
56
|
+
hasTypeId: false
|
|
57
|
+
}) => async (instancesOrInstance, options) => {
|
|
58
|
+
if (options.originalAttributes?.length > 0 && !options.originalAttributes?.includes?.("customFields")) return;
|
|
59
|
+
const primaryKey = "id";
|
|
60
|
+
let instances = Array.isArray(instancesOrInstance) ? instancesOrInstance : [instancesOrInstance];
|
|
61
|
+
instances = instances.filter(Boolean);
|
|
62
|
+
const identifiers = scopeAttributes_default(instances, scopeAttributes);
|
|
63
|
+
const uniqueIdentifiers = [...new Set(identifiers)].filter(Boolean);
|
|
64
|
+
const identifierCustomFieldDefinitionsMapping = uniqueIdentifiers.reduce((map, identifier) => ({
|
|
65
|
+
...map,
|
|
66
|
+
[identifier]: []
|
|
67
|
+
}), {});
|
|
68
|
+
let customFieldDefinitionsPromise;
|
|
69
|
+
let cacheKey;
|
|
70
|
+
if (options.transaction) {
|
|
71
|
+
options.transaction.definitionCache ??= /* @__PURE__ */ new Map();
|
|
72
|
+
cacheKey = `${modelType}:${uniqueIdentifiers.slice().sort().join(",")}`;
|
|
73
|
+
customFieldDefinitionsPromise = options.transaction.definitionCache.get(cacheKey);
|
|
74
|
+
}
|
|
75
|
+
let modelTypeDefinitionsMap;
|
|
76
|
+
if (!customFieldDefinitionsPromise) {
|
|
77
|
+
const shouldApplyTypeFiltering = sadotOptions.hasTypeId && instances.length > 0 && instances[0].typeId;
|
|
78
|
+
const fetchDefinitions = async (transaction = options.transaction) => {
|
|
79
|
+
if (shouldApplyTypeFiltering) {
|
|
80
|
+
const uniqueTypeIds = [...new Set(instances.map((instance) => instance.typeId).filter(Boolean))];
|
|
81
|
+
modelTypeDefinitionsMap = /* @__PURE__ */ new Map();
|
|
82
|
+
uniqueTypeIds.forEach((typeId) => modelTypeDefinitionsMap.set(typeId, /* @__PURE__ */ new Set()));
|
|
83
|
+
const allDefinitions = (await Promise.all(uniqueTypeIds.map(async (typeId) => {
|
|
84
|
+
const defs = await findByModelTypeId(typeId, {
|
|
85
|
+
withDisabled: false,
|
|
86
|
+
entityIds: uniqueIdentifiers,
|
|
87
|
+
modelType,
|
|
88
|
+
modelOptions,
|
|
89
|
+
transaction
|
|
90
|
+
});
|
|
91
|
+
defs.forEach((def) => modelTypeDefinitionsMap.get(typeId).add(def.id));
|
|
92
|
+
return defs;
|
|
93
|
+
}))).flat();
|
|
94
|
+
const uniqueDefinitionsMap = /* @__PURE__ */ new Map();
|
|
95
|
+
allDefinitions.forEach((def) => {
|
|
96
|
+
uniqueDefinitionsMap.set(def.id, def);
|
|
97
|
+
});
|
|
98
|
+
return Array.from(uniqueDefinitionsMap.values());
|
|
99
|
+
}
|
|
100
|
+
return findByEntityIds(modelType, uniqueIdentifiers, {
|
|
101
|
+
transaction,
|
|
102
|
+
modelOptions,
|
|
103
|
+
attributes: CUSTOM_FIELD_DEFINITION_ATTRIBUTES_TO_PULL
|
|
104
|
+
});
|
|
105
|
+
};
|
|
106
|
+
customFieldDefinitionsPromise = fetchDefinitions();
|
|
107
|
+
if (!shouldApplyTypeFiltering) options.transaction?.definitionCache?.set(cacheKey, customFieldDefinitionsPromise);
|
|
108
|
+
}
|
|
109
|
+
const customFieldDefinitions = await customFieldDefinitionsPromise;
|
|
110
|
+
if (customFieldDefinitions.length === 0) {
|
|
111
|
+
instances.forEach((instance) => {
|
|
112
|
+
instance.customFields = {};
|
|
113
|
+
});
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
if (modelOptions?.include && modelOptions.useEntityIdFromInclude) modelOptions.include(identifiers).forEach(({ model }) => {
|
|
117
|
+
customFieldDefinitions.forEach((cfd) => {
|
|
118
|
+
const entityId = cfd[model.name]?.entityId || cfd[`${model.name}.entityId`];
|
|
119
|
+
if (entityId && !identifierCustomFieldDefinitionsMapping[entityId]) identifierCustomFieldDefinitionsMapping[entityId] = [];
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
const definitionsMap = customFieldDefinitions.reduce((map, definition) => ({
|
|
123
|
+
...map,
|
|
124
|
+
[definition.id]: definition
|
|
125
|
+
}), {});
|
|
126
|
+
customFieldDefinitions.forEach((cfd) => {
|
|
127
|
+
let entityIdToUse = cfd.entityId;
|
|
128
|
+
if (modelOptions?.useEntityIdFromInclude && modelOptions.include) {
|
|
129
|
+
const contextIncludes = modelOptions.include(identifiers);
|
|
130
|
+
for (const { model } of contextIncludes) {
|
|
131
|
+
const joinedEntityId = cfd[model.name]?.entityId || cfd[`${model.name}.entityId`];
|
|
132
|
+
if (joinedEntityId) {
|
|
133
|
+
entityIdToUse = joinedEntityId;
|
|
134
|
+
break;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
if (identifierCustomFieldDefinitionsMapping[entityIdToUse]) identifierCustomFieldDefinitionsMapping[entityIdToUse].push(cfd);
|
|
139
|
+
});
|
|
140
|
+
const instancesIds = instances.map((i) => i[primaryKey]);
|
|
141
|
+
const [valuesGroupByInstance, customFieldEntriesByInstanceId] = await Promise.all([getValuesGroupByInstance({
|
|
142
|
+
instancesIds,
|
|
143
|
+
options,
|
|
144
|
+
sadotOptions
|
|
145
|
+
}), getCustomFieldEntriesByInstanceId({
|
|
146
|
+
instancesIds,
|
|
147
|
+
options,
|
|
148
|
+
sadotOptions
|
|
149
|
+
})]);
|
|
150
|
+
instances.forEach((instance) => {
|
|
151
|
+
const { id } = instance;
|
|
152
|
+
const instanceValues = valuesGroupByInstance[id];
|
|
153
|
+
const serializedCustomFieldsValues = instanceValues ? serializeCustomFields(instanceValues, definitionsMap) : {};
|
|
154
|
+
const customFields = sadotOptions.useCustomFieldsEntries ? customFieldEntriesByInstanceId[id] : serializedCustomFieldsValues;
|
|
155
|
+
scopeAttributes.forEach((attribute) => {
|
|
156
|
+
const entityCustomFieldDefinitions = identifierCustomFieldDefinitionsMapping[instance[attribute]];
|
|
157
|
+
if (entityCustomFieldDefinitions && entityCustomFieldDefinitions.length > 0) entityCustomFieldDefinitions.forEach((customFieldDefinition) => {
|
|
158
|
+
if (modelTypeDefinitionsMap) {
|
|
159
|
+
if (!modelTypeDefinitionsMap.get(instance.typeId)?.has(customFieldDefinition.id)) return;
|
|
160
|
+
}
|
|
161
|
+
if (customFields[customFieldDefinition.name] === void 0) customFields[customFieldDefinition.name] = null;
|
|
162
|
+
});
|
|
163
|
+
});
|
|
164
|
+
instance.customFields = customFields;
|
|
165
|
+
options.attributesToRemove?.forEach?.((attribute) => {
|
|
166
|
+
delete instance.dataValues?.[attribute];
|
|
167
|
+
delete instance?.[attribute];
|
|
168
|
+
});
|
|
169
|
+
if (hookType === "afterFind") instance?.changed?.("customFields", false);
|
|
170
|
+
});
|
|
171
|
+
};
|
|
172
|
+
var enrich_default = enrichResults;
|
|
173
|
+
|
|
174
|
+
//#endregion
|
|
175
|
+
export { enrich_default as default };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
const require_index = require('../utils/logger/index.cjs');
|
|
2
|
+
|
|
3
|
+
//#region src/hooks/find.ts
|
|
4
|
+
const doScopeAttributesMissing = (scopeAttributes, queryAttributes) => {
|
|
5
|
+
const attributes = scopeAttributes.filter((attribute) => !queryAttributes.includes(attribute));
|
|
6
|
+
if (!queryAttributes.includes?.("id")) attributes.push("id");
|
|
7
|
+
return attributes;
|
|
8
|
+
};
|
|
9
|
+
const beforeFind = (scopeAttributes) => (options) => {
|
|
10
|
+
const { attributes: queryAttributes } = options;
|
|
11
|
+
if (queryAttributes?.includes?.("customFields")) {
|
|
12
|
+
const missingScopeAttributes = doScopeAttributesMissing(scopeAttributes, queryAttributes);
|
|
13
|
+
require_index.default.debug("sadot - before find hook");
|
|
14
|
+
if (missingScopeAttributes?.length > 0) {
|
|
15
|
+
queryAttributes.push(...missingScopeAttributes);
|
|
16
|
+
options.attributesToRemove = missingScopeAttributes;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
//#endregion
|
|
22
|
+
exports.beforeFind = beforeFind;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import logger_default from "../utils/logger/index.js";
|
|
2
|
+
|
|
3
|
+
//#region src/hooks/find.ts
|
|
4
|
+
const doScopeAttributesMissing = (scopeAttributes, queryAttributes) => {
|
|
5
|
+
const attributes = scopeAttributes.filter((attribute) => !queryAttributes.includes(attribute));
|
|
6
|
+
if (!queryAttributes.includes?.("id")) attributes.push("id");
|
|
7
|
+
return attributes;
|
|
8
|
+
};
|
|
9
|
+
const beforeFind = (scopeAttributes) => (options) => {
|
|
10
|
+
const { attributes: queryAttributes } = options;
|
|
11
|
+
if (queryAttributes?.includes?.("customFields")) {
|
|
12
|
+
const missingScopeAttributes = doScopeAttributesMissing(scopeAttributes, queryAttributes);
|
|
13
|
+
logger_default.debug("sadot - before find hook");
|
|
14
|
+
if (missingScopeAttributes?.length > 0) {
|
|
15
|
+
queryAttributes.push(...missingScopeAttributes);
|
|
16
|
+
options.attributesToRemove = missingScopeAttributes;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
//#endregion
|
|
22
|
+
export { beforeFind };
|