@memberjunction/metadata-sync 3.4.0 → 4.0.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.
Files changed (129) hide show
  1. package/dist/config.d.ts +1 -0
  2. package/dist/config.d.ts.map +1 -0
  3. package/dist/config.js +17 -27
  4. package/dist/config.js.map +1 -1
  5. package/dist/constants/metadata-keywords.d.ts +1 -0
  6. package/dist/constants/metadata-keywords.d.ts.map +1 -0
  7. package/dist/constants/metadata-keywords.js +31 -42
  8. package/dist/constants/metadata-keywords.js.map +1 -1
  9. package/dist/index.d.ts +39 -37
  10. package/dist/index.d.ts.map +1 -0
  11. package/dist/index.js +26 -62
  12. package/dist/index.js.map +1 -1
  13. package/dist/lib/EntityPropertyExtractor.d.ts +1 -0
  14. package/dist/lib/EntityPropertyExtractor.d.ts.map +1 -0
  15. package/dist/lib/EntityPropertyExtractor.js +1 -5
  16. package/dist/lib/EntityPropertyExtractor.js.map +1 -1
  17. package/dist/lib/FieldExternalizer.d.ts +1 -0
  18. package/dist/lib/FieldExternalizer.d.ts.map +1 -0
  19. package/dist/lib/FieldExternalizer.js +14 -21
  20. package/dist/lib/FieldExternalizer.js.map +1 -1
  21. package/dist/lib/RecordProcessor.d.ts +3 -2
  22. package/dist/lib/RecordProcessor.d.ts.map +1 -0
  23. package/dist/lib/RecordProcessor.js +16 -25
  24. package/dist/lib/RecordProcessor.js.map +1 -1
  25. package/dist/lib/RelatedEntityHandler.d.ts +3 -2
  26. package/dist/lib/RelatedEntityHandler.d.ts.map +1 -0
  27. package/dist/lib/RelatedEntityHandler.js +3 -9
  28. package/dist/lib/RelatedEntityHandler.js.map +1 -1
  29. package/dist/lib/config-manager.d.ts +2 -1
  30. package/dist/lib/config-manager.d.ts.map +1 -0
  31. package/dist/lib/config-manager.js +10 -15
  32. package/dist/lib/config-manager.js.map +1 -1
  33. package/dist/lib/database-reference-scanner.d.ts +3 -2
  34. package/dist/lib/database-reference-scanner.d.ts.map +1 -0
  35. package/dist/lib/database-reference-scanner.js +7 -13
  36. package/dist/lib/database-reference-scanner.js.map +1 -1
  37. package/dist/lib/deletion-auditor.d.ts +3 -2
  38. package/dist/lib/deletion-auditor.d.ts.map +1 -0
  39. package/dist/lib/deletion-auditor.js +9 -15
  40. package/dist/lib/deletion-auditor.js.map +1 -1
  41. package/dist/lib/deletion-report-generator.d.ts +2 -1
  42. package/dist/lib/deletion-report-generator.d.ts.map +1 -0
  43. package/dist/lib/deletion-report-generator.js +1 -5
  44. package/dist/lib/deletion-report-generator.js.map +1 -1
  45. package/dist/lib/entity-foreign-key-helper.d.ts +1 -0
  46. package/dist/lib/entity-foreign-key-helper.d.ts.map +1 -0
  47. package/dist/lib/entity-foreign-key-helper.js +1 -5
  48. package/dist/lib/entity-foreign-key-helper.js.map +1 -1
  49. package/dist/lib/file-backup-manager.d.ts +1 -0
  50. package/dist/lib/file-backup-manager.d.ts.map +1 -0
  51. package/dist/lib/file-backup-manager.js +22 -27
  52. package/dist/lib/file-backup-manager.js.map +1 -1
  53. package/dist/lib/file-write-batch.d.ts +2 -1
  54. package/dist/lib/file-write-batch.d.ts.map +1 -0
  55. package/dist/lib/file-write-batch.js +16 -21
  56. package/dist/lib/file-write-batch.js.map +1 -1
  57. package/dist/lib/json-preprocessor.d.ts +1 -0
  58. package/dist/lib/json-preprocessor.d.ts.map +1 -0
  59. package/dist/lib/json-preprocessor.js +21 -26
  60. package/dist/lib/json-preprocessor.js.map +1 -1
  61. package/dist/lib/json-write-helper.d.ts +2 -1
  62. package/dist/lib/json-write-helper.d.ts.map +1 -0
  63. package/dist/lib/json-write-helper.js +4 -11
  64. package/dist/lib/json-write-helper.js.map +1 -1
  65. package/dist/lib/provider-utils.d.ts +2 -1
  66. package/dist/lib/provider-utils.d.ts.map +1 -0
  67. package/dist/lib/provider-utils.js +15 -46
  68. package/dist/lib/provider-utils.js.map +1 -1
  69. package/dist/lib/record-dependency-analyzer.d.ts +2 -1
  70. package/dist/lib/record-dependency-analyzer.d.ts.map +1 -0
  71. package/dist/lib/record-dependency-analyzer.js +26 -31
  72. package/dist/lib/record-dependency-analyzer.js.map +1 -1
  73. package/dist/lib/singleton-manager.d.ts +2 -1
  74. package/dist/lib/singleton-manager.d.ts.map +1 -0
  75. package/dist/lib/singleton-manager.js +4 -9
  76. package/dist/lib/singleton-manager.js.map +1 -1
  77. package/dist/lib/sql-logger.d.ts +2 -1
  78. package/dist/lib/sql-logger.d.ts.map +1 -0
  79. package/dist/lib/sql-logger.js +8 -16
  80. package/dist/lib/sql-logger.js.map +1 -1
  81. package/dist/lib/sync-engine.d.ts +2 -1
  82. package/dist/lib/sync-engine.d.ts.map +1 -0
  83. package/dist/lib/sync-engine.js +58 -76
  84. package/dist/lib/sync-engine.js.map +1 -1
  85. package/dist/lib/transaction-manager.d.ts +2 -1
  86. package/dist/lib/transaction-manager.d.ts.map +1 -0
  87. package/dist/lib/transaction-manager.js +6 -11
  88. package/dist/lib/transaction-manager.js.map +1 -1
  89. package/dist/services/FileResetService.d.ts +1 -0
  90. package/dist/services/FileResetService.d.ts.map +1 -0
  91. package/dist/services/FileResetService.js +17 -24
  92. package/dist/services/FileResetService.js.map +1 -1
  93. package/dist/services/FormattingService.d.ts +2 -1
  94. package/dist/services/FormattingService.d.ts.map +1 -0
  95. package/dist/services/FormattingService.js +68 -73
  96. package/dist/services/FormattingService.js.map +1 -1
  97. package/dist/services/InitService.d.ts +1 -0
  98. package/dist/services/InitService.d.ts.map +1 -0
  99. package/dist/services/InitService.js +12 -19
  100. package/dist/services/InitService.js.map +1 -1
  101. package/dist/services/PullService.d.ts +2 -1
  102. package/dist/services/PullService.d.ts.map +1 -0
  103. package/dist/services/PullService.js +49 -60
  104. package/dist/services/PullService.js.map +1 -1
  105. package/dist/services/PushService.d.ts +2 -1
  106. package/dist/services/PushService.d.ts.map +1 -0
  107. package/dist/services/PushService.js +59 -68
  108. package/dist/services/PushService.js.map +1 -1
  109. package/dist/services/StatusService.d.ts +2 -1
  110. package/dist/services/StatusService.d.ts.map +1 -0
  111. package/dist/services/StatusService.js +14 -22
  112. package/dist/services/StatusService.js.map +1 -1
  113. package/dist/services/ValidationService.d.ts +2 -1
  114. package/dist/services/ValidationService.d.ts.map +1 -0
  115. package/dist/services/ValidationService.js +41 -71
  116. package/dist/services/ValidationService.js.map +1 -1
  117. package/dist/services/WatchService.d.ts +4 -3
  118. package/dist/services/WatchService.d.ts.map +1 -0
  119. package/dist/services/WatchService.js +35 -43
  120. package/dist/services/WatchService.js.map +1 -1
  121. package/dist/services/index.d.ts +9 -8
  122. package/dist/services/index.d.ts.map +1 -0
  123. package/dist/services/index.js +8 -19
  124. package/dist/services/index.js.map +1 -1
  125. package/dist/types/validation.d.ts +2 -1
  126. package/dist/types/validation.d.ts.map +1 -0
  127. package/dist/types/validation.js +2 -23
  128. package/dist/types/validation.js.map +1 -1
  129. package/package.json +23 -21
