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