douban-cli is a Node.js >=22.13.0 TypeScript ESM command-line application built with Commander. Source code lives in src/; npm run build emits the executable package to dist/.
Start with:
src/index.tsfor command registration and root help.README.mdfor current user-visible commands and behavior.package.jsonfor the supported toolchain and verification pipeline.
Public reads:
src/index.ts -> commands/* -> api/* -> api/common.ts -> api/http/* -> decoder/parser -> terminal or JSON output
Authenticated writes:
commands/* -> src/auth.ts -> cached account verification -> api/mutations.ts -> Douban
Authenticated reads:
commands/* -> src/auth.ts -> api/account.ts -> Douban
Exports:
commands/* -> api/account.ts -> serializer -> storage/secure-file.ts
src/index.ts— CLI composition root. Creates the Commander program, formats root help, and registers command groups.src/commands/— CLI arguments, validation, orchestration, pagination, and terminal/JSON presentation.movie.ts— movie and TV discovery, search, details, ratings, comments, and reviews.book.ts— book charts, search, details, ratings, comments, reviews, and notes.book-collection.ts— public book collections and Markdown/CSV/JSON export.user.ts— movie collections,me, and local user configuration.auth.ts— login, identity display, and logout commands.mark.ts/social.ts— account mutations, statistics, and private exports.
src/api/— Douban URLs, response validation, domain parsing, and API result types. It must not render terminal output.http/— timeout, redirect, retry, content-type, and structured transport errors for public reads.common.ts— shared read client and HTML/text helpers.movie.ts,book.ts,search.ts,list.ts— domain-specific read APIs.book-parsers.ts— pure book HTML parsers.subject.ts— behavior genuinely shared by movies and books, such as ratings, comments, and reviews.collection.ts— shared movie/book collection parsing and cursor-based pagination; its authenticated loader is internal toaccount.ts.account.ts— authenticated profile and collection reads.mutations.ts— CSRF resolution and non-idempotent account endpoints.index.ts— public unauthenticated read APIs only; authenticated modules are imported directly.user.ts— compatibility wrapper for older movie collection callers.
src/auth.ts— browser-cookie login, account selection, identity verification, and encrypted auth cache.src/storage/secure-file.ts— atomic private-file writes with restrictive permissions.src/utils/— domain-independent errors, pagination, parsing, spinner, debug, and timing helpers.src/__tests__/— API, parser, command, authentication, pagination, and secure-file tests.scripts/— post-build executable handling and CLI smoke tests..github/workflows/— CI and GitHub Release-driven npm publishing.skills/— source artifacts for external skill registries; not runtime code and not included in the npm package.
- Command names, options, help, or presentation: change the relevant file in
src/commands/; register new top-level groups insrc/index.ts. - Douban HTML or JSON schema changes: change the owning
src/api/module or parser and add a focused fixture/decoder test. - Movie/book shared ratings, comments, reviews, or collections: use
subject.tsorcollection.tsonly when both domains have the same contract. - Timeout, retry, redirect, challenge, or content-type behavior: change
src/api/http/andapi-reliability.test.ts. - Login or Cookie handling: change
src/auth.ts,src/api/account.ts, orsrc/storage/; tests must use mocks. - Account mutations or CSRF handling: change
src/api/mutations.ts; commands import it directly rather than throughsrc/api/index.ts. - Interactive pagination: change
src/utils/pagination.tsand the command's page loader. - User-visible behavior: update
README.mdand the relevant CLI smoke or command test. - External skill packaging: update
skills/douban-cli/; derive command behavior from the CLI, README, and tests.
src/commands/does not callfetchdirectly.src/api/index.tsexposes public reads only;account.ts,mutations.ts, andcommon.tsare explicit internal imports.- Only idempotent reads may be retried automatically; account writes must not be blindly retried.
- Treat all Douban HTML and JSON as untrusted input and validate it at the API boundary.
- Preserve successfully fetched pages or fields when a later source fails; surface partial results with warnings.
- Keep movie- and book-specific behavior separate until at least two concrete consumers share the same contract.
- Commands supporting
--jsonmust render structured failures to stderr as well as structured successes to stdout. - Non-TTY execution must not enter interactive pagination.
- Tests must not read real browser Cookies or perform real authenticated mutations.
- Code comments are English; user-facing CLI text may be Chinese.
Run before committing:
npm run verify
git diff --checkFor packaging changes, also run:
npm pack --dry-run --ignore-scripts