sfdx-git-delta 6.41.2 → 6.43.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/README.md +35 -2
- package/lib/adapter/GitAdapter.d.ts +51 -2
- package/lib/adapter/GitAdapter.js +367 -41
- package/lib/adapter/GitAdapter.js.map +1 -1
- package/lib/adapter/gitBatchCatFile.d.ts +26 -4
- package/lib/adapter/gitBatchCatFile.js +128 -44
- package/lib/adapter/gitBatchCatFile.js.map +1 -1
- package/lib/adapter/gitBlobReader.d.ts +58 -0
- package/lib/adapter/gitBlobReader.js +27 -0
- package/lib/adapter/gitBlobReader.js.map +1 -0
- package/lib/adapter/ioExecutor.d.ts +18 -6
- package/lib/adapter/ioExecutor.js +97 -12
- package/lib/adapter/ioExecutor.js.map +1 -1
- package/lib/commands/sgd/source/delta.d.ts +2 -0
- package/lib/commands/sgd/source/delta.js +31 -1
- package/lib/commands/sgd/source/delta.js.map +1 -1
- package/lib/constant/cliConstants.d.ts +2 -0
- package/lib/constant/cliConstants.js +4 -0
- package/lib/constant/cliConstants.js.map +1 -1
- package/lib/constant/gitConstants.d.ts +1 -0
- package/lib/constant/gitConstants.js +4 -0
- package/lib/constant/gitConstants.js.map +1 -1
- package/lib/main.js +35 -7
- package/lib/main.js.map +1 -1
- package/lib/metadata/MetadataRepositoryImpl.d.ts +1 -0
- package/lib/metadata/MetadataRepositoryImpl.js +14 -2
- package/lib/metadata/MetadataRepositoryImpl.js.map +1 -1
- package/lib/post-processor/changesManifestProcessor.d.ts +15 -0
- package/lib/post-processor/changesManifestProcessor.js +50 -0
- package/lib/post-processor/changesManifestProcessor.js.map +1 -0
- package/lib/post-processor/flowTranslationProcessor.d.ts +31 -14
- package/lib/post-processor/flowTranslationProcessor.js +146 -51
- package/lib/post-processor/flowTranslationProcessor.js.map +1 -1
- package/lib/post-processor/packageGenerator.d.ts +1 -2
- package/lib/post-processor/packageGenerator.js +23 -34
- package/lib/post-processor/packageGenerator.js.map +1 -1
- package/lib/post-processor/postProcessorManager.js +9 -6
- package/lib/post-processor/postProcessorManager.js.map +1 -1
- package/lib/service/botHandler.d.ts +2 -1
- package/lib/service/botHandler.js +4 -3
- package/lib/service/botHandler.js.map +1 -1
- package/lib/service/containedDecomposedHandler.d.ts +3 -2
- package/lib/service/containedDecomposedHandler.js +6 -6
- package/lib/service/containedDecomposedHandler.js.map +1 -1
- package/lib/service/customFieldHandler.d.ts +2 -1
- package/lib/service/customFieldHandler.js +2 -2
- package/lib/service/customFieldHandler.js.map +1 -1
- package/lib/service/customLabelHandler.d.ts +2 -1
- package/lib/service/customLabelHandler.js +3 -3
- package/lib/service/customLabelHandler.js.map +1 -1
- package/lib/service/customObjectHandler.d.ts +2 -1
- package/lib/service/customObjectHandler.js +2 -2
- package/lib/service/customObjectHandler.js.map +1 -1
- package/lib/service/decomposedHandler.d.ts +2 -1
- package/lib/service/decomposedHandler.js +2 -2
- package/lib/service/decomposedHandler.js.map +1 -1
- package/lib/service/diffLineInterpreter.d.ts +1 -1
- package/lib/service/diffLineInterpreter.js +16 -6
- package/lib/service/diffLineInterpreter.js.map +1 -1
- package/lib/service/flowHandler.d.ts +2 -1
- package/lib/service/flowHandler.js +2 -2
- package/lib/service/flowHandler.js.map +1 -1
- package/lib/service/inFileHandler.d.ts +8 -7
- package/lib/service/inFileHandler.js +37 -30
- package/lib/service/inFileHandler.js.map +1 -1
- package/lib/service/inFolderHandler.d.ts +2 -1
- package/lib/service/inFolderHandler.js +2 -2
- package/lib/service/inFolderHandler.js.map +1 -1
- package/lib/service/inResourceHandler.d.ts +3 -2
- package/lib/service/inResourceHandler.js +5 -5
- package/lib/service/inResourceHandler.js.map +1 -1
- package/lib/service/objectTranslationHandler.d.ts +3 -3
- package/lib/service/objectTranslationHandler.js +15 -8
- package/lib/service/objectTranslationHandler.js.map +1 -1
- package/lib/service/reportingFolderHandler.d.ts +8 -4
- package/lib/service/reportingFolderHandler.js +5 -6
- package/lib/service/reportingFolderHandler.js.map +1 -1
- package/lib/service/sharedFolderHandler.d.ts +8 -4
- package/lib/service/sharedFolderHandler.js +5 -6
- package/lib/service/sharedFolderHandler.js.map +1 -1
- package/lib/service/standardHandler.d.ts +14 -7
- package/lib/service/standardHandler.js +47 -27
- package/lib/service/standardHandler.js.map +1 -1
- package/lib/service/typeHandlerFactory.d.ts +2 -0
- package/lib/service/typeHandlerFactory.js +15 -0
- package/lib/service/typeHandlerFactory.js.map +1 -1
- package/lib/types/config.d.ts +1 -0
- package/lib/types/handlerResult.d.ts +17 -8
- package/lib/types/handlerResult.js +9 -11
- package/lib/types/handlerResult.js.map +1 -1
- package/lib/types/work.d.ts +2 -5
- package/lib/utils/LoggingDecorator.js +22 -11
- package/lib/utils/LoggingDecorator.js.map +1 -1
- package/lib/utils/changeSet.d.ts +53 -0
- package/lib/utils/changeSet.js +257 -0
- package/lib/utils/changeSet.js.map +1 -0
- package/lib/utils/configValidator.d.ts +1 -0
- package/lib/utils/configValidator.js +39 -1
- package/lib/utils/configValidator.js.map +1 -1
- package/lib/utils/gitLfsHelper.js +9 -1
- package/lib/utils/gitLfsHelper.js.map +1 -1
- package/lib/utils/metadataDiff/index.d.ts +28 -0
- package/lib/utils/metadataDiff/index.js +57 -0
- package/lib/utils/metadataDiff/index.js.map +1 -0
- package/lib/utils/metadataDiff/streamingDiff.d.ts +68 -0
- package/lib/utils/metadataDiff/streamingDiff.js +300 -0
- package/lib/utils/metadataDiff/streamingDiff.js.map +1 -0
- package/lib/utils/metadataDiff/xmlEventReader.d.ts +28 -0
- package/lib/utils/metadataDiff/xmlEventReader.js +221 -0
- package/lib/utils/metadataDiff/xmlEventReader.js.map +1 -0
- package/lib/utils/metadataDiff/xmlWriter.d.ts +17 -0
- package/lib/utils/metadataDiff/xmlWriter.js +213 -0
- package/lib/utils/metadataDiff/xmlWriter.js.map +1 -0
- package/lib/utils/packageHelper.d.ts +8 -1
- package/lib/utils/packageHelper.js +25 -28
- package/lib/utils/packageHelper.js.map +1 -1
- package/lib/utils/renameResolver.d.ts +19 -0
- package/lib/utils/renameResolver.js +52 -0
- package/lib/utils/renameResolver.js.map +1 -0
- package/lib/utils/repoGitDiff.d.ts +18 -5
- package/lib/utils/repoGitDiff.js +66 -33
- package/lib/utils/repoGitDiff.js.map +1 -1
- package/lib/utils/treeIndexScope.d.ts +1 -1
- package/lib/utils/treeIndexScope.js.map +1 -1
- package/lib/utils/txmlAdapter.d.ts +30 -0
- package/lib/utils/txmlAdapter.js +121 -0
- package/lib/utils/txmlAdapter.js.map +1 -0
- package/lib/utils/xmlHelper.d.ts +0 -5
- package/lib/utils/xmlHelper.js +0 -57
- package/lib/utils/xmlHelper.js.map +1 -1
- package/messages/delta.md +12 -0
- package/npm-shrinkwrap.json +628 -486
- package/oclif.manifest.json +9 -1
- package/package.json +53 -21
- package/lib/utils/manifestAggregator.d.ts +0 -3
- package/lib/utils/manifestAggregator.js +0 -22
- package/lib/utils/manifestAggregator.js.map +0 -1
- package/lib/utils/metadataDiff.d.ts +0 -23
- package/lib/utils/metadataDiff.js +0 -242
- package/lib/utils/metadataDiff.js.map +0 -1
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
import { deepEqual } from 'fast-equals';
|
|
3
|
+
import { writeXmlDocument } from './xmlWriter.js';
|
|
4
|
+
const ARRAY_SPECIAL_KEY = '<array>';
|
|
5
|
+
const OBJECT_SPECIAL_KEY = '<object>';
|
|
6
|
+
export const CARDINALITY_SAFETY_LIMIT = 100_000;
|
|
7
|
+
/**
|
|
8
|
+
* Two-pass streaming diff engine. Pass 1 consumes from-side elements into
|
|
9
|
+
* per-bucket indexes; Pass 2 classifies to-side elements, emitting manifest
|
|
10
|
+
* entries (added/modified/deleted) and retaining survivors in prunedBySubType
|
|
11
|
+
* for later writer-driven output. Deferred buckets (array / object / keyless
|
|
12
|
+
* / unknown) drain at end of pass.
|
|
13
|
+
*
|
|
14
|
+
* Memory bound, per DESIGN.md \xc2\xa75.3: keyed subType indexes shrink during
|
|
15
|
+
* Pass 2 as matches drain, so peak on that bucket is O(changed_keyed_count).
|
|
16
|
+
* Deferred buckets (array/object/keyless/unknown) hold every to-side element
|
|
17
|
+
* of those subTypes until end-of-pass — they are O(element_count) per
|
|
18
|
+
* subType, capped by CARDINALITY_SAFETY_LIMIT. The writer closure then
|
|
19
|
+
* captures prunedBySubType and keeps it reachable until the IOExecutor
|
|
20
|
+
* invokes the writer or the HandlerResult is GC'd.
|
|
21
|
+
*
|
|
22
|
+
* The writer closure is not thread-safe against reuse: run() instantiates a
|
|
23
|
+
* fresh StreamingDiff per call and the writer is expected to fire at most
|
|
24
|
+
* once. Calling it twice is safe but produces the same bytes.
|
|
25
|
+
*/
|
|
26
|
+
export class StreamingDiff {
|
|
27
|
+
attributes;
|
|
28
|
+
generateDelta;
|
|
29
|
+
passOne = {
|
|
30
|
+
fromKeyed: new Map(),
|
|
31
|
+
fromArrays: new Map(),
|
|
32
|
+
fromObjectFingerprints: new Map(),
|
|
33
|
+
fromKeyless: new Map(),
|
|
34
|
+
fromUnknown: new Map(),
|
|
35
|
+
};
|
|
36
|
+
passTwo = {
|
|
37
|
+
toArrays: new Map(),
|
|
38
|
+
toObjectFingerprints: new Map(),
|
|
39
|
+
toKeyless: new Map(),
|
|
40
|
+
toUnknown: new Map(),
|
|
41
|
+
};
|
|
42
|
+
prunedBySubType = new Map();
|
|
43
|
+
// Tracks first-seen-in-to order across all subTypes (keyed + deferred)
|
|
44
|
+
// so buildWriter emits root children in the same order legacy's
|
|
45
|
+
// JsonTransformer produced (document order from to-side).
|
|
46
|
+
toSubTypeOrder = [];
|
|
47
|
+
seenSubTypes = new Set();
|
|
48
|
+
added = [];
|
|
49
|
+
modified = [];
|
|
50
|
+
deleted = [];
|
|
51
|
+
hasAnyChanges = false;
|
|
52
|
+
constructor(attributes, generateDelta) {
|
|
53
|
+
this.attributes = attributes;
|
|
54
|
+
this.generateDelta = generateDelta;
|
|
55
|
+
}
|
|
56
|
+
onFromElement = (subType, element) => {
|
|
57
|
+
if (!this.attributes.has(subType)) {
|
|
58
|
+
this.appendBounded(this.passOne.fromUnknown, subType, element);
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
// Stryker disable next-line OptionalChaining -- defensive: attributes.has gate above guarantees a hit; optional chain is for future-proofing
|
|
62
|
+
const keyField = this.attributes.get(subType)?.key;
|
|
63
|
+
if (keyField === undefined) {
|
|
64
|
+
this.appendBounded(this.passOne.fromKeyless, subType, element);
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
if (keyField === ARRAY_SPECIAL_KEY) {
|
|
68
|
+
this.appendBounded(this.passOne.fromArrays, subType, element);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
if (keyField === OBJECT_SPECIAL_KEY) {
|
|
72
|
+
const set = this.passOne.fromObjectFingerprints.get(subType) ?? new Set();
|
|
73
|
+
set.add(JSON.stringify(element));
|
|
74
|
+
this.passOne.fromObjectFingerprints.set(subType, set);
|
|
75
|
+
this.guardCardinality(set.size, subType);
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
const key = element[keyField];
|
|
79
|
+
/* v8 ignore next -- defensive: keyed subTypes always have the configured key in well-formed metadata */
|
|
80
|
+
if (key === undefined)
|
|
81
|
+
return;
|
|
82
|
+
const map = this.passOne.fromKeyed.get(subType) ?? new Map();
|
|
83
|
+
map.set(key, element);
|
|
84
|
+
this.passOne.fromKeyed.set(subType, map);
|
|
85
|
+
this.guardCardinality(map.size, subType);
|
|
86
|
+
};
|
|
87
|
+
onToElement = (subType, element) => {
|
|
88
|
+
this.trackToOrder(subType);
|
|
89
|
+
if (!this.attributes.has(subType)) {
|
|
90
|
+
this.appendBounded(this.passTwo.toUnknown, subType, element);
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
// Stryker disable next-line OptionalChaining -- defensive: attributes.has gate above guarantees a hit
|
|
94
|
+
const keyField = this.attributes.get(subType)?.key;
|
|
95
|
+
if (keyField === undefined) {
|
|
96
|
+
this.appendBounded(this.passTwo.toKeyless, subType, element);
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
if (keyField === ARRAY_SPECIAL_KEY) {
|
|
100
|
+
this.appendBounded(this.passTwo.toArrays, subType, element);
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
if (keyField === OBJECT_SPECIAL_KEY) {
|
|
104
|
+
this.appendObjectFingerprint(subType, element);
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
this.classifyKeyedElement(subType, element, keyField);
|
|
108
|
+
};
|
|
109
|
+
trackToOrder(subType) {
|
|
110
|
+
if (this.seenSubTypes.has(subType))
|
|
111
|
+
return;
|
|
112
|
+
this.seenSubTypes.add(subType);
|
|
113
|
+
this.toSubTypeOrder.push(subType);
|
|
114
|
+
}
|
|
115
|
+
finalize() {
|
|
116
|
+
this.drainArrays();
|
|
117
|
+
this.drainObjectFingerprints();
|
|
118
|
+
this.drainKeyless();
|
|
119
|
+
this.drainUnknown();
|
|
120
|
+
this.drainDeletions();
|
|
121
|
+
return {
|
|
122
|
+
added: this.added,
|
|
123
|
+
modified: this.modified,
|
|
124
|
+
deleted: this.deleted,
|
|
125
|
+
hasAnyChanges: this.hasAnyChanges,
|
|
126
|
+
isEmpty: this.prunedBySubType.size === 0,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
buildWriter(rootCapture) {
|
|
130
|
+
if (!this.generateDelta || !this.hasAnyChanges || !rootCapture) {
|
|
131
|
+
return undefined;
|
|
132
|
+
}
|
|
133
|
+
// No surviving children means the pruned output is just the empty
|
|
134
|
+
// root tag, which legacy treated as "do not emit". Skipping here keeps
|
|
135
|
+
// delete-only files out of the delta output entirely.
|
|
136
|
+
if (this.prunedBySubType.size === 0)
|
|
137
|
+
return undefined;
|
|
138
|
+
const rootChildren = this.collectRootChildren(rootCapture);
|
|
139
|
+
return async (out) => {
|
|
140
|
+
// Per-file pruned XML retains the legacy trailing newline (matches
|
|
141
|
+
// convertJsonToXml output). Manifest writer (PackageBuilder) uses the
|
|
142
|
+
// trimmed variant — see DESIGN.md \xc2\xa75.5.1.
|
|
143
|
+
await writeXmlDocument(out, rootCapture, rootChildren);
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
collectRootChildren(_rootCapture) {
|
|
147
|
+
const entries = [];
|
|
148
|
+
for (const subType of this.toSubTypeOrder) {
|
|
149
|
+
const elements = this.prunedBySubType.get(subType);
|
|
150
|
+
/* v8 ignore next -- defensive: trackToOrder is paired with retainSubTypeElement, so prunedBySubType is always populated for tracked subTypes */
|
|
151
|
+
if (!elements || elements.length === 0)
|
|
152
|
+
continue;
|
|
153
|
+
entries.push([subType, elements]);
|
|
154
|
+
}
|
|
155
|
+
return entries;
|
|
156
|
+
}
|
|
157
|
+
classifyKeyedElement(subType, element, keyField) {
|
|
158
|
+
const key = element[keyField];
|
|
159
|
+
/* v8 ignore next -- defensive: keyed subTypes always have the configured key in well-formed metadata */
|
|
160
|
+
if (key === undefined)
|
|
161
|
+
return;
|
|
162
|
+
const fromMap = this.passOne.fromKeyed.get(subType);
|
|
163
|
+
const fromElem = fromMap?.get(key);
|
|
164
|
+
if (fromMap === undefined || fromElem === undefined) {
|
|
165
|
+
this.recordAdded(subType, key);
|
|
166
|
+
this.retainSubTypeElement(subType, element);
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
fromMap.delete(key);
|
|
170
|
+
if (deepEqual(fromElem, element))
|
|
171
|
+
return;
|
|
172
|
+
this.recordModified(subType, key);
|
|
173
|
+
this.retainSubTypeElement(subType, element);
|
|
174
|
+
}
|
|
175
|
+
recordAdded(subType, member) {
|
|
176
|
+
this.hasAnyChanges = true;
|
|
177
|
+
if (this.isPackageable(subType)) {
|
|
178
|
+
this.added.push({ type: this.xmlNameOf(subType), member });
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
recordModified(subType, member) {
|
|
182
|
+
this.hasAnyChanges = true;
|
|
183
|
+
if (this.isPackageable(subType)) {
|
|
184
|
+
this.modified.push({ type: this.xmlNameOf(subType), member });
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
isPackageable(subType) {
|
|
188
|
+
// Stryker disable next-line OptionalChaining -- defensive: callers gate via attributes.has so the entry is always present
|
|
189
|
+
return !this.attributes.get(subType)?.excluded;
|
|
190
|
+
}
|
|
191
|
+
xmlNameOf(subType) {
|
|
192
|
+
// Stryker disable next-line OptionalChaining,LogicalOperator -- defensive: every tracked subType has an xmlName in the registry; the optional chain + nullish-coalesce is unreachable in practice
|
|
193
|
+
/* v8 ignore next */
|
|
194
|
+
return this.attributes.get(subType)?.xmlName ?? '';
|
|
195
|
+
}
|
|
196
|
+
retainSubTypeElement(subType, element) {
|
|
197
|
+
if (!this.generateDelta)
|
|
198
|
+
return;
|
|
199
|
+
let existing = this.prunedBySubType.get(subType);
|
|
200
|
+
if (existing === undefined) {
|
|
201
|
+
existing = [];
|
|
202
|
+
this.prunedBySubType.set(subType, existing);
|
|
203
|
+
}
|
|
204
|
+
existing.push(element);
|
|
205
|
+
}
|
|
206
|
+
drainArrays() {
|
|
207
|
+
for (const [subType, toArr] of this.passTwo.toArrays.entries()) {
|
|
208
|
+
const fromArr = this.passOne.fromArrays.get(subType) ?? [];
|
|
209
|
+
if (!deepEqual(fromArr, toArr)) {
|
|
210
|
+
this.hasAnyChanges = true;
|
|
211
|
+
if (this.generateDelta)
|
|
212
|
+
this.prunedBySubType.set(subType, toArr);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
drainObjectFingerprints() {
|
|
217
|
+
for (const [subType, toArr,] of this.passTwo.toObjectFingerprints.entries()) {
|
|
218
|
+
const fromSet = this.passOne.fromObjectFingerprints.get(subType) ?? new Set();
|
|
219
|
+
const retained = [];
|
|
220
|
+
for (const [element, fingerprint] of toArr) {
|
|
221
|
+
if (!fromSet.has(fingerprint))
|
|
222
|
+
retained.push(element);
|
|
223
|
+
}
|
|
224
|
+
if (retained.length > 0) {
|
|
225
|
+
this.hasAnyChanges = true;
|
|
226
|
+
if (this.generateDelta)
|
|
227
|
+
this.prunedBySubType.set(subType, retained);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
drainKeyless() {
|
|
232
|
+
for (const [subType, toArr] of this.passTwo.toKeyless.entries()) {
|
|
233
|
+
const fromArr = this.passOne.fromKeyless.get(subType) ?? [];
|
|
234
|
+
const changed = fromArr.length === 0 || !deepEqual(fromArr, toArr);
|
|
235
|
+
if (changed)
|
|
236
|
+
this.hasAnyChanges = true;
|
|
237
|
+
// Legacy JsonTransformer retains keyless content unconditionally when
|
|
238
|
+
// toMeta is non-empty (matches getPartialContentWithoutKey). Keep that
|
|
239
|
+
// behavior for byte-equality.
|
|
240
|
+
if (this.generateDelta && toArr.length > 0) {
|
|
241
|
+
this.prunedBySubType.set(subType, toArr);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
drainUnknown() {
|
|
246
|
+
for (const [subType, toArr] of this.passTwo.toUnknown.entries()) {
|
|
247
|
+
const fromArr = this.passOne.fromUnknown.get(subType) ?? [];
|
|
248
|
+
const changed = fromArr.length === 0 || !deepEqual(fromArr, toArr);
|
|
249
|
+
if (changed)
|
|
250
|
+
this.hasAnyChanges = true;
|
|
251
|
+
if (this.generateDelta && toArr.length > 0) {
|
|
252
|
+
this.prunedBySubType.set(subType, toArr);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
drainDeletions() {
|
|
257
|
+
for (const [subType, remaining] of this.passOne.fromKeyed.entries()) {
|
|
258
|
+
if (remaining.size === 0)
|
|
259
|
+
continue;
|
|
260
|
+
if (!this.isPackageable(subType))
|
|
261
|
+
continue;
|
|
262
|
+
// Stryker disable next-line OptionalChaining -- defensive: fromKeyed is only populated for subTypes with a configured key
|
|
263
|
+
const keyField = this.attributes.get(subType)?.key;
|
|
264
|
+
/* v8 ignore next -- defensive: passOne.fromKeyed is only populated for subTypes whose key field is defined */
|
|
265
|
+
if (keyField === undefined)
|
|
266
|
+
continue;
|
|
267
|
+
for (const [, element] of remaining.entries()) {
|
|
268
|
+
this.recordDeleted(subType, element[keyField]);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
recordDeleted(subType, member) {
|
|
273
|
+
this.hasAnyChanges = true;
|
|
274
|
+
this.deleted.push({ type: this.xmlNameOf(subType), member });
|
|
275
|
+
}
|
|
276
|
+
appendBounded(bucket, subType, element) {
|
|
277
|
+
let list = bucket.get(subType);
|
|
278
|
+
if (list === undefined) {
|
|
279
|
+
list = [];
|
|
280
|
+
bucket.set(subType, list);
|
|
281
|
+
}
|
|
282
|
+
list.push(element);
|
|
283
|
+
this.guardCardinality(list.length, subType);
|
|
284
|
+
}
|
|
285
|
+
appendObjectFingerprint(subType, element) {
|
|
286
|
+
let list = this.passTwo.toObjectFingerprints.get(subType);
|
|
287
|
+
if (list === undefined) {
|
|
288
|
+
list = [];
|
|
289
|
+
this.passTwo.toObjectFingerprints.set(subType, list);
|
|
290
|
+
}
|
|
291
|
+
list.push([element, JSON.stringify(element)]);
|
|
292
|
+
this.guardCardinality(list.length, subType);
|
|
293
|
+
}
|
|
294
|
+
guardCardinality(size, subType) {
|
|
295
|
+
if (size > CARDINALITY_SAFETY_LIMIT) {
|
|
296
|
+
throw new Error(`cardinality safety limit exceeded for ${subType}`);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
//# sourceMappingURL=streamingDiff.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"streamingDiff.js","sourceRoot":"","sources":["../../../src/utils/metadataDiff/streamingDiff.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { type XmlContent } from '../xmlHelper.js';
|
|
2
|
+
export type RootCapture = {
|
|
3
|
+
xmlHeader: XmlContent | undefined;
|
|
4
|
+
rootKey: string;
|
|
5
|
+
rootAttributes: Record<string, string>;
|
|
6
|
+
};
|
|
7
|
+
export type SubTypeElementHandler = (subType: string, element: XmlContent) => void;
|
|
8
|
+
/**
|
|
9
|
+
* Parses the `from`-side blob for streaming diff ingestion. Errors and
|
|
10
|
+
* empty/missing sources resolve to `null` — preserving the ADDITION path
|
|
11
|
+
* where a missing `from` is treated as "no prior content" rather than a
|
|
12
|
+
* failure.
|
|
13
|
+
*
|
|
14
|
+
* Emits `onElement(subType, element)` per direct-child element of the
|
|
15
|
+
* document root, parsed one at a time via txml's parseNode primitive.
|
|
16
|
+
* Peak resident memory stays bounded by the largest single child rather
|
|
17
|
+
* than the full document because each parsed subtree is released as soon
|
|
18
|
+
* as onElement returns and the cursor advances.
|
|
19
|
+
*/
|
|
20
|
+
export declare const parseFromSideSwallowing: (source: Buffer | string | null | undefined, onElement: SubTypeElementHandler) => Promise<RootCapture | null>;
|
|
21
|
+
/**
|
|
22
|
+
* Parses the `to`-side blob for streaming diff ingestion. Parse errors
|
|
23
|
+
* propagate so the caller's `MalformedXML` warning path fires.
|
|
24
|
+
*
|
|
25
|
+
* Emits `onElement(subType, element)` per direct-child element of the
|
|
26
|
+
* document root.
|
|
27
|
+
*/
|
|
28
|
+
export declare const parseToSidePropagating: (source: Buffer | string, onElement: SubTypeElementHandler) => Promise<RootCapture>;
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
3
|
+
// @ts-expect-error -- txml does not re-export its .d.ts via package.json exports
|
|
4
|
+
import { parse as txmlParse } from 'txml';
|
|
5
|
+
import { getErrorMessage } from '../errorUtils.js';
|
|
6
|
+
import { Logger, lazy } from '../LoggingService.js';
|
|
7
|
+
import { tNodeToXmlContent, } from '../txmlAdapter.js';
|
|
8
|
+
import { ATTRIBUTE_PREFIX, XML_HEADER_ATTRIBUTE_KEY, } from '../xmlHelper.js';
|
|
9
|
+
const XML_DECL_RE = /^\s*<\?xml\b[^?]*\?>/;
|
|
10
|
+
const COMMENT_RE = /^<!--[\s\S]*?-->/;
|
|
11
|
+
const WS_RE = /^\s+/;
|
|
12
|
+
const ROOT_OPEN_RE = /<([A-Za-z_:][\w.:-]*)([^>]*)>/y;
|
|
13
|
+
const parseDeclaration = (decl) => {
|
|
14
|
+
const tree = txmlParse(decl);
|
|
15
|
+
const declNode = tree.find((n) => typeof n !== 'string' && n.tagName === XML_HEADER_ATTRIBUTE_KEY);
|
|
16
|
+
if (!declNode)
|
|
17
|
+
return { [XML_HEADER_ATTRIBUTE_KEY]: {} };
|
|
18
|
+
const headerAttrs = {};
|
|
19
|
+
for (const key of Object.keys(declNode.attributes)) {
|
|
20
|
+
const value = declNode.attributes[key];
|
|
21
|
+
headerAttrs[`${ATTRIBUTE_PREFIX}${key}`] = value === null ? true : value;
|
|
22
|
+
}
|
|
23
|
+
return { [XML_HEADER_ATTRIBUTE_KEY]: headerAttrs };
|
|
24
|
+
};
|
|
25
|
+
// Walks the prologue (BOM, optional declaration, leading whitespace,
|
|
26
|
+
// comments, and `<!...>` declarations such as DOCTYPE) and stops at the
|
|
27
|
+
// root opening tag. Returns the root name, its attributes, the byte
|
|
28
|
+
// offset where the root's body starts so the streaming loop can pick up
|
|
29
|
+
// from there, and whether the root is self-closing.
|
|
30
|
+
const parsePrologue = (xml) => {
|
|
31
|
+
let i = 0;
|
|
32
|
+
let xmlHeader;
|
|
33
|
+
const declMatch = XML_DECL_RE.exec(xml);
|
|
34
|
+
if (declMatch && declMatch.index === 0) {
|
|
35
|
+
xmlHeader = parseDeclaration(declMatch[0]);
|
|
36
|
+
i += declMatch[0].length;
|
|
37
|
+
}
|
|
38
|
+
while (i < xml.length) {
|
|
39
|
+
const wsMatch = WS_RE.exec(xml.slice(i));
|
|
40
|
+
if (wsMatch) {
|
|
41
|
+
i += wsMatch[0].length;
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
const commentMatch = COMMENT_RE.exec(xml.slice(i));
|
|
45
|
+
if (commentMatch) {
|
|
46
|
+
i += commentMatch[0].length;
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
// `<!...>` declarations (DOCTYPE, ENTITY, etc.) before the root.
|
|
50
|
+
// Naive boundary at the next `>` — none of our metadata payloads use
|
|
51
|
+
// bracketed internal subsets, so a more elaborate scan would be
|
|
52
|
+
// unused work.
|
|
53
|
+
if (xml.startsWith('<!', i) && !xml.startsWith('<!--', i)) {
|
|
54
|
+
const end = xml.indexOf('>', i + 2);
|
|
55
|
+
if (end < 0)
|
|
56
|
+
return null;
|
|
57
|
+
i = end + 1;
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
break;
|
|
61
|
+
}
|
|
62
|
+
ROOT_OPEN_RE.lastIndex = i;
|
|
63
|
+
const rootMatch = ROOT_OPEN_RE.exec(xml);
|
|
64
|
+
if (!rootMatch || rootMatch.index !== i)
|
|
65
|
+
return null;
|
|
66
|
+
const [full, rootName, attrsRaw] = rootMatch;
|
|
67
|
+
const isSelfClosing = attrsRaw.trimEnd().endsWith('/');
|
|
68
|
+
const bodyStart = i + full.length;
|
|
69
|
+
// Reuse txml to parse just the root open tag's attributes consistently
|
|
70
|
+
// with how it parses every other tag. Wrapping it as self-closing gives
|
|
71
|
+
// us a clean parse target that always returns one node.
|
|
72
|
+
const synthetic = isSelfClosing
|
|
73
|
+
? `<${rootName}${attrsRaw.replace(/\/\s*$/, '')}/>`
|
|
74
|
+
: `<${rootName}${attrsRaw}/>`;
|
|
75
|
+
const syntheticTree = txmlParse(synthetic);
|
|
76
|
+
const syntheticNode = syntheticTree.find((n) => typeof n !== 'string');
|
|
77
|
+
const rootAttributes = {};
|
|
78
|
+
if (syntheticNode) {
|
|
79
|
+
for (const key of Object.keys(syntheticNode.attributes)) {
|
|
80
|
+
const value = syntheticNode.attributes[key];
|
|
81
|
+
// Boolean attributes round-trip as "true" so the writer's
|
|
82
|
+
// `attr="value"` template renders them consistently.
|
|
83
|
+
rootAttributes[`${ATTRIBUTE_PREFIX}${key}`] =
|
|
84
|
+
value === null ? 'true' : value;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return {
|
|
88
|
+
xmlHeader,
|
|
89
|
+
rootName: rootName,
|
|
90
|
+
rootAttributes,
|
|
91
|
+
bodyStart,
|
|
92
|
+
isSelfClosing,
|
|
93
|
+
};
|
|
94
|
+
};
|
|
95
|
+
// One-shot per-element parse via txml's parseNode primitive. We loop
|
|
96
|
+
// from bodyStart to the closing root tag, parsing exactly one direct
|
|
97
|
+
// child per iteration and emitting it through onElement before advancing
|
|
98
|
+
// the cursor. txml returns the parsed subtree fully built — but we drop
|
|
99
|
+
// our reference after onElement, so peak resident memory stays bounded
|
|
100
|
+
// by the largest single child rather than the full document.
|
|
101
|
+
//
|
|
102
|
+
// Returns the cursor position where the loop exited so the strict-mode
|
|
103
|
+
// caller can verify the root close tag and reject trailing content.
|
|
104
|
+
const streamRootChildren = (xml, bodyStart, onElement) => {
|
|
105
|
+
let pos = bodyStart;
|
|
106
|
+
while (pos < xml.length) {
|
|
107
|
+
const lt = xml.indexOf('<', pos);
|
|
108
|
+
/* v8 ignore next 4 -- defensive: well-formed XML always has the closing root tag, so '<' is reachable until the </Root> marker exits the loop below */
|
|
109
|
+
if (lt < 0) {
|
|
110
|
+
pos = xml.length;
|
|
111
|
+
break;
|
|
112
|
+
}
|
|
113
|
+
if (xml.startsWith('</', lt)) {
|
|
114
|
+
pos = lt;
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
if (xml.startsWith('<!--', lt)) {
|
|
118
|
+
const end = xml.indexOf('-->', lt + 4);
|
|
119
|
+
pos = end < 0 ? xml.length : end + 3;
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
const res = txmlParse(xml, {
|
|
123
|
+
pos: lt,
|
|
124
|
+
parseNode: true,
|
|
125
|
+
setPos: true,
|
|
126
|
+
keepComments: true,
|
|
127
|
+
});
|
|
128
|
+
onElement(res.tagName, tNodeToXmlContent(res));
|
|
129
|
+
pos = res.pos;
|
|
130
|
+
}
|
|
131
|
+
return pos;
|
|
132
|
+
};
|
|
133
|
+
// Strict-mode tail check: confirms the document closes with `</rootName>`
|
|
134
|
+
// (or is a self-closing root) and that only whitespace or comments
|
|
135
|
+
// follow. Covers what txml itself is too tolerant to flag — unclosed
|
|
136
|
+
// roots, multi-root documents, trailing junk after the root close.
|
|
137
|
+
const verifyTail = (xml, pos, rootName, isSelfClosing) => {
|
|
138
|
+
let i = pos;
|
|
139
|
+
if (!isSelfClosing) {
|
|
140
|
+
const expected = `</${rootName}>`;
|
|
141
|
+
if (!xml.startsWith(expected, i)) {
|
|
142
|
+
throw new Error(`unclosed or mismatched root <${rootName}> at offset ${i}`);
|
|
143
|
+
}
|
|
144
|
+
i += expected.length;
|
|
145
|
+
}
|
|
146
|
+
while (i < xml.length) {
|
|
147
|
+
const ch = xml[i];
|
|
148
|
+
if (ch === ' ' || ch === '\t' || ch === '\n' || ch === '\r') {
|
|
149
|
+
i++;
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
if (xml.startsWith('<!--', i)) {
|
|
153
|
+
const end = xml.indexOf('-->', i + 4);
|
|
154
|
+
if (end < 0)
|
|
155
|
+
throw new Error('unterminated comment after root close');
|
|
156
|
+
i = end + 3;
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
throw new Error(`unexpected content after root close: ${xml.slice(i, Math.min(i + 30, xml.length))}`);
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
const driveParse = (source, onElement, options) => {
|
|
163
|
+
const payload = typeof source === 'string' ? source : source.toString('utf8');
|
|
164
|
+
const prologue = parsePrologue(payload);
|
|
165
|
+
if (prologue === null)
|
|
166
|
+
return null;
|
|
167
|
+
const endPos = prologue.isSelfClosing
|
|
168
|
+
? prologue.bodyStart
|
|
169
|
+
: streamRootChildren(payload, prologue.bodyStart, onElement);
|
|
170
|
+
// Strict mode (to-side): confirm the input closes cleanly so the
|
|
171
|
+
// MalformedXML warning path in the diff caller fires. Inner mismatches
|
|
172
|
+
// already throw via txml's per-child parseNode. The swallowing path
|
|
173
|
+
// skips this — its caller already discards errors and falls back to
|
|
174
|
+
// "no prior content", so a partial parse is acceptable there.
|
|
175
|
+
if (options.strict) {
|
|
176
|
+
verifyTail(payload, endPos, prologue.rootName, prologue.isSelfClosing);
|
|
177
|
+
}
|
|
178
|
+
return {
|
|
179
|
+
xmlHeader: prologue.xmlHeader,
|
|
180
|
+
rootKey: prologue.rootName,
|
|
181
|
+
rootAttributes: prologue.rootAttributes,
|
|
182
|
+
};
|
|
183
|
+
};
|
|
184
|
+
/**
|
|
185
|
+
* Parses the `from`-side blob for streaming diff ingestion. Errors and
|
|
186
|
+
* empty/missing sources resolve to `null` — preserving the ADDITION path
|
|
187
|
+
* where a missing `from` is treated as "no prior content" rather than a
|
|
188
|
+
* failure.
|
|
189
|
+
*
|
|
190
|
+
* Emits `onElement(subType, element)` per direct-child element of the
|
|
191
|
+
* document root, parsed one at a time via txml's parseNode primitive.
|
|
192
|
+
* Peak resident memory stays bounded by the largest single child rather
|
|
193
|
+
* than the full document because each parsed subtree is released as soon
|
|
194
|
+
* as onElement returns and the cursor advances.
|
|
195
|
+
*/
|
|
196
|
+
export const parseFromSideSwallowing = async (source, onElement) => {
|
|
197
|
+
if (!source)
|
|
198
|
+
return null;
|
|
199
|
+
try {
|
|
200
|
+
return driveParse(source, onElement, { strict: false });
|
|
201
|
+
}
|
|
202
|
+
catch (error) {
|
|
203
|
+
Logger.debug(lazy `parseFromSideSwallowing failed: ${() => getErrorMessage(error)}`);
|
|
204
|
+
return null;
|
|
205
|
+
}
|
|
206
|
+
};
|
|
207
|
+
/**
|
|
208
|
+
* Parses the `to`-side blob for streaming diff ingestion. Parse errors
|
|
209
|
+
* propagate so the caller's `MalformedXML` warning path fires.
|
|
210
|
+
*
|
|
211
|
+
* Emits `onElement(subType, element)` per direct-child element of the
|
|
212
|
+
* document root.
|
|
213
|
+
*/
|
|
214
|
+
export const parseToSidePropagating = async (source, onElement) => {
|
|
215
|
+
const capture = driveParse(source, onElement, { strict: true });
|
|
216
|
+
if (capture === null) {
|
|
217
|
+
throw new Error('to-side document has no root element');
|
|
218
|
+
}
|
|
219
|
+
return capture;
|
|
220
|
+
};
|
|
221
|
+
//# sourceMappingURL=xmlEventReader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"xmlEventReader.js","sourceRoot":"","sources":["../../../src/utils/metadataDiff/xmlEventReader.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { Writable } from 'node:stream';
|
|
2
|
+
import type { RootCapture } from './xmlEventReader.js';
|
|
3
|
+
type ElementEntry = readonly [key: string, value: unknown];
|
|
4
|
+
export type WriteOptions = {
|
|
5
|
+
trailingNewline?: boolean;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Streams a generic XML document to `out`. Iterative depth-first traversal
|
|
9
|
+
* with an explicit LIFO frame stack — safe under unexpectedly-deep input,
|
|
10
|
+
* cancellation-friendly, back-pressure aware via drain-await per chunk.
|
|
11
|
+
*
|
|
12
|
+
* Output is byte-identical to `fast-xml-builder` when given the same
|
|
13
|
+
* attribute prefix, comment key, and entity-passthrough (processEntities:
|
|
14
|
+
* false) conventions as the rest of the project. See DESIGN.md \xc2\xa75.5.1.
|
|
15
|
+
*/
|
|
16
|
+
export declare const writeXmlDocument: (out: Writable, rootCapture: RootCapture, rootChildren: ElementEntry[], options?: WriteOptions) => Promise<void>;
|
|
17
|
+
export {};
|