openvibers/openvibe.examples Commits

Examples: the developer path releases on OpenVibe.Services (services.release.manage, OV_SERVICES_URL); openvibe-sdk v0.35.2 (#4)

OP OpenVibers committed 8 Oct 2026 · c8d15fbdde · 15 files, +56 −55

The developer console moved from openvibe.codes to openvibe.services (openvibe-contracts 0.113.0); the daily production probe's release step follows, and its mock stands in for Services' release API.


Claude-Session: https://claude.ai/code/session_01K8AYn3FF3HE7CPfM262qdh

Co-authored-by: Claude Opus 5.5 <[email protected]>

Changes

ddiff --git a/README.md b/README.md
iindex e6d6d17..819b117 100644
---- a/README.md
++++ b/README.md
@@@ -9,7 +9,7 @@ of them (Media, Events pull, a Tools job) against the real platform with your ow
is not part of CI or `npm test`, and it was not run against production as part of this release.
`npm run developer-path` is the Wave 20 exit check (account to Media and Events to revoked
credentials); CI runs it against the mock platform, and a person runs it against production.
--**Built on:** [openvibe-sdk v0.35.0](https://github.com/OpenVibers/OpenVibe.SDK/tree/v0.35.0), and
++**Built on:** [openvibe-sdk v0.35.2](https://github.com/OpenVibers/OpenVibe.SDK/tree/v0.35.2), and
openvibe-contracts v0.112.0 for the mod manifest.
**Plan:** OpenVibe End-to-End Realignment & Implementation Plan, revision 3 (20 Sep 2026), §15.1
and §18.9; roadmap Wave 20, §30 (public SDK surface), ADR-014 (developer projects).
@@@ -71,7 +71,7 @@ capabilities approved at once.
**2. Create a project, a sandbox app and its grants.** Either:
--- **in the developer portal, <https://openvibe.codes>:** sign in, create a project, add a
++- **in the developer console, <https://openvibe.services>:** sign in, create a project, add a
**confidential** app in the `sandbox` environment with the redirect URI
`http://localhost:3009/callback` (for [oauth-app](examples/oauth-app)), copy the client secret
(it is shown **once**), and request the grants `media.object.upload`, `media.object.read`,
@@@ -160,11 +160,11 @@ scoped credentials only, then rotates and revokes those credentials and cleans u
| 2. discovery | reads `/.well-known/openvibe` as any origin may |
| 3. project | creates a sandbox project with `openvibe-sdk/projects` |
| 4. app | creates a confidential sandbox app; its secret stays in memory |
--| 5. grants | requests `media.object.upload`, `media.object.read`, `events.app.publish`, `events.app.read`, `codes.release.manage`; all must be approved at once |
++| 5. grants | requests `media.object.upload`, `media.object.read`, `events.app.publish`, `events.app.read`, `services.release.manage`; all must be approved at once |
| 6. media | [media-uploader](examples/media-uploader): upload a small file, read it back, delete it |
| 7. events | [event-subscriber](examples/event-subscriber): publish `app.<project_key>.developer_path.ran`, pull it with a cursor |
| 8. export | as the project's owner: Network mints 5-minute read-only export tokens; Media lists the project's sandbox files with one and refuses an upload; Events returns the event from step 7 with the other |
--| 9. release | as the app, on OpenVibe.Codes (`OV_CODES_URL`): a sandbox release of itself goes draft → published → deprecated → revoked, checked in the public list each time |
++| 9. release | as the app, on OpenVibe.Services (`OV_SERVICES_URL`): a sandbox release of itself goes draft → published → deprecated → revoked, checked in the public list each time |
| 10. credentials | rotates with no overlap and revokes the first credential; the old secret must be refused at `/oauth/token`, the new one must work |
| 11. cleanup | archives the project, even when an earlier step failed; the app's secret must then be refused |
@@@ -172,7 +172,7 @@ scoped credentials only, then rotates and revokes those credentials and cleans u
`openvibe-sdk/testing`'s mock platform (the `developer-path` job; `test/developer-path.test.js`
also checks it leaves nothing behind, never prints a secret, and still cleans up after a failure).
The mock has no account API, so `scripts/developer-path-mock.js` adds register and login routes
--that mint mock user tokens, mints export tokens, and stands in for Codes' release API; every other step is the platform mock's own.
++that mint mock user tokens, mints export tokens, and stands in for Services' release API; every other step is the platform mock's own.
**Against production** it runs only when a person starts it. Credentials come from the
environment (or `./.env`) only:
@@@ -191,7 +191,7 @@ secret and token in its output and prints signed URLs without their signature. E
eleven steps passed, `1` when one failed, `2` when it refused to start.
It does not yet cover webhook delivery to an external endpoint (that needs a public https host)
--or publishing an app release in OpenVibe.Codes.
++or publishing an app release in OpenVibe.Services.
### Tools job proof
@@@ -265,7 +265,7 @@ Repository checks (`test/`):
value in a `.env.example`.
- `structure.test.js` checks the nine examples are complete and copyable: README with "What it
proves" and "Run it against the real platform", a `.env.example` that names every variable the
-- code reads, MIT license, `openvibe-sdk` pinned to the v0.35.0 tag, no `file:` links; and that
++ code reads, MIT license, `openvibe-sdk` pinned to the v0.35.2 tag, no `file:` links; and that
`npm run e2e` is outside CI and `npm test` and refuses to start without its variables; and that
CI runs the developer path against the mock platform only.
- `developer-path.test.js` runs the developer path against the mock platform and checks the
@@@ -294,11 +294,11 @@ test/public-surface.test.js, test/structure.test.js
## Does not own
- any platform service, the SDK (OpenVibe.SDK), the contracts (OpenVibe.Contracts) or the
-- developer portal (OpenVibe.Codes)
++ developer console (OpenVibe.Services)
## Depends on
--- OpenVibe.SDK (v0.35.0), OpenVibe.Contracts (v0.112.0, mod manifest only)
++- OpenVibe.SDK (v0.35.2), OpenVibe.Contracts (v0.113.0, mod manifest only)
- at run time against the real platform: Network (tokens, registry, developer projects), Events,
Media, Tools, Chat (on openvibe.live)
@@@ -308,7 +308,7 @@ Examples implements no capability (its manifest lists none). The examples call t
developer app with the grants a sandbox project asks for (`npm run new-app`): `media.object.upload`
and `media.object.read` (Media), `events.app.publish`, `events.app.read` and `events.app.subscribe`
(Events), and `tools.job.create`, `tools.job.read` and `tools.job.cancel` (Tools); a public browser app
--gets `media.object.read` only. The developer path check also uses `codes.release.manage` (Codes). The
++gets `media.object.read` only. The developer path check also uses `services.release.manage` (Services). The
chat bot uses a Live `hbt_` token with scope `chat`, because `chat.message.send` is first-party.
## Acceptance
@@@ -349,5 +349,5 @@ own app.
Part of the [OpenVibe network](https://openvibe.network). Built in the open by [OpenVibers](https://github.com/OpenVibers).
<!-- versions:start -->
--- openvibe-sdk: v0.35.0
++- openvibe-sdk: v0.35.2
<!-- versions:end -->
ddiff --git a/STATUS.json b/STATUS.json
iindex 1a11386..283f025 100644
---- a/STATUS.json
++++ b/STATUS.json
@@@ -4,7 +4,7 @@
"code": true,
"wave": "W20",
"version": "0.3.0",
-- "sdk": "openvibe-sdk v0.35.0",
++ "sdk": "openvibe-sdk v0.35.2",
"contracts": "openvibe-contracts v0.49.0 (mod-manifest example)",
"deployed": false,
"deployment": "none: a repository with CI, not a runtime and not a published package",
ddiff --git a/examples/browser-app/package.json b/examples/browser-app/package.json
iindex 7d87dae..00f8ddf 100644
---- a/examples/browser-app/package.json
++++ b/examples/browser-app/package.json
@@@ -13,6 +13,6 @@
"node": ">=22"
},
"dependencies": {
-- "openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.35.0"
++ "openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.35.2"
}
}
ddiff --git a/examples/event-subscriber/package.json b/examples/event-subscriber/package.json
iindex 6bd9ac7..1f5b4bb 100644
---- a/examples/event-subscriber/package.json
++++ b/examples/event-subscriber/package.json
@@@ -13,6 +13,6 @@
"node": ">=22"
},
"dependencies": {
-- "openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.35.0"
++ "openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.35.2"
}
}
ddiff --git a/examples/media-uploader/package.json b/examples/media-uploader/package.json
iindex ef2ff23..ecb4487 100644
---- a/examples/media-uploader/package.json
++++ b/examples/media-uploader/package.json
@@@ -13,6 +13,6 @@
"node": ">=22"
},
"dependencies": {
-- "openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.35.0"
++ "openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.35.2"
}
}
ddiff --git a/examples/mod-manifest/package.json b/examples/mod-manifest/package.json
iindex fee74f8..151f733 100644
---- a/examples/mod-manifest/package.json
++++ b/examples/mod-manifest/package.json
@@@ -13,7 +13,7 @@
"node": ">=22"
},
"dependencies": {
-- "openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.35.0",
++ "openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.35.2",
"openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.112.0"
}
}
ddiff --git a/examples/node-server-app/package.json b/examples/node-server-app/package.json
iindex 605d7c9..f2cf46b 100644
---- a/examples/node-server-app/package.json
++++ b/examples/node-server-app/package.json
@@@ -13,6 +13,6 @@
"node": ">=22"
},
"dependencies": {
-- "openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.35.0"
++ "openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.35.2"
}
}
ddiff --git a/examples/oauth-app/package.json b/examples/oauth-app/package.json
iindex b4f17ff..7ef3a1e 100644
---- a/examples/oauth-app/package.json
++++ b/examples/oauth-app/package.json
@@@ -13,6 +13,6 @@
"node": ">=22"
},
"dependencies": {
-- "openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.35.0"
++ "openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.35.2"
}
}
ddiff --git a/examples/tool-job/package.json b/examples/tool-job/package.json
iindex aaf0eaa..19d6d11 100644
---- a/examples/tool-job/package.json
++++ b/examples/tool-job/package.json
@@@ -13,6 +13,6 @@
"node": ">=22"
},
"dependencies": {
-- "openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.35.0"
++ "openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.35.2"
}
}
ddiff --git a/examples/webhook-consumer/package.json b/examples/webhook-consumer/package.json
iindex 0447139..50ae525 100644
---- a/examples/webhook-consumer/package.json
++++ b/examples/webhook-consumer/package.json
@@@ -13,7 +13,7 @@
"node": ">=22"
},
"dependencies": {
-- "openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.35.0",
++ "openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.35.2",
"better-sqlite3": "^11.10.0"
}
}
ddiff --git a/package-lock.json b/package-lock.json
iindex cd322c3..1aea0f7 100644
---- a/package-lock.json
++++ b/package-lock.json
@@@ -15,7 +15,7 @@
"create-openvibe-app": "scripts/create-openvibe-app.js"
},
"devDependencies": {
-- "openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.35.0"
++ "openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.35.2"
},
"engines": {
"node": ">=22"
@@@ -26,7 +26,7 @@
"version": "0.2.0",
"license": "MIT",
"dependencies": {
-- "openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.35.0"
++ "openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.35.2"
},
"engines": {
"node": ">=22"
@@@ -48,7 +48,7 @@
"version": "0.2.0",
"license": "MIT",
"dependencies": {
-- "openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.35.0"
++ "openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.35.2"
},
"engines": {
"node": ">=22"
@@@ -59,7 +59,7 @@
"version": "0.2.0",
"license": "MIT",
"dependencies": {
-- "openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.35.0"
++ "openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.35.2"
},
"engines": {
"node": ">=22"
@@@ -71,7 +71,7 @@
"license": "MIT",
"dependencies": {
"openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.112.0",
-- "openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.35.0"
++ "openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.35.2"
},
"engines": {
"node": ">=22"
@@@ -82,7 +82,7 @@
"version": "0.2.0",
"license": "MIT",
"dependencies": {
-- "openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.35.0"
++ "openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.35.2"
},
"engines": {
"node": ">=22"
@@@ -93,7 +93,7 @@
"version": "0.2.0",
"license": "MIT",
"dependencies": {
-- "openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.35.0"
++ "openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.35.2"
},
"engines": {
"node": ">=22"
@@@ -104,7 +104,7 @@
"version": "0.2.0",
"license": "MIT",
"dependencies": {
-- "openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.35.0"
++ "openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.35.2"
},
"engines": {
"node": ">=22"
@@@ -116,7 +116,7 @@
"license": "MIT",
"dependencies": {
"better-sqlite3": "^11.10.0",
-- "openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.35.0"
++ "openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.35.2"
},
"engines": {
"node": ">=22"
@@@ -472,9 +472,10 @@
"link": true
},
"node_modules/openvibe-sdk": {
-- "version": "0.35.0",
-- "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.35.0",
-- "integrity": "sha512-IF7XB97tU7Q+ccwssGx6QXXcfDPcVpl+mX3BjIr7C6NJlcmoqj9DbHiKrBxlVav0eG44Jf8zuXEwokrHDq3J0w==",
++ "version": "0.35.2",
++ "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.35.2",
++ "integrity": "sha512-HudKZJK3lZ9i0+yRdMrz9pJmIrYNTN8AFqbHFCz5jDCF68CfZwUJQyhE61pHODzGRyTvUi4DtAzkd0WEzIWx/g==",
++ "dev": true,
"license": "MIT",
"engines": {
"node": ">=20"
ddiff --git a/package.json b/package.json
iindex 082cab7..5805942 100644
---- a/package.json
++++ b/package.json
@@@ -23,6 +23,6 @@
"node": ">=22"
},
"devDependencies": {
-- "openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.35.0"
++ "openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.35.2"
}
}
ddiff --git a/scripts/developer-path-mock.js b/scripts/developer-path-mock.js
iindex 2b3d6e5..2a676b1 100644
---- a/scripts/developer-path-mock.js
++++ b/scripts/developer-path-mock.js
@@@ -10,21 +10,21 @@
* the flow uses, /api/auth/register and /api/auth/login, as a thin layer: register creates a mock
* user and returns a Network user token for it; login returns one for an existing user (the mock
* does not check passwords). It also mints Network's export tokens (the export step, signed by the
-- * platform like any app token) and stands in for OpenVibe.Codes' release API (the release step):
-- * an app token for openvibe.codes carrying codes.release.manage manages the app's own releases,
-- * draft → published → deprecated → revoked, and the public list shows every release but drafts, like Codes.
++ * platform like any app token) and stands in for OpenVibe.Services' release API (the release step):
++ * an app token for openvibe.services carrying services.release.manage manages the app's own releases,
++ * draft → published → deprecated → revoked, and the public list shows every release but drafts, like Services.
* Everything else is the platform mock's own.
*/
const { createMockPlatform } = require('openvibe-sdk/testing');
--const { runDeveloperPath, PRODUCTION_NETWORK, PRODUCTION_CODES } = require('./developer-path');
++const { runDeveloperPath, PRODUCTION_NETWORK, PRODUCTION_SERVICES } = require('./developer-path');
function withAccounts(platform, network = PRODUCTION_NETWORK) {
const byName = new Map();
const reply = (status, body) => new Response(JSON.stringify(body), { status, headers: { 'Content-Type': 'application/json' } });
-- // OpenVibe.Codes' release API, in memory (the token's signature is the platform's; here its claims decide).
++ // OpenVibe.Services' release API, in memory (the token's signature is the platform's; here its claims decide).
const releases = new Map();
let n = 0;
-- function codes(url, method, init) {
++ function services(url, method, init) {
const m = url.pathname.match(/^\/api\/v1\/(?:apps\/(app_[0-9A-Z]+)\/releases|releases\/([a-z0-9_]+)\/(publish|deprecate|revoke))$/i);
if (!m) return reply(404, { code: 'route.not_found' });
const list = (appId) => [...releases.values()].filter((r) => r.app_id === appId && r.status !== 'draft');
@@@ -32,7 +32,7 @@ function withAccounts(platform, network = PRODUCTION_NETWORK) {
let claims = null;
try { claims = JSON.parse(Buffer.from(String((init.headers || {}).Authorization || '').replace(/^Bearer /, '').split('.')[1], 'base64url').toString('utf8')); } catch { claims = null; }
if (!claims) return reply(401, { code: 'auth.required' });
-- if (!(claims.aud || []).includes('openvibe.codes') || !(claims.cap || []).includes('codes.release.manage')) return reply(403, { code: 'capability.denied' });
++ if (!(claims.aud || []).includes('openvibe.services') || !(claims.cap || []).includes('services.release.manage')) return reply(403, { code: 'capability.denied' });
const body = JSON.parse(init.body || '{}');
if (m[1]) {
if (claims.sub !== `app:${m[1]}` || !body.manifest || body.manifest.id !== m[1]) return reply(403, { code: 'release.forbidden' });
@@@ -73,7 +73,7 @@ function withAccounts(platform, network = PRODUCTION_NETWORK) {
const token = platform.signAppToken(`app_${ex[1].slice(4)}`, { audience: body.audience, capabilities: caps, projectId: ex[1], env: body.env || 'production' });
return reply(201, { access_token: token, token_type: 'Bearer', expires_in: 300, scope: caps.join(' ') });
}
-- if (url.origin === PRODUCTION_CODES) return codes(url, method, init);
++ if (url.origin === PRODUCTION_SERVICES) return services(url, method, init);
return platform.fetch(input, init);
};
}
ddiff --git a/scripts/developer-path.js b/scripts/developer-path.js
iindex d616210..9c778d8 100644
---- a/scripts/developer-path.js
++++ b/scripts/developer-path.js
@@@ -9,14 +9,14 @@
* 2. discovery GET /.well-known/openvibe, as any origin may
* 3. project a new project (sandbox) through /api/v1/projects (openvibe-sdk/projects)
* 4. app a confidential sandbox app; its secret is held in memory only
-- * 5. grants media.object.upload|read, events.app.publish|read and codes.release.manage,
++ * 5. grants media.object.upload|read, events.app.publish|read and services.release.manage,
* approved at once for the project owner inside the sandbox allowance
* 6. media examples/media-uploader: upload a small file, read it back, delete it
* 7. events examples/event-subscriber: publish app.<project_key>.developer_path.ran, pull it
* 8. export as the project's owner: Network mints read-only export tokens (5 minutes); Media
* lists the project's sandbox files with one and refuses an upload; Events returns the
* event from step 7 with the other (roadmap WS-N task 9, the project export)
-- * 9. release as the app, on OpenVibe.Codes: a sandbox release of itself goes draft →
++ * 9. release as the app, on OpenVibe.Services: a sandbox release of itself goes draft →
* published → deprecated → revoked, checked in the public list at each step (a
* draft is never listed; a revoked release stays listed, marked revoked)
* (roadmap WS-N task 5, the app release flow in production)
@@@ -35,7 +35,7 @@
*
* Credentials come from the environment only (or ./.env). It refuses to start without them, and
* refuses to run in CI against the production Network (CI set and OV_NETWORK_URL unset or
-- * openvibe.network). Optional: OV_NETWORK_URL, OV_CODES_URL. It never prints a password, secret or token: they
++ * openvibe.network). Optional: OV_NETWORK_URL, OV_SERVICES_URL. It never prints a password, secret or token: they
* are masked in all output, and signed URLs are shown without their signature. Exit 0 when every
* step passed, 1 when one failed, 2 when it refused to start.
*/
@@@ -52,10 +52,10 @@ const { publishAppEvent, loadConfig: publishConfig } = require(path.join(ROOT, '
const { createSubscriber, createCursorStore, loadConfig: subscriberConfig } = require(path.join(ROOT, 'examples/event-subscriber/subscriber'));
const PRODUCTION_NETWORK = 'https://openvibe.network';
--const PRODUCTION_CODES = 'https://openvibe.codes';
++const PRODUCTION_SERVICES = 'https://openvibe.services';
const PRODUCTION_MEDIA = 'https://openvibe.media';
const PRODUCTION_EVENTS = 'https://openvibe.events';
--const GRANTS = ['media.object.upload', 'media.object.read', 'events.app.publish', 'events.app.read', 'codes.release.manage'];
++const GRANTS = ['media.object.upload', 'media.object.read', 'events.app.publish', 'events.app.read', 'services.release.manage'];
const STEPS = ['account', 'discovery', 'project', 'app', 'grants', 'media', 'events', 'export', 'release', 'credentials', 'cleanup'];
const STEP_TIMEOUT_MS = 120000;
@@@ -102,9 +102,9 @@ async function tryToken(fetchImpl, network, clientId, clientSecret, audience) {
* called with every password, secret and token as soon as it is known, so the caller can mask it.
* → { ok, steps: [{ name, ok, skipped?, error? }], projectId, appId }
*/
--async function runDeveloperPath({ network = PRODUCTION_NETWORK, codes = PRODUCTION_CODES, media = PRODUCTION_MEDIA, events = PRODUCTION_EVENTS, fetch: fetchImpl = globalThis.fetch, account, log = (m) => console.log(m), onSecret = () => {}, now = () => new Date() }) {
++async function runDeveloperPath({ network = PRODUCTION_NETWORK, services = PRODUCTION_SERVICES, media = PRODUCTION_MEDIA, events = PRODUCTION_EVENTS, fetch: fetchImpl = globalThis.fetch, account, log = (m) => console.log(m), onSecret = () => {}, now = () => new Date() }) {
network = network.replace(/\/+$/, '');
-- codes = codes.replace(/\/+$/, '');
++ services = services.replace(/\/+$/, '');
const say = (m) => log(` ${m}`);
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'ov-developer-path-'));
const st = { token: null, projects: null, projectId: null, appId: null, secret: null, credentialId: null, newSecret: null };
@@@ -256,10 +256,10 @@ async function runDeveloperPath({ network = PRODUCTION_NETWORK, codes = PRODUCTI
});
await step('release', async () => {
-- const token = await appToken(fetchImpl, network, st.appId, st.secret, 'openvibe.codes');
++ const token = await appToken(fetchImpl, network, st.appId, st.secret, 'openvibe.services');
onSecret(token);
const call = async (method, p, body, auth = true) => {
-- const res = await fetchImpl(`${codes}/api/v1${p}`, {
++ const res = await fetchImpl(`${services}/api/v1${p}`, {
method, headers: { Accept: 'application/json', ...(body ? { 'Content-Type': 'application/json' } : {}), ...(auth ? { Authorization: `Bearer ${token}` } : {}) },
body: body ? JSON.stringify(body) : undefined,
});
@@@ -277,7 +277,7 @@ async function runDeveloperPath({ network = PRODUCTION_NETWORK, codes = PRODUCTI
if (!draft || draft.status !== 'draft') throw new Error(`the new release is ${draft && draft.status}, not draft`);
if (await listed(draft.id)) throw new Error('a draft is listed publicly');
say(`draft ${draft.id} (${version})`);
-- // Codes lists every release but drafts, a revoked one included (marked revoked), so people see it was pulled.
++ // Services lists every release but drafts, a revoked one included (marked revoked), so people see it was pulled.
const steps = [['publish', {}, 'published'], ['deprecate', { reason: 'developer path check' }, 'deprecated'], ['revoke', { reason: 'developer path check done' }, 'revoked']];
for (const [action, body, want] of steps) {
const r = await call('POST', `/releases/${draft.id}/${action}`, body);
@@@ -358,8 +358,8 @@ async function main(argv = process.argv.slice(2), env = process.env) {
const onSecret = maskOutput();
console.log(`OpenVibe developer path against ${network}\n`);
const started = Date.now();
-- const codes = (env.OV_CODES_URL || PRODUCTION_CODES).replace(/\/+$/, '');
-- const result = await runDeveloperPath({ network, codes, media: env.OV_MEDIA_URL || PRODUCTION_MEDIA, events: env.OV_EVENTS_URL || PRODUCTION_EVENTS, account, onSecret });
++ const services = (env.OV_SERVICES_URL || PRODUCTION_SERVICES).replace(/\/+$/, '');
++ const result = await runDeveloperPath({ network, services, media: env.OV_MEDIA_URL || PRODUCTION_MEDIA, events: env.OV_EVENTS_URL || PRODUCTION_EVENTS, account, onSecret });
// --result <file>: a JSON record for the scheduled production run (OpenVibe.Host openvibe-devpath.timer,
// shown on openvibe.network/status): step names and outcomes only — never an error text, URL, id or secret.
const out = argv.indexOf('--result');
@@@ -378,7 +378,7 @@ function writeResult(file, result, { network, started = Date.now(), now = Date.n
return record;
}
--module.exports = { runDeveloperPath, writeResult, GRANTS, STEPS, PRODUCTION_NETWORK, PRODUCTION_CODES };
++module.exports = { runDeveloperPath, writeResult, GRANTS, STEPS, PRODUCTION_NETWORK, PRODUCTION_SERVICES };
if (require.main === module) {
main().then((code) => { process.exitCode = code; }, (err) => { console.error(`developer-path: ${describeError(err)}`); process.exitCode = 1; });
ddiff --git a/test/structure.test.js b/test/structure.test.js
iindex 1b4ae11..f878024 100644
---- a/test/structure.test.js
++++ b/test/structure.test.js
@@@ -12,7 +12,7 @@ const path = require('node:path');
const ROOT = path.join(__dirname, '..');
const EXPECTED = ['browser-app', 'chat-bot', 'event-subscriber', 'media-uploader', 'mod-manifest', 'node-server-app', 'oauth-app', 'tool-job', 'webhook-consumer'];
--const SDK = 'https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.35.0';
++const SDK = 'https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.35.2';
const dirs = fs.readdirSync(path.join(ROOT, 'examples')).filter((d) => fs.statSync(path.join(ROOT, 'examples', d)).isDirectory()).sort();
assert.deepEqual(dirs, EXPECTED, 'the nine charter examples');