@msout/microsoft-onenote-exporter 0.1.2 → 0.1.4

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,91 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [0.1.4] - 2026-10-02
10
+
11
+ A **patch**. Three of the five subcommands could not run through
12
+ `start-container.sh` at all, and only `export` had ever been tried.
13
+
14
+ ### Fixed
15
+
16
+ - **`list`, `check` and `logout` were rejected when given no flags**, by a
17
+ `$# -eq 0` guard written for `export` and applied to all five subcommands. Those
18
+ three steps need no arguments; the extra guard is gone and the export-specific
19
+ one is now the only one. Closes #3.
20
+
21
+ - **`logout` cannot be done in a container, and now does not try.** Mounting the
22
+ session read-write and letting the container delete it cannot work: Docker
23
+ mounts a single file at `/data/auth/session.json`, and a container cannot remove
24
+ a mount point, so unlinking it failed with `EACCES` whether the mount was
25
+ read-only or not. Deleting a session is a host-side operation, so the wrapper
26
+ removes the file and its `-meta.json` itself, before an image is even required.
27
+ The session stays mounted read-only for every other step, so a bug in the
28
+ container still cannot destroy it.
29
+
30
+ - **`--auth-file` is no longer silently ignored.** The wrapper picks the session
31
+ itself and passes its own `--auth-file` to the container, so a caller's
32
+ `--auth-file ./my.json` was neither honoured nor rejected — the wrong session
33
+ was used and the run succeeded against it. It is now the highest-precedence
34
+ source, verified with a decoy `output/auth.json` left in place.
35
+
36
+ - **Failure messages name the subcommand.** A failed `logout` reported "the export
37
+ failed and produced nothing usable" and pointed at notes that were never the
38
+ point of the command.
39
+
40
+ Tests: 132 → 137. Five of them fail against 0.1.3, and two assert source *position*
41
+ rather than text, because assertions in this file had already passed against
42
+ broken versions twice: one checked only that a guard existed rather than that it
43
+ was scoped to `export`, and another matched a path that a comment matched first.
44
+
45
+ Verified against a real account, all four through the wrapper: `list` exits 0 with
46
+ 12 notebooks, `check` exits 0 reporting Authenticated, `logout` removes the session
47
+ and its metadata with no image needed, and `export` still produces 19 notes.
48
+
49
+ ## [0.1.3] - 2026-10-02 - 2026-10-02
50
+
51
+ A **patch**, and the first release driven by the automation added in the previous
52
+ one rather than by remembering to check.
53
+
54
+ ### Changed
55
+
56
+ - **`@msout/microsoft-onenote-list-notebooks` 0.0.6 → 0.0.7.** Pin bumped and the
57
+ lockfile regenerated, so it now resolves that version from the registry rather
58
+ than the previous tarball.
59
+
60
+ The contract this adapter depends on is unchanged — `listNotebooks(options)`
61
+ still returns `Array<{name, url, id}>`, and the module still exports
62
+ `listNotebooks` and `dismissMcasInterstitial` — so no code here changed.
63
+
64
+ What 0.0.7 brings, from its own release: real notebook URLs are resolved instead
65
+ of the MRU placeholder, and links are read from the MRU feed in canonical form.
66
+ That matters here because `list` prints `nb.url`, so the URLs this tool reports
67
+ are now the ones that can actually be opened.
68
+
69
+ 0.0.6 was still pinned when this was written, which is what the `stale-steps`
70
+ CI job reported on its first run and what Dependabot has a grouped PR open for.
71
+
72
+ ### Fixed
73
+
74
+ - **`entrypoint.sh` offered `--output-dir` to every subcommand.** `list`, `check`
75
+ and `logout` do not define that option, so all three died with
76
+ `error: unknown option '--output-dir'` and exit 1 — the container refused to list
77
+ anything, while the flag commander rejected had been added by the entrypoint
78
+ itself. `export` kept working, and it was the only subcommand anyone had run
79
+ through a container. Now gated on the subcommand actually being `export`.
80
+
81
+ Two tests, both of which fail against the previous entrypoint: one asserts the
82
+ injection sits *inside* the export gate by comparing source positions, because
83
+ the earlier assertion checked only that the injection existed and not which
84
+ subcommands it applied to — which is exactly why it passed against the broken
85
+ version. The other pins the subcommand match by name.
86
+
87
+ - Related: **issue #3** — `start-container.sh` still refuses `list`, `check` and
88
+ `logout` when given no flags, from a `$# -eq 0` guard written for `export` and
89
+ applied to all five subcommands. Tracked, not yet fixed; both it and the
90
+ entrypoint bug have to be resolved before `list` works through the wrapper.
91
+
92
+ Tests: 130 → 132.
93
+
9
94
  ## [0.1.2] - 2026-10-02
