diff --git a/changelog.md b/changelog.md index a12e7fb..2f335dc 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,13 @@ # Changelog +## 2025-11-28 - 7.0.13 - fix(classes.doc) +Remove noisy debug logging from decorators and serialization logic + +- Removed debug logger calls from globalSvDb decorator initialization +- Removed debug logger calls from svDb decorator initialization and svDb options handling +- Removed debug logger calls from unI and index decorator initializers +- Removed debug logging in createSavableObject to reduce console noise; no functional changes + ## 2025-11-28 - 7.0.12 - fix(collection) Ensure TC39 decorator metadata is initialized on both original and decorated constructors/prototypes and add debug logging diff --git a/ts/00_commitinfo_data.ts b/ts/00_commitinfo_data.ts index 94956e4..d77260d 100644 --- a/ts/00_commitinfo_data.ts +++ b/ts/00_commitinfo_data.ts @@ -3,6 +3,6 @@ */ export const commitinfo = { name: '@push.rocks/smartdata', - version: '7.0.12', + version: '7.0.13', description: 'An advanced library for NoSQL data organization and manipulation using TypeScript with support for MongoDB, data validation, collections, and custom data types.' } diff --git a/ts/classes.collection.ts b/ts/classes.collection.ts index 964b63e..edb20d5 100644 --- a/ts/classes.collection.ts +++ b/ts/classes.collection.ts @@ -31,9 +31,7 @@ export function Collection(dbArg: SmartdataDb | TDelayed) { throw new Error('Collection can only decorate classes'); } - // Capture original constructor for _svDbOptions forwarding - const originalConstructor = value as any; - const constructor = value as { new (...args: any[]): any }; + const constructor = value as { new (...args: any[]): any } & { className?: string }; const getCollection = () => { if (!(dbArg instanceof SmartdataDb)) { @@ -42,121 +40,61 @@ export function Collection(dbArg: SmartdataDb | TDelayed) { const coll = collectionFactory.getCollection(constructor.name, dbArg); // Attach document constructor for searchableFields lookup if (coll && !(coll as any).docCtor) { - (coll as any).docCtor = decoratedClass; + (coll as any).docCtor = constructor; } return coll; }; - const decoratedClass = class extends constructor { - public static className = constructor.name; - public static get collection() { - return getCollection(); - } - public get collection() { - return getCollection(); - } - }; + // Add static className property directly on the constructor + (constructor as any).className = constructor.name; - // Ensure instance getter works in Deno by defining it on the prototype - Object.defineProperty(decoratedClass.prototype, 'collection', { - get: getCollection, - enumerable: false, - configurable: true - }); - - // Closure fix: When class methods reference the class name (e.g., `User.collection`), - // they get the original constructor via closure, not the decorated class. - // Define collection getter on the original constructor. + // Define collection getter on constructor (static access) Object.defineProperty(constructor, 'collection', { get: getCollection, enumerable: false, configurable: true }); + + // Define collection getter on prototype (instance access) Object.defineProperty(constructor.prototype, 'collection', { get: getCollection, enumerable: false, configurable: true }); - // Deno compatibility note: Property decorators set properties on the prototype. - // Since we removed instance property declarations from SmartDataDbDoc, - // the decorator-set prototype properties are now accessible without shadowing. - // No manual forwarding needed - natural prototype inheritance works! - - // Point to original constructor's _svDbOptions - Object.defineProperty(decoratedClass, '_svDbOptions', { - get() { return originalConstructor._svDbOptions; }, - set(value) { originalConstructor._svDbOptions = value; }, - configurable: true - }); - // Initialize prototype properties from context.metadata (TC39 decorator metadata) // This ensures prototype properties are available before any instance is created const metadata = context.metadata as any; - logger.log('debug', `Collection decorator for ${constructor.name}: metadata.saveableProperties = ${metadata?.saveableProperties?.length ?? 'undefined'}`); if (metadata) { - const proto = decoratedClass.prototype; - const origProto = constructor.prototype; + const proto = constructor.prototype; - // Initialize globalSaveableProperties on BOTH prototypes - if (metadata.globalSaveableProperties) { - if (!proto.globalSaveableProperties) { - proto.globalSaveableProperties = [...metadata.globalSaveableProperties]; - } - if (!origProto.globalSaveableProperties) { - origProto.globalSaveableProperties = [...metadata.globalSaveableProperties]; - } + if (metadata.globalSaveableProperties && !proto.globalSaveableProperties) { + proto.globalSaveableProperties = [...metadata.globalSaveableProperties]; } - // Initialize saveableProperties on BOTH prototypes (closure fix) - if (metadata.saveableProperties) { - if (!proto.saveableProperties) { - proto.saveableProperties = [...metadata.saveableProperties]; - } - // Also set on original constructor's prototype for closure references - if (!origProto.saveableProperties) { - origProto.saveableProperties = [...metadata.saveableProperties]; - logger.log('debug', `Collection decorator: set saveableProperties on original prototype (${origProto.saveableProperties.length} props)`); - } + if (metadata.saveableProperties && !proto.saveableProperties) { + proto.saveableProperties = [...metadata.saveableProperties]; } - // Initialize uniqueIndexes on BOTH prototypes - if (metadata.uniqueIndexes) { - if (!proto.uniqueIndexes) { - proto.uniqueIndexes = [...metadata.uniqueIndexes]; - } - if (!origProto.uniqueIndexes) { - origProto.uniqueIndexes = [...metadata.uniqueIndexes]; - } + if (metadata.uniqueIndexes && !proto.uniqueIndexes) { + proto.uniqueIndexes = [...metadata.uniqueIndexes]; } - // Initialize regularIndexes on BOTH prototypes - if (metadata.regularIndexes) { - if (!proto.regularIndexes) { - proto.regularIndexes = [...metadata.regularIndexes]; - } - if (!origProto.regularIndexes) { - origProto.regularIndexes = [...metadata.regularIndexes]; - } + if (metadata.regularIndexes && !proto.regularIndexes) { + proto.regularIndexes = [...metadata.regularIndexes]; } - // Initialize searchableFields on BOTH constructors - if (metadata.searchableFields) { - if (!Array.isArray((decoratedClass as any).searchableFields)) { - (decoratedClass as any).searchableFields = [...metadata.searchableFields]; - } - if (!Array.isArray((constructor as any).searchableFields)) { - (constructor as any).searchableFields = [...metadata.searchableFields]; - } + if (metadata.searchableFields && !Array.isArray((constructor as any).searchableFields)) { + (constructor as any).searchableFields = [...metadata.searchableFields]; } - // Initialize _svDbOptions from metadata - if (metadata._svDbOptions && !originalConstructor._svDbOptions) { - originalConstructor._svDbOptions = { ...metadata._svDbOptions }; + if (metadata._svDbOptions && !(constructor as any)._svDbOptions) { + (constructor as any)._svDbOptions = { ...metadata._svDbOptions }; } } - return decoratedClass as any; + // Return the ORIGINAL constructor (no class replacement) + return constructor as any; }; } @@ -179,11 +117,14 @@ export function managed(managerArg?: TManager | TDela throw new Error('managed can only decorate classes'); } - const constructor = value as { new (...args: any[]): any }; + const constructor = value as { new (...args: any[]): any } & { className?: string }; - const decoratedClass = class extends constructor { - public static className = constructor.name; - public static get collection() { + // Add static className property directly on the constructor + (constructor as any).className = constructor.name; + + // Define collection getter (static) + Object.defineProperty(constructor, 'collection', { + get: function(this: any) { let dbArg: SmartdataDb; if (!managerArg) { dbArg = this.prototype.defaultManager.db; @@ -193,12 +134,16 @@ export function managed(managerArg?: TManager | TDela dbArg = (managerArg as TDelayed)().db; } return collectionFactory.getCollection(constructor.name, dbArg); - } - public get collection() { + }, + enumerable: false, + configurable: true + }); + + // Define collection getter (instance) + Object.defineProperty(constructor.prototype, 'collection', { + get: function(this: any) { let dbArg: SmartdataDb; if (!managerArg) { - //console.log(this.defaultManager.db); - //process.exit(0) dbArg = this.defaultManager.db; } else if (managerArg['db']) { dbArg = (managerArg as TManager).db; @@ -206,132 +151,74 @@ export function managed(managerArg?: TManager | TDela dbArg = (managerArg as TDelayed)().db; } return collectionFactory.getCollection(constructor.name, dbArg); - } - public static get manager() { - let manager: TManager; - if (!managerArg) { - manager = this.prototype.defaultManager; - } else if (managerArg['db']) { - manager = managerArg as TManager; - } else { - manager = (managerArg as TDelayed)(); - } - return manager; - } - public get manager() { - let manager: TManager; - if (!managerArg) { - manager = this.defaultManager; - } else if (managerArg['db']) { - manager = managerArg as TManager; - } else { - manager = (managerArg as TDelayed)(); - } - return manager; - } - }; - - // Closure fix: When class methods reference the class name (e.g., `User.collection`), - // they get the original constructor via closure, not the decorated class. - // Define collection/manager getters on the original constructor. - const getCollectionStatic = function(this: any) { - let dbArg: SmartdataDb; - if (!managerArg) { - dbArg = this.prototype.defaultManager.db; - } else if (managerArg['db']) { - dbArg = (managerArg as TManager).db; - } else { - dbArg = (managerArg as TDelayed)().db; - } - return collectionFactory.getCollection(constructor.name, dbArg); - }; - const getCollectionInstance = function(this: any) { - let dbArg: SmartdataDb; - if (!managerArg) { - dbArg = this.defaultManager.db; - } else if (managerArg['db']) { - dbArg = (managerArg as TManager).db; - } else { - dbArg = (managerArg as TDelayed)().db; - } - return collectionFactory.getCollection(constructor.name, dbArg); - }; - Object.defineProperty(constructor, 'collection', { - get: getCollectionStatic, + }, enumerable: false, configurable: true }); - Object.defineProperty(constructor.prototype, 'collection', { - get: getCollectionInstance, + + // Define manager getter (static) + Object.defineProperty(constructor, 'manager', { + get: function(this: any) { + if (!managerArg) { + return this.prototype.defaultManager; + } else if (managerArg['db']) { + return managerArg as TManager; + } else { + return (managerArg as TDelayed)(); + } + }, + enumerable: false, + configurable: true + }); + + // Define manager getter (instance) + Object.defineProperty(constructor.prototype, 'manager', { + get: function(this: any) { + if (!managerArg) { + return this.defaultManager; + } else if (managerArg['db']) { + return managerArg as TManager; + } else { + return (managerArg as TDelayed)(); + } + }, enumerable: false, configurable: true }); // Initialize prototype properties from context.metadata (TC39 decorator metadata) // This ensures prototype properties are available before any instance is created - const originalConstructor = value as any; const metadata = context.metadata as any; if (metadata) { - const proto = decoratedClass.prototype; - const origProto = constructor.prototype; + const proto = constructor.prototype; - // Initialize globalSaveableProperties on BOTH prototypes - if (metadata.globalSaveableProperties) { - if (!proto.globalSaveableProperties) { - proto.globalSaveableProperties = [...metadata.globalSaveableProperties]; - } - if (!origProto.globalSaveableProperties) { - origProto.globalSaveableProperties = [...metadata.globalSaveableProperties]; - } + if (metadata.globalSaveableProperties && !proto.globalSaveableProperties) { + proto.globalSaveableProperties = [...metadata.globalSaveableProperties]; } - // Initialize saveableProperties on BOTH prototypes (closure fix) - if (metadata.saveableProperties) { - if (!proto.saveableProperties) { - proto.saveableProperties = [...metadata.saveableProperties]; - } - if (!origProto.saveableProperties) { - origProto.saveableProperties = [...metadata.saveableProperties]; - } + if (metadata.saveableProperties && !proto.saveableProperties) { + proto.saveableProperties = [...metadata.saveableProperties]; } - // Initialize uniqueIndexes on BOTH prototypes - if (metadata.uniqueIndexes) { - if (!proto.uniqueIndexes) { - proto.uniqueIndexes = [...metadata.uniqueIndexes]; - } - if (!origProto.uniqueIndexes) { - origProto.uniqueIndexes = [...metadata.uniqueIndexes]; - } + if (metadata.uniqueIndexes && !proto.uniqueIndexes) { + proto.uniqueIndexes = [...metadata.uniqueIndexes]; } - // Initialize regularIndexes on BOTH prototypes - if (metadata.regularIndexes) { - if (!proto.regularIndexes) { - proto.regularIndexes = [...metadata.regularIndexes]; - } - if (!origProto.regularIndexes) { - origProto.regularIndexes = [...metadata.regularIndexes]; - } + if (metadata.regularIndexes && !proto.regularIndexes) { + proto.regularIndexes = [...metadata.regularIndexes]; } - // Initialize searchableFields on BOTH constructors - if (metadata.searchableFields) { - if (!Array.isArray((decoratedClass as any).searchableFields)) { - (decoratedClass as any).searchableFields = [...metadata.searchableFields]; - } - if (!Array.isArray((constructor as any).searchableFields)) { - (constructor as any).searchableFields = [...metadata.searchableFields]; - } + if (metadata.searchableFields && !Array.isArray((constructor as any).searchableFields)) { + (constructor as any).searchableFields = [...metadata.searchableFields]; } - // Initialize _svDbOptions from metadata - if (metadata._svDbOptions && !originalConstructor._svDbOptions) { - originalConstructor._svDbOptions = { ...metadata._svDbOptions }; + if (metadata._svDbOptions && !(constructor as any)._svDbOptions) { + (constructor as any)._svDbOptions = { ...metadata._svDbOptions }; } } - return decoratedClass as any; + // Return the ORIGINAL constructor (no class replacement) + return constructor as any; }; } diff --git a/ts/classes.doc.ts b/ts/classes.doc.ts index 06ea1ea..781d8cc 100644 --- a/ts/classes.doc.ts +++ b/ts/classes.doc.ts @@ -51,8 +51,6 @@ export function globalSvDb() { } metadata.globalSaveableProperties.push(String(context.name)); - logger.log('debug', `called globalSvDb() on metadata for property ${String(context.name)}`); - // Use addInitializer to ensure prototype arrays are set up once context.addInitializer(function(this: any) { const proto = this.constructor.prototype; @@ -61,7 +59,6 @@ export function globalSvDb() { if (metadata && metadata.globalSaveableProperties && !proto.globalSaveableProperties) { // Initialize prototype array from metadata (runs once per class) proto.globalSaveableProperties = [...metadata.globalSaveableProperties]; - logger.log('debug', `initialized globalSaveableProperties with ${proto.globalSaveableProperties.length} properties`); } }); }; @@ -103,8 +100,6 @@ export function svDb(options?: SvDbOptions) { metadata._svDbOptions[propName] = options; } - logger.log('debug', `called svDb() on metadata for property ${propName}`); - // Use addInitializer to ensure prototype arrays are set up once context.addInitializer(function(this: any) { const proto = this.constructor.prototype; @@ -114,7 +109,6 @@ export function svDb(options?: SvDbOptions) { if (metadata && metadata.saveableProperties && !proto.saveableProperties) { // Initialize prototype array from metadata (runs once per class) proto.saveableProperties = [...metadata.saveableProperties]; - logger.log('debug', `initialized saveableProperties with ${proto.saveableProperties.length} properties`); } // Initialize svDbOptions from metadata @@ -187,8 +181,6 @@ export function unI() { metadata.saveableProperties.push(propName); } - logger.log('debug', `called unI on metadata for property ${propName}`); - // Use addInitializer to ensure prototype arrays are set up once context.addInitializer(function(this: any) { const proto = this.constructor.prototype; @@ -196,7 +188,6 @@ export function unI() { if (metadata && metadata.uniqueIndexes && !proto.uniqueIndexes) { proto.uniqueIndexes = [...metadata.uniqueIndexes]; - logger.log('debug', `initialized uniqueIndexes with ${proto.uniqueIndexes.length} properties`); } if (metadata && metadata.saveableProperties && !proto.saveableProperties) { @@ -246,8 +237,6 @@ export function index(options?: IIndexOptions) { metadata.saveableProperties.push(propName); } - logger.log('debug', `called index() on metadata for property ${propName}`); - // Use addInitializer to ensure prototype arrays are set up once context.addInitializer(function(this: any) { const proto = this.constructor.prototype; @@ -255,7 +244,6 @@ export function index(options?: IIndexOptions) { if (metadata && metadata.regularIndexes && !proto.regularIndexes) { proto.regularIndexes = [...metadata.regularIndexes]; - logger.log('debug', `initialized regularIndexes with ${proto.regularIndexes.length} indexes`); } if (metadata && metadata.saveableProperties && !proto.saveableProperties) { @@ -951,7 +939,6 @@ export class SmartDataDbDoc