@cumulus/cmrjs 9.9.0 → 10.0.0-beta.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/cmr-utils.d.ts +45 -9
- package/cmr-utils.d.ts.map +1 -1
- package/cmr-utils.js +104 -38
- package/cmr-utils.js.map +1 -1
- package/index.d.ts +5 -1
- package/index.js +5 -1
- package/index.js.map +1 -1
- package/package.json +9 -9
- package/src/cmr-utils.js +108 -38
- package/src/index.js +8 -0
- package/tsconfig.tsbuildinfo +1 -1
package/src/cmr-utils.js
CHANGED
|
@@ -65,12 +65,13 @@ function getFileDescription(file, urlType = 'distribution') {
|
|
|
65
65
|
return filename ? `Download ${filename}` : 'File to download';
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
-
const
|
|
69
|
-
const
|
|
70
|
-
const
|
|
71
|
-
const
|
|
72
|
-
|
|
73
|
-
||
|
|
68
|
+
const isECHO10Filename = (filename) => filename.endsWith('cmr.xml');
|
|
69
|
+
const isUMMGFilename = (filename) => filename.endsWith('cmr.json');
|
|
70
|
+
const isISOFilename = (filename) => filename.endsWith('.iso.xml');
|
|
71
|
+
const isCMRISOFilename = (filename) => filename.endsWith('cmr_iso.xml');
|
|
72
|
+
const isCMRFilename = (filename) => isECHO10Filename(filename)
|
|
73
|
+
|| isUMMGFilename(filename)
|
|
74
|
+
|| isCMRISOFilename(filename);
|
|
74
75
|
|
|
75
76
|
const constructCmrConceptLink = (conceptId, extension) => `${getSearchUrl()}concepts/${conceptId}.${extension}`;
|
|
76
77
|
|
|
@@ -85,6 +86,17 @@ function isCMRFile(fileobject) {
|
|
|
85
86
|
return isCMRFilename(cmrfilename);
|
|
86
87
|
}
|
|
87
88
|
|
|
89
|
+
/**
|
|
90
|
+
* Returns True if this object can be determined to be an ISO file object.
|
|
91
|
+
*
|
|
92
|
+
* @param {Object} fileobject
|
|
93
|
+
* @returns {boolean} true if object references an ISO file metadata.
|
|
94
|
+
*/
|
|
95
|
+
function isISOFile(fileobject) {
|
|
96
|
+
const filename = fileobject.key || fileobject.name || fileobject.filename || '';
|
|
97
|
+
return isISOFilename(filename) || isCMRISOFilename(filename);
|
|
98
|
+
}
|
|
99
|
+
|
|
88
100
|
/**
|
|
89
101
|
* Extracts CMR file objects from the specified granule object.
|
|
90
102
|
*
|
|
@@ -92,30 +104,37 @@ function isCMRFile(fileobject) {
|
|
|
92
104
|
* `files` property
|
|
93
105
|
* @param {Array<Object>} granule.files - array of files for a granule
|
|
94
106
|
* @param {string} granule.granuleId - granule ID
|
|
107
|
+
* @param {Function} filterFunc - function to determine if the given file object is a
|
|
108
|
+
CMR file; defaults to `isCMRFile`
|
|
95
109
|
* @returns {Array<Object>} an array of CMR file objects, each with properties
|
|
96
|
-
* `granuleId`, `
|
|
110
|
+
* `granuleId`, `bucket`, `key`, and possibly `etag` (if present on input)
|
|
97
111
|
*/
|
|
98
|
-
function granuleToCmrFileObject({ granuleId, files = [] }) {
|
|
112
|
+
function granuleToCmrFileObject({ granuleId, files = [] }, filterFunc = isCMRFile) {
|
|
99
113
|
return files
|
|
100
|
-
.filter(
|
|
101
|
-
.map((file) =>
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
114
|
+
.filter(filterFunc)
|
|
115
|
+
.map((file) => {
|
|
116
|
+
const { Bucket, Key } = parseS3Uri(getS3UrlOfFile(file));
|
|
117
|
+
return {
|
|
118
|
+
// Include etag only if file has one
|
|
119
|
+
...pick(file, 'etag'),
|
|
120
|
+
bucket: Bucket,
|
|
121
|
+
key: Key,
|
|
122
|
+
granuleId,
|
|
123
|
+
};
|
|
124
|
+
});
|
|
108
125
|
}
|
|
109
126
|
|
|
110
127
|
/**
|
|
111
128
|
* Reduce granule object array to CMR files array
|
|
112
129
|
*
|
|
113
130
|
* @param {Array<Object>} granules - granule objects array
|
|
131
|
+
* @param {Function} filterFunc - function to determine if the given file object is a
|
|
132
|
+
CMR file; defaults to `isCMRFile`
|
|
114
133
|
*
|
|
115
|
-
* @returns {Array<Object>} - CMR file object array: {
|
|
134
|
+
* @returns {Array<Object>} - CMR file object array: { etag, bucket, key, granuleId }
|
|
116
135
|
*/
|
|
117
|
-
function granulesToCmrFileObjects(granules) {
|
|
118
|
-
return granules.flatMap(granuleToCmrFileObject);
|
|
136
|
+
function granulesToCmrFileObjects(granules, filterFunc = isCMRFile) {
|
|
137
|
+
return granules.flatMap((granule) => granuleToCmrFileObject(granule, filterFunc));
|
|
119
138
|
}
|
|
120
139
|
|
|
121
140
|
/**
|
|
@@ -200,12 +219,13 @@ async function publishUMMGJSON2CMR(cmrFile, cmrClient, revisionId) {
|
|
|
200
219
|
*/
|
|
201
220
|
async function publish2CMR(cmrPublishObject, creds, cmrRevisionId) {
|
|
202
221
|
const cmrClient = new CMR(creds);
|
|
222
|
+
const cmrFileName = getFilename(cmrPublishObject);
|
|
203
223
|
|
|
204
224
|
// choose xml or json and do the things.
|
|
205
|
-
if (
|
|
225
|
+
if (isECHO10Filename(cmrFileName)) {
|
|
206
226
|
return await publishECHO10XML2CMR(cmrPublishObject, cmrClient, cmrRevisionId);
|
|
207
227
|
}
|
|
208
|
-
if (
|
|
228
|
+
if (isUMMGFilename(cmrFileName)) {
|
|
209
229
|
return await publishUMMGJSON2CMR(cmrPublishObject, cmrClient, cmrRevisionId);
|
|
210
230
|
}
|
|
211
231
|
|
|
@@ -290,14 +310,14 @@ const metadataObjectFromCMRXMLFile = (cmrFilename, etag) =>
|
|
|
290
310
|
* @returns {Promise<Object>} metadata object from the file
|
|
291
311
|
* @throws {Error} if the specified filename does not represent an ECHO-10 XML
|
|
292
312
|
* file or a UMMG file
|
|
293
|
-
* @see
|
|
294
|
-
* @see
|
|
313
|
+
* @see isECHO10Filename
|
|
314
|
+
* @see isUMMGFilename
|
|
295
315
|
*/
|
|
296
316
|
function metadataObjectFromCMRFile(cmrFilename, etag) {
|
|
297
|
-
if (
|
|
317
|
+
if (isECHO10Filename(cmrFilename) || isISOFilename(cmrFilename)) {
|
|
298
318
|
return metadataObjectFromCMRXMLFile(cmrFilename, etag);
|
|
299
319
|
}
|
|
300
|
-
if (
|
|
320
|
+
if (isUMMGFilename(cmrFilename)) {
|
|
301
321
|
return metadataObjectFromCMRJSONFile(cmrFilename, etag);
|
|
302
322
|
}
|
|
303
323
|
throw new Error(
|
|
@@ -347,6 +367,51 @@ function mapCNMTypeToCMRType(type, urlType = 'distribution', useDirectS3Type = f
|
|
|
347
367
|
return mappedType;
|
|
348
368
|
}
|
|
349
369
|
|
|
370
|
+
/**
|
|
371
|
+
* Add ETags to file objects as some downstream functions expect this structure.
|
|
372
|
+
*
|
|
373
|
+
* @param {Object} granule - input granule object
|
|
374
|
+
* @param {Object} etags - map of s3URIs and ETags
|
|
375
|
+
* @returns {Object} - updated granule object
|
|
376
|
+
*/
|
|
377
|
+
function addEtagsToFileObjects(granule, etags) {
|
|
378
|
+
granule.files.forEach((incomingFile) => {
|
|
379
|
+
const file = incomingFile;
|
|
380
|
+
const fileURI = getS3UrlOfFile(file);
|
|
381
|
+
if (etags[fileURI]) file.etag = etags[fileURI];
|
|
382
|
+
});
|
|
383
|
+
return granule;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
/**
|
|
387
|
+
* Remove ETags to match output schema
|
|
388
|
+
*
|
|
389
|
+
* @param {Object} granule - output granule object
|
|
390
|
+
* @returns {undefined}
|
|
391
|
+
*/
|
|
392
|
+
function removeEtagsFromFileObjects(granule) {
|
|
393
|
+
granule.files.forEach((incomingFile) => {
|
|
394
|
+
const file = incomingFile;
|
|
395
|
+
delete file.etag;
|
|
396
|
+
});
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
/**
|
|
400
|
+
* Maps etag values from the specified granules' files.
|
|
401
|
+
*
|
|
402
|
+
* @param {Object[]} files - array of file objects with `bucket`, `key` and
|
|
403
|
+
* `etag` properties
|
|
404
|
+
* @returns {Object} mapping of file S3 URIs to etags
|
|
405
|
+
*/
|
|
406
|
+
function mapFileEtags(files) {
|
|
407
|
+
return files.reduce((filesMap, file) => {
|
|
408
|
+
const { bucket, key, etag } = file;
|
|
409
|
+
const s3Uri = getS3UrlOfFile({ bucket, key });
|
|
410
|
+
filesMap[s3Uri] = etag; // eslint-disable-line no-param-reassign
|
|
411
|
+
return filesMap;
|
|
412
|
+
}, {});
|
|
413
|
+
}
|
|
414
|
+
|
|
350
415
|
/**
|
|
351
416
|
* generate a url for a given file and a url type.
|
|
352
417
|
*
|
|
@@ -885,9 +950,9 @@ async function updateCMRMetadata({
|
|
|
885
950
|
let metadataObject;
|
|
886
951
|
let etag;
|
|
887
952
|
|
|
888
|
-
if (
|
|
953
|
+
if (isECHO10Filename(filename)) {
|
|
889
954
|
({ metadataObject, etag } = await updateEcho10XMLMetadata(params));
|
|
890
|
-
} else if (
|
|
955
|
+
} else if (isUMMGFilename(filename)) {
|
|
891
956
|
({ metadataObject, etag } = await updateUMMGMetadata(params));
|
|
892
957
|
} else {
|
|
893
958
|
throw new errors.CMRMetaFileNotFound(`Invalid CMR filetype: ${filename}`);
|
|
@@ -1022,9 +1087,9 @@ async function getGranuleTemporalInfo(granule) {
|
|
|
1022
1087
|
const cmrFile = granuleToCmrFileObject(granule);
|
|
1023
1088
|
if (cmrFile.length === 0) return {};
|
|
1024
1089
|
|
|
1025
|
-
const cmrFilename = cmrFile[0]
|
|
1090
|
+
const cmrFilename = getS3UrlOfFile(cmrFile[0]);
|
|
1026
1091
|
|
|
1027
|
-
if (
|
|
1092
|
+
if (isCMRISOFilename(cmrFilename)) {
|
|
1028
1093
|
const metadata = await metadataObjectFromCMRXMLFile(cmrFilename);
|
|
1029
1094
|
const metadataMI = metadata['gmd:DS_Series']['gmd:composedOf']['gmd:DS_DataSet']['gmd:has']['gmi:MI_Metadata'];
|
|
1030
1095
|
|
|
@@ -1044,7 +1109,7 @@ async function getGranuleTemporalInfo(granule) {
|
|
|
1044
1109
|
|
|
1045
1110
|
return { beginningDateTime, endingDateTime, productionDateTime, lastUpdateDateTime };
|
|
1046
1111
|
}
|
|
1047
|
-
if (
|
|
1112
|
+
if (isECHO10Filename(cmrFilename)) {
|
|
1048
1113
|
const metadata = await metadataObjectFromCMRXMLFile(cmrFilename);
|
|
1049
1114
|
const beginningDateTime = get(metadata.Granule, 'Temporal.RangeDateTime.BeginningDateTime');
|
|
1050
1115
|
const endingDateTime = get(metadata.Granule, 'Temporal.RangeDateTime.EndingDateTime');
|
|
@@ -1054,16 +1119,15 @@ async function getGranuleTemporalInfo(granule) {
|
|
|
1054
1119
|
beginningDateTime, endingDateTime, productionDateTime, lastUpdateDateTime,
|
|
1055
1120
|
};
|
|
1056
1121
|
}
|
|
1057
|
-
if (
|
|
1122
|
+
if (isUMMGFilename(cmrFilename)) {
|
|
1058
1123
|
const metadata = await metadataObjectFromCMRJSONFile(cmrFilename);
|
|
1059
1124
|
const beginningDateTime = get(metadata, 'TemporalExtent.RangeDateTime.BeginningDateTime');
|
|
1060
1125
|
const endingDateTime = get(metadata, 'TemporalExtent.RangeDateTime.EndingDateTime');
|
|
1061
1126
|
const productionDateTime = get(metadata, 'DataGranule.ProductionDateTime');
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
const lastUpdateDateTime = updateDate[0].Date;
|
|
1127
|
+
const lastUpdateDateTime = (metadata.ProviderDates.find((d) => d.Type === 'Update')
|
|
1128
|
+
|| metadata.ProviderDates.find((d) => d.Type === 'Insert')
|
|
1129
|
+
|| metadata.ProviderDates.find((d) => d.Type === 'Create') || {}).Date;
|
|
1130
|
+
|
|
1067
1131
|
return {
|
|
1068
1132
|
beginningDateTime, endingDateTime, productionDateTime, lastUpdateDateTime,
|
|
1069
1133
|
};
|
|
@@ -1072,6 +1136,7 @@ async function getGranuleTemporalInfo(granule) {
|
|
|
1072
1136
|
}
|
|
1073
1137
|
|
|
1074
1138
|
module.exports = {
|
|
1139
|
+
addEtagsToFileObjects,
|
|
1075
1140
|
constructCmrConceptLink,
|
|
1076
1141
|
constructOnlineAccessUrl,
|
|
1077
1142
|
constructOnlineAccessUrls,
|
|
@@ -1083,16 +1148,21 @@ module.exports = {
|
|
|
1083
1148
|
getFilename,
|
|
1084
1149
|
getGranuleTemporalInfo,
|
|
1085
1150
|
getCollectionsByShortNameAndVersion,
|
|
1151
|
+
getS3UrlOfFile,
|
|
1086
1152
|
getUserAccessibleBuckets,
|
|
1087
1153
|
granulesToCmrFileObjects,
|
|
1088
1154
|
isCMRFile,
|
|
1089
1155
|
isCMRFilename,
|
|
1090
|
-
|
|
1156
|
+
isCMRISOFilename,
|
|
1157
|
+
isECHO10Filename,
|
|
1091
1158
|
isISOFile,
|
|
1092
|
-
|
|
1159
|
+
isISOFilename,
|
|
1160
|
+
isUMMGFilename,
|
|
1161
|
+
mapFileEtags,
|
|
1093
1162
|
metadataObjectFromCMRFile,
|
|
1094
1163
|
publish2CMR,
|
|
1095
1164
|
reconcileCMRMetadata,
|
|
1165
|
+
removeEtagsFromFileObjects,
|
|
1096
1166
|
updateCMRMetadata,
|
|
1097
1167
|
uploadEcho10CMRFile,
|
|
1098
1168
|
uploadUMMGJSONCMRFile,
|
package/src/index.js
CHANGED
|
@@ -4,28 +4,36 @@ const {
|
|
|
4
4
|
ValidationError,
|
|
5
5
|
} = require('./utils');
|
|
6
6
|
const {
|
|
7
|
+
addEtagsToFileObjects,
|
|
7
8
|
constructOnlineAccessUrl,
|
|
8
9
|
getGranuleTemporalInfo,
|
|
9
10
|
getCollectionsByShortNameAndVersion,
|
|
10
11
|
getUserAccessibleBuckets,
|
|
11
12
|
isCMRFile,
|
|
13
|
+
isISOFile,
|
|
14
|
+
mapFileEtags,
|
|
12
15
|
metadataObjectFromCMRFile,
|
|
13
16
|
publish2CMR,
|
|
14
17
|
granulesToCmrFileObjects,
|
|
15
18
|
reconcileCMRMetadata,
|
|
19
|
+
removeEtagsFromFileObjects,
|
|
16
20
|
updateCMRMetadata,
|
|
17
21
|
} = require('./cmr-utils');
|
|
18
22
|
|
|
19
23
|
module.exports = {
|
|
24
|
+
addEtagsToFileObjects,
|
|
20
25
|
constructOnlineAccessUrl,
|
|
21
26
|
ValidationError,
|
|
22
27
|
getGranuleTemporalInfo,
|
|
23
28
|
getCollectionsByShortNameAndVersion,
|
|
24
29
|
getUserAccessibleBuckets,
|
|
25
30
|
isCMRFile,
|
|
31
|
+
isISOFile,
|
|
32
|
+
mapFileEtags,
|
|
26
33
|
metadataObjectFromCMRFile,
|
|
27
34
|
publish2CMR,
|
|
28
35
|
reconcileCMRMetadata,
|
|
36
|
+
removeEtagsFromFileObjects,
|
|
29
37
|
granulesToCmrFileObjects,
|
|
30
38
|
updateCMRMetadata,
|
|
31
39
|
};
|