openvibers/openvibe.sources Commits
openvibe-shared v1.5.0 (Track R release manifest), openvibe-contracts v0.32.0
Changes
@@@ -126,7 +126,7 @@ Callers use an OpenVibe.Network client-credentials token for audience `openvibe.`GET /api/v1/items` pages in change order (creations, revisions and — with `include_removed=1` —removals); resume from `next_after`. Every page carries the status and staleness of the sourcesit contains. The capability ids (first proposed in [docs/capabilities-proposal/](docs/capabilities-proposal/))--are released in `openvibe-contracts` v0.12.0 (this repo pins v0.13.0); [server/auth.js](server/auth.js)++are released in `openvibe-contracts` v0.12.0 (this repo pins v0.32.0); [server/auth.js](server/auth.js)decides them with the contracts grant rule.## Events (transactional outbox → OpenVibe.Events when `EVENTS_URL` is set)@@@ -7,7 +7,7 @@"runtime": "node 22, express, better-sqlite3, fast-xml-parser","port": 4720,"domain": "sources.openvibe.network (vhost in deploy/nginx, not installed: until it is, the name falls through to the admin.openvibe.network placeholder; once installed it answers an internal-service page, health and JSON 404s, API loopback-only; README \"Public host\")",-- "contracts": "openvibe-contracts v0.13.0",++ "contracts": "openvibe-contracts v0.32.0","capabilities": ["sources.source.read", "sources.item.read", "sources.source.manage"],"capabilitiesRegistered": true,"contractsProposed": ["sources.source@1 (released in openvibe-contracts v0.12.0)", "sources.item@1 (released in openvibe-contracts v0.12.0)"],@@@ -13,8 +13,8 @@"dotenv": "^16.4.7","express": "^4.21.2","fast-xml-parser": "^4.5.3",-- "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.13.0",-- "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v1.3.0"++ "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.32.0",++ "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v1.5.0"},"devDependencies": {"ajv": "^8.20.0",@@@ -990,9 +990,9 @@}},"node_modules/openvibe-contracts": {-- "version": "0.13.0",-- "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.13.0",-- "integrity": "sha512-MeIGJYHQsbr6ISeEErduUw/PD52X5IBclH2ht/G/t4lSX5X4o2AwcZYLEzOZrcbaXQyplgC7r86RCGFvi1ifUA==",++ "version": "0.32.0",++ "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.32.0",++ "integrity": "sha512-ntN58SIG03YDxbhsiIzOM5GRH19jRMHZUYWI3xU2VwovExagF5DdwApLVfezsu84UTJ+V2Jfn+LWDc+Oz8ab+g==","license": "AGPL-3.0-only","dependencies": {"ajv": "^8.17.1",@@@ -1006,9 +1006,9 @@}},"node_modules/openvibe-shared": {-- "version": "1.3.0",-- "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v1.3.0",-- "integrity": "sha512-w8yl/5+9eend8I2O/DzAJnEAL2N3GTUY7c7pzK+MLJuLAGD8FmJJQ9gwbgyrq70Snjt3ebrg3TlpORhRAp2kgA==",++ "version": "1.5.0",++ "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v1.5.0",++ "integrity": "sha512-cehnscuYMkJwuCYGcI6wPSswbUn0bhTyGAaD5feNCoO//2e9gyC7cgjkEcIOtM8DQF3yTuUNyXnOwckIeM4fUg==","license": "MIT","dependencies": {"jsonwebtoken": "^9.0.0"@@@ -27,8 +27,8 @@"dotenv": "^16.4.7","express": "^4.21.2","fast-xml-parser": "^4.5.3",-- "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.13.0",-- "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v1.3.0"++ "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.32.0",++ "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v1.5.0"},"engines": {"node": ">=22.0.0"@@@ -87,7 +87,8 @@ function createApp({ config, db, registry, items, ingest, scheduler, auth, keys,// fetcher (worker running, queue keeping up) are optional and degrade it (see observability.js).const readiness = createSourcesReadiness({ db, keys, config, registry, ingest, scheduler, outbox, relay, now, release: release.release });app.get('/api/ready', readiness.handler);-- app.get('/release.json', release.handler);++ // GET /release.json (ADR-016) and POST /release-metrics (open tabs' update reports into /metrics).++ release.mount(app, { registry: metrics.registry });app.use(sourcesRouter({ db, registry, ingest, auth }));app.use(itemsRouter({ db, registry, items, auth, relay, now }));@@@ -77,6 +77,14 @@ t('/metrics: 404 through a proxy; route templates and Sources gauges direct', asassert.ok(/\nsources_outbox_pending \d+\n/.test(text));});++t('/release.json: a registry.release-manifest@1 that names where tabs report updates', async () => {++ const r = await request(svc.base, 'GET', '/release.json');++ assert.strictEqual(r.status, 200, r.text);++ assert.strictEqual(r.body.service, 'sources');++ assert.deepStrictEqual(require('openvibe-contracts').validate('registry.release-manifest@1', r.body).errors, []);++ assert.strictEqual(r.body.metrics_url, '/release-metrics');++});++t('a broken database makes the service unready (503); /metrics still answers', async () => {svc.db.close();const r = await request(svc.base, 'GET', '/api/ready');
@@ -126,7 +126,7 @@ Callers use an OpenVibe.Network client-credentials token for audience `openvibe.
@@ -126,7 +126,7 @@ Callers use an OpenVibe.Network client-credentials token for audience `openvibe.
`GET /api/v1/items` pages in change order (creations, revisions and — with `include_removed=1` —
`GET /api/v1/items` pages in change order (creations, revisions and — with `include_removed=1` —
removals); resume from `next_after`. Every page carries the status and staleness of the sources
removals); resume from `next_after`. Every page carries the status and staleness of the sources
it contains. The capability ids (first proposed in [docs/capabilities-proposal/](docs/capabilities-proposal/))
it contains. The capability ids (first proposed in [docs/capabilities-proposal/](docs/capabilities-proposal/))
-are released in `openvibe-contracts` v0.12.0 (this repo pins v0.13.0); [server/auth.js](server/auth.js)
+are released in `openvibe-contracts` v0.12.0 (this repo pins v0.32.0); [server/auth.js](server/auth.js)
decides them with the contracts grant rule.
decides them with the contracts grant rule.
## Events (transactional outbox → OpenVibe.Events when `EVENTS_URL` is set)
## Events (transactional outbox → OpenVibe.Events when `EVENTS_URL` is set)
@@ -7,7 +7,7 @@
@@ -7,7 +7,7 @@
"runtime": "node 22, express, better-sqlite3, fast-xml-parser",
"runtime": "node 22, express, better-sqlite3, fast-xml-parser",
"port": 4720,
"port": 4720,
"domain": "sources.openvibe.network (vhost in deploy/nginx, not installed: until it is, the name falls through to the admin.openvibe.network placeholder; once installed it answers an internal-service page, health and JSON 404s, API loopback-only; README \"Public host\")",
"domain": "sources.openvibe.network (vhost in deploy/nginx, not installed: until it is, the name falls through to the admin.openvibe.network placeholder; once installed it answers an internal-service page, health and JSON 404s, API loopback-only; README \"Public host\")",
- "contracts": "openvibe-contracts v0.13.0",
+ "contracts": "openvibe-contracts v0.32.0",
"capabilities": ["sources.source.read", "sources.item.read", "sources.source.manage"],
"capabilities": ["sources.source.read", "sources.item.read", "sources.source.manage"],
"capabilitiesRegistered": true,
"capabilitiesRegistered": true,
"contractsProposed": ["sources.source@1 (released in openvibe-contracts v0.12.0)", "sources.item@1 (released in openvibe-contracts v0.12.0)"],
"contractsProposed": ["sources.source@1 (released in openvibe-contracts v0.12.0)", "sources.item@1 (released in openvibe-contracts v0.12.0)"],
@@ -13,8 +13,8 @@
@@ -13,8 +13,8 @@
"dotenv": "^16.4.7",
"dotenv": "^16.4.7",
"express": "^4.21.2",
"express": "^4.21.2",
"fast-xml-parser": "^4.5.3",
"fast-xml-parser": "^4.5.3",
- "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.13.0",
- "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v1.3.0"
+ "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.32.0",
+ "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v1.5.0"
},
},
"devDependencies": {
"devDependencies": {
"ajv": "^8.20.0",
"ajv": "^8.20.0",
@@ -990,9 +990,9 @@
@@ -990,9 +990,9 @@
}
}
},
},
"node_modules/openvibe-contracts": {
"node_modules/openvibe-contracts": {
- "version": "0.13.0",
- "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.13.0",
- "integrity": "sha512-MeIGJYHQsbr6ISeEErduUw/PD52X5IBclH2ht/G/t4lSX5X4o2AwcZYLEzOZrcbaXQyplgC7r86RCGFvi1ifUA==",
+ "version": "0.32.0",
+ "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.32.0",
+ "integrity": "sha512-ntN58SIG03YDxbhsiIzOM5GRH19jRMHZUYWI3xU2VwovExagF5DdwApLVfezsu84UTJ+V2Jfn+LWDc+Oz8ab+g==",
"license": "AGPL-3.0-only",
"license": "AGPL-3.0-only",
"dependencies": {
"dependencies": {
"ajv": "^8.17.1",
"ajv": "^8.17.1",
@@ -1006,9 +1006,9 @@
@@ -1006,9 +1006,9 @@
}
}
},
},
"node_modules/openvibe-shared": {
"node_modules/openvibe-shared": {
- "version": "1.3.0",
- "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v1.3.0",
- "integrity": "sha512-w8yl/5+9eend8I2O/DzAJnEAL2N3GTUY7c7pzK+MLJuLAGD8FmJJQ9gwbgyrq70Snjt3ebrg3TlpORhRAp2kgA==",
+ "version": "1.5.0",
+ "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v1.5.0",
+ "integrity": "sha512-cehnscuYMkJwuCYGcI6wPSswbUn0bhTyGAaD5feNCoO//2e9gyC7cgjkEcIOtM8DQF3yTuUNyXnOwckIeM4fUg==",
"license": "MIT",
"license": "MIT",
"dependencies": {
"dependencies": {
"jsonwebtoken": "^9.0.0"
"jsonwebtoken": "^9.0.0"
@@ -27,8 +27,8 @@
@@ -27,8 +27,8 @@
"dotenv": "^16.4.7",
"dotenv": "^16.4.7",
"express": "^4.21.2",
"express": "^4.21.2",
"fast-xml-parser": "^4.5.3",
"fast-xml-parser": "^4.5.3",
- "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.13.0",
- "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v1.3.0"
+ "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.32.0",
+ "openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v1.5.0"
},
},
"engines": {
"engines": {
"node": ">=22.0.0"
"node": ">=22.0.0"
@@ -87,7 +87,8 @@ function createApp({ config, db, registry, items, ingest, scheduler, auth, keys,
@@ -87,7 +87,8 @@ function createApp({ config, db, registry, items, ingest, scheduler, auth, keys,
// fetcher (worker running, queue keeping up) are optional and degrade it (see observability.js).
// fetcher (worker running, queue keeping up) are optional and degrade it (see observability.js).
const readiness = createSourcesReadiness({ db, keys, config, registry, ingest, scheduler, outbox, relay, now, release: release.release });
const readiness = createSourcesReadiness({ db, keys, config, registry, ingest, scheduler, outbox, relay, now, release: release.release });
app.get('/api/ready', readiness.handler);
app.get('/api/ready', readiness.handler);
- app.get('/release.json', release.handler);
+ // GET /release.json (ADR-016) and POST /release-metrics (open tabs' update reports into /metrics).
+ release.mount(app, { registry: metrics.registry });
app.use(sourcesRouter({ db, registry, ingest, auth }));
app.use(sourcesRouter({ db, registry, ingest, auth }));
app.use(itemsRouter({ db, registry, items, auth, relay, now }));
app.use(itemsRouter({ db, registry, items, auth, relay, now }));
@@ -77,6 +77,14 @@ t('/metrics: 404 through a proxy; route templates and Sources gauges direct', as
@@ -77,6 +77,14 @@ t('/metrics: 404 through a proxy; route templates and Sources gauges direct', as
assert.ok(/\nsources_outbox_pending \d+\n/.test(text));
assert.ok(/\nsources_outbox_pending \d+\n/.test(text));
});
});
+t('/release.json: a registry.release-manifest@1 that names where tabs report updates', async () => {
+ const r = await request(svc.base, 'GET', '/release.json');
+ assert.strictEqual(r.status, 200, r.text);
+ assert.strictEqual(r.body.service, 'sources');
+ assert.deepStrictEqual(require('openvibe-contracts').validate('registry.release-manifest@1', r.body).errors, []);
+ assert.strictEqual(r.body.metrics_url, '/release-metrics');
+});
+
t('a broken database makes the service unready (503); /metrics still answers', async () => {
t('a broken database makes the service unready (503); /metrics still answers', async () => {
svc.db.close();
svc.db.close();
const r = await request(svc.base, 'GET', '/api/ready');
const r = await request(svc.base, 'GET', '/api/ready');