adminizer 4.1.0-commit.ad1476a → 4.1.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/Readme.md +46 -0
- package/assets/{VanillaJSONEditor-FUe77pIA.js → VanillaJSONEditor-DfRefswH.js} +104 -104
- package/assets/add-CJ1-zeA1.js +1 -0
- package/assets/add-form-CbNl0wdS.js +1 -0
- package/assets/add-group-form-Bt_Dx9wm.js +1 -0
- package/assets/add-group-pIFJV5qL.js +1 -0
- package/assets/add-user-D2US8hL_.js +1 -0
- package/assets/add-user-form-Bt8Jy6S2.js +1 -0
- package/assets/{app-DMmad2-f.css → app-B6cCPfWk.css} +1 -1
- package/assets/app-layout-B86jl9bH.js +1 -0
- package/assets/app-shell-CiGyzQ0C.js +1 -0
- package/assets/app-sidebar-Bz-SRwBg.js +1 -0
- package/assets/app-sidebar-header-7CNCx7Rs.js +11 -0
- package/assets/app.js +45 -37
- package/assets/breadcrumbs-_jhtTcOi.js +1 -0
- package/assets/catalog-CON6moaA.js +16 -0
- package/assets/catalog-Cc6Mk9sX.css +1 -0
- package/assets/checkbox-CQdZw5mb.js +1 -0
- package/assets/dashboard-BOltB2Hq.css +1 -0
- package/assets/dashboard-es9ZT8qk.js +3 -0
- package/assets/{date-picker-B__dVVqj.js → date-picker-Dz-d-YWX.js} +2 -2
- package/assets/debounce-qdyXyOeG.js +1 -0
- package/assets/del-modal-D0mrZvki.js +11 -0
- package/assets/dialog-stack-BiMbfm58.js +1 -0
- package/assets/dropdown-menu-BSBcRiXx.js +1 -0
- package/assets/{field-renderer-CapylJU9.js → field-renderer-B6hFAeiU.js} +3 -3
- package/assets/form-Buslty7y.js +1 -0
- package/assets/form-aqiRmPix.js +1 -0
- package/assets/{geo-json-CwteYDGB.js → geo-json-BKmYmu3d.js} +2 -2
- package/assets/{handsontable-BCnjOpBr.js → handsontable-B8xVeMAQ.js} +5 -5
- package/assets/home-Dr72Jk-w.js +2 -0
- package/assets/icon-B-a7xg54.js +1 -0
- package/assets/index-B68_akQe.js +1 -0
- package/assets/index-B7-xTDyy.js +1 -0
- package/assets/index-BJFFlCSo.js +1 -0
- package/assets/{index-DTRTjOmh.js → index-BOuMo_nl.js} +3 -3
- package/assets/index-BzOcGsBq.js +1 -0
- package/assets/index-CFbQ2Rv0.js +1 -0
- package/assets/{index-D5ir9iUV.js → index-Cq31rrfZ.js} +1 -1
- package/assets/{index-BcE9FUM6.js → index-D5UDXTFs.js} +1 -1
- package/assets/index-oxIQWAdI.js +41 -0
- package/assets/init-user-5H689LP0.js +1 -0
- package/assets/input-CSJjrf2i.js +1 -0
- package/assets/input-error-CK92Shhm.js +1 -0
- package/assets/label-Muj0-Efy.js +1 -0
- package/assets/list-Cvh7zbyG.js +1 -0
- package/assets/list-table-Bs_vbQiV.js +52 -0
- package/assets/login-DliJrjMQ.js +6 -0
- package/assets/manifest.json +589 -666
- package/assets/material-icon-BRS58Qpk.js +1 -0
- package/assets/module-CjG21VCT.js +1 -0
- package/assets/{monaco-editor-DqAqwxw4.js → monaco-editor-9fDiyfuW.js} +2 -2
- package/assets/{multi-select-oabtVhUP.js → multi-select-CMQIJ0JT.js} +2 -2
- package/assets/nav-footer-IGMn9NiE.js +1 -0
- package/assets/nav-main-DBE4rMiZ.js +1 -0
- package/assets/nav-user-CjyLRyq-.js +1 -0
- package/assets/pagination-render-DUAq2klc.js +1 -0
- package/assets/popover-C_cww-4_.js +1 -0
- package/assets/register-UzQn3J0g.js +1 -0
- package/assets/{select-D1N8zRPY.js → select-DzBno-dc.js} +2 -2
- package/assets/{sidebar-4D-sX2l4.js → sidebar-Dc4iqfu-.js} +2 -2
- package/assets/skeleton-Dkmj2o2Z.js +1 -0
- package/assets/sonner-De1t71Gj.js +1 -0
- package/assets/{toast-editor-FbrFd1ft.js → toast-editor-1Pul3oMs.js} +2 -2
- package/assets/tooltip-CwPrC-HD.js +1 -0
- package/assets/use-appearance-J8J2w43p.js +1 -0
- package/assets/use-window-size-DLSEoR6e.js +1 -0
- package/assets/{user-info-DBYoAJYJ.js → user-info-8RyDk7qh.js} +2 -2
- package/assets/user-menu-content-CpxTLH56.js +6 -0
- package/assets/welcome-BYKI6yO-.js +1 -0
- package/controllers/add.js +10 -10
- package/controllers/addGroup.js +2 -4
- package/controllers/addUser.js +4 -6
- package/controllers/catalog/Catalog.d.ts +1 -1
- package/controllers/catalog/Catalog.js +42 -37
- package/controllers/catalog/FrontentCatalogAdapter.d.ts +36 -26
- package/controllers/catalog/FrontentCatalogAdapter.js +71 -73
- package/controllers/ckeditorUpload.js +2 -3
- package/controllers/dashboard.js +16 -2
- package/controllers/edit.js +10 -14
- package/controllers/editGroup.js +2 -4
- package/controllers/editUser.js +3 -5
- package/controllers/form.js +2 -3
- package/controllers/getAllWidgets.js +3 -3
- package/controllers/initUser.js +1 -2
- package/controllers/list.js +6 -6
- package/controllers/login.js +43 -18
- package/controllers/media-manager/mediaManagerAdapter.js +1 -2
- package/controllers/media-manager/mediaManagerApi.js +2 -2
- package/controllers/navigation/edit.js +2 -2
- package/controllers/register.js +1 -4
- package/controllers/remove.js +3 -3
- package/controllers/timezones.js +1 -1
- package/controllers/view.js +3 -3
- package/controllers/welcome.js +1 -1
- package/controllers/widgets/Action.js +2 -2
- package/controllers/widgets/Custom.js +2 -2
- package/controllers/widgets/Info.js +2 -2
- package/controllers/widgets/switch.js +2 -2
- package/controllers/widgetsDB.js +5 -5
- package/helpers/JsUtils.d.ts +1 -0
- package/helpers/JsUtils.js +3 -0
- package/helpers/accessRightsHelper.d.ts +6 -2
- package/helpers/accessRightsHelper.js +28 -5
- package/helpers/configHelper.js +2 -1
- package/helpers/controllerHelper.js +39 -18
- package/helpers/fieldsHelper.d.ts +4 -3
- package/helpers/fieldsHelper.js +5 -1
- package/helpers/inertiaActionsHelper.js +1 -1
- package/helpers/inertiaAddHelper.d.ts +3 -4
- package/helpers/inertiaAddHelper.js +27 -7
- package/helpers/inertiaFromHelper.js +2 -0
- package/helpers/inertiaGroupHelper.d.ts +4 -2
- package/helpers/inertiaGroupHelper.js +1 -1
- package/helpers/inertiaListHelper.js +5 -5
- package/helpers/inertiaMenuHelper.d.ts +1 -1
- package/helpers/inertiaMenuHelper.js +2 -2
- package/helpers/inertiaUserHelper.d.ts +7 -1
- package/helpers/inertiaUserHelper.js +5 -1
- package/helpers/menuHelper.d.ts +8 -3
- package/helpers/menuHelper.js +26 -17
- package/index.d.ts +6 -3
- package/index.js +9 -3
- package/interfaces/adminpanelConfig.d.ts +41 -32
- package/interfaces/global.d.ts +10 -28
- package/interfaces/types.d.ts +1 -1
- package/lib/Adminizer.d.ts +11 -3
- package/lib/Adminizer.js +49 -17
- package/lib/media-manager/AbstractMediaManager.d.ts +2 -2
- package/lib/media-manager/AbstractMediaManager.js +1 -1
- package/lib/media-manager/Items.js +0 -3
- package/lib/requestProcessor.js +10 -3
- package/lib/v4/DataAccessor.d.ts +5 -2
- package/lib/v4/DataAccessor.js +44 -19
- package/lib/v4/I18n.js +2 -0
- package/lib/v4/POWCaptcha.js +0 -1
- package/lib/v4/PolicyManager.js +0 -1
- package/lib/{catalog → v4/catalog}/AbstractCatalog.d.ts +89 -60
- package/lib/{catalog → v4/catalog}/AbstractCatalog.js +59 -55
- package/lib/v4/catalog/Navigation.d.ts +43 -0
- package/lib/v4/catalog/Navigation.js +457 -0
- package/lib/{controls → v4/controls}/AbstractControls.d.ts +1 -1
- package/lib/{controls → v4/controls}/codeEditor/MonacoEditor.d.ts +1 -1
- package/lib/{controls → v4/controls}/geojsoneditor/GeoEditor.d.ts +1 -1
- package/lib/{controls → v4/controls}/jsoneditor/JsonEditor.d.ts +1 -1
- package/lib/{controls → v4/controls}/markdown/ToastUiEditor.d.ts +1 -1
- package/lib/{controls → v4/controls}/table/Handsontable.d.ts +1 -1
- package/lib/{controls → v4/controls}/wysiwyg/CKeditor.d.ts +1 -1
- package/lib/{datatable → v4/datatable}/NodeTable.d.ts +3 -3
- package/lib/{datatable → v4/datatable}/NodeTable.js +8 -8
- package/lib/v4/helper/jwt.d.ts +10 -0
- package/lib/v4/helper/jwt.js +18 -0
- package/lib/{inertia → v4/inertia}/inertiaAdapter.js +0 -1
- package/lib/v4/model/AbstractModel.d.ts +5 -1
- package/lib/v4/model/AbstractModel.js +2 -3
- package/lib/v4/model/ModelHandler.js +1 -4
- package/lib/v4/model/adapter/sequelize.d.ts +11 -2
- package/lib/v4/model/adapter/sequelize.js +451 -118
- package/lib/v4/model/adapter/waterline.js +5 -3
- package/lib/{widgets → v4/widgets}/abstractAction.d.ts +1 -1
- package/lib/v4/widgets/abstractCustom.d.ts +28 -0
- package/lib/v4/widgets/abstractCustom.js +9 -0
- package/lib/{widgets → v4/widgets}/abstractInfo.d.ts +1 -1
- package/lib/{widgets → v4/widgets}/abstractInfo.js +1 -1
- package/lib/{widgets → v4/widgets}/abstractLink.d.ts +2 -1
- package/lib/{widgets → v4/widgets}/abstractSwitch.d.ts +1 -1
- package/lib/{widgets → v4/widgets}/abstractWidgetBase.d.ts +2 -2
- package/lib/{widgets → v4/widgets}/widgetHandler.d.ts +29 -5
- package/lib/{widgets → v4/widgets}/widgetHandler.js +25 -25
- package/models/GroupAP.d.ts +8 -0
- package/models/NavigationAP.d.ts +7 -3
- package/models/NavigationAP.js +5 -6
- package/models/UserAP.d.ts +24 -2
- package/models/UserAP.js +2 -2
- package/package.json +29 -11
- package/policies/checkAuth.js +4 -3
- package/policies/setLocale.js +2 -2
- package/system/Router.js +14 -17
- package/system/bindAccessRights.js +0 -4
- package/system/bindAuthorization.js +4 -5
- package/system/bindControls.js +6 -6
- package/system/bindDev.js +1 -0
- package/system/bindInertia.js +17 -12
- package/system/bindMediaManager.js +0 -1
- package/system/bindModels.js +9 -6
- package/system/bindNavigation.d.ts +2 -0
- package/system/bindNavigation.js +42 -42
- package/system/bindReqFunctions.js +15 -0
- package/system/defaults.js +13 -6
- package/translations/ar.json +70 -1
- package/translations/cn.json +70 -1
- package/translations/de.json +71 -3
- package/translations/en.json +70 -102
- package/translations/es.json +70 -1
- package/translations/fr.json +70 -1
- package/translations/hi.json +70 -1
- package/translations/jp.json +70 -1
- package/translations/ko.json +70 -1
- package/translations/pt.json +70 -1
- package/translations/ru.json +71 -94
- package/translations/ua.json +70 -1
- package/translations/uz.json +72 -0
- package/translations/vi.json +70 -1
- package/assets/add-ZITr43GJ.js +0 -1
- package/assets/add-form-CYOfr0Ef.js +0 -1
- package/assets/add-group-B332wN8K.js +0 -1
- package/assets/add-group-form-dzadPSfL.js +0 -1
- package/assets/add-user-TC-mYdsB.js +0 -1
- package/assets/add-user-form-y2f_1_lM.js +0 -1
- package/assets/app-layout-D1m9Kvxq.js +0 -1
- package/assets/app-shell-BWMRMkHM.js +0 -1
- package/assets/app-sidebar-BCtaEFGb.js +0 -1
- package/assets/app-sidebar-header-DLAFi13E.js +0 -11
- package/assets/breadcrumbs-CQNon4Vl.js +0 -1
- package/assets/button-CQ9t1kLz.js +0 -1
- package/assets/checkbox-W0nGAXIj.js +0 -1
- package/assets/compiler-runtime-tM4jBQ-T.js +0 -9
- package/assets/dashboard-BR602KhL.js +0 -1
- package/assets/dropdown-menu-SEBnEIiL.js +0 -1
- package/assets/form-DOUNk3o2.js +0 -1
- package/assets/form-lOKv4Qbw.js +0 -1
- package/assets/home-Ch6QfTIt.js +0 -2
- package/assets/icon-Bz9BMaD0.js +0 -1
- package/assets/index-BC0yfOHo.js +0 -1
- package/assets/index-BbXEMx9n.js +0 -1
- package/assets/index-C0SL3SHw.js +0 -41
- package/assets/index-Cdb9ACvz.js +0 -1
- package/assets/index-DEk3sC8d.js +0 -1
- package/assets/index-DrWfGwtf.js +0 -1
- package/assets/index-K81GbF6O.js +0 -1
- package/assets/init-user-D9mW-g14.js +0 -1
- package/assets/input-DF7Ue23C.js +0 -1
- package/assets/input-error-BBygona6.js +0 -1
- package/assets/label-Z506NKsW.js +0 -1
- package/assets/list-Qyd7ecQH.js +0 -1
- package/assets/list-table-DB1sEQLF.js +0 -62
- package/assets/login-DrGaTWhY.js +0 -6
- package/assets/material-icon-CItZiB53.js +0 -1
- package/assets/module-DBaykv8l.js +0 -1
- package/assets/nav-footer-CM-yHiRs.js +0 -1
- package/assets/nav-main-Q3xofGRT.js +0 -1
- package/assets/nav-user-Ds8i0Pa2.js +0 -1
- package/assets/pagination-render-B57pOpFy.js +0 -1
- package/assets/popover-I249Gg2O.js +0 -1
- package/assets/register-C9FQIDtS.js +0 -1
- package/assets/sonner-Dzckw3U3.js +0 -1
- package/assets/tooltip-D2ehgLlB.js +0 -1
- package/assets/use-appearance-Co6mO0dV.js +0 -1
- package/assets/use-window-size-B8l6Bpkf.js +0 -1
- package/assets/user-menu-content-qkvdkUVd.js +0 -6
- package/assets/utils-DjqsqOe8.js +0 -1
- package/assets/welcome-D2adQ8EU.js +0 -1
- package/controllers/processInstallFinalize.d.ts +0 -1
- package/controllers/processInstallFinalize.js +0 -16
- package/controllers/processInstallStep.d.ts +0 -1
- package/controllers/processInstallStep.js +0 -132
- package/lib/catalog/Navigation.d.ts +0 -0
- package/lib/catalog/Navigation.js +0 -532
- package/lib/installStepper/InstallStepAbstract.d.ts +0 -52
- package/lib/installStepper/InstallStepAbstract.js +0 -69
- package/lib/installStepper/finalizeStep.d.ts +0 -21
- package/lib/installStepper/finalizeStep.js +0 -48
- package/lib/installStepper/installStepper.d.ts +0 -40
- package/lib/installStepper/installStepper.js +0 -195
- package/lib/widgets/abstractCustom.d.ts +0 -13
- package/lib/widgets/abstractCustom.js +0 -3
- package/models/MediaManagerAP.d.ts +0 -46
- package/models/MediaManagerAP.js +0 -45
- package/models/MediaManagerAssociationsAP.d.ts +0 -28
- package/models/MediaManagerAssociationsAP.js +0 -27
- package/models/MediaManagerMetaAP.d.ts +0 -22
- package/models/MediaManagerMetaAP.js +0 -21
- package/system/bindInstallStepper.d.ts +0 -2
- package/system/bindInstallStepper.js +0 -23
- /package/lib/{catalog → v4/catalog}/CatalogHandler.d.ts +0 -0
- /package/lib/{catalog → v4/catalog}/CatalogHandler.js +0 -0
- /package/lib/{controls → v4/controls}/AbstractControls.js +0 -0
- /package/lib/{controls → v4/controls}/ControlsHandler.d.ts +0 -0
- /package/lib/{controls → v4/controls}/ControlsHandler.js +0 -0
- /package/lib/{controls → v4/controls}/codeEditor/MonacoEditor.js +0 -0
- /package/lib/{controls → v4/controls}/geojsoneditor/GeoEditor.js +0 -0
- /package/lib/{controls → v4/controls}/jsoneditor/JsonEditor.js +0 -0
- /package/lib/{controls → v4/controls}/markdown/ToastUiEditor.js +0 -0
- /package/lib/{controls → v4/controls}/table/Handsontable.js +0 -0
- /package/lib/{controls → v4/controls}/wysiwyg/CKeditor.js +0 -0
- /package/lib/{inertia → v4/inertia}/flash.d.ts +0 -0
- /package/lib/{inertia → v4/inertia}/flash.js +0 -0
- /package/lib/{inertia → v4/inertia}/inertiaAdapter.d.ts +0 -0
- /package/lib/{widgets → v4/widgets}/abstractAction.js +0 -0
- /package/lib/{widgets → v4/widgets}/abstractLink.js +0 -0
- /package/lib/{widgets → v4/widgets}/abstractSwitch.js +0 -0
- /package/lib/{widgets → v4/widgets}/abstractWidgetBase.js +0 -0
|
@@ -3,162 +3,456 @@ import { AbstractAdapter, AbstractModel } from "../AbstractModel";
|
|
|
3
3
|
import path from "path";
|
|
4
4
|
import fs from "fs";
|
|
5
5
|
import { pathToFileURL } from "url";
|
|
6
|
-
function
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
6
|
+
function generateAssociationsFromSchema(models, schemas) {
|
|
7
|
+
for (const modelName in schemas) {
|
|
8
|
+
const schema = schemas[modelName];
|
|
9
|
+
const model = models[modelName];
|
|
10
|
+
if (!model)
|
|
11
|
+
continue;
|
|
12
|
+
for (const fieldName in schema) {
|
|
13
|
+
const field = schema[fieldName];
|
|
14
|
+
if (field.collection && field.via) {
|
|
15
|
+
const targetModel = models[field.collection];
|
|
16
|
+
const targetSchema = schemas[field.collection];
|
|
17
|
+
const inverseField = targetSchema?.[field.via];
|
|
18
|
+
const throughTableName = [modelName, field.collection].sort().join("");
|
|
19
|
+
// 💡 M:N связь
|
|
20
|
+
if (inverseField && inverseField.collection === modelName) {
|
|
21
|
+
model.belongsToMany(targetModel, {
|
|
22
|
+
through: throughTableName,
|
|
23
|
+
as: fieldName,
|
|
24
|
+
foreignKey: `${modelName}Id`,
|
|
25
|
+
otherKey: `${field.collection}Id`
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
// 💡 O:M связь (один ко многим)
|
|
29
|
+
else {
|
|
30
|
+
model.hasMany(targetModel, {
|
|
31
|
+
as: fieldName,
|
|
32
|
+
foreignKey: `${modelName}Id`,
|
|
33
|
+
});
|
|
34
|
+
targetModel.belongsTo(model, {
|
|
35
|
+
as: field.via,
|
|
36
|
+
foreignKey: `${modelName}Id`,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
// 💡 O:1 или 1:1 (belongsTo)
|
|
41
|
+
if (field.model) {
|
|
42
|
+
const targetModel = models[field.model];
|
|
43
|
+
if (!targetModel)
|
|
44
|
+
continue;
|
|
45
|
+
// Avoid naming collision by making FK explicit: `${fieldName}Id`
|
|
46
|
+
const foreignKey = `${fieldName}Id`;
|
|
47
|
+
const alias = fieldName;
|
|
48
|
+
// Если поле уже существует — избегаем конфликта
|
|
49
|
+
if (model.rawAttributes[alias]) {
|
|
50
|
+
model.belongsTo(targetModel, {
|
|
51
|
+
as: alias,
|
|
52
|
+
foreignKey,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
model.belongsTo(targetModel, {
|
|
57
|
+
foreignKey: alias, // если нет конфликта, можно использовать alias как FK
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
17
62
|
}
|
|
18
|
-
return result;
|
|
19
63
|
}
|
|
20
64
|
function resolveType(type) {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
if (sqlType.includes("date"))
|
|
36
|
-
return "string"; // 👈 фикс: дата как строка
|
|
37
|
-
return "ref";
|
|
38
|
-
}
|
|
39
|
-
catch {
|
|
40
|
-
return "ref";
|
|
41
|
-
}
|
|
65
|
+
const sqlType = typeof type.toString === "function"
|
|
66
|
+
? type.toString().toLowerCase()
|
|
67
|
+
: "";
|
|
68
|
+
if (sqlType.includes("string") || sqlType.includes("uuid"))
|
|
69
|
+
return "string";
|
|
70
|
+
if (sqlType.includes("int") || sqlType.includes("float") || sqlType.includes("decimal"))
|
|
71
|
+
return "number";
|
|
72
|
+
if (sqlType.includes("bool"))
|
|
73
|
+
return "boolean";
|
|
74
|
+
if (sqlType.includes("json"))
|
|
75
|
+
return "json";
|
|
76
|
+
if (sqlType.includes("date"))
|
|
77
|
+
return "string";
|
|
78
|
+
return "ref";
|
|
42
79
|
}
|
|
43
|
-
|
|
44
|
-
function convertCriteriaToSequelize(criteria) {
|
|
45
|
-
console.log("waterline criteria", criteria);
|
|
80
|
+
export function mapSequelizeToWaterline(model) {
|
|
46
81
|
const result = {};
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
});
|
|
72
|
-
if (operatorEntries.length > 0) {
|
|
73
|
-
result[key] = Object.fromEntries(operatorEntries);
|
|
82
|
+
const rawAttrs = model.getAttributes();
|
|
83
|
+
for (const name in rawAttrs) {
|
|
84
|
+
const meta = rawAttrs[name];
|
|
85
|
+
result[name] = {
|
|
86
|
+
type: resolveType(meta.type),
|
|
87
|
+
required: meta.allowNull !== undefined ? !meta.allowNull : false,
|
|
88
|
+
allowNull: meta.allowNull,
|
|
89
|
+
unique: !!meta.unique,
|
|
90
|
+
defaultsTo: meta.defaultValue,
|
|
91
|
+
columnName: meta.field || name,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
for (const alias in model.associations) {
|
|
95
|
+
const assoc = model.associations[alias];
|
|
96
|
+
switch (assoc.associationType) {
|
|
97
|
+
case "BelongsTo": {
|
|
98
|
+
const a = assoc;
|
|
99
|
+
result[a.foreignKey]["primaryKeyForAssociation"] = true;
|
|
100
|
+
result[alias] = {
|
|
101
|
+
type: "association",
|
|
102
|
+
model: a.target.name,
|
|
103
|
+
via: a.foreignKey,
|
|
104
|
+
};
|
|
105
|
+
break;
|
|
74
106
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
107
|
+
case "HasOne": {
|
|
108
|
+
const a = assoc;
|
|
109
|
+
result[a.foreignKey]["primaryKeyForAssociation"] = true;
|
|
110
|
+
result[alias] = {
|
|
111
|
+
type: "association",
|
|
112
|
+
model: a.target.name,
|
|
113
|
+
via: a.foreignKey,
|
|
114
|
+
};
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
case "HasMany": {
|
|
118
|
+
const a = assoc;
|
|
119
|
+
result[alias] = {
|
|
120
|
+
type: "association-many",
|
|
121
|
+
collection: a.target.name,
|
|
122
|
+
via: a.foreignKey,
|
|
123
|
+
};
|
|
124
|
+
break;
|
|
125
|
+
}
|
|
126
|
+
case "BelongsToMany": {
|
|
127
|
+
const a = assoc;
|
|
128
|
+
result[alias] = {
|
|
129
|
+
type: "association-many",
|
|
130
|
+
collection: a.target.name,
|
|
131
|
+
via: a.otherKey,
|
|
132
|
+
};
|
|
133
|
+
break;
|
|
134
|
+
}
|
|
135
|
+
default:
|
|
136
|
+
break;
|
|
78
137
|
}
|
|
79
138
|
}
|
|
80
139
|
return result;
|
|
81
140
|
}
|
|
82
|
-
function
|
|
83
|
-
|
|
84
|
-
const { where = {}, skip, limit, sort } = criteria;
|
|
85
|
-
const result = {
|
|
86
|
-
where: convertCriteriaToSequelize(where),
|
|
87
|
-
};
|
|
88
|
-
if (typeof skip === "number") {
|
|
89
|
-
result.offset = skip;
|
|
90
|
-
}
|
|
91
|
-
if (typeof limit === "number") {
|
|
92
|
-
result.limit = limit;
|
|
93
|
-
}
|
|
94
|
-
if (typeof sort === "string") {
|
|
95
|
-
const [field, direction] = sort.trim().split(/\s+/);
|
|
96
|
-
result.order = [[field, direction?.toUpperCase() === "DESC" ? "DESC" : "ASC"]];
|
|
97
|
-
}
|
|
98
|
-
return result;
|
|
141
|
+
function capitalize(str) {
|
|
142
|
+
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
99
143
|
}
|
|
100
144
|
export class SequelizeModel extends AbstractModel {
|
|
101
145
|
model;
|
|
102
146
|
constructor(modelName, model) {
|
|
103
|
-
super(modelName,
|
|
147
|
+
super(modelName, mapSequelizeToWaterline(model), model.primaryKeyAttribute, model.name);
|
|
104
148
|
this.model = model;
|
|
105
149
|
}
|
|
150
|
+
_convertCriteriaToSequelize(criteria) {
|
|
151
|
+
const result = {};
|
|
152
|
+
for (const key in criteria) {
|
|
153
|
+
const value = criteria[key];
|
|
154
|
+
if (value === undefined ||
|
|
155
|
+
value === null ||
|
|
156
|
+
(typeof value === "object" && Object.keys(value).length === 0)) {
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
// 🧠 Заменяем ключ на `via`, если это ассоциация
|
|
160
|
+
const attr = this.attributes?.[key];
|
|
161
|
+
let targetKey = key;
|
|
162
|
+
if (attr?.type === "association" && attr.via) {
|
|
163
|
+
targetKey = attr.via;
|
|
164
|
+
}
|
|
165
|
+
if (typeof value === "object" && !Array.isArray(value)) {
|
|
166
|
+
const operatorEntries = Object.entries(value)
|
|
167
|
+
.filter(([_, v]) => v !== undefined && v !== null)
|
|
168
|
+
.map(([op, val]) => {
|
|
169
|
+
switch (op) {
|
|
170
|
+
case "contains": return [Op.like, `%${val}%`];
|
|
171
|
+
case "startsWith": return [Op.startsWith, val];
|
|
172
|
+
case "endsWith": return [Op.endsWith, val];
|
|
173
|
+
case ">": return [Op.gt, val];
|
|
174
|
+
case ">=": return [Op.gte, val];
|
|
175
|
+
case "<": return [Op.lt, val];
|
|
176
|
+
case "<=": return [Op.lte, val];
|
|
177
|
+
case "!=": return [Op.ne, val];
|
|
178
|
+
case "in": return [Op.in, val];
|
|
179
|
+
case "nin": return [Op.notIn, val];
|
|
180
|
+
default: return [Op.eq, val];
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
if (operatorEntries.length > 0) {
|
|
184
|
+
result[targetKey] = Object.fromEntries(operatorEntries);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
else {
|
|
188
|
+
result[targetKey] = value;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return result;
|
|
192
|
+
}
|
|
193
|
+
_convertWaterlineCriteriaToSequelizeOptions(criteria) {
|
|
194
|
+
// console.debug("WATERLINE CRITERIA (raw):", criteria);
|
|
195
|
+
const { where: nestedWhere, skip, limit, sort, ...rest } = criteria;
|
|
196
|
+
const rawWhere = (nestedWhere && Object.keys(nestedWhere).length > 0)
|
|
197
|
+
? nestedWhere
|
|
198
|
+
: rest;
|
|
199
|
+
// console.debug("WATERLINE CRITERIA: using rawWhere =", rawWhere);
|
|
200
|
+
const where = this._convertCriteriaToSequelize(rawWhere);
|
|
201
|
+
const result = { where };
|
|
202
|
+
if (typeof skip === "number") {
|
|
203
|
+
result.offset = skip;
|
|
204
|
+
// console.debug("→ offset =", skip);
|
|
205
|
+
}
|
|
206
|
+
if (typeof limit === "number") {
|
|
207
|
+
result.limit = limit;
|
|
208
|
+
// console.debug("→ limit =", limit);
|
|
209
|
+
}
|
|
210
|
+
if (typeof sort === "string") {
|
|
211
|
+
const [field, dir] = sort.trim().split(/\s+/);
|
|
212
|
+
result.order = [[field, dir?.toUpperCase() === "DESC" ? "DESC" : "ASC"]];
|
|
213
|
+
// console.debug("→ order =", result.order);
|
|
214
|
+
}
|
|
215
|
+
return result;
|
|
216
|
+
}
|
|
217
|
+
async _assignAssociations(instance, assocData) {
|
|
218
|
+
for (const [alias, ids] of Object.entries(assocData)) {
|
|
219
|
+
const assoc = this.model.associations[alias];
|
|
220
|
+
if (!assoc)
|
|
221
|
+
continue;
|
|
222
|
+
//@ts-ignore
|
|
223
|
+
const { set: setAccessor, add: addAccessor } = assoc.accessors;
|
|
224
|
+
if (Array.isArray(ids)) {
|
|
225
|
+
if (typeof instance[setAccessor] === 'function') {
|
|
226
|
+
await instance[setAccessor](ids);
|
|
227
|
+
continue;
|
|
228
|
+
}
|
|
229
|
+
if (typeof instance[addAccessor] === 'function') {
|
|
230
|
+
for (const id of ids) {
|
|
231
|
+
await instance[addAccessor](id);
|
|
232
|
+
}
|
|
233
|
+
continue;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
if (typeof instance[setAccessor] === 'function') {
|
|
237
|
+
await instance[setAccessor](ids);
|
|
238
|
+
}
|
|
239
|
+
else if (typeof instance[addAccessor] === 'function') {
|
|
240
|
+
await instance[addAccessor](ids);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
106
244
|
// --- CREATE ---
|
|
107
245
|
async _create(data) {
|
|
108
|
-
|
|
109
|
-
const
|
|
110
|
-
|
|
246
|
+
// console.clear()
|
|
247
|
+
const assocNames = Object.keys(this.model.associations);
|
|
248
|
+
const plainData = {};
|
|
249
|
+
const assocData = {};
|
|
250
|
+
// console.debug(">> _create: входные данные:", data);
|
|
251
|
+
// console.debug(">> Доступные ассоциации:", assocNames);
|
|
252
|
+
for (const [key, val] of Object.entries(data)) {
|
|
253
|
+
if (assocNames.includes(key)) {
|
|
254
|
+
assocData[key] = val;
|
|
255
|
+
}
|
|
256
|
+
else {
|
|
257
|
+
plainData[key] = val;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
// console.debug(">> Обычные поля для create():", plainData);
|
|
261
|
+
// console.debug(">> Данные ассоциаций:", assocData);
|
|
262
|
+
let instance;
|
|
263
|
+
try {
|
|
264
|
+
instance = await this.model.create(plainData);
|
|
265
|
+
// console.debug(">> Создан экземпляр (без ассоциаций):", instance.toJSON());
|
|
266
|
+
}
|
|
267
|
+
catch (err) {
|
|
268
|
+
// console.error("!! Ошибка при create(plainData):", err);
|
|
269
|
+
throw err;
|
|
270
|
+
}
|
|
271
|
+
// assocData = { example: 5, userAPs: [1,2,3], category: 7, tags: [11,22] }
|
|
272
|
+
// this.model.associations — ваш объект ассоциаций
|
|
273
|
+
for (const [alias, ids] of Object.entries(assocData)) {
|
|
274
|
+
const assoc = this.model.associations[alias];
|
|
275
|
+
if (!assoc) {
|
|
276
|
+
// console.warn(`Association "${alias}" not defined on model`);
|
|
277
|
+
continue;
|
|
278
|
+
}
|
|
279
|
+
// @ts-ignore accessors is present
|
|
280
|
+
const { set: setAccessor, add: addAccessor } = assoc.accessors;
|
|
281
|
+
if (Array.isArray(ids)) {
|
|
282
|
+
if (typeof instance[setAccessor] === 'function') {
|
|
283
|
+
await instance[setAccessor](ids);
|
|
284
|
+
continue;
|
|
285
|
+
}
|
|
286
|
+
if (typeof instance[addAccessor] === 'function') {
|
|
287
|
+
for (const id of ids) {
|
|
288
|
+
await instance[addAccessor](id);
|
|
289
|
+
}
|
|
290
|
+
continue;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
if (typeof instance[setAccessor] === 'function') {
|
|
294
|
+
await instance[setAccessor](ids);
|
|
295
|
+
}
|
|
296
|
+
else if (typeof instance[addAccessor] === 'function') {
|
|
297
|
+
await instance[addAccessor](ids);
|
|
298
|
+
}
|
|
299
|
+
else {
|
|
300
|
+
// console.warn(`No suitable accessor for "${alias}": tried set=${setAccessor}, add=${addAccessor}`);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
await instance.reload({ include: Object.values(this.model.associations) });
|
|
304
|
+
const pk = this.primaryKey;
|
|
305
|
+
const fresh = await this.model.findByPk(instance.get(pk), { include: assocNames.map(a => ({ association: a })) });
|
|
306
|
+
// console.debug(">> Результат после reload:", fresh?.toJSON());
|
|
307
|
+
return fresh;
|
|
111
308
|
}
|
|
112
309
|
// --- FIND ONE ---
|
|
113
310
|
async _findOne(criteria) {
|
|
114
|
-
|
|
115
|
-
const
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
311
|
+
// console.debug(">> _findOne: входные критерии:", criteria);
|
|
312
|
+
const { where } = this._convertWaterlineCriteriaToSequelizeOptions(criteria);
|
|
313
|
+
const includes = this._buildIncludes();
|
|
314
|
+
// console.debug(">> _findOne: преобразованные where:", where);
|
|
315
|
+
// console.debug(">> _findOne: includes:", includes);
|
|
316
|
+
let instance = null;
|
|
317
|
+
try {
|
|
318
|
+
instance = await this.model.findOne({ where, include: includes });
|
|
319
|
+
// console.debug(">> _findOne: сырое instance:", instance ? instance.toJSON() : null);
|
|
320
|
+
}
|
|
321
|
+
catch (err) {
|
|
322
|
+
// console.error("!! _findOne: ошибка при вызове findOne:", err);
|
|
323
|
+
throw err;
|
|
324
|
+
}
|
|
325
|
+
if (!instance) {
|
|
326
|
+
// console.debug(">> _findOne: ничего не найдено");
|
|
327
|
+
return null;
|
|
328
|
+
}
|
|
329
|
+
const plain = instance.get({ plain: true });
|
|
330
|
+
// console.debug(">> _findOne: plain результат:", plain);
|
|
331
|
+
return plain;
|
|
121
332
|
}
|
|
122
333
|
// --- FIND MANY ---
|
|
123
334
|
async _find(criteria = {}, options = {}) {
|
|
124
|
-
const
|
|
125
|
-
|
|
335
|
+
const assocNames = Object.keys(this.model.associations);
|
|
336
|
+
// console.debug(">> _find: входные criteria:", criteria, "options:", options);
|
|
337
|
+
const { where, limit, offset, order } = this._convertWaterlineCriteriaToSequelizeOptions(criteria);
|
|
338
|
+
const includes = options.populate
|
|
126
339
|
? options.populate.map(([field, opts]) => ({ association: field, ...opts }))
|
|
127
|
-
:
|
|
128
|
-
|
|
340
|
+
: assocNames.map(a => ({ association: a }));
|
|
341
|
+
// console.debug(">> _find: where, limit, offset, order, includes:", {
|
|
342
|
+
// where,
|
|
343
|
+
// limit,
|
|
344
|
+
// offset,
|
|
345
|
+
// order,
|
|
346
|
+
// includes,
|
|
347
|
+
// });
|
|
348
|
+
let instances;
|
|
349
|
+
instances = await this.model.findAll({
|
|
129
350
|
where,
|
|
130
351
|
limit,
|
|
131
352
|
offset,
|
|
132
353
|
order,
|
|
133
|
-
include
|
|
134
|
-
raw: true,
|
|
354
|
+
include: includes
|
|
135
355
|
});
|
|
136
|
-
|
|
356
|
+
for (const inst of instances) {
|
|
357
|
+
//For each association, we call getxxx () once again
|
|
358
|
+
for (const alias of assocNames) {
|
|
359
|
+
// @ts-ignore accessors is present
|
|
360
|
+
const getAccessor = this.model.associations[alias].accessors.get;
|
|
361
|
+
if (typeof inst[getAccessor] === "function") {
|
|
362
|
+
try {
|
|
363
|
+
const related = await inst[getAccessor]();
|
|
364
|
+
const mapped = Array.isArray(related)
|
|
365
|
+
? related.map((r) => r.toJSON())
|
|
366
|
+
: related?.toJSON();
|
|
367
|
+
// console.debug(`---- get${alias}():`, mapped);
|
|
368
|
+
}
|
|
369
|
+
catch (e) {
|
|
370
|
+
// console.error(`!! ошибка при вызове ${getAccessor}():`, e);
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
const plain = instances.map(i => i.get({ plain: true }));
|
|
376
|
+
// console.debug(">> _find: plain результаты:", plain);
|
|
377
|
+
return plain;
|
|
137
378
|
}
|
|
138
379
|
// --- UPDATE ONE ---
|
|
139
380
|
async _updateOne(criteria, data) {
|
|
140
|
-
const { where } =
|
|
381
|
+
const { where } = this._convertWaterlineCriteriaToSequelizeOptions(criteria);
|
|
141
382
|
const record = await this.model.findOne({ where });
|
|
142
|
-
if (!record)
|
|
383
|
+
if (!record)
|
|
143
384
|
return null;
|
|
385
|
+
const assocNames = Object.keys(this.model.associations);
|
|
386
|
+
const plainData = {};
|
|
387
|
+
const assocData = {};
|
|
388
|
+
for (const [key, val] of Object.entries(data)) {
|
|
389
|
+
if (assocNames.includes(key)) {
|
|
390
|
+
assocData[key] = val;
|
|
391
|
+
}
|
|
392
|
+
else {
|
|
393
|
+
plainData[key] = val;
|
|
394
|
+
}
|
|
144
395
|
}
|
|
145
|
-
await record.update(
|
|
146
|
-
|
|
147
|
-
|
|
396
|
+
await record.update(plainData);
|
|
397
|
+
await this._assignAssociations(record, assocData);
|
|
398
|
+
await record.reload({ include: Object.values(this.model.associations) });
|
|
399
|
+
return record.get({ plain: true });
|
|
148
400
|
}
|
|
149
401
|
// --- UPDATE MANY ---
|
|
150
402
|
async _update(criteria, data) {
|
|
151
|
-
const { where } =
|
|
152
|
-
|
|
153
|
-
const
|
|
154
|
-
|
|
403
|
+
const { where } = this._convertWaterlineCriteriaToSequelizeOptions(criteria);
|
|
404
|
+
const assocNames = Object.keys(this.model.associations);
|
|
405
|
+
const plainData = {};
|
|
406
|
+
const assocData = {};
|
|
407
|
+
for (const [key, val] of Object.entries(data)) {
|
|
408
|
+
if (assocNames.includes(key)) {
|
|
409
|
+
assocData[key] = val;
|
|
410
|
+
}
|
|
411
|
+
else {
|
|
412
|
+
plainData[key] = val;
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
const records = await this.model.findAll({ where });
|
|
416
|
+
for (const record of records) {
|
|
417
|
+
await record.update(plainData);
|
|
418
|
+
await this._assignAssociations(record, assocData);
|
|
419
|
+
}
|
|
420
|
+
const reloaded = await this.model.findAll({
|
|
421
|
+
where,
|
|
422
|
+
include: Object.values(this.model.associations)
|
|
423
|
+
});
|
|
424
|
+
return reloaded.map(r => r.get({ plain: true }));
|
|
155
425
|
}
|
|
156
426
|
// --- DESTROY ONE ---
|
|
157
427
|
async _destroyOne(criteria) {
|
|
158
|
-
const { where } =
|
|
428
|
+
const { where } = this._convertWaterlineCriteriaToSequelizeOptions(criteria);
|
|
159
429
|
const record = await this.model.findOne({ where });
|
|
160
|
-
if (!record)
|
|
430
|
+
if (!record)
|
|
161
431
|
return null;
|
|
432
|
+
const assocNames = Object.keys(this.model.associations);
|
|
433
|
+
for (const alias of assocNames) {
|
|
434
|
+
const assoc = this.model.associations[alias];
|
|
435
|
+
// @ts-ignore: accessors should exist
|
|
436
|
+
const getAccessor = assoc.accessors?.get;
|
|
437
|
+
if (typeof record[getAccessor] === "function") {
|
|
438
|
+
try {
|
|
439
|
+
const related = await record[getAccessor]();
|
|
440
|
+
// 🧹 Удаляем связанные записи
|
|
441
|
+
if (Array.isArray(related)) {
|
|
442
|
+
for (const r of related) {
|
|
443
|
+
if (typeof r.destroy === "function") {
|
|
444
|
+
await r.destroy();
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
else if (related && typeof related.destroy === "function") {
|
|
449
|
+
await related.destroy();
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
catch (e) {
|
|
453
|
+
// console.warn(`Failed to fetch/delete relation "${alias}":`, e);
|
|
454
|
+
}
|
|
455
|
+
}
|
|
162
456
|
}
|
|
163
457
|
const raw = record.get({ plain: true });
|
|
164
458
|
await record.destroy();
|
|
@@ -166,15 +460,44 @@ export class SequelizeModel extends AbstractModel {
|
|
|
166
460
|
}
|
|
167
461
|
// --- DESTROY MANY ---
|
|
168
462
|
async _destroy(criteria) {
|
|
169
|
-
const { where } =
|
|
463
|
+
const { where } = this._convertWaterlineCriteriaToSequelizeOptions(criteria);
|
|
170
464
|
const records = await this.model.findAll({ where });
|
|
465
|
+
const assocNames = Object.keys(this.model.associations);
|
|
466
|
+
for (const record of records) {
|
|
467
|
+
for (const alias of assocNames) {
|
|
468
|
+
const assoc = this.model.associations[alias];
|
|
469
|
+
// 🛑 Не трогаем родительские связи
|
|
470
|
+
if (assoc.associationType === "BelongsTo")
|
|
471
|
+
continue;
|
|
472
|
+
// @ts-ignore accessor exists
|
|
473
|
+
const getAccessor = assoc.accessors?.get;
|
|
474
|
+
if (typeof record[getAccessor] === "function") {
|
|
475
|
+
try {
|
|
476
|
+
const related = await record[getAccessor]();
|
|
477
|
+
if (Array.isArray(related)) {
|
|
478
|
+
for (const rel of related) {
|
|
479
|
+
if (typeof rel.destroy === "function") {
|
|
480
|
+
await rel.destroy();
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
else if (related && typeof related.destroy === "function") {
|
|
485
|
+
await related.destroy();
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
catch (e) {
|
|
489
|
+
// console.warn(`Failed to delete relation ${alias}:`, e);
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
}
|
|
171
494
|
const raw = records.map(r => r.get({ plain: true }));
|
|
172
495
|
await this.model.destroy({ where });
|
|
173
496
|
return raw;
|
|
174
497
|
}
|
|
175
498
|
// --- COUNT ---
|
|
176
499
|
async _count(criteria = {}) {
|
|
177
|
-
const { where } =
|
|
500
|
+
const { where } = this._convertWaterlineCriteriaToSequelizeOptions(criteria);
|
|
178
501
|
const result = await this.model.count({ where });
|
|
179
502
|
return result;
|
|
180
503
|
}
|
|
@@ -205,20 +528,30 @@ export class SequelizeAdapter extends AbstractAdapter {
|
|
|
205
528
|
const model = this.getModel(modelName);
|
|
206
529
|
return model?.getAttributes();
|
|
207
530
|
}
|
|
208
|
-
/**
|
|
531
|
+
/**Registration of system models*/
|
|
209
532
|
static async registerSystemModels(sequelize) {
|
|
210
533
|
const modelsDir = path.resolve(import.meta.dirname, "../../../../models");
|
|
211
|
-
|
|
534
|
+
let files = fs.readdirSync(modelsDir).filter(f => f.endsWith(".js"));
|
|
535
|
+
if (!files.length) {
|
|
536
|
+
files = fs.readdirSync(modelsDir).filter(f => f.endsWith(".ts") && !f.endsWith(".d.ts"));
|
|
537
|
+
}
|
|
538
|
+
if (!files.length) {
|
|
539
|
+
throw `Model files not found in dir ${modelsDir}`;
|
|
540
|
+
}
|
|
541
|
+
const schemas = {};
|
|
212
542
|
for (const file of files) {
|
|
213
543
|
const modelName = path.basename(file, path.extname(file));
|
|
214
544
|
const filePath = path.resolve(modelsDir, file);
|
|
215
|
-
const
|
|
545
|
+
const mod = await import(pathToFileURL(filePath).href);
|
|
546
|
+
const definition = mod.default;
|
|
547
|
+
schemas[modelName] = definition;
|
|
216
548
|
generateSequelizeModel(sequelize, modelName, definition);
|
|
217
549
|
}
|
|
550
|
+
generateAssociationsFromSchema(sequelize.models, schemas);
|
|
218
551
|
await sequelize.sync();
|
|
219
552
|
}
|
|
220
553
|
}
|
|
221
|
-
/**
|
|
554
|
+
/**Generation of the SEQUELIZE model from the definition, analogue of Waterinecollection.extenD*/
|
|
222
555
|
function generateSequelizeModel(sequelize, modelName, rawAttributes) {
|
|
223
556
|
const attributes = {};
|
|
224
557
|
let primaryKey = null;
|