adminizer 5.0.0-build.0 → 5.0.0-build.10

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.
Files changed (142) hide show
  1. package/assets/{add-a4odXvQk.js → add-BtctcXXV.js} +1 -1
  2. package/assets/{add-group-D-NleXth.js → add-group-C0LgrR0Z.js} +1 -1
  3. package/assets/add-user-CALUedTL.js +1 -0
  4. package/assets/app-DNXiApCk.css +1 -0
  5. package/assets/{app-layout-eaSzcROf.js → app-layout-CTavO9pF.js} +1 -1
  6. package/assets/app.js +33 -33
  7. package/assets/catalog-BGkKJyhR.js +6 -0
  8. package/assets/controls/ckeditor.es.js +2735 -2712
  9. package/assets/controls/handsontable.es.js +11546 -11511
  10. package/assets/controls/jsoneditor.es.js +13004 -12846
  11. package/assets/controls/leaflet.es.js +1023 -1004
  12. package/assets/controls/toast-ui.es.js +10509 -10472
  13. package/assets/dashboard-CvSStqLV.js +3 -0
  14. package/assets/{history-B8KIDy44.js → history-RlFpGr4e.js} +1 -1
  15. package/assets/list-cNVyzYi8.js +4 -0
  16. package/assets/manifest.json +25 -25
  17. package/assets/{module-D59aE9uv.js → module-B_i1LQ3L.js} +1 -1
  18. package/assets/{notification-DNoyfNmT.js → notification-DXP7ACui.js} +1 -1
  19. package/assets/user-filters-list-DWE5MBBP.js +1 -0
  20. package/assets/{welcome-37rNVUHt.js → welcome-B6-atbAF.js} +1 -1
  21. package/controllers/catalog/FrontendCatalogAdapter.d.ts +1 -1
  22. package/controllers/catalog/FrontentCatalogAdapter.d.ts +1 -1
  23. package/controllers/feedback/feedbackController.d.ts +1 -1
  24. package/controllers/history-actions/HistoryController.d.ts +1 -1
  25. package/controllers/media-manager/mediaManagerAdapter.d.ts +1 -1
  26. package/helpers/accessRightsHelper.d.ts +3 -3
  27. package/helpers/configHelper.d.ts +3 -3
  28. package/helpers/configHelper.js +8 -1
  29. package/helpers/controllerHelper.d.ts +2 -2
  30. package/helpers/fieldsHelper.d.ts +2 -2
  31. package/helpers/filterDatetimeHelper.d.ts +1 -1
  32. package/helpers/inertiaActionsHelper.d.ts +2 -2
  33. package/helpers/inertiaAddHelper.d.ts +4 -4
  34. package/helpers/inertiaGroupHelper.d.ts +3 -3
  35. package/helpers/inertiaListHelper.d.ts +3 -3
  36. package/helpers/inertiaMenuHelper.d.ts +2 -2
  37. package/helpers/inertiaUserHelper.d.ts +3 -3
  38. package/helpers/menuHelper.d.ts +2 -2
  39. package/helpers/translationHelper.d.ts +2 -2
  40. package/index.d.ts +58 -57
  41. package/index.js +1 -0
  42. package/interfaces/adminpanelConfig.d.ts +4 -4
  43. package/interfaces/global.d.ts +6 -6
  44. package/interfaces/internalModelAccess.d.ts +1 -1
  45. package/interfaces/listQueryBuilder.d.ts +1 -1
  46. package/interfaces/types.d.ts +2 -2
  47. package/lib/Adminizer.d.ts +38 -26
  48. package/lib/Adminizer.js +19 -1
  49. package/lib/DataAccessor.d.ts +6 -6
  50. package/lib/DataAccessor.js +5 -1
  51. package/lib/MiddlewareManager.d.ts +1 -1
  52. package/lib/access-rights/AccessRightsHandler.d.ts +2 -2
  53. package/lib/ai-assistant/AbstractAiModelService.d.ts +2 -2
  54. package/lib/ai-assistant/AiAssistantHandler.d.ts +15 -5
  55. package/lib/ai-assistant/AiAssistantHandler.js +31 -1
  56. package/lib/app-manager/AdminizerApp.d.ts +10 -10
  57. package/lib/app-manager/AppManager.d.ts +2 -2
  58. package/lib/app-manager/AppManager.js +11 -8
  59. package/lib/app-manager/AssetHandler.d.ts +2 -2
  60. package/lib/app-manager/ConfigLayerHandler.d.ts +2 -2
  61. package/lib/app-manager/ControllerHandler.d.ts +2 -2
  62. package/lib/catalog/AbstractCatalog.d.ts +1 -1
  63. package/lib/catalog/CatalogHandler.d.ts +1 -1
  64. package/lib/controls/ControlsHandler.d.ts +1 -1
  65. package/lib/controls/codeEditor/MonacoEditor.d.ts +1 -1
  66. package/lib/controls/geojsoneditor/GeoEditor.d.ts +1 -1
  67. package/lib/controls/jsoneditor/JsonEditor.d.ts +1 -1
  68. package/lib/controls/markdown/ToastUiEditor.d.ts +1 -1
  69. package/lib/controls/table/Handsontable.d.ts +1 -1
  70. package/lib/controls/wysiwyg/CKeditor.d.ts +1 -1
  71. package/lib/feedback/FeedbackHandler.d.ts +2 -2
  72. package/lib/filters/ConditionValidator.d.ts +1 -1
  73. package/lib/filters/FilterCustomFieldHandler.d.ts +2 -2
  74. package/lib/filters/FilterService.d.ts +4 -4
  75. package/lib/filters/index.d.ts +6 -6
  76. package/lib/history-actions/AbstractHistoryAdapter.d.ts +6 -6
  77. package/lib/history-actions/DefaultHistoryAdapter.d.ts +4 -4
  78. package/lib/history-actions/HistoryHandler.d.ts +1 -1
  79. package/lib/list-query-builder/ListQueryBuilder.d.ts +7 -7
  80. package/lib/media-manager/AbstractMediaManager.d.ts +2 -2
  81. package/lib/media-manager/MediaManagerHandler.d.ts +1 -1
  82. package/lib/media-manager/Thumb.d.ts +1 -1
  83. package/lib/media-manager/helpers/MediaManagerHelper.d.ts +5 -5
  84. package/lib/model/AbstractModel.d.ts +9 -4
  85. package/lib/model/InternalModelAccessFactory.d.ts +2 -2
  86. package/lib/model/ModelHandler.d.ts +3 -3
  87. package/lib/model/adapter/sequelize.d.ts +7 -5
  88. package/lib/model/adapter/sequelize.js +79 -46
  89. package/lib/model/adapter/typeorm.d.ts +2 -2
  90. package/lib/model/adapter/typeorm.js +1 -1
  91. package/lib/model/internalModelRepository.d.ts +2 -2
  92. package/lib/notifications/AbstractNotificationService.d.ts +4 -4
  93. package/lib/notifications/GeneralNotificationService.d.ts +2 -2
  94. package/lib/notifications/GeneralNotificationService.js +5 -4
  95. package/lib/notifications/NotificationHandler.d.ts +2 -2
  96. package/lib/notifications/SystemNotificationService.d.ts +2 -2
  97. package/lib/requestProcessor.d.ts +1 -1
  98. package/lib/widgets/abstractAction.d.ts +1 -1
  99. package/lib/widgets/abstractCustom.d.ts +2 -2
  100. package/lib/widgets/abstractInfo.d.ts +1 -1
  101. package/lib/widgets/abstractLink.d.ts +2 -2
  102. package/lib/widgets/abstractSwitch.d.ts +1 -1
  103. package/lib/widgets/abstractWidgetBase.d.ts +1 -1
  104. package/lib/widgets/widgetHandler.d.ts +9 -9
  105. package/models/Filter.d.ts +1 -1
  106. package/models/FilterColumn.d.ts +1 -1
  107. package/models/Group.d.ts +1 -1
  108. package/models/HistoryActions.d.ts +1 -1
  109. package/models/MediaManagerAP.d.ts +2 -2
  110. package/models/MediaManagerAssociationsAP.d.ts +1 -1
  111. package/models/MediaManagerMetaAP.d.ts +1 -1
  112. package/models/User.d.ts +2 -2
  113. package/models/UserNotification.d.ts +1 -1
  114. package/package.json +1 -1
  115. package/services/FeedService.d.ts +3 -3
  116. package/system/Router.d.ts +1 -1
  117. package/system/Router.js +9 -1
  118. package/system/bindAccessRights.d.ts +1 -1
  119. package/system/bindAuthorization.d.ts +1 -1
  120. package/system/bindControls.d.ts +1 -1
  121. package/system/bindCors.d.ts +1 -1
  122. package/system/bindCustomFilterHandlers.d.ts +1 -1
  123. package/system/bindDashboardWidgets.d.ts +1 -1
  124. package/system/bindDev.d.ts +1 -1
  125. package/system/bindHistory.d.ts +1 -1
  126. package/system/bindInertia.d.ts +1 -1
  127. package/system/bindMediaManager.d.ts +1 -1
  128. package/system/bindNotifications.d.ts +1 -1
  129. package/system/bindReqFunctions.d.ts +1 -1
  130. package/system/bindTranslations.d.ts +1 -1
  131. package/system/buildInternalModelAccess.d.ts +3 -3
  132. package/system/defaults.d.ts +1 -1
  133. package/system/routePolicies.d.ts +1 -1
  134. package/system/systemModelContracts.d.ts +1 -1
  135. package/system/systemModelContracts.js +11 -7
  136. package/system/validateSystemModels.d.ts +1 -1
  137. package/assets/add-user-B4SVJT5P.js +0 -1
  138. package/assets/app-CtWuWD5N.css +0 -1
  139. package/assets/catalog-ByUICd5z.js +0 -6
  140. package/assets/dashboard-BYd8G2cW.js +0 -3
  141. package/assets/list-ChmtBGjG.js +0 -4
  142. package/assets/user-filters-list-BMFRwkYF.js +0 -1
