@adobe/aio-cli-plugin-api-mesh 3.7.0 → 3.8.0-alpha.1

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 (26) hide show
  1. package/README.md +3 -3
  2. package/oclif.manifest.json +1 -1
  3. package/package.json +3 -3
  4. package/src/commands/__fixtures__/files/requestParams.json +2 -2
  5. package/src/commands/__fixtures__/openapi-schema.json +3 -3
  6. package/src/commands/__fixtures__/requestParams.json +2 -2
  7. package/src/commands/__fixtures__/sample_fully_qualified_mesh.json +28 -28
  8. package/src/commands/__fixtures__/sample_mesh_files.json +22 -22
  9. package/src/commands/__fixtures__/sample_mesh_invalid_file_content.json +13 -13
  10. package/src/commands/__fixtures__/sample_mesh_invalid_file_name.json +24 -26
  11. package/src/commands/__fixtures__/sample_mesh_invalid_paths.json +22 -22
  12. package/src/commands/__fixtures__/sample_mesh_invalid_type.json +24 -26
  13. package/src/commands/__fixtures__/sample_mesh_mismatching_path.json +28 -28
  14. package/src/commands/__fixtures__/sample_mesh_outside_workspace_dir.json +22 -22
  15. package/src/commands/__fixtures__/sample_mesh_path_from_home.json +13 -13
  16. package/src/commands/__fixtures__/sample_mesh_subdirectory.json +22 -22
  17. package/src/commands/__fixtures__/sample_mesh_with_files_array.json +28 -28
  18. package/src/commands/__fixtures__/sample_secrets_mesh.json +1 -1
  19. package/src/commands/api-mesh/__tests__/log-get-bulk.test.js +253 -0
  20. package/src/commands/api-mesh/__tests__/log-get.test.js +234 -0
  21. package/src/commands/api-mesh/__tests__/log-list.test.js +162 -0
  22. package/src/commands/api-mesh/log-get-bulk.js +243 -0
  23. package/src/commands/api-mesh/log-get.js +83 -0
  24. package/src/commands/api-mesh/log-list.js +105 -0
  25. package/src/lib/devConsole.js +139 -0
  26. package/src/utils.js +70 -0
@@ -112,6 +112,45 @@ const describeMesh = async (organizationId, projectId, workspaceId, workspaceNam
112
112
  }
113
113
  };
114
114
 