10
95
 
11
96
  A **patch**. It changes what is published, not what the package does.
package/entrypoint.sh CHANGED
@@ -72,19 +72,40 @@ if [ ! -d /data/output ]; then
72
72
  echo " when it exits. Mount one, for example:" >&2
73
73
  echo " -v \"\$PWD/output:/data/output\"" >&2
74
74
  else
75
- # Appending --output-dir rather than exporting a variable, because the CLI has
76
- # no environment variable for it and its default resolves against a cwd of
77
- # /app. Only when the caller did not pass one, for the same reason as
78
- # --auth-file below: an explicit choice must never be overridden.
79
- has_output_dir=false
75
+ # Only `export` writes notes, so only `export` is offered --output-dir.
76
+ #
77
+ # Appending it for every subcommand broke the other three: `list`, `check` and
78
+ # `logout` do not define that option, so commander answered
79
+ #
80
+ # error: unknown option '--output-dir'
81
+ #
82
+ # and exited 1 - the container refused to list anything, while the flag it
83
+ # complained about had been added here, not by the caller. `export` kept
84
+ # working, which is why it went unnoticed: it was the only subcommand anyone
85
+ # had run through a container.
86
+ is_export=false
80
87
  for arg in "$@"; do
81
- if [ "$arg" = "--output-dir" ]; then
82
- has_output_dir=true
88
+ if [ "$arg" = "export" ]; then
89
+ is_export=true
83
90
  break
84
91
  fi
85
92
  done
86
- if [ "$has_output_dir" = false ]; then
87
- set -- "$@" --output-dir /data/output
93
+
94
+ if [ "$is_export" = true ]; then
95
+ # Appending --output-dir rather than exporting a variable, because the CLI
96
+ # has no environment variable for it and its default resolves against a
97
+ # cwd of /app. Only when the caller did not pass one, for the same reason
98
+ # as --auth-file below: an explicit choice must never be overridden.
99
+ has_output_dir=false
100
+ for arg in "$@"; do
101
+ if [ "$arg" = "--output-dir" ]; then
102
+ has_output_dir=true
103
+ break
104
+ fi
105
+ done
106
+ if [ "$has_output_dir" = false ]; then
107
+ set -- "$@" --output-dir /data/output
108
+ fi
88
109
  fi
89
110
  fi
90
111
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@msout/microsoft-onenote-exporter",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "Log in, list and export Microsoft OneNote notebooks as Obsidian Markdown - one CLI over @msout/microsoft-webauth, @msout/microsoft-onenote-list-notebooks and @msout/microsoft-onenote-export-notebook.",
5
5
  "main": "src/index.js",
