@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 +85 -0
- package/entrypoint.sh +30 -9
- package/package.json +2 -2
- package/start-container.sh +89 -21
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
|
-
#
|
|
76
|
-
#
|
|
77
|
-
#
|
|
78
|
-
#
|
|
79
|
-
|
|
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" = "
|
|
82
|
-
|
|
88
|
+
if [ "$arg" = "export" ]; then
|
|
89
|
+
is_export=true
|
|
83
90
|
break
|
|
84
91
|
fi
|
|
85
92
|
done
|
|
86
|
-
|
|
87
|
-
|
|
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.
|
|
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.
|
|
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",
|
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"
|