diff --git a/.bazelrc b/.bazelrc index a1c84ea..d098b49 100644 --- a/.bazelrc +++ b/.bazelrc @@ -1,4 +1,9 @@ common --enable_bzlmod +common --registry=https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635 +common --registry=https://bcr.bazel.build +common --lockfile_mode=error +# rules_js 2.9.1 package links retain the execution tree's external layout. +common --legacy_external_runfiles build --jobs=auto build --worker_sandboxing diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0d61fa4..c977410 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,29 +8,15 @@ on: workflow_dispatch: permissions: - actions: read contents: read - packages: read jobs: package: - uses: tinyland-inc/ci-templates/.github/workflows/js-bazel-package.yml@61cd1338ca9dae8a25985c0a36ff7beb111449be + # Exact-head TIN-89 canary. Replace this with the signed immutable v4 + # release commit before merging; never fall back to the v3 publisher lane. + uses: tinyland-inc/ci-templates/.github/workflows/js-bazel-package.yml@6244d36f3048cf93672a8f37a873ec2db2cb09a3 with: runner_mode: repo_owned runner_labels_json: ${{ vars.PRIMARY_LINUX_RUNNER_LABELS_JSON }} - workspace_mode: isolated - publish_mode: hosted_exception - node_versions: '["22"]' - publish_node_version: "22" - pnpm_version: "10.13.1" - typecheck_command: pnpm typecheck - unit_test_command: pnpm test:unit - build_command: pnpm build - package_check_command: pnpm check:package - bazel_targets: "//:pkg //:test" - package_dir: ./bazel-bin/pkg - npm_access: public - npm_publish_mode: disabled - github_package_name: "@tinyland-inc/tinyland-auth-pg" - dry_run: true - secrets: inherit + bazel_targets: "//:pkg //:typecheck //:test //:integration_test //:package_authority_test //:package_artifact_test //:auth_runtime_link_test" + verify_bzlmod_lock: true diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml deleted file mode 100644 index c1ec172..0000000 --- a/.github/workflows/publish.yml +++ /dev/null @@ -1,42 +0,0 @@ -name: Publish - -on: - release: - types: [published] - workflow_dispatch: - inputs: - dry_run: - description: "Dry run without publishing" - required: false - type: boolean - default: true - -permissions: - actions: read - contents: read - id-token: write - packages: write - -jobs: - package: - uses: tinyland-inc/ci-templates/.github/workflows/js-bazel-package.yml@61cd1338ca9dae8a25985c0a36ff7beb111449be - with: - runner_mode: repo_owned - runner_labels_json: ${{ vars.PRIMARY_LINUX_RUNNER_LABELS_JSON }} - workspace_mode: isolated - publish_mode: hosted_exception - node_versions: '["22"]' - publish_node_version: "22" - pnpm_version: "10.13.1" - typecheck_command: pnpm typecheck - unit_test_command: pnpm test:unit - build_command: pnpm build - package_check_command: pnpm check:package - bazel_targets: "//:pkg //:test" - package_dir: ./bazel-bin/pkg - npm_access: public - npm_publish_mode: disabled - github_package_name: "@tinyland-inc/tinyland-auth-pg" - dry_run: ${{ github.event_name == 'workflow_dispatch' && inputs.dry_run || false }} - secrets: - TINYLAND_GITHUB_PACKAGES_TOKEN: ${{ secrets.TINYLAND_GITHUB_PACKAGES_TOKEN }} diff --git a/BUILD.bazel b/BUILD.bazel index 35cc31b..1ad80c7 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -1,4 +1,6 @@ -load("@aspect_rules_js//npm:defs.bzl", "npm_package") +load("@aspect_bazel_lib//lib:jq.bzl", "jq") +load("@aspect_rules_js//js:defs.bzl", "js_test") +load("@aspect_rules_js//npm:defs.bzl", "npm_link_package", "npm_package") load("@aspect_rules_ts//ts:defs.bzl", "ts_project") load("@tummycrypt_tinyland_auth_pg_npm//:defs.bzl", "npm_link_all_packages") load("@tummycrypt_tinyland_auth_pg_npm//:vitest/package_json.bzl", vitest_bin = "bin") @@ -7,6 +9,64 @@ package(default_visibility = ["//visibility:public"]) npm_link_all_packages(name = "node_modules") +# The auth source/type edge is owned here and comes only from Bzlmod. Rewrap the +# external package tree so Node resolves its runtime links from this consumer's +# lock-derived stores instead of producer-local runfile paths. +filegroup( + name = "tinyland_auth_registry_files", + srcs = ["@tummycrypt_tinyland_auth//:pkg"], +) + +npm_package( + name = "tinyland_auth_registry_package", + srcs = [":tinyland_auth_registry_files"], + include_external_repositories = ["tummycrypt_tinyland_auth+"], + package = "@tummycrypt/tinyland-auth", + root_paths = ["pkg"], + version = "0.3.3", +) + +npm_link_package( + name = "node_modules/@tummycrypt/tinyland-auth", + deps = { + ":.aspect_rules_js/node_modules/bcryptjs@2.4.3": "bcryptjs", + ":.aspect_rules_js/node_modules/nanoid@5.1.9": "nanoid", + ":.aspect_rules_js/node_modules/otplib@12.0.1": "otplib", + ":.aspect_rules_js/node_modules/qrcode@1.5.4": "qrcode", + }, + src = ":tinyland_auth_registry_package", +) + +AUTH_PG_NPM_DEPS = [ + ":node_modules", + ":node_modules/@neondatabase/serverless", + ":node_modules/@tummycrypt/tinyland-auth", + ":node_modules/@types/node", + ":node_modules/@types/pg", + ":node_modules/drizzle-orm", + ":node_modules/pg", +] + +PACKAGE_AUTHORITY_DATA = [ + ":node_modules", + ":node_modules/vitest", + ".bazelrc", + ".github/workflows/ci.yml", + "BUILD.bazel", + "CHANGELOG.md", + "Justfile", + "MODULE.bazel", + "MODULE.bazel.lock", + "README.md", + "package.json", + "pnpm-lock.yaml", + "pnpm-workspace.yaml", + "src/__tests__/package-authority.test.ts", + "tests/bzlmod-consumer/BUILD.fixture", + "tests/bzlmod-consumer/MODULE.bazel.template", + "vitest.config.ts", +] + ts_project( name = "tinyland-auth-pg", srcs = glob(["src/**/*.ts"], exclude = ["src/__tests__/**"]), @@ -18,34 +78,99 @@ ts_project( transpiler = "tsc", tsconfig = "tsconfig.json", validate = False, - deps = [ + deps = AUTH_PG_NPM_DEPS, +) + +ts_project( + name = "typecheck", + srcs = glob(["src/**/*.ts"], exclude = ["src/__tests__/**"]), + declaration = False, + no_emit = True, + transpiler = "tsc", + tsconfig = "tsconfig.json", + validate = False, + deps = AUTH_PG_NPM_DEPS, +) + +vitest_bin.vitest_test( + name = "test", + args = [ + "run", + "--exclude", + "src/__tests__/node-pg.test.ts", + "--exclude", + "src/__tests__/postgres-js.test.ts", + ], + data = glob([ + "drizzle/**", + "drizzle-public/**", + "src/**/*.ts", + ]) + [ ":node_modules", - ":node_modules/@neondatabase/serverless", ":node_modules/@tummycrypt/tinyland-auth", - ":node_modules/@types/node", - ":node_modules/@types/pg", - ":node_modules/drizzle-orm", - ":node_modules/pg", + ".bazelrc", + "BUILD.bazel", + "Justfile", + "MODULE.bazel", + "MODULE.bazel.lock", + "package.json", + "pnpm-lock.yaml", + "pnpm-workspace.yaml", + "tsconfig.json", + "vitest.config.ts", ], + log_level = "info", ) +# The database behavior proof is its own graph node. It may skip for a local +# developer without a container runtime, but the remote validation target sets +# AUTH_PG_INTEGRATION_REQUIRED and therefore fails closed if PostgreSQL cannot +# actually be started. vitest_bin.vitest_test( - name = "test", - args = ["run"], + name = "integration_test", + args = [ + "run", + "$(rootpath src/__tests__/node-pg.test.ts)", + "$(rootpath src/__tests__/postgres-js.test.ts)", + ], data = glob([ "drizzle/**", "drizzle-public/**", "src/**/*.ts", ]) + [ ":node_modules", + ":node_modules/@tummycrypt/tinyland-auth", "tsconfig.json", "vitest.config.ts", ], + env = {"AUTH_PG_INTEGRATION_REQUIRED": "true"}, + log_level = "info", +) + +vitest_bin.vitest_test( + name = "package_authority_test", + args = [ + "run", + "--config", + "$(rootpath vitest.config.ts)", + "$(rootpath src/__tests__/package-authority.test.ts)", + ], + data = PACKAGE_AUTHORITY_DATA, log_level = "info", ) +jq( + name = "publish_package_json", + srcs = ["package.json"], + filter = ".peerDependencies = {\"@tummycrypt/tinyland-auth\": \"^0.3.0\"} | del(.devDependencies, .scripts)", + out = "package.publish.json", +) + npm_package( name = "pkg", + data = [ + ":node_modules/@tummycrypt/tinyland-auth", + ], srcs = glob([ "drizzle/**", "drizzle-public/**", @@ -53,8 +178,26 @@ npm_package( ":tinyland-auth-pg", "CHANGELOG.md", "README.md", - "package.json", + ":publish_package_json", ], package = "@tummycrypt/tinyland-auth-pg", - version = "0.2.4", + replace_prefixes = { + "package.publish.json": "package.json", + }, + version = "0.2.5", +) + +js_test( + name = "package_artifact_test", + entry_point = "tests/package-artifact.test.mjs", + args = ["$(rootpath :pkg)"], + data = [":pkg"] + AUTH_PG_NPM_DEPS, +) + +js_test( + name = "auth_runtime_link_test", + entry_point = "tests/auth-runtime-link.test.mjs", + data = [ + ":node_modules/@tummycrypt/tinyland-auth", + ], ) diff --git a/CHANGELOG.md b/CHANGELOG.md index 62b7ed9..c424f51 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,45 @@ All notable changes to `@tummycrypt/tinyland-auth-pg` will be documented here. Format loosely follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); this package uses pre-1.0 semver where **breaking changes bump the minor**. +## [0.2.5] - Unreleased + +### Changed + +- Resolve `@tummycrypt/tinyland-auth` source and types exclusively from the + exact `tummycrypt_tinyland_auth@0.3.3` Bzlmod dependency in + `tinyland-inc/bazel-registry`, then rewrap `//:pkg` with consumer-owned, + lock-derived third-party stores instead of an npm peer/development edge. +- Generate the compatibility manifest under Bazel so its intentional + `@tummycrypt/tinyland-auth@^0.3.0` peer metadata does not restore a + first-party package-manager build edge. Canonical consumption remains the + `tummycrypt_tinyland_auth_pg` Bzlmod module. +- Route compile, typecheck, tests, and package assembly through finite Bazel + targets. The module, source manifest, package target, and eventual signed tag + must carry one version before a BCR append is proposed. +- Remove npmjs and GitHub Packages publication from the active lane. A signed + source tag becomes consumable only through a reviewed, append-only + `tinyland-inc/bazel-registry` entry after exact-head remote graph proof. +- Retire the alternate Nix pnpm/tsc package derivation; the flake now supplies + only the reproducible development shell for the Bazel authority. + +### Added + +- Contract coverage for package identity/version parity, first-party + package-manager edge rejection, the explicit Node runtime-store closure, + auth runtime resolution, the external-consumer fixture, CI publication + prohibition, and both packaged SQL migration trees. + +### Fixed + +- Make PostgreSQL's UTC clock and `expires_at` column authoritative for every + session-read path. Reads no longer parse driver-rendered naive timestamps or + delete expired rows; the explicit, tenant-scoped janitor alone deletes rows, + including the exact expiry boundary. +- Add destructive DateStyle, process-timezone, client-clock, exact-boundary, + tenant-isolation, and node-postgres/postgres.js parity coverage against real + PostgreSQL. The remote graph has a dedicated integration target that refuses + to turn missing container infrastructure into a green skip. + ## [0.2.4] — 2026-04-28 ### Added diff --git a/Justfile b/Justfile new file mode 100644 index 0000000..b29ed49 --- /dev/null +++ b/Justfile @@ -0,0 +1,78 @@ +set shell := ["bash", "-euo", "pipefail", "-c"] + +root := justfile_directory() +build_targets := "//:tinyland-auth-pg //:typecheck //:pkg" +test_targets := "//:test //:integration_test //:package_authority_test //:package_artifact_test //:auth_runtime_link_test" + +default: + @just --list --unsorted + +info: + cd {{ root }} && bazelisk info release + +flake-check: + cd {{ root }} && nix flake check --no-build + +format-check: + cd {{ root }} && nix fmt -- --check flake.nix + +setup: + cd {{ root }} && pnpm install --frozen-lockfile + +clean: + cd {{ root }} && rm -rf dist + +publish-guard: + @echo "Refusing package-registry publication; release only by signed source tag plus reviewed BCR entry after remote graph proof." >&2 + @exit 1 + +bazel-graph: + cd {{ root }} && bazelisk mod graph + +bazel-query *args: + cd {{ root }} && bazelisk query {{ args }} + +lock: + cd {{ root }} && pnpm install --lockfile-only + +build: + cd {{ root }} && bazelisk build //:tinyland-auth-pg + +typecheck: + cd {{ root }} && bazelisk build //:typecheck + +package: + cd {{ root }} && bazelisk build //:pkg + +test-unit: + cd {{ root }} && bazelisk test {{ test_targets }} --test_output=errors + +test: test-unit + +package-authority: + cd {{ root }} && bazelisk test //:package_authority_test --test_output=errors + +package-smoke: + cd {{ root }} && bazelisk test //:package_artifact_test //:auth_runtime_link_test --test_output=errors + +package-check: package package-smoke + cd {{ root }} && pnpm exec publint bazel-bin/pkg + +db-generate: + cd {{ root }} && pnpm exec drizzle-kit generate + +db-migrate: + cd {{ root }} && pnpm exec drizzle-kit migrate + +db-push: + cd {{ root }} && pnpm exec drizzle-kit push + +db-push-public: + cd {{ root }} && pnpm exec drizzle-kit push --config=drizzle.public.config.ts + +check: + cd {{ root }} && bazelisk build {{ build_targets }} + cd {{ root }} && bazelisk test {{ test_targets }} --test_output=errors + cd {{ root }} && pnpm exec publint bazel-bin/pkg + +ci: flake-check format-check bazel-graph check diff --git a/MODULE.bazel b/MODULE.bazel index 0ea049d..3af70de 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -1,6 +1,6 @@ module( name = "tummycrypt_tinyland_auth_pg", - version = "0.2.4", + version = "0.2.5", compatibility_level = 1, ) @@ -11,6 +11,9 @@ bazel_dep(name = "bazel_skylib", version = "1.8.2") bazel_dep(name = "platforms", version = "1.0.0") bazel_dep(name = "rules_nodejs", version = "6.7.3") +# Source/type authority comes from the immutable module in the Tinyland registry. +bazel_dep(name = "tummycrypt_tinyland_auth", version = "0.3.3") + node = use_extension("@rules_nodejs//nodejs:extensions.bzl", "node") node.toolchain(node_version = "22.13.1") diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock index 86d5d5e..79daa79 100644 --- a/MODULE.bazel.lock +++ b/MODULE.bazel.lock @@ -179,14 +179,315 @@ "https://bcr.bazel.build/modules/zlib/1.2.11/MODULE.bazel": "07b389abc85fdbca459b69e2ec656ae5622873af3f845e1c9d80fe179f3effa0", "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.3/MODULE.bazel": "af322bc08976524477c79d1e45e241b6efbeb918c497e8840b8ab116802dda79", "https://bcr.bazel.build/modules/zlib/1.3.1.bcr.3/source.json": "2be409ac3c7601245958cd4fcdff4288be79ed23bd690b4b951f500d54ee6e7d", - "https://bcr.bazel.build/modules/zlib/1.3.1/MODULE.bazel": "751c9940dcfe869f5f7274e1295422a34623555916eb98c174c1e945594bf198" + "https://bcr.bazel.build/modules/zlib/1.3.1/MODULE.bazel": "751c9940dcfe869f5f7274e1295422a34623555916eb98c174c1e945594bf198", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/bazel_registry.json": "7c83cacd455b1ff0c5864326cbcdef0caa1181c9c112c84ed4cb4d04568e4418", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/abseil-cpp/20210324.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/abseil-cpp/20211102.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/abseil-cpp/20230125.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/abseil-cpp/20230802.0.bcr.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/abseil-cpp/20230802.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/abseil-cpp/20230802.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/abseil-cpp/20240116.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/aspect_bazel_lib/2.0.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/aspect_bazel_lib/2.14.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/aspect_bazel_lib/2.17.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/aspect_bazel_lib/2.19.3/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/aspect_bazel_lib/2.22.5/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/aspect_bazel_lib/2.7.7/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/aspect_bazel_lib/2.8.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/aspect_rules_js/2.0.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/aspect_rules_js/2.9.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/aspect_rules_ts/3.8.4/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/aspect_tools_telemetry/0.2.8/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/aspect_tools_telemetry/0.3.3/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/bazel_features/1.1.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/bazel_features/1.11.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/bazel_features/1.15.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/bazel_features/1.17.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/bazel_features/1.18.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/bazel_features/1.19.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/bazel_features/1.21.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/bazel_features/1.28.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/bazel_features/1.39.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/bazel_features/1.4.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/bazel_features/1.9.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/bazel_features/1.9.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/bazel_lib/3.0.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/bazel_skylib/1.0.3/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/bazel_skylib/1.1.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/bazel_skylib/1.2.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/bazel_skylib/1.2.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/bazel_skylib/1.3.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/bazel_skylib/1.4.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/bazel_skylib/1.4.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/bazel_skylib/1.5.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/bazel_skylib/1.6.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/bazel_skylib/1.7.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/bazel_skylib/1.7.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/bazel_skylib/1.8.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/bazel_skylib/1.8.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/buildozer/7.1.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/gawk/5.3.2.bcr.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/google_benchmark/1.8.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/googletest/1.11.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/googletest/1.14.0.bcr.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/googletest/1.14.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/jq.bzl/0.1.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/jsoncpp/1.9.5/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/libpfm/4.11.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/package_metadata/0.0.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/platforms/0.0.10/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/platforms/0.0.11/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/platforms/0.0.4/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/platforms/0.0.5/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/platforms/0.0.6/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/platforms/0.0.7/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/platforms/0.0.8/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/platforms/1.0.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/protobuf/21.7/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/protobuf/27.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/protobuf/27.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/protobuf/29.0-rc2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/protobuf/29.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/protobuf/3.19.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/pybind11_bazel/2.11.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/re2/2023-09-01/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/rules_android/0.1.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/rules_cc/0.0.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/rules_cc/0.0.10/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/rules_cc/0.0.13/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/rules_cc/0.0.14/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/rules_cc/0.0.15/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/rules_cc/0.0.16/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/rules_cc/0.0.17/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/rules_cc/0.0.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/rules_cc/0.0.6/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/rules_cc/0.0.8/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/rules_cc/0.0.9/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/rules_cc/0.1.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/rules_cc/0.2.16/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/rules_foreign_cc/0.9.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/rules_fuzzing/0.5.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/rules_java/4.0.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/rules_java/5.3.5/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/rules_java/6.0.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/rules_java/6.3.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/rules_java/6.4.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/rules_java/6.5.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/rules_java/7.10.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/rules_java/7.12.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/rules_java/7.2.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/rules_java/7.3.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/rules_java/7.6.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/rules_java/8.6.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/rules_jvm_external/4.4.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/rules_jvm_external/5.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/rules_jvm_external/5.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/rules_jvm_external/5.3/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/rules_jvm_external/6.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/rules_jvm_external/6.3/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/rules_kotlin/1.9.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/rules_kotlin/1.9.6/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/rules_license/0.0.3/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/rules_license/0.0.7/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/rules_license/1.0.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/rules_nodejs/6.2.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/rules_nodejs/6.3.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/rules_nodejs/6.7.3/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/rules_pkg/0.7.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/rules_pkg/1.0.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/rules_proto/4.0.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/rules_proto/5.3.0-21.7/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/rules_proto/6.0.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/rules_proto/6.0.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/rules_proto/7.0.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/rules_python/0.10.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/rules_python/0.23.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/rules_python/0.25.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/rules_python/0.28.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/rules_python/0.31.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/rules_python/0.4.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/rules_python/0.40.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/rules_shell/0.2.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/rules_shell/0.4.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/stardoc/0.5.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/stardoc/0.5.3/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/stardoc/0.5.4/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/stardoc/0.5.6/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/stardoc/0.6.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/stardoc/0.7.0/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/stardoc/0.7.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/tar.bzl/0.2.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/tar.bzl/0.5.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/tummycrypt_tinyland_auth/0.3.3/MODULE.bazel": "6a04cda4f65f847d1249e6849f47e7d229d78f14d784806b534b3791102c0676", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/tummycrypt_tinyland_auth/0.3.3/source.json": "6ff387400cbe1df557e27008bdd30d30969813a021580a77abd4fc55797987ea", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/upb/0.0.0-20220923-a547704/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/yq.bzl/0.1.1/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/yq.bzl/0.3.2/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/zlib/1.2.11/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/zlib/1.3.1.bcr.3/MODULE.bazel": "not found", + "https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635/modules/zlib/1.3.1/MODULE.bazel": "not found" }, "selectedYankedVersions": {}, "moduleExtensions": { + "@@aspect_rules_js+//npm:extensions.bzl%pnpm": { + "general": { + "bzlTransitiveDigest": "+38sdUshoDaaBOpNBG17zT25s0y5uiGlxqyEtzgmzVs=", + "usagesDigest": "8CEnCI2JvDnusQ0v7Bqv7UVQmZmNYyoIO1nUY1NlqKo=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "pnpm": { + "repoRuleId": "@@aspect_rules_js+//npm/private:npm_import.bzl%npm_import_rule", + "attributes": { + "package": "pnpm", + "version": "10.13.1", + "root_package": "", + "link_workspace": "", + "link_packages": {}, + "integrity": "sha512-N+vxpcejDV+r4MXfRO6NpMllygxa89urKMOhaBtwolYhjQXIHJwNz3Z+9rhVHrW5YAQrntQwDFkkIzY3fgHPrQ==", + "url": "", + "commit": "", + "patch_args": [ + "-p0" + ], + "patches": [], + "custom_postinstall": "", + "npm_auth": "", + "npm_auth_basic": "", + "npm_auth_username": "", + "npm_auth_password": "", + "lifecycle_hooks": [], + "extra_build_content": "load(\"@aspect_rules_js//js:defs.bzl\", \"js_binary\")\njs_binary(name = \"pnpm\", data = glob([\"package/**\"]), entry_point = \"package/dist/pnpm.cjs\", visibility = [\"//visibility:public\"])", + "generate_bzl_library_targets": false, + "extract_full_archive": true, + "exclude_package_contents": [] + } + }, + "pnpm__links": { + "repoRuleId": "@@aspect_rules_js+//npm/private:npm_import.bzl%npm_import_links", + "attributes": { + "package": "pnpm", + "version": "10.13.1", + "dev": false, + "root_package": "", + "link_packages": {}, + "deps": {}, + "transitive_closure": {}, + "lifecycle_build_target": false, + "lifecycle_hooks_env": [], + "lifecycle_hooks_execution_requirements": [ + "no-sandbox" + ], + "lifecycle_hooks_use_default_shell_env": false, + "bins": {}, + "package_visibility": [ + "//visibility:public" + ], + "replace_package": "", + "exclude_package_contents": [] + } + } + }, + "recordedRepoMappingEntries": [ + [ + "aspect_bazel_lib+", + "bazel_lib", + "bazel_lib+" + ], + [ + "aspect_bazel_lib+", + "bazel_skylib", + "bazel_skylib+" + ], + [ + "aspect_bazel_lib+", + "bazel_tools", + "bazel_tools" + ], + [ + "aspect_bazel_lib+", + "tar.bzl", + "tar.bzl+" + ], + [ + "aspect_rules_js+", + "aspect_bazel_lib", + "aspect_bazel_lib+" + ], + [ + "aspect_rules_js+", + "aspect_rules_js", + "aspect_rules_js+" + ], + [ + "aspect_rules_js+", + "aspect_tools_telemetry_report", + "aspect_tools_telemetry++telemetry+aspect_tools_telemetry_report" + ], + [ + "aspect_rules_js+", + "bazel_features", + "bazel_features+" + ], + [ + "aspect_rules_js+", + "bazel_lib", + "bazel_lib+" + ], + [ + "aspect_rules_js+", + "bazel_skylib", + "bazel_skylib+" + ], + [ + "aspect_rules_js+", + "bazel_tools", + "bazel_tools" + ], + [ + "bazel_features+", + "bazel_features_globals", + "bazel_features++version_extension+bazel_features_globals" + ], + [ + "bazel_features+", + "bazel_features_version", + "bazel_features++version_extension+bazel_features_version" + ], + [ + "bazel_lib+", + "bazel_skylib", + "bazel_skylib+" + ], + [ + "bazel_lib+", + "bazel_tools", + "bazel_tools" + ], + [ + "tar.bzl+", + "aspect_bazel_lib", + "aspect_bazel_lib+" + ], + [ + "tar.bzl+", + "bazel_skylib", + "bazel_skylib+" + ], + [ + "tar.bzl+", + "tar.bzl", + "tar.bzl+" + ] + ] + } + }, "@@aspect_rules_ts+//ts:extensions.bzl%ext": { "general": { "bzlTransitiveDigest": "kpFi+ae3stSvLHgS7Fiwn/tb3J3dDqMOi1EP3tJ/TKY=", - "usagesDigest": "cbhq84lxQuTKaO/pSR7hT0/agYCXaQ4qhj4oMyTtpgk=", + "usagesDigest": "tU2DeCGQiyYqr++DIGhcxVnEu7lnhzQQaC58f5Al32s=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, "envVariables": {}, @@ -249,6 +550,123 @@ ] } }, + "@@pybind11_bazel+//:python_configure.bzl%extension": { + "general": { + "bzlTransitiveDigest": "d4N/SZrl3ONcmzE98rcV0Fsro0iUbjNQFTIiLiGuH+k=", + "usagesDigest": "fycyB39YnXIJkfWCIXLUKJMZzANcuLy9ZE73hRucjFk=", + "recordedFileInputs": { + "@@pybind11_bazel+//MODULE.bazel": "88af1c246226d87e65be78ed49ecd1e6f5e98648558c14ce99176da041dc378e" + }, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "local_config_python": { + "repoRuleId": "@@pybind11_bazel+//:python_configure.bzl%python_configure", + "attributes": {} + }, + "pybind11": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file": "@@pybind11_bazel+//:pybind11.BUILD", + "strip_prefix": "pybind11-2.11.1", + "urls": [ + "https://github.com/pybind/pybind11/archive/v2.11.1.zip" + ] + } + } + }, + "recordedRepoMappingEntries": [ + [ + "pybind11_bazel+", + "bazel_tools", + "bazel_tools" + ] + ] + } + }, + "@@rules_fuzzing+//fuzzing/private:extensions.bzl%non_module_dependencies": { + "general": { + "bzlTransitiveDigest": "mGiTB79hRNjmeDTQdzkpCHyzXhErMbufeAmySBt7s5s=", + "usagesDigest": "wy6ISK6UOcBEjj/mvJ/S3WeXoO67X+1llb9yPyFtPgc=", + "recordedFileInputs": {}, + "recordedDirentsInputs": {}, + "envVariables": {}, + "generatedRepoSpecs": { + "platforms": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "urls": [ + "https://mirror.bazel.build/github.com/bazelbuild/platforms/releases/download/0.0.8/platforms-0.0.8.tar.gz", + "https://github.com/bazelbuild/platforms/releases/download/0.0.8/platforms-0.0.8.tar.gz" + ], + "sha256": "8150406605389ececb6da07cbcb509d5637a3ab9a24bc69b1101531367d89d74" + } + }, + "rules_python": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "sha256": "d70cd72a7a4880f0000a6346253414825c19cdd40a28289bdf67b8e6480edff8", + "strip_prefix": "rules_python-0.28.0", + "url": "https://github.com/bazelbuild/rules_python/releases/download/0.28.0/rules_python-0.28.0.tar.gz" + } + }, + "bazel_skylib": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "sha256": "cd55a062e763b9349921f0f5db8c3933288dc8ba4f76dd9416aac68acee3cb94", + "urls": [ + "https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.5.0/bazel-skylib-1.5.0.tar.gz", + "https://github.com/bazelbuild/bazel-skylib/releases/download/1.5.0/bazel-skylib-1.5.0.tar.gz" + ] + } + }, + "com_google_absl": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "urls": [ + "https://github.com/abseil/abseil-cpp/archive/refs/tags/20240116.1.zip" + ], + "strip_prefix": "abseil-cpp-20240116.1", + "integrity": "sha256-7capMWOvWyoYbUaHF/b+I2U6XLMaHmky8KugWvfXYuk=" + } + }, + "rules_fuzzing_oss_fuzz": { + "repoRuleId": "@@rules_fuzzing+//fuzzing/private/oss_fuzz:repository.bzl%oss_fuzz_repository", + "attributes": {} + }, + "honggfuzz": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive", + "attributes": { + "build_file": "@@rules_fuzzing+//:honggfuzz.BUILD", + "sha256": "6b18ba13bc1f36b7b950c72d80f19ea67fbadc0ac0bb297ec89ad91f2eaa423e", + "url": "https://github.com/google/honggfuzz/archive/2.5.zip", + "strip_prefix": "honggfuzz-2.5" + } + }, + "rules_fuzzing_jazzer": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_jar", + "attributes": { + "sha256": "ee6feb569d88962d59cb59e8a31eb9d007c82683f3ebc64955fd5b96f277eec2", + "url": "https://repo1.maven.org/maven2/com/code-intelligence/jazzer/0.20.1/jazzer-0.20.1.jar" + } + }, + "rules_fuzzing_jazzer_api": { + "repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_jar", + "attributes": { + "sha256": "f5a60242bc408f7fa20fccf10d6c5c5ea1fcb3c6f44642fec5af88373ae7aa1b", + "url": "https://repo1.maven.org/maven2/com/code-intelligence/jazzer-api/0.20.1/jazzer-api-0.20.1.jar" + } + } + }, + "recordedRepoMappingEntries": [ + [ + "rules_fuzzing+", + "bazel_tools", + "bazel_tools" + ] + ] + } + }, "@@rules_java+//java:rules_java_deps.bzl%compatibility_proxy": { "general": { "bzlTransitiveDigest": "84xJEZ1jnXXwo8BXMprvBm++rRt4jsTu9liBxz0ivps=", @@ -338,7 +756,7 @@ "@@rules_nodejs+//nodejs:extensions.bzl%node": { "general": { "bzlTransitiveDigest": "4pUxCNc22K4I+6+4Nxu52Hur12tFRfa1JMsN5mdDv60=", - "usagesDigest": "/znRB0sdK54G4RfrFaCr9l5g+x/bj37O/H9FxWYnOWU=", + "usagesDigest": "aizJBEMzvGR5aw1O3DQeaqUHm9cb68UBHSb5P1JtFyc=", "recordedFileInputs": {}, "recordedDirentsInputs": {}, "envVariables": {}, @@ -469,6 +887,2500 @@ "recordedRepoMappingEntries": [] } }, + "@@rules_python+//python/private/pypi:pip.bzl%pip_internal": { + "general": { + "bzlTransitiveDigest": "LoTaMl3T/Mr0pZwTYVMcRc5gv6qNfnE8umRCDYy1m7U=", + "usagesDigest": "OLoIStnzNObNalKEMRq99FqenhPGLFZ5utVLV4sz7OI=", + "recordedFileInputs": { + "@@rules_python+//tools/publish/requirements_darwin.txt": "2994136eab7e57b083c3de76faf46f70fad130bc8e7360a7fed2b288b69e79dc", + "@@rules_python+//tools/publish/requirements_linux.txt": "8175b4c8df50ae2f22d1706961884beeb54e7da27bd2447018314a175981997d", + "@@rules_python+//tools/publish/requirements_windows.txt": "7673adc71dc1a81d3661b90924d7a7c0fc998cd508b3cb4174337cef3f2de556" + }, + "recordedDirentsInputs": {}, + "envVariables": { + "RULES_PYTHON_REPO_DEBUG": null, + "RULES_PYTHON_REPO_DEBUG_VERBOSITY": null + }, + "generatedRepoSpecs": { + "rules_python_publish_deps_311_backports_tarfile_py3_none_any_77e284d7": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "backports.tarfile-1.2.0-py3-none-any.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "backports-tarfile==1.2.0", + "sha256": "77e284d754527b01fb1e6fa8a1afe577858ebe4e9dad8919e34c862cb399bc34", + "urls": [ + "https://files.pythonhosted.org/packages/b9/fa/123043af240e49752f1c4bd24da5053b6bd00cad78c2be53c0d1e8b975bc/backports.tarfile-1.2.0-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_backports_tarfile_sdist_d75e02c2": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "backports_tarfile-1.2.0.tar.gz", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "backports-tarfile==1.2.0", + "sha256": "d75e02c268746e1b8144c278978b6e98e85de6ad16f8e4b0844a154557eca991", + "urls": [ + "https://files.pythonhosted.org/packages/86/72/cd9b395f25e290e633655a100af28cb253e4393396264a98bd5f5951d50f/backports_tarfile-1.2.0.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_certifi_py3_none_any_922820b5": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "certifi-2024.8.30-py3-none-any.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "certifi==2024.8.30", + "sha256": "922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8", + "urls": [ + "https://files.pythonhosted.org/packages/12/90/3c9ff0512038035f59d279fddeb79f5f1eccd8859f06d6163c58798b9487/certifi-2024.8.30-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_certifi_sdist_bec941d2": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "certifi-2024.8.30.tar.gz", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "certifi==2024.8.30", + "sha256": "bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9", + "urls": [ + "https://files.pythonhosted.org/packages/b0/ee/9b19140fe824b367c04c5e1b369942dd754c4c5462d5674002f75c4dedc1/certifi-2024.8.30.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_cffi_cp311_cp311_manylinux_2_17_aarch64_a1ed2dd2": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64" + ], + "filename": "cffi-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "cffi==1.17.1", + "sha256": "a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41", + "urls": [ + "https://files.pythonhosted.org/packages/2e/ea/70ce63780f096e16ce8588efe039d3c4f91deb1dc01e9c73a287939c79a6/cffi-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" + ] + } + }, + "rules_python_publish_deps_311_cffi_cp311_cp311_manylinux_2_17_ppc64le_46bf4316": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64" + ], + "filename": "cffi-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "cffi==1.17.1", + "sha256": "46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1", + "urls": [ + "https://files.pythonhosted.org/packages/1c/a0/a4fa9f4f781bda074c3ddd57a572b060fa0df7655d2a4247bbe277200146/cffi-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl" + ] + } + }, + "rules_python_publish_deps_311_cffi_cp311_cp311_manylinux_2_17_s390x_a24ed04c": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64" + ], + "filename": "cffi-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "cffi==1.17.1", + "sha256": "a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6", + "urls": [ + "https://files.pythonhosted.org/packages/62/12/ce8710b5b8affbcdd5c6e367217c242524ad17a02fe5beec3ee339f69f85/cffi-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl" + ] + } + }, + "rules_python_publish_deps_311_cffi_cp311_cp311_manylinux_2_17_x86_64_610faea7": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64" + ], + "filename": "cffi-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "cffi==1.17.1", + "sha256": "610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d", + "urls": [ + "https://files.pythonhosted.org/packages/ff/6b/d45873c5e0242196f042d555526f92aa9e0c32355a1be1ff8c27f077fd37/cffi-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl" + ] + } + }, + "rules_python_publish_deps_311_cffi_cp311_cp311_musllinux_1_1_aarch64_a9b15d49": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64" + ], + "filename": "cffi-1.17.1-cp311-cp311-musllinux_1_1_aarch64.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "cffi==1.17.1", + "sha256": "a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6", + "urls": [ + "https://files.pythonhosted.org/packages/1a/52/d9a0e523a572fbccf2955f5abe883cfa8bcc570d7faeee06336fbd50c9fc/cffi-1.17.1-cp311-cp311-musllinux_1_1_aarch64.whl" + ] + } + }, + "rules_python_publish_deps_311_cffi_cp311_cp311_musllinux_1_1_x86_64_fc48c783": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64" + ], + "filename": "cffi-1.17.1-cp311-cp311-musllinux_1_1_x86_64.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "cffi==1.17.1", + "sha256": "fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b", + "urls": [ + "https://files.pythonhosted.org/packages/f8/4a/34599cac7dfcd888ff54e801afe06a19c17787dfd94495ab0c8d35fe99fb/cffi-1.17.1-cp311-cp311-musllinux_1_1_x86_64.whl" + ] + } + }, + "rules_python_publish_deps_311_cffi_sdist_1c39c601": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "cffi-1.17.1.tar.gz", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "cffi==1.17.1", + "sha256": "1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824", + "urls": [ + "https://files.pythonhosted.org/packages/fc/97/c783634659c2920c3fc70419e3af40972dbaf758daa229a7d6ea6135c90d/cffi-1.17.1.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_charset_normalizer_cp311_cp311_macosx_10_9_universal2_0d99dd8f": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "charset-normalizer==3.4.0", + "sha256": "0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c", + "urls": [ + "https://files.pythonhosted.org/packages/9c/61/73589dcc7a719582bf56aae309b6103d2762b526bffe189d635a7fcfd998/charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl" + ] + } + }, + "rules_python_publish_deps_311_charset_normalizer_cp311_cp311_macosx_10_9_x86_64_c57516e5": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "charset-normalizer==3.4.0", + "sha256": "c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944", + "urls": [ + "https://files.pythonhosted.org/packages/77/d5/8c982d58144de49f59571f940e329ad6e8615e1e82ef84584c5eeb5e1d72/charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl" + ] + } + }, + "rules_python_publish_deps_311_charset_normalizer_cp311_cp311_macosx_11_0_arm64_6dba5d19": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "charset-normalizer==3.4.0", + "sha256": "6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee", + "urls": [ + "https://files.pythonhosted.org/packages/bf/19/411a64f01ee971bed3231111b69eb56f9331a769072de479eae7de52296d/charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl" + ] + } + }, + "rules_python_publish_deps_311_charset_normalizer_cp311_cp311_manylinux_2_17_aarch64_bf4475b8": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "charset-normalizer==3.4.0", + "sha256": "bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c", + "urls": [ + "https://files.pythonhosted.org/packages/4c/92/97509850f0d00e9f14a46bc751daabd0ad7765cff29cdfb66c68b6dad57f/charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" + ] + } + }, + "rules_python_publish_deps_311_charset_normalizer_cp311_cp311_manylinux_2_17_ppc64le_ce031db0": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "charset-normalizer==3.4.0", + "sha256": "ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6", + "urls": [ + "https://files.pythonhosted.org/packages/e2/29/d227805bff72ed6d6cb1ce08eec707f7cfbd9868044893617eb331f16295/charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl" + ] + } + }, + "rules_python_publish_deps_311_charset_normalizer_cp311_cp311_manylinux_2_17_s390x_8ff4e7cd": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "charset-normalizer==3.4.0", + "sha256": "8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea", + "urls": [ + "https://files.pythonhosted.org/packages/13/bc/87c2c9f2c144bedfa62f894c3007cd4530ba4b5351acb10dc786428a50f0/charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl" + ] + } + }, + "rules_python_publish_deps_311_charset_normalizer_cp311_cp311_manylinux_2_17_x86_64_3710a975": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "charset-normalizer==3.4.0", + "sha256": "3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc", + "urls": [ + "https://files.pythonhosted.org/packages/eb/5b/6f10bad0f6461fa272bfbbdf5d0023b5fb9bc6217c92bf068fa5a99820f5/charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl" + ] + } + }, + "rules_python_publish_deps_311_charset_normalizer_cp311_cp311_musllinux_1_2_aarch64_47334db7": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "charset-normalizer==3.4.0", + "sha256": "47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594", + "urls": [ + "https://files.pythonhosted.org/packages/d7/a1/493919799446464ed0299c8eef3c3fad0daf1c3cd48bff9263c731b0d9e2/charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl" + ] + } + }, + "rules_python_publish_deps_311_charset_normalizer_cp311_cp311_musllinux_1_2_ppc64le_f1a2f519": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "charset-normalizer==3.4.0", + "sha256": "f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365", + "urls": [ + "https://files.pythonhosted.org/packages/75/d2/0ab54463d3410709c09266dfb416d032a08f97fd7d60e94b8c6ef54ae14b/charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl" + ] + } + }, + "rules_python_publish_deps_311_charset_normalizer_cp311_cp311_musllinux_1_2_s390x_63bc5c4a": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "charset-normalizer==3.4.0", + "sha256": "63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129", + "urls": [ + "https://files.pythonhosted.org/packages/8d/c9/27e41d481557be53d51e60750b85aa40eaf52b841946b3cdeff363105737/charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl" + ] + } + }, + "rules_python_publish_deps_311_charset_normalizer_cp311_cp311_musllinux_1_2_x86_64_bcb4f8ea": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "charset-normalizer==3.4.0", + "sha256": "bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236", + "urls": [ + "https://files.pythonhosted.org/packages/ee/44/4f62042ca8cdc0cabf87c0fc00ae27cd8b53ab68be3605ba6d071f742ad3/charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl" + ] + } + }, + "rules_python_publish_deps_311_charset_normalizer_cp311_cp311_win_amd64_cee4373f": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "charset-normalizer==3.4.0", + "sha256": "cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27", + "urls": [ + "https://files.pythonhosted.org/packages/0b/6e/b13bd47fa9023b3699e94abf565b5a2f0b0be6e9ddac9812182596ee62e4/charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl" + ] + } + }, + "rules_python_publish_deps_311_charset_normalizer_py3_none_any_fe9f97fe": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "charset_normalizer-3.4.0-py3-none-any.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "charset-normalizer==3.4.0", + "sha256": "fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079", + "urls": [ + "https://files.pythonhosted.org/packages/bf/9b/08c0432272d77b04803958a4598a51e2a4b51c06640af8b8f0f908c18bf2/charset_normalizer-3.4.0-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_charset_normalizer_sdist_223217c3": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "charset_normalizer-3.4.0.tar.gz", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "charset-normalizer==3.4.0", + "sha256": "223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e", + "urls": [ + "https://files.pythonhosted.org/packages/f2/4f/e1808dc01273379acc506d18f1504eb2d299bd4131743b9fc54d7be4df1e/charset_normalizer-3.4.0.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_cryptography_cp39_abi3_manylinux_2_17_aarch64_846da004": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64" + ], + "filename": "cryptography-43.0.3-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "cryptography==43.0.3", + "sha256": "846da004a5804145a5f441b8530b4bf35afbf7da70f82409f151695b127213d5", + "urls": [ + "https://files.pythonhosted.org/packages/2f/78/55356eb9075d0be6e81b59f45c7b48df87f76a20e73893872170471f3ee8/cryptography-43.0.3-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" + ] + } + }, + "rules_python_publish_deps_311_cryptography_cp39_abi3_manylinux_2_17_x86_64_0f996e72": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64" + ], + "filename": "cryptography-43.0.3-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "cryptography==43.0.3", + "sha256": "0f996e7268af62598f2fc1204afa98a3b5712313a55c4c9d434aef49cadc91d4", + "urls": [ + "https://files.pythonhosted.org/packages/2a/2c/488776a3dc843f95f86d2f957ca0fc3407d0242b50bede7fad1e339be03f/cryptography-43.0.3-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl" + ] + } + }, + "rules_python_publish_deps_311_cryptography_cp39_abi3_manylinux_2_28_aarch64_f7b178f1": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64" + ], + "filename": "cryptography-43.0.3-cp39-abi3-manylinux_2_28_aarch64.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "cryptography==43.0.3", + "sha256": "f7b178f11ed3664fd0e995a47ed2b5ff0a12d893e41dd0494f406d1cf555cab7", + "urls": [ + "https://files.pythonhosted.org/packages/7c/04/2345ca92f7a22f601a9c62961741ef7dd0127c39f7310dffa0041c80f16f/cryptography-43.0.3-cp39-abi3-manylinux_2_28_aarch64.whl" + ] + } + }, + "rules_python_publish_deps_311_cryptography_cp39_abi3_manylinux_2_28_x86_64_c2e6fc39": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64" + ], + "filename": "cryptography-43.0.3-cp39-abi3-manylinux_2_28_x86_64.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "cryptography==43.0.3", + "sha256": "c2e6fc39c4ab499049df3bdf567f768a723a5e8464816e8f009f121a5a9f4405", + "urls": [ + "https://files.pythonhosted.org/packages/ac/25/e715fa0bc24ac2114ed69da33adf451a38abb6f3f24ec207908112e9ba53/cryptography-43.0.3-cp39-abi3-manylinux_2_28_x86_64.whl" + ] + } + }, + "rules_python_publish_deps_311_cryptography_cp39_abi3_musllinux_1_2_aarch64_e1be4655": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64" + ], + "filename": "cryptography-43.0.3-cp39-abi3-musllinux_1_2_aarch64.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "cryptography==43.0.3", + "sha256": "e1be4655c7ef6e1bbe6b5d0403526601323420bcf414598955968c9ef3eb7d16", + "urls": [ + "https://files.pythonhosted.org/packages/21/ce/b9c9ff56c7164d8e2edfb6c9305045fbc0df4508ccfdb13ee66eb8c95b0e/cryptography-43.0.3-cp39-abi3-musllinux_1_2_aarch64.whl" + ] + } + }, + "rules_python_publish_deps_311_cryptography_cp39_abi3_musllinux_1_2_x86_64_df6b6c6d": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64" + ], + "filename": "cryptography-43.0.3-cp39-abi3-musllinux_1_2_x86_64.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "cryptography==43.0.3", + "sha256": "df6b6c6d742395dd77a23ea3728ab62f98379eff8fb61be2744d4679ab678f73", + "urls": [ + "https://files.pythonhosted.org/packages/2a/33/b3682992ab2e9476b9c81fff22f02c8b0a1e6e1d49ee1750a67d85fd7ed2/cryptography-43.0.3-cp39-abi3-musllinux_1_2_x86_64.whl" + ] + } + }, + "rules_python_publish_deps_311_cryptography_sdist_315b9001": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "cryptography-43.0.3.tar.gz", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "cryptography==43.0.3", + "sha256": "315b9001266a492a6ff443b61238f956b214dbec9910a081ba5b6646a055a805", + "urls": [ + "https://files.pythonhosted.org/packages/0d/05/07b55d1fa21ac18c3a8c79f764e2514e6f6a9698f1be44994f5adf0d29db/cryptography-43.0.3.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_docutils_py3_none_any_dafca5b9": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "docutils-0.21.2-py3-none-any.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "docutils==0.21.2", + "sha256": "dafca5b9e384f0e419294eb4d2ff9fa826435bf15f15b7bd45723e8ad76811b2", + "urls": [ + "https://files.pythonhosted.org/packages/8f/d7/9322c609343d929e75e7e5e6255e614fcc67572cfd083959cdef3b7aad79/docutils-0.21.2-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_docutils_sdist_3a6b1873": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "docutils-0.21.2.tar.gz", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "docutils==0.21.2", + "sha256": "3a6b18732edf182daa3cd12775bbb338cf5691468f91eeeb109deff6ebfa986f", + "urls": [ + "https://files.pythonhosted.org/packages/ae/ed/aefcc8cd0ba62a0560c3c18c33925362d46c6075480bfa4df87b28e169a9/docutils-0.21.2.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_idna_py3_none_any_946d195a": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "idna-3.10-py3-none-any.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "idna==3.10", + "sha256": "946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", + "urls": [ + "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_idna_sdist_12f65c9b": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "idna-3.10.tar.gz", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "idna==3.10", + "sha256": "12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", + "urls": [ + "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_importlib_metadata_py3_none_any_45e54197": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "importlib_metadata-8.5.0-py3-none-any.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "importlib-metadata==8.5.0", + "sha256": "45e54197d28b7a7f1559e60b95e7c567032b602131fbd588f1497f47880aa68b", + "urls": [ + "https://files.pythonhosted.org/packages/a0/d9/a1e041c5e7caa9a05c925f4bdbdfb7f006d1f74996af53467bc394c97be7/importlib_metadata-8.5.0-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_importlib_metadata_sdist_71522656": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "importlib_metadata-8.5.0.tar.gz", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "importlib-metadata==8.5.0", + "sha256": "71522656f0abace1d072b9e5481a48f07c138e00f079c38c8f883823f9c26bd7", + "urls": [ + "https://files.pythonhosted.org/packages/cd/12/33e59336dca5be0c398a7482335911a33aa0e20776128f038019f1a95f1b/importlib_metadata-8.5.0.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_jaraco_classes_py3_none_any_f662826b": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "jaraco.classes-3.4.0-py3-none-any.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "jaraco-classes==3.4.0", + "sha256": "f662826b6bed8cace05e7ff873ce0f9283b5c924470fe664fff1c2f00f581790", + "urls": [ + "https://files.pythonhosted.org/packages/7f/66/b15ce62552d84bbfcec9a4873ab79d993a1dd4edb922cbfccae192bd5b5f/jaraco.classes-3.4.0-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_jaraco_classes_sdist_47a024b5": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "jaraco.classes-3.4.0.tar.gz", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "jaraco-classes==3.4.0", + "sha256": "47a024b51d0239c0dd8c8540c6c7f484be3b8fcf0b2d85c13825780d3b3f3acd", + "urls": [ + "https://files.pythonhosted.org/packages/06/c0/ed4a27bc5571b99e3cff68f8a9fa5b56ff7df1c2251cc715a652ddd26402/jaraco.classes-3.4.0.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_jaraco_context_py3_none_any_f797fc48": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "jaraco.context-6.0.1-py3-none-any.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "jaraco-context==6.0.1", + "sha256": "f797fc481b490edb305122c9181830a3a5b76d84ef6d1aef2fb9b47ab956f9e4", + "urls": [ + "https://files.pythonhosted.org/packages/ff/db/0c52c4cf5e4bd9f5d7135ec7669a3a767af21b3a308e1ed3674881e52b62/jaraco.context-6.0.1-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_jaraco_context_sdist_9bae4ea5": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "jaraco_context-6.0.1.tar.gz", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "jaraco-context==6.0.1", + "sha256": "9bae4ea555cf0b14938dc0aee7c9f32ed303aa20a3b73e7dc80111628792d1b3", + "urls": [ + "https://files.pythonhosted.org/packages/df/ad/f3777b81bf0b6e7bc7514a1656d3e637b2e8e15fab2ce3235730b3e7a4e6/jaraco_context-6.0.1.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_jaraco_functools_py3_none_any_ad159f13": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "jaraco.functools-4.1.0-py3-none-any.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "jaraco-functools==4.1.0", + "sha256": "ad159f13428bc4acbf5541ad6dec511f91573b90fba04df61dafa2a1231cf649", + "urls": [ + "https://files.pythonhosted.org/packages/9f/4f/24b319316142c44283d7540e76c7b5a6dbd5db623abd86bb7b3491c21018/jaraco.functools-4.1.0-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_jaraco_functools_sdist_70f7e0e2": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "jaraco_functools-4.1.0.tar.gz", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "jaraco-functools==4.1.0", + "sha256": "70f7e0e2ae076498e212562325e805204fc092d7b4c17e0e86c959e249701a9d", + "urls": [ + "https://files.pythonhosted.org/packages/ab/23/9894b3df5d0a6eb44611c36aec777823fc2e07740dabbd0b810e19594013/jaraco_functools-4.1.0.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_jeepney_py3_none_any_c0a454ad": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64" + ], + "filename": "jeepney-0.8.0-py3-none-any.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "jeepney==0.8.0", + "sha256": "c0a454ad016ca575060802ee4d590dd912e35c122fa04e70306de3d076cce755", + "urls": [ + "https://files.pythonhosted.org/packages/ae/72/2a1e2290f1ab1e06f71f3d0f1646c9e4634e70e1d37491535e19266e8dc9/jeepney-0.8.0-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_jeepney_sdist_5efe48d2": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "jeepney-0.8.0.tar.gz", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "jeepney==0.8.0", + "sha256": "5efe48d255973902f6badc3ce55e2aa6c5c3b3bc642059ef3a91247bcfcc5806", + "urls": [ + "https://files.pythonhosted.org/packages/d6/f4/154cf374c2daf2020e05c3c6a03c91348d59b23c5366e968feb198306fdf/jeepney-0.8.0.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_keyring_py3_none_any_5426f817": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "keyring-25.4.1-py3-none-any.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "keyring==25.4.1", + "sha256": "5426f817cf7f6f007ba5ec722b1bcad95a75b27d780343772ad76b17cb47b0bf", + "urls": [ + "https://files.pythonhosted.org/packages/83/25/e6d59e5f0a0508d0dca8bb98c7f7fd3772fc943ac3f53d5ab18a218d32c0/keyring-25.4.1-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_keyring_sdist_b07ebc55": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "keyring-25.4.1.tar.gz", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "keyring==25.4.1", + "sha256": "b07ebc55f3e8ed86ac81dd31ef14e81ace9dd9c3d4b5d77a6e9a2016d0d71a1b", + "urls": [ + "https://files.pythonhosted.org/packages/a5/1c/2bdbcfd5d59dc6274ffb175bc29aa07ecbfab196830e0cfbde7bd861a2ea/keyring-25.4.1.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_markdown_it_py_py3_none_any_35521684": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "markdown_it_py-3.0.0-py3-none-any.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "markdown-it-py==3.0.0", + "sha256": "355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1", + "urls": [ + "https://files.pythonhosted.org/packages/42/d7/1ec15b46af6af88f19b8e5ffea08fa375d433c998b8a7639e76935c14f1f/markdown_it_py-3.0.0-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_markdown_it_py_sdist_e3f60a94": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "markdown-it-py-3.0.0.tar.gz", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "markdown-it-py==3.0.0", + "sha256": "e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb", + "urls": [ + "https://files.pythonhosted.org/packages/38/71/3b932df36c1a044d397a1f92d1cf91ee0a503d91e470cbd670aa66b07ed0/markdown-it-py-3.0.0.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_mdurl_py3_none_any_84008a41": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "mdurl-0.1.2-py3-none-any.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "mdurl==0.1.2", + "sha256": "84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", + "urls": [ + "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_mdurl_sdist_bb413d29": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "mdurl-0.1.2.tar.gz", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "mdurl==0.1.2", + "sha256": "bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", + "urls": [ + "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_more_itertools_py3_none_any_037b0d32": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "more_itertools-10.5.0-py3-none-any.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "more-itertools==10.5.0", + "sha256": "037b0d3203ce90cca8ab1defbbdac29d5f993fc20131f3664dc8d6acfa872aef", + "urls": [ + "https://files.pythonhosted.org/packages/48/7e/3a64597054a70f7c86eb0a7d4fc315b8c1ab932f64883a297bdffeb5f967/more_itertools-10.5.0-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_more_itertools_sdist_5482bfef": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "more-itertools-10.5.0.tar.gz", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "more-itertools==10.5.0", + "sha256": "5482bfef7849c25dc3c6dd53a6173ae4795da2a41a80faea6700d9f5846c5da6", + "urls": [ + "https://files.pythonhosted.org/packages/51/78/65922308c4248e0eb08ebcbe67c95d48615cc6f27854b6f2e57143e9178f/more-itertools-10.5.0.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_nh3_cp37_abi3_macosx_10_12_x86_64_14c5a72e": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "nh3-0.2.18-cp37-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "nh3==0.2.18", + "sha256": "14c5a72e9fe82aea5fe3072116ad4661af5cf8e8ff8fc5ad3450f123e4925e86", + "urls": [ + "https://files.pythonhosted.org/packages/b3/89/1daff5d9ba5a95a157c092c7c5f39b8dd2b1ddb4559966f808d31cfb67e0/nh3-0.2.18-cp37-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl" + ] + } + }, + "rules_python_publish_deps_311_nh3_cp37_abi3_macosx_10_12_x86_64_7b7c2a3c": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "nh3-0.2.18-cp37-abi3-macosx_10_12_x86_64.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "nh3==0.2.18", + "sha256": "7b7c2a3c9eb1a827d42539aa64091640bd275b81e097cd1d8d82ef91ffa2e811", + "urls": [ + "https://files.pythonhosted.org/packages/2c/b6/42fc3c69cabf86b6b81e4c051a9b6e249c5ba9f8155590222c2622961f58/nh3-0.2.18-cp37-abi3-macosx_10_12_x86_64.whl" + ] + } + }, + "rules_python_publish_deps_311_nh3_cp37_abi3_manylinux_2_17_aarch64_42c64511": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "nh3-0.2.18-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "nh3==0.2.18", + "sha256": "42c64511469005058cd17cc1537578eac40ae9f7200bedcfd1fc1a05f4f8c200", + "urls": [ + "https://files.pythonhosted.org/packages/45/b9/833f385403abaf0023c6547389ec7a7acf141ddd9d1f21573723a6eab39a/nh3-0.2.18-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl" + ] + } + }, + "rules_python_publish_deps_311_nh3_cp37_abi3_manylinux_2_17_armv7l_0411beb0": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "nh3-0.2.18-cp37-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "nh3==0.2.18", + "sha256": "0411beb0589eacb6734f28d5497ca2ed379eafab8ad8c84b31bb5c34072b7164", + "urls": [ + "https://files.pythonhosted.org/packages/05/2b/85977d9e11713b5747595ee61f381bc820749daf83f07b90b6c9964cf932/nh3-0.2.18-cp37-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl" + ] + } + }, + "rules_python_publish_deps_311_nh3_cp37_abi3_manylinux_2_17_ppc64_5f36b271": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "nh3-0.2.18-cp37-abi3-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "nh3==0.2.18", + "sha256": "5f36b271dae35c465ef5e9090e1fdaba4a60a56f0bb0ba03e0932a66f28b9189", + "urls": [ + "https://files.pythonhosted.org/packages/72/f2/5c894d5265ab80a97c68ca36f25c8f6f0308abac649aaf152b74e7e854a8/nh3-0.2.18-cp37-abi3-manylinux_2_17_ppc64.manylinux2014_ppc64.whl" + ] + } + }, + "rules_python_publish_deps_311_nh3_cp37_abi3_manylinux_2_17_ppc64le_34c03fa7": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "nh3-0.2.18-cp37-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "nh3==0.2.18", + "sha256": "34c03fa78e328c691f982b7c03d4423bdfd7da69cd707fe572f544cf74ac23ad", + "urls": [ + "https://files.pythonhosted.org/packages/ab/a7/375afcc710dbe2d64cfbd69e31f82f3e423d43737258af01f6a56d844085/nh3-0.2.18-cp37-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl" + ] + } + }, + "rules_python_publish_deps_311_nh3_cp37_abi3_manylinux_2_17_s390x_19aaba96": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "nh3-0.2.18-cp37-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "nh3==0.2.18", + "sha256": "19aaba96e0f795bd0a6c56291495ff59364f4300d4a39b29a0abc9cb3774a84b", + "urls": [ + "https://files.pythonhosted.org/packages/c2/a8/3bb02d0c60a03ad3a112b76c46971e9480efa98a8946677b5a59f60130ca/nh3-0.2.18-cp37-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl" + ] + } + }, + "rules_python_publish_deps_311_nh3_cp37_abi3_manylinux_2_17_x86_64_de3ceed6": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "nh3-0.2.18-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "nh3==0.2.18", + "sha256": "de3ceed6e661954871d6cd78b410213bdcb136f79aafe22aa7182e028b8c7307", + "urls": [ + "https://files.pythonhosted.org/packages/1b/63/6ab90d0e5225ab9780f6c9fb52254fa36b52bb7c188df9201d05b647e5e1/nh3-0.2.18-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl" + ] + } + }, + "rules_python_publish_deps_311_nh3_cp37_abi3_musllinux_1_2_aarch64_f0eca9ca": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "nh3-0.2.18-cp37-abi3-musllinux_1_2_aarch64.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "nh3==0.2.18", + "sha256": "f0eca9ca8628dbb4e916ae2491d72957fdd35f7a5d326b7032a345f111ac07fe", + "urls": [ + "https://files.pythonhosted.org/packages/a3/da/0c4e282bc3cff4a0adf37005fa1fb42257673fbc1bbf7d1ff639ec3d255a/nh3-0.2.18-cp37-abi3-musllinux_1_2_aarch64.whl" + ] + } + }, + "rules_python_publish_deps_311_nh3_cp37_abi3_musllinux_1_2_armv7l_3a157ab1": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "nh3-0.2.18-cp37-abi3-musllinux_1_2_armv7l.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "nh3==0.2.18", + "sha256": "3a157ab149e591bb638a55c8c6bcb8cdb559c8b12c13a8affaba6cedfe51713a", + "urls": [ + "https://files.pythonhosted.org/packages/de/81/c291231463d21da5f8bba82c8167a6d6893cc5419b0639801ee5d3aeb8a9/nh3-0.2.18-cp37-abi3-musllinux_1_2_armv7l.whl" + ] + } + }, + "rules_python_publish_deps_311_nh3_cp37_abi3_musllinux_1_2_x86_64_36c95d4b": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "nh3-0.2.18-cp37-abi3-musllinux_1_2_x86_64.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "nh3==0.2.18", + "sha256": "36c95d4b70530b320b365659bb5034341316e6a9b30f0b25fa9c9eff4c27a204", + "urls": [ + "https://files.pythonhosted.org/packages/eb/61/73a007c74c37895fdf66e0edcd881f5eaa17a348ff02f4bb4bc906d61085/nh3-0.2.18-cp37-abi3-musllinux_1_2_x86_64.whl" + ] + } + }, + "rules_python_publish_deps_311_nh3_cp37_abi3_win_amd64_8ce0f819": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "nh3-0.2.18-cp37-abi3-win_amd64.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "nh3==0.2.18", + "sha256": "8ce0f819d2f1933953fca255db2471ad58184a60508f03e6285e5114b6254844", + "urls": [ + "https://files.pythonhosted.org/packages/26/8d/53c5b19c4999bdc6ba95f246f4ef35ca83d7d7423e5e38be43ad66544e5d/nh3-0.2.18-cp37-abi3-win_amd64.whl" + ] + } + }, + "rules_python_publish_deps_311_nh3_sdist_94a16692": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "nh3-0.2.18.tar.gz", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "nh3==0.2.18", + "sha256": "94a166927e53972a9698af9542ace4e38b9de50c34352b962f4d9a7d4c927af4", + "urls": [ + "https://files.pythonhosted.org/packages/62/73/10df50b42ddb547a907deeb2f3c9823022580a7a47281e8eae8e003a9639/nh3-0.2.18.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_pkginfo_py3_none_any_889a6da2": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "pkginfo-1.10.0-py3-none-any.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "pkginfo==1.10.0", + "sha256": "889a6da2ed7ffc58ab5b900d888ddce90bce912f2d2de1dc1c26f4cb9fe65097", + "urls": [ + "https://files.pythonhosted.org/packages/56/09/054aea9b7534a15ad38a363a2bd974c20646ab1582a387a95b8df1bfea1c/pkginfo-1.10.0-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_pkginfo_sdist_5df73835": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "pkginfo-1.10.0.tar.gz", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "pkginfo==1.10.0", + "sha256": "5df73835398d10db79f8eecd5cd86b1f6d29317589ea70796994d49399af6297", + "urls": [ + "https://files.pythonhosted.org/packages/2f/72/347ec5be4adc85c182ed2823d8d1c7b51e13b9a6b0c1aae59582eca652df/pkginfo-1.10.0.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_pycparser_py3_none_any_c3702b6d": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64" + ], + "filename": "pycparser-2.22-py3-none-any.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "pycparser==2.22", + "sha256": "c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc", + "urls": [ + "https://files.pythonhosted.org/packages/13/a3/a812df4e2dd5696d1f351d58b8fe16a405b234ad2886a0dab9183fb78109/pycparser-2.22-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_pycparser_sdist_491c8be9": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "pycparser-2.22.tar.gz", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "pycparser==2.22", + "sha256": "491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6", + "urls": [ + "https://files.pythonhosted.org/packages/1d/b2/31537cf4b1ca988837256c910a668b553fceb8f069bedc4b1c826024b52c/pycparser-2.22.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_pygments_py3_none_any_b8e6aca0": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "pygments-2.18.0-py3-none-any.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "pygments==2.18.0", + "sha256": "b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a", + "urls": [ + "https://files.pythonhosted.org/packages/f7/3f/01c8b82017c199075f8f788d0d906b9ffbbc5a47dc9918a945e13d5a2bda/pygments-2.18.0-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_pygments_sdist_786ff802": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "pygments-2.18.0.tar.gz", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "pygments==2.18.0", + "sha256": "786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199", + "urls": [ + "https://files.pythonhosted.org/packages/8e/62/8336eff65bcbc8e4cb5d05b55faf041285951b6e80f33e2bff2024788f31/pygments-2.18.0.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_pywin32_ctypes_py3_none_any_8a151337": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_windows_x86_64" + ], + "filename": "pywin32_ctypes-0.2.3-py3-none-any.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "pywin32-ctypes==0.2.3", + "sha256": "8a1513379d709975552d202d942d9837758905c8d01eb82b8bcc30918929e7b8", + "urls": [ + "https://files.pythonhosted.org/packages/de/3d/8161f7711c017e01ac9f008dfddd9410dff3674334c233bde66e7ba65bbf/pywin32_ctypes-0.2.3-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_pywin32_ctypes_sdist_d162dc04": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "pywin32-ctypes-0.2.3.tar.gz", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "pywin32-ctypes==0.2.3", + "sha256": "d162dc04946d704503b2edc4d55f3dba5c1d539ead017afa00142c38b9885755", + "urls": [ + "https://files.pythonhosted.org/packages/85/9f/01a1a99704853cb63f253eea009390c88e7131c67e66a0a02099a8c917cb/pywin32-ctypes-0.2.3.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_readme_renderer_py3_none_any_2fbca89b": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "readme_renderer-44.0-py3-none-any.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "readme-renderer==44.0", + "sha256": "2fbca89b81a08526aadf1357a8c2ae889ec05fb03f5da67f9769c9a592166151", + "urls": [ + "https://files.pythonhosted.org/packages/e1/67/921ec3024056483db83953ae8e48079ad62b92db7880013ca77632921dd0/readme_renderer-44.0-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_readme_renderer_sdist_8712034e": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "readme_renderer-44.0.tar.gz", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "readme-renderer==44.0", + "sha256": "8712034eabbfa6805cacf1402b4eeb2a73028f72d1166d6f5cb7f9c047c5d1e1", + "urls": [ + "https://files.pythonhosted.org/packages/5a/a9/104ec9234c8448c4379768221ea6df01260cd6c2ce13182d4eac531c8342/readme_renderer-44.0.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_requests_py3_none_any_70761cfe": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "requests-2.32.3-py3-none-any.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "requests==2.32.3", + "sha256": "70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6", + "urls": [ + "https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_requests_sdist_55365417": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "requests-2.32.3.tar.gz", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "requests==2.32.3", + "sha256": "55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", + "urls": [ + "https://files.pythonhosted.org/packages/63/70/2bf7780ad2d390a8d301ad0b550f1581eadbd9a20f896afe06353c2a2913/requests-2.32.3.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_requests_toolbelt_py2_none_any_cccfdd66": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "requests_toolbelt-1.0.0-py2.py3-none-any.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "requests-toolbelt==1.0.0", + "sha256": "cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06", + "urls": [ + "https://files.pythonhosted.org/packages/3f/51/d4db610ef29373b879047326cbf6fa98b6c1969d6f6dc423279de2b1be2c/requests_toolbelt-1.0.0-py2.py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_requests_toolbelt_sdist_7681a0a3": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "requests-toolbelt-1.0.0.tar.gz", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "requests-toolbelt==1.0.0", + "sha256": "7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6", + "urls": [ + "https://files.pythonhosted.org/packages/f3/61/d7545dafb7ac2230c70d38d31cbfe4cc64f7144dc41f6e4e4b78ecd9f5bb/requests-toolbelt-1.0.0.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_rfc3986_py2_none_any_50b1502b": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "rfc3986-2.0.0-py2.py3-none-any.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "rfc3986==2.0.0", + "sha256": "50b1502b60e289cb37883f3dfd34532b8873c7de9f49bb546641ce9cbd256ebd", + "urls": [ + "https://files.pythonhosted.org/packages/ff/9a/9afaade874b2fa6c752c36f1548f718b5b83af81ed9b76628329dab81c1b/rfc3986-2.0.0-py2.py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_rfc3986_sdist_97aacf9d": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "rfc3986-2.0.0.tar.gz", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "rfc3986==2.0.0", + "sha256": "97aacf9dbd4bfd829baad6e6309fa6573aaf1be3f6fa735c8ab05e46cecb261c", + "urls": [ + "https://files.pythonhosted.org/packages/85/40/1520d68bfa07ab5a6f065a186815fb6610c86fe957bc065754e47f7b0840/rfc3986-2.0.0.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_rich_py3_none_any_9836f509": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "rich-13.9.3-py3-none-any.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "rich==13.9.3", + "sha256": "9836f5096eb2172c9e77df411c1b009bace4193d6a481d534fea75ebba758283", + "urls": [ + "https://files.pythonhosted.org/packages/9a/e2/10e9819cf4a20bd8ea2f5dabafc2e6bf4a78d6a0965daeb60a4b34d1c11f/rich-13.9.3-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_rich_sdist_bc1e01b8": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "rich-13.9.3.tar.gz", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "rich==13.9.3", + "sha256": "bc1e01b899537598cf02579d2b9f4a415104d3fc439313a7a2c165d76557a08e", + "urls": [ + "https://files.pythonhosted.org/packages/d9/e9/cf9ef5245d835065e6673781dbd4b8911d352fb770d56cf0879cf11b7ee1/rich-13.9.3.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_secretstorage_py3_none_any_f356e662": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64" + ], + "filename": "SecretStorage-3.3.3-py3-none-any.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "secretstorage==3.3.3", + "sha256": "f356e6628222568e3af06f2eba8df495efa13b3b63081dafd4f7d9a7b7bc9f99", + "urls": [ + "https://files.pythonhosted.org/packages/54/24/b4293291fa1dd830f353d2cb163295742fa87f179fcc8a20a306a81978b7/SecretStorage-3.3.3-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_secretstorage_sdist_2403533e": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "SecretStorage-3.3.3.tar.gz", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "secretstorage==3.3.3", + "sha256": "2403533ef369eca6d2ba81718576c5e0f564d5cca1b58f73a8b23e7d4eeebd77", + "urls": [ + "https://files.pythonhosted.org/packages/53/a4/f48c9d79cb507ed1373477dbceaba7401fd8a23af63b837fa61f1dcd3691/SecretStorage-3.3.3.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_twine_py3_none_any_215dbe7b": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "twine-5.1.1-py3-none-any.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "twine==5.1.1", + "sha256": "215dbe7b4b94c2c50a7315c0275d2258399280fbb7d04182c7e55e24b5f93997", + "urls": [ + "https://files.pythonhosted.org/packages/5d/ec/00f9d5fd040ae29867355e559a94e9a8429225a0284a3f5f091a3878bfc0/twine-5.1.1-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_twine_sdist_9aa08251": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "twine-5.1.1.tar.gz", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "twine==5.1.1", + "sha256": "9aa0825139c02b3434d913545c7b847a21c835e11597f5255842d457da2322db", + "urls": [ + "https://files.pythonhosted.org/packages/77/68/bd982e5e949ef8334e6f7dcf76ae40922a8750aa2e347291ae1477a4782b/twine-5.1.1.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_urllib3_py3_none_any_ca899ca0": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "urllib3-2.2.3-py3-none-any.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "urllib3==2.2.3", + "sha256": "ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac", + "urls": [ + "https://files.pythonhosted.org/packages/ce/d9/5f4c13cecde62396b0d3fe530a50ccea91e7dfc1ccf0e09c228841bb5ba8/urllib3-2.2.3-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_urllib3_sdist_e7d814a8": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "urllib3-2.2.3.tar.gz", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "urllib3==2.2.3", + "sha256": "e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9", + "urls": [ + "https://files.pythonhosted.org/packages/ed/63/22ba4ebfe7430b76388e7cd448d5478814d3032121827c12a2cc287e2260/urllib3-2.2.3.tar.gz" + ] + } + }, + "rules_python_publish_deps_311_zipp_py3_none_any_a817ac80": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "filename": "zipp-3.20.2-py3-none-any.whl", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "zipp==3.20.2", + "sha256": "a817ac80d6cf4b23bf7f2828b7cabf326f15a001bea8b1f9b49631780ba28350", + "urls": [ + "https://files.pythonhosted.org/packages/62/8b/5ba542fa83c90e09eac972fc9baca7a88e7e7ca4b221a89251954019308b/zipp-3.20.2-py3-none-any.whl" + ] + } + }, + "rules_python_publish_deps_311_zipp_sdist_bc9eb26f": { + "repoRuleId": "@@rules_python+//python/private/pypi:whl_library.bzl%whl_library", + "attributes": { + "dep_template": "@rules_python_publish_deps//{name}:{target}", + "experimental_target_platforms": [ + "cp311_linux_aarch64", + "cp311_linux_arm", + "cp311_linux_ppc", + "cp311_linux_s390x", + "cp311_linux_x86_64", + "cp311_osx_aarch64", + "cp311_osx_x86_64", + "cp311_windows_x86_64" + ], + "extra_pip_args": [ + "--index-url", + "https://pypi.org/simple" + ], + "filename": "zipp-3.20.2.tar.gz", + "python_interpreter_target": "@@rules_python++python+python_3_11_host//:python", + "repo": "rules_python_publish_deps_311", + "requirement": "zipp==3.20.2", + "sha256": "bc9eb26f4506fda01b81bcde0ca78103b6e62f991b381fec825435c836edbc29", + "urls": [ + "https://files.pythonhosted.org/packages/54/bf/5c0000c44ebc80123ecbdddba1f5dcd94a5ada602a9c225d84b5aaa55e86/zipp-3.20.2.tar.gz" + ] + } + }, + "rules_python_publish_deps": { + "repoRuleId": "@@rules_python+//python/private/pypi:hub_repository.bzl%hub_repository", + "attributes": { + "repo_name": "rules_python_publish_deps", + "extra_hub_aliases": {}, + "whl_map": { + "backports_tarfile": "[{\"filename\":\"backports.tarfile-1.2.0-py3-none-any.whl\",\"repo\":\"rules_python_publish_deps_311_backports_tarfile_py3_none_any_77e284d7\",\"version\":\"3.11\"},{\"filename\":\"backports_tarfile-1.2.0.tar.gz\",\"repo\":\"rules_python_publish_deps_311_backports_tarfile_sdist_d75e02c2\",\"version\":\"3.11\"}]", + "certifi": "[{\"filename\":\"certifi-2024.8.30-py3-none-any.whl\",\"repo\":\"rules_python_publish_deps_311_certifi_py3_none_any_922820b5\",\"version\":\"3.11\"},{\"filename\":\"certifi-2024.8.30.tar.gz\",\"repo\":\"rules_python_publish_deps_311_certifi_sdist_bec941d2\",\"version\":\"3.11\"}]", + "cffi": "[{\"filename\":\"cffi-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl\",\"repo\":\"rules_python_publish_deps_311_cffi_cp311_cp311_manylinux_2_17_aarch64_a1ed2dd2\",\"version\":\"3.11\"},{\"filename\":\"cffi-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl\",\"repo\":\"rules_python_publish_deps_311_cffi_cp311_cp311_manylinux_2_17_ppc64le_46bf4316\",\"version\":\"3.11\"},{\"filename\":\"cffi-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl\",\"repo\":\"rules_python_publish_deps_311_cffi_cp311_cp311_manylinux_2_17_s390x_a24ed04c\",\"version\":\"3.11\"},{\"filename\":\"cffi-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl\",\"repo\":\"rules_python_publish_deps_311_cffi_cp311_cp311_manylinux_2_17_x86_64_610faea7\",\"version\":\"3.11\"},{\"filename\":\"cffi-1.17.1-cp311-cp311-musllinux_1_1_aarch64.whl\",\"repo\":\"rules_python_publish_deps_311_cffi_cp311_cp311_musllinux_1_1_aarch64_a9b15d49\",\"version\":\"3.11\"},{\"filename\":\"cffi-1.17.1-cp311-cp311-musllinux_1_1_x86_64.whl\",\"repo\":\"rules_python_publish_deps_311_cffi_cp311_cp311_musllinux_1_1_x86_64_fc48c783\",\"version\":\"3.11\"},{\"filename\":\"cffi-1.17.1.tar.gz\",\"repo\":\"rules_python_publish_deps_311_cffi_sdist_1c39c601\",\"version\":\"3.11\"}]", + "charset_normalizer": "[{\"filename\":\"charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl\",\"repo\":\"rules_python_publish_deps_311_charset_normalizer_cp311_cp311_macosx_10_9_universal2_0d99dd8f\",\"version\":\"3.11\"},{\"filename\":\"charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl\",\"repo\":\"rules_python_publish_deps_311_charset_normalizer_cp311_cp311_macosx_10_9_x86_64_c57516e5\",\"version\":\"3.11\"},{\"filename\":\"charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl\",\"repo\":\"rules_python_publish_deps_311_charset_normalizer_cp311_cp311_macosx_11_0_arm64_6dba5d19\",\"version\":\"3.11\"},{\"filename\":\"charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl\",\"repo\":\"rules_python_publish_deps_311_charset_normalizer_cp311_cp311_manylinux_2_17_aarch64_bf4475b8\",\"version\":\"3.11\"},{\"filename\":\"charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl\",\"repo\":\"rules_python_publish_deps_311_charset_normalizer_cp311_cp311_manylinux_2_17_ppc64le_ce031db0\",\"version\":\"3.11\"},{\"filename\":\"charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl\",\"repo\":\"rules_python_publish_deps_311_charset_normalizer_cp311_cp311_manylinux_2_17_s390x_8ff4e7cd\",\"version\":\"3.11\"},{\"filename\":\"charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl\",\"repo\":\"rules_python_publish_deps_311_charset_normalizer_cp311_cp311_manylinux_2_17_x86_64_3710a975\",\"version\":\"3.11\"},{\"filename\":\"charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl\",\"repo\":\"rules_python_publish_deps_311_charset_normalizer_cp311_cp311_musllinux_1_2_aarch64_47334db7\",\"version\":\"3.11\"},{\"filename\":\"charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl\",\"repo\":\"rules_python_publish_deps_311_charset_normalizer_cp311_cp311_musllinux_1_2_ppc64le_f1a2f519\",\"version\":\"3.11\"},{\"filename\":\"charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl\",\"repo\":\"rules_python_publish_deps_311_charset_normalizer_cp311_cp311_musllinux_1_2_s390x_63bc5c4a\",\"version\":\"3.11\"},{\"filename\":\"charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl\",\"repo\":\"rules_python_publish_deps_311_charset_normalizer_cp311_cp311_musllinux_1_2_x86_64_bcb4f8ea\",\"version\":\"3.11\"},{\"filename\":\"charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl\",\"repo\":\"rules_python_publish_deps_311_charset_normalizer_cp311_cp311_win_amd64_cee4373f\",\"version\":\"3.11\"},{\"filename\":\"charset_normalizer-3.4.0-py3-none-any.whl\",\"repo\":\"rules_python_publish_deps_311_charset_normalizer_py3_none_any_fe9f97fe\",\"version\":\"3.11\"},{\"filename\":\"charset_normalizer-3.4.0.tar.gz\",\"repo\":\"rules_python_publish_deps_311_charset_normalizer_sdist_223217c3\",\"version\":\"3.11\"}]", + "cryptography": "[{\"filename\":\"cryptography-43.0.3-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl\",\"repo\":\"rules_python_publish_deps_311_cryptography_cp39_abi3_manylinux_2_17_aarch64_846da004\",\"version\":\"3.11\"},{\"filename\":\"cryptography-43.0.3-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl\",\"repo\":\"rules_python_publish_deps_311_cryptography_cp39_abi3_manylinux_2_17_x86_64_0f996e72\",\"version\":\"3.11\"},{\"filename\":\"cryptography-43.0.3-cp39-abi3-manylinux_2_28_aarch64.whl\",\"repo\":\"rules_python_publish_deps_311_cryptography_cp39_abi3_manylinux_2_28_aarch64_f7b178f1\",\"version\":\"3.11\"},{\"filename\":\"cryptography-43.0.3-cp39-abi3-manylinux_2_28_x86_64.whl\",\"repo\":\"rules_python_publish_deps_311_cryptography_cp39_abi3_manylinux_2_28_x86_64_c2e6fc39\",\"version\":\"3.11\"},{\"filename\":\"cryptography-43.0.3-cp39-abi3-musllinux_1_2_aarch64.whl\",\"repo\":\"rules_python_publish_deps_311_cryptography_cp39_abi3_musllinux_1_2_aarch64_e1be4655\",\"version\":\"3.11\"},{\"filename\":\"cryptography-43.0.3-cp39-abi3-musllinux_1_2_x86_64.whl\",\"repo\":\"rules_python_publish_deps_311_cryptography_cp39_abi3_musllinux_1_2_x86_64_df6b6c6d\",\"version\":\"3.11\"},{\"filename\":\"cryptography-43.0.3.tar.gz\",\"repo\":\"rules_python_publish_deps_311_cryptography_sdist_315b9001\",\"version\":\"3.11\"}]", + "docutils": "[{\"filename\":\"docutils-0.21.2-py3-none-any.whl\",\"repo\":\"rules_python_publish_deps_311_docutils_py3_none_any_dafca5b9\",\"version\":\"3.11\"},{\"filename\":\"docutils-0.21.2.tar.gz\",\"repo\":\"rules_python_publish_deps_311_docutils_sdist_3a6b1873\",\"version\":\"3.11\"}]", + "idna": "[{\"filename\":\"idna-3.10-py3-none-any.whl\",\"repo\":\"rules_python_publish_deps_311_idna_py3_none_any_946d195a\",\"version\":\"3.11\"},{\"filename\":\"idna-3.10.tar.gz\",\"repo\":\"rules_python_publish_deps_311_idna_sdist_12f65c9b\",\"version\":\"3.11\"}]", + "importlib_metadata": "[{\"filename\":\"importlib_metadata-8.5.0-py3-none-any.whl\",\"repo\":\"rules_python_publish_deps_311_importlib_metadata_py3_none_any_45e54197\",\"version\":\"3.11\"},{\"filename\":\"importlib_metadata-8.5.0.tar.gz\",\"repo\":\"rules_python_publish_deps_311_importlib_metadata_sdist_71522656\",\"version\":\"3.11\"}]", + "jaraco_classes": "[{\"filename\":\"jaraco.classes-3.4.0-py3-none-any.whl\",\"repo\":\"rules_python_publish_deps_311_jaraco_classes_py3_none_any_f662826b\",\"version\":\"3.11\"},{\"filename\":\"jaraco.classes-3.4.0.tar.gz\",\"repo\":\"rules_python_publish_deps_311_jaraco_classes_sdist_47a024b5\",\"version\":\"3.11\"}]", + "jaraco_context": "[{\"filename\":\"jaraco.context-6.0.1-py3-none-any.whl\",\"repo\":\"rules_python_publish_deps_311_jaraco_context_py3_none_any_f797fc48\",\"version\":\"3.11\"},{\"filename\":\"jaraco_context-6.0.1.tar.gz\",\"repo\":\"rules_python_publish_deps_311_jaraco_context_sdist_9bae4ea5\",\"version\":\"3.11\"}]", + "jaraco_functools": "[{\"filename\":\"jaraco.functools-4.1.0-py3-none-any.whl\",\"repo\":\"rules_python_publish_deps_311_jaraco_functools_py3_none_any_ad159f13\",\"version\":\"3.11\"},{\"filename\":\"jaraco_functools-4.1.0.tar.gz\",\"repo\":\"rules_python_publish_deps_311_jaraco_functools_sdist_70f7e0e2\",\"version\":\"3.11\"}]", + "jeepney": "[{\"filename\":\"jeepney-0.8.0-py3-none-any.whl\",\"repo\":\"rules_python_publish_deps_311_jeepney_py3_none_any_c0a454ad\",\"version\":\"3.11\"},{\"filename\":\"jeepney-0.8.0.tar.gz\",\"repo\":\"rules_python_publish_deps_311_jeepney_sdist_5efe48d2\",\"version\":\"3.11\"}]", + "keyring": "[{\"filename\":\"keyring-25.4.1-py3-none-any.whl\",\"repo\":\"rules_python_publish_deps_311_keyring_py3_none_any_5426f817\",\"version\":\"3.11\"},{\"filename\":\"keyring-25.4.1.tar.gz\",\"repo\":\"rules_python_publish_deps_311_keyring_sdist_b07ebc55\",\"version\":\"3.11\"}]", + "markdown_it_py": "[{\"filename\":\"markdown-it-py-3.0.0.tar.gz\",\"repo\":\"rules_python_publish_deps_311_markdown_it_py_sdist_e3f60a94\",\"version\":\"3.11\"},{\"filename\":\"markdown_it_py-3.0.0-py3-none-any.whl\",\"repo\":\"rules_python_publish_deps_311_markdown_it_py_py3_none_any_35521684\",\"version\":\"3.11\"}]", + "mdurl": "[{\"filename\":\"mdurl-0.1.2-py3-none-any.whl\",\"repo\":\"rules_python_publish_deps_311_mdurl_py3_none_any_84008a41\",\"version\":\"3.11\"},{\"filename\":\"mdurl-0.1.2.tar.gz\",\"repo\":\"rules_python_publish_deps_311_mdurl_sdist_bb413d29\",\"version\":\"3.11\"}]", + "more_itertools": "[{\"filename\":\"more-itertools-10.5.0.tar.gz\",\"repo\":\"rules_python_publish_deps_311_more_itertools_sdist_5482bfef\",\"version\":\"3.11\"},{\"filename\":\"more_itertools-10.5.0-py3-none-any.whl\",\"repo\":\"rules_python_publish_deps_311_more_itertools_py3_none_any_037b0d32\",\"version\":\"3.11\"}]", + "nh3": "[{\"filename\":\"nh3-0.2.18-cp37-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl\",\"repo\":\"rules_python_publish_deps_311_nh3_cp37_abi3_macosx_10_12_x86_64_14c5a72e\",\"version\":\"3.11\"},{\"filename\":\"nh3-0.2.18-cp37-abi3-macosx_10_12_x86_64.whl\",\"repo\":\"rules_python_publish_deps_311_nh3_cp37_abi3_macosx_10_12_x86_64_7b7c2a3c\",\"version\":\"3.11\"},{\"filename\":\"nh3-0.2.18-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl\",\"repo\":\"rules_python_publish_deps_311_nh3_cp37_abi3_manylinux_2_17_aarch64_42c64511\",\"version\":\"3.11\"},{\"filename\":\"nh3-0.2.18-cp37-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl\",\"repo\":\"rules_python_publish_deps_311_nh3_cp37_abi3_manylinux_2_17_armv7l_0411beb0\",\"version\":\"3.11\"},{\"filename\":\"nh3-0.2.18-cp37-abi3-manylinux_2_17_ppc64.manylinux2014_ppc64.whl\",\"repo\":\"rules_python_publish_deps_311_nh3_cp37_abi3_manylinux_2_17_ppc64_5f36b271\",\"version\":\"3.11\"},{\"filename\":\"nh3-0.2.18-cp37-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl\",\"repo\":\"rules_python_publish_deps_311_nh3_cp37_abi3_manylinux_2_17_ppc64le_34c03fa7\",\"version\":\"3.11\"},{\"filename\":\"nh3-0.2.18-cp37-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl\",\"repo\":\"rules_python_publish_deps_311_nh3_cp37_abi3_manylinux_2_17_s390x_19aaba96\",\"version\":\"3.11\"},{\"filename\":\"nh3-0.2.18-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl\",\"repo\":\"rules_python_publish_deps_311_nh3_cp37_abi3_manylinux_2_17_x86_64_de3ceed6\",\"version\":\"3.11\"},{\"filename\":\"nh3-0.2.18-cp37-abi3-musllinux_1_2_aarch64.whl\",\"repo\":\"rules_python_publish_deps_311_nh3_cp37_abi3_musllinux_1_2_aarch64_f0eca9ca\",\"version\":\"3.11\"},{\"filename\":\"nh3-0.2.18-cp37-abi3-musllinux_1_2_armv7l.whl\",\"repo\":\"rules_python_publish_deps_311_nh3_cp37_abi3_musllinux_1_2_armv7l_3a157ab1\",\"version\":\"3.11\"},{\"filename\":\"nh3-0.2.18-cp37-abi3-musllinux_1_2_x86_64.whl\",\"repo\":\"rules_python_publish_deps_311_nh3_cp37_abi3_musllinux_1_2_x86_64_36c95d4b\",\"version\":\"3.11\"},{\"filename\":\"nh3-0.2.18-cp37-abi3-win_amd64.whl\",\"repo\":\"rules_python_publish_deps_311_nh3_cp37_abi3_win_amd64_8ce0f819\",\"version\":\"3.11\"},{\"filename\":\"nh3-0.2.18.tar.gz\",\"repo\":\"rules_python_publish_deps_311_nh3_sdist_94a16692\",\"version\":\"3.11\"}]", + "pkginfo": "[{\"filename\":\"pkginfo-1.10.0-py3-none-any.whl\",\"repo\":\"rules_python_publish_deps_311_pkginfo_py3_none_any_889a6da2\",\"version\":\"3.11\"},{\"filename\":\"pkginfo-1.10.0.tar.gz\",\"repo\":\"rules_python_publish_deps_311_pkginfo_sdist_5df73835\",\"version\":\"3.11\"}]", + "pycparser": "[{\"filename\":\"pycparser-2.22-py3-none-any.whl\",\"repo\":\"rules_python_publish_deps_311_pycparser_py3_none_any_c3702b6d\",\"version\":\"3.11\"},{\"filename\":\"pycparser-2.22.tar.gz\",\"repo\":\"rules_python_publish_deps_311_pycparser_sdist_491c8be9\",\"version\":\"3.11\"}]", + "pygments": "[{\"filename\":\"pygments-2.18.0-py3-none-any.whl\",\"repo\":\"rules_python_publish_deps_311_pygments_py3_none_any_b8e6aca0\",\"version\":\"3.11\"},{\"filename\":\"pygments-2.18.0.tar.gz\",\"repo\":\"rules_python_publish_deps_311_pygments_sdist_786ff802\",\"version\":\"3.11\"}]", + "pywin32_ctypes": "[{\"filename\":\"pywin32-ctypes-0.2.3.tar.gz\",\"repo\":\"rules_python_publish_deps_311_pywin32_ctypes_sdist_d162dc04\",\"version\":\"3.11\"},{\"filename\":\"pywin32_ctypes-0.2.3-py3-none-any.whl\",\"repo\":\"rules_python_publish_deps_311_pywin32_ctypes_py3_none_any_8a151337\",\"version\":\"3.11\"}]", + "readme_renderer": "[{\"filename\":\"readme_renderer-44.0-py3-none-any.whl\",\"repo\":\"rules_python_publish_deps_311_readme_renderer_py3_none_any_2fbca89b\",\"version\":\"3.11\"},{\"filename\":\"readme_renderer-44.0.tar.gz\",\"repo\":\"rules_python_publish_deps_311_readme_renderer_sdist_8712034e\",\"version\":\"3.11\"}]", + "requests": "[{\"filename\":\"requests-2.32.3-py3-none-any.whl\",\"repo\":\"rules_python_publish_deps_311_requests_py3_none_any_70761cfe\",\"version\":\"3.11\"},{\"filename\":\"requests-2.32.3.tar.gz\",\"repo\":\"rules_python_publish_deps_311_requests_sdist_55365417\",\"version\":\"3.11\"}]", + "requests_toolbelt": "[{\"filename\":\"requests-toolbelt-1.0.0.tar.gz\",\"repo\":\"rules_python_publish_deps_311_requests_toolbelt_sdist_7681a0a3\",\"version\":\"3.11\"},{\"filename\":\"requests_toolbelt-1.0.0-py2.py3-none-any.whl\",\"repo\":\"rules_python_publish_deps_311_requests_toolbelt_py2_none_any_cccfdd66\",\"version\":\"3.11\"}]", + "rfc3986": "[{\"filename\":\"rfc3986-2.0.0-py2.py3-none-any.whl\",\"repo\":\"rules_python_publish_deps_311_rfc3986_py2_none_any_50b1502b\",\"version\":\"3.11\"},{\"filename\":\"rfc3986-2.0.0.tar.gz\",\"repo\":\"rules_python_publish_deps_311_rfc3986_sdist_97aacf9d\",\"version\":\"3.11\"}]", + "rich": "[{\"filename\":\"rich-13.9.3-py3-none-any.whl\",\"repo\":\"rules_python_publish_deps_311_rich_py3_none_any_9836f509\",\"version\":\"3.11\"},{\"filename\":\"rich-13.9.3.tar.gz\",\"repo\":\"rules_python_publish_deps_311_rich_sdist_bc1e01b8\",\"version\":\"3.11\"}]", + "secretstorage": "[{\"filename\":\"SecretStorage-3.3.3-py3-none-any.whl\",\"repo\":\"rules_python_publish_deps_311_secretstorage_py3_none_any_f356e662\",\"version\":\"3.11\"},{\"filename\":\"SecretStorage-3.3.3.tar.gz\",\"repo\":\"rules_python_publish_deps_311_secretstorage_sdist_2403533e\",\"version\":\"3.11\"}]", + "twine": "[{\"filename\":\"twine-5.1.1-py3-none-any.whl\",\"repo\":\"rules_python_publish_deps_311_twine_py3_none_any_215dbe7b\",\"version\":\"3.11\"},{\"filename\":\"twine-5.1.1.tar.gz\",\"repo\":\"rules_python_publish_deps_311_twine_sdist_9aa08251\",\"version\":\"3.11\"}]", + "urllib3": "[{\"filename\":\"urllib3-2.2.3-py3-none-any.whl\",\"repo\":\"rules_python_publish_deps_311_urllib3_py3_none_any_ca899ca0\",\"version\":\"3.11\"},{\"filename\":\"urllib3-2.2.3.tar.gz\",\"repo\":\"rules_python_publish_deps_311_urllib3_sdist_e7d814a8\",\"version\":\"3.11\"}]", + "zipp": "[{\"filename\":\"zipp-3.20.2-py3-none-any.whl\",\"repo\":\"rules_python_publish_deps_311_zipp_py3_none_any_a817ac80\",\"version\":\"3.11\"},{\"filename\":\"zipp-3.20.2.tar.gz\",\"repo\":\"rules_python_publish_deps_311_zipp_sdist_bc9eb26f\",\"version\":\"3.11\"}]" + }, + "packages": [ + "backports_tarfile", + "certifi", + "charset_normalizer", + "docutils", + "idna", + "importlib_metadata", + "jaraco_classes", + "jaraco_context", + "jaraco_functools", + "keyring", + "markdown_it_py", + "mdurl", + "more_itertools", + "nh3", + "pkginfo", + "pygments", + "readme_renderer", + "requests", + "requests_toolbelt", + "rfc3986", + "rich", + "twine", + "urllib3", + "zipp" + ], + "groups": {} + } + } + }, + "recordedRepoMappingEntries": [ + [ + "bazel_features+", + "bazel_features_globals", + "bazel_features++version_extension+bazel_features_globals" + ], + [ + "bazel_features+", + "bazel_features_version", + "bazel_features++version_extension+bazel_features_version" + ], + [ + "rules_python+", + "bazel_features", + "bazel_features+" + ], + [ + "rules_python+", + "bazel_skylib", + "bazel_skylib+" + ], + [ + "rules_python+", + "bazel_tools", + "bazel_tools" + ], + [ + "rules_python+", + "pypi__build", + "rules_python++internal_deps+pypi__build" + ], + [ + "rules_python+", + "pypi__click", + "rules_python++internal_deps+pypi__click" + ], + [ + "rules_python+", + "pypi__colorama", + "rules_python++internal_deps+pypi__colorama" + ], + [ + "rules_python+", + "pypi__importlib_metadata", + "rules_python++internal_deps+pypi__importlib_metadata" + ], + [ + "rules_python+", + "pypi__installer", + "rules_python++internal_deps+pypi__installer" + ], + [ + "rules_python+", + "pypi__more_itertools", + "rules_python++internal_deps+pypi__more_itertools" + ], + [ + "rules_python+", + "pypi__packaging", + "rules_python++internal_deps+pypi__packaging" + ], + [ + "rules_python+", + "pypi__pep517", + "rules_python++internal_deps+pypi__pep517" + ], + [ + "rules_python+", + "pypi__pip", + "rules_python++internal_deps+pypi__pip" + ], + [ + "rules_python+", + "pypi__pip_tools", + "rules_python++internal_deps+pypi__pip_tools" + ], + [ + "rules_python+", + "pypi__pyproject_hooks", + "rules_python++internal_deps+pypi__pyproject_hooks" + ], + [ + "rules_python+", + "pypi__setuptools", + "rules_python++internal_deps+pypi__setuptools" + ], + [ + "rules_python+", + "pypi__tomli", + "rules_python++internal_deps+pypi__tomli" + ], + [ + "rules_python+", + "pypi__wheel", + "rules_python++internal_deps+pypi__wheel" + ], + [ + "rules_python+", + "pypi__zipp", + "rules_python++internal_deps+pypi__zipp" + ], + [ + "rules_python+", + "pythons_hub", + "rules_python++python+pythons_hub" + ], + [ + "rules_python++python+pythons_hub", + "python_3_10_host", + "rules_python++python+python_3_10_host" + ], + [ + "rules_python++python+pythons_hub", + "python_3_11_host", + "rules_python++python+python_3_11_host" + ], + [ + "rules_python++python+pythons_hub", + "python_3_12_host", + "rules_python++python+python_3_12_host" + ], + [ + "rules_python++python+pythons_hub", + "python_3_8_host", + "rules_python++python+python_3_8_host" + ], + [ + "rules_python++python+pythons_hub", + "python_3_9_host", + "rules_python++python+python_3_9_host" + ] + ] + } + }, "@@tar.bzl+//tar:extensions.bzl%toolchains": { "general": { "bzlTransitiveDigest": "/2afh6fPjq/rcyE/jztQDK3ierehmFFngfvmqyRv72M=", diff --git a/README.md b/README.md index 3e7a507..8752a62 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # @tummycrypt/tinyland-auth-pg -PostgreSQL storage adapter for [@tummycrypt/tinyland-auth](https://github.com/Jesssullivan/tinyland-auth), backed by [Drizzle ORM](https://orm.drizzle.team) with driver-agnostic construction and multi-tenant scoping. +PostgreSQL storage adapter for [@tummycrypt/tinyland-auth](https://github.com/tinyland-inc/tinyland-auth), backed by [Drizzle ORM](https://orm.drizzle.team) with driver-agnostic construction and multi-tenant scoping. Supports Neon HTTP, `postgres.js`, and `node-postgres`. Use `createNodePgStorageAdapter()` when you want the package to own a `pg.Pool`, or `createPgStorageAdapter({ db })` @@ -10,20 +10,46 @@ when you already have a pre-built Drizzle client. > as its first parameter. Every row-bearing table has `tenant_id uuid NOT NULL`. > See [`CHANGELOG.md`](./CHANGELOG.md#020--2026-04-17) for the full migration guide. -## Installation +## Consumption -```bash -npm install @tummycrypt/tinyland-auth-pg -# or -pnpm add @tummycrypt/tinyland-auth-pg -``` +### Bzlmod (canonical) -### Peer Dependencies +Canonical first-party consumption is the immutable +`tummycrypt_tinyland_auth_pg` module in +`tinyland-inc/bazel-registry`. A version is consumable only after that exact +registry entry lands. The coordinates for this release candidate are: -```bash -npm install @tummycrypt/tinyland-auth +```starlark +bazel_dep(name = "tummycrypt_tinyland_auth_pg", version = "0.2.5") +bazel_dep(name = "tummycrypt_tinyland_auth", version = "0.3.3") ``` +First-party Bazel consumers link both +`@tummycrypt_tinyland_auth_pg//:pkg` and +`@tummycrypt_tinyland_auth//:pkg` into their Node package tree. The executable +fixture in [`tests/bzlmod-consumer`](./tests/bzlmod-consumer) is the reference +consumer. + +Repository source builds do not resolve `@tummycrypt/tinyland-auth` through +npm, GitHub Packages, workspace protocols, or file links. Bazel resolves the +exact `tummycrypt_tinyland_auth@0.3.3` module, consumes +`@tummycrypt_tinyland_auth//:pkg`, and links explicit third-party runtime +stores. + +### Release authority + +This repository publishes neither npmjs nor GitHub Packages artifacts. The +central TIN-89 package workflow proves the Bazel package graph remotely. Only +after exact-head proof may an operator create the signed immutable source tag; +the reviewed, append-only `tinyland-inc/bazel-registry` entry makes that source +release consumable. + +The emitted package manifest intentionally carries +`@tummycrypt/tinyland-auth@^0.3.0` as peer compatibility metadata. That peer +entry is not source, build, type, or runtime authority for this repository; +those edges remain on the exact Bzlmod `@tummycrypt_tinyland_auth//:pkg` +target. Source-tree publication is blocked. + ## Quick Start (0.2.0+) ### With `node-postgres` (owned pool; recommended for CNPG / local PG) @@ -149,17 +175,17 @@ Push schema changes directly (development): ```bash # Auth schema -DATABASE_URL="postgresql://..." pnpm db:push +DATABASE_URL="postgresql://..." just db-push # Public schema (booking, content) -DATABASE_URL="postgresql://..." npx drizzle-kit push --config=drizzle.public.config.ts +DATABASE_URL="postgresql://..." just db-push-public ``` Generate migration files (production): ```bash -DATABASE_URL="postgresql://..." pnpm db:generate -DATABASE_URL="postgresql://..." pnpm db:migrate +DATABASE_URL="postgresql://..." just db-generate +DATABASE_URL="postgresql://..." just db-migrate ``` ## API Reference @@ -248,6 +274,11 @@ Every method accepts `tenantId: string` as its **first parameter** and returns - `getAllSessions(tenantId): Promise[]>` - `cleanupExpiredSessions(tenantId): Promise` +Session liveness is evaluated in PostgreSQL from `expires_at` against the +database's UTC clock. Read methods never delete rows and never parse +driver-rendered timestamps in JavaScript; invoke `cleanupExpiredSessions` +explicitly when expired-row removal is desired. + #### TOTP / Backup Codes - `saveTOTPSecret(tenantId, handle, secret): Promise` - `getTOTPSecret(tenantId, handle): Promise` @@ -270,11 +301,10 @@ Every method accepts `tenantId: string` as its **first parameter** and returns - `logAuditEvent(tenantId, event): Promise` - `getAuditEvents(tenantId, filters?): Promise` -> **Interface note:** the class does not `implements IStorageAdapter` from -> `@tummycrypt/tinyland-auth@0.2.x` because the peer package predates Pattern B. -> An interface uplift will ship with tinyland-auth 0.3.0 and this adapter will -> re-implement it then. Until then, consume the concrete class or type against -> the exported method signatures directly. +> **Interface note:** `IStorageAdapter` is the single-tenant Pattern A shape. +> `PgStorageAdapter` exposes the tenant-scoped Pattern B shape supported by +> `@tummycrypt/tinyland-auth@0.3.3`; use the upstream fixed-tenant wrapper when a +> Pattern A consumer needs to bind this adapter to one tenant. ### `NodePgStorageAdapter` @@ -290,17 +320,32 @@ that pool by default when `adapter.close()` is called. ## Development ```bash -pnpm install -pnpm test # Run tests -pnpm build # Compile TypeScript -pnpm test:watch # Watch mode +nix develop +just setup +just check +just build +just typecheck +just test +just package-authority +just package-check ``` -### Nix +`MODULE.bazel` is the package version and first-party dependency authority; +`package.json`, `BUILD.bazel`, and the packaged manifest must remain in parity. +The package-manager manifest and lock intentionally contain no first-party +source edge. -```bash -nix develop # Enter dev shell with Node 20 + pnpm + tsc -``` +The checked-in `tests/bzlmod-consumer` fixture records the expected external +link shape for auth and auth-pg. Actual registry/archive consumption is a +post-tag, post-BCR remote release gate; this source branch does not substitute a +local-path build for that receipt. + +The Nix flake supplies the pinned development shell only. The former Nix +package derivation used a second pnpm/tsc build path, so it was removed rather +than retained as competing package authority. + +This is package/build authority only. It does not configure a remote cache, +enroll an executor, or claim remote execution (RBE). ## License diff --git a/docs/superpowers/plans/2026-04-17-v0.2.0-driver-agnostic-tenant-id.md b/docs/superpowers/plans/2026-04-17-v0.2.0-driver-agnostic-tenant-id.md index f5c6e38..557e83e 100644 --- a/docs/superpowers/plans/2026-04-17-v0.2.0-driver-agnostic-tenant-id.md +++ b/docs/superpowers/plans/2026-04-17-v0.2.0-driver-agnostic-tenant-id.md @@ -1,5 +1,13 @@ # tinyland-auth-pg v0.2.0 Implementation Plan +> **Historical plan:** The publication commands and npm identities below record +> the 0.2.0 plan and are not current release authority. Current first-party +> consumption is the `tummycrypt_tinyland_auth_pg` Bzlmod module. npmjs +> publication is disabled; the only configured compatibility artifact is a +> publish-time rewrite to GitHub Packages identity +> `@tinyland-inc/tinyland-auth-pg`. See the repository README and publish +> workflow for the current contract. + > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. **Goal:** Ship `@tummycrypt/tinyland-auth-pg@0.2.0` that (a) accepts a pre-built drizzle client via DI instead of constructing neon-http internally, and (b) enforces tenant isolation via explicit `tenantId` on every adapter method (Pattern B) backed by `tenant_id uuid NOT NULL` on every row-bearing table. diff --git a/flake.nix b/flake.nix index 70573ca..15e3351 100644 --- a/flake.nix +++ b/flake.nix @@ -1,44 +1,40 @@ { - description = - "@tummycrypt/tinyland-auth-pg - PostgreSQL storage adapter for tinyland-auth"; + description = "@tummycrypt/tinyland-auth-pg - PostgreSQL storage adapter for tinyland-auth"; inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; flake-utils.url = "github:numtide/flake-utils"; }; - outputs = { self, nixpkgs, flake-utils }: - let - packageJson = builtins.fromJSON (builtins.readFile ./package.json); - overlay = final: prev: { - tinyland-auth-pg = final.callPackage ./nix/package.nix { - version = packageJson.version; - }; - }; - in flake-utils.lib.eachDefaultSystem (system: + outputs = + { + self, + nixpkgs, + flake-utils, + }: + flake-utils.lib.eachDefaultSystem ( + system: let - pkgs = import nixpkgs { - inherit system; - overlays = [ overlay ]; - }; - in { - packages.default = pkgs.tinyland-auth-pg; - packages.tinyland-auth-pg = pkgs.tinyland-auth-pg; - - checks.default = pkgs.tinyland-auth-pg; - + pkgs = nixpkgs.legacyPackages.${system}; + pnpmPackage = if pkgs ? pnpm_10 then pkgs.pnpm_10 else pkgs.pnpm; + in + { devShells.default = pkgs.mkShell { - buildInputs = with pkgs; [ bazel_8 nodejs_22 (pnpm_10 or pnpm) ]; + buildInputs = [ + pkgs.bazelisk + pkgs.just + pkgs.nodejs_22 + pnpmPackage + ]; shellHook = '' echo "tinyland-auth-pg dev shell" echo " node $(node --version)" echo " pnpm $(pnpm --version)" - echo " bazel $(bazel --version | head -n1)" + echo " bazel $(bazelisk --version | head -n1)" ''; }; - formatter = pkgs.nixfmt-rfc-style; - }) // { - overlays.default = overlay; - }; + formatter = pkgs.nixfmt; + } + ); } diff --git a/nix/package.nix b/nix/package.nix deleted file mode 100644 index 14f5782..0000000 --- a/nix/package.nix +++ /dev/null @@ -1,46 +0,0 @@ -{ pkgs, lib ? pkgs.lib, version ? "0.2.1", packageSrc ? lib.cleanSource ./.. }: - -let - nodejs = pkgs.nodejs_22; - pnpm = pkgs.pnpm_10 or pkgs.pnpm; -in pkgs.stdenv.mkDerivation { - pname = "tinyland-auth-pg"; - inherit version; - src = packageSrc; - - nativeBuildInputs = [ nodejs pnpm pkgs.pnpmConfigHook ]; - - pnpmDeps = pkgs.fetchPnpmDeps { - pname = "tinyland-auth-pg"; - inherit version; - src = packageSrc; - inherit pnpm; - fetcherVersion = 3; - hash = "sha256-IoyEv6w3aL4BMr7ExAOv8kOIZt22vKnUa5NFIUi/VfA="; - }; - - buildPhase = '' - runHook preBuild - export HOME="$TMPDIR/home" - export CI=true - mkdir -p "$HOME" - pnpm --config.manage-package-manager-versions=false build - runHook postBuild - ''; - - installPhase = '' - runHook preInstall - package_root="$out/lib/node_modules/@tummycrypt/tinyland-auth-pg" - mkdir -p "$package_root" - cp -r dist drizzle drizzle-public package.json README.md CHANGELOG.md "$package_root"/ - runHook postInstall - ''; - - meta = with lib; { - description = "PostgreSQL storage adapter for @tummycrypt/tinyland-auth"; - homepage = "https://github.com/tinyland-inc/tinyland-auth-pg"; - license = licenses.mit; - maintainers = [ ]; - platforms = platforms.unix; - }; -} diff --git a/package.json b/package.json index f01e786..32aebbb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@tummycrypt/tinyland-auth-pg", - "version": "0.2.4", + "version": "0.2.5", "type": "module", "packageManager": "pnpm@10.13.1", "license": "MIT", @@ -13,9 +13,6 @@ "type": "git", "url": "git+https://github.com/tinyland-inc/tinyland-auth-pg.git" }, - "publishConfig": { - "access": "public" - }, "exports": { ".": { "types": "./dist/index.d.ts", @@ -58,34 +55,33 @@ "!dist/**/*.js.map" ], "scripts": { - "build": "tsc", - "clean": "rm -rf dist", - "typecheck": "tsc --noEmit", - "test": "vitest run", - "test:unit": "vitest run", - "test:watch": "vitest watch", - "check:package": "publint", - "db:generate": "drizzle-kit generate", - "db:migrate": "drizzle-kit migrate", - "db:push": "drizzle-kit push", - "prepublishOnly": "pnpm build && pnpm check:package" + "build": "just build", + "clean": "just clean", + "typecheck": "just typecheck", + "test": "just test", + "test:unit": "just test-unit", + "check:package": "just package-check", + "db:generate": "just db-generate", + "db:migrate": "just db-migrate", + "db:push": "just db-push", + "prepublishOnly": "just publish-guard" }, "dependencies": { "@neondatabase/serverless": "^0.10.4", "drizzle-orm": "0.39.3", "pg": "^8.20.0" }, - "peerDependencies": { - "@tummycrypt/tinyland-auth": "^0.2.0 || ^0.3.0" - }, "devDependencies": { - "@tummycrypt/tinyland-auth": "^0.3.0", "@testcontainers/postgresql": "^11.14.0", "@types/node": "^22.0.0", "@types/pg": "^8.20.0", + "bcryptjs": "2.4.3", "drizzle-kit": "^0.30.5", + "nanoid": "5.1.9", + "otplib": "12.0.1", "postgres": "^3.4.9", "publint": "^0.3.18", + "qrcode": "1.5.4", "testcontainers": "^11.14.0", "typescript": "5.9.3", "vitest": "^4.0.18" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 29e2261..974df8d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -21,24 +21,33 @@ importers: '@testcontainers/postgresql': specifier: ^11.14.0 version: 11.14.0 - '@tummycrypt/tinyland-auth': - specifier: ^0.3.0 - version: 0.3.0 '@types/node': specifier: ^22.0.0 version: 22.19.17 '@types/pg': specifier: ^8.20.0 version: 8.20.0 + bcryptjs: + specifier: 2.4.3 + version: 2.4.3 drizzle-kit: specifier: ^0.30.5 version: 0.30.6 + nanoid: + specifier: 5.1.9 + version: 5.1.9 + otplib: + specifier: 12.0.1 + version: 12.0.1 postgres: specifier: ^3.4.9 version: 3.4.9 publint: specifier: ^0.3.18 version: 0.3.18 + qrcode: + specifier: 1.5.4 + version: 1.5.4 testcontainers: specifier: ^11.14.0 version: 11.14.0 @@ -68,11 +77,11 @@ packages: '@esbuild-kit/core-utils@3.3.2': resolution: {integrity: sha512-sPRAnw9CdSsRmEtnsl2WXWdyquogVpB3yZ3dgwJfe8zrOzTsV7cJvmwrKVa+0ma5BoiGJ+BoqkMvawbayKUsqQ==} - deprecated: 'Merged into tsx: https://tsx.is' + deprecated: 'Merged into tsx: https://tsx.hirok.io' '@esbuild-kit/esm-loader@2.6.5': resolution: {integrity: sha512-FxEMIkJKnodyA1OaCUoEvbYRkoZlLZ4d/eXFu9Fh8CbBBgP5EmZxrfTRyN0qpXZ4vOvqnE5YdRdcrmUUXuU+dA==} - deprecated: 'Merged into tsx: https://tsx.is' + deprecated: 'Merged into tsx: https://tsx.hirok.io' '@esbuild/aix-ppc64@0.19.12': resolution: {integrity: sha512-bmoCYyWdEL3wDQIVbcyzRyeKLgk2WtWLTWz1ZIAZF/EGbNOwSA6ew3PftJ1PqMiOOGu0OyFMzG53L0zqIpPeNA==} @@ -537,18 +546,6 @@ packages: '@testcontainers/postgresql@11.14.0': resolution: {integrity: sha512-wYbJn8GRTj8qfqzfVubxioYWlHJU/ImIjuzPwyy9C5Qfo6g3GLduPZAj+BifvqTZjgT3gd4gFVLCPhBji7dc1w==} - '@tummycrypt/tinyland-auth@0.3.0': - resolution: {integrity: sha512-RiDHH5EdhLS4uF2D/GEBAaVN3712E5Xtj9W4SnVycUE2BbVmIrCPTjif3vcHhwy0QmiwMNGKQWsRIXgHiMIcsw==} - engines: {node: '>=22.0.0'} - peerDependencies: - '@sveltejs/kit': ^2.0.0 - svelte: ^5.0.0 - peerDependenciesMeta: - '@sveltejs/kit': - optional: true - svelte: - optional: true - '@tybys/wasm-util@0.10.1': resolution: {integrity: sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==} @@ -1183,8 +1180,8 @@ packages: engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true - nanoid@5.1.7: - resolution: {integrity: sha512-ua3NDgISf6jdwezAheMOk4mbE1LXjm1DfMUDMuJf4AqxLFK3ccGpgWizwa5YV7Yz9EpXwEaWoRXSb/BnV0t5dQ==} + nanoid@5.1.9: + resolution: {integrity: sha512-ZUvP7KeBLe3OZ1ypw6dI/TzYJuvHP77IM4Ry73waSQTLn8/g8rpdjfyVAh7t1/+FjBtG4lCP42MEbDxOsRpBMw==} engines: {node: ^18 || >=20} hasBin: true @@ -1567,6 +1564,7 @@ packages: uuid@10.0.0: resolution: {integrity: sha512-8XkAphELsDnEGrDxUOHB3RGvXz6TeuYSGEZBOjtTtPm2lwhGBjLgOzLHB63IUWfBpNucQjND6d3AOudO+H3RWQ==} + deprecated: uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028). hasBin: true vite@8.0.1: @@ -2047,13 +2045,6 @@ snapshots: - react-native-b4a - supports-color - '@tummycrypt/tinyland-auth@0.3.0': - dependencies: - bcryptjs: 2.4.3 - nanoid: 5.1.7 - otplib: 12.0.1 - qrcode: 1.5.4 - '@tybys/wasm-util@0.10.1': dependencies: tslib: 2.8.1 @@ -2634,7 +2625,7 @@ snapshots: nanoid@3.3.11: {} - nanoid@5.1.7: {} + nanoid@5.1.9: {} normalize-path@3.0.0: {} diff --git a/src/__tests__/container-runtime.ts b/src/__tests__/container-runtime.ts index 3385e1d..d706b3a 100644 --- a/src/__tests__/container-runtime.ts +++ b/src/__tests__/container-runtime.ts @@ -11,9 +11,15 @@ function hasPodmanSocket(): boolean { } export function hasContainerRuntime(): boolean { - return Boolean( + const available = Boolean( process.env.DOCKER_HOST || existsSync(dockerSocket) || hasPodmanSocket(), ); + if (!available && process.env.AUTH_PG_INTEGRATION_REQUIRED === 'true') { + throw new Error( + 'AUTH_PG_INTEGRATION_REQUIRED=true but no Docker or Podman socket is available; refusing vacuous PostgreSQL evidence', + ); + } + return available; } diff --git a/src/__tests__/node-pg.test.ts b/src/__tests__/node-pg.test.ts index 4ee49f3..240c06f 100644 --- a/src/__tests__/node-pg.test.ts +++ b/src/__tests__/node-pg.test.ts @@ -8,16 +8,19 @@ * SKIPS automatically when no Docker/Podman runtime is discoverable. */ -import { describe, it, expect, beforeAll, afterAll } from 'vitest'; +import { randomUUID } from 'node:crypto'; +import { describe, it, expect, beforeAll, afterAll, afterEach, vi } from 'vitest'; import { PostgreSqlContainer, type StartedPostgreSqlContainer, } from '@testcontainers/postgresql'; -import { Pool } from 'pg'; +import { drizzle } from 'drizzle-orm/node-postgres'; +import { Pool, type PoolClient } from 'pg'; import { readFileSync, readdirSync } from 'node:fs'; import { dirname, join } from 'node:path'; import { fileURLToPath } from 'node:url'; -import { createNodePgStorageAdapter } from '../adapter.js'; +import { createNodePgStorageAdapter, createPgStorageAdapter } from '../adapter.js'; +import * as schema from '../schema.js'; import { hasContainerRuntime } from './container-runtime.js'; const __filename = fileURLToPath(import.meta.url); @@ -29,6 +32,7 @@ describe.skipIf(!hasContainerRuntime())( let container: StartedPostgreSqlContainer; let setupPool: Pool; let adapter: ReturnType; + const originalTimezone = process.env.TZ; const TENANT_A = '11111111-1111-1111-1111-111111111111'; const TENANT_B = '22222222-2222-2222-2222-222222222222'; @@ -53,7 +57,9 @@ describe.skipIf(!hasContainerRuntime())( adapter = createNodePgStorageAdapter({ connectionString: container.getConnectionUri(), - poolConfig: { max: 4 }, + // Session-level DateStyle probes below must use one physical + // connection for SET + adapter query. + poolConfig: { max: 1 }, }); await adapter.init(); }, 120_000); @@ -64,6 +70,44 @@ describe.skipIf(!hasContainerRuntime())( await container?.stop(); }); + afterEach(async () => { + vi.useRealTimers(); + if (originalTimezone === undefined) delete process.env.TZ; + else process.env.TZ = originalTimezone; + await adapter.pool.query('reset datestyle'); + }); + + async function createSessionFixture(tenantId = randomUUID()) { + const suffix = randomUUID().slice(0, 8); + const now = new Date().toISOString(); + const user = await adapter.createUser(tenantId, { + handle: `session-${suffix}`, + email: `session-${suffix}@example.com`, + passwordHash: 'fixture-hash', + role: 'admin', + isActive: true, + needsOnboarding: false, + onboardingStep: 0, + totpEnabled: false, + createdAt: now, + updatedAt: now, + }); + const session = await adapter.createSession(tenantId, user.id, user); + return { tenantId, user, session }; + } + + async function sessionExists( + tenantId: string, + sessionId: string, + queryable: Pool | PoolClient = setupPool, + ): Promise { + const { rows } = await queryable.query<{ exists: boolean }>( + 'select exists(select 1 from auth.sessions where tenant_id = $1 and id = $2)', + [tenantId, sessionId], + ); + return rows[0]!.exists; + } + it('createUser scopes by tenantId', async () => { const now = new Date().toISOString(); @@ -104,5 +148,124 @@ describe.skipIf(!hasContainerRuntime())( expect(fromA?.passwordHash).toBe('hash_a'); expect(fromB?.passwordHash).toBe('hash_b'); }); + + it('uses the database clock for every session-read path', async () => { + const fixture = await createSessionFixture(); + await setupPool.query( + `update auth.sessions + set expires = (now() at time zone 'utc') + interval '1 day', + expires_at = (now() at time zone 'utc') + interval '1 day' + where tenant_id = $1 and id = $2`, + [fixture.tenantId, fixture.session.id], + ); + + // Fake Date only; network and pool timers stay real. + vi.useFakeTimers({ toFake: ['Date'] }); + vi.setSystemTime(new Date('2100-01-01T00:00:00Z')); + + expect(await adapter.getSession(fixture.tenantId, fixture.session.id)).not.toBeNull(); + expect((await adapter.getSessionsByUser(fixture.tenantId, fixture.user.id)).map((row) => row.id)).toContain( + fixture.session.id, + ); + expect((await adapter.getAllSessions(fixture.tenantId)).map((row) => row.id)).toContain(fixture.session.id); + expect(await sessionExists(fixture.tenantId, fixture.session.id)).toBe(true); + }); + + it('keeps a live SQL, DMY session without parsing or deleting it', async () => { + const fixture = await createSessionFixture(); + const yearResult = await setupPool.query<{ year: number }>( + "select extract(year from now())::int + 1 as year", + ); + const year = yearResult.rows[0]!.year; + await setupPool.query( + `update auth.sessions + set expires = make_timestamp($3, 12, 3, 12, 0, 0), + expires_at = make_timestamp($3, 12, 3, 12, 0, 0) + where tenant_id = $1 and id = $2`, + [fixture.tenantId, fixture.session.id, year], + ); + await adapter.pool.query("set datestyle to 'SQL, DMY'"); + const rendered = await adapter.pool.query<{ expires: string }>( + 'select expires::text as expires from auth.sessions where tenant_id = $1 and id = $2', + [fixture.tenantId, fixture.session.id], + ); + + vi.useFakeTimers({ toFake: ['Date'] }); + vi.setSystemTime(new Date(Date.UTC(year, 5, 1, 12, 0, 0))); + // Negative control: the old bare-Date heuristic sees 03/12 as March 12, + // which is already past on June 1 and would delete this live row. + expect(new Date(rendered.rows[0]!.expires).getTime()).toBeLessThan(Date.now()); + + expect(await adapter.getSession(fixture.tenantId, fixture.session.id)).not.toBeNull(); + expect(await sessionExists(fixture.tenantId, fixture.session.id)).toBe(true); + }); + + it('keeps a live session under an Asia/Tokyo process timezone', async () => { + const fixture = await createSessionFixture(); + await setupPool.query( + `update auth.sessions + set expires = (now() at time zone 'utc') + interval '3 hours', + expires_at = (now() at time zone 'utc') + interval '3 hours' + where tenant_id = $1 and id = $2`, + [fixture.tenantId, fixture.session.id], + ); + process.env.TZ = 'Asia/Tokyo'; + const rendered = await adapter.pool.query<{ expires: string }>( + 'select expires::text as expires from auth.sessions where tenant_id = $1 and id = $2', + [fixture.tenantId, fixture.session.id], + ); + // Negative control: interpreting the naive UTC string as Tokyo local + // time moves it six hours behind the real clock. + expect(new Date(rendered.rows[0]!.expires).getTime()).toBeLessThan(Date.now()); + + expect(await adapter.getSession(fixture.tenantId, fixture.session.id)).not.toBeNull(); + expect(await sessionExists(fixture.tenantId, fixture.session.id)).toBe(true); + }); + + it('keeps expired reads non-mutating and reaps only through the explicit janitor', async () => { + const fixture = await createSessionFixture(); + await setupPool.query( + `update auth.sessions + set expires = (now() at time zone 'utc') - interval '1 day', + expires_at = (now() at time zone 'utc') - interval '1 day' + where tenant_id = $1 and id = $2`, + [fixture.tenantId, fixture.session.id], + ); + + expect(await adapter.getSession(fixture.tenantId, fixture.session.id)).toBeNull(); + expect(await sessionExists(fixture.tenantId, fixture.session.id)).toBe(true); + expect(await adapter.cleanupExpiredSessions(fixture.tenantId)).toBe(1); + expect(await sessionExists(fixture.tenantId, fixture.session.id)).toBe(false); + }); + + it('uses expires_at with strict-live and boundary-inclusive tenant cleanup', async () => { + const a = await createSessionFixture(); + const b = await createSessionFixture(); + const client = await adapter.pool.connect(); + try { + await client.query('begin'); + await client.query( + `update auth.sessions + set expires = (now() at time zone 'utc') + interval '1 day', + expires_at = (now() at time zone 'utc') + where (tenant_id = $1 and id = $2) or (tenant_id = $3 and id = $4)`, + [a.tenantId, a.session.id, b.tenantId, b.session.id], + ); + + const txAdapter = createPgStorageAdapter({ db: drizzle(client, { schema }) }); + expect(await txAdapter.getSession(a.tenantId, a.session.id)).toBeNull(); + expect((await txAdapter.getSessionsByUser(a.tenantId, a.user.id)).map((row) => row.id)).not.toContain( + a.session.id, + ); + expect((await txAdapter.getAllSessions(a.tenantId)).map((row) => row.id)).not.toContain(a.session.id); + expect(await sessionExists(a.tenantId, a.session.id, client)).toBe(true); + expect(await txAdapter.cleanupExpiredSessions(a.tenantId)).toBe(1); + expect(await sessionExists(a.tenantId, a.session.id, client)).toBe(false); + expect(await sessionExists(b.tenantId, b.session.id, client)).toBe(true); + } finally { + await client.query('rollback'); + client.release(); + } + }); }, ); diff --git a/src/__tests__/package-authority.test.ts b/src/__tests__/package-authority.test.ts index 089d9cf..6281760 100644 --- a/src/__tests__/package-authority.test.ts +++ b/src/__tests__/package-authority.test.ts @@ -2,39 +2,113 @@ import { readFile } from 'node:fs/promises'; import { describe, expect, it } from 'vitest'; const readText = (path: string) => readFile(path, 'utf8'); +const IN_HOUSE_SCOPES = ['@tummycrypt/', '@tinyland/'] as const; +const AUTH_MODULE = 'tummycrypt_tinyland_auth'; +const AUTH_VERSION = '0.3.3'; +const REGISTRY_REVISION = 'ef734c4a26045a7b396913e6cf410e50fbe16635'; +const PRIVATE_REGISTRY = + `https://raw.githubusercontent.com/tinyland-inc/bazel-registry/${REGISTRY_REVISION}`; +const PUBLIC_REGISTRY = 'https://bcr.bazel.build'; +const CI_TEMPLATES_CANARY = + 'tinyland-inc/ci-templates/.github/workflows/js-bazel-package.yml@6244d36f3048cf93672a8f37a873ec2db2cb09a3'; -// Extract the version declared inside the top-level module() call of MODULE.bazel. -// Scoped to the module() block so bazel_dep(..., version = ...) lines cannot match. -const extractModuleVersion = (moduleBazel: string): string => { +const extractModuleBlock = (moduleBazel: string): string => { const moduleBlock = moduleBazel.match(/module\(([\s\S]*?)\)/); if (!moduleBlock) { throw new Error('module() declaration not found in MODULE.bazel'); } - const version = moduleBlock[1].match(/version\s*=\s*"([^"]+)"/); + return moduleBlock[1]; +}; + +// Extract the version declared inside the top-level module() call of MODULE.bazel. +// Scoped to the module() block so bazel_dep(..., version = ...) lines cannot match. +const extractModuleVersion = (moduleBazel: string): string => { + const version = extractModuleBlock(moduleBazel).match(/version\s*=\s*"([^"]+)"/); if (!version) { throw new Error('version attribute not found in the module() declaration'); } return version[1]; }; -// Extract the version declared inside the npm_package() target of BUILD.bazel. -const extractNpmPackageVersion = (buildBazel: string): string => { - const pkgBlock = buildBazel.match(/npm_package\(([\s\S]*?)\n\)/); +const extractModuleName = (moduleBazel: string): string => { + const name = extractModuleBlock(moduleBazel).match(/name\s*=\s*"([^"]+)"/); + if (!name) { + throw new Error('name attribute not found in the module() declaration'); + } + return name[1]; +}; + +const extractNpmPackageBlock = (buildBazel: string, targetName: string): string => { + const pkgBlock = buildBazel.match( + new RegExp(`npm_package\\(\\s*name\\s*=\\s*"${targetName}",([\\s\\S]*?)\\n\\)`), + ); if (!pkgBlock) { - throw new Error('npm_package() target not found in BUILD.bazel'); + throw new Error(`npm_package(${targetName}) target not found in BUILD.bazel`); } - const version = pkgBlock[1].match(/version\s*=\s*"([^"]+)"/); + return pkgBlock[1]; +}; + +// Extract the version declared inside the publishable npm_package() target. +const extractNpmPackageVersion = (buildBazel: string): string => { + const version = extractNpmPackageBlock(buildBazel, 'pkg').match(/version\s*=\s*"([^"]+)"/); if (!version) { throw new Error('version attribute not found in the npm_package() target'); } return version[1]; }; +const extractNpmPackageName = (buildBazel: string): string => { + const packageName = extractNpmPackageBlock(buildBazel, 'pkg').match( + /package\s*=\s*"([^"]+)"/, + ); + if (!packageName) { + throw new Error('package attribute not found in the npm_package() target'); + } + return packageName[1]; +}; + +const extractBazelDepVersion = (moduleBazel: string, moduleName: string): string => { + const dep = moduleBazel.match( + new RegExp( + `bazel_dep\\(\\s*name\\s*=\\s*"${moduleName}"\\s*,\\s*version\\s*=\\s*"([^"]+)"\\s*\\)`, + ), + ); + if (!dep) { + throw new Error(`bazel_dep(${moduleName}) not found in MODULE.bazel`); + } + return dep[1]; +}; + +const hasInHouseName = (name: string): boolean => + IN_HOUSE_SCOPES.some((scope) => name.startsWith(scope)); + +const findInHouseCoordinates = (value: unknown, path = 'package.json'): string[] => { + if (typeof value === 'string') { + return hasInHouseName(value) ? [`${path}=${value}`] : []; + } + if (Array.isArray(value)) { + return value.flatMap((entry, index) => + findInHouseCoordinates(entry, `${path}[${index}]`), + ); + } + if (!value || typeof value !== 'object') { + return []; + } + + return Object.entries(value).flatMap(([key, entry]) => [ + ...(hasInHouseName(key) ? [`${path}.${key}`] : []), + ...findInHouseCoordinates(entry, `${path}.${key}`), + ]); +}; + describe('package release authority', () => { - it('keeps the packaged version aligned with the MODULE.bazel SSOT', async () => { + it('keeps package identity and version aligned with the MODULE.bazel SSOT', async () => { const moduleBazel = await readText('MODULE.bazel'); const buildBazel = await readText('BUILD.bazel'); - const packageJson = JSON.parse(await readText('package.json')) as { version?: string }; + const packageJson = JSON.parse(await readText('package.json')) as { + name?: string; + version?: string; + }; const moduleVersion = extractModuleVersion(moduleBazel); const packagedVersion = extractNpmPackageVersion(buildBazel); @@ -44,5 +118,156 @@ describe('package release authority', () => { // version that disagrees with the Bazel-registry SSOT and the git tag. expect(packagedVersion).toBe(moduleVersion); expect(packageJson.version).toBe(moduleVersion); + expect(extractModuleName(moduleBazel)).toBe('tummycrypt_tinyland_auth_pg'); + expect(extractNpmPackageName(buildBazel)).toBe('@tummycrypt/tinyland-auth-pg'); + expect(packageJson.name).toBe('@tummycrypt/tinyland-auth-pg'); + }); + + it('resolves auth from the exact Bzlmod module with explicit Node runtime stores', async () => { + const moduleBazel = await readText('MODULE.bazel'); + const buildBazel = await readText('BUILD.bazel'); + const bazelrc = await readText('.bazelrc'); + const moduleLock = JSON.parse(await readText('MODULE.bazel.lock')) as { + registryFileHashes?: Record; + }; + + expect(extractBazelDepVersion(moduleBazel, AUTH_MODULE)).toBe(AUTH_VERSION); + expect( + bazelrc + .split('\n') + .map((line) => line.trim()) + .filter((line) => line.startsWith('common --registry=')), + ).toEqual([ + `common --registry=${PRIVATE_REGISTRY}`, + `common --registry=${PUBLIC_REGISTRY}`, + ]); + expect(bazelrc).toContain('common --lockfile_mode=error'); + expect( + Object.keys(moduleLock.registryFileHashes ?? {}).some((path) => + path.includes('tinyland-inc/bazel-registry/main/'), + ), + ).toBe(false); + + const authRegistryPrefix = `${PRIVATE_REGISTRY}/modules/${AUTH_MODULE}/${AUTH_VERSION}/`; + const authRegistryEntries = Object.entries(moduleLock.registryFileHashes ?? {}) + .filter(([path]) => path.startsWith(authRegistryPrefix)) + .sort(([left], [right]) => left.localeCompare(right)); + expect(authRegistryEntries.map(([path]) => path)).toEqual([ + `${authRegistryPrefix}MODULE.bazel`, + `${authRegistryPrefix}source.json`, + ]); + expect(authRegistryEntries.every(([, hash]) => hash !== 'not found')).toBe(true); + + const authWrapper = extractNpmPackageBlock(buildBazel, 'tinyland_auth_registry_package'); + expect(authWrapper).toContain('srcs = [":tinyland_auth_registry_files"]'); + expect(authWrapper).toContain( + 'include_external_repositories = ["tummycrypt_tinyland_auth+"]', + ); + expect(authWrapper).toContain('package = "@tummycrypt/tinyland-auth"'); + expect(authWrapper).toContain(`version = "${AUTH_VERSION}"`); + expect(buildBazel).toContain('srcs = ["@tummycrypt_tinyland_auth//:pkg"]'); + + const authLink = buildBazel.match( + /npm_link_package\(\s*name\s*=\s*"node_modules\/@tummycrypt\/tinyland-auth"([\s\S]*?)\n\)/, + ); + expect(authLink, 'consumer-owned tinyland-auth npm_link_package').not.toBeNull(); + expect(authLink?.[1]).toContain('src = ":tinyland_auth_registry_package"'); + + for (const [store, alias] of [ + ['bcryptjs@2.4.3', 'bcryptjs'], + ['nanoid@5.1.9', 'nanoid'], + ['otplib@12.0.1', 'otplib'], + ['qrcode@1.5.4', 'qrcode'], + ] as const) { + expect(authLink?.[1]).toContain( + `:.aspect_rules_js/node_modules/${store}": "${alias}"`, + ); + } + }); + + it('rejects every first-party package-manager source edge', async () => { + const packageJson = JSON.parse(await readText('package.json')) as Record; + expect(packageJson.publishConfig).toBeUndefined(); + + const packageManagerCoordinateFields = [ + 'dependencies', + 'devDependencies', + 'peerDependencies', + 'optionalDependencies', + 'bundledDependencies', + 'bundleDependencies', + 'overrides', + 'resolutions', + 'pnpm', + 'workspaces', + ] as const; + const packageManagerCoordinates = packageManagerCoordinateFields.flatMap((field) => + findInHouseCoordinates(packageJson[field], `package.json.${field}`), + ); + expect(packageManagerCoordinates).toEqual([]); + + expect(packageJson.devDependencies).toMatchObject({ + bcryptjs: '2.4.3', + nanoid: '5.1.9', + otplib: '12.0.1', + qrcode: '1.5.4', + }); + + const packageManagerFiles = await Promise.all([ + readText('pnpm-lock.yaml'), + readText('pnpm-workspace.yaml'), + ]); + for (const contents of packageManagerFiles) { + for (const scope of IN_HOUSE_SCOPES) { + expect(contents).not.toContain(scope); + } + } + }); + + it('keeps peer metadata non-authoritative and delegates CI to the central v4 graph carrier', async () => { + const [buildBazel, readme, ciWorkflow] = await Promise.all([ + readText('BUILD.bazel'), + readText('README.md'), + readText('.github/workflows/ci.yml'), + ]); + + expect(buildBazel).toContain( + 'filter = ".peerDependencies = {\\"@tummycrypt/tinyland-auth\\": \\"^0.3.0\\"} | del(.devDependencies, .scripts)"', + ); + expect(readme).toContain('Canonical first-party consumption is the immutable'); + expect(readme).toContain('publishes neither npmjs nor GitHub Packages'); + expect(readme).toContain('peer compatibility metadata'); + expect(readme).not.toContain('npm install @tummycrypt/tinyland-auth-pg'); + expect(readme).not.toContain('pnpm add @tummycrypt/tinyland-auth-pg'); + expect(ciWorkflow).toContain(`uses: ${CI_TEMPLATES_CANARY}`); + expect(ciWorkflow).toContain('verify_bzlmod_lock: true'); + expect(ciWorkflow).toContain('//:integration_test'); + expect(ciWorkflow).not.toMatch( + /\b(?:publish_mode|npm_publish_mode|github_package_name|package_dir|dry_run):/, + ); + expect(ciWorkflow).not.toContain('packages: write'); + expect(ciWorkflow).not.toContain('secrets: inherit'); + }); + + it('records an external Bzlmod consumer with both first-party package links', async () => { + const [consumerModule, consumerBuild] = await Promise.all([ + readText('tests/bzlmod-consumer/MODULE.bazel.template'), + readText('tests/bzlmod-consumer/BUILD.fixture'), + ]); + + expect(extractBazelDepVersion(consumerModule, AUTH_MODULE)).toBe(AUTH_VERSION); + expect(extractBazelDepVersion(consumerModule, 'tummycrypt_tinyland_auth_pg')).toBe( + '0.2.5', + ); + expect(consumerModule).not.toMatch( + /local_path_override\([\s\S]*?module_name\s*=\s*"tummycrypt_tinyland_auth"[\s\S]*?\)/, + ); + expect(consumerBuild).toContain('srcs = ["@tummycrypt_tinyland_auth//:pkg"]'); + expect(consumerBuild).toContain('srcs = ["@tummycrypt_tinyland_auth_pg//:pkg"]'); + expect(consumerBuild).toContain('name = "node_modules/@tummycrypt/tinyland-auth"'); + expect(consumerBuild).toContain('name = "node_modules/@tummycrypt/tinyland-auth-pg"'); + for (const forbidden of ['@npm', 'npm_translate_lock', 'npm.pkg.github.com', 'workspace:', 'file:']) { + expect(`${consumerModule}\n${consumerBuild}`).not.toContain(forbidden); + } }); }); diff --git a/src/__tests__/postgres-js.test.ts b/src/__tests__/postgres-js.test.ts index 14035f6..4b818fe 100644 --- a/src/__tests__/postgres-js.test.ts +++ b/src/__tests__/postgres-js.test.ts @@ -9,6 +9,7 @@ * SKIPS automatically when no Docker/Podman runtime is discoverable. */ +import { randomUUID } from 'node:crypto'; import { describe, it, expect, beforeAll, afterAll } from 'vitest'; import { PostgreSqlContainer, @@ -126,5 +127,45 @@ describe.skipIf(!hasContainerRuntime())( expect(usersA.every((u) => u.tenantId === TENANT_A)).toBe(true); expect(usersB.every((u) => u.tenantId === TENANT_B)).toBe(true); }); + + it('keeps expired reads non-mutating and reaps explicitly through postgres.js', async () => { + const db = drizzle(sql, { schema }); + const adapter = createPgStorageAdapter({ db }); + const tenantId = randomUUID(); + const suffix = randomUUID().slice(0, 8); + const now = new Date().toISOString(); + const user = await adapter.createUser(tenantId, { + handle: `expiry-${suffix}`, + email: `expiry-${suffix}@example.com`, + passwordHash: 'fixture-hash', + role: 'admin', + isActive: true, + needsOnboarding: false, + onboardingStep: 0, + totpEnabled: false, + createdAt: now, + updatedAt: now, + }); + const session = await adapter.createSession(tenantId, user.id, user); + await sql` + update auth.sessions + set expires = (now() at time zone 'utc') - interval '1 day', + expires_at = (now() at time zone 'utc') - interval '1 day' + where tenant_id = ${tenantId} and id = ${session.id} + `; + + expect(await adapter.getSession(tenantId, session.id)).toBeNull(); + const before = await sql` + select count(*)::int as count from auth.sessions + where tenant_id = ${tenantId} and id = ${session.id} + `; + expect(before[0]!.count).toBe(1); + expect(await adapter.cleanupExpiredSessions(tenantId)).toBe(1); + const after = await sql` + select count(*)::int as count from auth.sessions + where tenant_id = ${tenantId} and id = ${session.id} + `; + expect(after[0]!.count).toBe(0); + }); }, ); diff --git a/src/adapter.ts b/src/adapter.ts index 49351c3..01fcdcc 100644 --- a/src/adapter.ts +++ b/src/adapter.ts @@ -58,8 +58,7 @@ export type Database = /** * Domain objects from `@tummycrypt/tinyland-auth/types` don't natively carry * `tenantId`. We widen locally so the adapter can surface the column without - * a breaking cross-repo change. A follow-up `@tummycrypt/tinyland-auth@0.3.0` - * will remove the need for this wrapper. + * changing the upstream domain model pinned by this package. */ export type TenantScoped = T & { tenantId: string }; @@ -93,6 +92,14 @@ export interface NodePgStorageConfig { const SEVEN_DAYS_MS = 7 * 24 * 60 * 60 * 1000; +// PostgreSQL owns session liveness. Both session timestamp columns are +// `timestamp without time zone` strings for compatibility with the existing +// public schema, so parsing driver-rendered text in JavaScript would make +// DateStyle and process TZ part of authentication correctness. Compare the +// authoritative expires_at column to the database's UTC wall clock instead. +const SESSION_IS_LIVE = sql`${schema.sessions.expiresAt} > (now() at time zone 'utc')`; +const SESSION_IS_EXPIRED = sql`${schema.sessions.expiresAt} <= (now() at time zone 'utc')`; + // --------------------------------------------------------------------------- // Row → Domain mappers (pure transforms, tenant-scoped) // --------------------------------------------------------------------------- @@ -217,11 +224,9 @@ const toAuditEvent = (row: AuditRow): TenantScoped => ({ /** * PgStorageAdapter — driver-agnostic, tenant-scoped. * - * NOTE (v0.2.0): this class no longer implements `IStorageAdapter` from - * `@tummycrypt/tinyland-auth/storage`. That interface's method signatures - * (e.g. `getUser(id)`) are incompatible with Pattern B (`getUser(tenantId, id)`). - * A follow-up `@tummycrypt/tinyland-auth@0.3.0` will ship a tenant-aware - * interface and this adapter will implement it then. + * This class exposes tinyland-auth's Pattern B tenant-scoped shape. The + * `IStorageAdapter` interface remains Pattern A (for example, `getUser(id)`), + * while this adapter requires `getUser(tenantId, id)`. */ export class PgStorageAdapter { // Narrow to NeonHttpDatabase internally — runtime is compatible across drivers @@ -425,22 +430,18 @@ export class PgStorageAdapter { const rows = await this.db .select() .from(schema.sessions) - .where(and(eq(schema.sessions.tenantId, tenantId), eq(schema.sessions.id, id))) + .where( + and( + eq(schema.sessions.tenantId, tenantId), + eq(schema.sessions.id, id), + SESSION_IS_LIVE, + ), + ) .limit(1); - - if (!rows[0]) return null; - - const session = toSession(rows[0]); - if (new Date(session.expires) < new Date()) { - await this.deleteSession(tenantId, id); - return null; - } - - return session; + return rows[0] ? toSession(rows[0]) : null; } async getSessionsByUser(tenantId: string, userId: string): Promise[]> { - const now = new Date().toISOString(); const rows = await this.db .select() .from(schema.sessions) @@ -448,7 +449,7 @@ export class PgStorageAdapter { and( eq(schema.sessions.tenantId, tenantId), eq(schema.sessions.userId, userId), - gt(schema.sessions.expires, now), + SESSION_IS_LIVE, ), ); @@ -456,14 +457,13 @@ export class PgStorageAdapter { } async getAllSessions(tenantId: string): Promise[]> { - const now = new Date().toISOString(); const rows = await this.db .select() .from(schema.sessions) .where( and( eq(schema.sessions.tenantId, tenantId), - gt(schema.sessions.expires, now), + SESSION_IS_LIVE, ), ); @@ -564,13 +564,12 @@ export class PgStorageAdapter { } async cleanupExpiredSessions(tenantId: string): Promise { - const now = new Date().toISOString(); const deleted = await this.db .delete(schema.sessions) .where( and( eq(schema.sessions.tenantId, tenantId), - lt(schema.sessions.expires, now), + SESSION_IS_EXPIRED, ), ) .returning({ id: schema.sessions.id }); diff --git a/tests/auth-runtime-link.test.mjs b/tests/auth-runtime-link.test.mjs new file mode 100644 index 0000000..28bbb63 --- /dev/null +++ b/tests/auth-runtime-link.test.mjs @@ -0,0 +1,10 @@ +import assert from 'node:assert/strict'; + +import * as auth from '@tummycrypt/tinyland-auth'; +import * as storage from '@tummycrypt/tinyland-auth/storage'; + +assert.equal(typeof auth.hashPassword, 'function'); +assert.equal(typeof auth.generateTOTPSecret, 'function'); +assert.equal(typeof auth.generateTOTPQRCode, 'function'); +assert.equal(typeof auth.generateSecureCredentialsLink, 'function'); +assert.equal(typeof storage.createFixedTenantStorageAdapter, 'function'); diff --git a/tests/bzlmod-consumer/.bazelrc b/tests/bzlmod-consumer/.bazelrc new file mode 100644 index 0000000..42c9170 --- /dev/null +++ b/tests/bzlmod-consumer/.bazelrc @@ -0,0 +1,7 @@ +common --enable_bzlmod +common --registry=https://raw.githubusercontent.com/tinyland-inc/bazel-registry/ef734c4a26045a7b396913e6cf410e50fbe16635 +common --registry=https://bcr.bazel.build +common --legacy_external_runfiles +common --lockfile_mode=off + +test --test_output=errors diff --git a/tests/bzlmod-consumer/BUILD.fixture b/tests/bzlmod-consumer/BUILD.fixture new file mode 100644 index 0000000..02a6481 --- /dev/null +++ b/tests/bzlmod-consumer/BUILD.fixture @@ -0,0 +1,61 @@ +load("@aspect_rules_js//js:defs.bzl", "js_test") +load("@aspect_rules_js//npm:defs.bzl", "npm_link_package", "npm_package") + +filegroup( + name = "auth_registry_files", + srcs = ["@tummycrypt_tinyland_auth//:pkg"], +) + +npm_package( + name = "auth_registry_package", + srcs = [":auth_registry_files"], + include_external_repositories = ["tummycrypt_tinyland_auth+"], + package = "@tummycrypt/tinyland-auth", + root_paths = ["pkg"], + version = "0.3.3", +) + +npm_link_package( + name = "node_modules/@tummycrypt/tinyland-auth", + deps = { + "@tummycrypt_tinyland_auth//:node_modules/bcryptjs": "bcryptjs", + "@tummycrypt_tinyland_auth//:node_modules/nanoid": "nanoid", + "@tummycrypt_tinyland_auth//:node_modules/otplib": "otplib", + "@tummycrypt_tinyland_auth//:node_modules/qrcode": "qrcode", + }, + src = ":auth_registry_package", +) + +filegroup( + name = "auth_pg_registry_files", + srcs = ["@tummycrypt_tinyland_auth_pg//:pkg"], +) + +npm_package( + name = "auth_pg_registry_package", + srcs = [":auth_pg_registry_files"], + include_external_repositories = ["tummycrypt_tinyland_auth_pg+"], + package = "@tummycrypt/tinyland-auth-pg", + root_paths = ["pkg"], + version = "0.2.5", +) + +npm_link_package( + name = "node_modules/@tummycrypt/tinyland-auth-pg", + deps = { + ":node_modules/@tummycrypt/tinyland-auth": "@tummycrypt/tinyland-auth", + "@tummycrypt_tinyland_auth_pg//:node_modules/@neondatabase/serverless": "@neondatabase/serverless", + "@tummycrypt_tinyland_auth_pg//:node_modules/drizzle-orm": "drizzle-orm", + "@tummycrypt_tinyland_auth_pg//:node_modules/pg": "pg", + }, + src = ":auth_pg_registry_package", +) + +js_test( + name = "consumer_test", + entry_point = "consumer.test.mjs", + data = [ + ":node_modules/@tummycrypt/tinyland-auth", + ":node_modules/@tummycrypt/tinyland-auth-pg", + ], +) diff --git a/tests/bzlmod-consumer/MODULE.bazel.template b/tests/bzlmod-consumer/MODULE.bazel.template new file mode 100644 index 0000000..8945637 --- /dev/null +++ b/tests/bzlmod-consumer/MODULE.bazel.template @@ -0,0 +1,19 @@ +module( + name = "tin_2923_auth_pg_consumer_proof", + version = "0.0.0", +) + +bazel_dep(name = "aspect_rules_js", version = "2.9.1") +bazel_dep(name = "rules_nodejs", version = "6.7.3") +bazel_dep(name = "tummycrypt_tinyland_auth", version = "0.3.3") +bazel_dep(name = "tummycrypt_tinyland_auth_pg", version = "0.2.5") + +# The candidate is not in the immutable registry yet. Only the package under +# test is overridden; auth must still resolve from its exact registry module. +local_path_override( + module_name = "tummycrypt_tinyland_auth_pg", + path = __AUTH_PG_ROOT__, +) + +node = use_extension("@rules_nodejs//nodejs:extensions.bzl", "node") +node.toolchain(node_version = "22.13.1") diff --git a/tests/bzlmod-consumer/consumer.test.mjs b/tests/bzlmod-consumer/consumer.test.mjs new file mode 100644 index 0000000..1bc7676 --- /dev/null +++ b/tests/bzlmod-consumer/consumer.test.mjs @@ -0,0 +1,11 @@ +import assert from 'node:assert/strict'; + +import { hashPassword } from '@tummycrypt/tinyland-auth'; +import { createPgStorageAdapter } from '@tummycrypt/tinyland-auth-pg'; + +assert.equal(typeof hashPassword, 'function'); +assert.equal(typeof createPgStorageAdapter, 'function'); +assert.throws( + () => createPgStorageAdapter({ db: null }), + /`db` must be a pre-built Drizzle database instance/, +); diff --git a/tests/package-artifact.test.mjs b/tests/package-artifact.test.mjs new file mode 100644 index 0000000..f9fceaa --- /dev/null +++ b/tests/package-artifact.test.mjs @@ -0,0 +1,101 @@ +import assert from 'node:assert/strict'; +import { access, readFile } from 'node:fs/promises'; +import { resolve } from 'node:path'; +import { pathToFileURL } from 'node:url'; + +const packageRoot = resolve(process.argv[2]); +const manifest = JSON.parse(await readFile(resolve(packageRoot, 'package.json'), 'utf8')); + +assert.equal(manifest.name, '@tummycrypt/tinyland-auth-pg'); +assert.equal(manifest.version, '0.2.5'); +assert.deepEqual(manifest.peerDependencies, { + '@tummycrypt/tinyland-auth': '^0.3.0', +}); +assert.equal(manifest.dependencies?.['@tummycrypt/tinyland-auth'], undefined); +assert.equal(manifest.devDependencies, undefined); +assert.equal(manifest.scripts, undefined); +assert.equal(manifest.publishConfig, undefined); +await assert.rejects(access(resolve(packageRoot, 'node_modules'))); + +const requiredPaths = [ + 'dist/index.js', + 'dist/index.d.ts', + 'drizzle/0000_lush_carmella_unuscione.sql', + 'drizzle/meta/0000_snapshot.json', + 'drizzle/meta/_journal.json', + 'drizzle-public/0000_worthless_post.sql', + 'drizzle-public/meta/0000_snapshot.json', + 'drizzle-public/meta/_journal.json', +]; +await Promise.all(requiredPaths.map((relativePath) => access(resolve(packageRoot, relativePath)))); + +const runtime = await import(pathToFileURL(resolve(packageRoot, 'dist/index.js')).href); +assert.equal(typeof runtime.createPgStorageAdapter, 'function'); +assert.equal(typeof runtime.createNodePgStorageAdapter, 'function'); +assert.equal(typeof runtime.bootstrapUsers, 'function'); +assert.throws( + () => runtime.createPgStorageAdapter({ db: null }), + /`db` is required when using driver injection/, +); + +const authMigration = await readFile( + resolve(packageRoot, 'drizzle/0000_lush_carmella_unuscione.sql'), + 'utf8', +); +for (const table of [ + 'audit_events', + 'backup_codes', + 'invitations', + 'sessions', + 'totp_secrets', + 'users', +]) { + assert.ok(authMigration.includes(`CREATE TABLE "auth"."${table}"`), table); +} +assert.ok( + authMigration.includes( + 'CREATE UNIQUE INDEX "users_tenant_handle_unique" ON "auth"."users" USING btree ("tenant_id","handle")', + ), +); + +const publicMigration = await readFile( + resolve(packageRoot, 'drizzle-public/0000_worthless_post.sql'), + 'utf8', +); +for (const table of [ + 'appointments', + 'bookings', + 'business_hours', + 'business_hours_overrides', + 'business_profile', + 'clients', + 'gift_certificates', + 'intake_form_responses', + 'intake_form_templates', + 'local_bookings', + 'packages', + 'payments', + 'practitioners', + 'redemptions', + 'reviews', + 'services', + 'slot_reservations', + 'time_blocks', +]) { + assert.ok(publicMigration.includes(`CREATE TABLE "${table}"`), table); +} + +const authJournal = JSON.parse( + await readFile(resolve(packageRoot, 'drizzle/meta/_journal.json'), 'utf8'), +); +const publicJournal = JSON.parse( + await readFile(resolve(packageRoot, 'drizzle-public/meta/_journal.json'), 'utf8'), +); +assert.deepEqual( + authJournal.entries.map(({ idx, tag }) => ({ idx, tag })), + [{ idx: 0, tag: '0000_lush_carmella_unuscione' }], +); +assert.deepEqual( + publicJournal.entries.map(({ idx, tag }) => ({ idx, tag })), + [{ idx: 0, tag: '0000_worthless_post' }], +);