@memberjunction/global 2.115.0 → 2.117.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/warningManager.d.ts +126 -0
- package/dist/warningManager.d.ts.map +1 -0
- package/dist/warningManager.js +373 -0
- package/dist/warningManager.js.map +1 -0
- package/package.json +1 -1
- package/readme.md +105 -0
package/dist/index.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ export * from './util/PatternUtils';
|
|
|
9
9
|
export * from './ValidationTypes';
|
|
10
10
|
export * from './JSONValidator';
|
|
11
11
|
export * from './SafeExpressionEvaluator';
|
|
12
|
+
export * from './warningManager';
|
|
12
13
|
export * from './Global';
|
|
13
14
|
export * from './RegisterClass';
|
|
14
15
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAChE,cAAc,aAAa,CAAA;AAC3B,cAAc,QAAQ,CAAA;AACtB,cAAc,eAAe,CAAA;AAC7B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,YAAY,CAAA;AAC1B,cAAc,cAAc,CAAA;AAC5B,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAA;AACjC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,2BAA2B,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAA;AAChE,cAAc,aAAa,CAAA;AAC3B,cAAc,QAAQ,CAAA;AACtB,cAAc,eAAe,CAAA;AAC7B,cAAc,iBAAiB,CAAA;AAC/B,cAAc,YAAY,CAAA;AAC1B,cAAc,cAAc,CAAA;AAC5B,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAA;AACjC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,2BAA2B,CAAA;AACzC,cAAc,kBAAkB,CAAA;AAGhC,cAAc,UAAU,CAAA;AACxB,cAAc,iBAAiB,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -29,6 +29,7 @@ __exportStar(require("./util/PatternUtils"), exports);
|
|
|
29
29
|
__exportStar(require("./ValidationTypes"), exports);
|
|
30
30
|
__exportStar(require("./JSONValidator"), exports);
|
|
31
31
|
__exportStar(require("./SafeExpressionEvaluator"), exports);
|
|
32
|
+
__exportStar(require("./warningManager"), exports);
|
|
32
33
|
// Export the main classes
|
|
33
34
|
__exportStar(require("./Global"), exports);
|
|
34
35
|
__exportStar(require("./RegisterClass"), exports);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,iCAAiC;AACjC,+CAAgE;AAAvD,4GAAA,YAAY,OAAA;AAAE,iHAAA,iBAAiB,OAAA;AACxC,8CAA2B;AAC3B,yCAAsB;AACtB,gDAA6B;AAC7B,kDAA+B;AAC/B,6CAA0B;AAC1B,+CAA4B;AAC5B,sDAAoC;AACpC,oDAAiC;AACjC,kDAA+B;AAC/B,4DAAyC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,iCAAiC;AACjC,+CAAgE;AAAvD,4GAAA,YAAY,OAAA;AAAE,iHAAA,iBAAiB,OAAA;AACxC,8CAA2B;AAC3B,yCAAsB;AACtB,gDAA6B;AAC7B,kDAA+B;AAC/B,6CAA0B;AAC1B,+CAA4B;AAC5B,sDAAoC;AACpC,oDAAiC;AACjC,kDAA+B;AAC/B,4DAAyC;AACzC,mDAAgC;AAEhC,0BAA0B;AAC1B,2CAAwB;AACxB,kDAA+B"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Manages various types of warnings across the MemberJunction system.
|
|
3
|
+
*
|
|
4
|
+
* Features:
|
|
5
|
+
* - Session-level tracking: Each warning shown once per session
|
|
6
|
+
* - Debounced output: Groups warnings and displays after a quiet period
|
|
7
|
+
* - Formatted output: Tree-structured, grouped by entity and warning type
|
|
8
|
+
* - Configurable: Control debounce timing and behavior via options
|
|
9
|
+
* - Multiple warning types: Deprecation, field-not-found, and extensible for more
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* const wm = WarningManager.Instance;
|
|
14
|
+
* wm.RecordEntityDeprecationWarning('User Preferences', 'BaseEntity::constructor');
|
|
15
|
+
* wm.RecordFieldDeprecationWarning('AI Prompts', 'OldField', 'AIPromptEntity::validate');
|
|
16
|
+
* wm.RecordFieldNotFoundWarning('Users', 'DeletedColumn', 'BaseEntity::SetMany');
|
|
17
|
+
* // Warnings will be flushed automatically after debounce period
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
/**
|
|
21
|
+
* Configuration options for the warning system
|
|
22
|
+
*/
|
|
23
|
+
export interface WarningConfig {
|
|
24
|
+
/**
|
|
25
|
+
* Time in milliseconds to wait after last warning before flushing output.
|
|
26
|
+
* Default: 10000 (10 seconds)
|
|
27
|
+
*/
|
|
28
|
+
DebounceMs: number;
|
|
29
|
+
/**
|
|
30
|
+
* If true, shows every occurrence of warnings (ignores session tracking).
|
|
31
|
+
* Default: false
|
|
32
|
+
*/
|
|
33
|
+
ShowAll: boolean;
|
|
34
|
+
/**
|
|
35
|
+
* If true, disables all warnings.
|
|
36
|
+
* Default: false
|
|
37
|
+
*/
|
|
38
|
+
DisableWarnings: boolean;
|
|
39
|
+
/**
|
|
40
|
+
* If true, groups warnings and displays them in formatted tree structure.
|
|
41
|
+
* If false, displays warnings immediately as they occur.
|
|
42
|
+
* Default: true
|
|
43
|
+
*/
|
|
44
|
+
GroupWarnings: boolean;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Singleton class that manages warnings across the entire application session.
|
|
48
|
+
* Tracks which warnings have been shown and batches them for clean, grouped output.
|
|
49
|
+
*/
|
|
50
|
+
export declare class WarningManager {
|
|
51
|
+
private static instance;
|
|
52
|
+
private warnedDeprecatedEntities;
|
|
53
|
+
private warnedDeprecatedFields;
|
|
54
|
+
private warnedFieldNotFound;
|
|
55
|
+
private pendingEntityDeprecationWarnings;
|
|
56
|
+
private pendingFieldDeprecationWarnings;
|
|
57
|
+
private pendingFieldNotFoundWarnings;
|
|
58
|
+
private debounceTimer;
|
|
59
|
+
private config;
|
|
60
|
+
private constructor();
|
|
61
|
+
/**
|
|
62
|
+
* Gets the singleton instance of the WarningManager
|
|
63
|
+
*/
|
|
64
|
+
static get Instance(): WarningManager;
|
|
65
|
+
/**
|
|
66
|
+
* Updates the configuration for the warning system.
|
|
67
|
+
* This allows runtime customization of behavior.
|
|
68
|
+
*/
|
|
69
|
+
UpdateConfig(config: Partial<WarningConfig>): void;
|
|
70
|
+
/**
|
|
71
|
+
* Gets the current configuration
|
|
72
|
+
*/
|
|
73
|
+
GetConfig(): Readonly<WarningConfig>;
|
|
74
|
+
/**
|
|
75
|
+
* Records a deprecation warning for an entity.
|
|
76
|
+
*
|
|
77
|
+
* @param entityName - The name of the deprecated entity
|
|
78
|
+
* @param callerName - The name of the caller (e.g., 'BaseEntity::constructor')
|
|
79
|
+
* @returns true if this warning should be emitted immediately (when ShowAll is true)
|
|
80
|
+
*/
|
|
81
|
+
RecordEntityDeprecationWarning(entityName: string, callerName: string): boolean;
|
|
82
|
+
/**
|
|
83
|
+
* Records a deprecation warning for an entity field.
|
|
84
|
+
*
|
|
85
|
+
* @param entityName - The name of the entity containing the deprecated field
|
|
86
|
+
* @param fieldName - The name of the deprecated field
|
|
87
|
+
* @param callerName - The name of the caller (e.g., 'AIPromptEntity::validate')
|
|
88
|
+
* @returns true if this warning should be emitted immediately (when ShowAll is true)
|
|
89
|
+
*/
|
|
90
|
+
RecordFieldDeprecationWarning(entityName: string, fieldName: string, callerName: string): boolean;
|
|
91
|
+
/**
|
|
92
|
+
* Records a warning when a field is not found in an entity definition.
|
|
93
|
+
* This typically occurs during data loading when source data contains fields
|
|
94
|
+
* that don't exist in the entity schema.
|
|
95
|
+
*
|
|
96
|
+
* @param entityName - The name of the entity where the field was not found
|
|
97
|
+
* @param fieldName - The name of the field that was not found
|
|
98
|
+
* @param context - Context description (e.g., 'BaseEntity::SetMany during data load')
|
|
99
|
+
* @returns true if this warning should be emitted immediately (when ShowAll is true)
|
|
100
|
+
*/
|
|
101
|
+
RecordFieldNotFoundWarning(entityName: string, fieldName: string, context: string): boolean;
|
|
102
|
+
/**
|
|
103
|
+
* Schedules a flush of pending warnings after the debounce period.
|
|
104
|
+
* Resets the timer if new warnings arrive.
|
|
105
|
+
*/
|
|
106
|
+
private scheduleFlush;
|
|
107
|
+
/**
|
|
108
|
+
* Immediately flushes all pending warnings to the console.
|
|
109
|
+
* Can be called manually to force output before the debounce period.
|
|
110
|
+
*/
|
|
111
|
+
FlushWarnings(): void;
|
|
112
|
+
/**
|
|
113
|
+
* Internal method that formats and outputs all pending warnings.
|
|
114
|
+
*/
|
|
115
|
+
private flushWarnings;
|
|
116
|
+
/**
|
|
117
|
+
* Resets all tracking state. Useful for testing or starting fresh.
|
|
118
|
+
* Does NOT clear pending warnings - call FlushWarnings first if needed.
|
|
119
|
+
*/
|
|
120
|
+
Reset(): void;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* @deprecated Use WarningManager instead. This alias is provided for backward compatibility.
|
|
124
|
+
*/
|
|
125
|
+
export declare const DeprecationWarningManager: typeof WarningManager;
|
|
126
|
+
//# sourceMappingURL=warningManager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"warningManager.d.ts","sourceRoot":"","sources":["../src/warningManager.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH;;GAEG;AACH,MAAM,WAAW,aAAa;IAC1B;;;OAGG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,OAAO,EAAE,OAAO,CAAC;IAEjB;;;OAGG;IACH,eAAe,EAAE,OAAO,CAAC;IAEzB;;;;OAIG;IACH,aAAa,EAAE,OAAO,CAAC;CAC1B;AA4BD;;;GAGG;AACH,qBAAa,cAAc;IACvB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAiB;IAGxC,OAAO,CAAC,wBAAwB,CAA0B;IAC1D,OAAO,CAAC,sBAAsB,CAAuC;IAGrE,OAAO,CAAC,mBAAmB,CAAuC;IAGlE,OAAO,CAAC,gCAAgC,CAA2D;IACnG,OAAO,CAAC,+BAA+B,CAA4D;IACnG,OAAO,CAAC,4BAA4B,CAAyD;IAE7F,OAAO,CAAC,aAAa,CAA+B;IAEpD,OAAO,CAAC,MAAM,CAAgB;IAE9B,OAAO;IAUP;;OAEG;IACH,WAAkB,QAAQ,IAAI,cAAc,CAK3C;IAED;;;OAGG;IACI,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,aAAa,CAAC,GAAG,IAAI;IAIzD;;OAEG;IACI,SAAS,IAAI,QAAQ,CAAC,aAAa,CAAC;IAI3C;;;;;;OAMG;IACI,8BAA8B,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO;IA2CtF;;;;;;;OAOG;IACI,6BAA6B,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO;IA8DxG;;;;;;;;;OASG;IACI,0BAA0B,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO;IA8DlG;;;OAGG;IACH,OAAO,CAAC,aAAa;IAYrB;;;OAGG;IACI,aAAa,IAAI,IAAI;IAQ5B;;OAEG;IACH,OAAO,CAAC,aAAa;IAuHrB;;;OAGG;IACI,KAAK,IAAI,IAAI;CAavB;AAED;;GAEG;AACH,eAAO,MAAM,yBAAyB,uBAAiB,CAAC"}
|
|
@@ -0,0 +1,373 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Manages various types of warnings across the MemberJunction system.
|
|
4
|
+
*
|
|
5
|
+
* Features:
|
|
6
|
+
* - Session-level tracking: Each warning shown once per session
|
|
7
|
+
* - Debounced output: Groups warnings and displays after a quiet period
|
|
8
|
+
* - Formatted output: Tree-structured, grouped by entity and warning type
|
|
9
|
+
* - Configurable: Control debounce timing and behavior via options
|
|
10
|
+
* - Multiple warning types: Deprecation, field-not-found, and extensible for more
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```typescript
|
|
14
|
+
* const wm = WarningManager.Instance;
|
|
15
|
+
* wm.RecordEntityDeprecationWarning('User Preferences', 'BaseEntity::constructor');
|
|
16
|
+
* wm.RecordFieldDeprecationWarning('AI Prompts', 'OldField', 'AIPromptEntity::validate');
|
|
17
|
+
* wm.RecordFieldNotFoundWarning('Users', 'DeletedColumn', 'BaseEntity::SetMany');
|
|
18
|
+
* // Warnings will be flushed automatically after debounce period
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
|
+
exports.DeprecationWarningManager = exports.WarningManager = void 0;
|
|
23
|
+
/**
|
|
24
|
+
* Singleton class that manages warnings across the entire application session.
|
|
25
|
+
* Tracks which warnings have been shown and batches them for clean, grouped output.
|
|
26
|
+
*/
|
|
27
|
+
class WarningManager {
|
|
28
|
+
constructor() {
|
|
29
|
+
// Tracking for deprecation warnings
|
|
30
|
+
this.warnedDeprecatedEntities = new Set();
|
|
31
|
+
this.warnedDeprecatedFields = new Map(); // entityName -> Set<fieldName>
|
|
32
|
+
// Tracking for field-not-found warnings
|
|
33
|
+
this.warnedFieldNotFound = new Map(); // entityName -> Set<fieldName>
|
|
34
|
+
// Pending warnings by type
|
|
35
|
+
this.pendingEntityDeprecationWarnings = new Map();
|
|
36
|
+
this.pendingFieldDeprecationWarnings = new Map();
|
|
37
|
+
this.pendingFieldNotFoundWarnings = new Map();
|
|
38
|
+
this.debounceTimer = null;
|
|
39
|
+
// Initialize with default configuration
|
|
40
|
+
this.config = {
|
|
41
|
+
DebounceMs: 10000,
|
|
42
|
+
ShowAll: false,
|
|
43
|
+
DisableWarnings: false,
|
|
44
|
+
GroupWarnings: true
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Gets the singleton instance of the WarningManager
|
|
49
|
+
*/
|
|
50
|
+
static get Instance() {
|
|
51
|
+
if (!WarningManager.instance) {
|
|
52
|
+
WarningManager.instance = new WarningManager();
|
|
53
|
+
}
|
|
54
|
+
return WarningManager.instance;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Updates the configuration for the warning system.
|
|
58
|
+
* This allows runtime customization of behavior.
|
|
59
|
+
*/
|
|
60
|
+
UpdateConfig(config) {
|
|
61
|
+
this.config = { ...this.config, ...config };
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Gets the current configuration
|
|
65
|
+
*/
|
|
66
|
+
GetConfig() {
|
|
67
|
+
return { ...this.config };
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Records a deprecation warning for an entity.
|
|
71
|
+
*
|
|
72
|
+
* @param entityName - The name of the deprecated entity
|
|
73
|
+
* @param callerName - The name of the caller (e.g., 'BaseEntity::constructor')
|
|
74
|
+
* @returns true if this warning should be emitted immediately (when ShowAll is true)
|
|
75
|
+
*/
|
|
76
|
+
RecordEntityDeprecationWarning(entityName, callerName) {
|
|
77
|
+
if (this.config.DisableWarnings) {
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
const key = entityName;
|
|
81
|
+
const alreadyWarned = this.warnedDeprecatedEntities.has(key);
|
|
82
|
+
if (this.config.ShowAll) {
|
|
83
|
+
// Emit immediately, don't track or queue
|
|
84
|
+
console.warn(`Entity "${entityName}" is deprecated and should not be used as it could be removed in the future. (Called from: ${callerName})`);
|
|
85
|
+
return true;
|
|
86
|
+
}
|
|
87
|
+
if (!this.config.GroupWarnings) {
|
|
88
|
+
// Emit immediately if not grouping, but still track to avoid duplicates
|
|
89
|
+
if (!alreadyWarned) {
|
|
90
|
+
console.warn(`Entity "${entityName}" is deprecated and should not be used as it could be removed in the future. (Called from: ${callerName})`);
|
|
91
|
+
this.warnedDeprecatedEntities.add(key);
|
|
92
|
+
}
|
|
93
|
+
return !alreadyWarned;
|
|
94
|
+
}
|
|
95
|
+
// Group warnings - only queue if we haven't warned about this entity yet
|
|
96
|
+
if (!alreadyWarned) {
|
|
97
|
+
this.warnedDeprecatedEntities.add(key);
|
|
98
|
+
// Add to pending warnings
|
|
99
|
+
if (!this.pendingEntityDeprecationWarnings.has(key)) {
|
|
100
|
+
this.pendingEntityDeprecationWarnings.set(key, {
|
|
101
|
+
entityName,
|
|
102
|
+
callerNames: new Set()
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
this.pendingEntityDeprecationWarnings.get(key).callerNames.add(callerName);
|
|
106
|
+
this.scheduleFlush();
|
|
107
|
+
return true;
|
|
108
|
+
}
|
|
109
|
+
return false;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Records a deprecation warning for an entity field.
|
|
113
|
+
*
|
|
114
|
+
* @param entityName - The name of the entity containing the deprecated field
|
|
115
|
+
* @param fieldName - The name of the deprecated field
|
|
116
|
+
* @param callerName - The name of the caller (e.g., 'AIPromptEntity::validate')
|
|
117
|
+
* @returns true if this warning should be emitted immediately (when ShowAll is true)
|
|
118
|
+
*/
|
|
119
|
+
RecordFieldDeprecationWarning(entityName, fieldName, callerName) {
|
|
120
|
+
if (this.config.DisableWarnings) {
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
// Check if we've already warned about this specific field
|
|
124
|
+
const entityFields = this.warnedDeprecatedFields.get(entityName);
|
|
125
|
+
const alreadyWarned = entityFields?.has(fieldName) || false;
|
|
126
|
+
if (this.config.ShowAll) {
|
|
127
|
+
// Emit immediately, don't track or queue
|
|
128
|
+
console.warn(`Entity Field "${entityName}.${fieldName}" is deprecated and should not be used as it could be removed in the future. (Called from: ${callerName})`);
|
|
129
|
+
return true;
|
|
130
|
+
}
|
|
131
|
+
if (!this.config.GroupWarnings) {
|
|
132
|
+
// Emit immediately if not grouping, but still track to avoid duplicates
|
|
133
|
+
if (!alreadyWarned) {
|
|
134
|
+
console.warn(`Entity Field "${entityName}.${fieldName}" is deprecated and should not be used as it could be removed in the future. (Called from: ${callerName})`);
|
|
135
|
+
if (!this.warnedDeprecatedFields.has(entityName)) {
|
|
136
|
+
this.warnedDeprecatedFields.set(entityName, new Set());
|
|
137
|
+
}
|
|
138
|
+
this.warnedDeprecatedFields.get(entityName).add(fieldName);
|
|
139
|
+
}
|
|
140
|
+
return !alreadyWarned;
|
|
141
|
+
}
|
|
142
|
+
// Group warnings - only queue if we haven't warned about this field yet
|
|
143
|
+
if (!alreadyWarned) {
|
|
144
|
+
// Mark as warned
|
|
145
|
+
if (!this.warnedDeprecatedFields.has(entityName)) {
|
|
146
|
+
this.warnedDeprecatedFields.set(entityName, new Set());
|
|
147
|
+
}
|
|
148
|
+
this.warnedDeprecatedFields.get(entityName).add(fieldName);
|
|
149
|
+
// Add to pending warnings
|
|
150
|
+
if (!this.pendingFieldDeprecationWarnings.has(entityName)) {
|
|
151
|
+
this.pendingFieldDeprecationWarnings.set(entityName, []);
|
|
152
|
+
}
|
|
153
|
+
const fieldWarnings = this.pendingFieldDeprecationWarnings.get(entityName);
|
|
154
|
+
let fieldWarning = fieldWarnings.find(fw => fw.fieldName === fieldName);
|
|
155
|
+
if (!fieldWarning) {
|
|
156
|
+
fieldWarning = {
|
|
157
|
+
entityName,
|
|
158
|
+
fieldName,
|
|
159
|
+
callerNames: new Set()
|
|
160
|
+
};
|
|
161
|
+
fieldWarnings.push(fieldWarning);
|
|
162
|
+
}
|
|
163
|
+
fieldWarning.callerNames.add(callerName);
|
|
164
|
+
this.scheduleFlush();
|
|
165
|
+
return true;
|
|
166
|
+
}
|
|
167
|
+
return false;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Records a warning when a field is not found in an entity definition.
|
|
171
|
+
* This typically occurs during data loading when source data contains fields
|
|
172
|
+
* that don't exist in the entity schema.
|
|
173
|
+
*
|
|
174
|
+
* @param entityName - The name of the entity where the field was not found
|
|
175
|
+
* @param fieldName - The name of the field that was not found
|
|
176
|
+
* @param context - Context description (e.g., 'BaseEntity::SetMany during data load')
|
|
177
|
+
* @returns true if this warning should be emitted immediately (when ShowAll is true)
|
|
178
|
+
*/
|
|
179
|
+
RecordFieldNotFoundWarning(entityName, fieldName, context) {
|
|
180
|
+
if (this.config.DisableWarnings) {
|
|
181
|
+
return false;
|
|
182
|
+
}
|
|
183
|
+
// Check if we've already warned about this specific field
|
|
184
|
+
const entityFields = this.warnedFieldNotFound.get(entityName);
|
|
185
|
+
const alreadyWarned = entityFields?.has(fieldName) || false;
|
|
186
|
+
if (this.config.ShowAll) {
|
|
187
|
+
// Emit immediately, don't track or queue
|
|
188
|
+
console.warn(`Field "${fieldName}" does not exist on entity "${entityName}". Context: ${context}`);
|
|
189
|
+
return true;
|
|
190
|
+
}
|
|
191
|
+
if (!this.config.GroupWarnings) {
|
|
192
|
+
// Emit immediately if not grouping, but still track to avoid duplicates
|
|
193
|
+
if (!alreadyWarned) {
|
|
194
|
+
console.warn(`Field "${fieldName}" does not exist on entity "${entityName}". Context: ${context}`);
|
|
195
|
+
if (!this.warnedFieldNotFound.has(entityName)) {
|
|
196
|
+
this.warnedFieldNotFound.set(entityName, new Set());
|
|
197
|
+
}
|
|
198
|
+
this.warnedFieldNotFound.get(entityName).add(fieldName);
|
|
199
|
+
}
|
|
200
|
+
return !alreadyWarned;
|
|
201
|
+
}
|
|
202
|
+
// Group warnings - only queue if we haven't warned about this field yet
|
|
203
|
+
if (!alreadyWarned) {
|
|
204
|
+
// Mark as warned
|
|
205
|
+
if (!this.warnedFieldNotFound.has(entityName)) {
|
|
206
|
+
this.warnedFieldNotFound.set(entityName, new Set());
|
|
207
|
+
}
|
|
208
|
+
this.warnedFieldNotFound.get(entityName).add(fieldName);
|
|
209
|
+
// Add to pending warnings
|
|
210
|
+
if (!this.pendingFieldNotFoundWarnings.has(entityName)) {
|
|
211
|
+
this.pendingFieldNotFoundWarnings.set(entityName, []);
|
|
212
|
+
}
|
|
213
|
+
const fieldWarnings = this.pendingFieldNotFoundWarnings.get(entityName);
|
|
214
|
+
let fieldWarning = fieldWarnings.find(fw => fw.fieldName === fieldName);
|
|
215
|
+
if (!fieldWarning) {
|
|
216
|
+
fieldWarning = {
|
|
217
|
+
entityName,
|
|
218
|
+
fieldName,
|
|
219
|
+
contexts: new Set()
|
|
220
|
+
};
|
|
221
|
+
fieldWarnings.push(fieldWarning);
|
|
222
|
+
}
|
|
223
|
+
fieldWarning.contexts.add(context);
|
|
224
|
+
this.scheduleFlush();
|
|
225
|
+
return true;
|
|
226
|
+
}
|
|
227
|
+
return false;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Schedules a flush of pending warnings after the debounce period.
|
|
231
|
+
* Resets the timer if new warnings arrive.
|
|
232
|
+
*/
|
|
233
|
+
scheduleFlush() {
|
|
234
|
+
// Clear existing timer
|
|
235
|
+
if (this.debounceTimer) {
|
|
236
|
+
clearTimeout(this.debounceTimer);
|
|
237
|
+
}
|
|
238
|
+
// Schedule new flush
|
|
239
|
+
this.debounceTimer = setTimeout(() => {
|
|
240
|
+
this.flushWarnings();
|
|
241
|
+
}, this.config.DebounceMs);
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Immediately flushes all pending warnings to the console.
|
|
245
|
+
* Can be called manually to force output before the debounce period.
|
|
246
|
+
*/
|
|
247
|
+
FlushWarnings() {
|
|
248
|
+
if (this.debounceTimer) {
|
|
249
|
+
clearTimeout(this.debounceTimer);
|
|
250
|
+
this.debounceTimer = null;
|
|
251
|
+
}
|
|
252
|
+
this.flushWarnings();
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Internal method that formats and outputs all pending warnings.
|
|
256
|
+
*/
|
|
257
|
+
flushWarnings() {
|
|
258
|
+
const hasEntityDeprecationWarnings = this.pendingEntityDeprecationWarnings.size > 0;
|
|
259
|
+
const hasFieldDeprecationWarnings = this.pendingFieldDeprecationWarnings.size > 0;
|
|
260
|
+
const hasFieldNotFoundWarnings = this.pendingFieldNotFoundWarnings.size > 0;
|
|
261
|
+
if (!hasEntityDeprecationWarnings && !hasFieldDeprecationWarnings && !hasFieldNotFoundWarnings) {
|
|
262
|
+
return; // Nothing to flush
|
|
263
|
+
}
|
|
264
|
+
const lines = [];
|
|
265
|
+
// Output deprecation warnings if any
|
|
266
|
+
if (hasEntityDeprecationWarnings || hasFieldDeprecationWarnings) {
|
|
267
|
+
lines.push('');
|
|
268
|
+
lines.push('⚠️ DEPRECATION WARNINGS - The following entities/fields are deprecated and may be removed in future versions:');
|
|
269
|
+
lines.push('');
|
|
270
|
+
// Output entity deprecation warnings
|
|
271
|
+
if (hasEntityDeprecationWarnings) {
|
|
272
|
+
lines.push('📦 DEPRECATED ENTITIES:');
|
|
273
|
+
const sortedEntities = Array.from(this.pendingEntityDeprecationWarnings.values())
|
|
274
|
+
.sort((a, b) => a.entityName.localeCompare(b.entityName));
|
|
275
|
+
for (const warning of sortedEntities) {
|
|
276
|
+
const callers = Array.from(warning.callerNames).sort().join(', ');
|
|
277
|
+
lines.push(` • "${warning.entityName}" (called from: ${callers})`);
|
|
278
|
+
}
|
|
279
|
+
lines.push('');
|
|
280
|
+
}
|
|
281
|
+
// Output field deprecation warnings
|
|
282
|
+
if (hasFieldDeprecationWarnings) {
|
|
283
|
+
lines.push('📋 DEPRECATED ENTITY FIELDS:');
|
|
284
|
+
const sortedEntityNames = Array.from(this.pendingFieldDeprecationWarnings.keys()).sort();
|
|
285
|
+
for (let i = 0; i < sortedEntityNames.length; i++) {
|
|
286
|
+
const entityName = sortedEntityNames[i];
|
|
287
|
+
const fieldWarnings = this.pendingFieldDeprecationWarnings.get(entityName);
|
|
288
|
+
const isLast = i === sortedEntityNames.length - 1;
|
|
289
|
+
const entityPrefix = isLast ? '└─' : '├─';
|
|
290
|
+
lines.push(` ${entityPrefix} "${entityName}"`);
|
|
291
|
+
// Sort field warnings by field name
|
|
292
|
+
const sortedFields = fieldWarnings.sort((a, b) => a.fieldName.localeCompare(b.fieldName));
|
|
293
|
+
for (let j = 0; j < sortedFields.length; j++) {
|
|
294
|
+
const fieldWarning = sortedFields[j];
|
|
295
|
+
const isLastField = j === sortedFields.length - 1;
|
|
296
|
+
const fieldPrefix = isLastField ? '└─' : '├─';
|
|
297
|
+
const continuation = isLast ? ' ' : '│';
|
|
298
|
+
const callers = Array.from(fieldWarning.callerNames).sort().join(', ');
|
|
299
|
+
lines.push(` ${continuation} ${fieldPrefix} ${fieldWarning.fieldName} (called from: ${callers})`);
|
|
300
|
+
}
|
|
301
|
+
if (!isLast) {
|
|
302
|
+
lines.push(` │`);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
lines.push('');
|
|
306
|
+
}
|
|
307
|
+
lines.push('💡 Set ShowAll=true in configuration to see every occurrence.');
|
|
308
|
+
lines.push('');
|
|
309
|
+
}
|
|
310
|
+
// Output field-not-found warnings if any
|
|
311
|
+
if (hasFieldNotFoundWarnings) {
|
|
312
|
+
lines.push('');
|
|
313
|
+
lines.push('⚠️ DATA INTEGRITY WARNINGS - The following fields were not found in entity definitions:');
|
|
314
|
+
lines.push('');
|
|
315
|
+
lines.push('📋 MISSING FIELDS:');
|
|
316
|
+
const sortedEntityNames = Array.from(this.pendingFieldNotFoundWarnings.keys()).sort();
|
|
317
|
+
for (let i = 0; i < sortedEntityNames.length; i++) {
|
|
318
|
+
const entityName = sortedEntityNames[i];
|
|
319
|
+
const fieldWarnings = this.pendingFieldNotFoundWarnings.get(entityName);
|
|
320
|
+
const isLast = i === sortedEntityNames.length - 1;
|
|
321
|
+
const entityPrefix = isLast ? '└─' : '├─';
|
|
322
|
+
lines.push(` ${entityPrefix} "${entityName}"`);
|
|
323
|
+
// Sort field warnings by field name
|
|
324
|
+
const sortedFields = fieldWarnings.sort((a, b) => a.fieldName.localeCompare(b.fieldName));
|
|
325
|
+
for (let j = 0; j < sortedFields.length; j++) {
|
|
326
|
+
const fieldWarning = sortedFields[j];
|
|
327
|
+
const isLastField = j === sortedFields.length - 1;
|
|
328
|
+
const fieldPrefix = isLastField ? '└─' : '├─';
|
|
329
|
+
const continuation = isLast ? ' ' : '│';
|
|
330
|
+
const contexts = Array.from(fieldWarning.contexts).sort().join(', ');
|
|
331
|
+
lines.push(` ${continuation} ${fieldPrefix} ${fieldWarning.fieldName} (context: ${contexts})`);
|
|
332
|
+
}
|
|
333
|
+
if (!isLast) {
|
|
334
|
+
lines.push(` │`);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
lines.push('');
|
|
338
|
+
lines.push('💡 These fields exist in your data but not in the entity schema. This may indicate:');
|
|
339
|
+
lines.push(' • Schema is out of sync with database');
|
|
340
|
+
lines.push(' • Data contains legacy fields that were removed');
|
|
341
|
+
lines.push(' • Field names have been changed');
|
|
342
|
+
lines.push('');
|
|
343
|
+
}
|
|
344
|
+
// Output all lines at once
|
|
345
|
+
console.warn(lines.join('\n'));
|
|
346
|
+
// Clear pending warnings
|
|
347
|
+
this.pendingEntityDeprecationWarnings.clear();
|
|
348
|
+
this.pendingFieldDeprecationWarnings.clear();
|
|
349
|
+
this.pendingFieldNotFoundWarnings.clear();
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* Resets all tracking state. Useful for testing or starting fresh.
|
|
353
|
+
* Does NOT clear pending warnings - call FlushWarnings first if needed.
|
|
354
|
+
*/
|
|
355
|
+
Reset() {
|
|
356
|
+
this.warnedDeprecatedEntities.clear();
|
|
357
|
+
this.warnedDeprecatedFields.clear();
|
|
358
|
+
this.warnedFieldNotFound.clear();
|
|
359
|
+
this.pendingEntityDeprecationWarnings.clear();
|
|
360
|
+
this.pendingFieldDeprecationWarnings.clear();
|
|
361
|
+
this.pendingFieldNotFoundWarnings.clear();
|
|
362
|
+
if (this.debounceTimer) {
|
|
363
|
+
clearTimeout(this.debounceTimer);
|
|
364
|
+
this.debounceTimer = null;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
exports.WarningManager = WarningManager;
|
|
369
|
+
/**
|
|
370
|
+
* @deprecated Use WarningManager instead. This alias is provided for backward compatibility.
|
|
371
|
+
*/
|
|
372
|
+
exports.DeprecationWarningManager = WarningManager;
|
|
373
|
+
//# sourceMappingURL=warningManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"warningManager.js","sourceRoot":"","sources":["../src/warningManager.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -19,6 +19,7 @@ The `@memberjunction/global` library serves as the foundation for cross-componen
|
|
|
19
19
|
- **Class Reflection Utilities** - Runtime class hierarchy inspection and analysis
|
|
20
20
|
- **Deep Diff Engine** - Comprehensive object comparison and change tracking
|
|
21
21
|
- **JSON Validator** - Lightweight JSON validation with flexible rules and special syntax
|
|
22
|
+
- **Warning Manager** - Smart warning system with debouncing, batching, and session tracking
|
|
22
23
|
- **Utility Functions** - Common string manipulation, JSON parsing (including recursive nested JSON parsing), pattern matching, and formatting utilities
|
|
23
24
|
|
|
24
25
|
## Core Components
|
|
@@ -650,6 +651,110 @@ const html = ConvertMarkdownStringToHtmlList('Unordered', '- Item 1\n- Item 2\n-
|
|
|
650
651
|
// Returns: <ul><li>Item 1</li><li>Item 2</li><li>Item 3</li></ul>
|
|
651
652
|
```
|
|
652
653
|
|
|
654
|
+
### Warning Manager
|
|
655
|
+
|
|
656
|
+
The Warning Manager provides intelligent warning batching and deduplication for console messages across your application. It tracks warnings per session, groups them by type, and displays them in clean, formatted output after a configurable debounce period.
|
|
657
|
+
|
|
658
|
+
#### Features
|
|
659
|
+
|
|
660
|
+
- **Session-level tracking** - Each warning shown only once per session
|
|
661
|
+
- **Debounced output** - Groups warnings and displays after a configurable quiet period (default 10s)
|
|
662
|
+
- **Multiple warning types** - Supports deprecation warnings and data integrity warnings
|
|
663
|
+
- **Beautiful formatting** - Tree-structured console output with emojis and clear grouping
|
|
664
|
+
- **Configurable** - Runtime API and environment variables for customization
|
|
665
|
+
- **Backward compatible** - `DeprecationWarningManager` alias provided
|
|
666
|
+
|
|
667
|
+
#### Basic Usage
|
|
668
|
+
|
|
669
|
+
```typescript
|
|
670
|
+
import { WarningManager } from '@memberjunction/global';
|
|
671
|
+
|
|
672
|
+
const wm = WarningManager.Instance;
|
|
673
|
+
|
|
674
|
+
// Record deprecation warnings
|
|
675
|
+
wm.RecordEntityDeprecationWarning('LegacyEntity', 'MyComponent::method');
|
|
676
|
+
wm.RecordFieldDeprecationWarning('Users', 'OldField', 'DataLoader::process');
|
|
677
|
+
|
|
678
|
+
// Record field-not-found warnings (data integrity issues)
|
|
679
|
+
wm.RecordFieldNotFoundWarning('Users', 'DeletedColumn', 'BaseEntity::SetMany during import');
|
|
680
|
+
|
|
681
|
+
// Warnings are automatically batched and displayed after debounce period
|
|
682
|
+
// Or manually flush immediately:
|
|
683
|
+
wm.FlushWarnings();
|
|
684
|
+
```
|
|
685
|
+
|
|
686
|
+
#### Example Output
|
|
687
|
+
|
|
688
|
+
```
|
|
689
|
+
⚠️ DEPRECATION WARNINGS - The following entities/fields are deprecated and may be removed in future versions:
|
|
690
|
+
|
|
691
|
+
📦 DEPRECATED ENTITIES:
|
|
692
|
+
• "LegacyEntity" (called from: MyComponent::method)
|
|
693
|
+
|
|
694
|
+
📋 DEPRECATED ENTITY FIELDS:
|
|
695
|
+
└─ "Users"
|
|
696
|
+
└─ OldField (called from: DataLoader::process)
|
|
697
|
+
|
|
698
|
+
💡 Set ShowAll=true in configuration to see every occurrence.
|
|
699
|
+
|
|
700
|
+
|
|
701
|
+
⚠️ DATA INTEGRITY WARNINGS - The following fields were not found in entity definitions:
|
|
702
|
+
|
|
703
|
+
📋 MISSING FIELDS:
|
|
704
|
+
└─ "Users"
|
|
705
|
+
└─ DeletedColumn (context: BaseEntity::SetMany during import)
|
|
706
|
+
|
|
707
|
+
💡 These fields exist in your data but not in the entity schema. This may indicate:
|
|
708
|
+
• Schema is out of sync with database
|
|
709
|
+
• Data contains legacy fields that were removed
|
|
710
|
+
• Field names have been changed
|
|
711
|
+
```
|
|
712
|
+
|
|
713
|
+
#### Configuration
|
|
714
|
+
|
|
715
|
+
Configure via runtime API:
|
|
716
|
+
|
|
717
|
+
```typescript
|
|
718
|
+
wm.UpdateConfig({
|
|
719
|
+
DebounceMs: 5000, // Wait 5 seconds after last warning
|
|
720
|
+
ShowAll: false, // Show each warning once per session (default)
|
|
721
|
+
DisableWarnings: false, // Enable warnings (default)
|
|
722
|
+
GroupWarnings: true // Group warnings in tree format (default)
|
|
723
|
+
});
|
|
724
|
+
|
|
725
|
+
// Get current configuration
|
|
726
|
+
const config = wm.GetConfig();
|
|
727
|
+
```
|
|
728
|
+
|
|
729
|
+
All configuration is done via the runtime API.
|
|
730
|
+
|
|
731
|
+
#### Warning Types
|
|
732
|
+
|
|
733
|
+
**Deprecation Warnings** indicate entities or fields that may be removed in future versions:
|
|
734
|
+
- `RecordEntityDeprecationWarning(entityName, callerName)` - Deprecated entity
|
|
735
|
+
- `RecordFieldDeprecationWarning(entityName, fieldName, callerName)` - Deprecated field
|
|
736
|
+
|
|
737
|
+
**Data Integrity Warnings** indicate mismatches between data and schema:
|
|
738
|
+
- `RecordFieldNotFoundWarning(entityName, fieldName, context)` - Field exists in data but not in schema
|
|
739
|
+
|
|
740
|
+
#### Advanced Usage
|
|
741
|
+
|
|
742
|
+
```typescript
|
|
743
|
+
// Reset all tracking (useful for testing)
|
|
744
|
+
wm.Reset();
|
|
745
|
+
|
|
746
|
+
// Backward compatibility - DeprecationWarningManager is an alias
|
|
747
|
+
import { DeprecationWarningManager } from '@memberjunction/global';
|
|
748
|
+
const dwm = DeprecationWarningManager.Instance; // Same as WarningManager.Instance
|
|
749
|
+
```
|
|
750
|
+
|
|
751
|
+
#### Use Cases
|
|
752
|
+
|
|
753
|
+
1. **Framework-level warnings** - Alert developers about deprecated APIs
|
|
754
|
+
2. **Data migration** - Track fields that don't match current schema
|
|
755
|
+
3. **Development debugging** - Identify outdated code patterns
|
|
756
|
+
4. **Testing** - Verify no deprecated features are used
|
|
757
|
+
|
|
653
758
|
### Safe Expression Evaluator
|
|
654
759
|
|
|
655
760
|
Secure boolean expression evaluation for conditional logic without allowing arbitrary code execution:
|