@powerhousedao/registry 6.0.2-staging.0 → 6.0.2-staging.10

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.
Files changed (38) hide show
  1. package/{dist/cdn-cache/@powerhousedao/vetra/6.0.0-dev.59/LICENSE → LICENSE} +1 -1
  2. package/README.md +177 -28
  3. package/dist/cli.d.mts +49 -0
  4. package/dist/cli.d.mts.map +1 -0
  5. package/dist/cli.mjs +1059 -0
  6. package/dist/cli.mjs.map +1 -0
  7. package/package.json +18 -13
  8. package/static/favicon.ico +0 -0
  9. package/static/logo.svg +11 -0
  10. package/dist/bundle.d.ts +0 -2
  11. package/dist/bundle.d.ts.map +0 -1
  12. package/dist/cdn-cache/@powerhousedao/vetra/6.0.0-dev.59/package.json +0 -114
  13. package/dist/src/cdn.d.ts +0 -12
  14. package/dist/src/cdn.d.ts.map +0 -1
  15. package/dist/src/cli.d.ts +0 -32
  16. package/dist/src/cli.d.ts.map +0 -1
  17. package/dist/src/cli.js +0 -161040
  18. package/dist/src/constants.d.ts +0 -4
  19. package/dist/src/constants.d.ts.map +0 -1
  20. package/dist/src/index.d.ts +0 -6
  21. package/dist/src/index.d.ts.map +0 -1
  22. package/dist/src/index.js +0 -74
  23. package/dist/src/middleware.d.ts +0 -6
  24. package/dist/src/middleware.d.ts.map +0 -1
  25. package/dist/src/packages.d.ts +0 -5
  26. package/dist/src/packages.d.ts.map +0 -1
  27. package/dist/src/run.d.ts +0 -3
  28. package/dist/src/run.d.ts.map +0 -1
  29. package/dist/src/types.d.ts +0 -69
  30. package/dist/src/types.d.ts.map +0 -1
  31. package/dist/src/verdaccio-config.d.ts +0 -3
  32. package/dist/src/verdaccio-config.d.ts.map +0 -1
  33. package/dist/storage/@powerhousedao/vetra/package.json +0 -154
  34. package/dist/tests/e2e.test.d.ts +0 -2
  35. package/dist/tests/e2e.test.d.ts.map +0 -1
  36. package/dist/tsconfig.tsbuildinfo +0 -1
  37. package/dist/vitest.config.d.ts +0 -3
  38. package/dist/vitest.config.d.ts.map +0 -1
@@ -658,4 +658,4 @@ specific requirements.
658
658
  You should also get your employer (if you work as a programmer) or school,
659
659
  if any, to sign a "copyright disclaimer" for the program, if necessary.
660
660
  For more information on this, and how to apply and follow the GNU AGPL, see
661
- <https://www.gnu.org/licenses/>.
661
+ <https://www.gnu.org/licenses/>.
package/README.md CHANGED
@@ -1,52 +1,201 @@
1
1
  # @powerhousedao/registry
2
2
 
3
- Express-based server that serves Powerhouse packages (ESM bundles) for dynamic loading via `import()` in browsers and Node.js.
3
+ Powerhouse package registry built on Verdaccio. Serves as both an npm registry and a CDN for Powerhouse package bundles (ESM) for dynamic `import()` in browsers and Node.js.
4
4
 
5
- ## Quick Start
5
+ ## API
6
6
 
7
- ### CLI
7
+ ### Packages
8
8
 
9
- ```sh
10
- # Serve packages from a directory
11
- ph-registry ./path/to/packages 3000
9
+ #### `GET /packages`
12
10
 
13
- # Or with environment variables
14
- REGISTRY_DIR=./packages PORT=3000 ph-registry
11
+ Returns a JSON array of all discovered packages. Supports filtering by document type:
15
12
 
16
- # Or run directly
17
- node dist/src/run.js ./path/to/packages 3000
18
13
  ```
