@iwonz/ywtc 3.4.1 → 3.5.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/CHANGELOG.md +23 -0
- package/README.md +4 -2
- package/dist/adapters/confluence.d.ts +8 -2
- package/dist/adapters/confluence.js +16 -3
- package/dist/adapters/confluence.js.map +1 -1
- package/dist/adapters/yandex.d.ts +18 -4
- package/dist/adapters/yandex.js +34 -6
- package/dist/adapters/yandex.js.map +1 -1
- package/dist/domain.d.ts +7 -0
- package/dist/domain.js.map +1 -1
- package/dist/graph.js +11 -2
- package/dist/graph.js.map +1 -1
- package/dist/issues.d.ts +7 -0
- package/dist/issues.js +9 -1
- package/dist/issues.js.map +1 -1
- package/dist/migrator.d.ts +1 -1
- package/dist/migrator.js +75 -3
- package/dist/migrator.js.map +1 -1
- package/dist/report-contract.d.ts +259 -0
- package/dist/report-contract.js +15 -0
- package/dist/report-contract.js.map +1 -0
- package/dist/report-ui/index.html +92 -0
- package/dist/report.d.ts +12 -208
- package/dist/report.js +214 -197
- package/dist/report.js.map +1 -1
- package/dist/state.d.ts +3 -0
- package/dist/state.js +3 -0
- package/dist/state.js.map +1 -1
- package/docs/assets/report-header-transparent.png +0 -0
- package/package.json +24 -3
package/dist/migrator.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { createHash } from 'node:crypto';
|
|
2
2
|
import { mkdir, readFile, rm, writeFile } from 'node:fs/promises';
|
|
3
3
|
import path from 'node:path';
|
|
4
|
+
import { pathToFileURL } from 'node:url';
|
|
4
5
|
import PQueue from 'p-queue';
|
|
5
6
|
import { createProviderAdapter } from './adapters/factory.js';
|
|
7
|
+
import { secretValues } from './config.js';
|
|
6
8
|
import { appendGridSnapshots, assertDestinationContent, emptyRendererFallbackReason, isLegacyTransferPlaceholder, normalizePageContent, normalizedPreviewHtml, rawContentFallback, renderedPreviewHtml, renderConfluenceStorage, renderYfm, setSourceResourceBinding, sourceResourceBindings, verifyDestinationContent, } from './content-model.js';
|
|
7
9
|
import { commentAttachmentUses, createCommentArchiveZip, renderCommentArchive, renderCommentArchiveIndex, resolveCommentAttachmentReferences, verifyCommentArchive, } from './comments.js';
|
|
8
10
|
import { ConfirmedDestinationMissingError, verifyConfirmedDestinationPage } from './consistency.js';
|
|
@@ -186,6 +188,19 @@ function destinationFromState(state, adapter) {
|
|
|
186
188
|
};
|
|
187
189
|
}
|
|
188
190
|
function reportPage(input) {
|
|
191
|
+
const inventory = input.commentInventory;
|
|
192
|
+
const commentResourceIds = new Set();
|
|
193
|
+
for (const thread of inventory?.threads ?? []) {
|
|
194
|
+
const stack = [thread.root];
|
|
195
|
+
while (stack.length > 0) {
|
|
196
|
+
const entry = stack.pop();
|
|
197
|
+
for (const attachment of entry.attachments) {
|
|
198
|
+
if (attachment.resourceId)
|
|
199
|
+
commentResourceIds.add(attachment.resourceId);
|
|
200
|
+
}
|
|
201
|
+
stack.push(...entry.replies);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
189
204
|
const transferable = input.resources.filter((resource) => resource.kind !== 'grid');
|
|
190
205
|
const resourceItems = transferable.map((resource) => {
|
|
191
206
|
const state = input.resourceStates?.[resource.id];
|
|
@@ -194,12 +209,16 @@ function reportPage(input) {
|
|
|
194
209
|
return {
|
|
195
210
|
sourceId: resource.id,
|
|
196
211
|
sourceName: resource.name,
|
|
197
|
-
|
|
212
|
+
...(resource.downloadUrl ? { sourceUrl: resource.downloadUrl } : {}),
|
|
213
|
+
...(resource.referenceAliases?.[0] ? { sourceReference: resource.referenceAliases[0] } : {}),
|
|
214
|
+
kind: commentResourceIds.has(resource.id) ? 'comment-attachment' : resource.kind,
|
|
198
215
|
status,
|
|
199
216
|
...(sourceBytes !== undefined ? { sourceBytes } : {}),
|
|
200
217
|
...(status === 'complete' && sourceBytes !== undefined ? { transferredBytes: sourceBytes } : {}),
|
|
201
218
|
...(state?.destinationId ? { destinationId: state.destinationId } : {}),
|
|
202
219
|
...(state?.destinationName ? { destinationName: state.destinationName } : {}),
|
|
220
|
+
...(state?.destinationUrl ? { destinationUrl: state.destinationUrl } : {}),
|
|
221
|
+
...(state?.sha256 ? { sha256: state.sha256 } : {}),
|
|
203
222
|
...(state?.lastError ? { error: state.lastError } : {}),
|
|
204
223
|
...(status === 'blocked' && input.blockedBy ? input.blockedBy : {}),
|
|
205
224
|
};
|
|
@@ -207,24 +226,57 @@ function reportPage(input) {
|
|
|
207
226
|
const knownBytes = resourceItems.reduce((total, resource) => total + (resource.sourceBytes ?? 0), 0);
|
|
208
227
|
const transferredBytes = resourceItems.reduce((total, resource) => total + (resource.transferredBytes ?? 0), 0);
|
|
209
228
|
const commentsEnabled = input.commentsEnabled ?? true;
|
|
210
|
-
const inventory = input.commentInventory;
|
|
211
229
|
const commentState = input.commentState;
|
|
212
230
|
const commentStatus = !commentsEnabled
|
|
213
231
|
? 'skipped'
|
|
214
232
|
: commentState?.status
|
|
215
233
|
?? (inventory?.status === 'failed' ? 'failed' : inventory?.status === 'empty' ? 'complete' : 'planned');
|
|
216
234
|
const commentError = commentState?.lastError ?? inventory?.error;
|
|
235
|
+
const commentItems = inventory?.threads.flatMap((thread) => {
|
|
236
|
+
const result = [];
|
|
237
|
+
const visit = (entry) => {
|
|
238
|
+
const author = entry.author.displayName
|
|
239
|
+
?? entry.author.username
|
|
240
|
+
?? entry.author.publicName
|
|
241
|
+
?? entry.author.providerId;
|
|
242
|
+
result.push({
|
|
243
|
+
threadId: thread.id,
|
|
244
|
+
commentId: entry.id,
|
|
245
|
+
...(entry.parentId ? { parentId: entry.parentId } : {}),
|
|
246
|
+
author,
|
|
247
|
+
...(entry.createdAt ? { createdAt: entry.createdAt } : {}),
|
|
248
|
+
...(entry.status ? { sourceStatus: entry.status } : {}),
|
|
249
|
+
outcome: commentStatus,
|
|
250
|
+
sourceUrl: `${input.page.url}#comment-${encodeURIComponent(entry.id)}`,
|
|
251
|
+
...(commentState?.destinationUrl ? { destinationUrl: commentState.destinationUrl } : {}),
|
|
252
|
+
...(commentError ? { error: commentError } : {}),
|
|
253
|
+
});
|
|
254
|
+
for (const reply of entry.replies)
|
|
255
|
+
visit(reply);
|
|
256
|
+
};
|
|
257
|
+
visit(thread.root);
|
|
258
|
+
return result;
|
|
259
|
+
});
|
|
217
260
|
return {
|
|
218
261
|
sourceCanonicalId: input.page.canonicalId,
|
|
219
262
|
sourceId: input.page.id,
|
|
220
263
|
sourceTitle: input.page.title,
|
|
221
264
|
sourceUrl: input.page.url,
|
|
265
|
+
...(input.page.parentId ? { sourceParentId: input.page.parentId } : {}),
|
|
266
|
+
...(input.page.ancestorIds?.length ? { sourceAncestorIds: input.page.ancestorIds } : {}),
|
|
222
267
|
...(input.destination ? {
|
|
223
268
|
destinationId: input.destination.id,
|
|
224
269
|
destinationTitle: input.destination.title,
|
|
225
270
|
destinationUrl: input.destination.url,
|
|
271
|
+
...(input.destination.parentId ? { destinationParentId: input.destination.parentId } : {}),
|
|
226
272
|
} : {}),
|
|
227
|
-
...(input.
|
|
273
|
+
...(input.destinationFile ? {
|
|
274
|
+
destinationId: input.destinationFile.id,
|
|
275
|
+
destinationTitle: input.page.title,
|
|
276
|
+
destinationUrl: input.destinationFile.url,
|
|
277
|
+
...(input.destinationFile.parentId ? { destinationParentId: input.destinationFile.parentId } : {}),
|
|
278
|
+
} : {}),
|
|
279
|
+
...(input.page.projectedParentId ? { parentId: input.page.projectedParentId, projectedParentId: input.page.projectedParentId } : {}),
|
|
228
280
|
depth: input.page.depth,
|
|
229
281
|
status: input.status,
|
|
230
282
|
inventoryStatus: input.inventoryStatus ?? 'complete',
|
|
@@ -252,11 +304,14 @@ function reportPage(input) {
|
|
|
252
304
|
attachments: commentState?.attachments ?? inventory?.attachments ?? 0,
|
|
253
305
|
bytes: commentState?.bytes ?? inventory?.knownBytes ?? 0,
|
|
254
306
|
...(commentState?.archiveName ? { archiveName: commentState.archiveName } : {}),
|
|
307
|
+
...(commentState?.archiveUrl ? { archiveUrl: commentState.archiveUrl } : {}),
|
|
255
308
|
...(commentState?.destinationId ? { destinationId: commentState.destinationId } : {}),
|
|
309
|
+
...(commentState?.destinationUrl ? { destinationUrl: commentState.destinationUrl } : {}),
|
|
256
310
|
...(commentState?.previousDestinationIds?.length ? { revision: true } : {}),
|
|
257
311
|
...(commentState?.status === 'stale' ? { stale: true } : {}),
|
|
258
312
|
...(commentError ? { error: commentError } : {}),
|
|
259
313
|
...(commentState?.preview ? { preview: commentState.preview } : {}),
|
|
314
|
+
...(commentItems?.length ? { items: commentItems } : {}),
|
|
260
315
|
...(commentStatus === 'blocked' && input.blockedBy ? input.blockedBy : {}),
|
|
261
316
|
},
|
|
262
317
|
};
|
|
@@ -380,6 +435,7 @@ export class Migrator {
|
|
|
380
435
|
await store.save();
|
|
381
436
|
const run = await store.beginRun(options.scope, options.dryRun, sourceStatus, commentsEnabled);
|
|
382
437
|
const report = new TransferReport({
|
|
438
|
+
secrets: secretValues(this.config),
|
|
383
439
|
dryRun: options.dryRun,
|
|
384
440
|
commentsEnabled,
|
|
385
441
|
scope: options.scope,
|
|
@@ -590,6 +646,8 @@ export class Migrator {
|
|
|
590
646
|
const result = await this.exportFilesystem(source, graph, options.destination, options, stateLocation.id, store, report, sourceFingerprints, resourcesByPage, commentsByPage);
|
|
591
647
|
output = result.directory;
|
|
592
648
|
archive = result.archive;
|
|
649
|
+
const exportEntry = path.join(result.directory, options.destination.format === 'html' ? 'index.html' : 'index.md');
|
|
650
|
+
report.setDestinationUrl(pathToFileURL(exportEntry).toString());
|
|
593
651
|
report.output('directory', result.directory);
|
|
594
652
|
if (result.archive)
|
|
595
653
|
report.output('archive', result.archive);
|
|
@@ -684,6 +742,7 @@ export class Migrator {
|
|
|
684
742
|
sourceName: sourceResource?.name ?? resource.name,
|
|
685
743
|
destinationId: resource.path,
|
|
686
744
|
destinationName: resource.name,
|
|
745
|
+
destinationUrl: pathToFileURL(path.join(destination.path, resource.path)).toString(),
|
|
687
746
|
...(resource.sha256 ? { sha256: resource.sha256 } : {}),
|
|
688
747
|
...(resource.size !== undefined ? { size: resource.size } : {}),
|
|
689
748
|
status: options.dryRun ? 'planned' : 'complete',
|
|
@@ -722,8 +781,16 @@ export class Migrator {
|
|
|
722
781
|
} } : {}),
|
|
723
782
|
updatedAt: new Date().toISOString(),
|
|
724
783
|
});
|
|
784
|
+
const parentManifestPage = manifestPage?.parentId
|
|
785
|
+
? result.manifest.pages.find((item) => item.sourceCanonicalId === manifestPage.parentId)
|
|
786
|
+
: undefined;
|
|
725
787
|
report.addPage(reportPage({
|
|
726
788
|
page,
|
|
789
|
+
...(manifestPage ? { destinationFile: {
|
|
790
|
+
id: manifestPage.path,
|
|
791
|
+
url: pathToFileURL(path.join(destination.path, manifestPage.path)).toString(),
|
|
792
|
+
...(parentManifestPage ? { parentId: parentManifestPage.path } : {}),
|
|
793
|
+
} } : {}),
|
|
727
794
|
status: pageStatus,
|
|
728
795
|
resources: sourceResources,
|
|
729
796
|
document,
|
|
@@ -928,6 +995,7 @@ export class Migrator {
|
|
|
928
995
|
const archiveState = zip ? {
|
|
929
996
|
...(archiveResource ? { archiveResourceId: archiveResource.id } : {}),
|
|
930
997
|
archiveName: archiveResource?.name ?? zip.name,
|
|
998
|
+
...(archiveResource?.url ? { archiveUrl: archiveResource.url } : {}),
|
|
931
999
|
archivePath: zip.path,
|
|
932
1000
|
archiveSha256: zip.sha256,
|
|
933
1001
|
} : {};
|
|
@@ -1047,6 +1115,7 @@ export class Migrator {
|
|
|
1047
1115
|
fingerprint,
|
|
1048
1116
|
destinationId: verified.id,
|
|
1049
1117
|
destinationFingerprint: verified.fingerprint,
|
|
1118
|
+
...(verified.url ? { destinationUrl: verified.url } : {}),
|
|
1050
1119
|
...(previousIds?.length ? { previousDestinationIds: previousIds } : {}),
|
|
1051
1120
|
...archiveState,
|
|
1052
1121
|
...fullArchiveState,
|
|
@@ -1535,6 +1604,7 @@ export class Migrator {
|
|
|
1535
1604
|
sourceName: resource.name,
|
|
1536
1605
|
destinationId: mappedRemote.id,
|
|
1537
1606
|
destinationName: mappedRemote.name,
|
|
1607
|
+
...(mappedRemote.url ? { destinationUrl: mappedRemote.url } : {}),
|
|
1538
1608
|
sha256: downloaded.sha256,
|
|
1539
1609
|
size: downloaded.size,
|
|
1540
1610
|
cachePath: downloaded.path,
|
|
@@ -1558,6 +1628,7 @@ export class Migrator {
|
|
|
1558
1628
|
sourceName: resource.name,
|
|
1559
1629
|
destinationId: reconciled.id,
|
|
1560
1630
|
destinationName: reconciled.name,
|
|
1631
|
+
...(reconciled.url ? { destinationUrl: reconciled.url } : {}),
|
|
1561
1632
|
sha256: downloaded.sha256,
|
|
1562
1633
|
size: downloaded.size,
|
|
1563
1634
|
cachePath: downloaded.path,
|
|
@@ -1621,6 +1692,7 @@ export class Migrator {
|
|
|
1621
1692
|
sourceName: resource.name,
|
|
1622
1693
|
destinationId: result.id,
|
|
1623
1694
|
destinationName: result.name,
|
|
1695
|
+
...(result.url ? { destinationUrl: result.url } : {}),
|
|
1624
1696
|
sha256: downloaded.sha256,
|
|
1625
1697
|
size: downloaded.size,
|
|
1626
1698
|
cachePath: downloaded.path,
|