115
+ /**
116
+ * List Recent Logs
117
+ *
118
+ * @param {*} organizationId
119
+ * @param {*} projectId
120
+ * @param {*} workspaceId
121
+ * @param {*} workspaceName
122
+ * @param {*} meshId
123
+ * @returns
124
+ */
125
+ const listLogs = async (organizationCode, projectId, workspaceId, meshId, fileName) => {
126
+ const { accessToken, apiKey } = await getDevConsoleConfig();
127
+ const url = `${SMS_BASE_URL}/organizations/${organizationCode}/projects/${projectId}/workspaces/${workspaceId}/meshes/${meshId}/logs/list`;
128
+ const config = {
129
+ method: 'get',
130
+ url: fileName ? url + `?filename=${fileName}` : url,
131
+ headers: {
132
+ 'Authorization': `Bearer ${accessToken}`,
133
+ 'x-request-id': global.requestId,
134
+ 'x-api-key': apiKey,
135
+ },
136
+ };
137
+
138
+ logger.info('Initiating GET %s', url);
139
+
140
+ try {
141
+ const response = await axios(config);
142
+
143
+ logger.info('Response from GET %s', response.status);
144
+
145
+ if (response?.status === 200) {
146
+ return response.data;
147
+ }
148
+ } catch (error) {
149
+ logger.error(`Error fetching recent logs: ${error}`);
150
+ throw error;
151
+ }
152
+ };
153
+
115
154
  const getMesh = async (organizationId, projectId, workspaceId, workspaceName, meshId) => {
116
155
  const { baseUrl: devConsoleUrl, accessToken, apiKey } = await getDevConsoleConfig();
117
156
  const config = {
@@ -1015,6 +1054,103 @@ const getPublicEncryptionKey = async organizationCode => {
1015
1054
  }
1016
1055
  };
1017
1056
 
1057
+ const getPresignedUrls = async (
1058
+ organizationCode,
1059
+ projectId,
1060
+ workspaceId,
1061
+ meshId,
1062
+ startTime,
1063
+ endTime,
1064
+ ) => {
1065
+ const { accessToken, apiKey } = await getDevConsoleConfig();
1066
+ const config = {
1067
+ method: 'get',
1068
+ url: `${SMS_BASE_URL}/organizations/${organizationCode}/projects/${projectId}/workspaces/${workspaceId}/meshes/${meshId}/logs?startDateTime=${startTime}&endDateTime=${endTime}`,
1069
+ headers: {
1070
+ 'Authorization': `Bearer ${accessToken}`,
1071
+ 'x-request-id': global.requestId,
1072
+ 'x-api-key': apiKey,
1073
+ },
1074
+ };
1075
+
1076
+ logger.info(
1077
+ 'Initiating GET %s',
1078
+ `${SMS_BASE_URL}/organizations/${organizationCode}/projects/${projectId}/workspaces/${workspaceId}/meshes/${meshId}/logs?startDateTime=${startTime}&endDateTime=${endTime}`,
1079
+ );
1080
+
1081
+ try {
1082
+ const response = await axios(config);
1083
+
1084
+ logger.info('Response from GET %s', response.status);
1085
+
1086
+ if (response?.status === 200) {
1087
+ logger.info(`Presigned urls : ${objToString(response, ['data'])}`);
1088
+ const { presignedUrls, totalSize } = response.data;
1089
+ return {
1090
+ presignedUrls,
1091
+ totalSize,
1092
+ };
1093
+ }
1094
+ } catch (error) {
1095
+ logger.error(`Error fetching presigned urls: ${error}`);
1096
+ return {
1097
+ urls: {},
1098
+ totalsize: 0,
1099
+ };
1100
+ }
1101
+ };
1102
+
1103
+ const getLogsByRayId = async (organizationCode, projectId, workspaceId, meshId, rayId) => {
1104
+ const { accessToken, apiKey } = await getDevConsoleConfig();
1105
+ const config = {
1106
+ method: 'get',
1107
+ url: `${SMS_BASE_URL}/organizations/${organizationCode}/projects/${projectId}/workspaces/${workspaceId}/meshes/${meshId}/logs/${rayId}`,
1108
+ headers: {
1109
+ 'Authorization': `Bearer ${accessToken}`,
1110
+ 'x-request-id': global.requestId,
1111
+ 'x-api-key': apiKey,
1112
+ },
1113
+ };
1114
+
1115
+ logger.info(
1116
+ 'Initiating GET %s',
1117
+ `${SMS_BASE_URL}/organizations/${organizationCode}/projects/${projectId}/workspaces/${workspaceId}/meshes/${meshId}/logs/${rayId}`,
1118
+ );
1119
+
1120
+ try {
1121
+ const response = await axios(config);
1122
+
1123
+ logger.info('Response from GET log %s', response.status);
1124
+ if (response?.status === 200) {
1125
+ logger.info(`Fetched log: ${objToString(response, ['data'])}`);
1126
+ return response.data;
1127
+ } else {
1128
+ let errorMessage = `Unexpected response status: ${response.status}`;
1129
+ logger.error(errorMessage);
1130
+ throw new Error(errorMessage);
1131
+ }
1132
+ } catch (error) {
1133
+ logger.info('Response from GET Logs %s', error.response.status);
1134
+ if (error.response.status === 404) {
1135
+ // The request was made and the server responded with a 404 status code
1136
+ logger.error('Logs not found for the given Ray ID');
1137
+
1138
+ let errorMessage = `LogNotFound`;
1139
+ logger.error(`${errorMessage}. Received ${error.response.status}, expected 200`);
1140
+ throw new Error(errorMessage);
1141
+ } else if (error.response.status === 500) {
1142
+ // Handle 500 Internal Server Error
1143
+ let errorMessage = `ServerError`;
1144
+ logger.error(errorMessage);
1145
+ throw new Error(errorMessage);
1146
+ } else {
1147
+ let errorMessage = `Something went wrong while getting logs. Received ${error.response.status}`;
1148
+ logger.error(errorMessage);
1149
+ throw new Error(errorMessage);
1150
+ }
1151
+ }
1152
+ };
1153
+
1018
1154
  module.exports = {
1019
1155
  getApiKeyCredential,
1020
1156
  describeMesh,
@@ -1023,6 +1159,7 @@ module.exports = {
1023
1159
  updateMesh,
1024
1160
  deleteMesh,
1025
1161
  getMeshId,
1162
+ listLogs,
1026
1163
  createAPIMeshCredentials,
1027
1164
  getListOfCurrentServices,
1028
1165
  subscribeCredentialToServices,
@@ -1032,4 +1169,6 @@ module.exports = {
1032
1169
  getTenantFeatures,
1033
1170
  getMeshDeployments,
1034
1171
  getPublicEncryptionKey,
1172
+ getPresignedUrls,
1173
+ getLogsByRayId,
1035
1174
  };
package/src/utils.js CHANGED
@@ -67,6 +67,25 @@ const selectFlag = Flags.boolean({
67
67
  default: false,
68
68
  });
69
69
 
70
+ const fileNameFlag = Flags.string({
71
+ description: 'Name of CSV file to export the recent logs to',
72
+ });
73
+
74
+ const startTimeFlag = Flags.string({
75
+ description: 'Start time for the logs in UTC',
76
+ required: true,
77
+ });
78
+
79
+ const endTimeFlag = Flags.string({
80
+ description: 'End time for the logs in UTC',
81
+ required: true,
82
+ });
83
+
84
+ const logFilenameFlag = Flags.string({
85
+ description: 'Path to the output file for logs',
86
+ required: true,
87
+ });
88
+
70
89
  /**
71
90
  * Parse the meshConfig and get the list of (local) files to be imported
72
91
  *
@@ -534,6 +553,52 @@ function reduceConsecutiveBackslashes(str) {
534
553
  return result;
535
554
  }
536
555
 
556
+ /**
557
+ * Helper function to suggest a corrected format for the user provided input date
558
+ * @param {string} inputDate
559
+ */
560
+ function suggestCorrectedDateFormat(inputDate) {
561
+ // Remove any non-numeric characters except 'T' and 'Z'
562
+ let correctedDate = inputDate.replace(/[^\dTZ]/g, '');
563
+
564
+ // If "T" is missing, insert it between the date and time
565
+ if (!/T/.test(correctedDate) && correctedDate.length >= 14) {
566
+ correctedDate = correctedDate.slice(0, 8) + 'T' + correctedDate.slice(8);
567
+ }
568
+
569
+ // Extract date components for validation
570
+ const month = parseInt(correctedDate.slice(4, 6), 10);
571
+ const day = parseInt(correctedDate.slice(6, 8), 10);
572
+ const hour = parseInt(correctedDate.slice(9, 11), 10);
573
+ const minute = parseInt(correctedDate.slice(11, 13), 10);
574
+ const second = parseInt(correctedDate.slice(13, 15), 10);
575
+
576
+ // Check for invalid month, day, hour, minute, second
577
+ const isValidDate =
578
+ month >= 1 &&
579
+ month <= 12 &&
580
+ day >= 1 &&
581
+ day <= 31 && // Note: Can be further validated by month and year
582
+ hour >= 0 &&
583
+ hour <= 23 &&
584
+ minute >= 0 &&
585
+ minute <= 59 &&
586
+ second >= 0 &&
587
+ second <= 59;
588
+
589
+ if (!isValidDate) {
590
+ return null; // Or return an error-specific message for better UX
591
+ }
592
+
593
+ // Add missing characters to match the correct format
594
+ correctedDate = correctedDate.replace(
595
+ /(\d{4})(\d{2})(\d{2})T?(\d{2})(\d{2})(\d{2})Z?/,
596
+ '$1-$2-$3T$4:$5:$6Z',
597
+ );
598
+
599
+ return correctedDate;
600
+ }
601
+
537
602
  module.exports = {
538
603
  ignoreCacheFlag,
539
604
  autoConfirmActionFlag,
@@ -548,7 +613,12 @@ module.exports = {
548
613
  debugFlag,
549
614
  selectFlag,
550
615
  secretsFlag,
616
+ fileNameFlag,
551
617
  interpolateSecrets,
552
618
  validateSecretsFile,
553
619
  encryptSecrets,
620
+ startTimeFlag,
621
+ endTimeFlag,
622
+ logFilenameFlag,
623
+ suggestCorrectedDateFormat,
554
624
  };