@enbox/gitd 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +177 -0
- package/README.md +134 -0
- package/dist/esm/ci.js +76 -0
- package/dist/esm/ci.js.map +1 -0
- package/dist/esm/cli/agent.js +86 -0
- package/dist/esm/cli/agent.js.map +1 -0
- package/dist/esm/cli/commands/ci.js +278 -0
- package/dist/esm/cli/commands/ci.js.map +1 -0
- package/dist/esm/cli/commands/clone.js +77 -0
- package/dist/esm/cli/commands/clone.js.map +1 -0
- package/dist/esm/cli/commands/daemon.js +132 -0
- package/dist/esm/cli/commands/daemon.js.map +1 -0
- package/dist/esm/cli/commands/github-api.js +36 -0
- package/dist/esm/cli/commands/github-api.js.map +1 -0
- package/dist/esm/cli/commands/init.js +69 -0
- package/dist/esm/cli/commands/init.js.map +1 -0
- package/dist/esm/cli/commands/issue.js +293 -0
- package/dist/esm/cli/commands/issue.js.map +1 -0
- package/dist/esm/cli/commands/log.js +90 -0
- package/dist/esm/cli/commands/log.js.map +1 -0
- package/dist/esm/cli/commands/migrate.js +444 -0
- package/dist/esm/cli/commands/migrate.js.map +1 -0
- package/dist/esm/cli/commands/notification.js +141 -0
- package/dist/esm/cli/commands/notification.js.map +1 -0
- package/dist/esm/cli/commands/org.js +353 -0
- package/dist/esm/cli/commands/org.js.map +1 -0
- package/dist/esm/cli/commands/patch.js +375 -0
- package/dist/esm/cli/commands/patch.js.map +1 -0
- package/dist/esm/cli/commands/registry.js +501 -0
- package/dist/esm/cli/commands/registry.js.map +1 -0
- package/dist/esm/cli/commands/release.js +197 -0
- package/dist/esm/cli/commands/release.js.map +1 -0
- package/dist/esm/cli/commands/repo.js +148 -0
- package/dist/esm/cli/commands/repo.js.map +1 -0
- package/dist/esm/cli/commands/serve.js +148 -0
- package/dist/esm/cli/commands/serve.js.map +1 -0
- package/dist/esm/cli/commands/setup.js +92 -0
- package/dist/esm/cli/commands/setup.js.map +1 -0
- package/dist/esm/cli/commands/shim.js +75 -0
- package/dist/esm/cli/commands/shim.js.map +1 -0
- package/dist/esm/cli/commands/social.js +206 -0
- package/dist/esm/cli/commands/social.js.map +1 -0
- package/dist/esm/cli/commands/web.js +36 -0
- package/dist/esm/cli/commands/web.js.map +1 -0
- package/dist/esm/cli/commands/wiki.js +185 -0
- package/dist/esm/cli/commands/wiki.js.map +1 -0
- package/dist/esm/cli/flags.js +29 -0
- package/dist/esm/cli/flags.js.map +1 -0
- package/dist/esm/cli/main.js +331 -0
- package/dist/esm/cli/main.js.map +1 -0
- package/dist/esm/cli/repo-context.js +53 -0
- package/dist/esm/cli/repo-context.js.map +1 -0
- package/dist/esm/daemon/adapter.js +18 -0
- package/dist/esm/daemon/adapter.js.map +1 -0
- package/dist/esm/daemon/adapters/github.js +112 -0
- package/dist/esm/daemon/adapters/github.js.map +1 -0
- package/dist/esm/daemon/adapters/go.js +51 -0
- package/dist/esm/daemon/adapters/go.js.map +1 -0
- package/dist/esm/daemon/adapters/index.js +32 -0
- package/dist/esm/daemon/adapters/index.js.map +1 -0
- package/dist/esm/daemon/adapters/npm.js +51 -0
- package/dist/esm/daemon/adapters/npm.js.map +1 -0
- package/dist/esm/daemon/adapters/oci.js +62 -0
- package/dist/esm/daemon/adapters/oci.js.map +1 -0
- package/dist/esm/daemon/index.js +12 -0
- package/dist/esm/daemon/index.js.map +1 -0
- package/dist/esm/daemon/server.js +167 -0
- package/dist/esm/daemon/server.js.map +1 -0
- package/dist/esm/git-remote/credential-helper.js +106 -0
- package/dist/esm/git-remote/credential-helper.js.map +1 -0
- package/dist/esm/git-remote/credential-main.js +109 -0
- package/dist/esm/git-remote/credential-main.js.map +1 -0
- package/dist/esm/git-remote/index.js +10 -0
- package/dist/esm/git-remote/index.js.map +1 -0
- package/dist/esm/git-remote/main.js +78 -0
- package/dist/esm/git-remote/main.js.map +1 -0
- package/dist/esm/git-remote/parse-url.js +60 -0
- package/dist/esm/git-remote/parse-url.js.map +1 -0
- package/dist/esm/git-remote/resolve.js +175 -0
- package/dist/esm/git-remote/resolve.js.map +1 -0
- package/dist/esm/git-remote/service.js +82 -0
- package/dist/esm/git-remote/service.js.map +1 -0
- package/dist/esm/git-server/auth.js +211 -0
- package/dist/esm/git-server/auth.js.map +1 -0
- package/dist/esm/git-server/bundle-restore.js +180 -0
- package/dist/esm/git-server/bundle-restore.js.map +1 -0
- package/dist/esm/git-server/bundle-sync.js +233 -0
- package/dist/esm/git-server/bundle-sync.js.map +1 -0
- package/dist/esm/git-server/did-service.js +73 -0
- package/dist/esm/git-server/did-service.js.map +1 -0
- package/dist/esm/git-server/git-backend.js +186 -0
- package/dist/esm/git-server/git-backend.js.map +1 -0
- package/dist/esm/git-server/http-handler.js +295 -0
- package/dist/esm/git-server/http-handler.js.map +1 -0
- package/dist/esm/git-server/index.js +16 -0
- package/dist/esm/git-server/index.js.map +1 -0
- package/dist/esm/git-server/push-authorizer.js +62 -0
- package/dist/esm/git-server/push-authorizer.js.map +1 -0
- package/dist/esm/git-server/ref-sync.js +132 -0
- package/dist/esm/git-server/ref-sync.js.map +1 -0
- package/dist/esm/git-server/server.js +185 -0
- package/dist/esm/git-server/server.js.map +1 -0
- package/dist/esm/git-server/verify.js +109 -0
- package/dist/esm/git-server/verify.js.map +1 -0
- package/dist/esm/github-shim/helpers.js +273 -0
- package/dist/esm/github-shim/helpers.js.map +1 -0
- package/dist/esm/github-shim/index.js +13 -0
- package/dist/esm/github-shim/index.js.map +1 -0
- package/dist/esm/github-shim/issues.js +318 -0
- package/dist/esm/github-shim/issues.js.map +1 -0
- package/dist/esm/github-shim/pulls.js +423 -0
- package/dist/esm/github-shim/pulls.js.map +1 -0
- package/dist/esm/github-shim/releases.js +154 -0
- package/dist/esm/github-shim/releases.js.map +1 -0
- package/dist/esm/github-shim/repos.js +86 -0
- package/dist/esm/github-shim/repos.js.map +1 -0
- package/dist/esm/github-shim/server.js +351 -0
- package/dist/esm/github-shim/server.js.map +1 -0
- package/dist/esm/github-shim/users.js +61 -0
- package/dist/esm/github-shim/users.js.map +1 -0
- package/dist/esm/index.js +26 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/indexer/api.js +132 -0
- package/dist/esm/indexer/api.js.map +1 -0
- package/dist/esm/indexer/crawler.js +256 -0
- package/dist/esm/indexer/crawler.js.map +1 -0
- package/dist/esm/indexer/index.js +9 -0
- package/dist/esm/indexer/index.js.map +1 -0
- package/dist/esm/indexer/main.js +76 -0
- package/dist/esm/indexer/main.js.map +1 -0
- package/dist/esm/indexer/store.js +334 -0
- package/dist/esm/indexer/store.js.map +1 -0
- package/dist/esm/issues.js +133 -0
- package/dist/esm/issues.js.map +1 -0
- package/dist/esm/notifications.js +47 -0
- package/dist/esm/notifications.js.map +1 -0
- package/dist/esm/org.js +90 -0
- package/dist/esm/org.js.map +1 -0
- package/dist/esm/patches.js +136 -0
- package/dist/esm/patches.js.map +1 -0
- package/dist/esm/refs.js +54 -0
- package/dist/esm/refs.js.map +1 -0
- package/dist/esm/registry.js +81 -0
- package/dist/esm/registry.js.map +1 -0
- package/dist/esm/releases.js +78 -0
- package/dist/esm/releases.js.map +1 -0
- package/dist/esm/repo.js +150 -0
- package/dist/esm/repo.js.map +1 -0
- package/dist/esm/resolver/index.js +10 -0
- package/dist/esm/resolver/index.js.map +1 -0
- package/dist/esm/resolver/resolve.js +189 -0
- package/dist/esm/resolver/resolve.js.map +1 -0
- package/dist/esm/resolver/trust-chain.js +155 -0
- package/dist/esm/resolver/trust-chain.js.map +1 -0
- package/dist/esm/resolver/verify.js +186 -0
- package/dist/esm/resolver/verify.js.map +1 -0
- package/dist/esm/shims/go/index.js +9 -0
- package/dist/esm/shims/go/index.js.map +1 -0
- package/dist/esm/shims/go/proxy.js +275 -0
- package/dist/esm/shims/go/proxy.js.map +1 -0
- package/dist/esm/shims/go/server.js +70 -0
- package/dist/esm/shims/go/server.js.map +1 -0
- package/dist/esm/shims/index.js +15 -0
- package/dist/esm/shims/index.js.map +1 -0
- package/dist/esm/shims/npm/index.js +9 -0
- package/dist/esm/shims/npm/index.js.map +1 -0
- package/dist/esm/shims/npm/registry.js +234 -0
- package/dist/esm/shims/npm/registry.js.map +1 -0
- package/dist/esm/shims/npm/server.js +72 -0
- package/dist/esm/shims/npm/server.js.map +1 -0
- package/dist/esm/shims/oci/index.js +9 -0
- package/dist/esm/shims/oci/index.js.map +1 -0
- package/dist/esm/shims/oci/registry.js +276 -0
- package/dist/esm/shims/oci/registry.js.map +1 -0
- package/dist/esm/shims/oci/server.js +82 -0
- package/dist/esm/shims/oci/server.js.map +1 -0
- package/dist/esm/social.js +70 -0
- package/dist/esm/social.js.map +1 -0
- package/dist/esm/web/html.js +123 -0
- package/dist/esm/web/html.js.map +1 -0
- package/dist/esm/web/index.js +7 -0
- package/dist/esm/web/index.js.map +1 -0
- package/dist/esm/web/routes.js +420 -0
- package/dist/esm/web/routes.js.map +1 -0
- package/dist/esm/web/server.js +225 -0
- package/dist/esm/web/server.js.map +1 -0
- package/dist/esm/wiki.js +63 -0
- package/dist/esm/wiki.js.map +1 -0
- package/dist/types/ci.d.ts +203 -0
- package/dist/types/ci.d.ts.map +1 -0
- package/dist/types/cli/agent.d.ts +59 -0
- package/dist/types/cli/agent.d.ts.map +1 -0
- package/dist/types/cli/commands/ci.d.ts +16 -0
- package/dist/types/cli/commands/ci.d.ts.map +1 -0
- package/dist/types/cli/commands/clone.d.ts +13 -0
- package/dist/types/cli/commands/clone.d.ts.map +1 -0
- package/dist/types/cli/commands/daemon.d.ts +29 -0
- package/dist/types/cli/commands/daemon.d.ts.map +1 -0
- package/dist/types/cli/commands/github-api.d.ts +14 -0
- package/dist/types/cli/commands/github-api.d.ts.map +1 -0
- package/dist/types/cli/commands/init.d.ts +11 -0
- package/dist/types/cli/commands/init.d.ts.map +1 -0
- package/dist/types/cli/commands/issue.d.ts +16 -0
- package/dist/types/cli/commands/issue.d.ts.map +1 -0
- package/dist/types/cli/commands/log.d.ts +13 -0
- package/dist/types/cli/commands/log.d.ts.map +1 -0
- package/dist/types/cli/commands/migrate.d.ts +19 -0
- package/dist/types/cli/commands/migrate.d.ts.map +1 -0
- package/dist/types/cli/commands/notification.d.ts +16 -0
- package/dist/types/cli/commands/notification.d.ts.map +1 -0
- package/dist/types/cli/commands/org.d.ts +19 -0
- package/dist/types/cli/commands/org.d.ts.map +1 -0
- package/dist/types/cli/commands/patch.d.ts +17 -0
- package/dist/types/cli/commands/patch.d.ts.map +1 -0
- package/dist/types/cli/commands/registry.d.ts +25 -0
- package/dist/types/cli/commands/registry.d.ts.map +1 -0
- package/dist/types/cli/commands/release.d.ts +13 -0
- package/dist/types/cli/commands/release.d.ts.map +1 -0
- package/dist/types/cli/commands/repo.d.ts +15 -0
- package/dist/types/cli/commands/repo.d.ts.map +1 -0
- package/dist/types/cli/commands/serve.d.ts +22 -0
- package/dist/types/cli/commands/serve.d.ts.map +1 -0
- package/dist/types/cli/commands/setup.d.ts +16 -0
- package/dist/types/cli/commands/setup.d.ts.map +1 -0
- package/dist/types/cli/commands/shim.d.ts +16 -0
- package/dist/types/cli/commands/shim.d.ts.map +1 -0
- package/dist/types/cli/commands/social.d.ts +19 -0
- package/dist/types/cli/commands/social.d.ts.map +1 -0
- package/dist/types/cli/commands/web.d.ts +14 -0
- package/dist/types/cli/commands/web.d.ts.map +1 -0
- package/dist/types/cli/commands/wiki.d.ts +14 -0
- package/dist/types/cli/commands/wiki.d.ts.map +1 -0
- package/dist/types/cli/flags.d.ts +16 -0
- package/dist/types/cli/flags.d.ts.map +1 -0
- package/dist/types/cli/main.d.ts +69 -0
- package/dist/types/cli/main.d.ts.map +1 -0
- package/dist/types/cli/repo-context.d.ts +30 -0
- package/dist/types/cli/repo-context.d.ts.map +1 -0
- package/dist/types/daemon/adapter.d.ts +74 -0
- package/dist/types/daemon/adapter.d.ts.map +1 -0
- package/dist/types/daemon/adapters/github.d.ts +10 -0
- package/dist/types/daemon/adapters/github.d.ts.map +1 -0
- package/dist/types/daemon/adapters/go.d.ts +10 -0
- package/dist/types/daemon/adapters/go.d.ts.map +1 -0
- package/dist/types/daemon/adapters/index.d.ts +22 -0
- package/dist/types/daemon/adapters/index.d.ts.map +1 -0
- package/dist/types/daemon/adapters/npm.d.ts +10 -0
- package/dist/types/daemon/adapters/npm.d.ts.map +1 -0
- package/dist/types/daemon/adapters/oci.d.ts +10 -0
- package/dist/types/daemon/adapters/oci.d.ts.map +1 -0
- package/dist/types/daemon/index.d.ts +14 -0
- package/dist/types/daemon/index.d.ts.map +1 -0
- package/dist/types/daemon/server.d.ts +55 -0
- package/dist/types/daemon/server.d.ts.map +1 -0
- package/dist/types/git-remote/credential-helper.d.ts +49 -0
- package/dist/types/git-remote/credential-helper.d.ts.map +1 -0
- package/dist/types/git-remote/credential-main.d.ts +24 -0
- package/dist/types/git-remote/credential-main.d.ts.map +1 -0
- package/dist/types/git-remote/index.d.ts +10 -0
- package/dist/types/git-remote/index.d.ts.map +1 -0
- package/dist/types/git-remote/main.d.ts +23 -0
- package/dist/types/git-remote/main.d.ts.map +1 -0
- package/dist/types/git-remote/parse-url.d.ts +32 -0
- package/dist/types/git-remote/parse-url.d.ts.map +1 -0
- package/dist/types/git-remote/resolve.d.ts +30 -0
- package/dist/types/git-remote/resolve.d.ts.map +1 -0
- package/dist/types/git-remote/service.d.ts +75 -0
- package/dist/types/git-remote/service.d.ts.map +1 -0
- package/dist/types/git-server/auth.d.ts +129 -0
- package/dist/types/git-server/auth.d.ts.map +1 -0
- package/dist/types/git-server/bundle-restore.d.ts +48 -0
- package/dist/types/git-server/bundle-restore.d.ts.map +1 -0
- package/dist/types/git-server/bundle-sync.d.ts +90 -0
- package/dist/types/git-server/bundle-sync.d.ts.map +1 -0
- package/dist/types/git-server/did-service.d.ts +26 -0
- package/dist/types/git-server/did-service.d.ts.map +1 -0
- package/dist/types/git-server/git-backend.d.ts +84 -0
- package/dist/types/git-server/git-backend.d.ts.map +1 -0
- package/dist/types/git-server/http-handler.d.ts +73 -0
- package/dist/types/git-server/http-handler.d.ts.map +1 -0
- package/dist/types/git-server/index.d.ts +16 -0
- package/dist/types/git-server/index.d.ts.map +1 -0
- package/dist/types/git-server/push-authorizer.d.ts +38 -0
- package/dist/types/git-server/push-authorizer.d.ts.map +1 -0
- package/dist/types/git-server/ref-sync.d.ts +52 -0
- package/dist/types/git-server/ref-sync.d.ts.map +1 -0
- package/dist/types/git-server/server.d.ts +70 -0
- package/dist/types/git-server/server.d.ts.map +1 -0
- package/dist/types/git-server/verify.d.ts +12 -0
- package/dist/types/git-server/verify.d.ts.map +1 -0
- package/dist/types/github-shim/helpers.d.ts +108 -0
- package/dist/types/github-shim/helpers.d.ts.map +1 -0
- package/dist/types/github-shim/index.d.ts +15 -0
- package/dist/types/github-shim/index.d.ts.map +1 -0
- package/dist/types/github-shim/issues.d.ts +24 -0
- package/dist/types/github-shim/issues.d.ts.map +1 -0
- package/dist/types/github-shim/pulls.d.ts +31 -0
- package/dist/types/github-shim/pulls.d.ts.map +1 -0
- package/dist/types/github-shim/releases.d.ts +18 -0
- package/dist/types/github-shim/releases.d.ts.map +1 -0
- package/dist/types/github-shim/repos.d.ts +21 -0
- package/dist/types/github-shim/repos.d.ts.map +1 -0
- package/dist/types/github-shim/server.d.ts +53 -0
- package/dist/types/github-shim/server.d.ts.map +1 -0
- package/dist/types/github-shim/users.d.ts +17 -0
- package/dist/types/github-shim/users.d.ts.map +1 -0
- package/dist/types/index.d.ts +26 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/indexer/api.d.ts +32 -0
- package/dist/types/indexer/api.d.ts.map +1 -0
- package/dist/types/indexer/crawler.d.ts +72 -0
- package/dist/types/indexer/crawler.d.ts.map +1 -0
- package/dist/types/indexer/index.d.ts +12 -0
- package/dist/types/indexer/index.d.ts.map +1 -0
- package/dist/types/indexer/main.d.ts +21 -0
- package/dist/types/indexer/main.d.ts.map +1 -0
- package/dist/types/indexer/store.d.ts +168 -0
- package/dist/types/indexer/store.d.ts.map +1 -0
- package/dist/types/issues.d.ts +395 -0
- package/dist/types/issues.d.ts.map +1 -0
- package/dist/types/notifications.d.ts +93 -0
- package/dist/types/notifications.d.ts.map +1 -0
- package/dist/types/org.d.ts +232 -0
- package/dist/types/org.d.ts.map +1 -0
- package/dist/types/patches.d.ts +410 -0
- package/dist/types/patches.d.ts.map +1 -0
- package/dist/types/refs.d.ts +114 -0
- package/dist/types/refs.d.ts.map +1 -0
- package/dist/types/registry.d.ts +212 -0
- package/dist/types/registry.d.ts.map +1 -0
- package/dist/types/releases.d.ts +204 -0
- package/dist/types/releases.d.ts.map +1 -0
- package/dist/types/repo.d.ts +450 -0
- package/dist/types/repo.d.ts.map +1 -0
- package/dist/types/resolver/index.d.ts +13 -0
- package/dist/types/resolver/index.d.ts.map +1 -0
- package/dist/types/resolver/resolve.d.ts +80 -0
- package/dist/types/resolver/resolve.d.ts.map +1 -0
- package/dist/types/resolver/trust-chain.d.ts +54 -0
- package/dist/types/resolver/trust-chain.d.ts.map +1 -0
- package/dist/types/resolver/verify.d.ts +62 -0
- package/dist/types/resolver/verify.d.ts.map +1 -0
- package/dist/types/shims/go/index.d.ts +11 -0
- package/dist/types/shims/go/index.d.ts.map +1 -0
- package/dist/types/shims/go/proxy.d.ts +51 -0
- package/dist/types/shims/go/proxy.d.ts.map +1 -0
- package/dist/types/shims/go/server.d.ts +23 -0
- package/dist/types/shims/go/server.d.ts.map +1 -0
- package/dist/types/shims/index.d.ts +18 -0
- package/dist/types/shims/index.d.ts.map +1 -0
- package/dist/types/shims/npm/index.d.ts +11 -0
- package/dist/types/shims/npm/index.d.ts.map +1 -0
- package/dist/types/shims/npm/registry.d.ts +46 -0
- package/dist/types/shims/npm/registry.d.ts.map +1 -0
- package/dist/types/shims/npm/server.d.ts +23 -0
- package/dist/types/shims/npm/server.d.ts.map +1 -0
- package/dist/types/shims/oci/index.d.ts +11 -0
- package/dist/types/shims/oci/index.d.ts.map +1 -0
- package/dist/types/shims/oci/registry.d.ts +56 -0
- package/dist/types/shims/oci/registry.d.ts.map +1 -0
- package/dist/types/shims/oci/server.d.ts +23 -0
- package/dist/types/shims/oci/server.d.ts.map +1 -0
- package/dist/types/social.d.ts +162 -0
- package/dist/types/social.d.ts.map +1 -0
- package/dist/types/web/html.d.ts +23 -0
- package/dist/types/web/html.d.ts.map +1 -0
- package/dist/types/web/index.d.ts +8 -0
- package/dist/types/web/index.d.ts.map +1 -0
- package/dist/types/web/routes.d.ts +21 -0
- package/dist/types/web/routes.d.ts.map +1 -0
- package/dist/types/web/server.d.ts +38 -0
- package/dist/types/web/server.d.ts.map +1 -0
- package/dist/types/wiki.d.ts +143 -0
- package/dist/types/wiki.d.ts.map +1 -0
- package/package.json +108 -0
- package/schemas/ci/check-run.json +23 -0
- package/schemas/ci/check-suite.json +23 -0
- package/schemas/issues/assignment.json +17 -0
- package/schemas/issues/comment.json +14 -0
- package/schemas/issues/issue.json +20 -0
- package/schemas/issues/label.json +17 -0
- package/schemas/issues/reaction.json +14 -0
- package/schemas/issues/status-change.json +14 -0
- package/schemas/notifications/notification.json +20 -0
- package/schemas/org/org-member.json +17 -0
- package/schemas/org/org.json +26 -0
- package/schemas/org/team-member.json +17 -0
- package/schemas/org/team.json +17 -0
- package/schemas/patches/merge-result.json +14 -0
- package/schemas/patches/patch-status-change.json +14 -0
- package/schemas/patches/patch.json +20 -0
- package/schemas/patches/review-comment.json +17 -0
- package/schemas/patches/review.json +14 -0
- package/schemas/patches/revision.json +30 -0
- package/schemas/refs/git-ref.json +32 -0
- package/schemas/registry/attestation.json +23 -0
- package/schemas/registry/package-version.json +23 -0
- package/schemas/registry/package.json +32 -0
- package/schemas/releases/release.json +17 -0
- package/schemas/repo/collaborator.json +17 -0
- package/schemas/repo/repo.json +35 -0
- package/schemas/repo/settings.json +39 -0
- package/schemas/repo/topic.json +14 -0
- package/schemas/repo/webhook.json +26 -0
- package/schemas/social/activity.json +23 -0
- package/schemas/social/follow.json +17 -0
- package/schemas/social/star.json +20 -0
- package/schemas/wiki/wiki-history.json +20 -0
- package/schemas/wiki/wiki-page.json +17 -0
- package/src/ci.ts +118 -0
- package/src/cli/agent.ts +117 -0
- package/src/cli/commands/ci.ts +300 -0
- package/src/cli/commands/clone.ts +78 -0
- package/src/cli/commands/daemon.ts +129 -0
- package/src/cli/commands/github-api.ts +30 -0
- package/src/cli/commands/init.ts +69 -0
- package/src/cli/commands/issue.ts +321 -0
- package/src/cli/commands/log.ts +106 -0
- package/src/cli/commands/migrate.ts +525 -0
- package/src/cli/commands/notification.ts +148 -0
- package/src/cli/commands/org.ts +381 -0
- package/src/cli/commands/patch.ts +413 -0
- package/src/cli/commands/registry.ts +542 -0
- package/src/cli/commands/release.ts +189 -0
- package/src/cli/commands/repo.ts +160 -0
- package/src/cli/commands/serve.ts +153 -0
- package/src/cli/commands/setup.ts +97 -0
- package/src/cli/commands/shim.ts +79 -0
- package/src/cli/commands/social.ts +221 -0
- package/src/cli/commands/web.ts +30 -0
- package/src/cli/commands/wiki.ts +199 -0
- package/src/cli/flags.ts +28 -0
- package/src/cli/main.ts +350 -0
- package/src/cli/repo-context.ts +55 -0
- package/src/daemon/adapter.ts +95 -0
- package/src/daemon/adapters/github.ts +86 -0
- package/src/daemon/adapters/go.ts +47 -0
- package/src/daemon/adapters/index.ts +36 -0
- package/src/daemon/adapters/npm.ts +47 -0
- package/src/daemon/adapters/oci.ts +59 -0
- package/src/daemon/index.ts +16 -0
- package/src/daemon/server.ts +204 -0
- package/src/git-remote/credential-helper.ts +114 -0
- package/src/git-remote/credential-main.ts +118 -0
- package/src/git-remote/index.ts +10 -0
- package/src/git-remote/main.ts +74 -0
- package/src/git-remote/parse-url.ts +81 -0
- package/src/git-remote/resolve.ts +207 -0
- package/src/git-remote/service.ts +126 -0
- package/src/git-server/auth.ts +308 -0
- package/src/git-server/bundle-restore.ts +217 -0
- package/src/git-server/bundle-sync.ts +300 -0
- package/src/git-server/did-service.ts +77 -0
- package/src/git-server/git-backend.ts +222 -0
- package/src/git-server/http-handler.ts +386 -0
- package/src/git-server/index.ts +16 -0
- package/src/git-server/push-authorizer.ts +77 -0
- package/src/git-server/ref-sync.ts +166 -0
- package/src/git-server/server.ts +236 -0
- package/src/git-server/verify.ts +116 -0
- package/src/github-shim/helpers.ts +311 -0
- package/src/github-shim/index.ts +35 -0
- package/src/github-shim/issues.ts +389 -0
- package/src/github-shim/pulls.ts +500 -0
- package/src/github-shim/releases.ts +185 -0
- package/src/github-shim/repos.ts +95 -0
- package/src/github-shim/server.ts +334 -0
- package/src/github-shim/users.ts +63 -0
- package/src/index.ts +26 -0
- package/src/indexer/api.ts +162 -0
- package/src/indexer/crawler.ts +290 -0
- package/src/indexer/index.ts +22 -0
- package/src/indexer/main.ts +83 -0
- package/src/indexer/store.ts +408 -0
- package/src/issues.ts +200 -0
- package/src/notifications.ts +80 -0
- package/src/org.ts +147 -0
- package/src/patches.ts +203 -0
- package/src/refs.ts +94 -0
- package/src/registry.ts +132 -0
- package/src/releases.ts +124 -0
- package/src/repo.ts +234 -0
- package/src/resolver/index.ts +42 -0
- package/src/resolver/resolve.ts +244 -0
- package/src/resolver/trust-chain.ts +217 -0
- package/src/resolver/verify.ts +237 -0
- package/src/shims/go/index.ts +14 -0
- package/src/shims/go/proxy.ts +336 -0
- package/src/shims/go/server.ts +82 -0
- package/src/shims/index.ts +20 -0
- package/src/shims/npm/index.ts +14 -0
- package/src/shims/npm/registry.ts +288 -0
- package/src/shims/npm/server.ts +84 -0
- package/src/shims/oci/index.ts +14 -0
- package/src/shims/oci/registry.ts +334 -0
- package/src/shims/oci/server.ts +94 -0
- package/src/social.ts +116 -0
- package/src/web/html.ts +120 -0
- package/src/web/index.ts +8 -0
- package/src/web/routes.ts +449 -0
- package/src/web/server.ts +256 -0
- package/src/wiki.ts +102 -0
|
@@ -0,0 +1,386 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Git smart HTTP transport handler.
|
|
3
|
+
*
|
|
4
|
+
* Implements the server side of Git's smart HTTP protocol (v1):
|
|
5
|
+
* - `GET /<did>/<repo>/info/refs?service=git-upload-pack` — ref discovery (clone/fetch)
|
|
6
|
+
* - `POST /<did>/<repo>/git-upload-pack` — pack negotiation (clone/fetch)
|
|
7
|
+
* - `GET /<did>/<repo>/info/refs?service=git-receive-pack` — ref discovery (push)
|
|
8
|
+
* - `POST /<did>/<repo>/git-receive-pack` — receive pack (push)
|
|
9
|
+
*
|
|
10
|
+
* When `onRepoNotFound` is provided, the handler auto-restores repos from
|
|
11
|
+
* DWN bundle records on first access (cold-start). This enables commodity
|
|
12
|
+
* git hosts to serve repos they've never seen before.
|
|
13
|
+
*
|
|
14
|
+
* The handler is a pure function `(Request) => Response | Promise<Response>`
|
|
15
|
+
* suitable for use with `Bun.serve()`, `Deno.serve()`, or any fetch-compatible
|
|
16
|
+
* HTTP runtime.
|
|
17
|
+
*
|
|
18
|
+
* URL format: `/<did>/<repo>/...`
|
|
19
|
+
* The DID is URL-encoded in the path (colons are preserved since they're
|
|
20
|
+
* valid in path segments).
|
|
21
|
+
*
|
|
22
|
+
* @module
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
import { spawn } from 'node:child_process';
|
|
26
|
+
|
|
27
|
+
import type { GitBackend } from './git-backend.js';
|
|
28
|
+
|
|
29
|
+
// ---------------------------------------------------------------------------
|
|
30
|
+
// Types
|
|
31
|
+
// ---------------------------------------------------------------------------
|
|
32
|
+
|
|
33
|
+
/** Options for creating the git HTTP handler. */
|
|
34
|
+
export type GitHttpHandlerOptions = {
|
|
35
|
+
/** The git backend for repository operations. */
|
|
36
|
+
backend: GitBackend;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Optional authentication callback for push operations.
|
|
40
|
+
* Called before `git-receive-pack` is allowed to proceed.
|
|
41
|
+
* Should return `true` if the request is authorized.
|
|
42
|
+
*
|
|
43
|
+
* @param request - The incoming HTTP request
|
|
44
|
+
* @param did - The repository owner's DID
|
|
45
|
+
* @param repo - The repository name
|
|
46
|
+
*/
|
|
47
|
+
authenticatePush?: (request: Request, did: string, repo: string) => Promise<boolean>;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Optional callback invoked after a successful `git receive-pack` (push).
|
|
51
|
+
* Use this for post-push operations like syncing refs to DWN records.
|
|
52
|
+
*
|
|
53
|
+
* @param did - The repository owner's DID
|
|
54
|
+
* @param repo - The repository name
|
|
55
|
+
* @param repoPath - Filesystem path to the bare repository
|
|
56
|
+
*/
|
|
57
|
+
onPushComplete?: (did: string, repo: string, repoPath: string) => Promise<void>;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Optional callback invoked when a clone/fetch request arrives for a
|
|
61
|
+
* repository that doesn't exist on disk. Implementations can restore
|
|
62
|
+
* the repo from DWN bundle records.
|
|
63
|
+
*
|
|
64
|
+
* @param did - The repository owner's DID
|
|
65
|
+
* @param repo - The repository name
|
|
66
|
+
* @param repoPath - The filesystem path where the repo should be created
|
|
67
|
+
* @returns `true` if the repo was restored successfully
|
|
68
|
+
*/
|
|
69
|
+
onRepoNotFound?: (did: string, repo: string, repoPath: string) => Promise<boolean>;
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Optional path prefix to strip from incoming URLs.
|
|
73
|
+
* For example, if the sidecar is mounted at `/git`, set this to `/git`.
|
|
74
|
+
* @default ''
|
|
75
|
+
*/
|
|
76
|
+
pathPrefix?: string;
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
/** Parsed route from a git smart HTTP URL. */
|
|
80
|
+
type GitRoute = {
|
|
81
|
+
did: string;
|
|
82
|
+
repo: string;
|
|
83
|
+
/** The path suffix after `/<did>/<repo>/`, e.g. `info/refs` or `git-upload-pack`. */
|
|
84
|
+
action: string;
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
// ---------------------------------------------------------------------------
|
|
88
|
+
// Handler factory
|
|
89
|
+
// ---------------------------------------------------------------------------
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Create a fetch-compatible HTTP handler for Git smart HTTP transport.
|
|
93
|
+
*
|
|
94
|
+
* @param options - Handler configuration
|
|
95
|
+
* @returns A function that handles incoming HTTP requests
|
|
96
|
+
*/
|
|
97
|
+
export function createGitHttpHandler(
|
|
98
|
+
options: GitHttpHandlerOptions,
|
|
99
|
+
): (request: Request) => Response | Promise<Response> {
|
|
100
|
+
const { backend, authenticatePush, onPushComplete, onRepoNotFound, pathPrefix = '' } = options;
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Ensure a repo exists on disk, attempting DWN bundle restore if absent.
|
|
104
|
+
* Returns `true` when the repo is available (or was restored).
|
|
105
|
+
*/
|
|
106
|
+
async function ensureRepo(did: string, repo: string): Promise<boolean> {
|
|
107
|
+
if (backend.exists(did, repo)) { return true; }
|
|
108
|
+
|
|
109
|
+
if (onRepoNotFound) {
|
|
110
|
+
const repoPath = backend.repoPath(did, repo);
|
|
111
|
+
try {
|
|
112
|
+
return await onRepoNotFound(did, repo, repoPath);
|
|
113
|
+
} catch (err) {
|
|
114
|
+
console.error(`onRepoNotFound error for ${did}/${repo}: ${(err as Error).message}`);
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return async (request: Request): Promise<Response> => {
|
|
123
|
+
const url = new URL(request.url);
|
|
124
|
+
let pathname = url.pathname;
|
|
125
|
+
|
|
126
|
+
// Strip path prefix.
|
|
127
|
+
if (pathPrefix && pathname.startsWith(pathPrefix)) {
|
|
128
|
+
pathname = pathname.slice(pathPrefix.length);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Parse the route.
|
|
132
|
+
const route = parseRoute(pathname);
|
|
133
|
+
if (!route) {
|
|
134
|
+
return new Response('Not Found', { status: 404 });
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
const { did, repo, action } = route;
|
|
138
|
+
|
|
139
|
+
// -----------------------------------------------------------------------
|
|
140
|
+
// GET /<did>/<repo>/info/refs?service=<service>
|
|
141
|
+
// -----------------------------------------------------------------------
|
|
142
|
+
if (request.method === 'GET' && action === 'info/refs') {
|
|
143
|
+
const service = url.searchParams.get('service');
|
|
144
|
+
if (service !== 'git-upload-pack' && service !== 'git-receive-pack') {
|
|
145
|
+
return new Response('Dumb HTTP transport is not supported. Use git smart HTTP.', { status: 403 });
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// Auth check for push ref discovery.
|
|
149
|
+
if (service === 'git-receive-pack' && authenticatePush) {
|
|
150
|
+
const authorized = await authenticatePush(request, did, repo);
|
|
151
|
+
if (!authorized) {
|
|
152
|
+
return new Response('Unauthorized', {
|
|
153
|
+
status : 401,
|
|
154
|
+
headers : { 'WWW-Authenticate': 'Basic realm="gitd"' },
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Ensure repo exists (auto-restore from DWN if possible).
|
|
160
|
+
if (!(await ensureRepo(did, repo))) {
|
|
161
|
+
return new Response('Repository not found', { status: 404 });
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
return handleInfoRefs(backend, did, repo, service);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// -----------------------------------------------------------------------
|
|
168
|
+
// POST /<did>/<repo>/git-upload-pack
|
|
169
|
+
// -----------------------------------------------------------------------
|
|
170
|
+
if (request.method === 'POST' && action === 'git-upload-pack') {
|
|
171
|
+
if (!(await ensureRepo(did, repo))) {
|
|
172
|
+
return new Response('Repository not found', { status: 404 });
|
|
173
|
+
}
|
|
174
|
+
return handleServiceRpc(backend, did, repo, 'upload-pack', request);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// -----------------------------------------------------------------------
|
|
178
|
+
// POST /<did>/<repo>/git-receive-pack
|
|
179
|
+
// -----------------------------------------------------------------------
|
|
180
|
+
if (request.method === 'POST' && action === 'git-receive-pack') {
|
|
181
|
+
// Auth check for push.
|
|
182
|
+
if (authenticatePush) {
|
|
183
|
+
const authorized = await authenticatePush(request, did, repo);
|
|
184
|
+
if (!authorized) {
|
|
185
|
+
return new Response('Unauthorized', {
|
|
186
|
+
status : 401,
|
|
187
|
+
headers : { 'WWW-Authenticate': 'Basic realm="gitd"' },
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
if (!(await ensureRepo(did, repo))) {
|
|
193
|
+
return new Response('Repository not found', { status: 404 });
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const response = await handleServiceRpc(backend, did, repo, 'receive-pack', request);
|
|
197
|
+
|
|
198
|
+
// Fire the post-push callback asynchronously (don't block the response).
|
|
199
|
+
if (onPushComplete && response.status === 200) {
|
|
200
|
+
const repoPath = backend.repoPath(did, repo);
|
|
201
|
+
onPushComplete(did, repo, repoPath).catch((err) => {
|
|
202
|
+
console.error(`onPushComplete error for ${did}/${repo}: ${(err as Error).message}`);
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
return response;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
return new Response('Not Found', { status: 404 });
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// ---------------------------------------------------------------------------
|
|
214
|
+
// Route parsing
|
|
215
|
+
// ---------------------------------------------------------------------------
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Parse a URL path into DID, repo, and action components.
|
|
219
|
+
*
|
|
220
|
+
* Expected format: `/<did>/<repo>/<action>`
|
|
221
|
+
* The DID occupies exactly 3 colon-separated segments: `did:<method>:<id>`.
|
|
222
|
+
* However, since the DID is in the URL path, we split by `/` and reconstruct.
|
|
223
|
+
*
|
|
224
|
+
* URL form: `/<did-scheme>:<did-method>:<did-id>/<repo>/<action...>`
|
|
225
|
+
* Example: `/did:dht:abc123/my-repo/info/refs`
|
|
226
|
+
*/
|
|
227
|
+
function parseRoute(pathname: string): GitRoute | undefined {
|
|
228
|
+
// Remove leading slash.
|
|
229
|
+
const path = pathname.startsWith('/') ? pathname.slice(1) : pathname;
|
|
230
|
+
|
|
231
|
+
// The DID is the first path segment (contains colons, not slashes).
|
|
232
|
+
const firstSlash = path.indexOf('/');
|
|
233
|
+
if (firstSlash === -1) { return undefined; }
|
|
234
|
+
|
|
235
|
+
const did = decodeURIComponent(path.slice(0, firstSlash));
|
|
236
|
+
|
|
237
|
+
// Validate it looks like a DID.
|
|
238
|
+
if (!did.startsWith('did:') || did.split(':').length < 3) {
|
|
239
|
+
return undefined;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
// Remaining path: <repo>/<action...>
|
|
243
|
+
const rest = path.slice(firstSlash + 1);
|
|
244
|
+
const secondSlash = rest.indexOf('/');
|
|
245
|
+
if (secondSlash === -1) { return undefined; }
|
|
246
|
+
|
|
247
|
+
const repo = rest.slice(0, secondSlash);
|
|
248
|
+
const action = rest.slice(secondSlash + 1);
|
|
249
|
+
|
|
250
|
+
if (!repo || !action) { return undefined; }
|
|
251
|
+
|
|
252
|
+
// Reject path-traversal and unsafe repo names.
|
|
253
|
+
if (!/^[a-zA-Z0-9._-]+$/.test(repo) || repo === '.' || repo === '..') {
|
|
254
|
+
return undefined;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
return { did, repo, action };
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// ---------------------------------------------------------------------------
|
|
261
|
+
// Git smart HTTP protocol handlers
|
|
262
|
+
// ---------------------------------------------------------------------------
|
|
263
|
+
|
|
264
|
+
/** Git pkt-line helper: encode a single line. */
|
|
265
|
+
function pktLine(line: string): string {
|
|
266
|
+
const len = line.length + 4;
|
|
267
|
+
return len.toString(16).padStart(4, '0') + line;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/** Git pkt-line flush: `0000`. */
|
|
271
|
+
const PKT_FLUSH = '0000';
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* Handle `GET /info/refs?service=<service>`.
|
|
275
|
+
*
|
|
276
|
+
* Runs `git <service> --stateless-rpc --advertise-refs` and wraps the output
|
|
277
|
+
* in the smart HTTP ref advertisement format.
|
|
278
|
+
*/
|
|
279
|
+
async function handleInfoRefs(
|
|
280
|
+
backend: GitBackend,
|
|
281
|
+
did: string,
|
|
282
|
+
repo: string,
|
|
283
|
+
service: 'git-upload-pack' | 'git-receive-pack',
|
|
284
|
+
): Promise<Response> {
|
|
285
|
+
const gitService = service === 'git-upload-pack' ? 'upload-pack' : 'receive-pack';
|
|
286
|
+
const repoPath = backend.repoPath(did, repo);
|
|
287
|
+
|
|
288
|
+
// Run git with --advertise-refs to get the ref listing.
|
|
289
|
+
const refData = await spawnAndCollect(gitService, repoPath);
|
|
290
|
+
|
|
291
|
+
if (refData === null) {
|
|
292
|
+
return new Response('Git service error', { status: 500 });
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
// Build the smart HTTP response: service announcement + ref data.
|
|
296
|
+
const encoder = new TextEncoder();
|
|
297
|
+
const announcement = pktLine(`# service=${service}\n`) + PKT_FLUSH;
|
|
298
|
+
const announcementBytes = encoder.encode(announcement);
|
|
299
|
+
|
|
300
|
+
const body = new Uint8Array(announcementBytes.length + refData.length);
|
|
301
|
+
body.set(announcementBytes, 0);
|
|
302
|
+
body.set(refData, announcementBytes.length);
|
|
303
|
+
|
|
304
|
+
return new Response(body, {
|
|
305
|
+
status : 200,
|
|
306
|
+
headers : {
|
|
307
|
+
'Content-Type' : `application/x-${service}-advertisement`,
|
|
308
|
+
'Cache-Control' : 'no-cache',
|
|
309
|
+
},
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* Handle `POST /git-upload-pack` or `POST /git-receive-pack`.
|
|
315
|
+
*
|
|
316
|
+
* Pipes the request body to `git <service> --stateless-rpc` stdin and
|
|
317
|
+
* streams stdout back as the response.
|
|
318
|
+
*/
|
|
319
|
+
async function handleServiceRpc(
|
|
320
|
+
backend: GitBackend,
|
|
321
|
+
did: string,
|
|
322
|
+
repo: string,
|
|
323
|
+
service: 'upload-pack' | 'receive-pack',
|
|
324
|
+
request: Request,
|
|
325
|
+
): Promise<Response> {
|
|
326
|
+
const gitProcess = service === 'upload-pack'
|
|
327
|
+
? backend.uploadPack(did, repo)
|
|
328
|
+
: backend.receivePack(did, repo);
|
|
329
|
+
|
|
330
|
+
// Pipe request body into git subprocess stdin.
|
|
331
|
+
if (request.body) {
|
|
332
|
+
const writer = gitProcess.stdin.getWriter();
|
|
333
|
+
const reader = request.body.getReader();
|
|
334
|
+
try {
|
|
335
|
+
while (true) {
|
|
336
|
+
const { done, value } = await reader.read();
|
|
337
|
+
if (done) { break; }
|
|
338
|
+
await writer.write(value);
|
|
339
|
+
}
|
|
340
|
+
} finally {
|
|
341
|
+
await writer.close();
|
|
342
|
+
reader.releaseLock();
|
|
343
|
+
}
|
|
344
|
+
} else {
|
|
345
|
+
const writer = gitProcess.stdin.getWriter();
|
|
346
|
+
await writer.close();
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
return new Response(gitProcess.stdout, {
|
|
350
|
+
status : 200,
|
|
351
|
+
headers : {
|
|
352
|
+
'Content-Type' : `application/x-git-${service}-result`,
|
|
353
|
+
'Cache-Control' : 'no-cache',
|
|
354
|
+
},
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
// ---------------------------------------------------------------------------
|
|
359
|
+
// Helpers
|
|
360
|
+
// ---------------------------------------------------------------------------
|
|
361
|
+
|
|
362
|
+
/**
|
|
363
|
+
* Spawn `git <service> --stateless-rpc --advertise-refs` and collect stdout.
|
|
364
|
+
* Returns `null` if the process exits with a non-zero code.
|
|
365
|
+
*/
|
|
366
|
+
function spawnAndCollect(service: string, repoPath: string): Promise<Uint8Array | null> {
|
|
367
|
+
return new Promise((resolve, reject) => {
|
|
368
|
+
const child = spawn('git', [service, '--stateless-rpc', '--advertise-refs', repoPath], {
|
|
369
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
370
|
+
});
|
|
371
|
+
|
|
372
|
+
const chunks: Buffer[] = [];
|
|
373
|
+
|
|
374
|
+
child.stdout!.on('data', (chunk: Buffer) => chunks.push(chunk));
|
|
375
|
+
child.stdout!.on('error', reject);
|
|
376
|
+
|
|
377
|
+
child.on('error', reject);
|
|
378
|
+
child.on('exit', (code) => {
|
|
379
|
+
if (code !== 0) {
|
|
380
|
+
resolve(null);
|
|
381
|
+
} else {
|
|
382
|
+
resolve(new Uint8Array(Buffer.concat(chunks)));
|
|
383
|
+
}
|
|
384
|
+
});
|
|
385
|
+
});
|
|
386
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Git transport server — smart HTTP git backend with DID-based push auth.
|
|
3
|
+
*
|
|
4
|
+
* @module git-server
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export * from './auth.js';
|
|
8
|
+
export * from './bundle-restore.js';
|
|
9
|
+
export * from './bundle-sync.js';
|
|
10
|
+
export * from './did-service.js';
|
|
11
|
+
export * from './git-backend.js';
|
|
12
|
+
export * from './http-handler.js';
|
|
13
|
+
export * from './push-authorizer.js';
|
|
14
|
+
export * from './ref-sync.js';
|
|
15
|
+
export * from './server.js';
|
|
16
|
+
export * from './verify.js';
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DWN-based push authorization — checks collaborator roles in the DWN.
|
|
3
|
+
*
|
|
4
|
+
* When a DID attempts to push to a repository, this module queries the
|
|
5
|
+
* DWN for `repo/maintainer` and `repo/contributor` role records to
|
|
6
|
+
* determine if the pusher is authorized.
|
|
7
|
+
*
|
|
8
|
+
* Authorization rules:
|
|
9
|
+
* - The repo owner (DID that owns the DWN) can always push
|
|
10
|
+
* - DIDs with a `maintainer` role record can push
|
|
11
|
+
* - DIDs with a `contributor` role record can push
|
|
12
|
+
* - All other DIDs are rejected
|
|
13
|
+
*
|
|
14
|
+
* @module
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import type { TypedWeb5 } from '@enbox/api';
|
|
18
|
+
|
|
19
|
+
import type { ForgeRepoProtocol } from '../repo.js';
|
|
20
|
+
import type { ForgeRepoSchemaMap } from '../repo.js';
|
|
21
|
+
|
|
22
|
+
import type { PushAuthorizer } from './auth.js';
|
|
23
|
+
|
|
24
|
+
// ---------------------------------------------------------------------------
|
|
25
|
+
// Types
|
|
26
|
+
// ---------------------------------------------------------------------------
|
|
27
|
+
|
|
28
|
+
/** Options for creating a DWN-based push authorizer. */
|
|
29
|
+
export type DwnPushAuthorizerOptions = {
|
|
30
|
+
/** The typed ForgeRepoProtocol Web5 handle. */
|
|
31
|
+
repo: TypedWeb5<typeof ForgeRepoProtocol.definition, ForgeRepoSchemaMap>;
|
|
32
|
+
/** The DID of the DWN owner (server operator). */
|
|
33
|
+
ownerDid: string;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
// ---------------------------------------------------------------------------
|
|
37
|
+
// Public API
|
|
38
|
+
// ---------------------------------------------------------------------------
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Create a `PushAuthorizer` that checks DWN collaborator role records.
|
|
42
|
+
*
|
|
43
|
+
* The authorizer queries the ForgeRepoProtocol for `maintainer` and
|
|
44
|
+
* `contributor` role records matching the pusher's DID. The repo owner
|
|
45
|
+
* is always authorized.
|
|
46
|
+
*
|
|
47
|
+
* @param options - Authorizer configuration
|
|
48
|
+
* @returns A PushAuthorizer callback
|
|
49
|
+
*/
|
|
50
|
+
export function createDwnPushAuthorizer(options: DwnPushAuthorizerOptions): PushAuthorizer {
|
|
51
|
+
const { repo, ownerDid } = options;
|
|
52
|
+
|
|
53
|
+
return async (did: string, owner: string, _repoName: string): Promise<boolean> => {
|
|
54
|
+
// The owner can always push to their own repos.
|
|
55
|
+
if (did === owner || did === ownerDid) {
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Query for maintainer role records for this DID.
|
|
60
|
+
const { records: maintainers } = await repo.records.query('repo/maintainer' as any, {
|
|
61
|
+
filter: { tags: { did } },
|
|
62
|
+
});
|
|
63
|
+
if (maintainers.length > 0) {
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Query for contributor role records for this DID.
|
|
68
|
+
const { records: contributors } = await repo.records.query('repo/contributor' as any, {
|
|
69
|
+
filter: { tags: { did } },
|
|
70
|
+
});
|
|
71
|
+
if (contributors.length > 0) {
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return false;
|
|
76
|
+
};
|
|
77
|
+
}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Git ref → DWN sync — mirrors git branch/tag refs as ForgeRefs records.
|
|
3
|
+
*
|
|
4
|
+
* After a successful `git push`, this module reads the current refs from
|
|
5
|
+
* the bare repository and creates or updates corresponding DWN records
|
|
6
|
+
* using the ForgeRefsProtocol.
|
|
7
|
+
*
|
|
8
|
+
* Ref sync flow:
|
|
9
|
+
* 1. Run `git for-each-ref` on the bare repo to enumerate current refs
|
|
10
|
+
* 2. Query existing DWN ref records for the repo
|
|
11
|
+
* 3. Create new records for refs that don't exist in DWN
|
|
12
|
+
* 4. Update existing records whose target (SHA) has changed
|
|
13
|
+
* 5. Delete DWN records for refs that no longer exist in git
|
|
14
|
+
*
|
|
15
|
+
* @module
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import type { TypedWeb5 } from '@enbox/api';
|
|
19
|
+
|
|
20
|
+
import { spawn } from 'node:child_process';
|
|
21
|
+
|
|
22
|
+
import type { ForgeRefsProtocol } from '../refs.js';
|
|
23
|
+
import type { ForgeRefsSchemaMap } from '../refs.js';
|
|
24
|
+
|
|
25
|
+
// ---------------------------------------------------------------------------
|
|
26
|
+
// Types
|
|
27
|
+
// ---------------------------------------------------------------------------
|
|
28
|
+
|
|
29
|
+
/** A git ref as read from `git for-each-ref`. */
|
|
30
|
+
export type GitRef = {
|
|
31
|
+
/** Full ref name, e.g. `refs/heads/main` or `refs/tags/v1.0.0`. */
|
|
32
|
+
name: string;
|
|
33
|
+
/** The commit SHA this ref points to. */
|
|
34
|
+
target: string;
|
|
35
|
+
/** Ref type discriminator. */
|
|
36
|
+
type: 'branch' | 'tag';
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
/** Options for syncing refs. */
|
|
40
|
+
export type RefSyncOptions = {
|
|
41
|
+
/** The typed ForgeRefsProtocol Web5 handle. */
|
|
42
|
+
refs: TypedWeb5<typeof ForgeRefsProtocol.definition, ForgeRefsSchemaMap>;
|
|
43
|
+
/** The repo's contextId (from the ForgeRepoProtocol repo record). */
|
|
44
|
+
repoContextId: string;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
/** Callback for post-push ref synchronization. */
|
|
48
|
+
export type OnPushComplete = (
|
|
49
|
+
did: string,
|
|
50
|
+
repo: string,
|
|
51
|
+
repoPath: string,
|
|
52
|
+
) => Promise<void>;
|
|
53
|
+
|
|
54
|
+
// ---------------------------------------------------------------------------
|
|
55
|
+
// Public API
|
|
56
|
+
// ---------------------------------------------------------------------------
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Create an `onPushComplete` callback that syncs git refs to DWN records.
|
|
60
|
+
*
|
|
61
|
+
* @param options - Ref sync configuration
|
|
62
|
+
* @returns An async callback to invoke after a successful push
|
|
63
|
+
*/
|
|
64
|
+
export function createRefSyncer(options: RefSyncOptions): OnPushComplete {
|
|
65
|
+
const { refs, repoContextId } = options;
|
|
66
|
+
|
|
67
|
+
return async (_did: string, _repo: string, repoPath: string): Promise<void> => {
|
|
68
|
+
// Read current git refs from the bare repository.
|
|
69
|
+
const gitRefs = await readGitRefs(repoPath);
|
|
70
|
+
|
|
71
|
+
// Query existing DWN ref records for this repo.
|
|
72
|
+
// The parentContextId links ref records to the repo context via $ref.
|
|
73
|
+
const { records: existingRecords } = await refs.records.query('repo/ref' as any);
|
|
74
|
+
|
|
75
|
+
// Build a map of existing DWN refs: name → { record, target }.
|
|
76
|
+
const existingMap = new Map<string, { record: any; target: string }>();
|
|
77
|
+
for (const record of existingRecords) {
|
|
78
|
+
const data = await record.data.json();
|
|
79
|
+
existingMap.set(data.name, { record, target: data.target });
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Build a set of current git ref names.
|
|
83
|
+
const gitRefNames = new Set(gitRefs.map((r) => r.name));
|
|
84
|
+
|
|
85
|
+
// Create or update refs.
|
|
86
|
+
for (const ref of gitRefs) {
|
|
87
|
+
const existing = existingMap.get(ref.name);
|
|
88
|
+
|
|
89
|
+
if (!existing) {
|
|
90
|
+
// Create a new DWN ref record.
|
|
91
|
+
await refs.records.create('repo/ref', {
|
|
92
|
+
data : { name: ref.name, target: ref.target, type: ref.type },
|
|
93
|
+
tags : { name: ref.name, type: ref.type, target: ref.target },
|
|
94
|
+
parentContextId : repoContextId,
|
|
95
|
+
});
|
|
96
|
+
} else if (existing.target !== ref.target) {
|
|
97
|
+
// Update existing record with new target.
|
|
98
|
+
await existing.record.update({
|
|
99
|
+
data : { name: ref.name, target: ref.target, type: ref.type },
|
|
100
|
+
tags : { name: ref.name, type: ref.type, target: ref.target },
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
// If target matches, no action needed.
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// Delete DWN records for refs that no longer exist in git.
|
|
107
|
+
for (const [name, { record }] of existingMap) {
|
|
108
|
+
if (!gitRefNames.has(name)) {
|
|
109
|
+
await record.delete();
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// ---------------------------------------------------------------------------
|
|
116
|
+
// Git ref reader
|
|
117
|
+
// ---------------------------------------------------------------------------
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Read all refs from a bare git repository using `git for-each-ref`.
|
|
121
|
+
*
|
|
122
|
+
* @param repoPath - Path to the bare git repository
|
|
123
|
+
* @returns Array of GitRef objects
|
|
124
|
+
*/
|
|
125
|
+
export async function readGitRefs(repoPath: string): Promise<GitRef[]> {
|
|
126
|
+
const output = await spawnCollectStdout('git', [
|
|
127
|
+
'for-each-ref',
|
|
128
|
+
'--format=%(refname)\t%(objectname)',
|
|
129
|
+
'refs/heads/',
|
|
130
|
+
'refs/tags/',
|
|
131
|
+
], repoPath);
|
|
132
|
+
|
|
133
|
+
const refs: GitRef[] = [];
|
|
134
|
+
for (const line of output.split('\n')) {
|
|
135
|
+
if (!line.trim()) { continue; }
|
|
136
|
+
const [name, target] = line.split('\t');
|
|
137
|
+
if (!name || !target) { continue; }
|
|
138
|
+
|
|
139
|
+
const type: 'branch' | 'tag' = name.startsWith('refs/tags/') ? 'tag' : 'branch';
|
|
140
|
+
refs.push({ name, target, type });
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
return refs;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// ---------------------------------------------------------------------------
|
|
147
|
+
// Helpers
|
|
148
|
+
// ---------------------------------------------------------------------------
|
|
149
|
+
|
|
150
|
+
/** Spawn a process, collect stdout, and return it as a string. */
|
|
151
|
+
function spawnCollectStdout(cmd: string, args: string[], cwd: string): Promise<string> {
|
|
152
|
+
return new Promise((resolve, reject) => {
|
|
153
|
+
const child = spawn(cmd, args, { cwd, stdio: ['pipe', 'pipe', 'pipe'] });
|
|
154
|
+
const chunks: Buffer[] = [];
|
|
155
|
+
|
|
156
|
+
child.stdout!.on('data', (chunk: Buffer) => chunks.push(chunk));
|
|
157
|
+
child.on('error', reject);
|
|
158
|
+
child.on('exit', (code) => {
|
|
159
|
+
if (code !== 0) {
|
|
160
|
+
resolve(''); // Empty refs for non-zero exit (e.g., empty repo).
|
|
161
|
+
} else {
|
|
162
|
+
resolve(Buffer.concat(chunks).toString('utf-8'));
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
});
|
|
166
|
+
}
|