edfcore 0.3.97 → 0.3.99

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/CHANGELOG.md CHANGED
@@ -6,6 +6,36 @@ alone does not tell you whether you were affected.
6
6
  edfcore is pre-1.0. Patch releases have carried behaviour changes where the old behaviour was a
7
7
  defect; those are called out below.
8
8
 
9
+ ## 0.3.99
10
+
11
+ - **Fixed** the CLI usage banner scoping `--patient` to "(header, json)". `redaction(args)` is
12
+ applied by `validate` too, so the flag un-redacts patient identification there as well: without it
13
+ a `PATIENT_ID_NONCONFORMANT` diagnostic renders the field as `[redacted]`, with it the full name.
14
+ - The flag exists so that the default output of a command someone pipes somewhere carries no
15
+ patient name. A banner that under-states which commands it governs is the wrong direction to be
16
+ wrong in: a reader gating on "validate doesn't print names anyway" is gating on nothing.
17
+ - `api-helpers.md` carried the same pair and now names all three.
18
+ - The test DERIVES the scope: it runs every subcommand with and without the flag over one
19
+ non-conformant file, collects the ones whose output changes, and requires the banner line to list
20
+ exactly those. It first asserts more than one command is affected, so it cannot pass on a file
21
+ where the flag does nothing.
22
+
23
+ ## 0.3.98
24
+
25
+ - **Fixed** `fileSource` carrying, as advice, a check it never performed. Its size refusal ended
26
+ "Next: check that the path names a regular file rather than a directory, a pipe or a device", and
27
+ none of the three can reach that branch.
28
+ - The branch fires only on `!Number.isSafeInteger(size) || size < 0`. A directory's `st_size` is
29
+ its allocation — 64 on macOS — and a FIFO's and a character device's is 0. All ordinary safe
30
+ integers, so the guard never fired for any of the causes it told you to check.
31
+ - `fileSource(dir)` therefore returned a working-looking `ByteSource` with `byteLength: 64`, and
32
+ the failure arrived on the first read as a raw `EISDIR` from Node — an error edfcore never
33
+ shaped, past the point where the caller could still act on it.
34
+ - It is now an actual check, before the size guard, using the `isFile()` the same `stat()` already
35
+ returns. The size guard's own "Next:" no longer points at causes it cannot be about.
36
+ - No new syscall: `fs.open` already returns the handle whose `stat()` was being called two lines
37
+ later; only the declared shape of the shim widened.
38
+
9
39
  ## 0.3.97
10
40
 
11
41
  - **Fixed** `httpSource()` issuing its size probe after the caller cancelled, and resolving a live
package/dist/cli-run.js CHANGED
@@ -47,7 +47,7 @@ const USAGE = `edfcore — read EDF, EDF+, BDF and BDF+ files
47
47
 
48
48
  Options
49
49
  --help, -h print this and exit 0
50
- --patient include patient identification (header, json)
50
+ --patient include patient identification (header, validate, json)
51
51
  --list list events one per line instead of counting (events)
52
52
  --limit <n> individual diagnostics or events to print (default 20)
53
53
 
@@ -109,5 +109,5 @@ export declare const SIGNAL_FIELD_BLOCK_OFFSETS: {
109
109
  readonly reserved: 224;
110
110
  };
111
111
  /** Published package version. Kept in sync with package.json by a test. */
112
- export declare const VERSION = "0.3.97";
112
+ export declare const VERSION = "0.3.99";
113
113
  //# sourceMappingURL=constants.d.ts.map
package/dist/constants.js CHANGED
@@ -79,5 +79,5 @@ export const SIGNAL_FIELD_BLOCK_OFFSETS = {
79
79
  reserved: 224,
80
80
  };
81
81
  /** Published package version. Kept in sync with package.json by a test. */
82
- export const VERSION = '0.3.97';
82
+ export const VERSION = '0.3.99';
83
83
  //# sourceMappingURL=constants.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAOH,OAAO,KAAK,EAAE,UAAU,EAAe,MAAM,YAAY,CAAC;AAE1D;;;;;;GAMG;AACH,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE1D;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,CACF,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAClC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAYD;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,GAAG,UAAU,CAqDvF;AAED;;;;;;;;;GASG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAqBlE"}
1
+ {"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAOH,OAAO,KAAK,EAAE,UAAU,EAAe,MAAM,YAAY,CAAC;AAE1D;;;;;;GAMG;AACH,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE1D;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,IAAI,CACF,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAClC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAYD;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,GAAG,UAAU,CAqDvF;AAED;;;;;;;;;GASG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAuClE"}
package/dist/node.js CHANGED
@@ -121,10 +121,25 @@ export async function fileSource(path) {
121
121
  try {
122
122
  const stats = await handle.stat();
123
123
  const byteLength = stats.size;
124
+ /*
125
+ * The regular-file check is a CHECK, not advice.
126
+ *
127
+ * The size guard below used to carry it as a "Next:" — "check that the path names a regular
128
+ * file rather than a directory, a pipe or a device" — and none of the three can reach it. A
129
+ * directory's `st_size` is its allocation (64 on macOS) and a FIFO's and a character device's
130
+ * is 0: all ordinary safe integers. So `fileSource(dir)` returned a working-looking
131
+ * `ByteSource` with `byteLength: 64`, and the first read failed with a raw `EISDIR` from Node
132
+ * rather than with anything edfcore said (fixed in 0.3.98).
133
+ */
134
+ if (!stats.isFile()) {
135
+ throw new EdfSourceError(`fileSource(): ${JSON.stringify(path)} is not a regular file. A directory, a pipe and a ` +
136
+ 'device all report a size the operating system will not let edfcore read from, so the ' +
137
+ 'first read would fail with a raw errno instead. Next: name the file itself.', { offset: 0, requestedLength: 0 });
138
+ }
124
139
  if (!Number.isSafeInteger(byteLength) || byteLength < 0) {
125
140
  throw new EdfSourceError(`fileSource(): the operating system reported a size of ${byteLength} bytes for ` +
126
- `${JSON.stringify(path)}, which is not a byte count edfcore can address. Next: check ` +
127
- 'that the path names a regular file rather than a directory, a pipe or a device.', { offset: 0, requestedLength: 0 });
141
+ `${JSON.stringify(path)}, which is not a byte count edfcore can address. Next: this is a ` +
142
+ 'regular file, so the size is the surprise check the filesystem.', { offset: 0, requestedLength: 0 });
128
143
  }
129
144
  return fileHandleSource(handle, byteLength);
130
145
  }
package/dist/node.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"node.js","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"node.js","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "edfcore",
3
- "version": "0.3.97",
3
+ "version": "0.3.99",
4
4
  "description": "Modern, typed, zero-dependency reader for EDF, EDF+, BDF and BDF+ biosignal files. Works in browsers and Node with true random access.",
5
5
  "keywords": [
6
6
  "edf",
package/src/cli-run.ts CHANGED
@@ -58,7 +58,7 @@ const USAGE = `edfcore — read EDF, EDF+, BDF and BDF+ files
58
58
 
