@ubercode/dcmtk 0.1.4 → 0.2.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/README.md +18 -15
- package/dist/DicomInstance-By9zd7GM.d.cts +625 -0
- package/dist/DicomInstance-CQEIuF_x.d.ts +625 -0
- package/dist/{dcmodify-CTXBWKU9.d.cts → dcmodify-B-_uUIKB.d.ts} +4 -2
- package/dist/{dcmodify-Daeafqrm.d.ts → dcmodify-Gds9u5Vj.d.cts} +4 -2
- package/dist/dicom.cjs +329 -51
- package/dist/dicom.cjs.map +1 -1
- package/dist/dicom.d.cts +368 -3
- package/dist/dicom.d.ts +368 -3
- package/dist/dicom.js +329 -51
- package/dist/dicom.js.map +1 -1
- package/dist/index.cjs +1460 -419
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -7
- package/dist/index.d.ts +8 -7
- package/dist/index.js +1432 -413
- package/dist/index.js.map +1 -1
- package/dist/servers.cjs +2379 -196
- package/dist/servers.cjs.map +1 -1
- package/dist/servers.d.cts +1654 -3
- package/dist/servers.d.ts +1654 -3
- package/dist/servers.js +2305 -145
- package/dist/servers.js.map +1 -1
- package/dist/tools.cjs +97 -50
- package/dist/tools.cjs.map +1 -1
- package/dist/tools.d.cts +21 -4
- package/dist/tools.d.ts +21 -4
- package/dist/tools.js +97 -51
- package/dist/tools.js.map +1 -1
- package/dist/{types-zHhxS7d2.d.cts → types-Cgumy1N4.d.cts} +1 -24
- package/dist/{types-zHhxS7d2.d.ts → types-Cgumy1N4.d.ts} +1 -24
- package/dist/utils.cjs.map +1 -1
- package/dist/utils.d.cts +1 -1
- package/dist/utils.d.ts +1 -1
- package/dist/utils.js.map +1 -1
- package/package.json +8 -8
- package/dist/index-BZxi4104.d.ts +0 -826
- package/dist/index-CapkWqxy.d.ts +0 -1295
- package/dist/index-DX4C3zbo.d.cts +0 -826
- package/dist/index-r7AvpkCE.d.cts +0 -1295
package/dist/dicom.cjs
CHANGED
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
var path = require('path');
|
|
4
4
|
var stderrLib = require('stderr-lib');
|
|
5
|
-
var promises = require('fs/promises');
|
|
6
|
-
var zod = require('zod');
|
|
7
5
|
var child_process = require('child_process');
|
|
8
6
|
var kill = require('tree-kill');
|
|
9
7
|
var fs = require('fs');
|
|
8
|
+
var zod = require('zod');
|
|
10
9
|
var fastXmlParser = require('fast-xml-parser');
|
|
10
|
+
var promises = require('fs/promises');
|
|
11
11
|
|
|
12
12
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
13
13
|
|
|
@@ -30129,6 +30129,18 @@ function buildMergedModifications(base, other, erasures) {
|
|
|
30129
30129
|
}
|
|
30130
30130
|
return merged;
|
|
30131
30131
|
}
|
|
30132
|
+
function applyBatchEntries(initial, entries) {
|
|
30133
|
+
const keys = Object.keys(entries);
|
|
30134
|
+
let cs = initial;
|
|
30135
|
+
for (let i = 0; i < keys.length; i++) {
|
|
30136
|
+
const key = keys[i];
|
|
30137
|
+
if (key === void 0) continue;
|
|
30138
|
+
const value = entries[key];
|
|
30139
|
+
if (value === void 0) continue;
|
|
30140
|
+
cs = cs.setTag(key, value);
|
|
30141
|
+
}
|
|
30142
|
+
return cs;
|
|
30143
|
+
}
|
|
30132
30144
|
var ChangeSet = class _ChangeSet {
|
|
30133
30145
|
constructor(mods, erasures) {
|
|
30134
30146
|
__publicField(this, "mods");
|
|
@@ -30146,7 +30158,7 @@ var ChangeSet = class _ChangeSet {
|
|
|
30146
30158
|
* Control characters (except LF/CR) are stripped from the value.
|
|
30147
30159
|
* If the tag was previously erased, it is removed from the erasure set.
|
|
30148
30160
|
*
|
|
30149
|
-
* @param path - The DICOM tag path to set
|
|
30161
|
+
* @param path - The DICOM tag path to set (e.g. `'(0010,0010)'`)
|
|
30150
30162
|
* @param value - The new value for the tag
|
|
30151
30163
|
* @returns A new ChangeSet with the modification applied
|
|
30152
30164
|
* @throws Error if operation count would exceed MAX_CHANGESET_OPERATIONS
|
|
@@ -30169,7 +30181,7 @@ var ChangeSet = class _ChangeSet {
|
|
|
30169
30181
|
*
|
|
30170
30182
|
* If the tag was previously set, the modification is removed.
|
|
30171
30183
|
*
|
|
30172
|
-
* @param path - The DICOM tag path to erase
|
|
30184
|
+
* @param path - The DICOM tag path to erase (e.g. `'(0010,0010)'`)
|
|
30173
30185
|
* @returns A new ChangeSet with the erasure applied
|
|
30174
30186
|
* @throws Error if operation count would exceed MAX_CHANGESET_OPERATIONS
|
|
30175
30187
|
*/
|
|
@@ -30200,6 +30212,50 @@ var ChangeSet = class _ChangeSet {
|
|
|
30200
30212
|
newErasures.add(ERASE_PRIVATE_SENTINEL);
|
|
30201
30213
|
return new _ChangeSet(new Map(this.mods), newErasures);
|
|
30202
30214
|
}
|
|
30215
|
+
// -----------------------------------------------------------------------
|
|
30216
|
+
// Convenience setters for common DICOM tags
|
|
30217
|
+
// -----------------------------------------------------------------------
|
|
30218
|
+
/** Sets Patient's Name (0010,0010). */
|
|
30219
|
+
setPatientName(value) {
|
|
30220
|
+
return this.setTag("(0010,0010)", value);
|
|
30221
|
+
}
|
|
30222
|
+
/** Sets Patient ID (0010,0020). */
|
|
30223
|
+
setPatientID(value) {
|
|
30224
|
+
return this.setTag("(0010,0020)", value);
|
|
30225
|
+
}
|
|
30226
|
+
/** Sets Study Date (0008,0020). */
|
|
30227
|
+
setStudyDate(value) {
|
|
30228
|
+
return this.setTag("(0008,0020)", value);
|
|
30229
|
+
}
|
|
30230
|
+
/** Sets Modality (0008,0060). */
|
|
30231
|
+
setModality(value) {
|
|
30232
|
+
return this.setTag("(0008,0060)", value);
|
|
30233
|
+
}
|
|
30234
|
+
/** Sets Accession Number (0008,0050). */
|
|
30235
|
+
setAccessionNumber(value) {
|
|
30236
|
+
return this.setTag("(0008,0050)", value);
|
|
30237
|
+
}
|
|
30238
|
+
/** Sets Study Description (0008,1030). */
|
|
30239
|
+
setStudyDescription(value) {
|
|
30240
|
+
return this.setTag("(0008,1030)", value);
|
|
30241
|
+
}
|
|
30242
|
+
/** Sets Series Description (0008,103E). */
|
|
30243
|
+
setSeriesDescription(value) {
|
|
30244
|
+
return this.setTag("(0008,103E)", value);
|
|
30245
|
+
}
|
|
30246
|
+
/** Sets Institution Name (0008,0080). */
|
|
30247
|
+
setInstitutionName(value) {
|
|
30248
|
+
return this.setTag("(0008,0080)", value);
|
|
30249
|
+
}
|
|
30250
|
+
/**
|
|
30251
|
+
* Sets multiple tags at once, returning a new ChangeSet.
|
|
30252
|
+
*
|
|
30253
|
+
* @param entries - A record of tag path → value pairs
|
|
30254
|
+
* @returns A new ChangeSet with all modifications applied
|
|
30255
|
+
*/
|
|
30256
|
+
setBatch(entries) {
|
|
30257
|
+
return applyBatchEntries(this, entries);
|
|
30258
|
+
}
|
|
30203
30259
|
/** All pending tag modifications as a readonly map of path → value. */
|
|
30204
30260
|
get modifications() {
|
|
30205
30261
|
return this.mods;
|
|
@@ -30730,7 +30786,8 @@ var DcmodifyOptionsSchema = zod.z.object({
|
|
|
30730
30786
|
erasures: zod.z.array(zod.z.string()).optional(),
|
|
30731
30787
|
erasePrivateTags: zod.z.boolean().optional(),
|
|
30732
30788
|
noBackup: zod.z.boolean().optional(),
|
|
30733
|
-
insertIfMissing: zod.z.boolean().optional()
|
|
30789
|
+
insertIfMissing: zod.z.boolean().optional(),
|
|
30790
|
+
ignoreMissingTags: zod.z.boolean().optional()
|
|
30734
30791
|
}).strict().refine((data) => data.modifications.length > 0 || data.erasures !== void 0 && data.erasures.length > 0 || data.erasePrivateTags === true, {
|
|
30735
30792
|
message: "At least one of modifications, erasures, or erasePrivateTags is required"
|
|
30736
30793
|
});
|
|
@@ -30739,6 +30796,9 @@ function buildArgs(inputPath, options) {
|
|
|
30739
30796
|
if (options.noBackup !== false) {
|
|
30740
30797
|
args.push("-nb");
|
|
30741
30798
|
}
|
|
30799
|
+
if (options.ignoreMissingTags === true) {
|
|
30800
|
+
args.push("-imt");
|
|
30801
|
+
}
|
|
30742
30802
|
const flag = options.insertIfMissing === true ? "-i" : "-m";
|
|
30743
30803
|
const modifications = options.modifications ?? [];
|
|
30744
30804
|
for (const mod of modifications) {
|
|
@@ -30758,7 +30818,7 @@ function buildArgs(inputPath, options) {
|
|
|
30758
30818
|
async function dcmodify(inputPath, options) {
|
|
30759
30819
|
const validation = DcmodifyOptionsSchema.safeParse(options);
|
|
30760
30820
|
if (!validation.success) {
|
|
30761
|
-
return err(
|
|
30821
|
+
return err(createValidationError("dcmodify", validation.error));
|
|
30762
30822
|
}
|
|
30763
30823
|
const binaryResult = resolveBinary("dcmodify");
|
|
30764
30824
|
if (!binaryResult.ok) {
|
|
@@ -30778,16 +30838,16 @@ async function dcmodify(inputPath, options) {
|
|
|
30778
30838
|
}
|
|
30779
30839
|
return ok({ filePath: inputPath });
|
|
30780
30840
|
}
|
|
30781
|
-
|
|
30782
|
-
// src/dicom/DicomFile.ts
|
|
30783
30841
|
async function applyModifications(filePath, changeset, options) {
|
|
30784
30842
|
const modifications = changeset.toModifications();
|
|
30785
30843
|
const erasures = changeset.toErasureArgs();
|
|
30844
|
+
const hasErasures = erasures.length > 0 || changeset.erasePrivate;
|
|
30786
30845
|
const result = await dcmodify(filePath, {
|
|
30787
30846
|
modifications: modifications.length > 0 ? modifications : void 0,
|
|
30788
30847
|
erasures: erasures.length > 0 ? erasures : void 0,
|
|
30789
30848
|
erasePrivateTags: changeset.erasePrivate || void 0,
|
|
30790
30849
|
insertIfMissing: true,
|
|
30850
|
+
ignoreMissingTags: hasErasures || void 0,
|
|
30791
30851
|
timeoutMs: options.timeoutMs ?? DEFAULT_TIMEOUT_MS,
|
|
30792
30852
|
signal: options.signal
|
|
30793
30853
|
});
|
|
@@ -30812,24 +30872,28 @@ async function unlinkFile(path) {
|
|
|
30812
30872
|
(e) => new Error(`Failed to delete file: ${e.message}`)
|
|
30813
30873
|
);
|
|
30814
30874
|
}
|
|
30815
|
-
|
|
30816
|
-
|
|
30817
|
-
|
|
30818
|
-
|
|
30819
|
-
|
|
30820
|
-
__publicField(this, "
|
|
30821
|
-
|
|
30822
|
-
__publicField(this, "
|
|
30823
|
-
this.
|
|
30824
|
-
this.
|
|
30825
|
-
this.
|
|
30875
|
+
|
|
30876
|
+
// src/dicom/DicomInstance.ts
|
|
30877
|
+
var DicomInstance = class _DicomInstance {
|
|
30878
|
+
constructor(dataset, changes, filePath, metadata) {
|
|
30879
|
+
__publicField(this, "dicomDataset");
|
|
30880
|
+
__publicField(this, "changeSet");
|
|
30881
|
+
__publicField(this, "filepath");
|
|
30882
|
+
__publicField(this, "meta");
|
|
30883
|
+
this.dicomDataset = dataset;
|
|
30884
|
+
this.changeSet = changes;
|
|
30885
|
+
this.filepath = filePath;
|
|
30886
|
+
this.meta = metadata;
|
|
30826
30887
|
}
|
|
30888
|
+
// -----------------------------------------------------------------------
|
|
30889
|
+
// Factories
|
|
30890
|
+
// -----------------------------------------------------------------------
|
|
30827
30891
|
/**
|
|
30828
|
-
* Opens a DICOM file and
|
|
30892
|
+
* Opens a DICOM file and creates a DicomInstance.
|
|
30829
30893
|
*
|
|
30830
30894
|
* @param path - Filesystem path to the DICOM file
|
|
30831
30895
|
* @param options - Timeout and abort options
|
|
30832
|
-
* @returns A Result containing the
|
|
30896
|
+
* @returns A Result containing the DicomInstance or an error
|
|
30833
30897
|
*/
|
|
30834
30898
|
static async open(path, options) {
|
|
30835
30899
|
const filePathResult = createDicomFilePath(path);
|
|
@@ -30841,64 +30905,250 @@ var DicomFile = class _DicomFile {
|
|
|
30841
30905
|
if (!jsonResult.ok) return err(jsonResult.error);
|
|
30842
30906
|
const datasetResult = DicomDataset.fromJson(jsonResult.value.data);
|
|
30843
30907
|
if (!datasetResult.ok) return err(datasetResult.error);
|
|
30844
|
-
return ok(new
|
|
30908
|
+
return ok(new _DicomInstance(datasetResult.value, ChangeSet.empty(), filePathResult.value, /* @__PURE__ */ new Map()));
|
|
30845
30909
|
}
|
|
30846
30910
|
/**
|
|
30847
|
-
*
|
|
30911
|
+
* Creates a DicomInstance from an existing DicomDataset.
|
|
30912
|
+
*
|
|
30913
|
+
* @param dataset - The DicomDataset to wrap
|
|
30914
|
+
* @param filePath - Optional file path (e.g. if the dataset came from a file)
|
|
30915
|
+
* @returns A Result containing the DicomInstance
|
|
30916
|
+
*/
|
|
30917
|
+
static fromDataset(dataset, filePath) {
|
|
30918
|
+
let fp;
|
|
30919
|
+
if (filePath !== void 0) {
|
|
30920
|
+
const fpResult = createDicomFilePath(filePath);
|
|
30921
|
+
if (!fpResult.ok) return err(fpResult.error);
|
|
30922
|
+
fp = fpResult.value;
|
|
30923
|
+
}
|
|
30924
|
+
return ok(new _DicomInstance(dataset, ChangeSet.empty(), fp, /* @__PURE__ */ new Map()));
|
|
30925
|
+
}
|
|
30926
|
+
// -----------------------------------------------------------------------
|
|
30927
|
+
// Read accessors (delegate to DicomDataset)
|
|
30928
|
+
// -----------------------------------------------------------------------
|
|
30929
|
+
/** The underlying immutable DICOM dataset. */
|
|
30930
|
+
get dataset() {
|
|
30931
|
+
return this.dicomDataset;
|
|
30932
|
+
}
|
|
30933
|
+
/** The pending change set. */
|
|
30934
|
+
get changes() {
|
|
30935
|
+
return this.changeSet;
|
|
30936
|
+
}
|
|
30937
|
+
/** Whether there are unsaved changes. */
|
|
30938
|
+
get hasUnsavedChanges() {
|
|
30939
|
+
return !this.changeSet.isEmpty;
|
|
30940
|
+
}
|
|
30941
|
+
/** The file path, or undefined if this instance has no associated file. */
|
|
30942
|
+
get filePath() {
|
|
30943
|
+
return this.filepath;
|
|
30944
|
+
}
|
|
30945
|
+
/** Patient's Name (0010,0010). */
|
|
30946
|
+
get patientName() {
|
|
30947
|
+
return this.dicomDataset.patientName;
|
|
30948
|
+
}
|
|
30949
|
+
/** Patient ID (0010,0020). */
|
|
30950
|
+
get patientID() {
|
|
30951
|
+
return this.dicomDataset.patientID;
|
|
30952
|
+
}
|
|
30953
|
+
/** Study Date (0008,0020). */
|
|
30954
|
+
get studyDate() {
|
|
30955
|
+
return this.dicomDataset.studyDate;
|
|
30956
|
+
}
|
|
30957
|
+
/** Modality (0008,0060). */
|
|
30958
|
+
get modality() {
|
|
30959
|
+
return this.dicomDataset.modality;
|
|
30960
|
+
}
|
|
30961
|
+
/** Accession Number (0008,0050). */
|
|
30962
|
+
get accession() {
|
|
30963
|
+
return this.dicomDataset.accession;
|
|
30964
|
+
}
|
|
30965
|
+
/** SOP Class UID (0008,0016). */
|
|
30966
|
+
get sopClassUID() {
|
|
30967
|
+
return this.dicomDataset.sopClassUID;
|
|
30968
|
+
}
|
|
30969
|
+
/** Study Instance UID (0020,000D). */
|
|
30970
|
+
get studyInstanceUID() {
|
|
30971
|
+
return this.dicomDataset.studyInstanceUID;
|
|
30972
|
+
}
|
|
30973
|
+
/** Series Instance UID (0020,000E). */
|
|
30974
|
+
get seriesInstanceUID() {
|
|
30975
|
+
return this.dicomDataset.seriesInstanceUID;
|
|
30976
|
+
}
|
|
30977
|
+
/** SOP Instance UID (0008,0018). */
|
|
30978
|
+
get sopInstanceUID() {
|
|
30979
|
+
return this.dicomDataset.sopInstanceUID;
|
|
30980
|
+
}
|
|
30981
|
+
/** Transfer Syntax UID (0002,0010). */
|
|
30982
|
+
get transferSyntaxUID() {
|
|
30983
|
+
return this.dicomDataset.transferSyntaxUID;
|
|
30984
|
+
}
|
|
30985
|
+
/**
|
|
30986
|
+
* Gets a tag value as a string with optional fallback.
|
|
30987
|
+
*
|
|
30988
|
+
* @param tag - A DICOM tag, e.g. `'(0010,0010)'` or `'00100010'`
|
|
30989
|
+
* @param fallback - Value to return if tag is missing (default: `''`)
|
|
30990
|
+
*/
|
|
30991
|
+
getString(tag, fallback = "") {
|
|
30992
|
+
return this.dicomDataset.getString(tag, fallback);
|
|
30993
|
+
}
|
|
30994
|
+
/**
|
|
30995
|
+
* Gets a tag value as a number.
|
|
30996
|
+
*
|
|
30997
|
+
* @param tag - A DICOM tag, e.g. `'(0020,0013)'`
|
|
30998
|
+
*/
|
|
30999
|
+
getNumber(tag) {
|
|
31000
|
+
return this.dicomDataset.getNumber(tag);
|
|
31001
|
+
}
|
|
31002
|
+
/** Checks whether a tag exists in the dataset. */
|
|
31003
|
+
hasTag(tag) {
|
|
31004
|
+
return this.dicomDataset.hasTag(tag);
|
|
31005
|
+
}
|
|
31006
|
+
/**
|
|
31007
|
+
* Finds all values matching a wildcard path.
|
|
31008
|
+
*
|
|
31009
|
+
* @param path - A DicomTagPath with optional wildcard indices
|
|
31010
|
+
*/
|
|
31011
|
+
findValues(path) {
|
|
31012
|
+
return this.dicomDataset.findValues(path);
|
|
31013
|
+
}
|
|
31014
|
+
// -----------------------------------------------------------------------
|
|
31015
|
+
// Write methods (return new instance)
|
|
31016
|
+
// -----------------------------------------------------------------------
|
|
31017
|
+
/**
|
|
31018
|
+
* Sets a tag value, returning a new DicomInstance.
|
|
31019
|
+
*
|
|
31020
|
+
* @param path - The DICOM tag path (e.g. `'(0010,0010)'`)
|
|
31021
|
+
* @param value - The new value
|
|
31022
|
+
*/
|
|
31023
|
+
setTag(path, value) {
|
|
31024
|
+
return new _DicomInstance(this.dicomDataset, this.changeSet.setTag(path, value), this.filepath, this.meta);
|
|
31025
|
+
}
|
|
31026
|
+
/**
|
|
31027
|
+
* Erases a tag, returning a new DicomInstance.
|
|
31028
|
+
*
|
|
31029
|
+
* @param path - The DICOM tag path to erase
|
|
31030
|
+
*/
|
|
31031
|
+
eraseTag(path) {
|
|
31032
|
+
return new _DicomInstance(this.dicomDataset, this.changeSet.eraseTag(path), this.filepath, this.meta);
|
|
31033
|
+
}
|
|
31034
|
+
/** Erases all private tags, returning a new DicomInstance. */
|
|
31035
|
+
erasePrivateTags() {
|
|
31036
|
+
return new _DicomInstance(this.dicomDataset, this.changeSet.erasePrivateTags(), this.filepath, this.meta);
|
|
31037
|
+
}
|
|
31038
|
+
/** Sets Patient's Name (0010,0010). */
|
|
31039
|
+
setPatientName(value) {
|
|
31040
|
+
return this.setTag("(0010,0010)", value);
|
|
31041
|
+
}
|
|
31042
|
+
/** Sets Patient ID (0010,0020). */
|
|
31043
|
+
setPatientID(value) {
|
|
31044
|
+
return this.setTag("(0010,0020)", value);
|
|
31045
|
+
}
|
|
31046
|
+
/** Sets Study Date (0008,0020). */
|
|
31047
|
+
setStudyDate(value) {
|
|
31048
|
+
return this.setTag("(0008,0020)", value);
|
|
31049
|
+
}
|
|
31050
|
+
/** Sets Modality (0008,0060). */
|
|
31051
|
+
setModality(value) {
|
|
31052
|
+
return this.setTag("(0008,0060)", value);
|
|
31053
|
+
}
|
|
31054
|
+
/** Sets Accession Number (0008,0050). */
|
|
31055
|
+
setAccessionNumber(value) {
|
|
31056
|
+
return this.setTag("(0008,0050)", value);
|
|
31057
|
+
}
|
|
31058
|
+
/** Sets Study Description (0008,1030). */
|
|
31059
|
+
setStudyDescription(value) {
|
|
31060
|
+
return this.setTag("(0008,1030)", value);
|
|
31061
|
+
}
|
|
31062
|
+
/** Sets Series Description (0008,103E). */
|
|
31063
|
+
setSeriesDescription(value) {
|
|
31064
|
+
return this.setTag("(0008,103E)", value);
|
|
31065
|
+
}
|
|
31066
|
+
/** Sets Institution Name (0008,0080). */
|
|
31067
|
+
setInstitutionName(value) {
|
|
31068
|
+
return this.setTag("(0008,0080)", value);
|
|
31069
|
+
}
|
|
31070
|
+
/**
|
|
31071
|
+
* Transforms a tag value using a function.
|
|
31072
|
+
*
|
|
31073
|
+
* The function receives the current string value (or undefined if tag is missing)
|
|
31074
|
+
* and returns the new value. Returns a new DicomInstance with the modification.
|
|
31075
|
+
*
|
|
31076
|
+
* @param path - The DICOM tag path
|
|
31077
|
+
* @param fn - Transform function receiving the current value
|
|
31078
|
+
*/
|
|
31079
|
+
transformTag(path, fn) {
|
|
31080
|
+
const current = this.dicomDataset.getString(path);
|
|
31081
|
+
const newValue = fn(current.length > 0 ? current : void 0);
|
|
31082
|
+
return this.setTag(path, newValue);
|
|
31083
|
+
}
|
|
31084
|
+
/**
|
|
31085
|
+
* Sets multiple tags at once, returning a new DicomInstance.
|
|
31086
|
+
*
|
|
31087
|
+
* @param entries - A record of tag path → value pairs
|
|
31088
|
+
*/
|
|
31089
|
+
setBatch(entries) {
|
|
31090
|
+
return new _DicomInstance(this.dicomDataset, this.changeSet.setBatch(entries), this.filepath, this.meta);
|
|
31091
|
+
}
|
|
31092
|
+
/**
|
|
31093
|
+
* Returns a new DicomInstance with the given changes merged into pending changes.
|
|
30848
31094
|
*
|
|
30849
31095
|
* @param changes - A ChangeSet to merge with existing pending changes
|
|
30850
|
-
* @returns A new
|
|
31096
|
+
* @returns A new DicomInstance with accumulated changes
|
|
30851
31097
|
*/
|
|
30852
31098
|
withChanges(changes) {
|
|
30853
|
-
return new
|
|
31099
|
+
return new _DicomInstance(this.dicomDataset, this.changeSet.merge(changes), this.filepath, this.meta);
|
|
30854
31100
|
}
|
|
30855
31101
|
/**
|
|
30856
|
-
* Returns a new
|
|
31102
|
+
* Returns a new DicomInstance pointing to a different file path.
|
|
30857
31103
|
*
|
|
30858
|
-
* Preserves the dataset
|
|
31104
|
+
* Preserves the dataset, pending changes, and metadata.
|
|
30859
31105
|
*
|
|
30860
|
-
* @param newPath - The new
|
|
30861
|
-
* @returns A new
|
|
31106
|
+
* @param newPath - The new filesystem path (validated via createDicomFilePath)
|
|
31107
|
+
* @returns A new DicomInstance with the updated path
|
|
31108
|
+
* @throws If the path is invalid
|
|
30862
31109
|
*/
|
|
30863
31110
|
withFilePath(newPath) {
|
|
30864
|
-
|
|
31111
|
+
const result = createDicomFilePath(newPath);
|
|
31112
|
+
if (!result.ok) throw result.error;
|
|
31113
|
+
return new _DicomInstance(this.dicomDataset, this.changeSet, result.value, this.meta);
|
|
30865
31114
|
}
|
|
31115
|
+
// -----------------------------------------------------------------------
|
|
31116
|
+
// File I/O
|
|
31117
|
+
// -----------------------------------------------------------------------
|
|
30866
31118
|
/**
|
|
30867
|
-
* Applies pending changes to the file in-place
|
|
31119
|
+
* Applies pending changes to the file in-place.
|
|
30868
31120
|
*
|
|
30869
|
-
*
|
|
30870
|
-
* After applying, the dataset is NOT refreshed — call {@link DicomFile.open}
|
|
30871
|
-
* again if you need fresh data.
|
|
31121
|
+
* Requires that the instance has an associated file path.
|
|
30872
31122
|
*
|
|
30873
31123
|
* @param options - Timeout and abort options
|
|
30874
|
-
* @returns A Result indicating success or failure
|
|
30875
31124
|
*/
|
|
30876
31125
|
async applyChanges(options) {
|
|
30877
|
-
if (this.
|
|
30878
|
-
|
|
31126
|
+
if (this.filepath === void 0) return err(new Error("No file path associated with this instance"));
|
|
31127
|
+
if (this.changeSet.isEmpty) return ok(void 0);
|
|
31128
|
+
return applyModifications(this.filepath, this.changeSet, options ?? {});
|
|
30879
31129
|
}
|
|
30880
31130
|
/**
|
|
30881
31131
|
* Copies the file to a new path and applies pending changes to the copy.
|
|
30882
31132
|
*
|
|
30883
|
-
*
|
|
30884
|
-
* On dcmodify failure, the copy is cleaned up.
|
|
31133
|
+
* Returns a new DicomInstance pointing to the output path.
|
|
30885
31134
|
*
|
|
30886
31135
|
* @param outputPath - Destination filesystem path
|
|
30887
31136
|
* @param options - Timeout and abort options
|
|
30888
|
-
* @returns A Result containing the branded output path or an error
|
|
30889
31137
|
*/
|
|
30890
31138
|
async writeAs(outputPath, options) {
|
|
31139
|
+
if (this.filepath === void 0) return err(new Error("No file path associated with this instance"));
|
|
30891
31140
|
const outPathResult = createDicomFilePath(outputPath);
|
|
30892
31141
|
if (!outPathResult.ok) return err(outPathResult.error);
|
|
30893
|
-
const copyResult = await copyFileSafe(this.
|
|
31142
|
+
const copyResult = await copyFileSafe(this.filepath, outputPath);
|
|
30894
31143
|
if (!copyResult.ok) return err(copyResult.error);
|
|
30895
|
-
if (this.
|
|
30896
|
-
|
|
30897
|
-
|
|
30898
|
-
|
|
30899
|
-
|
|
31144
|
+
if (!this.changeSet.isEmpty) {
|
|
31145
|
+
const applyResult = await applyModifications(outPathResult.value, this.changeSet, options ?? {});
|
|
31146
|
+
if (!applyResult.ok) {
|
|
31147
|
+
await unlinkFile(outputPath);
|
|
31148
|
+
return err(applyResult.error);
|
|
31149
|
+
}
|
|
30900
31150
|
}
|
|
30901
|
-
return ok(outPathResult.value);
|
|
31151
|
+
return ok(new _DicomInstance(this.dicomDataset, ChangeSet.empty(), outPathResult.value, this.meta));
|
|
30902
31152
|
}
|
|
30903
31153
|
/**
|
|
30904
31154
|
* Gets the file size in bytes.
|
|
@@ -30906,15 +31156,43 @@ var DicomFile = class _DicomFile {
|
|
|
30906
31156
|
* @returns A Result containing the size or an error
|
|
30907
31157
|
*/
|
|
30908
31158
|
async fileSize() {
|
|
30909
|
-
|
|
31159
|
+
if (this.filepath === void 0) return err(new Error("No file path associated with this instance"));
|
|
31160
|
+
return statFileSize(this.filepath);
|
|
30910
31161
|
}
|
|
30911
31162
|
/**
|
|
30912
|
-
* Deletes the file from the filesystem.
|
|
31163
|
+
* Deletes the associated file from the filesystem.
|
|
30913
31164
|
*
|
|
30914
31165
|
* @returns A Result indicating success or failure
|
|
30915
31166
|
*/
|
|
30916
31167
|
async unlink() {
|
|
30917
|
-
|
|
31168
|
+
if (this.filepath === void 0) return err(new Error("No file path associated with this instance"));
|
|
31169
|
+
return unlinkFile(this.filepath);
|
|
31170
|
+
}
|
|
31171
|
+
// -----------------------------------------------------------------------
|
|
31172
|
+
// Metadata (non-DICOM app context)
|
|
31173
|
+
// -----------------------------------------------------------------------
|
|
31174
|
+
/**
|
|
31175
|
+
* Returns a new DicomInstance with application metadata attached.
|
|
31176
|
+
*
|
|
31177
|
+
* Metadata is not stored in the DICOM file — it's for application context
|
|
31178
|
+
* (e.g. tracking source association, processing status, etc.).
|
|
31179
|
+
*
|
|
31180
|
+
* @param key - Metadata key
|
|
31181
|
+
* @param value - Metadata value
|
|
31182
|
+
*/
|
|
31183
|
+
withMetadata(key, value) {
|
|
31184
|
+
const newMeta = new Map(this.meta);
|
|
31185
|
+
newMeta.set(key, value);
|
|
31186
|
+
return new _DicomInstance(this.dicomDataset, this.changeSet, this.filepath, newMeta);
|
|
31187
|
+
}
|
|
31188
|
+
/**
|
|
31189
|
+
* Gets application metadata by key.
|
|
31190
|
+
*
|
|
31191
|
+
* @param key - Metadata key
|
|
31192
|
+
* @returns The metadata value or undefined
|
|
31193
|
+
*/
|
|
31194
|
+
getMetadata(key) {
|
|
31195
|
+
return this.meta.get(key);
|
|
30918
31196
|
}
|
|
30919
31197
|
};
|
|
30920
31198
|
|
|
@@ -31034,7 +31312,7 @@ function sopClassNameFromUID(uid) {
|
|
|
31034
31312
|
|
|
31035
31313
|
exports.ChangeSet = ChangeSet;
|
|
31036
31314
|
exports.DicomDataset = DicomDataset;
|
|
31037
|
-
exports.
|
|
31315
|
+
exports.DicomInstance = DicomInstance;
|
|
31038
31316
|
exports.SOP_CLASSES = SOP_CLASSES;
|
|
31039
31317
|
exports.VR = VR;
|
|
31040
31318
|
exports.VR_CATEGORY = VR_CATEGORY;
|