6
6
  "exports": {
@@ -53,7 +53,7 @@
53
53
  "homepage": "https://github.com/Ms-OneNote-Exporter/microsoft-onenote-exporter#readme",
54
54
  "dependencies": {
55
55
  "@msout/microsoft-onenote-export-notebook": "0.3.7",
56
- "@msout/microsoft-onenote-list-notebooks": "0.0.6",
56
+ "@msout/microsoft-onenote-list-notebooks": "0.0.7",
57
57
  "@msout/microsoft-webauth": "0.1.8",
58
58
  "chalk": "^4.1.2",
59
59
  "commander": "^14.0.3",
@@ -33,23 +33,46 @@ OUTPUT_DIR="${OUTPUT_DIR:-./output}"
33
33
  # simply follows it and no copy is needed.
34
34
  # Which session to use, in order of preference:
35
35
  #
36
- # 1. $AUTH_FILE, if the caller set it
37
- # 2. ./output/auth.json, the convention the README documents - the session sits
36
+ # 1. --auth-file <path>, if the caller passed it on the command line
37
+ # 2. $AUTH_FILE, if the caller set it in the environment
38
+ # 3. ./output/auth.json, the convention the README documents - the session sits
38
39
  # beside the notes in the one mounted volume, so there is nothing else to
39
40
  # mount and no copy step on every run
40
- # 3. ~/.microsoft-webauth/auth-file.json, where `login` writes it, so the
41
+ # 4. ~/.microsoft-webauth/auth-file.json, where `login` writes it, so the
41
42
  # "log in on the host, then run this" sequence works with no preparation
42
43
  #
43
- # The default is NOT just (3): a check for (2) has to come first, because with the
44
- # default set to (3) the script looks for a file named `auth-file.json` in the
44
+ # (1) exists because the flag was silently ignored. This script picks the session
45
+ # itself and passes its own --auth-file to the container, so an
46
+ # `--auth-file ./my.json` from the caller was neither honoured nor rejected - the
47
+ # wrong session was used and the run succeeded against it. Found by passing the
48
+ # flag, watching a *different* file get deleted, and reading the code to see why.
49
+ #
50
+ # The default is NOT just (4): a check for (3) has to come first, because with the
51
+ # default set to (4) the script looks for a file named `auth-file.json` in the
45
52
  # output directory and silently ignores the `auth.json` a user following the
46
53
  # README actually placed there.
47
- if [ -z "${AUTH_FILE:-}" ]; then
48
- if [ -f "${OUTPUT_DIR}/auth.json" ]; then
49
- AUTH_FILE="${OUTPUT_DIR}/auth.json"
50
- else
51
- AUTH_FILE="$HOME/.microsoft-webauth/auth-file.json"
54
+ AUTH_FILE_FROM_ARGS=""
55
+ prev=""
56
+ for arg in "$@"; do
57
+ if [ "$prev" = "--auth-file" ]; then
58
+ AUTH_FILE_FROM_ARGS="$arg"
52
59
  fi
60
+ case "$arg" in
61
+ --auth-file=*)
62
+ AUTH_FILE_FROM_ARGS="${arg#--auth-file=}"
63
+ ;;
64
+ esac
65
+ prev="$arg"
66
+ done
67
+
68
+ if [ -n "$AUTH_FILE_FROM_ARGS" ]; then
69
+ AUTH_FILE="$AUTH_FILE_FROM_ARGS"
70
+ elif [ -n "${AUTH_FILE:-}" ]; then
71
+ AUTH_FILE="$AUTH_FILE"
72
+ elif [ -f "${OUTPUT_DIR}/auth.json" ]; then
73
+ AUTH_FILE="${OUTPUT_DIR}/auth.json"
74
+ else
75
+ AUTH_FILE="$HOME/.microsoft-webauth/auth-file.json"
53
76
  fi
54
77
 
55
78
  # The subcommand, when the caller did not give one.
@@ -73,7 +96,7 @@ case "$SUBCOMMAND" in
73
96
  ;;
74
97
  esac
75
98
 
76
- if [ $# -eq 0 ] && [ "$SUBCOMMAND" = "export" ]; then
99
+ if [ "$SUBCOMMAND" = "export" ] && [ $# -eq 0 ]; then
77
100
  echo "Usage: $0 [--export] --notebook <name> | --notebook-link <url> [options...]" >&2
78
101
  echo "" >&2
79
102
  echo "Example:" >&2
@@ -84,11 +107,6 @@ if [ $# -eq 0 ] && [ "$SUBCOMMAND" = "export" ]; then
84
107
  exit 1
85
108
  fi
86
109
 
87
- if [ $# -eq 0 ]; then
88
- echo "Usage: $0 <$SUBCOMMAND> [options...]" >&2
89
- exit 1
90
- fi
91
-
92
110
  # One of these two must be present for a non-interactive export, and finding out
93
111
  # here rather than inside the container is the difference between an explanation
94
112
  # and `error: unknown option '--notebook-link'`.
@@ -109,6 +127,41 @@ if [ "$SUBCOMMAND" = "export" ]; then
109
127
  fi
110
128
  fi
111
129
 
130
+ # logout does not need a container.
131
+ #
132
+ # The obvious approach - mount the session read-write and let the container delete
133
+ # it - cannot work. Docker mounts a single file at /data/auth/session.json, and a
134
+ # container cannot remove a mount point: the file is the mount, so unlinking it
135
+ # fails with EACCES whether the mount is read-only or not. Making it writable
136
+ # changed nothing except how far the error got.
137
+ #
138
+ # Deleting the session is a host-side operation - one file plus its -meta.json -
139
+ # and there is nothing for the container to do. So it is done here, before any
140
+ # image is required, which also means `./start-container.sh logout` works before
141
+ # the image has ever been built.
142
+ if [ "$SUBCOMMAND" = "logout" ]; then
143
+ if [ ! -f "$AUTH_FILE" ]; then
144
+ echo "ERROR: no auth file at $AUTH_FILE" >&2
145
+ echo " Nothing to sign out of; the file is already gone." >&2
146
+ exit 1
147
+ fi
148
+
149
+ echo "Removing $AUTH_FILE"
150
+ rm -f "$AUTH_FILE"
151
+
152
+ # webauth writes the metadata beside the session as <name>-meta.json, and
153
+ # logout removes both. Leaving it behind would leave a record of the account
154
+ # with no session to go with it.
155
+ META_FILE="${AUTH_FILE%.json}-meta.json"
156
+ if [ -f "$META_FILE" ]; then
157
+ echo "Removing $META_FILE"
158
+ rm -f "$META_FILE"
159
+ fi
160
+
161
+ echo "logout finished."
162
+ exit 0
163
+ fi
164
+
112
165
  # The container name is derived from the working directory, so it is stable across
113
166
  # runs on the same machine - which means the second run collides with the first.
114
167
  # Docker refuses to reuse a name, and the error it gives ("Conflict ... already in
@@ -276,14 +329,25 @@ wait "$WATCHDOG_PID" 2>/dev/null || true
276
329
 
277
330
  echo ""
278
331
  if [ "$EXIT_CODE" -eq 0 ]; then
279
- echo "Exported files are in: $OUTPUT_DIR_ABS"
332
+ if [ "$SUBCOMMAND" = "export" ]; then
333
+ echo "Exported files are in: $OUTPUT_DIR_ABS"
334
+ else
335
+ echo "$SUBCOMMAND finished."
336
+ fi
280
337
  else
338
+ # The messages name the subcommand rather than always saying "the export": a
339
+ # failed logout reporting "the export failed and produced nothing usable"
340
+ # sends you looking for notes that were never the point of the command.
281
341
  case "$EXIT_CODE" in
282
342
  1)
283
- echo "WARNING: the export failed and produced nothing usable." >&2
343
+ echo "WARNING: $SUBCOMMAND failed." >&2
284
344
  ;;
285
345
  2)
286
- echo "WARNING: the arguments were wrong - check --notebook or --notebook-link." >&2
346
+ if [ "$SUBCOMMAND" = "export" ]; then
347
+ echo "WARNING: the arguments were wrong - check --notebook or --notebook-link." >&2
348
+ else
349
+ echo "WARNING: the arguments were wrong." >&2
350
+ fi
287
351
  ;;
288
352
  3)
289
353
  echo "NOTE: the export finished but some pages, sections or groups are missing." >&2
@@ -294,8 +358,12 @@ else
294
358
  echo "WARNING: the container exited with status $EXIT_CODE." >&2
295
359
  ;;
296
360
  esac
297
- echo "Anything already written to $OUTPUT_DIR_ABS has been kept." >&2
298
- echo "See logs/app.log inside the output directory for the full run." >&2
361
+ if [ "$SUBCOMMAND" = "export" ]; then
362
+ echo "Anything already written to $OUTPUT_DIR_ABS has been kept." >&2
363
+ echo "See logs/app.log inside the output directory for the full run." >&2
364
+ else
365
+ echo "See logs/app.log inside the output directory for the full run." >&2
366
+ fi
299
367
  fi
300
368
 
301
369
  exit "$EXIT_CODE"