59
59
  Options
60
60
  --help, -h print this and exit 0
61
- --patient include patient identification (header, json)
61
+ --patient include patient identification (header, validate, json)
62
62
  --list list events one per line instead of counting (events)
63
63
  --limit <n> individual diagnostics or events to print (default 20)
64
64
 
package/src/constants.ts CHANGED
@@ -93,4 +93,4 @@ export const SIGNAL_FIELD_BLOCK_OFFSETS = {
93
93
  } as const;
94
94
 
95
95
  /** Published package version. Kept in sync with package.json by a test. */
96
- export const VERSION = '0.3.97';
96
+ export const VERSION = '0.3.99';
package/src/node.ts CHANGED
@@ -74,7 +74,7 @@ interface NodeFsPromises {
74
74
  open(
75
75
  path: string,
76
76
  flags: string,
77
- ): Promise<FileHandleLike & { stat(): Promise<{ size: number }> }>;
77
+ ): Promise<FileHandleLike & { stat(): Promise<{ size: number; isFile(): boolean }> }>;
78
78
  }
79
79
 
80
80
  const fs: NodeFsPromises = nodeFsPromises as unknown as NodeFsPromises;
@@ -161,11 +161,29 @@ export async function fileSource(path: string): Promise<ByteSource> {
161
161
  try {
162
162
  const stats = await handle.stat();
163
163
  const byteLength = stats.size;
164
+ /*
165
+ * The regular-file check is a CHECK, not advice.
166
+ *
167
+ * The size guard below used to carry it as a "Next:" — "check that the path names a regular
168
+ * file rather than a directory, a pipe or a device" — and none of the three can reach it. A
169
+ * directory's `st_size` is its allocation (64 on macOS) and a FIFO's and a character device's
170
+ * is 0: all ordinary safe integers. So `fileSource(dir)` returned a working-looking
171
+ * `ByteSource` with `byteLength: 64`, and the first read failed with a raw `EISDIR` from Node
172
+ * rather than with anything edfcore said (fixed in 0.3.98).
173
+ */
174
+ if (!stats.isFile()) {
175
+ throw new EdfSourceError(
176
+ `fileSource(): ${JSON.stringify(path)} is not a regular file. A directory, a pipe and a ` +
177
+ 'device all report a size the operating system will not let edfcore read from, so the ' +
178
+ 'first read would fail with a raw errno instead. Next: name the file itself.',
179
+ { offset: 0, requestedLength: 0 },
180
+ );
181
+ }
164
182
  if (!Number.isSafeInteger(byteLength) || byteLength < 0) {
165
183
  throw new EdfSourceError(
166
184
  `fileSource(): the operating system reported a size of ${byteLength} bytes for ` +
167
- `${JSON.stringify(path)}, which is not a byte count edfcore can address. Next: check ` +
168
- 'that the path names a regular file rather than a directory, a pipe or a device.',
185
+ `${JSON.stringify(path)}, which is not a byte count edfcore can address. Next: this is a ` +
186
+ 'regular file, so the size is the surprise check the filesystem.',
169
187
  { offset: 0, requestedLength: 0 },
170
188
  );
171
189
  }