@memberjunction/metadata-sync 3.3.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.
- package/dist/config.d.ts +1 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +17 -27
- package/dist/config.js.map +1 -1
- package/dist/constants/metadata-keywords.d.ts +1 -0
- package/dist/constants/metadata-keywords.d.ts.map +1 -0
- package/dist/constants/metadata-keywords.js +31 -42
- package/dist/constants/metadata-keywords.js.map +1 -1
- package/dist/index.d.ts +39 -37
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +26 -62
- package/dist/index.js.map +1 -1
- package/dist/lib/EntityPropertyExtractor.d.ts +1 -0
- package/dist/lib/EntityPropertyExtractor.d.ts.map +1 -0
- package/dist/lib/EntityPropertyExtractor.js +1 -5
- package/dist/lib/EntityPropertyExtractor.js.map +1 -1
- package/dist/lib/FieldExternalizer.d.ts +1 -0
- package/dist/lib/FieldExternalizer.d.ts.map +1 -0
- package/dist/lib/FieldExternalizer.js +14 -21
- package/dist/lib/FieldExternalizer.js.map +1 -1
- package/dist/lib/RecordProcessor.d.ts +3 -2
- package/dist/lib/RecordProcessor.d.ts.map +1 -0
- package/dist/lib/RecordProcessor.js +16 -25
- package/dist/lib/RecordProcessor.js.map +1 -1
- package/dist/lib/RelatedEntityHandler.d.ts +3 -2
- package/dist/lib/RelatedEntityHandler.d.ts.map +1 -0
- package/dist/lib/RelatedEntityHandler.js +3 -9
- package/dist/lib/RelatedEntityHandler.js.map +1 -1
- package/dist/lib/config-manager.d.ts +2 -1
- package/dist/lib/config-manager.d.ts.map +1 -0
- package/dist/lib/config-manager.js +10 -15
- package/dist/lib/config-manager.js.map +1 -1
- package/dist/lib/database-reference-scanner.d.ts +3 -2
- package/dist/lib/database-reference-scanner.d.ts.map +1 -0
- package/dist/lib/database-reference-scanner.js +7 -13
- package/dist/lib/database-reference-scanner.js.map +1 -1
- package/dist/lib/deletion-auditor.d.ts +3 -2
- package/dist/lib/deletion-auditor.d.ts.map +1 -0
- package/dist/lib/deletion-auditor.js +9 -15
- package/dist/lib/deletion-auditor.js.map +1 -1
- package/dist/lib/deletion-report-generator.d.ts +2 -1
- package/dist/lib/deletion-report-generator.d.ts.map +1 -0
- package/dist/lib/deletion-report-generator.js +1 -5
- package/dist/lib/deletion-report-generator.js.map +1 -1
- package/dist/lib/entity-foreign-key-helper.d.ts +1 -0
- package/dist/lib/entity-foreign-key-helper.d.ts.map +1 -0
- package/dist/lib/entity-foreign-key-helper.js +1 -5
- package/dist/lib/entity-foreign-key-helper.js.map +1 -1
- package/dist/lib/file-backup-manager.d.ts +1 -0
- package/dist/lib/file-backup-manager.d.ts.map +1 -0
- package/dist/lib/file-backup-manager.js +22 -27
- package/dist/lib/file-backup-manager.js.map +1 -1
- package/dist/lib/file-write-batch.d.ts +2 -1
- package/dist/lib/file-write-batch.d.ts.map +1 -0
- package/dist/lib/file-write-batch.js +16 -21
- package/dist/lib/file-write-batch.js.map +1 -1
- package/dist/lib/json-preprocessor.d.ts +1 -0
- package/dist/lib/json-preprocessor.d.ts.map +1 -0
- package/dist/lib/json-preprocessor.js +21 -26
- package/dist/lib/json-preprocessor.js.map +1 -1
- package/dist/lib/json-write-helper.d.ts +2 -1
- package/dist/lib/json-write-helper.d.ts.map +1 -0
- package/dist/lib/json-write-helper.js +4 -11
- package/dist/lib/json-write-helper.js.map +1 -1
- package/dist/lib/provider-utils.d.ts +2 -1
- package/dist/lib/provider-utils.d.ts.map +1 -0
- package/dist/lib/provider-utils.js +15 -46
- package/dist/lib/provider-utils.js.map +1 -1
- package/dist/lib/record-dependency-analyzer.d.ts +2 -1
- package/dist/lib/record-dependency-analyzer.d.ts.map +1 -0
- package/dist/lib/record-dependency-analyzer.js +26 -31
- package/dist/lib/record-dependency-analyzer.js.map +1 -1
- package/dist/lib/singleton-manager.d.ts +2 -1
- package/dist/lib/singleton-manager.d.ts.map +1 -0
- package/dist/lib/singleton-manager.js +4 -9
- package/dist/lib/singleton-manager.js.map +1 -1
- package/dist/lib/sql-logger.d.ts +2 -1
- package/dist/lib/sql-logger.d.ts.map +1 -0
- package/dist/lib/sql-logger.js +8 -16
- package/dist/lib/sql-logger.js.map +1 -1
- package/dist/lib/sync-engine.d.ts +2 -1
- package/dist/lib/sync-engine.d.ts.map +1 -0
- package/dist/lib/sync-engine.js +58 -76
- package/dist/lib/sync-engine.js.map +1 -1
- package/dist/lib/transaction-manager.d.ts +2 -1
- package/dist/lib/transaction-manager.d.ts.map +1 -0
- package/dist/lib/transaction-manager.js +6 -11
- package/dist/lib/transaction-manager.js.map +1 -1
- package/dist/services/FileResetService.d.ts +1 -0
- package/dist/services/FileResetService.d.ts.map +1 -0
- package/dist/services/FileResetService.js +17 -24
- package/dist/services/FileResetService.js.map +1 -1
- package/dist/services/FormattingService.d.ts +2 -1
- package/dist/services/FormattingService.d.ts.map +1 -0
- package/dist/services/FormattingService.js +68 -73
- package/dist/services/FormattingService.js.map +1 -1
- package/dist/services/InitService.d.ts +1 -0
- package/dist/services/InitService.d.ts.map +1 -0
- package/dist/services/InitService.js +12 -19
- package/dist/services/InitService.js.map +1 -1
- package/dist/services/PullService.d.ts +2 -1
- package/dist/services/PullService.d.ts.map +1 -0
- package/dist/services/PullService.js +49 -60
- package/dist/services/PullService.js.map +1 -1
- package/dist/services/PushService.d.ts +2 -1
- package/dist/services/PushService.d.ts.map +1 -0
- package/dist/services/PushService.js +59 -68
- package/dist/services/PushService.js.map +1 -1
- package/dist/services/StatusService.d.ts +2 -1
- package/dist/services/StatusService.d.ts.map +1 -0
- package/dist/services/StatusService.js +14 -22
- package/dist/services/StatusService.js.map +1 -1
- package/dist/services/ValidationService.d.ts +2 -1
- package/dist/services/ValidationService.d.ts.map +1 -0
- package/dist/services/ValidationService.js +41 -71
- package/dist/services/ValidationService.js.map +1 -1
- package/dist/services/WatchService.d.ts +4 -3
- package/dist/services/WatchService.d.ts.map +1 -0
- package/dist/services/WatchService.js +35 -43
- package/dist/services/WatchService.js.map +1 -1
- package/dist/services/index.d.ts +9 -8
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +8 -19
- package/dist/services/index.js.map +1 -1
- package/dist/types/validation.d.ts +2 -1
- package/dist/types/validation.d.ts.map +1 -0
- package/dist/types/validation.js +2 -23
- package/dist/types/validation.js.map +1 -1
- package/package.json +23 -21
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"singleton-manager.js","sourceRoot":"","sources":["../../src/lib/singleton-manager.ts"],"names":[],"mappings":"
|
|
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"}
|
package/dist/lib/sql-logger.d.ts
CHANGED
|
@@ -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"}
|
package/dist/lib/sql-logger.js
CHANGED
|
@@ -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
|
-
|
|
10
|
-
|
|
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
|
|
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 =
|
|
110
|
-
await
|
|
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":"
|
|
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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"}
|
package/dist/lib/sync-engine.js
CHANGED
|
@@ -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
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
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
|
|
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 (
|
|
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(
|
|
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 =
|
|
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(
|
|
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 =
|
|
157
|
+
const fieldName = extractKeywordValue(value) || '';
|
|
175
158
|
return rootRecord.Get(fieldName);
|
|
176
159
|
}
|
|
177
160
|
// Check for @file: reference
|
|
178
|
-
if (value.startsWith(
|
|
179
|
-
const filePath =
|
|
180
|
-
const fullPath =
|
|
181
|
-
if (await
|
|
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
|
|
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
|
|
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 =
|
|
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
|
|
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
|
|
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(
|
|
227
|
-
const url =
|
|
209
|
+
if (value.startsWith(METADATA_KEYWORDS.URL)) {
|
|
210
|
+
const url = extractKeywordValue(value);
|
|
228
211
|
try {
|
|
229
|
-
const response = await
|
|
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(
|
|
238
|
-
const lookupStr =
|
|
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(
|
|
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(
|
|
321
|
-
const envVar =
|
|
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
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
530
|
-
if (await
|
|
512
|
+
const configPath = path.join(dir, '.mj-folder.json');
|
|
513
|
+
if (await fs.pathExists(configPath)) {
|
|
531
514
|
try {
|
|
532
|
-
return await
|
|
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 =
|
|
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(
|
|
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 =
|
|
624
|
-
const fullPath =
|
|
625
|
-
if (await
|
|
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
|
|
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
|
|
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,
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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 =
|
|
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 =
|
|
832
|
-
const resolvedPath =
|
|
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
|
|
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
|
|
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 (
|
|
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 (
|
|
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
|