14
+ GET /packages?documentType=powerhouse/package
15
+ ```
16
+
17
+ #### `GET /packages/by-document-type?type=<documentType>`
18
+
19
+ Returns an array of package names that contain the specified document type.
20
+
21
+ #### `GET /packages/<packageName>`
22
+
23
+ Returns info for a single package (supports scoped names like `@powerhousedao/vetra`).
24
+
25
+ ### CDN
19
26
 
20
- Arguments:
27
+ #### `GET /-/cdn/<packageName>/<filePath>`
21
28
 
22
- - `dir` (positional, 1st) -- directory to serve packages from (default: `.`, env: `REGISTRY_DIR`)
23
- - `port` (positional, 2nd) -- port to listen on (default: `8080`, env: `PORT`)
29
+ Serves files from the CDN cache. On first request, fetches and extracts the tarball from Verdaccio. Looks for files in the package root, then `cdn/`, `dist/cdn/`, and `dist/` subdirectories.
30
+
31
+ If the package is not published locally, Verdaccio transparently proxies metadata and tarballs from the configured upstream (`--uplink`, default `https://registry.npmjs.org/`). The CDN then extracts the upstream tarball into `cdn-cache/<pkg>/<version>/` exactly as it does for locally-published packages, so subsequent requests are served from the local cache without re-hitting the upstream. The same fallback applies to `@powerhousedao/*` packages: the registry prefers its local copy, and falls back to the upstream when the package isn't published locally.
32
+
33
+ ### Publish Notifications
34
+
35
+ When a package is published, the registry can notify subscribers in real time via Server-Sent Events (SSE) and webhooks.
36
+
37
+ #### SSE — `GET /-/events`
38
+
39
+ Opens a persistent SSE connection. The server sends:
40
+
41
+ - `connected` event on initial connection
42
+ - `publish` event whenever a package is published, with payload:
43
+
44
+ ```json
45
+ { "packageName": "@scope/pkg", "version": "1.0.0" }
46
+ ```
24
47
 
25
- ### Library
48
+ Example (browser):
26
49
 
27
50
  ```ts
28
- import express from "express";
29
- import { createRegistryRouter } from "@powerhousedao/registry";
51
+ const source = new EventSource("http://localhost:8080/-/events");
52
+ source.addEventListener("publish", (e) => {
53
+ const { packageName, version } = JSON.parse(e.data);
54
+ console.log(`${packageName}@${version} published`);
55
+ });
56
+ ```
57
+
58
+ #### Webhooks
59
+
60
+ Webhooks are persisted to disk and survive restarts. Predefined webhooks can also be provided via configuration.
61
+
62
+ ##### `GET /-/webhooks`
30
63
 
31
- const app = express();
32
- app.use(createRegistryRouter("./packages"));
33
- app.listen(3000);
64
+ Returns all registered webhooks (predefined + dynamic).
65
+
66
+ ##### `POST /-/webhooks`
67
+
68
+ Registers a new webhook. Body:
69
+
70
+ ```json
71
+ { "endpoint": "https://example.com/hook", "headers": { "X-Token": "secret" } }
34
72
  ```
35
73
 
36
- ## API
74
+ `headers` is optional. Returns `201` on success. Duplicate endpoints are ignored.
37
75
 
38
- ### `createPowerhouseRouter(config)`
76
+ ##### `DELETE /-/webhooks`
39
77
 
40
- Creates an Express `Router` that serves packages.
78
+ Removes a dynamic webhook. Body:
41
79
 
42
- ### `GET /packages`
80
+ ```json
81
+ { "endpoint": "https://example.com/hook" }
82
+ ```
83
+
84
+ Returns `204` on success, `404` if not found. Predefined webhooks cannot be removed.
43
85
 
44
- Returns a JSON array of all discovered packages.
86
+ When a package is published, each webhook receives a POST with:
87
+
88
+ ```json
89
+ {
90
+ "packageName": "@scope/pkg",
91
+ "version": "1.0.0",
92
+ "publishedBy": {
93
+ "address": "0xabc...",
94
+ "did": "did:key:z6Mk..."
95
+ }
96
+ }
97
+ ```
45
98
 
46
- ### `GET /packages/by-document-type?type=<documentType>`
99
+ ### npm Protocol
47
100
 
48
- Returns package names that contain the specified document type.
101
+ All standard npm registry operations (publish, install, etc.) are handled by Verdaccio.
49
102
 
