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.
Files changed (140) hide show
  1. package/README.md +35 -2
  2. package/lib/adapter/GitAdapter.d.ts +51 -2
  3. package/lib/adapter/GitAdapter.js +367 -41
  4. package/lib/adapter/GitAdapter.js.map +1 -1
  5. package/lib/adapter/gitBatchCatFile.d.ts +26 -4
  6. package/lib/adapter/gitBatchCatFile.js +128 -44
  7. package/lib/adapter/gitBatchCatFile.js.map +1 -1
  8. package/lib/adapter/gitBlobReader.d.ts +58 -0
  9. package/lib/adapter/gitBlobReader.js +27 -0
  10. package/lib/adapter/gitBlobReader.js.map +1 -0
  11. package/lib/adapter/ioExecutor.d.ts +18 -6
  12. package/lib/adapter/ioExecutor.js +97 -12
  13. package/lib/adapter/ioExecutor.js.map +1 -1
  14. package/lib/commands/sgd/source/delta.d.ts +2 -0
  15. package/lib/commands/sgd/source/delta.js +31 -1
  16. package/lib/commands/sgd/source/delta.js.map +1 -1
  17. package/lib/constant/cliConstants.d.ts +2 -0
  18. package/lib/constant/cliConstants.js +4 -0
  19. package/lib/constant/cliConstants.js.map +1 -1
  20. package/lib/constant/gitConstants.d.ts +1 -0
  21. package/lib/constant/gitConstants.js +4 -0
  22. package/lib/constant/gitConstants.js.map +1 -1
  23. package/lib/main.js +35 -7
  24. package/lib/main.js.map +1 -1
  25. package/lib/metadata/MetadataRepositoryImpl.d.ts +1 -0
  26. package/lib/metadata/MetadataRepositoryImpl.js +14 -2
  27. package/lib/metadata/MetadataRepositoryImpl.js.map +1 -1
  28. package/lib/post-processor/changesManifestProcessor.d.ts +15 -0
  29. package/lib/post-processor/changesManifestProcessor.js +50 -0
  30. package/lib/post-processor/changesManifestProcessor.js.map +1 -0
  31. package/lib/post-processor/flowTranslationProcessor.d.ts +31 -14
  32. package/lib/post-processor/flowTranslationProcessor.js +146 -51
  33. package/lib/post-processor/flowTranslationProcessor.js.map +1 -1
  34. package/lib/post-processor/packageGenerator.d.ts +1 -2
  35. package/lib/post-processor/packageGenerator.js +23 -34
  36. package/lib/post-processor/packageGenerator.js.map +1 -1
  37. package/lib/post-processor/postProcessorManager.js +9 -6
  38. package/lib/post-processor/postProcessorManager.js.map +1 -1
  39. package/lib/service/botHandler.d.ts +2 -1
  40. package/lib/service/botHandler.js +4 -3
  41. package/lib/service/botHandler.js.map +1 -1
  42. package/lib/service/containedDecomposedHandler.d.ts +3 -2
  43. package/lib/service/containedDecomposedHandler.js +6 -6
  44. package/lib/service/containedDecomposedHandler.js.map +1 -1
  45. package/lib/service/customFieldHandler.d.ts +2 -1
  46. package/lib/service/customFieldHandler.js +2 -2
  47. package/lib/service/customFieldHandler.js.map +1 -1
  48. package/lib/service/customLabelHandler.d.ts +2 -1
  49. package/lib/service/customLabelHandler.js +3 -3
  50. package/lib/service/customLabelHandler.js.map +1 -1
  51. package/lib/service/customObjectHandler.d.ts +2 -1
  52. package/lib/service/customObjectHandler.js +2 -2
  53. package/lib/service/customObjectHandler.js.map +1 -1
  54. package/lib/service/decomposedHandler.d.ts +2 -1
  55. package/lib/service/decomposedHandler.js +2 -2
  56. package/lib/service/decomposedHandler.js.map +1 -1
  57. package/lib/service/diffLineInterpreter.d.ts +1 -1
  58. package/lib/service/diffLineInterpreter.js +16 -6
  59. package/lib/service/diffLineInterpreter.js.map +1 -1
  60. package/lib/service/flowHandler.d.ts +2 -1
  61. package/lib/service/flowHandler.js +2 -2
  62. package/lib/service/flowHandler.js.map +1 -1
  63. package/lib/service/inFileHandler.d.ts +8 -7
  64. package/lib/service/inFileHandler.js +37 -30
  65. package/lib/service/inFileHandler.js.map +1 -1
  66. package/lib/service/inFolderHandler.d.ts +2 -1
  67. package/lib/service/inFolderHandler.js +2 -2
  68. package/lib/service/inFolderHandler.js.map +1 -1
  69. package/lib/service/inResourceHandler.d.ts +3 -2
  70. package/lib/service/inResourceHandler.js +5 -5
  71. package/lib/service/inResourceHandler.js.map +1 -1
  72. package/lib/service/objectTranslationHandler.d.ts +3 -3
  73. package/lib/service/objectTranslationHandler.js +15 -8
  74. package/lib/service/objectTranslationHandler.js.map +1 -1
  75. package/lib/service/reportingFolderHandler.d.ts +8 -4
  76. package/lib/service/reportingFolderHandler.js +5 -6
  77. package/lib/service/reportingFolderHandler.js.map +1 -1
  78. package/lib/service/sharedFolderHandler.d.ts +8 -4
  79. package/lib/service/sharedFolderHandler.js +5 -6
  80. package/lib/service/sharedFolderHandler.js.map +1 -1
  81. package/lib/service/standardHandler.d.ts +14 -7
  82. package/lib/service/standardHandler.js +47 -27
  83. package/lib/service/standardHandler.js.map +1 -1
  84. package/lib/service/typeHandlerFactory.d.ts +2 -0
  85. package/lib/service/typeHandlerFactory.js +15 -0
  86. package/lib/service/typeHandlerFactory.js.map +1 -1
  87. package/lib/types/config.d.ts +1 -0
  88. package/lib/types/handlerResult.d.ts +17 -8
  89. package/lib/types/handlerResult.js +9 -11
  90. package/lib/types/handlerResult.js.map +1 -1
  91. package/lib/types/work.d.ts +2 -5
  92. package/lib/utils/LoggingDecorator.js +22 -11
  93. package/lib/utils/LoggingDecorator.js.map +1 -1
  94. package/lib/utils/changeSet.d.ts +53 -0
  95. package/lib/utils/changeSet.js +257 -0
  96. package/lib/utils/changeSet.js.map +1 -0
  97. package/lib/utils/configValidator.d.ts +1 -0
  98. package/lib/utils/configValidator.js +39 -1
  99. package/lib/utils/configValidator.js.map +1 -1
  100. package/lib/utils/gitLfsHelper.js +9 -1
  101. package/lib/utils/gitLfsHelper.js.map +1 -1
  102. package/lib/utils/metadataDiff/index.d.ts +28 -0
  103. package/lib/utils/metadataDiff/index.js +57 -0
  104. package/lib/utils/metadataDiff/index.js.map +1 -0
  105. package/lib/utils/metadataDiff/streamingDiff.d.ts +68 -0
  106. package/lib/utils/metadataDiff/streamingDiff.js +300 -0
  107. package/lib/utils/metadataDiff/streamingDiff.js.map +1 -0
  108. package/lib/utils/metadataDiff/xmlEventReader.d.ts +28 -0
  109. package/lib/utils/metadataDiff/xmlEventReader.js +221 -0
  110. package/lib/utils/metadataDiff/xmlEventReader.js.map +1 -0
  111. package/lib/utils/metadataDiff/xmlWriter.d.ts +17 -0
  112. package/lib/utils/metadataDiff/xmlWriter.js +213 -0
  113. package/lib/utils/metadataDiff/xmlWriter.js.map +1 -0
  114. package/lib/utils/packageHelper.d.ts +8 -1
  115. package/lib/utils/packageHelper.js +25 -28
  116. package/lib/utils/packageHelper.js.map +1 -1
  117. package/lib/utils/renameResolver.d.ts +19 -0
  118. package/lib/utils/renameResolver.js +52 -0
  119. package/lib/utils/renameResolver.js.map +1 -0
  120. package/lib/utils/repoGitDiff.d.ts +18 -5
  121. package/lib/utils/repoGitDiff.js +66 -33
  122. package/lib/utils/repoGitDiff.js.map +1 -1
  123. package/lib/utils/treeIndexScope.d.ts +1 -1
  124. package/lib/utils/treeIndexScope.js.map +1 -1
  125. package/lib/utils/txmlAdapter.d.ts +30 -0
  126. package/lib/utils/txmlAdapter.js +121 -0
  127. package/lib/utils/txmlAdapter.js.map +1 -0
  128. package/lib/utils/xmlHelper.d.ts +0 -5
  129. package/lib/utils/xmlHelper.js +0 -57
  130. package/lib/utils/xmlHelper.js.map +1 -1
  131. package/messages/delta.md +12 -0
  132. package/npm-shrinkwrap.json +628 -486
  133. package/oclif.manifest.json +9 -1
  134. package/package.json +53 -21
  135. package/lib/utils/manifestAggregator.d.ts +0 -3
  136. package/lib/utils/manifestAggregator.js +0 -22
  137. package/lib/utils/manifestAggregator.js.map +0 -1
  138. package/lib/utils/metadataDiff.d.ts +0 -23
  139. package/lib/utils/metadataDiff.js +0 -242
  140. package/lib/utils/metadataDiff.js.map +0 -1
