@hiraokahypertools/pst-extractor 0.1.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 (90) hide show
  1. package/dist/BTHeap.d.ts +15 -0
  2. package/dist/BTHeap.js +76 -0
  3. package/dist/CollectionAsyncProvider.d.ts +15 -0
  4. package/dist/CollectionAsyncProvider.js +44 -0
  5. package/dist/KeyedDelay.d.ts +8 -0
  6. package/dist/KeyedDelay.js +37 -0
  7. package/dist/LZFu.class.d.ts +12 -0
  8. package/dist/LZFu.class.js +95 -0
  9. package/dist/NodeMap.class.d.ts +35 -0
  10. package/dist/NodeMap.class.js +86 -0
  11. package/dist/OutlookProperties.d.ts +278 -0
  12. package/dist/OutlookProperties.js +284 -0
  13. package/dist/PAUtil.d.ts +17 -0
  14. package/dist/PAUtil.js +145 -0
  15. package/dist/PHNodeHeap.d.ts +16 -0
  16. package/dist/PHNodeHeap.js +2 -0
  17. package/dist/PHNodeHeapReader.d.ts +6 -0
  18. package/dist/PHNodeHeapReader.js +5 -0
  19. package/dist/PHUtil.d.ts +6 -0
  20. package/dist/PHUtil.js +103 -0
  21. package/dist/PLMisc.d.ts +8 -0
  22. package/dist/PLMisc.js +16 -0
  23. package/dist/PLNode.d.ts +11 -0
  24. package/dist/PLNode.js +5 -0
  25. package/dist/PLStore.d.ts +9 -0
  26. package/dist/PLStore.js +5 -0
  27. package/dist/PLSubNode.d.ts +8 -0
  28. package/dist/PLSubNode.js +5 -0
  29. package/dist/PLUtil.d.ts +29 -0
  30. package/dist/PLUtil.js +683 -0
  31. package/dist/PSTActivity.class.d.ts +103 -0
  32. package/dist/PSTActivity.class.js +144 -0
  33. package/dist/PSTAppointment.class.d.ts +275 -0
  34. package/dist/PSTAppointment.class.js +381 -0
  35. package/dist/PSTAttachment.class.d.ts +168 -0
  36. package/dist/PSTAttachment.class.js +286 -0
  37. package/dist/PSTContact.class.d.ts +900 -0
  38. package/dist/PSTContact.class.js +1253 -0
  39. package/dist/PSTFile.class.d.ts +144 -0
  40. package/dist/PSTFile.class.js +221 -0
  41. package/dist/PSTFolder.class.d.ts +111 -0
  42. package/dist/PSTFolder.class.js +269 -0
  43. package/dist/PSTMessage.class.d.ts +773 -0
  44. package/dist/PSTMessage.class.js +1264 -0
  45. package/dist/PSTMessageStore.class.d.ts +16 -0
  46. package/dist/PSTMessageStore.class.js +18 -0
  47. package/dist/PSTObject.class.d.ts +107 -0
  48. package/dist/PSTObject.class.js +208 -0
  49. package/dist/PSTOpts.d.ts +24 -0
  50. package/dist/PSTOpts.js +2 -0
  51. package/dist/PSTRecipient.class.d.ts +68 -0
  52. package/dist/PSTRecipient.class.js +105 -0
  53. package/dist/PSTTask.class.d.ts +146 -0
  54. package/dist/PSTTask.class.js +206 -0
  55. package/dist/PSTUtil.class.d.ts +134 -0
  56. package/dist/PSTUtil.class.js +804 -0
  57. package/dist/Property.d.ts +38 -0
  58. package/dist/Property.js +2 -0
  59. package/dist/PropertyContext.d.ts +6 -0
  60. package/dist/PropertyContext.js +2 -0
  61. package/dist/PropertyContextUtil.d.ts +4 -0
  62. package/dist/PropertyContextUtil.js +77 -0
  63. package/dist/PropertyTypeObject.d.ts +12 -0
  64. package/dist/PropertyTypeObject.js +21 -0
  65. package/dist/PropertyValueResolver.d.ts +4 -0
  66. package/dist/PropertyValueResolver.js +2 -0
  67. package/dist/PropertyValueResolverV1.d.ts +7 -0
  68. package/dist/PropertyValueResolverV1.js +253 -0
  69. package/dist/RawProperty.d.ts +8 -0
  70. package/dist/RawProperty.js +2 -0
  71. package/dist/RecurrencePattern.class.d.ts +50 -0
  72. package/dist/RecurrencePattern.class.js +120 -0
  73. package/dist/RootProvider.d.ts +12 -0
  74. package/dist/RootProvider.js +2 -0
  75. package/dist/SingleAsyncProvider.d.ts +5 -0
  76. package/dist/SingleAsyncProvider.js +30 -0
  77. package/dist/TableContext.d.ts +4 -0
  78. package/dist/TableContext.js +2 -0
  79. package/dist/TableContextUtil.d.ts +4 -0
  80. package/dist/TableContextUtil.js +147 -0
  81. package/dist/TableRow.d.ts +6 -0
  82. package/dist/TableRow.js +2 -0
  83. package/dist/index.d.ts +15 -0
  84. package/dist/index.js +28 -0
  85. package/dist/msftUuidStringify.d.ts +17 -0
  86. package/dist/msftUuidStringify.js +48 -0
  87. package/dist/openPstFile.d.ts +19 -0
  88. package/dist/openPstFile.js +67 -0
  89. package/package.json +105 -0
  90. package/readme.md +16 -0
