From 1287ec03979b8e4b70f51af9628d88ab2480cc93 Mon Sep 17 00:00:00 2001 From: Shane <6071159+smashedr@users.noreply.github.com> Date: Mon, 8 Dec 2025 23:57:14 -0800 Subject: [PATCH 1/6] Typer --- .gitignore | 2 + pyproject.toml | 5 +- src/npmstat/cli.py | 171 +++++++++++++++++++++------------------------ uv.lock | 28 +++++--- 4 files changed, 102 insertions(+), 104 deletions(-) diff --git a/.gitignore b/.gitignore index 1d1ae8a..c31b2cd 100644 --- a/.gitignore +++ b/.gitignore @@ -9,9 +9,11 @@ __pycache__/ build/ dist/ .*cache/ +/.*cache* *.log *.pyc .coverage coverage.xml # Zensical /site/ +/test*.* diff --git a/pyproject.toml b/pyproject.toml index 991401b..77e4950 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,9 +14,9 @@ classifiers = [ "Typing :: Typed", ] dependencies = [ - "argcomplete>=3,<4", "requests>=2,<3", "requests-cache>=1,<2", + "typer>=0.20.0", ] dynamic = ["version"] @@ -30,7 +30,7 @@ Homepage = "https://cssnr.com/" Issues = "https://github.com/cssnr/npmstat/issues" [project.scripts] -npmstat = "npmstat.cli:main" +npmstat = "npmstat.cli:app" [dependency-groups] dev = [ @@ -44,6 +44,7 @@ dev = [ "ruff>=0.14.7", "tombi>=0.7.3", "ty>=0.0.1a30", + "typer>=0.20.0", "types-requests>=2.32.4.20250913", "validate-pyproject[all]>=0.24.1", ] diff --git a/src/npmstat/cli.py b/src/npmstat/cli.py index 5629364..9f6fc39 100644 --- a/src/npmstat/cli.py +++ b/src/npmstat/cli.py @@ -1,112 +1,101 @@ -#!/usr/bin/env python -# PYTHON_ARGCOMPLETE_OK -import argparse -import json -import os import sys +from typing import Optional -import argcomplete +import typer +from rich import print, print_json +from typing_extensions import Annotated from . import __doc__ as package_doc from . import api from ._version import __version__ -_verbose = False +app = typer.Typer(no_args_is_help=True) +state = {"verbose": False} -def run(): - if os.name == "nt": - os.system("") # nosec - parser = argparse.ArgumentParser( - prog="npmstat", - description="example: npmstat stats @cssnr/vitepress-swiper", - epilog="Docs: https://cssnr.github.io/npmstat/", - ) - # root - parser.add_argument("-C", "--clear-cache", action="store_true", help="clear the request cache and exit") - parser.add_argument("-V", "--version", action="store_true", help="show the package version and exit") +def vprint(*objects: str): + if state.get("verbose"): + print(*objects, file=sys.stderr) - # global - common = argparse.ArgumentParser(add_help=False) - c_group = common.add_argument_group("global options") - c_group.add_argument("-i", "--indent", default=2, type=int, metavar="N", help="indent level of json, default: 2") - c_group.add_argument("-p", "--purge", action="store_true", help="purge cache for this request") - c_group.add_argument("-f", "--force-purge", action="store_true", help="force purge for this request") - c_group.add_argument("-v", "--verbose", action="store_true", help="enable verbose command output") - subparsers = parser.add_subparsers(dest="command", metavar="[command]") - - # info - info_parser = subparsers.add_parser("info", parents=[common], help="get package info") - info_parser.add_argument("package", type=str, help="Package name") - info_parser.add_argument("pkg_version", metavar="version", nargs="?", type=str, help="Package version") - - # stats - stats_parser = subparsers.add_parser("stats", parents=[common], help="get download stats") - stats_parser.add_argument("package", type=str, help="Package name") - stats_parser.add_argument("period", default="last-day", nargs="?", type=str, help="Stats period") - stats_parser.add_argument("-r", "--range", action="store_true", help="show a range vs cumulative") - - argcomplete.autocomplete(parser) - args = parser.parse_args() - - global _verbose - _verbose = args.verbose if hasattr(args, "verbose") else False - - if args.version: +def version_callback(value: bool): + if value: print(package_doc, file=sys.stderr) print(__version__) - return + raise typer.Exit() + - if args.clear_cache: +def clear_cache_callback(value: bool): + if value: api.session.cache.clear() - print("Cache Cleared") - return - - verb_print("package", getattr(args, "package", None)) - kwargs = {"refresh": getattr(args, "purge", False), "force_refresh": getattr(args, "force_purge", False)} - verb_print("kwargs", kwargs) - - if args.command == "info": - verb_print("version", args.pkg_version) - r = api.get_package(args.package, args.pkg_version, **kwargs) - verb_print("url", r.url) - verb_print("from_cache", r.from_cache) - stats = r.json() - print(json.dumps(stats, indent=args.indent or None)) - return - - if args.command == "stats": - verb_print("period", args.period) - verb_print("range", args.range) - r = api.get_downloads(args.package, args.period, args.range, **kwargs) - verb_print("url", r.url) - verb_print("from_cache", r.from_cache) - downloads = r.json() - print(json.dumps(downloads, indent=args.indent or None)) - return - - print("\033[31;1merror: \033[33;1mNo command provided.\033[0m", file=sys.stderr, end="\n\n") - parser.print_help(sys.stderr) - sys.exit(1) - - -def verb_print(name, value): + print("[bold green]Cache Cleared.") + raise typer.Exit() + + +@app.command() +def info( + package: Annotated[str, typer.Argument(help="NPM Package Name")], + version: Annotated[Optional[str], typer.Argument(help="Package Version")] = None, + _indent: Annotated[Optional[int], typer.Option("-i", "--indent", help="JSON Indent.")] = 2, + _purge: Annotated[Optional[bool], typer.Option("-p", "--purge", help="Purge Cache for Request.")] = False, + _force: Annotated[Optional[bool], typer.Option("-f", "--force-purge", help="Force Purge for Request.")] = False, +): + """Get Package Information.""" + vprint(f"package: {package}") + vprint(f"version: {version}") + vprint(f"_indent: {_indent}") + vprint(f"_purge: {_purge}") + vprint(f"_force: {_force}") + r = api.get_package(package, version) + vprint(f"url: {r.url}") + vprint(f"from_cache: {r.from_cache}") + data = r.json() + print_json(data=data, indent=_indent or None) + + +@app.command() +def stats( + package: Annotated[str, typer.Argument(help="NPM Package Name.")], + period: Annotated[str, typer.Argument(help="Stats Period.")] = "last-day", + _range: Annotated[bool, typer.Option("--range", "-r", help="Get Range.")] = False, + _indent: Annotated[Optional[int], typer.Option("-i", "--indent", help="JSON Indent.")] = 2, + _purge: Annotated[Optional[bool], typer.Option("-p", "--purge", help="Purge Cache for Request.")] = False, + _force: Annotated[Optional[bool], typer.Option("-f", "--force-purge", help="Force Purge for Request.")] = False, +): + """Get Package Download Stats.""" + vprint(f"package: {package}") + vprint(f"period: {period}") + vprint(f"_range: {_range}") + vprint(f"_indent: {_indent}") + vprint(f"_purge: {_purge}") + vprint(f"_force: {_force}") + r = api.get_downloads(package, period, get_range=_range) + vprint(f"url: {r.url}") + vprint(f"from_cache: {r.from_cache}") + data = r.json() + print_json(data=data, indent=_indent or None) + + +@app.callback(epilog="Docs: https://cssnr.github.io/npmstat/") +def main( + _verbose: Annotated[Optional[bool], typer.Option("-v", "--verbose", help="Verbose Output (jq safe).")] = False, + _version: Annotated[ + Optional[bool], typer.Option("-V", "--version", help="Show App Version.", callback=version_callback) + ] = None, + _cache: Annotated[ + Optional[bool], typer.Option("-C", "--clear-cache", help="Clear Request Cache.", callback=clear_cache_callback) + ] = None, +): + """ + NPM Stat CLI + + Example: npmstat stats @cssnr/vitepress-swiper + """ if _verbose: - print(f"\033[35;1m{name}: \033[36;1m{value}\033[0m", file=sys.stderr) - - -def main() -> None: - try: - run() - except KeyboardInterrupt: - sys.exit(1) - except Exception as error: - print("\nError: {}".format(str(error))) - sys.exit(1) + state["verbose"] = _verbose if __name__ == "__main__": - main() + app() diff --git a/uv.lock b/uv.lock index c010708..8faf809 100644 --- a/uv.lock +++ b/uv.lock @@ -16,15 +16,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/7f/9c/36c5c37947ebfb8c7f22e0eb6e4d188ee2d53aa3880f3f2744fb894f0cb1/anyio-4.12.0-py3-none-any.whl", hash = "sha256:dad2376a628f98eeca4881fc56cd06affd18f659b17a747d3ff0307ced94b1bb", size = 113362, upload-time = "2025-11-28T23:36:57.897Z" }, ] -[[package]] -name = "argcomplete" -version = "3.6.3" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/38/61/0b9ae6399dd4a58d8c1b1dc5a27d6f2808023d0b5dd3104bb99f45a33ff6/argcomplete-3.6.3.tar.gz", hash = "sha256:62e8ed4fd6a45864acc8235409461b72c9a28ee785a2011cc5eb78318786c89c", size = 73754, upload-time = "2025-10-20T03:33:34.741Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/74/f5/9373290775639cb67a2fce7f629a1c240dce9f12fe927bc32b2736e16dfc/argcomplete-3.6.3-py3-none-any.whl", hash = "sha256:f5007b3a600ccac5d25bbce33089211dfd49eab4a7718da3f10e3082525a92ce", size = 43846, upload-time = "2025-10-20T03:33:33.021Z" }, -] - [[package]] name = "attrs" version = "25.4.0" @@ -932,9 +923,9 @@ wheels = [ name = "npmstat" source = { editable = "." } dependencies = [ - { name = "argcomplete" }, { name = "requests" }, { name = "requests-cache" }, + { name = "typer" }, ] [package.dev-dependencies] @@ -955,9 +946,9 @@ dev = [ [package.metadata] requires-dist = [ - { name = "argcomplete", specifier = ">=3,<4" }, { name = "requests", specifier = ">=2,<3" }, { name = "requests-cache", specifier = ">=1,<2" }, + { name = "typer", specifier = ">=0.20.0" }, ] [package.metadata.requires-dev] @@ -1385,6 +1376,21 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e0/1c/350fd851fb91244f8c80cec218009cbee7564d76c14e2f423b47e69a5cbc/ty-0.0.1a32-py3-none-win_arm64.whl", hash = "sha256:dbb25f9b513d34cee8ce419514eaef03313f45c3f7ab4eb6e6d427ea1f6854af", size = 9453761, upload-time = "2025-12-05T21:04:24.502Z" }, ] +[[package]] +name = "typer" +version = "0.20.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "rich" }, + { name = "shellingham" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/8f/28/7c85c8032b91dbe79725b6f17d2fffc595dff06a35c7a30a37bef73a1ab4/typer-0.20.0.tar.gz", hash = "sha256:1aaf6494031793e4876fb0bacfa6a912b551cf43c1e63c800df8b1a866720c37", size = 106492, upload-time = "2025-10-20T17:03:49.445Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/78/64/7713ffe4b5983314e9d436a90d5bd4f63b6054e2aca783a3cfc44cb95bbf/typer-0.20.0-py3-none-any.whl", hash = "sha256:5b463df6793ec1dca6213a3cf4c0f03bc6e322ac5e16e13ddd622a889489784a", size = 47028, upload-time = "2025-10-20T17:03:47.617Z" }, +] + [[package]] name = "types-requests" version = "2.32.4.20250913" From e553ed7641af91b42fb88bb6968df76f88a7fe21 Mon Sep 17 00:00:00 2001 From: Shane <6071159+smashedr@users.noreply.github.com> Date: Mon, 8 Dec 2025 23:59:19 -0800 Subject: [PATCH 2/6] Fucking Lock - Yet Another Fucking Check Needed... --- uv.lock | 2 ++ 1 file changed, 2 insertions(+) diff --git a/uv.lock b/uv.lock index 8faf809..9baff75 100644 --- a/uv.lock +++ b/uv.lock @@ -940,6 +940,7 @@ dev = [ { name = "ruff" }, { name = "tombi" }, { name = "ty" }, + { name = "typer" }, { name = "types-requests" }, { name = "validate-pyproject", extra = ["all"] }, ] @@ -963,6 +964,7 @@ dev = [ { name = "ruff", specifier = ">=0.14.7" }, { name = "tombi", specifier = ">=0.7.3" }, { name = "ty", specifier = ">=0.0.1a30" }, + { name = "typer", specifier = ">=0.20.0" }, { name = "types-requests", specifier = ">=2.32.4.20250913" }, { name = "validate-pyproject", extras = ["all"], specifier = ">=0.24.1" }, ] From 279824820495b9069221ec9441261029f7b6413c Mon Sep 17 00:00:00 2001 From: Shane <6071159+smashedr@users.noreply.github.com> Date: Thu, 11 Dec 2025 12:05:48 -0800 Subject: [PATCH 3/6] Typer Updates and Cleanup --- src/npmstat/cli.py | 42 ++++++++++++++++++------------------------ tests/test_all.py | 8 ++++---- 2 files changed, 22 insertions(+), 28 deletions(-) diff --git a/src/npmstat/cli.py b/src/npmstat/cli.py index 9f6fc39..e0cccad 100644 --- a/src/npmstat/cli.py +++ b/src/npmstat/cli.py @@ -1,5 +1,5 @@ import sys -from typing import Optional +from typing import Any, Optional import typer from rich import print, print_json @@ -10,14 +10,19 @@ from ._version import __version__ -app = typer.Typer(no_args_is_help=True) +context_settings = { + "help_option_names": ["-h", "--help"], + # "ignore_unknown_options": True, +} + +app = typer.Typer(context_settings=context_settings) state = {"verbose": False} -def vprint(*objects: str): +def vprint(*objects: Any, **kwargs): if state.get("verbose"): - print(*objects, file=sys.stderr) + print(*objects, file=sys.stderr, **kwargs) def version_callback(value: bool): @@ -34,28 +39,23 @@ def clear_cache_callback(value: bool): raise typer.Exit() -@app.command() +@app.command(no_args_is_help=True, epilog="Docs: https://cssnr.github.io/npmstat/cli/#info") def info( - package: Annotated[str, typer.Argument(help="NPM Package Name")], + package: Annotated[str, typer.Argument(help="NPM Package Name.")], version: Annotated[Optional[str], typer.Argument(help="Package Version")] = None, _indent: Annotated[Optional[int], typer.Option("-i", "--indent", help="JSON Indent.")] = 2, _purge: Annotated[Optional[bool], typer.Option("-p", "--purge", help="Purge Cache for Request.")] = False, _force: Annotated[Optional[bool], typer.Option("-f", "--force-purge", help="Force Purge for Request.")] = False, ): """Get Package Information.""" - vprint(f"package: {package}") - vprint(f"version: {version}") - vprint(f"_indent: {_indent}") - vprint(f"_purge: {_purge}") - vprint(f"_force: {_force}") + vprint(f"{package=}", f"{version=}", f"{_indent=}", f"{_purge=}", f"{_force=}", sep="\n") r = api.get_package(package, version) - vprint(f"url: {r.url}") - vprint(f"from_cache: {r.from_cache}") + vprint(f"{r.url=}", f"{r.from_cache=}", sep="\n") data = r.json() print_json(data=data, indent=_indent or None) -@app.command() +@app.command(no_args_is_help=True, epilog="Docs: https://cssnr.github.io/npmstat/cli/#stats") def stats( package: Annotated[str, typer.Argument(help="NPM Package Name.")], period: Annotated[str, typer.Argument(help="Stats Period.")] = "last-day", @@ -65,20 +65,14 @@ def stats( _force: Annotated[Optional[bool], typer.Option("-f", "--force-purge", help="Force Purge for Request.")] = False, ): """Get Package Download Stats.""" - vprint(f"package: {package}") - vprint(f"period: {period}") - vprint(f"_range: {_range}") - vprint(f"_indent: {_indent}") - vprint(f"_purge: {_purge}") - vprint(f"_force: {_force}") + vprint(f"{package=}", f"{period=}", f"{_range=}", f"{_indent=}", f"{_purge=}", f"{_force=}", sep="\n") r = api.get_downloads(package, period, get_range=_range) - vprint(f"url: {r.url}") - vprint(f"from_cache: {r.from_cache}") + vprint(f"{r.url=}", f"{r.from_cache=}", sep="\n") data = r.json() print_json(data=data, indent=_indent or None) -@app.callback(epilog="Docs: https://cssnr.github.io/npmstat/") +@app.callback(no_args_is_help=True, epilog="Docs: https://cssnr.github.io/npmstat/cli/") def main( _verbose: Annotated[Optional[bool], typer.Option("-v", "--verbose", help="Verbose Output (jq safe).")] = False, _version: Annotated[ @@ -91,7 +85,7 @@ def main( """ NPM Stat CLI - Example: npmstat stats @cssnr/vitepress-swiper + Example: npmstat -v stats @cssnr/vitepress-swiper """ if _verbose: state["verbose"] = _verbose diff --git a/tests/test_all.py b/tests/test_all.py index 78514f3..353a469 100644 --- a/tests/test_all.py +++ b/tests/test_all.py @@ -3,15 +3,15 @@ def test_info(): r = api.get_package("@cssnr/vitepress-swiper", "0.0.1") - print(f"res.status_code: {r.status_code}") - print(f"res.from_cache: {r.from_cache}") + print(f"{r.status_code=}") + print(f"{r.from_cache=}") assert r.status_code == 200 assert r.json() def test_stats(): r = api.get_downloads("@cssnr/vitepress-swiper") - print(f"res.status_code: {r.status_code}") - print(f"res.from_cache: {r.from_cache}") + print(f"{r.status_code=}") + print(f"{r.from_cache=}") assert r.status_code == 200 assert r.json() From 18c5ae8dd99d3e4f34f722823fc6a74ac91287cb Mon Sep 17 00:00:00 2001 From: Shane <6071159+smashedr@users.noreply.github.com> Date: Thu, 11 Dec 2025 12:31:42 -0800 Subject: [PATCH 4/6] Typer Docs --- docs/cli.md | 120 ++++++++++++++++++++++++------------------------- docs/module.md | 4 +- 2 files changed, 59 insertions(+), 65 deletions(-) diff --git a/docs/cli.md b/docs/cli.md index c34830d..2c1bd76 100644 --- a/docs/cli.md +++ b/docs/cli.md @@ -23,19 +23,27 @@ To see the help use the `[COMMAND] -h` flag. ??? abstract "Global Help Output: `npmstat -h`" ```text - usage: npmstat [-h] [-C] [-V] [command] ... - - example: npmstat stats @cssnr/vitepress-swiper - - positional arguments: - [command] - info get package info - stats get download stats - - options: - -h, --help show this help message and exit - -C, --clear-cache clear the request cache and exit - -V, --version show the package version and exit + Usage: npmstat [OPTIONS] COMMAND [ARGS]... + + NPM Stat CLI + + Example: npmstat -v stats @cssnr/vitepress-swiper + + ┌─ Options ──────────────────────────────────────────────────────────┐ + │ --verbose -v Verbose Output (jq safe). │ + │ --version -V Show App Version. │ + │ --clear-cache -C Clear Request Cache. │ + │ --install-completion Install completion for the │ + │ current shell. │ + │ --show-completion Show completion for the │ + │ current shell, to copy it or │ + │ customize the installation. │ + │ --help -h Show this message and exit. │ + └─────────────────────────────────────────────────────────────────────┘ + ┌─ Commands ─────────────────────────────────────────────────────────┐ + │ info Get Package Information. │ + │ stats Get Package Download Stats. │ + └─────────────────────────────────────────────────────────────────────┘ ``` To enable tab-completion follow the [Autocomplete](#autocomplete) instructions. @@ -55,44 +63,46 @@ You can also view the [Examples](#examples) below. Get package information. Without a `version` all versions are returned. ```text -usage: npmstat info [-h] [-i N] [-p] [-f] [-v] package [version] - -positional arguments: - package Package name - version Package version - -options: - -h, --help show this help message and exit - -global options: - -i, --indent N indent level of json, default: 2 - -p, --purge purge cache for this request - -f, --force-purge force purge for this request - -v, --verbose enable verbose command output + Get Package Information. + +┌─ Arguments ────────────────────────────────────────────────────────┐ +│ * package TEXT NPM Package Name. [required] │ +│ version [VERSION] Package Version │ +└─────────────────────────────────────────────────────────────────────┘ +┌─ Options ──────────────────────────────────────────────────────────┐ +│ --indent -i INTEGER JSON Indent. [default: 2] │ +│ --purge -p Purge Cache for Request. │ +│ --force-purge -f Force Purge for Request. │ +│ --help -h Show this message and exit. │ +└─────────────────────────────────────────────────────────────────────┘ ``` +!!! tip "In the terminal output is scaled and displays properly." + ### stats Get package stats for a `period`. The default is `last-day`. ```text -usage: npmstat stats [-h] [-i N] [-p] [-f] [-v] [-r] package [period] - -positional arguments: - package Package name - period Stats period - -options: - -h, --help show this help message and exit - -r, --range show a range vs cumulative - -global options: - -i, --indent N indent level of json, default: 2 - -p, --purge purge cache for this request - -f, --force-purge force purge for this request - -v, --verbose enable verbose command output + Usage: npmstat stats [OPTIONS] PACKAGE [PERIOD] + + Get Package Download Stats. + +┌─ Arguments ────────────────────────────────────────────────────────┐ +│ * package TEXT NPM Package Name. [required] │ +│ period [PERIOD] Stats Period. [default: last-day] │ +└─────────────────────────────────────────────────────────────────────┘ +┌─ Options ──────────────────────────────────────────────────────────┐ +│ --range -r Get Range. │ +│ --indent -i INTEGER JSON Indent. [default: 2] │ +│ --purge -p Purge Cache for Request. │ +│ --force-purge -f Force Purge for Request. │ +│ --help -h Show this message and exit. │ +└─────────────────────────────────────────────────────────────────────┘ ``` +!!! tip "In the terminal output is scaled and displays properly." + **Period Options** To print individual stats for each day use the `-r` flag. @@ -193,31 +203,17 @@ Reference: https://github.com/npm/registry/blob/main/docs/download-counts.md ## Autocomplete :lucide-flask-conical:{ title="Experimental Feature" } -Bash/Zsh, Windows, and Fish support tab auto-complete for arguments. - -After [installing](index.md#install) run one of the following commands. +Shell autocomplete support is provided by [click](https://github.com/pallets/click). -=== "Bash/Zsh" +After [installing](index.md#install) run the following command. - ```shell - activate-global-python-argcomplete - ``` - -=== "Windows" - - ```shell - register-python-argcomplete --shell powershell npmstat | Out-String | Invoke-Expression - ``` - -=== "Fish" - - ```shell - register-python-argcomplete --shell fish my-awesome-script | source - ``` +```shell +npmstat --install-completion +``` Then restart your shell. -Reference: https://kislyuk.github.io/argcomplete/#activating-global-completion +Reference: https://click.palletsprojects.com/en/stable/shell-completion/   diff --git a/docs/module.md b/docs/module.md index 1daeaeb..7c3b2f3 100644 --- a/docs/module.md +++ b/docs/module.md @@ -31,9 +31,7 @@ print('cache cleared') For more details see the [api.py](https://github.com/cssnr/npmstat/blob/master/src/npmstat/api.py) source code. -!!! warning - - This API is incomplete and expected to change in the future. +!!! warning "This API is incomplete and may change in the future."   From c1a5407e0f03c1dca7b97b7f16e28a924f00eb68 Mon Sep 17 00:00:00 2001 From: Shane <6071159+smashedr@users.noreply.github.com> Date: Thu, 11 Dec 2025 12:36:07 -0800 Subject: [PATCH 5/6] Docs --- .gitignore | 3 +-- docs/assets/css/extra.css | 6 ++++++ docs/assets/js/{external-links.js => extra.js} | 7 ++----- zensical.toml | 4 ++-- 4 files changed, 11 insertions(+), 9 deletions(-) create mode 100644 docs/assets/css/extra.css rename docs/assets/js/{external-links.js => extra.js} (85%) diff --git a/.gitignore b/.gitignore index c31b2cd..7c67519 100644 --- a/.gitignore +++ b/.gitignore @@ -9,11 +9,10 @@ __pycache__/ build/ dist/ .*cache/ -/.*cache* *.log *.pyc .coverage coverage.xml -# Zensical +# App /site/ /test*.* diff --git a/docs/assets/css/extra.css b/docs/assets/css/extra.css new file mode 100644 index 0000000..de3cf9c --- /dev/null +++ b/docs/assets/css/extra.css @@ -0,0 +1,6 @@ +/* Fix content shift on scrollbar */ +@supports (scrollbar-gutter: stable) { + html { + scrollbar-gutter: stable; + } +} diff --git a/docs/assets/js/external-links.js b/docs/assets/js/extra.js similarity index 85% rename from docs/assets/js/external-links.js rename to docs/assets/js/extra.js index bc87679..a6a40fa 100644 --- a/docs/assets/js/external-links.js +++ b/docs/assets/js/extra.js @@ -1,9 +1,6 @@ // Open External Links in New Tab - // noinspection JSUnresolvedReference,JSIgnoredPromiseFromCall -document$.subscribe(documentLoaded) - -function documentLoaded() { +document$.subscribe(function () { // console.log('documentLoaded:', globalThis.location) for (const el of document.querySelectorAll('a')) { // console.log('el.host:', el.host) @@ -12,4 +9,4 @@ function documentLoaded() { el.rel = 'noopener' } } -} +}) diff --git a/zensical.toml b/zensical.toml index ffdd282..d9acdd8 100644 --- a/zensical.toml +++ b/zensical.toml @@ -21,9 +21,9 @@ nav = [ { "Support" = "support.md" }, ] # https://zensical.org/docs/customization/#additional-css -# extra_css = ["assets/css/extra.css"] +extra_css = ["assets/css/extra.css"] # https://zensical.org/docs/customization/#additional-javascript -extra_javascript = ["assets/js/external-links.js"] +extra_javascript = ["assets/js/extra.js"] # ---------------------------------------------------------------------------- # Section for configuring theme options From 2dd6e169bd226f95fe468645df37ff61b3b8340a Mon Sep 17 00:00:00 2001 From: Shane <6071159+smashedr@users.noreply.github.com> Date: Thu, 11 Dec 2025 12:41:19 -0800 Subject: [PATCH 6/6] Docs --- docs/index.md | 2 +- docs/module.md | 12 +++++------- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/docs/index.md b/docs/index.md index 7aa930b..b341c18 100644 --- a/docs/index.md +++ b/docs/index.md @@ -87,7 +87,7 @@ npmstat stats @cssnr/vitepress-swiper ```python from npmstat import api -downloads = api.get_downloads('@cssnr/vitepress-swiper') +downloads = api.get_downloads("@cssnr/vitepress-swiper") print(downloads.json()) ``` diff --git a/docs/module.md b/docs/module.md index 7c3b2f3..f38ec5f 100644 --- a/docs/module.md +++ b/docs/module.md @@ -9,8 +9,8 @@ You can import the module directly. ```python import npmstat -r = npmstat.get_package('@cssnr/vitepress-swiper') -print(f'cached: {r.from_cache}') +r = npmstat.get_package("@cssnr/vitepress-swiper") +print(f"{r.from_cache=}") print(r.json()) ``` @@ -19,14 +19,12 @@ Or import the api directly. ```python from npmstat import api - -r = api.get_downloads('@cssnr/vitepress-swiper', 'last-week') -print(f'cached: {r.from_cache}') +r = api.get_downloads("@cssnr/vitepress-swiper", "last-week") +print(f"{r.from_cache=}") print(r.json()) - api.session.cache.clear() -print('cache cleared') +print("cache cleared") ``` For more details see the [api.py](https://github.com/cssnr/npmstat/blob/master/src/npmstat/api.py) source code.