dicom-curate 0.40.7 → 0.41.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/dist/esm/applyMappingsWorker.js +24 -2
- package/dist/esm/collectMappings.js +24 -2
- package/dist/esm/curateDict.js +24 -2
- package/dist/esm/curateOne.js +24 -2
- package/dist/esm/getParser.js +11 -1
- package/dist/esm/index.js +24 -2
- package/dist/esm/mappingWorkerPool.js +24 -2
- package/dist/esm/scanDirectoryWorker.js +14 -3
- package/dist/types/getParser.d.ts +1 -1
- package/dist/types/scanDirectoryWorker.d.ts +10 -0
- package/dist/types/types.d.ts +1 -0
- package/dist/umd/dicom-curate.umd.js +112 -11
- package/dist/umd/dicom-curate.umd.js.map +1 -1
- package/dist/umd/dicom-curate.umd.min.js +2 -2
- package/dist/umd/dicom-curate.umd.min.js.map +1 -1
- package/package.json +1 -1
|
@@ -53787,7 +53787,7 @@
|
|
|
53787
53787
|
|
|
53788
53788
|
const FILEBASENAME = Symbol('fileBasename');
|
|
53789
53789
|
const FILENAME = Symbol('filename');
|
|
53790
|
-
function getParser(inputPathPattern, inputFilePath, naturalData, dicomPS315EOptions, columnMappings, additionalData) {
|
|
53790
|
+
function getParser(inputPathPattern, inputFilePath, naturalData, dicomPS315EOptions, columnMappings, additionalData, naturalMetaData) {
|
|
53791
53791
|
function protectUid$1(uid) {
|
|
53792
53792
|
let protectedUid = uid;
|
|
53793
53793
|
if (dicomPS315EOptions !== 'Off') {
|
|
@@ -53847,6 +53847,24 @@
|
|
|
53847
53847
|
return getCsvMapping(columnMappings, mapping, key, value);
|
|
53848
53848
|
};
|
|
53849
53849
|
})();
|
|
53850
|
+
// Reads the file meta information group (group 0002), which getDicom cannot
|
|
53851
|
+
// see because it operates on the dataset alone. Needed to identify a file by
|
|
53852
|
+
// MediaStorageSOPClassUID (e.g. for a DICOMDIR disguised as a .DCM).
|
|
53853
|
+
//
|
|
53854
|
+
// Values are always the ORIGINAL ones, even in postExclude where getDicom has
|
|
53855
|
+
// already switched to de-identified values — the meta group is captured once
|
|
53856
|
+
// and never re-read. Only string values are returned; a non-string meta value
|
|
53857
|
+
// (e.g. the OB FileMetaInformationVersion) reads as undefined.
|
|
53858
|
+
function getMetaDicom(attrName) {
|
|
53859
|
+
if (!naturalMetaData)
|
|
53860
|
+
return undefined;
|
|
53861
|
+
if (attrName in data$1.DicomMetaDictionary.dictionary) {
|
|
53862
|
+
// if in hex like "(0002,0002)", convert to text key
|
|
53863
|
+
attrName = data$1.DicomMetaDictionary.dictionary[attrName].name;
|
|
53864
|
+
}
|
|
53865
|
+
const value = lodashExports.get(naturalMetaData, attrName);
|
|
53866
|
+
return typeof value === 'string' ? value : undefined;
|
|
53867
|
+
}
|
|
53850
53868
|
function missingDicom(attrName) {
|
|
53851
53869
|
const value = getDicom(attrName);
|
|
53852
53870
|
return typeof value === 'undefined' || value === '';
|
|
@@ -53856,6 +53874,7 @@
|
|
|
53856
53874
|
getFilePathComp,
|
|
53857
53875
|
getMapping,
|
|
53858
53876
|
getDicom,
|
|
53877
|
+
getMetaDicom,
|
|
53859
53878
|
missingDicom,
|
|
53860
53879
|
protectUid: protectUid$1,
|
|
53861
53880
|
// TODO: Phase this out in favor of ISO8601 duration handling.
|
|
@@ -53902,15 +53921,31 @@
|
|
|
53902
53921
|
}
|
|
53903
53922
|
// Make make the naturalized data so parser code operates on with tags not hex
|
|
53904
53923
|
const naturalData = data$1.DicomMetaDictionary.naturalizeDataset(dicomData.dict);
|
|
53924
|
+
// File meta group (0002), kept separate from the dataset so preExclude can
|
|
53925
|
+
// reach MediaStorageSOPClassUID. Absent on a file that was not read from
|
|
53926
|
+
// Part 10 bytes, so guard rather than assume.
|
|
53927
|
+
const naturalMetaData = dicomData.meta
|
|
53928
|
+
? data$1.DicomMetaDictionary.naturalizeDataset(dicomData.meta)
|
|
53929
|
+
: undefined;
|
|
53905
53930
|
mapResults.sourceInstanceUID = naturalData.SOPInstanceUID;
|
|
53906
53931
|
const finalSpec = composeSpecs(mappingOptions.curationSpec());
|
|
53907
53932
|
// create a parser object to be used in the eval'ed mappingFunctions
|
|
53908
|
-
const parser = getParser(finalSpec.inputPathPattern, inputFilePath, naturalData, finalSpec.dicomPS315EOptions, mappingOptions.columnMappings, finalSpec.additionalData);
|
|
53909
|
-
// preExclude: original DICOM tags visible via parser.getDicom
|
|
53933
|
+
const parser = getParser(finalSpec.inputPathPattern, inputFilePath, naturalData, finalSpec.dicomPS315EOptions, mappingOptions.columnMappings, finalSpec.additionalData, naturalMetaData);
|
|
53934
|
+
// preExclude: original DICOM tags visible via parser.getDicom / parser.getMetaDicom
|
|
53910
53935
|
let preExcludeError;
|
|
53911
53936
|
try {
|
|
53912
53937
|
if (finalSpec.preExclude?.(parser)) {
|
|
53913
53938
|
mapResults.excluded = 'pre';
|
|
53939
|
+
// Write pass only: collectMappings runs on both the form-generation pass
|
|
53940
|
+
// (skipWrite) and the write pass, so emitting on both would double-count
|
|
53941
|
+
// the file for anomaly consumers. Matches the benign scan-exclusion
|
|
53942
|
+
// anomalies, which are likewise write-pass only.
|
|
53943
|
+
//
|
|
53944
|
+
// Name only, never the full path: anomalies are shared with the
|
|
53945
|
+
// server-bound log, and the raw path is carried in fileInfo instead.
|
|
53946
|
+
if (!mappingOptions.skipWrite) {
|
|
53947
|
+
mapResults.anomalies.push(`Skipped pre-excluded file: ${parser.getFilePathComp(parser.FILENAME)}`);
|
|
53948
|
+
}
|
|
53914
53949
|
return [naturalData, mapResults];
|
|
53915
53950
|
}
|
|
53916
53951
|
}
|
|
@@ -54002,13 +54037,18 @@
|
|
|
54002
54037
|
mapResults.outputFilePath = parts.join('/');
|
|
54003
54038
|
}
|
|
54004
54039
|
}
|
|
54005
|
-
// postExclude: output path is finalised; parser.getDicom() returns de-identified
|
|
54040
|
+
// postExclude: output path is finalised; parser.getDicom() returns de-identified
|
|
54041
|
+
// values — but parser.getMetaDicom() still returns the original meta group.
|
|
54006
54042
|
try {
|
|
54007
54043
|
if (finalSpec.postExclude?.({
|
|
54008
54044
|
...parser,
|
|
54009
54045
|
outputFilePath: mapResults.outputFilePath,
|
|
54010
54046
|
})) {
|
|
54011
54047
|
mapResults.excluded = 'post';
|
|
54048
|
+
// Write pass only — see the preExclude note above.
|
|
54049
|
+
if (!mappingOptions.skipWrite) {
|
|
54050
|
+
mapResults.anomalies.push(`Skipped post-excluded file: ${parser.getFilePathComp(parser.FILENAME)}`);
|
|
54051
|
+
}
|
|
54012
54052
|
return [naturalData, mapResults];
|
|
54013
54053
|
}
|
|
54014
54054
|
}
|
|
@@ -68839,7 +68879,7 @@
|
|
|
68839
68879
|
/* eslint-enable */
|
|
68840
68880
|
|
|
68841
68881
|
var WorkerFactory = /*#__PURE__*/createInlineWorkerFactory(/* rollup-plugin-web-worker-loader */function () {
|
|
68842
|
-
(function () {
|
|
68882
|
+
((function (exports) {
|
|
68843
68883
|
'__worker_loader_strict__';
|
|
68844
68884
|
|
|
68845
68885
|
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
@@ -68900,6 +68940,23 @@
|
|
|
68900
68940
|
'thumbs.db',
|
|
68901
68941
|
'.ds_store',
|
|
68902
68942
|
];
|
|
68943
|
+
/**
|
|
68944
|
+
* Name-based exclusion decision for an S3 object key.
|
|
68945
|
+
*
|
|
68946
|
+
* Exported for testing: the S3 listing path needs a live bucket, and the worker
|
|
68947
|
+
* runs in its own process where the S3 client cannot be mocked.
|
|
68948
|
+
*
|
|
68949
|
+
* Unlike the filesystem paths, an S3 key carries its whole prefix while the
|
|
68950
|
+
* exclusion list holds bare filenames — and the defaults apply here too.
|
|
68951
|
+
*/
|
|
68952
|
+
function isS3KeyExcludedByName(key, extraExcludedFiletypes, includeDefaults) {
|
|
68953
|
+
const objectName = key.slice(key.lastIndexOf('/') + 1);
|
|
68954
|
+
const allExcludedFiletypes = [
|
|
68955
|
+
...(includeDefaults ? DEFAULT_EXCLUDED_FILETYPES : []),
|
|
68956
|
+
...extraExcludedFiletypes,
|
|
68957
|
+
];
|
|
68958
|
+
return allExcludedFiletypes.some((excluded) => objectName.toLowerCase() === excluded.toLowerCase());
|
|
68959
|
+
}
|
|
68903
68960
|
/**
|
|
68904
68961
|
* Build a PHI-safe error message for a file that could not be read during
|
|
68905
68962
|
* scanning. Only the error code/name is included — never `error.message`,
|
|
@@ -69018,7 +69075,7 @@
|
|
|
69018
69075
|
return false;
|
|
69019
69076
|
}
|
|
69020
69077
|
// Check if the file is in the list of excluded files
|
|
69021
|
-
if (
|
|
69078
|
+
if (isS3KeyExcludedByName(s3Item.Key, excludedFiletypes, !noDefaultExclusions)) {
|
|
69022
69079
|
fileAnomalies.push(`Skipped excluded file: ${s3Item.Key}`);
|
|
69023
69080
|
return false;
|
|
69024
69081
|
}
|
|
@@ -69564,7 +69621,11 @@
|
|
|
69564
69621
|
__proto__: null
|
|
69565
69622
|
});
|
|
69566
69623
|
|
|
69567
|
-
|
|
69624
|
+
exports.isS3KeyExcludedByName = isS3KeyExcludedByName;
|
|
69625
|
+
|
|
69626
|
+
return exports;
|
|
69627
|
+
|
|
69628
|
+
}))({});
|
|
69568
69629
|
|
|
69569
69630
|
});
|
|
69570
69631
|
/* eslint-enable */
|
|
@@ -125511,7 +125572,7 @@
|
|
|
125511
125572
|
|
|
125512
125573
|
const FILEBASENAME = Symbol('fileBasename');
|
|
125513
125574
|
const FILENAME = Symbol('filename');
|
|
125514
|
-
function getParser(inputPathPattern, inputFilePath, naturalData, dicomPS315EOptions, columnMappings, additionalData) {
|
|
125575
|
+
function getParser(inputPathPattern, inputFilePath, naturalData, dicomPS315EOptions, columnMappings, additionalData, naturalMetaData) {
|
|
125515
125576
|
function protectUid$1(uid) {
|
|
125516
125577
|
let protectedUid = uid;
|
|
125517
125578
|
if (dicomPS315EOptions !== 'Off') {
|
|
@@ -125571,6 +125632,24 @@
|
|
|
125571
125632
|
return getCsvMapping(columnMappings, mapping, key, value);
|
|
125572
125633
|
};
|
|
125573
125634
|
})();
|
|
125635
|
+
// Reads the file meta information group (group 0002), which getDicom cannot
|
|
125636
|
+
// see because it operates on the dataset alone. Needed to identify a file by
|
|
125637
|
+
// MediaStorageSOPClassUID (e.g. for a DICOMDIR disguised as a .DCM).
|
|
125638
|
+
//
|
|
125639
|
+
// Values are always the ORIGINAL ones, even in postExclude where getDicom has
|
|
125640
|
+
// already switched to de-identified values — the meta group is captured once
|
|
125641
|
+
// and never re-read. Only string values are returned; a non-string meta value
|
|
125642
|
+
// (e.g. the OB FileMetaInformationVersion) reads as undefined.
|
|
125643
|
+
function getMetaDicom(attrName) {
|
|
125644
|
+
if (!naturalMetaData)
|
|
125645
|
+
return undefined;
|
|
125646
|
+
if (attrName in data$1.DicomMetaDictionary.dictionary) {
|
|
125647
|
+
// if in hex like "(0002,0002)", convert to text key
|
|
125648
|
+
attrName = data$1.DicomMetaDictionary.dictionary[attrName].name;
|
|
125649
|
+
}
|
|
125650
|
+
const value = lodashExports.get(naturalMetaData, attrName);
|
|
125651
|
+
return typeof value === 'string' ? value : undefined;
|
|
125652
|
+
}
|
|
125574
125653
|
function missingDicom(attrName) {
|
|
125575
125654
|
const value = getDicom(attrName);
|
|
125576
125655
|
return typeof value === 'undefined' || value === '';
|
|
@@ -125580,6 +125659,7 @@
|
|
|
125580
125659
|
getFilePathComp,
|
|
125581
125660
|
getMapping,
|
|
125582
125661
|
getDicom,
|
|
125662
|
+
getMetaDicom,
|
|
125583
125663
|
missingDicom,
|
|
125584
125664
|
protectUid: protectUid$1,
|
|
125585
125665
|
// TODO: Phase this out in favor of ISO8601 duration handling.
|
|
@@ -125626,15 +125706,31 @@
|
|
|
125626
125706
|
}
|
|
125627
125707
|
// Make make the naturalized data so parser code operates on with tags not hex
|
|
125628
125708
|
const naturalData = data$1.DicomMetaDictionary.naturalizeDataset(dicomData.dict);
|
|
125709
|
+
// File meta group (0002), kept separate from the dataset so preExclude can
|
|
125710
|
+
// reach MediaStorageSOPClassUID. Absent on a file that was not read from
|
|
125711
|
+
// Part 10 bytes, so guard rather than assume.
|
|
125712
|
+
const naturalMetaData = dicomData.meta
|
|
125713
|
+
? data$1.DicomMetaDictionary.naturalizeDataset(dicomData.meta)
|
|
125714
|
+
: undefined;
|
|
125629
125715
|
mapResults.sourceInstanceUID = naturalData.SOPInstanceUID;
|
|
125630
125716
|
const finalSpec = composeSpecs(mappingOptions.curationSpec());
|
|
125631
125717
|
// create a parser object to be used in the eval'ed mappingFunctions
|
|
125632
|
-
const parser = getParser(finalSpec.inputPathPattern, inputFilePath, naturalData, finalSpec.dicomPS315EOptions, mappingOptions.columnMappings, finalSpec.additionalData);
|
|
125633
|
-
// preExclude: original DICOM tags visible via parser.getDicom
|
|
125718
|
+
const parser = getParser(finalSpec.inputPathPattern, inputFilePath, naturalData, finalSpec.dicomPS315EOptions, mappingOptions.columnMappings, finalSpec.additionalData, naturalMetaData);
|
|
125719
|
+
// preExclude: original DICOM tags visible via parser.getDicom / parser.getMetaDicom
|
|
125634
125720
|
let preExcludeError;
|
|
125635
125721
|
try {
|
|
125636
125722
|
if (finalSpec.preExclude?.(parser)) {
|
|
125637
125723
|
mapResults.excluded = 'pre';
|
|
125724
|
+
// Write pass only: collectMappings runs on both the form-generation pass
|
|
125725
|
+
// (skipWrite) and the write pass, so emitting on both would double-count
|
|
125726
|
+
// the file for anomaly consumers. Matches the benign scan-exclusion
|
|
125727
|
+
// anomalies, which are likewise write-pass only.
|
|
125728
|
+
//
|
|
125729
|
+
// Name only, never the full path: anomalies are shared with the
|
|
125730
|
+
// server-bound log, and the raw path is carried in fileInfo instead.
|
|
125731
|
+
if (!mappingOptions.skipWrite) {
|
|
125732
|
+
mapResults.anomalies.push(`Skipped pre-excluded file: ${parser.getFilePathComp(parser.FILENAME)}`);
|
|
125733
|
+
}
|
|
125638
125734
|
return [naturalData, mapResults];
|
|
125639
125735
|
}
|
|
125640
125736
|
}
|
|
@@ -125726,13 +125822,18 @@
|
|
|
125726
125822
|
mapResults.outputFilePath = parts.join('/');
|
|
125727
125823
|
}
|
|
125728
125824
|
}
|
|
125729
|
-
// postExclude: output path is finalised; parser.getDicom() returns de-identified
|
|
125825
|
+
// postExclude: output path is finalised; parser.getDicom() returns de-identified
|
|
125826
|
+
// values — but parser.getMetaDicom() still returns the original meta group.
|
|
125730
125827
|
try {
|
|
125731
125828
|
if (finalSpec.postExclude?.({
|
|
125732
125829
|
...parser,
|
|
125733
125830
|
outputFilePath: mapResults.outputFilePath,
|
|
125734
125831
|
})) {
|
|
125735
125832
|
mapResults.excluded = 'post';
|
|
125833
|
+
// Write pass only — see the preExclude note above.
|
|
125834
|
+
if (!mappingOptions.skipWrite) {
|
|
125835
|
+
mapResults.anomalies.push(`Skipped post-excluded file: ${parser.getFilePathComp(parser.FILENAME)}`);
|
|
125836
|
+
}
|
|
125736
125837
|
return [naturalData, mapResults];
|
|
125737
125838
|
}
|
|
125738
125839
|
}
|