@@ -1 +1 @@
1
- {"version":3,"file":"singleton-manager.js","sourceRoot":"","sources":["../../src/lib/singleton-manager.ts"],"names":[],"mappings":";AAAA;;;;;;;GAOG;;;AAEH,+CAA2C;AAG3C,iCAAiC;AACjC,IAAI,gBAAgB,GAAsB,IAAI,CAAC;AAE/C,yDAAyD;AACzD,IAAI,qBAAqB,GAA+B,IAAI,CAAC;AAE7D;;;;;;;;;;;;;;;GAeG;AACI,KAAK,UAAU,aAAa,CAAC,WAAqB;IACvD,gDAAgD;IAChD,IAAI,gBAAgB,EAAE,CAAC;QACrB,OAAO,gBAAgB,CAAC;IAC1B,CAAC;IAED,+CAA+C;IAC/C,IAAI,qBAAqB,EAAE,CAAC;QAC1B,OAAO,qBAAqB,CAAC;IAC/B,CAAC;IAED,2BAA2B;IAC3B,qBAAqB,GAAG,CAAC,KAAK,IAAI,EAAE;QAClC,gBAAgB,GAAG,IAAI,wBAAU,CAAC,WAAW,CAAC,CAAC;QAC/C,MAAM,gBAAgB,CAAC,UAAU,EAAE,CAAC;QACpC,OAAO,gBAAgB,CAAC;IAC1B,CAAC,CAAC,EAAE,CAAC;IAEL,OAAO,qBAAqB,CAAC;AAC/B,CAAC;AAnBD,sCAmBC;AAED;;;;;GAKG;AACH,SAAgB,eAAe;IAC7B,gBAAgB,GAAG,IAAI,CAAC;IACxB,qBAAqB,GAAG,IAAI,CAAC;AAC/B,CAAC;AAHD,0CAGC","sourcesContent":["/**\n * @fileoverview Singleton manager for shared instances across MetadataSync\n * @module singleton-manager\n * \n * This module ensures that expensive resources like SyncEngine are only\n * initialized once per process, preventing duplicate metadata refreshes\n * and improving performance.\n */\n\nimport { SyncEngine } from './sync-engine';\nimport { UserInfo } from '@memberjunction/core';\n\n/** Global SyncEngine instance */\nlet globalSyncEngine: SyncEngine | null = null;\n\n/** Promise to track ongoing SyncEngine initialization */\nlet syncEngineInitPromise: Promise<SyncEngine> | null = null;\n\n/**\n * Get or create a singleton SyncEngine instance\n * \n * Ensures that only one SyncEngine is created and initialized per process,\n * preventing duplicate metadata refreshes that cause the double GetAllMetadata()\n * console output.\n * \n * @param contextUser - The user context for database operations\n * @returns Promise resolving to initialized SyncEngine instance\n * \n * @example\n * ```typescript\n * const syncEngine = await getSyncEngine(getSystemUser());\n * // Use syncEngine for operations\n * ```\n */\nexport async function getSyncEngine(contextUser: UserInfo): Promise<SyncEngine> {\n // Return existing engine if already initialized\n if (globalSyncEngine) {\n return globalSyncEngine;\n }\n \n // Return ongoing initialization if in progress\n if (syncEngineInitPromise) {\n return syncEngineInitPromise;\n }\n \n // Start new initialization\n syncEngineInitPromise = (async () => {\n globalSyncEngine = new SyncEngine(contextUser);\n await globalSyncEngine.initialize();\n return globalSyncEngine;\n })();\n \n return syncEngineInitPromise;\n}\n\n/**\n * Reset the singleton SyncEngine instance\n * \n * Should be called when cleaning up resources to ensure a fresh\n * instance is created on the next request.\n */\nexport function resetSyncEngine(): void {\n globalSyncEngine = null;\n syncEngineInitPromise = null;\n}"]}
1
+ {"version":3,"file":"singleton-manager.js","sourceRoot":"","sources":["../../src/lib/singleton-manager.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAG3C,iCAAiC;AACjC,IAAI,gBAAgB,GAAsB,IAAI,CAAC;AAE/C,yDAAyD;AACzD,IAAI,qBAAqB,GAA+B,IAAI,CAAC;AAE7D;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,WAAqB;IACvD,gDAAgD;IAChD,IAAI,gBAAgB,EAAE,CAAC;QACrB,OAAO,gBAAgB,CAAC;IAC1B,CAAC;IAED,+CAA+C;IAC/C,IAAI,qBAAqB,EAAE,CAAC;QAC1B,OAAO,qBAAqB,CAAC;IAC/B,CAAC;IAED,2BAA2B;IAC3B,qBAAqB,GAAG,CAAC,KAAK,IAAI,EAAE;QAClC,gBAAgB,GAAG,IAAI,UAAU,CAAC,WAAW,CAAC,CAAC;QAC/C,MAAM,gBAAgB,CAAC,UAAU,EAAE,CAAC;QACpC,OAAO,gBAAgB,CAAC;IAC1B,CAAC,CAAC,EAAE,CAAC;IAEL,OAAO,qBAAqB,CAAC;AAC/B,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe;IAC7B,gBAAgB,GAAG,IAAI,CAAC;IACxB,qBAAqB,GAAG,IAAI,CAAC;AAC/B,CAAC"}
@@ -5,7 +5,7 @@
5
5
  * This module provides SQL logging functionality to capture all database operations
6
6
  * during push commands. It supports both raw SQL logging and migration-formatted output.
7
7
  */
8
- import { SyncConfig } from '../config';
8
+ import { SyncConfig } from '../config.js';
9
9
  export interface SQLLoggerOptions {
10
10
  enabled: boolean;
11
11
  outputDirectory: string;
@@ -42,3 +42,4 @@ export declare class SQLLogger {
42
42
  */
43
43
  private formatParamValue;
44
44
  }
45
+ //# sourceMappingURL=sql-logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sql-logger.d.ts","sourceRoot":"","sources":["../../src/lib/sql-logger.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAEvC,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,OAAO,CAAC;CAC5B;AAED,qBAAa,SAAS;IACpB,OAAO,CAAC,OAAO,CAAmB;IAClC,OAAO,CAAC,UAAU,CAAgB;IAClC,OAAO,CAAC,aAAa,CAAS;gBAElB,UAAU,EAAE,UAAU,GAAG,IAAI;IAQzC,IAAI,OAAO,IAAI,OAAO,CAErB;IAED;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAUjC;;OAEG;IACH,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,GAAG,EAAE,GAAG,IAAI;IAmB/C;;OAEG;IACH,cAAc,CAAC,MAAM,EAAE,OAAO,GAAG,QAAQ,GAAG,UAAU,GAAG,IAAI;IAQ7D;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAgD7C;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb;;OAEG;IACH,OAAO,CAAC,gBAAgB;CAgBzB"}
@@ -1,4 +1,3 @@
1
- "use strict";
2
1
  /**
3
2
  * @fileoverview SQL Logger for capturing database operations during metadata sync
4
3
  * @module sql-logger
@@ -6,18 +5,12 @@
6
5
  * This module provides SQL logging functionality to capture all database operations
7
6
  * during push commands. It supports both raw SQL logging and migration-formatted output.
8
7
  */
9
- var __importDefault = (this && this.__importDefault) || function (mod) {
10
- return (mod && mod.__esModule) ? mod : { "default": mod };
11
- };
12
- Object.defineProperty(exports, "__esModule", { value: true });
13
- exports.SQLLogger = void 0;
14
- const fs_extra_1 = __importDefault(require("fs-extra"));
15
- const path_1 = __importDefault(require("path"));
16
- class SQLLogger {
17
- options;
18
- statements = [];
19
- isInitialized = false;
8
+ import fs from 'fs-extra';
9
+ import path from 'path';
10
+ export class SQLLogger {
20
11
  constructor(syncConfig) {
12
+ this.statements = [];
13
+ this.isInitialized = false;
21
14
  this.options = {
22
15
  enabled: syncConfig?.sqlLogging?.enabled ?? false,
23
16
  outputDirectory: syncConfig?.sqlLogging?.outputDirectory ?? './sql_logging',
@@ -35,7 +28,7 @@ class SQLLogger {
35
28
  return;
36
29
  }
37
30
  // Ensure output directory exists
38
- await fs_extra_1.default.ensureDir(this.options.outputDirectory);
31
+ await fs.ensureDir(this.options.outputDirectory);
39
32
  this.isInitialized = true;
40
33
  }
41
34
  /**
@@ -106,8 +99,8 @@ class SQLLogger {
106
99
  ...this.statements
107
100
  ].join('\n');
108
101
  }
109
- const filePath = path_1.default.join(this.options.outputDirectory, filename);
110
- await fs_extra_1.default.writeFile(filePath, content, 'utf8');
102
+ const filePath = path.join(this.options.outputDirectory, filename);
103
+ await fs.writeFile(filePath, content, 'utf8');
111
104
  return filePath;
112
105
  }
113
106
  /**
@@ -136,5 +129,4 @@ class SQLLogger {
136
129
  return String(value);
137
130
  }
138
131
  }
139
- exports.SQLLogger = SQLLogger;
140
132
  //# sourceMappingURL=sql-logger.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sql-logger.js","sourceRoot":"","sources":["../../src/lib/sql-logger.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview SQL Logger for capturing database operations during metadata sync\n * @module sql-logger\n * \n * This module provides SQL logging functionality to capture all database operations\n * during push commands. It supports both raw SQL logging and migration-formatted output.\n */\n\nimport fs from 'fs-extra';\nimport path from 'path';\nimport { SyncConfig } from '../config';\n\nexport interface SQLLoggerOptions {\n enabled: boolean;\n outputDirectory: string;\n formatAsMigration: boolean;\n}\n\nexport class SQLLogger {\n private options: SQLLoggerOptions;\n private statements: string[] = [];\n private isInitialized = false;\n \n constructor(syncConfig: SyncConfig | null) {\n this.options = {\n enabled: syncConfig?.sqlLogging?.enabled ?? false,\n outputDirectory: syncConfig?.sqlLogging?.outputDirectory ?? './sql_logging',\n formatAsMigration: syncConfig?.sqlLogging?.formatAsMigration ?? false\n };\n }\n \n get enabled(): boolean {\n return this.options.enabled;\n }\n \n /**\n * Initialize the SQL logger and prepare output directory\n */\n async initialize(): Promise<void> {\n if (!this.options.enabled || this.isInitialized) {\n return;\n }\n \n // Ensure output directory exists\n await fs.ensureDir(this.options.outputDirectory);\n this.isInitialized = true;\n }\n \n /**\n * Log a SQL statement\n */\n logStatement(sql: string, params?: any[]): void {\n if (!this.options.enabled) {\n return;\n }\n \n // Format SQL with parameters inline for readability\n let formattedSql = sql;\n if (params && params.length > 0) {\n // Replace parameter placeholders with actual values\n params.forEach((param, index) => {\n const placeholder = `@param${index + 1}`;\n const value = this.formatParamValue(param);\n formattedSql = formattedSql.replace(new RegExp(placeholder, 'g'), value);\n });\n }\n \n this.statements.push(formattedSql);\n }\n \n /**\n * Log a transaction boundary\n */\n logTransaction(action: 'BEGIN' | 'COMMIT' | 'ROLLBACK'): void {\n if (!this.options.enabled) {\n return;\n }\n \n this.statements.push(`${action} TRANSACTION;`);\n }\n \n /**\n * Write the collected SQL statements to file\n */\n async writeLog(): Promise<string | undefined> {\n if (!this.options.enabled || this.statements.length === 0) {\n return undefined;\n }\n \n await this.initialize();\n \n const timestamp = new Date().toISOString().replace(/[:.]/g, '-');\n let filename: string;\n let content: string;\n \n if (this.options.formatAsMigration) {\n // Format as Flyway migration\n const migrationTimestamp = timestamp.replace(/[-T]/g, '').substring(0, 14);\n filename = `V${migrationTimestamp}__MetadataSync_Push.sql`;\n \n content = [\n '-- MemberJunction MetadataSync Push Migration',\n `-- Generated at: ${new Date().toISOString()}`,\n '-- Description: Metadata changes pushed via mj sync push command',\n '',\n '-- Note: Schema placeholders can be replaced during deployment',\n '-- Replace ${flyway:defaultSchema} with your target schema name',\n '',\n ...this.statements.map(stmt => {\n // Add schema placeholders for migration format\n return stmt.replace(/(\\[?)__mj(\\]?)\\./g, '${flyway:defaultSchema}.');\n })\n ].join('\\n');\n } else {\n // Regular SQL log format\n filename = `metadatasync-push-${timestamp}.sql`;\n \n content = [\n '-- MemberJunction MetadataSync SQL Log',\n `-- Generated at: ${new Date().toISOString()}`,\n `-- Total statements: ${this.statements.length}`,\n '',\n ...this.statements\n ].join('\\n');\n }\n \n const filePath = path.join(this.options.outputDirectory, filename);\n await fs.writeFile(filePath, content, 'utf8');\n \n return filePath;\n }\n \n /**\n * Clear all logged statements\n */\n clear(): void {\n this.statements = [];\n }\n \n /**\n * Format a parameter value for SQL\n */\n private formatParamValue(value: any): string {\n if (value === null) {\n return 'NULL';\n }\n if (typeof value === 'string') {\n // Escape single quotes and wrap in quotes\n return `'${value.replace(/'/g, \"''\")}'`;\n }\n if (typeof value === 'boolean') {\n return value ? '1' : '0';\n }\n if (value instanceof Date) {\n return `'${value.toISOString()}'`;\n }\n return String(value);\n }\n}"]}
1
+ {"version":3,"file":"sql-logger.js","sourceRoot":"","sources":["../../src/lib/sql-logger.ts"],"names":[],"mappings":"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"}
@@ -8,7 +8,7 @@
8
8
  * manages entity operations, and provides utilities for data transformation.
9
9
  */
10
10
  import { EntityInfo, BaseEntity, UserInfo } from '@memberjunction/core';
11
- import { EntityConfig } from '../config';
11
+ import { EntityConfig } from '../config.js';
12
12
  /**
13
13
  * Custom error class for lookup failures that can be deferred.
14
14
  * When a lookup with `?allowDefer` flag fails, this error is thrown instead of a regular Error.
@@ -380,3 +380,4 @@ export declare class SyncEngine {
380
380
  */
381
381
  private processJsonFieldValues;
382
382
  }
383
+ //# sourceMappingURL=sync-engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync-engine.d.ts","sourceRoot":"","sources":["../../src/lib/sync-engine.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,3 @@
1
- "use strict";
2
1
  /**
3
2
  * @fileoverview Core synchronization engine for MemberJunction metadata
4
3
  * @module sync-engine
@@ -8,32 +7,19 @@
8
7
  * special reference types (@file, @url, @lookup, @env, @parent, @root, @template),
9
8
  * manages entity operations, and provides utilities for data transformation.
10
9
  */
11
- var __importDefault = (this && this.__importDefault) || function (mod) {
12
- return (mod && mod.__esModule) ? mod : { "default": mod };
13
- };
14
- Object.defineProperty(exports, "__esModule", { value: true });
15
- exports.SyncEngine = exports.DeferrableLookupError = void 0;
16
- const path_1 = __importDefault(require("path"));
17
- const fs_extra_1 = __importDefault(require("fs-extra"));
18
- const crypto_1 = __importDefault(require("crypto"));
19
- const axios_1 = __importDefault(require("axios"));
20
- const core_1 = require("@memberjunction/core");
21
- const json_preprocessor_1 = require("./json-preprocessor");
22
- const metadata_keywords_1 = require("../constants/metadata-keywords");
10
+ import path from 'path';
11
+ import fs from 'fs-extra';
12
+ import crypto from 'crypto';
13
+ import axios from 'axios';
14
+ import { Metadata, RunView, CompositeKey } from '@memberjunction/core';
15
+ import { JsonPreprocessor } from './json-preprocessor.js';
16
+ import { METADATA_KEYWORDS, isMetadataKeyword, isNonKeywordAtSymbol, extractKeywordValue } from '../constants/metadata-keywords.js';
23
17
  /**
24
18
  * Custom error class for lookup failures that can be deferred.
25
19
  * When a lookup with `?allowDefer` flag fails, this error is thrown instead of a regular Error.
26
20
  * The calling code can catch this specific error type and queue the lookup for later retry.
27
21
  */
28
- class DeferrableLookupError extends Error {
29
- /** The entity name being looked up */
30
- entityName;
31
- /** The lookup fields and values that failed */
32
- lookupFields;
33
- /** The original lookup string value */
34
- originalValue;
35
- /** The field name where this lookup was used */
36
- targetFieldName;
22
+ export class DeferrableLookupError extends Error {
37
23
  constructor(message, entityName, lookupFields, originalValue, targetFieldName) {
38
24
  super(message);
39
25
  this.name = 'DeferrableLookupError';
@@ -45,7 +31,6 @@ class DeferrableLookupError extends Error {
45
31
  Object.setPrototypeOf(this, DeferrableLookupError.prototype);
46
32
  }
47
33
  }
48
- exports.DeferrableLookupError = DeferrableLookupError;
49
34
  /**
50
35
  * Core engine for synchronizing MemberJunction metadata between database and files
51
36
  *
@@ -58,15 +43,13 @@ exports.DeferrableLookupError = DeferrableLookupError;
58
43
  * const value = await syncEngine.processFieldValue('@lookup:Users.Email=admin@example.com', '/path/to/base');
59
44
  * ```
60
45
  */
61
- class SyncEngine {
62
- metadata;
63
- contextUser;
46
+ export class SyncEngine {
64
47
  /**
65
48
  * Creates a new SyncEngine instance
66
49
  * @param contextUser - The user context for database operations
67
50
  */
68
51
  constructor(contextUser) {
69
- this.metadata = new core_1.Metadata();
52
+ this.metadata = new Metadata();
70
53
  this.contextUser = contextUser;
71
54
  }
72
55
  /**
@@ -145,15 +128,15 @@ class SyncEngine {
145
128
  }
146
129
  // If string starts with @ but isn't one of our known reference types, return as-is
147
130
  // This handles cases like npm package names (@mui/material, @angular/core, etc.)
148
- if ((0, metadata_keywords_1.isNonKeywordAtSymbol)(value)) {
131
+ if (isNonKeywordAtSymbol(value)) {
149
132
  return value; // Not a MetadataSync reference, just a string that happens to start with @
150
133
  }
151
134
  // Check for @parent: reference
152
- if (value.startsWith(metadata_keywords_1.METADATA_KEYWORDS.PARENT)) {
135
+ if (value.startsWith(METADATA_KEYWORDS.PARENT)) {
153
136
  if (!parentRecord) {
154
137
  throw new Error(`@parent reference used but no parent record available: ${value}`);
155
138
  }
156
- const parentFieldName = (0, metadata_keywords_1.extractKeywordValue)(value) || '';
139
+ const parentFieldName = extractKeywordValue(value) || '';
157
140
  const resolvedValue = parentRecord.Get(parentFieldName);
158
141
  // Track the resolution if collector is provided
159
142
  if (resolutionCollector && fieldName) {
@@ -167,37 +150,37 @@ class SyncEngine {
167
150
  return resolvedValue;
168
151
  }
169
152
  // Check for @root: reference
170
- if (value.startsWith(metadata_keywords_1.METADATA_KEYWORDS.ROOT)) {
153
+ if (value.startsWith(METADATA_KEYWORDS.ROOT)) {
171
154
  if (!rootRecord) {
172
155
  throw new Error(`@root reference used but no root record available: ${value}`);
173
156
  }
174
- const fieldName = (0, metadata_keywords_1.extractKeywordValue)(value) || '';
157
+ const fieldName = extractKeywordValue(value) || '';
175
158
  return rootRecord.Get(fieldName);
176
159
  }
177
160
  // Check for @file: reference
178
- if (value.startsWith(metadata_keywords_1.METADATA_KEYWORDS.FILE)) {
179
- const filePath = (0, metadata_keywords_1.extractKeywordValue)(value);
180
- const fullPath = path_1.default.resolve(baseDir, filePath);
181
- if (await fs_extra_1.default.pathExists(fullPath)) {
161
+ if (value.startsWith(METADATA_KEYWORDS.FILE)) {
162
+ const filePath = extractKeywordValue(value);
163
+ const fullPath = path.resolve(baseDir, filePath);
164
+ if (await fs.pathExists(fullPath)) {
182
165
  // Check if this is a JSON file that might contain @include directives
183
166
  if (fullPath.endsWith('.json')) {
184
167
  try {
185
168
  // Parse as JSON and check for @include directives
186
- const jsonContent = await fs_extra_1.default.readJson(fullPath);
169
+ const jsonContent = await fs.readJson(fullPath);
187
170
  // Check if the JSON contains any @include directives
188
171
  const jsonString = JSON.stringify(jsonContent);
189
172
  const hasIncludes = jsonString.includes('"@include') || jsonString.includes('"@include.');
190
173
  let processedJson;
191
174
  if (hasIncludes) {
192
175
  // Process @include directives with a fresh preprocessor instance
193
- const preprocessor = new json_preprocessor_1.JsonPreprocessor();
176
+ const preprocessor = new JsonPreprocessor();
194
177
  processedJson = await preprocessor.processFile(fullPath);
195
178
  }
196
179
  else {
197
180
  processedJson = jsonContent;
198
181
  }
199
182
  // Now recursively process any @file references within the JSON
200
- const fileDir = path_1.default.dirname(fullPath);
183
+ const fileDir = path.dirname(fullPath);
201
184
  processedJson = await this.processJsonFieldValues(processedJson, fileDir, parentRecord, rootRecord, depth + 1, batchContext);
202
185
  // Return the processed JSON object directly without stringifying
203
186
  // Let BaseEntity handle serialization when saving to database
@@ -206,14 +189,14 @@ class SyncEngine {
206
189
  }
207
190
  catch (jsonError) {
208
191
  // Not valid JSON or error processing, fall back to text file handling
209
- const fileContent = await fs_extra_1.default.readFile(fullPath, 'utf-8');
192
+ const fileContent = await fs.readFile(fullPath, 'utf-8');
210
193
  // Process the file content for {@include} references in text files
211
194
  return await this.processFileContentWithIncludes(fileContent, fullPath);
212
195
  }
213
196
  }
214
197
  else {
215
198
  // Not a JSON file, process as text with {@include} support
216
- const fileContent = await fs_extra_1.default.readFile(fullPath, 'utf-8');
199
+ const fileContent = await fs.readFile(fullPath, 'utf-8');
217
200
  // Process the file content for {@include} references
218
201
  return await this.processFileContentWithIncludes(fileContent, fullPath);
219
202
  }
@@ -223,10 +206,10 @@ class SyncEngine {
223
206
  }
224
207
  }
225
208
  // Check for @url: reference
226
- if (value.startsWith(metadata_keywords_1.METADATA_KEYWORDS.URL)) {
227
- const url = (0, metadata_keywords_1.extractKeywordValue)(value);
209
+ if (value.startsWith(METADATA_KEYWORDS.URL)) {
210
+ const url = extractKeywordValue(value);
228
211
  try {
229
- const response = await axios_1.default.get(url);
212
+ const response = await axios.get(url);
230
213
  return response.data;
231
214
  }
232
215
  catch (error) {
@@ -234,8 +217,8 @@ class SyncEngine {
234
217
  }
235
218
  }
236
219
  // Check for @lookup: reference
237
- if (value.startsWith(metadata_keywords_1.METADATA_KEYWORDS.LOOKUP)) {
238
- const lookupStr = (0, metadata_keywords_1.extractKeywordValue)(value);
220
+ if (value.startsWith(METADATA_KEYWORDS.LOOKUP)) {
221
+ const lookupStr = extractKeywordValue(value);
239
222
  // Parse lookup with optional flags: ?create, ?allowDefer
240
223
  // Format: EntityName.Field1=Value1&Field2=Value2?create&allowDefer&OtherField=Value
241
224
  const entityMatch = lookupStr.match(/^([^.]+)\./);
@@ -270,7 +253,7 @@ class SyncEngine {
270
253
  const processedValue = await this.processFieldValue(rawFieldValue, baseDir, parentRecord, rootRecord, depth + 1, batchContext, nestedCollector, lookupFieldName // Pass field name for tracking
271
254
  );
272
255
  // If the raw value was a lookup expression that got resolved, track it as nested
273
- if (rawFieldValue.startsWith(metadata_keywords_1.METADATA_KEYWORDS.LOOKUP) && rawFieldValue !== processedValue) {
256
+ if (rawFieldValue.startsWith(METADATA_KEYWORDS.LOOKUP) && rawFieldValue !== processedValue) {
274
257
  nestedResolutions.push({
275
258
  expression: rawFieldValue,
276
259
  resolved: String(processedValue)
@@ -317,8 +300,8 @@ class SyncEngine {
317
300
  return resolvedValue;
318
301
  }
319
302
  // Check for @env: reference
320
- if (value.startsWith(metadata_keywords_1.METADATA_KEYWORDS.ENV)) {
321
- const envVar = (0, metadata_keywords_1.extractKeywordValue)(value);
303
+ if (value.startsWith(METADATA_KEYWORDS.ENV)) {
304
+ const envVar = extractKeywordValue(value);
322
305
  const envValue = process.env[envVar];
323
306
  if (envValue === undefined) {
324
307
  throw new Error(`Environment variable not found: ${envVar}`);
@@ -394,7 +377,7 @@ class SyncEngine {
394
377
  }
395
378
  }
396
379
  // Not found in batch context, check database
397
- const rv = new core_1.RunView();
380
+ const rv = new RunView();
398
381
  const entityInfo = this.metadata.EntityByName(entityName);
399
382
  if (!entityInfo) {
400
383
  throw new Error(`Entity not found: ${entityName}`);
@@ -494,12 +477,12 @@ class SyncEngine {
494
477
  * @throws Error if any default value processing fails
495
478
  */
496
479
  async buildDefaults(filePath, entityConfig) {
497
- const parts = path_1.default.dirname(filePath).split(path_1.default.sep);
480
+ const parts = path.dirname(filePath).split(path.sep);
498
481
  let defaults = { ...entityConfig.defaults };
499
482
  // Walk up the directory tree building defaults
500
483
  let currentPath = '';
501
484
  for (const part of parts) {
502
- currentPath = path_1.default.join(currentPath, part);
485
+ currentPath = path.join(currentPath, part);
503
486
  const folderConfig = await this.loadFolderConfig(currentPath);
504
487
  if (folderConfig?.defaults) {
505
488
  defaults = { ...defaults, ...folderConfig.defaults };
@@ -507,7 +490,7 @@ class SyncEngine {
507
490
  }
508
491
  // Process all default values (lookups, file references, etc.)
509
492
  const processedDefaults = {};
510
- const baseDir = path_1.default.dirname(filePath);
493
+ const baseDir = path.dirname(filePath);
511
494
  for (const [field, value] of Object.entries(defaults)) {
512
495
  try {
513
496
  processedDefaults[field] = await this.processFieldValue(value, baseDir, null, null, 0);
@@ -526,10 +509,10 @@ class SyncEngine {
526
509
  * @private
527
510
  */
528
511
  async loadFolderConfig(dir) {
529
- const configPath = path_1.default.join(dir, '.mj-folder.json');
530
- if (await fs_extra_1.default.pathExists(configPath)) {
512
+ const configPath = path.join(dir, '.mj-folder.json');
513
+ if (await fs.pathExists(configPath)) {
531
514
  try {
532
- return await fs_extra_1.default.readJson(configPath);
515
+ return await fs.readJson(configPath);
533
516
  }
534
517
  catch (error) {
535
518
  console.error(`Error loading folder config at ${configPath}:`, error);
@@ -559,7 +542,7 @@ class SyncEngine {
559
542
  * ```
560
543
  */
561
544
  calculateChecksum(data) {
562
- const hash = crypto_1.default.createHash('sha256');
545
+ const hash = crypto.createHash('sha256');
563
546
  // Use a replacer function to ensure consistent key ordering for deterministic checksums
564
547
  const sortedJson = JSON.stringify(data, this.sortedReplacer, 2);
565
548
  hash.update(sortedJson);
@@ -617,23 +600,23 @@ class SyncEngine {
617
600
  }
618
601
  const result = {};
619
602
  for (const [key, value] of Object.entries(obj)) {
620
- if (typeof value === 'string' && value.startsWith(metadata_keywords_1.METADATA_KEYWORDS.FILE)) {
603
+ if (typeof value === 'string' && value.startsWith(METADATA_KEYWORDS.FILE)) {
621
604
  // Process @file reference and include actual content
622
605
  try {
623
- const filePath = (0, metadata_keywords_1.extractKeywordValue)(value);
624
- const fullPath = path_1.default.isAbsolute(filePath) ? filePath : path_1.default.join(entityDir, filePath);
625
- if (await fs_extra_1.default.pathExists(fullPath)) {
606
+ const filePath = extractKeywordValue(value);
607
+ const fullPath = path.isAbsolute(filePath) ? filePath : path.join(entityDir, filePath);
608
+ if (await fs.pathExists(fullPath)) {
626
609
  let processedContent;
627
610
  // Check if this is a JSON file that might contain @include directives or nested @file references
628
611
  if (fullPath.endsWith('.json')) {
629
612
  try {
630
- const jsonContent = await fs_extra_1.default.readJson(fullPath);
613
+ const jsonContent = await fs.readJson(fullPath);
631
614
  const jsonString = JSON.stringify(jsonContent);
632
615
  const hasIncludes = jsonString.includes('"@include') || jsonString.includes('"@include.');
633
616
  let resolvedJsonContent;
634
617
  if (hasIncludes) {
635
618
  // Process @include directives first
636
- const preprocessor = new json_preprocessor_1.JsonPreprocessor();
619
+ const preprocessor = new JsonPreprocessor();
637
620
  resolvedJsonContent = await preprocessor.processFile(fullPath);
638
621
  }
639
622
  else {
@@ -641,18 +624,18 @@ class SyncEngine {
641
624
  }
642
625
  // Recursively resolve any nested @file references in the loaded JSON
643
626
  // Use the JSON file's directory as the base for resolving relative paths
644
- const fullyResolvedContent = await this.resolveFileReferencesForChecksum(resolvedJsonContent, path_1.default.dirname(fullPath));
627
+ const fullyResolvedContent = await this.resolveFileReferencesForChecksum(resolvedJsonContent, path.dirname(fullPath));
645
628
  processedContent = JSON.stringify(fullyResolvedContent, null, 2);
646
629
  }
647
630
  catch {
648
631
  // Not valid JSON, process as text
649
- const content = await fs_extra_1.default.readFile(fullPath, 'utf-8');
632
+ const content = await fs.readFile(fullPath, 'utf-8');
650
633
  processedContent = await this.processFileContentWithIncludes(content, fullPath);
651
634
  }
652
635
  }
653
636
  else {
654
637
  // Text file - process {@include} references
655
- const content = await fs_extra_1.default.readFile(fullPath, 'utf-8');
638
+ const content = await fs.readFile(fullPath, 'utf-8');
656
639
  processedContent = await this.processFileContentWithIncludes(content, fullPath);
657
640
  }
658
641
  result[key] = {
@@ -755,7 +738,7 @@ class SyncEngine {
755
738
  }
756
739
  // First, check if the record exists using RunView to avoid "Error in BaseEntity.Load" messages
757
740
  // when records don't exist (which is a normal scenario during sync operations)
758
- const rv = new core_1.RunView();
741
+ const rv = new RunView();
759
742
  // Build filter for primary key(s)
760
743
  const filters = [];
761
744
  for (const pk of entityInfo.PrimaryKeys) {
@@ -780,7 +763,7 @@ class SyncEngine {
780
763
  }
781
764
  // Record exists, now load it properly through the entity
782
765
  const entity = await this.createEntityObject(entityName);
783
- const compositeKey = new core_1.CompositeKey();
766
+ const compositeKey = new CompositeKey();
784
767
  compositeKey.LoadFromSimpleObject(primaryKey);
785
768
  const loaded = await entity.InnerLoad(compositeKey);
786
769
  return loaded ? entity : null;
@@ -813,7 +796,7 @@ class SyncEngine {
813
796
  */
814
797
  async processFileContentWithIncludes(content, filePath, visitedPaths = new Set()) {
815
798
  // Add current file to visited set
816
- const absolutePath = path_1.default.resolve(filePath);
799
+ const absolutePath = path.resolve(filePath);
817
800
  if (visitedPaths.has(absolutePath)) {
818
801
  throw new Error(`Circular reference detected: ${absolutePath} is already being processed`);
819
802
  }
@@ -828,15 +811,15 @@ class SyncEngine {
828
811
  const [fullMatch, includePath] = match;
829
812
  const trimmedPath = includePath.trim();
830
813
  // Resolve the include path relative to the current file's directory
831
- const currentDir = path_1.default.dirname(filePath);
832
- const resolvedPath = path_1.default.resolve(currentDir, trimmedPath);
814
+ const currentDir = path.dirname(filePath);
815
+ const resolvedPath = path.resolve(currentDir, trimmedPath);
833
816
  try {
834
817
  // Check if the included file exists
835
- if (!await fs_extra_1.default.pathExists(resolvedPath)) {
818
+ if (!await fs.pathExists(resolvedPath)) {
836
819
  throw new Error(`Included file not found: ${resolvedPath}`);
837
820
  }
838
821
  // Read the included file
839
- const includedContent = await fs_extra_1.default.readFile(resolvedPath, 'utf-8');
822
+ const includedContent = await fs.readFile(resolvedPath, 'utf-8');
840
823
  // Recursively process the included content for nested includes
841
824
  const processedInclude = await this.processFileContentWithIncludes(includedContent, resolvedPath, new Set(visitedPaths) // Pass a copy to allow the same file in different branches
842
825
  );
@@ -873,7 +856,7 @@ class SyncEngine {
873
856
  }
874
857
  // Handle top-level strings (important for array elements that are strings with @ syntax)
875
858
  if (typeof obj === 'string') {
876
- if ((0, metadata_keywords_1.isMetadataKeyword)(obj)) {
859
+ if (isMetadataKeyword(obj)) {
877
860
  return this.processFieldValue(obj, baseDir, parentRecord, rootRecord, depth, batchContext);
878
861
  }
879
862
  return obj;
@@ -890,7 +873,7 @@ class SyncEngine {
890
873
  if (typeof value === 'string') {
891
874
  // Check if this looks like a reference that needs processing
892
875
  // Only process known reference types, ignore other @ strings (like npm packages)
893
- if ((0, metadata_keywords_1.isMetadataKeyword)(value)) {
876
+ if (isMetadataKeyword(value)) {
894
877
  result[key] = await this.processFieldValue(value, baseDir, parentRecord, rootRecord, depth, batchContext);
895
878
  }
896
879
  else {
@@ -912,5 +895,4 @@ class SyncEngine {
912
895
  return obj;
913
896
  }
914
897
  }
915
- exports.SyncEngine = SyncEngine;
916
898
  //# sourceMappingURL=sync-engine.js.map