openvibers/openvibe.connect Commits
/llms-full.txt (SEO-33): llms.txt and the README (#25)
Changes
@@@ -25,6 +25,8 @@ const views = require('../views');const { ShareError } = require('../shares');const { HookError } = require('../hooks');const { ApiKeyError } = require('../api-keys');++// Connect's README, its full public documentation, for /llms-full.txt (read once; empty if it is not shipped).++const README = (() => { try { return require('fs').readFileSync(require('path').join(__dirname, '..', '..', 'README.md'), 'utf8').trim(); } catch { return ''; } })();const { OAuthError } = require('../oauth');function createPageRoutes(ctx) {@@@ -306,8 +308,8 @@ function createPageRoutes(ctx) {r.get('/robots.txt', (req, res) => {res.type('text/plain').set('Cache-Control', 'public, max-age=3600').send(`User-agent: *\nAllow: /$\nDisallow: /shares\nDisallow: /grant\nDisallow: /auth\nDisallow: /api\n`);});-- r.get('/llms.txt', (req, res) => {-- res.type('text/plain').set('Cache-Control', 'public, max-age=3600').send([++ // What llms.txt says (SEO-33: /llms-full.txt adds the README, Connect's full documentation, after it).++ const LLMS_LINES = ['# OpenVibe Connect','','> Share one port on your computer at https://<name>--<username>.openvibe.website, behind OpenVibe sign-in.',@@@ -318,7 +320,12 @@ function createPageRoutes(ctx) {'- API (a person\'s Network token as a Bearer): GET/POST /api/v1/shares, GET/PATCH/DELETE /api/v1/shares/{id}, POST /api/v1/shares/{id}/key','- Source: https://github.com/OpenVibers/OpenVibe.Connect (AGPL-3.0)','',-- ].join('\n'));++ ];++ r.get('/llms.txt', (req, res) => {++ res.type('text/plain').set('Cache-Control', 'public, max-age=3600').send(LLMS_LINES.join('\n'));++ });++ r.get('/llms-full.txt', (req, res) => {++ res.type('text/plain').set('Cache-Control', 'public, max-age=3600').send(`${LLMS_LINES.join('\n')}\n\n## The documentation (README)\n\n${README}\n`);});return r;@@@ -100,6 +100,13 @@ const { check, done } = require('./helpers/check');await check('robots, llms.txt and the client download', async () => {assert.match((await t.get('/robots.txt')).text, /Disallow: \/grant/);assert.match((await t.get('/llms.txt')).text, /OpenVibe Connect/);++ // SEO-33: llms.txt, then the README (Connect's full documentation).++ const full = await t.get('/llms-full.txt');++ assert.strictEqual(full.status, 200);++ assert.ok(full.text.startsWith('# OpenVibe Connect'));++ assert.match(full.text, /## The documentation \(README\)\n\n# /);++ assert.match(full.text, /API keys for programs/, 'the README\'s sections are in it');++ assert.ok(full.text.length > 5000, `${full.text.length} characters`);const js = await t.get('/ov-connect.js');assert.strictEqual(js.status, 200);assert.match(js.headers.get('content-type'), /javascript/);
@@ -25,6 +25,8 @@ const views = require('../views');
@@ -25,6 +25,8 @@ const views = require('../views');
const { ShareError } = require('../shares');
const { ShareError } = require('../shares');
const { HookError } = require('../hooks');
const { HookError } = require('../hooks');
const { ApiKeyError } = require('../api-keys');
const { ApiKeyError } = require('../api-keys');
+// Connect's README, its full public documentation, for /llms-full.txt (read once; empty if it is not shipped).
+const README = (() => { try { return require('fs').readFileSync(require('path').join(__dirname, '..', '..', 'README.md'), 'utf8').trim(); } catch { return ''; } })();
const { OAuthError } = require('../oauth');
const { OAuthError } = require('../oauth');
function createPageRoutes(ctx) {
function createPageRoutes(ctx) {
@@ -306,8 +308,8 @@ function createPageRoutes(ctx) {
@@ -306,8 +308,8 @@ function createPageRoutes(ctx) {
r.get('/robots.txt', (req, res) => {
r.get('/robots.txt', (req, res) => {
res.type('text/plain').set('Cache-Control', 'public, max-age=3600').send(`User-agent: *\nAllow: /$\nDisallow: /shares\nDisallow: /grant\nDisallow: /auth\nDisallow: /api\n`);
res.type('text/plain').set('Cache-Control', 'public, max-age=3600').send(`User-agent: *\nAllow: /$\nDisallow: /shares\nDisallow: /grant\nDisallow: /auth\nDisallow: /api\n`);
});
});
- r.get('/llms.txt', (req, res) => {
- res.type('text/plain').set('Cache-Control', 'public, max-age=3600').send([
+ // What llms.txt says (SEO-33: /llms-full.txt adds the README, Connect's full documentation, after it).
+ const LLMS_LINES = [
'# OpenVibe Connect',
'# OpenVibe Connect',
'',
'',
'> Share one port on your computer at https://<name>--<username>.openvibe.website, behind OpenVibe sign-in.',
'> Share one port on your computer at https://<name>--<username>.openvibe.website, behind OpenVibe sign-in.',
@@ -318,7 +320,12 @@ function createPageRoutes(ctx) {
@@ -318,7 +320,12 @@ function createPageRoutes(ctx) {
'- API (a person\'s Network token as a Bearer): GET/POST /api/v1/shares, GET/PATCH/DELETE /api/v1/shares/{id}, POST /api/v1/shares/{id}/key',
'- API (a person\'s Network token as a Bearer): GET/POST /api/v1/shares, GET/PATCH/DELETE /api/v1/shares/{id}, POST /api/v1/shares/{id}/key',
'- Source: https://github.com/OpenVibers/OpenVibe.Connect (AGPL-3.0)',
'- Source: https://github.com/OpenVibers/OpenVibe.Connect (AGPL-3.0)',
'',
'',
- ].join('\n'));
+ ];
+ r.get('/llms.txt', (req, res) => {
+ res.type('text/plain').set('Cache-Control', 'public, max-age=3600').send(LLMS_LINES.join('\n'));
+ });
+ r.get('/llms-full.txt', (req, res) => {
+ res.type('text/plain').set('Cache-Control', 'public, max-age=3600').send(`${LLMS_LINES.join('\n')}\n\n## The documentation (README)\n\n${README}\n`);
});
});
return r;
return r;
@@ -100,6 +100,13 @@ const { check, done } = require('./helpers/check');
@@ -100,6 +100,13 @@ const { check, done } = require('./helpers/check');
await check('robots, llms.txt and the client download', async () => {
await check('robots, llms.txt and the client download', async () => {
assert.match((await t.get('/robots.txt')).text, /Disallow: \/grant/);
assert.match((await t.get('/robots.txt')).text, /Disallow: \/grant/);
assert.match((await t.get('/llms.txt')).text, /OpenVibe Connect/);
assert.match((await t.get('/llms.txt')).text, /OpenVibe Connect/);
+ // SEO-33: llms.txt, then the README (Connect's full documentation).
+ const full = await t.get('/llms-full.txt');
+ assert.strictEqual(full.status, 200);
+ assert.ok(full.text.startsWith('# OpenVibe Connect'));
+ assert.match(full.text, /## The documentation \(README\)\n\n# /);
+ assert.match(full.text, /API keys for programs/, 'the README\'s sections are in it');
+ assert.ok(full.text.length > 5000, `${full.text.length} characters`);
const js = await t.get('/ov-connect.js');
const js = await t.get('/ov-connect.js');
assert.strictEqual(js.status, 200);
assert.strictEqual(js.status, 200);
assert.match(js.headers.get('content-type'), /javascript/);
assert.match(js.headers.get('content-type'), /javascript/);