openvibers/openvibe.sites Commits
Record openvibe.services plannedRepo and let it supersede noRepo on sync
Changes
@@@ -13,6 +13,9 @@* the value sites.json has today (frozen, never dropped): the `network` block, LOCAL fields, and for* a service-home row SERVICE_LOCAL (a service manifest's site name/icon/tagline/legalProfile are the* console card's, not the page's). A sites.json domain missing from the catalog is kept and reported.++ *++ * plannedRepo is noRepo with the repository named (an entry without a live repository yet): when++ * sites.json names one, Contracts' noRepo does not come back (a row never carries both).*/const fs = require('fs');const path = require('path');@@@ -43,6 +46,12 @@ function fromContracts(row, field) {return SHAPE[field] ? SHAPE[field](v) : v;}++/** plannedRepo is noRepo with the repository named; a row must never carry both. */++function dropNoRepo(out) {++ if (out.plannedRepo !== undefined) delete out.noRepo;++ return out;++}++function sync(current) {const rows = new Map(catalog().map(r => [r.domain, r]));const kept = [];@@@ -56,24 +65,28 @@ function sync(current) {if (v !== undefined) out[k] = v;else if (site[k] !== undefined) out[k] = site[k];}-- return out;++ return dropNoRepo(out);});for (const row of rows.values()) {const out = {};for (const k of FIELDS) { const v = fromContracts(row, k); if (v !== undefined) out[k] = v; }-- sites.push(out);++ sites.push(dropNoRepo(out));}return { json: { ...current, sites }, kept };}--const before = fs.readFileSync(FILE, 'utf8');--const { json, kept } = sync(JSON.parse(before));--const after = JSON.stringify(json, null, 2) + '\n';--for (const d of kept) console.error(`sync-catalog: ${d} is not in the Contracts catalog; kept as it is`);--if (process.argv.includes('--check')) {-- if (after !== before) { console.error('sync-catalog: sites.json differs from the Contracts catalog; run node scripts/sync-catalog.js'); process.exit(1); }-- console.log(`sync-catalog: sites.json matches the Contracts catalog (${json.sites.length} sites)`);--} else {-- fs.writeFileSync(FILE, after);-- console.log(`sync-catalog: wrote ${json.sites.length} sites to sites.json`);++if (require.main === module) {++ const before = fs.readFileSync(FILE, 'utf8');++ const { json, kept } = sync(JSON.parse(before));++ const after = JSON.stringify(json, null, 2) + '\n';++ for (const d of kept) console.error(`sync-catalog: ${d} is not in the Contracts catalog; kept as it is`);++ if (process.argv.includes('--check')) {++ if (after !== before) { console.error('sync-catalog: sites.json differs from the Contracts catalog; run node scripts/sync-catalog.js'); process.exit(1); }++ console.log(`sync-catalog: sites.json matches the Contracts catalog (${json.sites.length} sites)`);++ } else {++ fs.writeFileSync(FILE, after);++ console.log(`sync-catalog: wrote ${json.sites.length} sites to sites.json`);++ }}++++module.exports = { sync, dropNoRepo };@@@ -1039,7 +1039,7 @@"name": "OpenVibe.Services","icon": "fa-server","accent": "#38bdf8",-- "noRepo": true,++ "plannedRepo": "OpenVibe.Services","tagline": "Build with the whole network.","description": "OpenVibe.Services will be the way into everything programmable on OpenVibe. Start from what you want to build (monitor a page and summarise changes, run an AI agent, process uploads, control a robot, add support to a site) and it assembles the services, keys, permissions and working code for you. Then operate it all in one place: projects, grants, usage, quotas, runs, events, deploys and health, with each service keeping its own data.","pillars": [@@@ -22,4 +22,12 @@ for (const conf of fs.readdirSync(path.join(ROOT, 'deploy', 'nginx'))) {assert.ok(sites.some(s => s.domain === d), `${d}: has a vhost, so sites.json keeps it`);assert.ok(domains.has(d) || AWAITING_CONTRACTS.includes(d), `${d}: has a home in the Contracts catalog`);}++// plannedRepo (a planned but not yet live repository) supersedes noRepo: Contracts still marks++// openvibe.services noRepo, and sync must not put it back beside the planned repository (T13).++const { dropNoRepo } = require('../scripts/sync-catalog.js');++assert.deepStrictEqual(dropNoRepo({ plannedRepo: 'OpenVibe.Services', noRepo: true }), { plannedRepo: 'OpenVibe.Services' });++assert.deepStrictEqual(dropNoRepo({ noRepo: true }), { noRepo: true });++const services = sites.find(s => s.domain === 'openvibe.services');++assert.strictEqual(services && services.plannedRepo, 'OpenVibe.Services', 'openvibe.services records its planned repository');++assert.ok(services && !('noRepo' in services), 'openvibe.services must not also carry noRepo');console.log(`sync-catalog: ${sites.length} sites, all in the Contracts catalog but ${AWAITING_CONTRACTS.join(', ')}`);
@@ -13,6 +13,9 @@
@@ -13,6 +13,9 @@
* the value sites.json has today (frozen, never dropped): the `network` block, LOCAL fields, and for
* the value sites.json has today (frozen, never dropped): the `network` block, LOCAL fields, and for
* a service-home row SERVICE_LOCAL (a service manifest's site name/icon/tagline/legalProfile are the
* a service-home row SERVICE_LOCAL (a service manifest's site name/icon/tagline/legalProfile are the
* console card's, not the page's). A sites.json domain missing from the catalog is kept and reported.
* console card's, not the page's). A sites.json domain missing from the catalog is kept and reported.
+ *
+ * plannedRepo is noRepo with the repository named (an entry without a live repository yet): when
+ * sites.json names one, Contracts' noRepo does not come back (a row never carries both).
*/
*/
const fs = require('fs');
const fs = require('fs');
const path = require('path');
const path = require('path');
@@ -43,6 +46,12 @@ function fromContracts(row, field) {
@@ -43,6 +46,12 @@ function fromContracts(row, field) {
return SHAPE[field] ? SHAPE[field](v) : v;
return SHAPE[field] ? SHAPE[field](v) : v;
}
}
+/** plannedRepo is noRepo with the repository named; a row must never carry both. */
+function dropNoRepo(out) {
+ if (out.plannedRepo !== undefined) delete out.noRepo;
+ return out;
+}
+
function sync(current) {
function sync(current) {
const rows = new Map(catalog().map(r => [r.domain, r]));
const rows = new Map(catalog().map(r => [r.domain, r]));
const kept = [];
const kept = [];
@@ -56,24 +65,28 @@ function sync(current) {
@@ -56,24 +65,28 @@ function sync(current) {
if (v !== undefined) out[k] = v;
if (v !== undefined) out[k] = v;
else if (site[k] !== undefined) out[k] = site[k];
else if (site[k] !== undefined) out[k] = site[k];
}
}
- return out;
+ return dropNoRepo(out);
});
});
for (const row of rows.values()) {
for (const row of rows.values()) {
const out = {};
const out = {};
for (const k of FIELDS) { const v = fromContracts(row, k); if (v !== undefined) out[k] = v; }
for (const k of FIELDS) { const v = fromContracts(row, k); if (v !== undefined) out[k] = v; }
- sites.push(out);
+ sites.push(dropNoRepo(out));
}
}
return { json: { ...current, sites }, kept };
return { json: { ...current, sites }, kept };
}
}
-const before = fs.readFileSync(FILE, 'utf8');
-const { json, kept } = sync(JSON.parse(before));
-const after = JSON.stringify(json, null, 2) + '\n';
-for (const d of kept) console.error(`sync-catalog: ${d} is not in the Contracts catalog; kept as it is`);
-if (process.argv.includes('--check')) {
- if (after !== before) { console.error('sync-catalog: sites.json differs from the Contracts catalog; run node scripts/sync-catalog.js'); process.exit(1); }
- console.log(`sync-catalog: sites.json matches the Contracts catalog (${json.sites.length} sites)`);
-} else {
- fs.writeFileSync(FILE, after);
- console.log(`sync-catalog: wrote ${json.sites.length} sites to sites.json`);
+if (require.main === module) {
+ const before = fs.readFileSync(FILE, 'utf8');
+ const { json, kept } = sync(JSON.parse(before));
+ const after = JSON.stringify(json, null, 2) + '\n';
+ for (const d of kept) console.error(`sync-catalog: ${d} is not in the Contracts catalog; kept as it is`);
+ if (process.argv.includes('--check')) {
+ if (after !== before) { console.error('sync-catalog: sites.json differs from the Contracts catalog; run node scripts/sync-catalog.js'); process.exit(1); }
+ console.log(`sync-catalog: sites.json matches the Contracts catalog (${json.sites.length} sites)`);
+ } else {
+ fs.writeFileSync(FILE, after);
+ console.log(`sync-catalog: wrote ${json.sites.length} sites to sites.json`);
+ }
}
}
+
+module.exports = { sync, dropNoRepo };
@@ -1039,7 +1039,7 @@
@@ -1039,7 +1039,7 @@
"name": "OpenVibe.Services",
"name": "OpenVibe.Services",
"icon": "fa-server",
"icon": "fa-server",
"accent": "#38bdf8",
"accent": "#38bdf8",
- "noRepo": true,
+ "plannedRepo": "OpenVibe.Services",
"tagline": "Build with the whole network.",
"tagline": "Build with the whole network.",
"description": "OpenVibe.Services will be the way into everything programmable on OpenVibe. Start from what you want to build (monitor a page and summarise changes, run an AI agent, process uploads, control a robot, add support to a site) and it assembles the services, keys, permissions and working code for you. Then operate it all in one place: projects, grants, usage, quotas, runs, events, deploys and health, with each service keeping its own data.",
"description": "OpenVibe.Services will be the way into everything programmable on OpenVibe. Start from what you want to build (monitor a page and summarise changes, run an AI agent, process uploads, control a robot, add support to a site) and it assembles the services, keys, permissions and working code for you. Then operate it all in one place: projects, grants, usage, quotas, runs, events, deploys and health, with each service keeping its own data.",
"pillars": [
"pillars": [
@@ -22,4 +22,12 @@ for (const conf of fs.readdirSync(path.join(ROOT, 'deploy', 'nginx'))) {
@@ -22,4 +22,12 @@ for (const conf of fs.readdirSync(path.join(ROOT, 'deploy', 'nginx'))) {
assert.ok(sites.some(s => s.domain === d), `${d}: has a vhost, so sites.json keeps it`);
assert.ok(sites.some(s => s.domain === d), `${d}: has a vhost, so sites.json keeps it`);
assert.ok(domains.has(d) || AWAITING_CONTRACTS.includes(d), `${d}: has a home in the Contracts catalog`);
assert.ok(domains.has(d) || AWAITING_CONTRACTS.includes(d), `${d}: has a home in the Contracts catalog`);
}
}
+// plannedRepo (a planned but not yet live repository) supersedes noRepo: Contracts still marks
+// openvibe.services noRepo, and sync must not put it back beside the planned repository (T13).
+const { dropNoRepo } = require('../scripts/sync-catalog.js');
+assert.deepStrictEqual(dropNoRepo({ plannedRepo: 'OpenVibe.Services', noRepo: true }), { plannedRepo: 'OpenVibe.Services' });
+assert.deepStrictEqual(dropNoRepo({ noRepo: true }), { noRepo: true });
+const services = sites.find(s => s.domain === 'openvibe.services');
+assert.strictEqual(services && services.plannedRepo, 'OpenVibe.Services', 'openvibe.services records its planned repository');
+assert.ok(services && !('noRepo' in services), 'openvibe.services must not also carry noRepo');
console.log(`sync-catalog: ${sites.length} sites, all in the Contracts catalog but ${AWAITING_CONTRACTS.join(', ')}`);
console.log(`sync-catalog: ${sites.length} sites, all in the Contracts catalog but ${AWAITING_CONTRACTS.join(', ')}`);