@@ -0,0 +1,257 @@
1
+ 'use strict';
2
+ import { ChangeKind, ManifestTarget, } from '../types/handlerResult.js';
3
+ const RENAME_KEY_SEPARATOR = '\0';
4
+ const renameKey = (from, to) => `${from}${RENAME_KEY_SEPARATOR}${to}`;
5
+ /**
6
+ * Domain object that collects every component change observed in a diff and
7
+ * derives the views consumed downstream:
8
+ * - Package manifest (`ManifestTarget.Package` entries + rename targets)
9
+ * - Destructive manifest (`ManifestTarget.DestructiveChanges` entries +
10
+ * rename sources — minus entries that also appear in the Package view)
11
+ * - Per-kind bucket map (used for the JSON review manifest)
12
+ *
13
+ * `ManifestTarget` and `ChangeKind` are orthogonal. A single ManifestElement
14
+ * can be (target=Package, changeKind=Delete) — this happens when InFileHandler
15
+ * treats a deleted container file as an addition to preserve surviving
16
+ * sub-elements. The xml manifests MUST route on `target` (the deployment
17
+ * contract); `changeKind` only drives the review-oriented JSON bucket.
18
+ *
19
+ * Insertion goes through `add` for single-component changes and
20
+ * `recordRename` for rename pairs. Views are pure projections.
21
+ */
22
+ export default class ChangeSet {
23
+ byTarget = {
24
+ [ManifestTarget.Package]: new Map(),
25
+ [ManifestTarget.DestructiveChanges]: new Map(),
26
+ };
27
+ byKind = {
28
+ [ChangeKind.Add]: new Map(),
29
+ [ChangeKind.Modify]: new Map(),
30
+ [ChangeKind.Delete]: new Map(),
31
+ };
32
+ renames = new Map();
33
+ static from(elements) {
34
+ const set = new ChangeSet();
35
+ for (const element of elements) {
36
+ set.addElement(element);
37
+ }
38
+ return set;
39
+ }
40
+ // Precise insertion — respects the full (target, changeKind) discriminator.
41
+ // Callers that know both axes use this; the handler pipeline feeds
42
+ // ManifestElements through `from()`.
43
+ addElement(element) {
44
+ this._addToManifest(this.byTarget[element.target], element.type, element.member);
45
+ this._addToManifest(this.byKind[element.changeKind], element.type, element.member);
46
+ }
47
+ // Diagnostic / test-only: reconstructs the (target, type, member, changeKind)
48
+ // tuples by joining byTarget × byKind on (type, member). Production diff
49
+ // lines never insert the same (type, member) under two different changeKind
50
+ // values, so the join is unambiguous in practice. Production code should
51
+ // use forPackageManifest / forDestructiveManifest / byChangeKind for the
52
+ // indexed views — this method exists only so tests can list inserted
53
+ // elements without paying a per-addElement push in the hot path.
54
+ toElements() {
55
+ const targets = [
56
+ ManifestTarget.Package,
57
+ ManifestTarget.DestructiveChanges,
58
+ ];
59
+ const kinds = [
60
+ ChangeKind.Add,
61
+ ChangeKind.Modify,
62
+ ChangeKind.Delete,
63
+ ];
64
+ const out = [];
65
+ for (const target of targets) {
66
+ for (const [type, members] of this.byTarget[target]) {
67
+ for (const member of members) {
68
+ let kind;
69
+ for (const k of kinds) {
70
+ if (this.byKind[k].get(type)?.has(member)) {
71
+ kind = k;
72
+ break;
73
+ }
74
+ }
75
+ /* v8 ignore next -- defensive: addElement always pairs byTarget and byKind, so every (type, member) in byTarget has a corresponding byKind entry */
76
+ if (kind !== undefined) {
77
+ out.push({ target, type, member, changeKind: kind });
78
+ }
79
+ }
80
+ }
81
+ }
82
+ return out;
83
+ }
84
+ // Convenience for callers (mostly tests) that operate under the standard
85
+ // convention: Add/Modify target Package, Delete targets DestructiveChanges.
86
+ // Production handlers that diverge from this convention (e.g. InFileHandler
87
+ // treating a deleted container as an addition) MUST use addElement instead.
88
+ add(kind, type, member) {
89
+ const target = kind === ChangeKind.Delete
90
+ ? ManifestTarget.DestructiveChanges
91
+ : ManifestTarget.Package;
92
+ this.addElement({ target, type, member, changeKind: kind });
93
+ }
94
+ recordRename(type, from, to) {
95
+ if (from === to)
96
+ return;
97
+ if (!this.renames.has(type)) {
98
+ this.renames.set(type, new Map());
99
+ }
100
+ this.renames.get(type).set(renameKey(from, to), { from, to });
101
+ }
102
+ // Folds another ChangeSet's entries into this one. Used to combine
103
+ // per-handler / per-collector outputs into a single project-wide view.
104
+ // Mutates `this`; `other` is left untouched so the source can stay
105
+ // referentially shared if a caller needs the snapshot it represents.
106
+ merge(other) {
107
+ for (const target of [
108
+ ManifestTarget.Package,
109
+ ManifestTarget.DestructiveChanges,
110
+ ]) {
111
+ for (const [type, members] of other.byTarget[target]) {
112
+ for (const member of members) {
113
+ this._addToManifest(this.byTarget[target], type, member);
114
+ }
115
+ }
116
+ }
117
+ for (const kind of [
118
+ ChangeKind.Add,
119
+ ChangeKind.Modify,
120
+ ChangeKind.Delete,
121
+ ]) {
122
+ for (const [type, members] of other.byKind[kind]) {
123
+ for (const member of members) {
124
+ this._addToManifest(this.byKind[kind], type, member);
125
+ }
126
+ }
127
+ }
128
+ for (const [type, pairs] of other.renames) {
129
+ for (const { from, to } of pairs.values()) {
130
+ this.recordRename(type, from, to);
131
+ }
132
+ }
133
+ }
134
+ forPackageManifest() {
135
+ return this._unionByType([
136
+ this.byTarget[ManifestTarget.Package],
137
+ this._renameTargetsByType(),
138
+ ]);
139
+ }
140
+ forDestructiveManifest() {
141
+ const baseDeletes = this._unionByType([
142
+ this.byTarget[ManifestTarget.DestructiveChanges],
143
+ this._renameSourcesByType(),
144
+ ]);
145
+ return this._subtractByType(baseDeletes, this.forPackageManifest());
146
+ }
147
+ byChangeKind() {
148
+ // Rename participants move to the Rename bucket so every entry lives in
149
+ // exactly one user-visible bucket.
150
+ // Delete subtracts Add ∪ Modify (cancelled deletions) and rename sources.
151
+ const targets = this._renameTargetsByType();
152
+ const sources = this._renameSourcesByType();
153
+ return {
154
+ [ChangeKind.Add]: this._subtractByType(this.byKind[ChangeKind.Add], targets),
155
+ // Clone so callers that mutate the returned Modify view cannot corrupt
156
+ // ChangeSet internal state. Add and Delete buckets are already new
157
+ // Map instances returned by _subtractByType.
158
+ [ChangeKind.Modify]: this._cloneManifest(this.byKind[ChangeKind.Modify]),
159
+ [ChangeKind.Delete]: this._subtractByType(this.byKind[ChangeKind.Delete], this._unionByType([
160
+ this.byKind[ChangeKind.Add],
161
+ this.byKind[ChangeKind.Modify],
162
+ sources,
163
+ ])),
164
+ [ChangeKind.Rename]: this._cloneRenames(),
165
+ };
166
+ }
167
+ _addToManifest(manifest, type, member) {
168
+ if (!manifest.has(type)) {
169
+ manifest.set(type, new Set());
170
+ }
171
+ manifest.get(type).add(member);
172
+ }
173
+ _cloneManifest(manifest) {
174
+ const clone = new Map();
175
+ for (const [type, members] of manifest) {
176
+ clone.set(type, new Set(members));
177
+ }
178
+ return clone;
179
+ }
180
+ // `recordRename` always inserts at least one pair per type key, so the
181
+ // inner Set is non-empty by construction. No size check needed.
182
+ _renameTargetsByType() {
183
+ const result = new Map();
184
+ for (const [type, pairs] of this.renames) {
185
+ const members = new Set();
186
+ for (const { to } of pairs.values())
187
+ members.add(to);
188
+ result.set(type, members);
189
+ }
190
+ return result;
191
+ }
192
+ _renameSourcesByType() {
193
+ const result = new Map();
194
+ for (const [type, pairs] of this.renames) {
195
+ const members = new Set();
196
+ for (const { from } of pairs.values())
197
+ members.add(from);
198
+ result.set(type, members);
199
+ }
200
+ return result;
201
+ }
202
+ _cloneRenames() {
203
+ const clone = new Map();
204
+ for (const [type, pairs] of this.renames) {
205
+ clone.set(type, new Map(pairs));
206
+ }
207
+ return clone;
208
+ }
209
+ _unionByType(manifests) {
210
+ const result = new Map();
211
+ for (const manifest of manifests) {
212
+ for (const [type, members] of manifest) {
213
+ const existing = result.get(type);
214
+ if (existing) {
215
+ for (const member of members)
216
+ existing.add(member);
217
+ }
218
+ else {
219
+ result.set(type, new Set(members));
220
+ }
221
+ }
222
+ }
223
+ return result;
224
+ }
225
+ _subtractByType(base, minus) {
226
+ const result = new Map();
227
+ for (const [type, members] of base) {
228
+ const cancellers = minus.get(type);
229
+ const remaining = new Set();
230
+ for (const member of members) {
231
+ if (!cancellers?.has(member)) {
232
+ remaining.add(member);
233
+ }
234
+ }
235
+ if (remaining.size > 0) {
236
+ result.set(type, remaining);
237
+ }
238
+ }
239
+ return result;
240
+ }
241
+ }
242
+ export const emptyResult = () => ({
243
+ changes: new ChangeSet(),
244
+ copies: [],
245
+ warnings: [],
246
+ });
247
+ export const mergeResults = (...results) => {
248
+ const merged = new ChangeSet();
249
+ for (const r of results)
250
+ merged.merge(r.changes);
251
+ return {
252
+ changes: merged,
253
+ copies: results.flatMap(r => r.copies),
254
+ warnings: results.flatMap(r => r.warnings),
255
+ };
256
+ };
257
+ //# sourceMappingURL=changeSet.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"changeSet.js","sourceRoot":"","sources":["../../src/utils/changeSet.ts"],"names":[],"mappings":"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"}
@@ -10,6 +10,7 @@ export default class ConfigValidator {
10
10
  constructor(work: Work);
11
11
  protected _validateGitSha(): Promise<string[]>;
12
12
  validateConfig(): Promise<void>;
13
+ protected _validateChangesManifest(): Promise<string[]>;
13
14
  protected _handleDefault(): Promise<void>;
14
15
  protected _getApiVersion(): Promise<void>;
15
16
  protected _apiVersionDefault(): Promise<void>;
@@ -1,5 +1,6 @@
1
1
  'use strict';
2
2
  import { __decorate } from "tslib";
3
+ import { stat } from 'node:fs/promises';
3
4
  import { join } from 'node:path/posix';
4
5
  import { SfProject } from '@salesforce/core';
5
6
  import GitAdapter from '../adapter/GitAdapter.js';
@@ -42,21 +43,57 @@ export default class ConfigValidator {
42
43
  }
43
44
  async validateConfig() {
44
45
  this._sanitizeConfig();
45
- const [, repoExists, gitErrors] = await Promise.all([
46
+ const [, repoExists, gitErrors, changesManifestErrors] = await Promise.all([
46
47
  this._handleDefault(),
47
48
  pathExists(join(this.config.repo, GIT_FOLDER)),
48
49
  this._validateGitSha(),
50
+ this._validateChangesManifest(),
49
51
  ]);
50
52
  const errors = [];
51
53
  if (!repoExists) {
52
54
  errors.push(this.message.getMessage('error.PathIsNotGit', [this.config.repo]));
53
55
  }
54
56
  pushAll(errors, gitErrors);
57
+ pushAll(errors, changesManifestErrors);
55
58
  if (errors.length > 0) {
56
59
  throw new ConfigError(errors.join(', '));
57
60
  }
58
61
  await this.gitAdapter.configureRepository();
59
62
  }
63
+ // oclif cannot natively validate --changes-manifest (it uses a string flag
64
+ // to allow the bare form). Replicate meaningful checks: if the path already
65
+ // exists it must be a regular file; otherwise ENOENT is fine because
66
+ // fs-extra's outputFile creates the parent directory at write time.
67
+ async _validateChangesManifest() {
68
+ const target = this.config.changesManifest;
69
+ if (!target)
70
+ return [];
71
+ try {
72
+ const stats = await stat(target);
73
+ if (!stats.isFile()) {
74
+ return [
75
+ this.message.getMessage('error.ChangesManifestNotAFile', [target]),
76
+ ];
77
+ }
78
+ }
79
+ catch (error) {
80
+ // fs/promises stat always rejects with ErrnoException; narrow through
81
+ // an `instanceof Error` guard to keep `unknown` discipline, then read
82
+ // the POSIX code to distinguish "doesn't exist yet" from real failures.
83
+ const code = error instanceof Error
84
+ ? error.code
85
+ : undefined;
86
+ if (code !== 'ENOENT') {
87
+ return [
88
+ this.message.getMessage('error.ChangesManifestStatFailed', [
89
+ target,
90
+ getErrorMessage(error),
91
+ ]),
92
+ ];
93
+ }
94
+ }
95
+ return [];
96
+ }
60
97
  async _handleDefault() {
61
98
  await this._getApiVersion();
62
99
  await this._apiVersionDefault();
@@ -104,6 +141,7 @@ export default class ConfigValidator {
104
141
  this.config.include = sanitizePath(this.config.include);
105
142
  this.config.includeDestructive = sanitizePath(this.config.includeDestructive);
106
143
  this.config.additionalMetadataRegistryPath = sanitizePath(this.config.additionalMetadataRegistryPath);
144
+ this.config.changesManifest = sanitizePath(this.config.changesManifest);
107
145
  }
108
146
  }
109
147
  __decorate([
@@ -1 +1 @@
1
- {"version":3,"file":"configValidator.js","sourceRoot":"","sources":["../../src/utils/configValidator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"configValidator.js","sourceRoot":"","sources":["../../src/utils/configValidator.ts"],"names":[],"mappings":"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"}
@@ -3,10 +3,18 @@ import { sep } from 'node:path/posix';
3
3
  import { UTF8_ENCODING } from '../constant/fsConstants.js';
4
4
  import { GIT_FOLDER } from '../constant/gitConstants.js';
5
5
  const LFS_HEADER = Buffer.from('version https://git-lfs');
6
+ // LFS object ids are sha256 hex — 64 lowercase [0-9a-f] characters. The
7
+ // regex guards against traversal via a crafted pointer (e.g. "oid
8
+ // sha256:../../etc/passwd") that would otherwise resolve under the repo
9
+ // root via join().
10
+ const LFS_OID_PATTERN = /^[a-f0-9]{64}$/;
6
11
  export const isLFS = (content) => content.subarray(0, LFS_HEADER.length).equals(LFS_HEADER);
7
12
  export const getLFSObjectContentPath = (bufferContent) => {
8
13
  const content = bufferContent.toString(UTF8_ENCODING);
9
- const oid = content.split(/\n/)[1].split(':')[1];
14
+ const oid = content.split(/\n/)[1]?.split(':')[1] ?? '';
15
+ if (!LFS_OID_PATTERN.test(oid)) {
16
+ throw new Error('Invalid LFS oid');
17
+ }
10
18
  return [
11
19
  GIT_FOLDER,
12
20
  'lfs',
@@ -1 +1 @@
1
- {"version":3,"file":"gitLfsHelper.js","sourceRoot":"","sources":["../../src/utils/gitLfsHelper.ts"],"names":[],"mappings":"AAAA,YAAY,CAAA;AACZ,OAAO,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAA;AAErC,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAA;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAA;AAExD,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAA;AAEzD,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,OAAe,EAAW,EAAE,CAChD,OAAO,CAAC,QAAQ,CAAC,CAAC,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAA;AAE3D,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,aAAqB,EAAU,EAAE;IACvE,MAAM,OAAO,GAAG,aAAa,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAA;IACrD,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAA;IAChD,OAAO;QACL,UAAU;QACV,KAAK;QACL,SAAS;QACT,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;QACf,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;QACf,GAAG;KACJ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AACb,CAAC,CAAA"}
1
+ {"version":3,"file":"gitLfsHelper.js","sourceRoot":"","sources":["../../src/utils/gitLfsHelper.ts"],"names":[],"mappings":"AAAA,YAAY,CAAA;AACZ,OAAO,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAA;AAErC,OAAO,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAA;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAA;AAExD,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAA;AACzD,wEAAwE;AACxE,kEAAkE;AAClE,wEAAwE;AACxE,mBAAmB;AACnB,MAAM,eAAe,GAAG,gBAAgB,CAAA;AAExC,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,OAAe,EAAW,EAAE,CAChD,OAAO,CAAC,QAAQ,CAAC,CAAC,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAA;AAE3D,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,aAAqB,EAAU,EAAE;IACvE,MAAM,OAAO,GAAG,aAAa,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAA;IACrD,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;IACvD,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAA;IACpC,CAAC;IACD,OAAO;QACL,UAAU;QACV,KAAK;QACL,SAAS;QACT,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;QACf,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;QACf,GAAG;KACJ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AACb,CAAC,CAAA"}
@@ -0,0 +1,28 @@
1
+ import type { Writable } from 'node:stream';
2
+ import type { Config } from '../../types/config.js';
3
+ import type { SharedFileMetadata } from '../../types/metadata.js';
4
+ import { type CompareEntry } from './streamingDiff.js';
5
+ import { type RootCapture } from './xmlEventReader.js';
6
+ export type DiffOutcome = {
7
+ manifests: {
8
+ added: CompareEntry[];
9
+ modified: CompareEntry[];
10
+ deleted: CompareEntry[];
11
+ };
12
+ hasAnyChanges: boolean;
13
+ isEmpty: boolean;
14
+ writer?: (out: Writable) => Promise<void>;
15
+ };
16
+ /**
17
+ * Streaming metadata diff engine. `run(path)` parses both revisions of
18
+ * the given file via the streaming xmlEventReader, runs the two-pass
19
+ * StreamingDiff engine, and returns manifests + an optional writer
20
+ * closure that emits pruned XML on demand.
21
+ */
22
+ export default class MetadataDiff {
23
+ private readonly config;
24
+ private readonly inFileAttributes;
25
+ constructor(config: Config, inFileAttributes: Map<string, SharedFileMetadata>);
26
+ run(path: string): Promise<DiffOutcome>;
27
+ }
28
+ export type { CompareEntry, RootCapture };
@@ -0,0 +1,57 @@
1
+ 'use strict';
2
+ import { __decorate } from "tslib";
3
+ import { readPathFromGit } from '../fsHelper.js';
4
+ import { log } from '../LoggingDecorator.js';
5
+ import { StreamingDiff } from './streamingDiff.js';
6
+ import { parseFromSideSwallowing, parseToSidePropagating, } from './xmlEventReader.js';
7
+ /**
8
+ * Streaming metadata diff engine. `run(path)` parses both revisions of
9
+ * the given file via the streaming xmlEventReader, runs the two-pass
10
+ * StreamingDiff engine, and returns manifests + an optional writer
11
+ * closure that emits pruned XML on demand.
12
+ */
13
+ export default class MetadataDiff {
14
+ config;
15
+ inFileAttributes;
16
+ constructor(config, inFileAttributes) {
17
+ this.config = config;
18
+ this.inFileAttributes = inFileAttributes;
19
+ }
20
+ async run(path) {
21
+ // Ordering mirrors the historical compare() behavior (to first, then
22
+ // from) so tests relying on mockResolvedValueOnce sequencing keep
23
+ // working and so readPathFromGit retries stay consistent under the same
24
+ // GitAdapter queue discipline.
25
+ const toSource = await readPathFromGit({ path, oid: this.config.to }, this.config);
26
+ const fromSource = await readPathFromGit({ path, oid: this.config.from }, this.config);
27
+ const engine = new StreamingDiff(this.inFileAttributes, this.config.generateDelta);
28
+ await parseFromSideSwallowing(fromSource, engine.onFromElement);
29
+ // Deleted files have an empty to-side; legacy parseXmlFileToJson
30
+ // silently returned {}, so MetadataComparator saw "no children" and
31
+ // emitted every from-side element as deleted. The strict to-side
32
+ // parser throws on empty input, so we short-circuit here: an empty
33
+ // toSource means there are no children to classify, and the engine's
34
+ // drainDeletions pass naturally records every from-side element as
35
+ // deleted. No rootCapture is produced — InFileHandler doesn't need
36
+ // one for a delete-only file and the writer is gated on hasAnyChanges.
37
+ const rootCapture = toSource
38
+ ? await parseToSidePropagating(toSource, engine.onToElement)
39
+ : null;
40
+ const outcome = engine.finalize();
41
+ const writer = engine.buildWriter(rootCapture);
42
+ return {
43
+ manifests: {
44
+ added: outcome.added,
45
+ modified: outcome.modified,
46
+ deleted: outcome.deleted,
47
+ },
48
+ hasAnyChanges: outcome.hasAnyChanges,
49
+ isEmpty: outcome.isEmpty,
50
+ ...(writer ? { writer } : {}),
51
+ };
52
+ }
53
+ }
54
+ __decorate([
55
+ log
56
+ ], MetadataDiff.prototype, "run", null);
57
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/utils/metadataDiff/index.ts"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAKZ,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAChD,OAAO,EAAE,GAAG,EAAE,MAAM,wBAAwB,CAAA;AAC5C,OAAO,EAAqB,aAAa,EAAE,MAAM,oBAAoB,CAAA;AACrE,OAAO,EACL,uBAAuB,EACvB,sBAAsB,GAEvB,MAAM,qBAAqB,CAAA;AAe5B;;;;;GAKG;AACH,MAAM,CAAC,OAAO,OAAO,YAAY;IAEZ;IACA;IAFnB,YACmB,MAAc,EACd,gBAAiD;QADjD,WAAM,GAAN,MAAM,CAAQ;QACd,qBAAgB,GAAhB,gBAAgB,CAAiC;IACjE,CAAC;IAGE,AAAN,KAAK,CAAC,GAAG,CAAC,IAAY;QACpB,qEAAqE;QACrE,kEAAkE;QAClE,wEAAwE;QACxE,+BAA+B;QAC/B,MAAM,QAAQ,GAAG,MAAM,eAAe,CACpC,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,EAC7B,IAAI,CAAC,MAAM,CACZ,CAAA;QACD,MAAM,UAAU,GAAG,MAAM,eAAe,CACtC,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,EAC/B,IAAI,CAAC,MAAM,CACZ,CAAA;QAED,MAAM,MAAM,GAAG,IAAI,aAAa,CAC9B,IAAI,CAAC,gBAAgB,EACrB,IAAI,CAAC,MAAM,CAAC,aAAa,CAC1B,CAAA;QACD,MAAM,uBAAuB,CAAC,UAAU,EAAE,MAAM,CAAC,aAAa,CAAC,CAAA;QAC/D,iEAAiE;QACjE,oEAAoE;QACpE,iEAAiE;QACjE,mEAAmE;QACnE,qEAAqE;QACrE,mEAAmE;QACnE,mEAAmE;QACnE,uEAAuE;QACvE,MAAM,WAAW,GAAuB,QAAQ;YAC9C,CAAC,CAAC,MAAM,sBAAsB,CAAC,QAAQ,EAAE,MAAM,CAAC,WAAW,CAAC;YAC5D,CAAC,CAAC,IAAI,CAAA;QACR,MAAM,OAAO,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAA;QACjC,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,CAAC,WAAW,CAAC,CAAA;QAC9C,OAAO;YACL,SAAS,EAAE;gBACT,KAAK,EAAE,OAAO,CAAC,KAAK;gBACpB,QAAQ,EAAE,OAAO,CAAC,QAAQ;gBAC1B,OAAO,EAAE,OAAO,CAAC,OAAO;aACzB;YACD,aAAa,EAAE,OAAO,CAAC,aAAa;YACpC,OAAO,EAAE,OAAO,CAAC,OAAO;YACxB,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC9B,CAAA;IACH,CAAC;CACF;AA3CO;IADL,GAAG;uCA2CH"}
@@ -0,0 +1,68 @@
1
+ import type { Writable } from 'node:stream';
2
+ import type { ManifestElement } from '../../types/handlerResult.js';
3
+ import type { SharedFileMetadata } from '../../types/metadata.js';
4
+ import type { RootCapture, SubTypeElementHandler } from './xmlEventReader.js';
5
+ export declare const CARDINALITY_SAFETY_LIMIT = 100000;
6
+ export type CompareEntry = Pick<ManifestElement, 'type' | 'member'>;
7
+ export type StreamingDiffResult = {
8
+ added: CompareEntry[];
9
+ modified: CompareEntry[];
10
+ deleted: CompareEntry[];
11
+ hasAnyChanges: boolean;
12
+ isEmpty: boolean;
13
+ writer?: (out: Writable) => Promise<void>;
14
+ };
15
+ /**
16
+ * Two-pass streaming diff engine. Pass 1 consumes from-side elements into
17
+ * per-bucket indexes; Pass 2 classifies to-side elements, emitting manifest
18
+ * entries (added/modified/deleted) and retaining survivors in prunedBySubType
19
+ * for later writer-driven output. Deferred buckets (array / object / keyless
20
+ * / unknown) drain at end of pass.
21
+ *
22
+ * Memory bound, per DESIGN.md \xc2\xa75.3: keyed subType indexes shrink during
23
+ * Pass 2 as matches drain, so peak on that bucket is O(changed_keyed_count).
24
+ * Deferred buckets (array/object/keyless/unknown) hold every to-side element
25
+ * of those subTypes until end-of-pass — they are O(element_count) per
26
+ * subType, capped by CARDINALITY_SAFETY_LIMIT. The writer closure then
27
+ * captures prunedBySubType and keeps it reachable until the IOExecutor
28
+ * invokes the writer or the HandlerResult is GC'd.
29
+ *
30
+ * The writer closure is not thread-safe against reuse: run() instantiates a
31
+ * fresh StreamingDiff per call and the writer is expected to fire at most
32
+ * once. Calling it twice is safe but produces the same bytes.
33
+ */
34
+ export declare class StreamingDiff {
35
+ private readonly attributes;
36
+ private readonly generateDelta;
37
+ private readonly passOne;
38
+ private readonly passTwo;
39
+ private readonly prunedBySubType;
40
+ private readonly toSubTypeOrder;
41
+ private readonly seenSubTypes;
42
+ private readonly added;
43
+ private readonly modified;
44
+ private readonly deleted;
45
+ private hasAnyChanges;
46
+ constructor(attributes: Map<string, SharedFileMetadata>, generateDelta: boolean);
47
+ onFromElement: SubTypeElementHandler;
48
+ onToElement: SubTypeElementHandler;
49
+ private trackToOrder;
50
+ finalize(): Pick<StreamingDiffResult, 'added' | 'modified' | 'deleted' | 'hasAnyChanges' | 'isEmpty'>;
51
+ buildWriter(rootCapture: RootCapture | null): ((out: Writable) => Promise<void>) | undefined;
52
+ private collectRootChildren;
53
+ private classifyKeyedElement;
54
+ private recordAdded;
55
+ private recordModified;
56
+ private isPackageable;
57
+ private xmlNameOf;
58
+ private retainSubTypeElement;
59
+ private drainArrays;
60
+ private drainObjectFingerprints;
61
+ private drainKeyless;
62
+ private drainUnknown;
63
+ private drainDeletions;
64
+ private recordDeleted;
65
+ private appendBounded;
66
+ private appendObjectFingerprint;
67
+ private guardCardinality;
68
+ }