Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: define Instance model #837

Merged
merged 4 commits into from
Nov 17, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions pkg/federation/model/__snapshots__/instance.test.ts.snap
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`Instance > should create new instance 1`] = `
Instance {
"adminContact": "https://example.com/contact",
"adminName": "Pulsate project",
"deliverState": "normal",
"description": "pulsate official instance",
"firstContact": 2023-09-10T00:00:00.000Z,
"fqdn": "social.example.com:3000",
"id": "1",
"isLocal": true,
"name": "Pulsate social",
"silenced": "normal",
"softwareName": "Pulsate",
"softwareVersion": "0.1.0",
"state": "normal",
"updated": [
Symbol(OptionNone),
],
}
`;
39 changes: 39 additions & 0 deletions pkg/federation/model/instance.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { describe, expect, it } from 'vitest';
import { Instance, type InstanceID } from './instance.js';

describe('Instance', () => {
it('should create new instance', () => {
const res = Instance.new({
id: '1' as InstanceID,
name: 'Pulsate social',
fqdn: new URL('https://social.example.com:3000'),
softwareName: 'Pulsate',
softwareVersion: '0.1.0',
adminName: 'Pulsate project',
description: 'pulsate official instance',
adminContact: 'https://example.com/contact',
isLocal: true,
firstContact: new Date('2023-09-10T00:00:00.000Z'),
});

expect(res).toMatchSnapshot();
});

it('should set Unknown/Unknwon if software version or name empty', () => {
const res = Instance.new({
id: '1' as InstanceID,
name: 'Pulsate social',
fqdn: new URL('https://social.example.com:3000'),
softwareName: '',
softwareVersion: '',
adminName: 'Pulsate project',
description: 'pulsate official instance',
adminContact: 'https://example.com/contact',
isLocal: true,
firstContact: new Date('2023-09-10T00:00:00.000Z'),
});

expect(res.getSoftwareName()).toBe('Unknown');
expect(res.getSoftwareVersion()).toBe('Unknown');
});
});
310 changes: 310 additions & 0 deletions pkg/federation/model/instance.ts
MikuroXina marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,310 @@
import { Option } from '@mikuroxina/mini-fn';
import type { ID } from '../../id/type.js';

export type InstanceID = ID<Instance>;
export type InstanceState = 'normal' | 'blocked';
export type InstanceSilenced = 'normal' | 'silenced';
export type InstanceDeliverState = 'normal' | 'stopped';
laminne marked this conversation as resolved.
Show resolved Hide resolved

export interface CreateInstanceArgs {
id: InstanceID;
name: string;
description: string;
fqdn: URL;
softwareName: string;
softwareVersion: string;
adminName: string;
adminContact: string;
isLocal: boolean;
firstContact: Date;
// private
state: InstanceState;
silenced: InstanceSilenced;
deliverState: InstanceDeliverState;
updated: Option.Option<Date>;
}