@@ -1,5 +1,5 @@
1
- import { Adminizer } from '../Adminizer';
2
- import { AbstractFeedbackHandler } from './AbstractFeedbackHandler';
1
+ import { Adminizer } from '../Adminizer.js';
2
+ import { AbstractFeedbackHandler } from './AbstractFeedbackHandler.js';
3
3
  export declare class FeedbackHandler {
4
4
  private handler;
5
5
  private adminizer;
@@ -1,4 +1,4 @@
1
- import { FilterCondition, FilterOperator } from '../../models/Filter';
1
+ import { FilterCondition, FilterOperator } from '../../models/Filter.js';
2
2
  /**
3
3
  * Security event types for logging suspicious filter attempts
4
4
  */
@@ -1,2 +1,2 @@
1
- export * from './CustomFilterHandler';
2
- export { default } from './CustomFilterHandler';
1
+ export * from './CustomFilterHandler.js';
2
+ export { default } from './CustomFilterHandler.js';
@@ -1,7 +1,7 @@
1
- import { Adminizer } from '../Adminizer';
2
- import { Filter } from '../../models/Filter';
3
- import { FilterColumn } from '../../models/FilterColumn';
4
- import { User } from '../../models/User';
1
+ import { Adminizer } from '../Adminizer.js';
2
+ import { Filter } from '../../models/Filter.js';
3
+ import { FilterColumn } from '../../models/FilterColumn.js';
4
+ import { User } from '../../models/User.js';
5
5
  /**
6
6
  * FilterService - manages filter operations
7
7
  *
@@ -1,6 +1,6 @@
1
- export { FilterService, default as FilterServiceDefault } from './FilterService';
2
- export { CustomFilterHandler, default as CustomFilterHandlerDefault } from './CustomFilterHandler';
3
- export { AbstractCustomFilter } from './CustomFilterHandler';
4
- export type { FilterCustomFieldCondition, RegisterOptions, FilterCustomFieldInputConfig, FilterCustomFieldInputDefinition, FilterCustomFieldInputType } from './CustomFilterHandler';
5
- export { ConditionValidator, default as ConditionValidatorDefault } from './ConditionValidator';
6
- export type { ValidationResult, ValidationError, FieldConfig, SecurityEvent, SecurityEventType } from './ConditionValidator';
1
+ export { FilterService, default as FilterServiceDefault } from './FilterService.js';
2
+ export { CustomFilterHandler, default as CustomFilterHandlerDefault } from './CustomFilterHandler.js';
3
+ export { AbstractCustomFilter } from './CustomFilterHandler.js';
4
+ export type { FilterCustomFieldCondition, RegisterOptions, FilterCustomFieldInputConfig, FilterCustomFieldInputDefinition, FilterCustomFieldInputType } from './CustomFilterHandler.js';
5
+ export { ConditionValidator, default as ConditionValidatorDefault } from './ConditionValidator.js';
6
+ export type { ValidationResult, ValidationError, FieldConfig, SecurityEvent, SecurityEventType } from './ConditionValidator.js';
@@ -1,9 +1,9 @@
1
- import { HistoryActions } from "../../models/HistoryActions";
2
- import { User } from "../../models/User";
3
- import { Adminizer } from "../Adminizer";
4
- import { Fields } from "../../helpers/fieldsHelper";
5
- import { ActionType } from "../../interfaces/adminpanelConfig";
6
- import { ModelResource } from "../../interfaces/types";
1
+ import { HistoryActions } from "../../models/HistoryActions.js";
2
+ import { User } from "../../models/User.js";
3
+ import { Adminizer } from "../Adminizer.js";
4
+ import { Fields } from "../../helpers/fieldsHelper.js";
5
+ import { ActionType } from "../../interfaces/adminpanelConfig.js";
6
+ import { ModelResource } from "../../interfaces/types.js";
7
7
  /**
8
8
  * Abstract base class for handling history operations in the AdminPanel.
9
9
  * Provides common methods and structure for retrieving, filtering, and formatting historical data.
@@ -1,7 +1,7 @@
1
- import { HistoryActions } from "../../models/HistoryActions";
2
- import { User } from "../../models/User";
3
- import { Adminizer } from "../Adminizer";
4
- import { AbstractHistoryAdapter } from "./AbstractHistoryAdapter";
1
+ import { HistoryActions } from "../../models/HistoryActions.js";
2
+ import { User } from "../../models/User.js";
3
+ import { Adminizer } from "../Adminizer.js";
4
+ import { AbstractHistoryAdapter } from "./AbstractHistoryAdapter.js";
5
5
  export declare class DefaultHistoryAdapter extends AbstractHistoryAdapter {
6
6
  id: string;
7
7
  model: string;
@@ -1,4 +1,4 @@
1
- import { AbstractHistoryAdapter } from "./AbstractHistoryAdapter";
1
+ import { AbstractHistoryAdapter } from "./AbstractHistoryAdapter.js";
2
2
  export declare class HistoryHandler {
3
3
  private adapters;
4
4
  add(adapter: AbstractHistoryAdapter): void;
@@ -1,10 +1,10 @@
1
- import { Fields } from '../../helpers/fieldsHelper';
2
- import { AbstractModel } from '../model/AbstractModel';
3
- import { DataAccessor } from '../DataAccessor';
4
- import { FilterOperator } from '../../models/Filter';
5
- import { CustomFilterHandler } from '../filters/CustomFilterHandler';
6
- import { ListQueryBuilderParams, ListQueryBuilderResult } from '../../interfaces/listQueryBuilder';
7
- import { CriteriaWhere } from '../../interfaces/queryCriteria';
1
+ import { Fields } from '../../helpers/fieldsHelper.js';
2
+ import { AbstractModel } from '../model/AbstractModel.js';
3
+ import { DataAccessor } from '../DataAccessor.js';
4
+ import { FilterOperator } from '../../models/Filter.js';
5
+ import { CustomFilterHandler } from '../filters/CustomFilterHandler.js';
6
+ import { ListQueryBuilderParams, ListQueryBuilderResult } from '../../interfaces/listQueryBuilder.js';
7
+ import { CriteriaWhere } from '../../interfaces/queryCriteria.js';
8
8
  /**
9
9
  * Security limits for filter conditions
10
10
  */
@@ -1,5 +1,5 @@
1
- import type { MediaManagerMetaAP } from "../../models/MediaManagerMetaAP";
2
- import { Adminizer } from "../Adminizer";
1
+ import type { MediaManagerMetaAP } from "../../models/MediaManagerMetaAP.js";
2
+ import { Adminizer } from "../Adminizer.js";
3
3
  export interface MediaManagerItem {
4
4
  id?: string;
5
5
  parent: string | null;
@@ -1,4 +1,4 @@
1
- import { AbstractMediaManager } from "./AbstractMediaManager";
1
+ import { AbstractMediaManager } from "./AbstractMediaManager.js";
2
2
  export declare class MediaManagerHandler {
3
3
  private managers;
4
4
  add(manager: AbstractMediaManager): void;
@@ -1,4 +1,4 @@
1
- import { Adminizer } from "../Adminizer";
1
+ import { Adminizer } from "../Adminizer.js";
2
2
  export declare class MediaManagerThumb {
3
3
  static getThumb(id: string, managerId: string, adminizer: Adminizer): Promise<NonSharedBuffer>;
4
4
  }
@@ -1,8 +1,8 @@
1
- import { Fields } from "../../../helpers/fieldsHelper";
2
- import { MediaManagerWidgetData, MediaManagerItem, MediaManagerWidgetItem, MediaManagerWidgetJSON } from "../AbstractMediaManager";
3
- import { BaseFieldConfig } from "../../../interfaces/adminpanelConfig";
4
- import { Adminizer } from "../../Adminizer";
5
- import type { AppRuntime } from "../../app-manager/AdminizerApp";
1
+ import { Fields } from "../../../helpers/fieldsHelper.js";
2
+ import { MediaManagerWidgetData, MediaManagerItem, MediaManagerWidgetItem, MediaManagerWidgetJSON } from "../AbstractMediaManager.js";
3
+ import { BaseFieldConfig } from "../../../interfaces/adminpanelConfig.js";
4
+ import { Adminizer } from "../../Adminizer.js";
5
+ import type { AppRuntime } from "../../app-manager/AdminizerApp.js";
6
6
  type PostParams = Record<string, string | number | boolean | object | string[] | number[] | null>;
7
7
  export declare function isMediaManagerFieldConfig(fieldConfig: BaseFieldConfig): boolean;
8
8
  export declare function normalizeMediaManagerWidgetData(value: PostParams[string] | undefined, prop: string): MediaManagerWidgetData[];
@@ -1,8 +1,13 @@
1
- import { DataAccessor } from "../DataAccessor";
2
- import { QueryCriteria } from "../../interfaces/queryCriteria";
3
- import { InternalModelRepository } from "../../interfaces/internalModelAccess";
1
+ import { DataAccessor } from "../DataAccessor.js";
2
+ import { QueryCriteria } from "../../interfaces/queryCriteria.js";
3
+ import { InternalModelRepository } from "../../interfaces/internalModelAccess.js";
4
4
  export interface Attribute {
5
- type: 'association' | 'association-many' | 'number' | 'json' | 'string' | 'boolean' | 'ref';
5
+ /**
6
+ * `date` covers every temporal column (date, time, timestamp). It is deliberately
7
+ * separate from `string`: dates must not take part in LIKE search, and the UI
8
+ * renders them with date controls.
9
+ */
10
+ type: 'association' | 'association-many' | 'number' | 'json' | 'string' | 'boolean' | 'date' | 'ref';
6
11
  required?: boolean;
7
12
  unique?: boolean;
8
13
  defaultsTo?: any;
@@ -1,5 +1,5 @@
1
- import { InternalModelAccessMap, InternalModelRepository } from "../../interfaces/internalModelAccess";
2
- import { AbstractModel } from "./AbstractModel";
1
+ import { InternalModelAccessMap, InternalModelRepository } from "../../interfaces/internalModelAccess.js";
2
+ import { AbstractModel } from "./AbstractModel.js";
3
3
  export declare const DEFAULT_INTERNAL_MODEL_ACCESS: InternalModelAccessMap;
4
4
  export declare class InternalModelScope {
5
5
  private readonly getModel;
@@ -1,6 +1,6 @@
1
- import { AbstractModel } from "./AbstractModel";
2
- import { InternalModelAccessMap, InternalModelRepository } from "../../interfaces/internalModelAccess";
3
- import { InternalModelScope } from "./InternalModelAccessFactory";
1
+ import { AbstractModel } from "./AbstractModel.js";
2
+ import { InternalModelAccessMap, InternalModelRepository } from "../../interfaces/internalModelAccess.js";
3
+ import { InternalModelScope } from "./InternalModelAccessFactory.js";
4
4
  export interface AppModelAccessRecord {
5
5
  id: string;
6
6
  appName: string;
@@ -1,9 +1,11 @@
1
- import { Sequelize, ModelStatic } from "sequelize";
2
- import { AbstractAdapter, AbstractAdapterOptions, AbstractModel, Attribute } from "../AbstractModel";
3
- import { QueryCriteria } from "../../../interfaces/queryCriteria";
1
+ import type { ModelStatic, Sequelize as SequelizeType } from "sequelize";
2
+ import { AbstractAdapter, AbstractAdapterOptions, AbstractModel, Attribute } from "../AbstractModel.js";
3
+ import { QueryCriteria } from "../../../interfaces/queryCriteria.js";
4
4
  export declare function mapSequelizeToAdminizerAttributes(model: ModelStatic<any>): Record<string, Attribute>;
5
5
  export declare class SequelizeModel<T> extends AbstractModel<T> {
6
6
  private model;
7
+ private _init;
8
+ private _ensure;
7
9
  constructor(modelName: string, model: ModelStatic<any>);
8
10
  private _buildJsonContainsCondition;
9
11
  _convertCriteriaToSequelize(criteria: any): any;
@@ -45,9 +47,9 @@ export declare class SequelizeModel<T> extends AbstractModel<T> {
45
47
  private _buildCriteriaIncludes;
46
48
  }
47
49
  export declare class SequelizeAdapter extends AbstractAdapter {
48
- sequelize: Sequelize;
50
+ sequelize: SequelizeType;
49
51
  Model: typeof SequelizeModel;
50
- constructor(sequelize: Sequelize, options?: AbstractAdapterOptions);
52
+ constructor(sequelize: SequelizeType, options?: AbstractAdapterOptions);
51
53
  get models(): Record<string, any>;
52
54
  getModel(modelName: string): any;
53
55
  getAttributes(modelName: string): any;
@@ -1,5 +1,16 @@
1
- import { Sequelize, Op, HasMany } from "sequelize";
2
1
  import { AbstractAdapter, AbstractModel } from "../AbstractModel.js";
2
+ let _Sequelize = null;
3
+ let _Op = null;
4
+ let _HasMany = null;
5
+ async function ensureSequelize() {
6
+ if (_Sequelize)
7
+ return _Sequelize;
8
+ const sequelize = await import('sequelize');
9
+ _Sequelize = sequelize.Sequelize;
10
+ _Op = sequelize.Op;
11
+ _HasMany = sequelize.HasMany;
12
+ return _Sequelize;
13
+ }
3
14
  function resolveType(type) {
4
15
  const sqlType = typeof type.toString === "function"
5
16
  ? type.toString().toLowerCase()
@@ -17,8 +28,10 @@ function resolveType(type) {
17
28
  return "number";
18
29
  if (sqlType.includes("json"))
19
30
  return "json";
20
- if (sqlType.includes("date"))
21
- return "string";
31
+ // Sequelize renders temporal types per dialect: sqlite gives DATETIME/DATE,
32
+ // postgres TIMESTAMP WITH TIME ZONE, mysql DATETIME/TIMESTAMP. Match all of them.
33
+ if (sqlType.includes("date") || sqlType.includes("time"))
34
+ return "date";
22
35
  return "ref";
23
36
  }
24
37
  export function mapSequelizeToAdminizerAttributes(model) {
@@ -92,6 +105,13 @@ function capitalize(str) {
92
105
  }
93
106
  export class SequelizeModel extends AbstractModel {
94
107
  model;
108
+ _init = false;
109
+ async _ensure() {
110
+ if (!this._init) {
111
+ await ensureSequelize();
112
+ this._init = true;
113
+ }
114
+ }
95
115
  constructor(modelName, model) {
96
116
  super(modelName, mapSequelizeToAdminizerAttributes(model), model.primaryKeyAttribute, model.name);
97
117
  this.model = model;
@@ -100,7 +120,7 @@ export class SequelizeModel extends AbstractModel {
100
120
  const pattern = `%${JSON.stringify(item).replace(/[%_]/g, "\\$&")}%`;
101
121
  const attribute = this.model.rawAttributes?.[targetKey];
102
122
  const columnName = typeof attribute?.field === "string" ? attribute.field : targetKey;
103
- return Sequelize.where(Sequelize.cast(Sequelize.col(`${this.model.name}.${columnName}`), "TEXT"), { [Op.like]: pattern });
123
+ return _Sequelize.where(_Sequelize.cast(_Sequelize.col(`${this.model.name}.${columnName}`), "TEXT"), { [_Op.like]: pattern });
104
124
  }
105
125
  _convertCriteriaToSequelize(criteria) {
106
126
  // Special handling for Sequelize.literal() at the top level
@@ -135,24 +155,24 @@ export class SequelizeModel extends AbstractModel {
135
155
  }
136
156
  // Special handling for null values (IS NULL condition)
137
157
  if (value === null) {
138
- result[targetKey] = { [Op.is]: null };
158
+ result[targetKey] = { [_Op.is]: null };
139
159
  continue;
140
160
  }
141
161
  // 🔹 Handle Sequelize Op operators (already in Sequelize format)
142
- if (key === Op.and || key === 'and') {
143
- result[Op.and] = Array.isArray(value)
162
+ if (key === _Op.and || key === 'and') {
163
+ result[_Op.and] = Array.isArray(value)
144
164
  ? value.map((item) => this._convertCriteriaToSequelize(item))
145
165
  : [];
146
166
  continue;
147
167
  }
148
- if (key === Op.or || key === 'or') {
149
- result[Op.or] = Array.isArray(value)
168
+ if (key === _Op.or || key === 'or') {
169
+ result[_Op.or] = Array.isArray(value)
150
170
  ? value.map((item) => this._convertCriteriaToSequelize(item))
151
171
  : [];
152
172
  continue;
153
173
  }
154
- if (key === Op.not || key === 'not' || key === '$not') {
155
- result[Op.not] = this._convertCriteriaToSequelize(value);
174
+ if (key === _Op.not || key === 'not' || key === '$not') {
175
+ result[_Op.not] = this._convertCriteriaToSequelize(value);
156
176
  continue;
157
177
  }
158
178
  // Skip Symbol keys that are not handled above (should not happen, but safety check)
@@ -161,7 +181,7 @@ export class SequelizeModel extends AbstractModel {
161
181
  }
162
182
  if (Array.isArray(value)) {
163
183
  // ✅ Array processing - use the IN operator
164
- result[targetKey] = { [Op.in]: value };
184
+ result[targetKey] = { [_Op.in]: value };
165
185
  }
166
186
  else if (typeof value === "object" && !Array.isArray(value)) {
167
187
  // Check if value already contains Sequelize Op operators
@@ -171,10 +191,10 @@ export class SequelizeModel extends AbstractModel {
171
191
  // Helper function to check if a symbol/op is a Sequelize operator
172
192
  const isSequelizeOp = (op) => {
173
193
  // Check direct Symbol equality first
174
- if (op === Op.gt || op === Op.gte || op === Op.lt || op === Op.lte ||
175
- op === Op.eq || op === Op.ne || op === Op.in || op === Op.notIn ||
176
- op === Op.like || op === Op.iLike || op === Op.between ||
177
- op === Op.startsWith || op === Op.endsWith || op === Op.is || op === Op.not) {
194
+ if (op === _Op.gt || op === _Op.gte || op === _Op.lt || op === _Op.lte ||
195
+ op === _Op.eq || op === _Op.ne || op === _Op.in || op === _Op.notIn ||
196
+ op === _Op.like || op === _Op.iLike || op === _Op.between ||
197
+ op === _Op.startsWith || op === _Op.endsWith || op === _Op.is || op === _Op.not) {
178
198
  return true;
179
199
  }
180
200
  // Fallback: check by Symbol description (handles different Symbol instances)
@@ -204,22 +224,22 @@ export class SequelizeModel extends AbstractModel {
204
224
  continue;
205
225
  switch (op) {
206
226
  case "eq":
207
- result[targetKey] = { [Op.eq]: val };
227
+ result[targetKey] = { [_Op.eq]: val };
208
228
  break;
209
229
  case "ne":
210
- result[targetKey] = { [Op.ne]: val };
230
+ result[targetKey] = { [_Op.ne]: val };
211
231
  break;
212
232
  case "gt":
213
- result[targetKey] = { [Op.gt]: val };
233
+ result[targetKey] = { [_Op.gt]: val };
214
234
  break;
215
235
  case "gte":
216
- result[targetKey] = { [Op.gte]: val };
236
+ result[targetKey] = { [_Op.gte]: val };
217
237
  break;
218
238
  case "lt":
219
- result[targetKey] = { [Op.lt]: val };
239
+ result[targetKey] = { [_Op.lt]: val };
220
240
  break;
221
241
  case "lte":
222
- result[targetKey] = { [Op.lte]: val };
242
+ result[targetKey] = { [_Op.lte]: val };
223
243
  break;
224
244
  case "contains":
225
245
  // Check if field is a date/datetime type
@@ -242,83 +262,83 @@ export class SequelizeModel extends AbstractModel {
242
262
  }
243
263
  else {
244
264
  // Valid date - use exact match
245
- result[targetKey] = { [Op.eq]: dateValue };
265
+ result[targetKey] = { [_Op.eq]: dateValue };
246
266
  }
247
267
  }
248
268
  else {
249
269
  // For time fields and non-date fields - use Op.like with wildcards
250
- result[targetKey] = { [Op.like]: `%${val}%` };
270
+ result[targetKey] = { [_Op.like]: `%${val}%` };
251
271
  }
252
272
  break;
253
273
  case "startsWith":
254
- result[targetKey] = { [Op.startsWith]: val };
274
+ result[targetKey] = { [_Op.startsWith]: val };
255
275
  break;
256
276
  case "endsWith":
257
- result[targetKey] = { [Op.endsWith]: val };
277
+ result[targetKey] = { [_Op.endsWith]: val };
258
278
  break;
259
279
  case ">":
260
- result[targetKey] = { [Op.gt]: val };
280
+ result[targetKey] = { [_Op.gt]: val };
261
281
  break;
262
282
  case ">=":
263
- result[targetKey] = { [Op.gte]: val };
283
+ result[targetKey] = { [_Op.gte]: val };
264
284
  break;
265
285
  case "<":
266
- result[targetKey] = { [Op.lt]: val };
286
+ result[targetKey] = { [_Op.lt]: val };
267
287
  break;
268
288
  case "<=":
269
- result[targetKey] = { [Op.lte]: val };
289
+ result[targetKey] = { [_Op.lte]: val };
270
290
  break;
271
291
  case "!=":
272
- result[targetKey] = { [Op.ne]: val };
292
+ result[targetKey] = { [_Op.ne]: val };
273
293
  break;
274
294
  case "in":
275
- result[targetKey] = { [Op.in]: val };
295
+ result[targetKey] = { [_Op.in]: val };
276
296
  break;
277
297
  case "notIn":
278
- result[targetKey] = { [Op.notIn]: val };
298
+ result[targetKey] = { [_Op.notIn]: val };
279
299
  break;
280
300
  case "nin":
281
- result[targetKey] = { [Op.notIn]: val };
301
+ result[targetKey] = { [_Op.notIn]: val };
282
302
  break;
283
303
  case "between":
284
- result[targetKey] = { [Op.between]: val };
304
+ result[targetKey] = { [_Op.between]: val };
285
305
  break;
286
306
  case "isNull":
287
307
  if (val) {
288
- result[targetKey] = { [Op.is]: null };
308
+ result[targetKey] = { [_Op.is]: null };
289
309
  }
290
310
  break;
291
311
  case "isNotNull":
292
312
  if (val) {
293
- result[targetKey] = { [Op.not]: null };
313
+ result[targetKey] = { [_Op.not]: null };
294
314
  }
295
315
  break;
296
316
  case "regex":
297
- result[targetKey] = { [Op.regexp]: val };
317
+ result[targetKey] = { [_Op.regexp]: val };
298
318
  break;
299
319
  case "jsonContains": {
300
320
  const values = Array.isArray(val) ? val : [val];
301
321
  const clauses = values.map((item) => this._buildJsonContainsCondition(targetKey, item));
302
- result[Op.and] = [
303
- ...(result[Op.and] ?? []),
322
+ result[_Op.and] = [
323
+ ...(result[_Op.and] ?? []),
304
324
  ...clauses
305
325
  ];
306
326
  break;
307
327
  }
308
328
  case "$is":
309
- result[targetKey] = { [Op.is]: val };
329
+ result[targetKey] = { [_Op.is]: val };
310
330
  break;
311
331
  case "$not":
312
- result[targetKey] = { [Op.not]: val };
332
+ result[targetKey] = { [_Op.not]: val };
313
333
  break;
314
334
  case "$ne":
315
- result[targetKey] = { [Op.ne]: val };
335
+ result[targetKey] = { [_Op.ne]: val };
316
336
  break;
317
337
  case "not":
318
- result[targetKey] = { [Op.not]: val };
338
+ result[targetKey] = { [_Op.not]: val };
319
339
  break;
320
340
  default:
321
- result[targetKey] = { [Op.eq]: val };
341
+ result[targetKey] = { [_Op.eq]: val };
322
342
  }
323
343
  }
324
344
  }
@@ -401,6 +421,7 @@ export class SequelizeModel extends AbstractModel {
401
421
  }
402
422
  // --- CREATE ---
403
423
  async _create(data) {
424
+ await this._ensure();
404
425
  // console.clear()
405
426
  const assocNames = Object.keys(this.model.associations);
406
427
  const plainData = {};
@@ -472,6 +493,7 @@ export class SequelizeModel extends AbstractModel {
472
493
  }
473
494
  // --- FIND ONE ---
474
495
  async _findOne(criteria) {
496
+ await this._ensure();
475
497
  // console.debug(">> _findOne: input criteria:", criteria);
476
498
  const { where, attributes } = this._convertAdminizerCriteriaToSequelizeOptions(criteria);
477
499
  const includes = criteria.populate
@@ -498,6 +520,7 @@ export class SequelizeModel extends AbstractModel {
498
520
  }
499
521
  // --- FIND MANY ---
500
522
  async _find(criteria = {}) {
523
+ await this._ensure();
501
524
  const assocNames = Object.keys(this.model.associations);
502
525
  // console.debug(">> _find: input criteria:", criteria, "options:", options);
503
526
  const { where, limit, offset, order, attributes } = this._convertAdminizerCriteriaToSequelizeOptions(criteria);
@@ -553,6 +576,7 @@ export class SequelizeModel extends AbstractModel {
553
576
  * Bypasses Adminizer criteria conversion for direct Sequelize usage
554
577
  */
555
578
  async findWithRawWhere(where, options = {}) {
579
+ await this._ensure();
556
580
  const assocNames = Object.keys(this.model.associations);
557
581
  const includes = options.populate !== false
558
582
  ? assocNames.map(a => ({ association: a }))
@@ -570,6 +594,7 @@ export class SequelizeModel extends AbstractModel {
570
594
  * Public method for count with raw SQL where clauses
571
595
  */
572
596
  async countWithRawWhere(where) {
597
+ await this._ensure();
573
598
  const assocNames = Object.keys(this.model.associations);
574
599
  const include = assocNames.map((association) => ({ association }));
575
600
  return await this.model.count({
@@ -581,6 +606,7 @@ export class SequelizeModel extends AbstractModel {
581
606
  }
582
607
  // --- UPDATE ONE ---
583
608
  async _updateOne(criteria, data) {
609
+ await this._ensure();
584
610
  const { where } = this._convertAdminizerCriteriaToSequelizeOptions(criteria);
585
611
  const record = await this.model.findOne({ where });
586
612
  if (!record)
@@ -612,6 +638,7 @@ export class SequelizeModel extends AbstractModel {
612
638
  }
613
639
  // --- UPDATE MANY ---
614
640
  async _update(criteria, data) {
641
+ await this._ensure();
615
642
  const { where } = this._convertAdminizerCriteriaToSequelizeOptions(criteria);
616
643
  const assocNames = Object.keys(this.model.associations);
617
644
  const plainData = {};
@@ -646,6 +673,7 @@ export class SequelizeModel extends AbstractModel {
646
673
  }
647
674
  // --- DESTROY ONE ---
648
675
  async _destroyOne(criteria) {
676
+ await this._ensure();
649
677
  const { where } = this._convertAdminizerCriteriaToSequelizeOptions(criteria);
650
678
  const record = await this.model.findOne({ where });
651
679
  if (!record)
@@ -681,6 +709,7 @@ export class SequelizeModel extends AbstractModel {
681
709
  }
682
710
  // --- DESTROY MANY ---
683
711
  async _destroy(criteria) {
712
+ await this._ensure();
684
713
  const { where } = this._convertAdminizerCriteriaToSequelizeOptions(criteria);
685
714
  const records = await this.model.findAll({ where });
686
715
  const assocNames = Object.keys(this.model.associations);
@@ -785,7 +814,7 @@ export class SequelizeModel extends AbstractModel {
785
814
  }
786
815
  const association = this.model.associations[alias];
787
816
  const isUsedInWhere = usedRelationAliases.has(alias);
788
- const isHasMany = association instanceof HasMany || association?.associationType === 'HasMany';
817
+ const isHasMany = association instanceof _HasMany || association?.associationType === 'HasMany';
789
818
  // When filtering by relation path ($alias.field$), extra joined hasMany associations
790
819
  // can duplicate base rows and break page size. Load such associations separately.
791
820
  if (isHasMany && !isUsedInWhere) {
@@ -841,10 +870,14 @@ export class SequelizeAdapter extends AbstractAdapter {
841
870
  sequelize;
842
871
  Model = SequelizeModel;
843
872
  constructor(sequelize, options = {}) {
873
+ ensureSequelize();
844
874
  super("sequelize", sequelize, options);
875
+ // Note: ensureSequelize is fire-and-forget during construction
876
+ // Methods also call this._ensure() to guarantee initialization
845
877
  this.sequelize = sequelize;
846
878
  }
847
879
  get models() {
880
+ ``;
848
881
  return this.sequelize.models;
849
882
  }
850
883
  getModel(modelName) {
@@ -1,6 +1,6 @@
1
1
  import { DataSource, EntityMetadata, EntitySchema, ObjectLiteral } from "typeorm";
2
- import { AbstractAdapter, AbstractAdapterOptions, AbstractModel, ModelAttributes } from "../AbstractModel";
3
- import { QueryCriteria } from "../../../interfaces/queryCriteria";
2
+ import { AbstractAdapter, AbstractAdapterOptions, AbstractModel, ModelAttributes } from "../AbstractModel.js";
3
+ import { QueryCriteria } from "../../../interfaces/queryCriteria.js";
4
4
  /**
5
5
  * Experimental TypeORM adapter.
6
6
  *
@@ -24,7 +24,7 @@ function resolveAdminizerTypeFromColumn(column) {
24
24
  if (type.includes("json"))
25
25
  return "json";
26
26
  if (type.includes("date") || type.includes("time"))
27
- return "string";
27
+ return "date";
28
28
  if (type.includes("char") || type.includes("text") || type.includes("uuid") || type.includes("string")) {
29
29
  return "string";
30
30
  }
@@ -1,3 +1,3 @@
1
- import { InternalModelRepository } from "../../interfaces/internalModelAccess";
2
- import { AbstractModel } from "./AbstractModel";
1
+ import { InternalModelRepository } from "../../interfaces/internalModelAccess.js";
2
+ import { AbstractModel } from "./AbstractModel.js";
3
3
  export declare function createInternalModelRepository<T>(modelName: string, model: AbstractModel<T>): InternalModelRepository<T>;
@@ -1,8 +1,8 @@
1
1
  import { EventEmitter } from 'events';
2
- import { Adminizer } from '../Adminizer';
3
- import { INotification, INotificationEvent } from '../../interfaces/types';
4
- import { NotificationModel } from "../../models/Notification";
5
- import { User } from "../../models/User";
2
+ import { Adminizer } from '../Adminizer.js';
3
+ import { INotification, INotificationEvent } from '../../interfaces/types.js';
4
+ import { NotificationModel } from "../../models/Notification.js";
5
+ import { User } from "../../models/User.js";
6
6
  /**
7
7
  * ░█████╗░██████╗░░██████╗████████╗██████╗░░█████╗░░█████╗░████████╗
8
8
  * ██╔══██╗██╔══██╗██╔════╝╚══██╔══╝██╔══██╗██╔══██╗██╔══██╗╚══██╔══╝
@@ -1,5 +1,5 @@
1
- import { AbstractNotificationService } from './AbstractNotificationService';
2
- import { INotification } from '../../interfaces/types';
1
+ import { AbstractNotificationService } from './AbstractNotificationService.js';
2
+ import { INotification } from '../../interfaces/types.js';
3
3
  export declare class GeneralNotificationService extends AbstractNotificationService {
4
4
  readonly notificationClass = "general";
5
5
  readonly displayName: string;
@@ -6,16 +6,17 @@ export class GeneralNotificationService extends AbstractNotificationService {
6
6
  icon = 'info';
7
7
  iconColor = '#5987de';
8
8
  async dispatchNotification(notification) {
9
+ const { userId, ...notificationData } = notification;
9
10
  const fullNotification = {
10
- ...notification,
11
+ ...notificationData,
11
12
  notificationClass: this.notificationClass
12
13
  };
13
14
  let notificationDB;
14
15
  try {
15
16
  notificationDB = await this.notificationModel().create(fullNotification);
16
- if (notification.userId) {
17
+ if (userId) {
17
18
  // For specific user
18
- await this.createUserNotification(notificationDB.id, notification.userId);
19
+ await this.createUserNotification(notificationDB.id, userId);
19
20
  }
20
21
  else {
21
22
  // For all users
@@ -45,7 +46,7 @@ export class GeneralNotificationService extends AbstractNotificationService {
45
46
  },
46
47
  },
47
48
  notificationClass: this.notificationClass,
48
- userId: notification.userId ?? null
49
+ userId: userId ?? null
49
50
  };
50
51
  this.broadcast(event);
51
52
  Adminizer.log.info(`[General] Notification dispatched: ${fullNotification.title}`);