-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcomposable-studio.ts
More file actions
137 lines (113 loc) · 5.29 KB
/
composable-studio.ts
File metadata and controls
137 lines (113 loc) · 5.29 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
127
128
129
130
131
132
133
134
135
136
137
import { resolve as pResolve } from 'node:path';
import {
cliux,
isAuthenticated,
log,
messageHandler,
handleAndLogError,
HttpClient,
authenticationHandler,
} from '@contentstack/cli-utilities';
import { fsUtil, getExportBasePath, getOrgUid } from '../../utils';
import { ModuleClassParams, ComposableStudioConfig, ExportConfig, ComposableStudioProject } from '../../types';
export default class ExportComposableStudio {
protected composableStudioConfig: ComposableStudioConfig;
protected composableStudioProject: ComposableStudioProject | null = null;
protected apiClient: HttpClient;
public composableStudioPath: string;
public exportConfig: ExportConfig;
constructor({ exportConfig }: Omit<ModuleClassParams, 'stackAPIClient' | 'moduleName'>) {
this.exportConfig = exportConfig;
this.composableStudioConfig = exportConfig.modules['composable-studio'];
this.exportConfig.context.module = 'composable-studio';
// Initialize HttpClient with Studio API base URL
this.apiClient = new HttpClient();
this.apiClient.baseUrl(`${this.composableStudioConfig.apiBaseUrl}/${this.composableStudioConfig.apiVersion}`);
}
async start(): Promise<void> {
log.debug('Starting Studio project export process...', this.exportConfig.context);
if (!isAuthenticated()) {
cliux.print(
'WARNING!!! To export Studio projects, you must be logged in. Please check csdx auth:login --help to log in',
{ color: 'yellow' },
);
return Promise.resolve();
}
this.composableStudioPath = pResolve(
getExportBasePath(this.exportConfig),
this.composableStudioConfig.dirName,
);
log.debug(`Studio folder path: ${this.composableStudioPath}`, this.exportConfig.context);
await fsUtil.makeDirectory(this.composableStudioPath);
log.debug('Created Studio directory', this.exportConfig.context);
this.exportConfig.org_uid = this.exportConfig.org_uid || (await getOrgUid(this.exportConfig));
log.debug(`Organization UID: ${this.exportConfig.org_uid}`, this.exportConfig.context);
await this.exportProjects();
log.debug('Studio project export process completed', this.exportConfig.context);
}
/**
* Export Studio projects connected to the current stack
*/
async exportProjects(): Promise<void> {
log.debug('Starting Studio project export...', this.exportConfig.context);
try {
// Get authentication details - following personalization-api-adapter pattern
log.debug('Initializing Studio API authentication...', this.exportConfig.context);
await authenticationHandler.getAuthDetails();
const token = authenticationHandler.accessToken;
log.debug(
`Authentication type: ${authenticationHandler.isOauthEnabled ? 'OAuth' : 'Token'}`,
this.exportConfig.context,
);
// Set authentication headers based on auth type
if (authenticationHandler.isOauthEnabled) {
log.debug('Setting OAuth authorization header', this.exportConfig.context);
this.apiClient.headers({ authorization: token });
} else {
log.debug('Setting authtoken header', this.exportConfig.context);
this.apiClient.headers({ authtoken: token });
}
// Set organization_uid header
this.apiClient.headers({
organization_uid: this.exportConfig.org_uid,
Accept: 'application/json',
});
const apiUrl = '/projects';
log.debug(
`Fetching projects from: ${this.composableStudioConfig.apiBaseUrl}${apiUrl}`,
this.exportConfig.context,
);
// Make API call to fetch projects using HttpClient
const response = await this.apiClient.get(apiUrl);
if (response.status < 200 || response.status >= 300) {
throw new Error(`API call failed with status ${response.status}: ${JSON.stringify(response.data)}`);
}
const data = response.data;
log.debug(`Fetched ${data.projects?.length || 0} total projects`, this.exportConfig.context);
// Filter projects connected to this stack
const connectedProject = data.projects?.filter(
(project: ComposableStudioProject) => project.connectedStackApiKey === this.exportConfig.apiKey,
);
if (!connectedProject || connectedProject.length === 0) {
log.info(messageHandler.parse('COMPOSABLE_STUDIO_NOT_FOUND'), this.exportConfig.context);
return;
}
// Use the first connected project (stacks should have only one project)
this.composableStudioProject = connectedProject[0];
log.debug(`Found Studio project: ${this.composableStudioProject.name}`, this.exportConfig.context);
// Write the project to file
const composableStudioFilePath = pResolve(this.composableStudioPath, this.composableStudioConfig.fileName);
log.debug(`Writing Studio project to: ${composableStudioFilePath}`, this.exportConfig.context);
fsUtil.writeFile(composableStudioFilePath, this.composableStudioProject as unknown as Record<string, unknown>);
log.success(
messageHandler.parse('COMPOSABLE_STUDIO_EXPORT_COMPLETE', this.composableStudioProject.name),
this.exportConfig.context,
);
} catch (error: any) {
log.debug('Error occurred while exporting Studio project', this.exportConfig.context);
handleAndLogError(error, {
...this.exportConfig.context,
});
}
}
}