-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathspaces.ts
More file actions
126 lines (109 loc) · 4.98 KB
/
spaces.ts
File metadata and controls
126 lines (109 loc) · 4.98 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import { resolve as pResolve } from 'node:path';
import { mkdir } from 'node:fs/promises';
import { log, CLIProgressManager, configHandler } from '@contentstack/cli-utilities';
import type { AssetManagementExportOptions, AssetManagementAPIConfig } from '../types/asset-management-api';
import type { ExportContext } from '../types/export-types';
import { AssetManagementAdapter } from '../utils/asset-management-api-adapter';
import { AM_MAIN_PROCESS_NAME, PROCESS_NAMES, PROCESS_STATUS } from '../constants/index';
import ExportAssetTypes from './asset-types';
import ExportFields from './fields';
import ExportWorkspace from './workspaces';
/**
* Orchestrates the full Asset Management 2.0 export: shared asset types and fields,
* then per-workspace metadata and assets (including internal download).
* Progress and download are fully owned by this package.
*/
export class ExportSpaces {
private readonly options: AssetManagementExportOptions;
private parentProgressManager: CLIProgressManager | null = null;
private progressManager: CLIProgressManager | null = null;
constructor(options: AssetManagementExportOptions) {
this.options = options;
}
public setParentProgressManager(parent: CLIProgressManager): void {
this.parentProgressManager = parent;
}
async start(): Promise<void> {
const { linkedWorkspaces, exportDir, branchName, assetManagementUrl, org_uid, apiKey, context, securedAssets } =
this.options;
if (!linkedWorkspaces.length) {
log.debug('No linked workspaces to export', context);
return;
}
log.debug(`Exporting Asset Management 2.0 (${linkedWorkspaces.length} space(s))`, context);
log.debug(`Spaces: ${linkedWorkspaces.map((ws) => ws.space_uid).join(', ')}`, context);
const spacesRootPath = pResolve(exportDir, branchName || 'main', 'spaces');
await mkdir(spacesRootPath, { recursive: true });
log.debug(`Spaces root path: ${spacesRootPath}`, context);
const totalSteps = 2 + linkedWorkspaces.length * 4;
const progress = this.createProgress();
progress.addProcess(AM_MAIN_PROCESS_NAME, totalSteps);
progress
.startProcess(AM_MAIN_PROCESS_NAME)
.updateStatus(PROCESS_STATUS[PROCESS_NAMES.AM_FIELDS].FETCHING, AM_MAIN_PROCESS_NAME);
const apiConfig: AssetManagementAPIConfig = {
baseURL: assetManagementUrl,
headers: { organization_uid: org_uid },
context,
};
const exportContext: ExportContext = {
spacesRootPath,
context,
securedAssets,
};
const sharedFieldsDir = pResolve(spacesRootPath, 'fields');
const sharedAssetTypesDir = pResolve(spacesRootPath, 'asset_types');
await mkdir(sharedFieldsDir, { recursive: true });
await mkdir(sharedAssetTypesDir, { recursive: true });
const firstSpaceUid = linkedWorkspaces[0].space_uid;
try {
const exportAssetTypes = new ExportAssetTypes(apiConfig, exportContext);
exportAssetTypes.setParentProgressManager(progress);
await exportAssetTypes.start(firstSpaceUid);
const exportFields = new ExportFields(apiConfig, exportContext);
exportFields.setParentProgressManager(progress);
await exportFields.start(firstSpaceUid);
for (const ws of linkedWorkspaces) {
progress.updateStatus(`Exporting space: ${ws.space_uid}...`, AM_MAIN_PROCESS_NAME);
log.debug(`Exporting space: ${ws.space_uid}`, context);
const spaceDir = pResolve(spacesRootPath, ws.space_uid);
try {
const exportWorkspace = new ExportWorkspace(apiConfig, exportContext);
exportWorkspace.setParentProgressManager(progress);
await exportWorkspace.start(ws, spaceDir, branchName || 'main');
log.debug(`Exported workspace structure for space ${ws.space_uid}`, context);
} catch (err) {
log.debug(`Failed to export workspace for space ${ws.space_uid}: ${err}`, context);
progress.tick(
false,
`space: ${ws.space_uid}`,
(err as Error)?.message ?? PROCESS_STATUS[PROCESS_NAMES.AM_SPACE_METADATA].FAILED,
AM_MAIN_PROCESS_NAME,
);
throw err;
}
}
progress.completeProcess(AM_MAIN_PROCESS_NAME, true);
log.debug('Asset Management 2.0 export completed', context);
} catch (err) {
progress.completeProcess(AM_MAIN_PROCESS_NAME, false);
throw err;
}
}
private createProgress(): CLIProgressManager {
if (this.parentProgressManager) {
this.progressManager = this.parentProgressManager;
return this.parentProgressManager;
}
const logConfig = configHandler.get('log') || {};
const showConsoleLogs = logConfig.showConsoleLogs ?? false;
this.progressManager = CLIProgressManager.createNested(AM_MAIN_PROCESS_NAME, showConsoleLogs);
return this.progressManager;
}
}
/**
* Entry point for callers that prefer a function. Delegates to ExportSpaces.
*/
export async function exportSpaceStructure(options: AssetManagementExportOptions): Promise<void> {
await new ExportSpaces(options).start();
}