export class Instance {
/**
* Instance ID
* @type {@link InstanceID}
* @example "30840483483726295"
*/
private readonly id: InstanceID;
/**
* Instance name
* @example "Pulsate social"
*/
private name: string;
/**
* Instance description
* @example
* ```
* Pulsate official instance
* ```
*/
private description: string;
/**
* Instance FQDN
* @example "pulsate.social"
*/
private readonly fqdn: string;
/**
* Software name
* @example "Pulsate"
*/
private readonly softwareName: string;
/**
* Software version
* @example "1.0.0"
*/
private softwareVersion: string;
/**
* Instance admin name
* @example "Pulsate project"
*/
private adminName: string;
/**
* Instance admin contact
* @example "[email protected]"
* @example "https://pulsate.dev/contact"
*/
private adminContact: string;
/**
* Instance state
* - `normal` - Instance is active
* - `blocked` - Instance is blocked(reject all activity)
*/
private state: InstanceState;
/**
* Instance silenced state
* - `normal` - Instance is not silenced
* - `silenced` - Instance is silenced (all PUBLIC notes visibility sets to HOME)
*/
private silenced: InstanceSilenced;
/**
* Instance deliver state
* - `normal` - Instance is delivering notes
* - `stopped` - Instance is not delivering notes
*/
private deliverState: InstanceDeliverState;
/**
* Instance isLocal flag
* - `true` - Instance is local
* - `false` - Instance is remote
*/
private readonly isLocal: boolean;

/**
* Instance first contact date
*/
private readonly firstContact: Date;
/**
* Instance data updated date
*/
private updated: Option.Option<Date>;

/**
* Instance ID
* @returns Instance ID
*/
getID(): InstanceID {
return this.id;
}

Check warning on line 113 in pkg/federation/model/instance.ts

View check run for this annotation

Codecov / codecov/patch

pkg/federation/model/instance.ts#L112-L113

Added lines #L112 - L113 were not covered by tests

/**
* Instance Name
* @returns Instance name
*/
getName(): string {
return this.name;
}

Check warning on line 121 in pkg/federation/model/instance.ts

View check run for this annotation

Codecov / codecov/patch

pkg/federation/model/instance.ts#L120-L121

Added lines #L120 - L121 were not covered by tests

/**
* Set instance name
* @param name Instance name
*/
setName(name: string) {
this.name = name;
this.setUpdated();
}

Check warning on line 130 in pkg/federation/model/instance.ts

View check run for this annotation

Codecov / codecov/patch

pkg/federation/model/instance.ts#L128-L130

Added lines #L128 - L130 were not covered by tests

/**
* Instance description
* @returns Instance description
*/
getDescription(): string {
return this.description;
}

Check warning on line 138 in pkg/federation/model/instance.ts

View check run for this annotation

Codecov / codecov/patch

pkg/federation/model/instance.ts#L137-L138

Added lines #L137 - L138 were not covered by tests

/**
* Set instance description
* @param description Instance description
*/
setDescription(description: string) {
this.description = description;
this.setUpdated();
}

Check warning on line 147 in pkg/federation/model/instance.ts

View check run for this annotation

Codecov / codecov/patch

pkg/federation/model/instance.ts#L145-L147

Added lines #L145 - L147 were not covered by tests

/**
* Instance FQDN
* @returns Instance FQDN
*/
getFQDN(): string {
laminne marked this conversation as resolved.
Show resolved Hide resolved
return this.fqdn;
}

Check warning on line 155 in pkg/federation/model/instance.ts

View check run for this annotation

Codecov / codecov/patch

pkg/federation/model/instance.ts#L154-L155

Added lines #L154 - L155 were not covered by tests

/**
* Software name
* @returns Software name
*/
getSoftwareName(): string {
return this.softwareName;
}

/**
* Software version
* @returns Software version
*/
getSoftwareVersion(): string {
return this.softwareVersion;
}

/**
* Set instance software version
* @param version Software version
*/
setSoftwareVersion(version: string) {
this.softwareVersion = version;
this.setUpdated();
}

Check warning on line 180 in pkg/federation/model/instance.ts

View check run for this annotation

Codecov / codecov/patch

pkg/federation/model/instance.ts#L178-L180

Added lines #L178 - L180 were not covered by tests

/**
* Instance admin name
* @returns Instance admin name
*/
getAdminName(): string {
return this.adminName;
}

Check warning on line 188 in pkg/federation/model/instance.ts

View check run for this annotation

Codecov / codecov/patch

pkg/federation/model/instance.ts#L187-L188

Added lines #L187 - L188 were not covered by tests

/**
* Set instance admin name
* @param name Admin name
*/
setAdminName(name: string) {
this.adminName = name;
this.setUpdated();
}

Check warning on line 197 in pkg/federation/model/instance.ts

View check run for this annotation

Codecov / codecov/patch

pkg/federation/model/instance.ts#L195-L197

Added lines #L195 - L197 were not covered by tests

/**
* Instance admin contact
* @returns Instance admin contact
*/
getAdminContact(): string {
return this.adminContact;
}

Check warning on line 205 in pkg/federation/model/instance.ts

View check run for this annotation

Codecov / codecov/patch

pkg/federation/model/instance.ts#L204-L205

Added lines #L204 - L205 were not covered by tests

/**
* Set instance admin contact
* @param contact Admin contact
*/
setAdminContact(contact: string) {
this.adminContact = contact;
this.setUpdated();
}

Check warning on line 214 in pkg/federation/model/instance.ts

View check run for this annotation

Codecov / codecov/patch

pkg/federation/model/instance.ts#L212-L214

Added lines #L212 - L214 were not covered by tests

isBlocked(): boolean {
return this.state === 'blocked';
}

Check warning on line 218 in pkg/federation/model/instance.ts

View check run for this annotation

Codecov / codecov/patch

pkg/federation/model/instance.ts#L217-L218

Added lines #L217 - L218 were not covered by tests

/**
* Set instance state
*/
setInstanceState(state: InstanceState) {
this.state = state;
this.setUpdated();
}

Check warning on line 226 in pkg/federation/model/instance.ts

View check run for this annotation

Codecov / codecov/patch

pkg/federation/model/instance.ts#L224-L226

Added lines #L224 - L226 were not covered by tests

isSilenced(): boolean {
return this.silenced === 'silenced';
}

Check warning on line 230 in pkg/federation/model/instance.ts

View check run for this annotation

Codecov / codecov/patch

pkg/federation/model/instance.ts#L229-L230

Added lines #L229 - L230 were not covered by tests

/**
* Set instance silenced state
*/
setSilencedState(silenced: InstanceSilenced) {
this.silenced = silenced;
this.setUpdated();
}

Check warning on line 238 in pkg/federation/model/instance.ts

View check run for this annotation

Codecov / codecov/patch

pkg/federation/model/instance.ts#L236-L238

Added lines #L236 - L238 were not covered by tests

isDeliverStopped(): boolean {
return this.deliverState === 'stopped';
}

Check warning on line 242 in pkg/federation/model/instance.ts

View check run for this annotation

Codecov / codecov/patch

pkg/federation/model/instance.ts#L241-L242

Added lines #L241 - L242 were not covered by tests

/**
* Set instance deliver state
*/
setDeliverState(state: InstanceDeliverState) {
this.deliverState = state;
this.setUpdated();
}

Check warning on line 250 in pkg/federation/model/instance.ts

View check run for this annotation

Codecov / codecov/patch

pkg/federation/model/instance.ts#L248-L250

Added lines #L248 - L250 were not covered by tests

isLocalInstance(): boolean {
return this.isLocal;
}

Check warning on line 254 in pkg/federation/model/instance.ts

View check run for this annotation

Codecov / codecov/patch

pkg/federation/model/instance.ts#L253-L254

Added lines #L253 - L254 were not covered by tests

/**
* Instance first contact date
* @returns Instance first contact date
*/
getFirstContact(): Date {
return this.firstContact;
}

Check warning on line 262 in pkg/federation/model/instance.ts

View check run for this annotation

Codecov / codecov/patch

pkg/federation/model/instance.ts#L261-L262

Added lines #L261 - L262 were not covered by tests

/**
* Instance data updated date
* @returns Instance data updated date
*/
getUpdated(): Option.Option<Date> {
return this.updated;
}

Check warning on line 270 in pkg/federation/model/instance.ts

View check run for this annotation

Codecov / codecov/patch

pkg/federation/model/instance.ts#L269-L270

Added lines #L269 - L270 were not covered by tests

private setUpdated() {
this.updated = Option.some(new Date());
}

Check warning on line 274 in pkg/federation/model/instance.ts

View check run for this annotation

Codecov / codecov/patch

pkg/federation/model/instance.ts#L273-L274

Added lines #L273 - L274 were not covered by tests

private constructor(arg: CreateInstanceArgs) {
this.id = arg.id;
this.name = arg.name;
this.description = arg.description;
this.fqdn = arg.fqdn.host;
this.softwareName = arg.softwareName;
this.softwareVersion = arg.softwareVersion;
this.adminName = arg.adminName;
this.adminContact = arg.adminContact;
this.isLocal = arg.isLocal;
this.firstContact = arg.firstContact;
this.state = arg.state;
this.silenced = arg.silenced;
this.deliverState = arg.deliverState;
this.updated = arg.updated;
}

public static new(
arg: Omit<
CreateInstanceArgs,
'state' | 'silenced' | 'deliverState' | 'updated'
>,
): Instance {
if (arg.softwareName === '') arg.softwareName = 'Unknown';
if (arg.softwareVersion === '') arg.softwareVersion = 'Unknown';

return new Instance({
...arg,
state: 'normal',
silenced: 'normal',
deliverState: 'normal',
updated: Option.none(),
});
}
}