package/dist/PAUtil.js ADDED
@@ -0,0 +1,145 @@
1
+ "use strict";
2
+ /**
3
+ * PST adapter utilities
4
+ */
5
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
6
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
7
+ return new (P || (P = Promise))(function (resolve, reject) {
8
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
9
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
10
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
11
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
12
+ });
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.createPropertyFinder = exports.processNameToIDMap = void 0;
16
+ const msftUuidStringify_1 = require("./msftUuidStringify");
17
+ const NodeMap_class_1 = require("./NodeMap.class");
18
+ const PHUtil_1 = require("./PHUtil");
19
+ const PropertyContextUtil_1 = require("./PropertyContextUtil");
20
+ const PSTUtil_class_1 = require("./PSTUtil.class");
21
+ const guidMap = new Map([
22
+ ['00020329-0000-0000-C000-000000000046', 0],
23
+ ['00062008-0000-0000-C000-000000000046', 1],
24
+ ['00062004-0000-0000-C000-000000000046', 2],
25
+ ['00020386-0000-0000-C000-000000000046', 3],
26
+ ['00062002-0000-0000-C000-000000000046', 4],
27
+ ['6ED8DA90-450B-101B-98DA-00AA003F1305', 5],
28
+ ['0006200A-0000-0000-C000-000000000046', 6],
29
+ ['41F28F13-83F4-4114-A584-EEDB5A6B0BFF', 7],
30
+ ['0006200E-0000-0000-C000-000000000046', 8],
31
+ ['00062041-0000-0000-C000-000000000046', 9],
32
+ ['00062003-0000-0000-C000-000000000046', 10],
33
+ ['4442858E-A9E3-4E80-B900-317A210CC15B', 11],
34
+ ['00020328-0000-0000-C000-000000000046', 12],
35
+ ['71035549-0739-4DCB-9163-00F0580DBBDF', 13],
36
+ ['00062040-0000-0000-C000-000000000046', 14],
37
+ ]);
38
+ /**
39
+ * Process name to ID map.
40
+ *
41
+ * @param nameToIdMapDescriptorNode nodeId 97
42
+ */
43
+ function processNameToIDMap(nameToIdMapDescriptorNode, resolver) {
44
+ return __awaiter(this, void 0, void 0, function* () {
45
+ const subNode = nameToIdMapDescriptorNode.getSubNode();
46
+ const bcTable = (yield (yield (0, PropertyContextUtil_1.getPropertyContext)(yield (0, PHUtil_1.getHeapFrom)(subNode), resolver))
47
+ .list());
48
+ function getTableItem(key) {
49
+ return __awaiter(this, void 0, void 0, function* () {
50
+ const found = bcTable.find(it => it.key === key);
51
+ if (found === undefined) {
52
+ throw new Error(`processNameToIDMap key:${key} is null`);
53
+ }
54
+ const { value } = found;
55
+ if (value instanceof ArrayBuffer) {
56
+ return value;
57
+ }
58
+ return undefined;
59
+ });
60
+ }
61
+ // process the map
62
+ // Get the guids
63
+ const guidEntry = yield getTableItem(2);
64
+ if (!guidEntry) {
65
+ throw new Error('PSTFile::processNameToIDMap guidEntry is null');
66
+ }
67
+ const guids = new Uint8Array(guidEntry);
68
+ const nGuids = Math.trunc(guids.byteLength / 16);
69
+ const guidIndexes = [];
70
+ let offset = 0;
71
+ for (let i = 0; i < nGuids; ++i) {
72
+ const strUID = (0, msftUuidStringify_1.msftUuidStringify)(guids, offset).toUpperCase();
73
+ const guid = guidMap.get(strUID);
74
+ if (guid) {
75
+ guidIndexes[i] = guid;
76
+ }
77
+ else {
78
+ guidIndexes[i] = -1; // We don't know this guid
79
+ }
80
+ // console.log('PSTFile:: processNameToIdMap idx: ' + i + ', ' + strUID + ', ' + guidIndexes[i]);
81
+ offset += 16;
82
+ }
83
+ // if we have a reference to an internal descriptor
84
+ const mapEntries = yield getTableItem(3);
85
+ if (!mapEntries) {
86
+ throw new Error('PSTFile::processNameToIDMap mapEntries is null');
87
+ }
88
+ const nameToIdByte = new Uint8Array(mapEntries);
89
+ const nameToIdByteView = new DataView(mapEntries);
90
+ const stringMapEntries = yield getTableItem(4);
91
+ if (!stringMapEntries) {
92
+ throw new Error('PSTFile::processNameToIDMap stringMapEntries is null');
93
+ }
94
+ const stringNameToIdByte = new Uint8Array(stringMapEntries);
95
+ const stringNameToIdByteView = new DataView(stringMapEntries);
96
+ const stringNameToIdByteBuffer = Buffer.from(stringMapEntries);
97
+ const nodeMap = new NodeMap_class_1.NodeMap();
98
+ // process the entries
99
+ for (let x = 0; x + 8 < nameToIdByte.length; x += 8) {
100
+ const key = nameToIdByteView.getUint32(x, true);
101
+ let guid = nameToIdByteView.getUint16(x + 4, true);
102
+ let propId = nameToIdByteView.getUint16(x + 6, true);
103
+ if (key == 0x55555555) {
104
+ break;
105
+ }
106
+ const PS_PUBLIC_STRINGS = 0;
107
+ const PS_MAPI = 12;
108
+ if ((guid & 0x0001) == 0) {
109
+ // identifier is numeric
110
+ propId += 0x8000;
111
+ guid >>= 1;
112
+ let guidIndex;
113
+ if (guid == 1) {
114
+ guidIndex = PS_MAPI;
115
+ }
116
+ else if (guid == 2) {
117
+ guidIndex = PS_PUBLIC_STRINGS;
118
+ }
119
+ else {
120
+ guidIndex = guidIndexes[guid - 3];
121
+ }
122
+ nodeMap.setId(key, propId, guidIndex);
123
+ }
124
+ else {
125
+ // identifier is a string
126
+ // key is byte offset into the String stream in which the string name of the property is stored.
127
+ const len = stringNameToIdByteView.getUint32(key, true);
128
+ const keyByteValue = Buffer.alloc(len);
129
+ PSTUtil_class_1.PSTUtil.arraycopy(stringNameToIdByteBuffer, key + 4, keyByteValue, 0, keyByteValue.length);
130
+ propId += 0x8000;
131
+ nodeMap.setId(keyByteValue.toString('utf16le').replace(/\0/g, ''), propId);
132
+ }
133
+ }
134
+ return nodeMap;
135
+ });
136
+ }
137
+ exports.processNameToIDMap = processNameToIDMap;
138
+ function createPropertyFinder(props) {
139
+ return {
140
+ findByKey(key) {
141
+ return props.find(it => it.key === key);
142
+ },
143
+ };
144
+ }
145
+ exports.createPropertyFinder = createPropertyFinder;
@@ -0,0 +1,16 @@
1
+ import { PHNodeHeapReader } from "./PHNodeHeapReader";
2
+ export interface PHNodeHeap {
3
+ /**
4
+ * bType
5
+ *
6
+ * Set to `0` if heap structure doesn't exist, in case of loading absent subNode
7
+ */
8
+ bClientSig: number;
9
+ /**
10
+ * hnid
11
+ *
12
+ * Set to `0` if heap structure doesn't exist, in case of loading absent subNode
13
+ */
14
+ userRootHnid: number;
15
+ getReader(): PHNodeHeapReader;
16
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,6 @@
1
+ /**
2
+ * PST high level node heap reader
3
+ */
4
+ export interface PHNodeHeapReader {
5
+ getHeapBuffers(hnid: number): Promise<ArrayBuffer[]>;
6
+ }
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ /**
3
+ * PST high level node heap reader
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,6 @@
1
+ /**
2
+ * PST higher level utilities
3
+ */
4
+ import { PHNodeHeap } from "./PHNodeHeap";
5
+ import { PLSubNode } from "./PLSubNode";
6
+ export declare function getHeapFrom(node: PLSubNode): Promise<PHNodeHeap>;
package/dist/PHUtil.js ADDED
@@ -0,0 +1,103 @@
1
+ "use strict";
2
+ /**
3
+ * PST higher level utilities
4
+ */
5
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
6
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
7
+ return new (P || (P = Promise))(function (resolve, reject) {
8
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
9
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
10
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
11
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
12
+ });
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.getHeapFrom = void 0;
16
+ function getHeapFrom(node) {
17
+ return __awaiter(this, void 0, void 0, function* () {
18
+ const data_array = yield node.getData();
19
+ const data_chunks = new Map();
20
+ let bClientSig = 0;
21
+ let userRootHnid = 0;
22
+ for (let x = 0; x < data_array.length; x++) {
23
+ if (x === 0) {
24
+ ({ bClientSig, userRoot: userRootHnid } = load_root_header(data_chunks, data_array[x]));
25
+ }
26
+ else {
27
+ load_page_header(data_chunks, data_array[x], x);
28
+ }
29
+ }
30
+ return {
31
+ bClientSig,
32
+ userRootHnid,
33
+ toString() {
34
+ return `${node}`;
35
+ },
36
+ getReader() {
37
+ return {
38
+ getHeapBuffers(hnid) {
39
+ return __awaiter(this, void 0, void 0, function* () {
40
+ if (hnid === 0) {
41
+ return [];
42
+ }
43
+ else if (hnid & 0x1f) {
44
+ // this is NID (node)
45
+ const childNode = yield node.getChildBy(hnid);
46
+ if (childNode === undefined) {
47
+ throw new Error(`childNode=0x${hnid.toString(16)} of ${node} not found`);
48
+ }
49
+ const data_array = yield childNode.getData();
50
+ return data_array;
51
+ }
52
+ else {
53
+ // this is HID (heap)
54
+ const data = data_chunks.get(hnid);
55
+ if (data === undefined) {
56
+ throw new Error(`heap=0x${hnid.toString(16)} of ${node} not found`);
57
+ }
58
+ return [data];
59
+ }
60
+ });
61
+ },
62
+ toString() {
63
+ return `reader of ${node}`;
64
+ },
65
+ };
66
+ },
67
+ };
68
+ });
69
+ }
70
+ exports.getHeapFrom = getHeapFrom;
71
+ /**
72
+ * Parse HNHDR
73
+ *
74
+ * @see https://docs.microsoft.com/en-us/openspecs/office_file_formats/ms-pst/8e4ae05c-3c24-4103-b7e5-ffef6f244834
75
+ */
76
+ function load_root_header(data_chunks, data) {
77
+ const view = new DataView(data);
78
+ const page_map = view.getUint16(0, true);
79
+ const sig = view.getUint8(2);
80
+ const bClientSig = view.getUint8(3);
81
+ const userRoot = view.getUint32(4, true);
82
+ if (sig !== 0xec) {
83
+ throw new Error("invalid HNHDR signature found");
84
+ }
85
+ // read HNPAGEMAP
86
+ const offsets_count = view.getUint16(page_map, true) + 1;
87
+ for (let x = 0; x < offsets_count - 1; x++) {
88
+ const from = view.getUint16(page_map + 4 + 2 * (x), true);
89
+ const to = view.getUint16(page_map + 4 + 2 * (x + 1), true);
90
+ data_chunks.set(0x20 * (1 + x), data.slice(from, to));
91
+ }
92
+ return { bClientSig, userRoot };
93
+ }
94
+ function load_page_header(data_chunks, data, page_index) {
95
+ const view = new DataView(data);
96
+ const page_map = view.getUint16(0, true);
97
+ const offsets_count = view.getUint16(page_map, true) + 1;
98
+ for (let x = 0; x < offsets_count - 1; x++) {
99
+ const from = view.getUint16(page_map + 4 + 2 * (x), true);
100
+ const to = view.getUint16(page_map + 4 + 2 * (x + 1), true);
101
+ data_chunks.set(0x20 * (1 + x) + 65536 * page_index, data.slice(from, to));
102
+ }
103
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * PST lower level misc utilities
3
+ */
4
+ /**
5
+ *
6
+ * @internal
7
+ */
8
+ export declare function splitPer(array: ArrayBuffer, per: number): Generator<ArrayBuffer>;
package/dist/PLMisc.js ADDED
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ /**
3
+ * PST lower level misc utilities
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.splitPer = void 0;
7
+ /**
8
+ *
9
+ * @internal
10
+ */
11
+ function* splitPer(array, per) {
12
+ for (let offset = 0; offset < array.byteLength; offset += per) {
13
+ yield array.slice(offset, offset + per);
14
+ }
15
+ }
16
+ exports.splitPer = splitPer;
@@ -0,0 +1,11 @@
1
+ /**
2
+ * PST lower level node
3
+ */
4
+ import { PLSubNode } from "./PLSubNode";
5
+ export interface PLNode {
6
+ nodeId: number;
7
+ getParent(): PLNode | undefined;
8
+ getChildren(): PLNode[];
9
+ getSubNode(): PLSubNode;
10
+ getSiblingNode(nidType: number): PLNode | undefined;
11
+ }
package/dist/PLNode.js ADDED
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ /**
3
+ * PST lower level node
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,9 @@
1
+ /**
2
+ * PST lower level store
3
+ */
4
+ import { PLNode } from "./PLNode";
5
+ export interface PLStore {
6
+ getOneNodeBy(nodeId: number): PLNode | undefined;
7
+ getOneNodeByOrError(nodeId: number): PLNode;
8
+ close(): void;
9
+ }
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ /**
3
+ * PST lower level store
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,8 @@
1
+ /**
2
+ * PST lower level node reader
3
+ */
4
+ export interface PLSubNode {
5
+ nodeId: number;
6
+ getChildBy(childNodeId: number): Promise<PLSubNode | undefined>;
7
+ getData(): Promise<ArrayBuffer[]>;
8
+ }
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ /**
3
+ * PST lower level node reader
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,29 @@
1
+ /**
2
+ * PST lower level utilities
3
+ */
4
+ import Long from "long";
5
+ import { PLStore } from "./PLStore";
6
+ export declare type ReadFile = (buffer: ArrayBuffer, offset: number, length: number, position: number) => Promise<number>;
7
+ export declare type Close = () => Promise<void>;
8
+ /**
9
+ * Defines a callback based async file operation API.
10
+ */
11
+ export interface ReadFileApi {
12
+ /**
13
+ * Defines read API like `fs.promises.readFile`.
14
+ */
15
+ readFile: ReadFile;
16
+ /**
17
+ * Defines close API like `fs.promises.close`.
18
+ */
19
+ close: Close;
20
+ }
21
+ /**
22
+ * @internal
23
+ */
24
+ export declare function readNumber64(view: DataView, offset: number): number;
25
+ /**
26
+ * @internal
27
+ */
28
+ export declare function readLong(view: DataView, offset: number): Long;
29
+ export declare function openLowPst(api: ReadFileApi): Promise<PLStore>;