50
- ### `GET /-/cdn/<packageName>/<filePath>`
103
+ ## Publishing Packages
104
+
105
+ ```sh
106
+ npm publish --registry http://localhost:8080/
107
+ ```
108
+
109
+ On publish, the CDN cache for that package is automatically invalidated and the new version is extracted immediately.
110
+
111
+ ## CLI
112
+
113
+ ```sh
114
+ ph-registry --port 8080 --storage-dir ./storage --cdn-cache-dir ./cdn-cache
115
+ ```
116
+
117
+ Options:
118
+
119
+ | Option | Env Variable | Default | Description |
120
+ | ------------------------ | ------------------------------ | ----------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
121
+ | `--port` | `PORT` | `8080` | Port to listen on |
122
+ | `--storage-dir` | `REGISTRY_STORAGE` | `./storage` | Verdaccio storage directory |
123
+ | `--cdn-cache-dir` | `REGISTRY_CDN_CACHE` | `./cdn-cache` | CDN cache directory |
124
+ | `--uplink` | `REGISTRY_UPLINK` | `https://registry.npmjs.org/` | Upstream npm registry URL used for fallback proxy |
125
+ | `--web-enabled` | `REGISTRY_WEB` | `true` | Enable Verdaccio web UI |
126
+ | `--webhook` | `REGISTRY_WEBHOOKS` | — | Comma-separated webhook URLs to notify on publish |
127
+ | `--s3-bucket` | `S3_BUCKET` | — | S3 bucket for storage |
128
+ | `--s3-endpoint` | `S3_ENDPOINT` | — | S3 endpoint URL |
129
+ | `--s3-region` | `S3_REGION` | — | S3 region |
130
+ | `--s3-access-key-id` | `S3_ACCESS_KEY_ID` | — | S3 access key |
131
+ | `--s3-secret-access-key` | `S3_SECRET_ACCESS_KEY` | — | S3 secret key |
132
+ | `--s3-key-prefix` | `S3_KEY_PREFIX` | — | S3 key prefix |
133
+ | `--s3-force-path-style` | `S3_FORCE_PATH_STYLE` | `true` | Force S3 path-style URLs |
134
+ | `--public-url` | `PH_REGISTRY_PUBLIC_URL` | — | Public URL of this registry — required when Renown auth is enabled. Used as the expected `aud` claim on bearer tokens. |
135
+ | `--auth-renown` | `PH_REGISTRY_AUTH_RENOWN` | `true` | Enable Renown JWT auth in front of verdaccio. Disabled (no-op) when `--public-url` is unset. |
136
+ | `--verdaccio-secret` | `PH_REGISTRY_VERDACCIO_SECRET` | random per pod | Verdaccio JWT signing secret. The renown middleware mints an in-process verdaccio token that never leaves the pod, so a per-pod secret is fine. |
137
+
138
+ ## Authentication
139
+
140
+ Two authentication paths are supported:
141
+
142
+ 1. **Renown bearer tokens (preferred).** Stateless: the registry verifies the
143
+ token's signature against the issuer's DID public key, with no shared secret
144
+ required across replicas. Activated by setting `--public-url`. CLI flow:
145
+ `ph login` once, then `ph publish` (mints a fresh 5-minute token per
146
+ invocation) or `ph registry-login` (writes a longer-lived token to
147
+ `~/.npmrc` for raw `npm publish`).
148
+
149
+ 2. **Legacy htpasswd.** Verdaccio's built-in plugin remains in the auth chain
150
+ as a grace-period fallback. Per-pod state, so it doesn't survive horizontal
151
+ scaling — being phased out as soon as all clients have moved to Renown.
152
+
153
+ ## Deployment
154
+
155
+ ### Build
156
+
157
+ ```sh
158
+ # Latest version
159
+ docker build -t ph-registry .
160
+
161
+ # Specific version
162
+ docker build --build-arg TAG=6.0.0-dev.112 -t ph-registry .
163
+ ```
164
+
165
+ The `TAG` build arg controls the npm version of `@powerhousedao/registry` to install (defaults to `latest`).
166
+
167
+ ### Run
168
+
169
+ ```sh
170
+ docker run -p 4873:4873 -v ph-data:/data ph-registry
171
+ ```
172
+
173
+ #### Environment variables
174
+
175
+ Pass env variables with `-e`:
176
+
177
+ ```sh
178
+ docker run -p 4873:4873 -v ph-data:/data \
179
+ -e REGISTRY_UPLINK=https://registry.npmjs.org \
180
+ -e S3_BUCKET=my-bucket \
181
+ -e S3_REGION=us-east-1 \
182
+ ph-registry
183
+ ```
184
+
185
+ Or use an env file:
186
+
187
+ ```sh
188
+ docker run -p 4873:4873 -v ph-data:/data --env-file .env ph-registry
189
+ ```
190
+
191
+ See the [CLI](#cli) section for all supported environment variables.
192
+
193
+ #### CLI arguments
194
+
195
+ Since the image uses `ENTRYPOINT`, CLI args can be passed directly:
196
+
197
+ ```sh
198
+ docker run -p 8080:8080 -v ph-data:/data ph-registry --port 8080 --uplink https://registry.npmjs.org
199
+ ```
51
200
 
52
- Serves files from the CDN cache for a package.
201
+ CLI arguments take precedence over environment variables.
package/dist/cli.d.mts ADDED
@@ -0,0 +1,49 @@
1
+ import * as cmd_ts_dist_cjs_argparser_js0 from "cmd-ts/dist/cjs/argparser.js";
2
+ import * as cmd_ts_dist_cjs_helpdoc_js0 from "cmd-ts/dist/cjs/helpdoc.js";
3
+ import * as cmd_ts_dist_cjs_runner_js0 from "cmd-ts/dist/cjs/runner.js";
4
+
5
+ //#region cli.d.ts
6
+ declare const registryCommand: Partial<cmd_ts_dist_cjs_argparser_js0.Register> & {
7
+ parse(context: cmd_ts_dist_cjs_argparser_js0.ParseContext): Promise<cmd_ts_dist_cjs_argparser_js0.ParsingResult<{
8
+ port: number;
9
+ storageDir: string;
10
+ cdnCacheDir: string;
11
+ uplink: string | undefined;
12
+ s3Bucket: string | undefined;
13
+ s3Endpoint: string | undefined;
14
+ s3Region: string | undefined;
15
+ s3AccessKeyId: string | undefined;
16
+ s3SecretAccessKey: string | undefined;
17
+ s3KeyPrefix: string | undefined;
18
+ s3ForcePathStyle: boolean;
19
+ webEnabled: boolean;
20
+ webhooks: string | undefined;
21
+ publicUrl: string | undefined;
22
+ authRenown: boolean;
23
+ verdaccioSecret: string | undefined;
24
+ localPackages: string | undefined;
25
+ }>>;
26
+ } & cmd_ts_dist_cjs_helpdoc_js0.PrintHelp & cmd_ts_dist_cjs_helpdoc_js0.ProvidesHelp & cmd_ts_dist_cjs_helpdoc_js0.Named & Partial<cmd_ts_dist_cjs_helpdoc_js0.Versioned> & cmd_ts_dist_cjs_argparser_js0.Register & cmd_ts_dist_cjs_runner_js0.Handling<{
27
+ port: number;
28
+ storageDir: string;
29
+ cdnCacheDir: string;
30
+ uplink: string | undefined;
31
+ s3Bucket: string | undefined;
32
+ s3Endpoint: string | undefined;
33
+ s3Region: string | undefined;
34
+ s3AccessKeyId: string | undefined;
35
+ s3SecretAccessKey: string | undefined;
36
+ s3KeyPrefix: string | undefined;
37
+ s3ForcePathStyle: boolean;
38
+ webEnabled: boolean;
39
+ webhooks: string | undefined;
40
+ publicUrl: string | undefined;
41
+ authRenown: boolean;
42
+ verdaccioSecret: string | undefined;
43
+ localPackages: string | undefined;
44
+ }, Promise<void>> & {
45
+ run(context: cmd_ts_dist_cjs_argparser_js0.ParseContext): Promise<cmd_ts_dist_cjs_argparser_js0.ParsingResult<Promise<void>>>;
46
+ } & Partial<cmd_ts_dist_cjs_helpdoc_js0.Versioned & cmd_ts_dist_cjs_helpdoc_js0.Descriptive & cmd_ts_dist_cjs_helpdoc_js0.Aliased>;
47
+ //#endregion
48
+ export { registryCommand };
49
+ //# sourceMappingURL=cli.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.mts","names":[],"sources":["../cli.ts"],"mappings":";;;;;cAiBa,eAAA,EAAe,OAAA,CA6H1B,6BAAA,CA7H0B,QAAA;iBAAA,6BAAA,CAAA,YAAA"}