@msout/microsoft-onenote-exporter 0.1.3 → 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 +41 -1
- package/package.json +1 -1
- package/start-container.sh +89 -21
package/CHANGELOG.md
CHANGED
|
@@ -6,7 +6,47 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
-
## [0.1.
|
|
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
|
|
10
50
|
|
|
11
51
|
A **patch**, and the first release driven by the automation added in the previous
|
|
12
52
|
one rather than by remembering to check.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@msout/microsoft-onenote-exporter",
|
|
3
|
-
"version": "0.1.
|
|
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": {
|
package/start-container.sh
CHANGED
|
@@ -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.
|
|
37
|
-
# 2.
|
|
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
|
-
#
|
|
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
|
-
#
|
|
44
|
-
#
|
|
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
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
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 [
|
|
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
|
-
|
|
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:
|
|
343
|
+
echo "WARNING: $SUBCOMMAND failed." >&2
|
|
284
344
|
;;
|
|
285
345
|
2)
|
|
286
|
-
|
|
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
|
-
|
|
298
|
-
|
|
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"
|