Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
mike182uk committed Sep 17, 2024
1 parent e09f23e commit 9e3d4f3
Show file tree
Hide file tree
Showing 17 changed files with 222 additions and 176 deletions.
35 changes: 35 additions & 0 deletions biome.jsonc
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
{
"$schema": "https://biomejs.dev/schemas/1.9.1/schema.json",
"vcs": {
"enabled": false,
"clientKind": "git",
"useIgnoreFile": false
},
"files": {
"ignoreUnknown": false,
"ignore": []
},
"formatter": {
"enabled": true,
"indentStyle": "space",
"indentWidth": 4
},
"organizeImports": {
"enabled": true
},
"linter": {
"enabled": true,
"rules": {
"recommended": true,
"suspicious": {
"noExplicitAny": "off",
"noImplicitAnyLet": "off"
}
}
},
"javascript": {
"formatter": {
"quoteStyle": "double"
}
}
}
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,14 @@
"test:integration": "c8 --src src --all --reporter text --reporter cobertura mocha -r tsx './src/**/*.integration.test.ts'",
"test:code": "c8 --src src --all --reporter text --reporter cobertura mocha -r tsx './src/**/*.test.ts'",
"test:all": "yarn test:types && yarn test:code",
"lint:code": "eslint *.js lib/ --ext .js --cache",
"lint:code": "biome lint src",
"lint": "yarn lint:code"
},
"files": [
"src"
],
"devDependencies": {
"@biomejs/biome": "1.9.1",
"@cucumber/cucumber": "10.8.0",
"@types/mocha": "10.0.7",
"@types/node": "20.12.12",
Expand Down
30 changes: 15 additions & 15 deletions src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
createFederation,
Follow,
KvKey,
KvStore,
type KvStore,
MemoryKvStore,
Create,
Note,
Expand All @@ -16,12 +16,12 @@ import {
Service,
Update,
Announce,
Context,
type Context,
Like,
Undo,
} from '@fedify/fedify';
import { federation } from '@fedify/fedify/x/hono';
import { Hono, Context as HonoContext } from 'hono';
import { Hono, type Context as HonoContext } from 'hono';
import { cors } from 'hono/cors';
import { behindProxy } from 'x-forwarded-fetch';
import { configure, getConsoleSink } from '@logtape/logtape';
Expand Down Expand Up @@ -90,7 +90,7 @@ export const db = await KnexKvStore.create(client, 'key_value');
* for example in the context of the Inbox Queue - so we need to wrap handlers with this.
*/
function ensureCorrectContext<B, R>(fn: (ctx: Context<ContextData>, b: B) => Promise<R>) {
return async function (ctx: Context<any>, b: B) {
return async (ctx: Context<any>, b: B) => {
const host = ctx.host;
if (!ctx.data) {
(ctx as any).data = {};
Expand Down Expand Up @@ -157,42 +157,42 @@ fedify

fedify.setObjectDispatcher(
Article,
`/.ghost/activitypub/article/{id}`,
'/.ghost/activitypub/article/{id}',
articleDispatcher,
);
fedify.setObjectDispatcher(
Note,
`/.ghost/activitypub/note/{id}`,
'/.ghost/activitypub/note/{id}',
noteDispatcher,
);
fedify.setObjectDispatcher(
Follow,
`/.ghost/activitypub/follow/{id}`,
'/.ghost/activitypub/follow/{id}',
followDispatcher,
);
fedify.setObjectDispatcher(
Accept,
`/.ghost/activitypub/accept/{id}`,
'/.ghost/activitypub/accept/{id}',
acceptDispatcher,
);
fedify.setObjectDispatcher(
Create,
`/.ghost/activitypub/create/{id}`,
'/.ghost/activitypub/create/{id}',
createDispatcher,
);
fedify.setObjectDispatcher(
Update,
`/.ghost/activitypub/update/{id}`,
'/.ghost/activitypub/update/{id}',
updateDispatcher,
);
fedify.setObjectDispatcher(
Like,
`/.ghost/activitypub/like/{id}`,
'/.ghost/activitypub/like/{id}',
likeDispatcher,
);
fedify.setObjectDispatcher(
Undo,
`/.ghost/activitypub/undo/{id}`,
'/.ghost/activitypub/undo/{id}',
undoDispatcher,
);

Expand Down Expand Up @@ -298,7 +298,7 @@ app.use(
);

function forceAcceptHeader(fn: (req: Request) => unknown) {
return function (request: Request) {
return (request: Request) => {
request.headers.set('accept', 'application/activity+json');
return fn(request);
};
Expand All @@ -307,9 +307,9 @@ function forceAcceptHeader(fn: (req: Request) => unknown) {
serve(
{
fetch: forceAcceptHeader(behindProxy(app.fetch)),
port: parseInt(process.env.PORT || '8080'),
port: Number.parseInt(process.env.PORT || '8080'),
},
function (info) {
(info) => {
console.log(`listening on ${info.address}:${info.port}`);
},
);
Expand Down
4 changes: 2 additions & 2 deletions src/db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ export const client = Knex({
client: 'mysql2',
connection: {
host: process.env.MYSQL_HOST,
port: parseInt(process.env.MYSQL_PORT!),
port: Number.parseInt(process.env.MYSQL_PORT!),
user: process.env.MYSQL_USER,
password: process.env.MYSQL_PASSWORD,
database: process.env.MYSQL_DATABASE,
},
});

await client.schema.createTableIfNotExists('key_value', function (table) {
await client.schema.createTableIfNotExists('key_value', (table) => {
table.increments('id').primary();
table.string('key', 2048);
table.json('value').notNullable();
Expand Down
34 changes: 14 additions & 20 deletions src/dispatchers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,23 @@ import {
Accept,
Follow,
Person,
RequestContext,
type RequestContext,
Create,
Note,
Activity,
Update,
Context,
Announce,
type Context,
type Announce,
isActor,
Actor,
type Actor,
Object as APObject,
Recipient,
type Recipient,
Like,
Undo,
} from '@fedify/fedify';
import { v4 as uuidv4 } from 'uuid';
import { addToList } from './kv-helpers';
import { ContextData } from './app';
import type { ContextData } from './app';
import { ACTOR_DEFAULT_HANDLE } from './constants';
import { getUserData, getUserKeypair } from './user';
import { lookupActor } from './lookup-helpers';
Expand Down Expand Up @@ -66,7 +66,7 @@ export async function handleFollow(
}

const currentFollowers = await ctx.data.db.get<string[]>(['followers']) ?? [];
let shouldRecordFollower = currentFollowers.includes(sender.id.href) === false;
const shouldRecordFollower = currentFollowers.includes(sender.id.href) === false;

// Add follow activity to inbox
const followJson = await follow.toJsonLd();
Expand Down Expand Up @@ -108,10 +108,7 @@ export async function handleAccept(
console.log('Handling Accept');
const parsed = (ctx as any).parseUri(accept.objectId);
console.log(parsed);
if (false && parsed?.type !== 'follow') {
console.log('Not accepting a follow - exit');
return;
}

if (!accept.id) {
console.log('Accept missing id - exit');
return;
Expand Down Expand Up @@ -140,10 +137,7 @@ export async function handleCreate(
console.log('Handling Create');
const parsed = (ctx as any).parseUri(create.objectId);
console.log(parsed);
if (false && parsed?.type !== 'article') {
console.log('Not accepting a follow - exit');
return;
}

if (!create.id) {
console.log('Accept missing id - exit');
return;
Expand Down Expand Up @@ -188,7 +182,7 @@ export async function handleAnnounce(

// Lookup announced object - If not found in globalDb, perform network lookup
let object = null;
let existing = await ctx.data.globaldb.get([announce.objectId.href]) ?? null;
const existing = await ctx.data.globaldb.get([announce.objectId.href]) ?? null;

if (!existing) {
console.log('Object not found in globalDb, performing network lookup');
Expand Down Expand Up @@ -257,7 +251,7 @@ export async function handleLike(

// Lookup liked object - If not found in globalDb, perform network lookup
let object = null;
let existing = await ctx.data.globaldb.get([like.objectId.href]) ?? null;
const existing = await ctx.data.globaldb.get([like.objectId.href]) ?? null;

if (!existing) {
console.log('Object not found in globalDb, performing network lookup');
Expand Down Expand Up @@ -349,7 +343,7 @@ export async function followingDispatcher(
console.log('Following Dispatcher');
const results = (await ctx.data.db.get<string[]>(['following'])) || [];
console.log(results);
let items: Person[] = [];
const items: Person[] = [];
for (const result of results) {
try {
const thing = await lookupActor(ctx, result);
Expand Down Expand Up @@ -386,7 +380,7 @@ export async function outboxDispatcher(
const results = filterOutboxActivityUris((await ctx.data.db.get<string[]>(['outbox'])) || []);
console.log(results);

let items: Activity[] = [];
const items: Activity[] = [];
for (const result of results) {
try {
const thing = await ctx.data.globaldb.get([result]);
Expand Down Expand Up @@ -418,7 +412,7 @@ export async function likedDispatcher(
const results = (await ctx.data.db.get<string[]>(['liked'])) || [];
console.log(results);

let items: Like[] = [];
const items: Like[] = [];
for (const result of results) {
try {
const thing = await ctx.data.globaldb.get([result]);
Expand Down
24 changes: 12 additions & 12 deletions src/dispatchers.unit.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import assert from 'assert';
import assert from 'node:assert';
import sinon from 'sinon';
import {
actorDispatcher,
Expand All @@ -19,12 +19,12 @@ import {
acceptDispatcher,
createDispatcher,
} from './dispatchers';
import { Activity, RequestContext } from '@fedify/fedify';
import { Activity, type RequestContext } from '@fedify/fedify';
import { ACTOR_DEFAULT_HANDLE } from './constants';

describe('dispatchers', function () {
describe('actorDispatcher', function () {
it(`returns null if the handle is not "${ACTOR_DEFAULT_HANDLE}"`, async function () {
describe('dispatchers', () => {
describe('actorDispatcher', () => {
it(`returns null if the handle is not "${ACTOR_DEFAULT_HANDLE}"`, async () => {
const ctx = {} as RequestContext<any>;
const handle = 'anything';

Expand All @@ -34,10 +34,10 @@ describe('dispatchers', function () {
assert.equal(actual, expected);
});
});
describe('keypairDispatcher', function () {});
describe('handleFollow', function () {});
describe('keypairDispatcher', () => {});
describe('handleFollow', () => {});

describe('outboxDispatcher', function () {
describe('outboxDispatcher', () => {
const outboxActivities: Record<string, any> = {
'https://example.com/create/123': {
'@context': [
Expand Down Expand Up @@ -84,15 +84,15 @@ describe('dispatchers', function () {
},
} as RequestContext<any>;

beforeEach(function () {
beforeEach(() => {
ctx.data.db.get.withArgs(['outbox']).resolves(Object.keys(outboxActivities));

Object.keys(outboxActivities).forEach(key => {
for (const key of Object.keys(outboxActivities)) {
ctx.data.globaldb.get.withArgs([key]).resolves(outboxActivities[key]);
});
}
});

it('returns relevant items from the outbox in the correct order', async function () {
it('returns relevant items from the outbox in the correct order', async () => {
const result = await outboxDispatcher(ctx, ACTOR_DEFAULT_HANDLE);

// Check items exist
Expand Down
6 changes: 3 additions & 3 deletions src/example.unit.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import assert from 'assert';
import assert from 'node:assert';

describe('Sanity', function () {
it('1 + 1 = 2', function () {
describe('Sanity', () => {
it('1 + 1 = 2', () => {
assert.equal(1 + 1, 2, '1 + 1 should equal 2');
});
});
12 changes: 6 additions & 6 deletions src/ghost.unit.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import assert from 'assert';
import assert from 'node:assert';
import sinon from 'sinon';
import ky from 'ky';
import { getSiteSettings } from './ghost';
Expand All @@ -8,20 +8,20 @@ import {
ACTOR_DEFAULT_SUMMARY
} from './constants';

describe('getSiteSettings', function () {
describe('getSiteSettings', () => {
const host = 'example.com';

let kyGetStub: sinon.SinonStub;

beforeEach(function () {
beforeEach(() => {
kyGetStub = sinon.stub(ky, 'get');
});

afterEach(function () {
afterEach(() => {
sinon.restore();
});

it('should retrieve settings from Ghost', async function () {
it('should retrieve settings from Ghost', async () => {
const settings = {
site: {
description: 'foo',
Expand All @@ -41,7 +41,7 @@ describe('getSiteSettings', function () {
assert.strictEqual(kyGetStub.firstCall.args[0], `https://${host}/ghost/api/admin/site/`);
});

it('should use defaults for missing settings', async function () {
it('should use defaults for missing settings', async () => {
let result;

// Missing description
Expand Down
Loading

0 comments on commit 9e3d4f3

Please sign in to comment.