Skip to content

Commit

Permalink
Merge pull request #38 from acelaya-forks/feature/dic
Browse files Browse the repository at this point in the history
Add a service container
  • Loading branch information
acelaya authored May 12, 2024
2 parents 2755cf3 + 8d4071e commit 2d6ffcb
Show file tree
Hide file tree
Showing 10 changed files with 56 additions and 16 deletions.
20 changes: 20 additions & 0 deletions app/api/apiClientBuilder.server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { ShlinkApiClient } from '@shlinkio/shlink-js-sdk';
import { NodeHttpClient } from '@shlinkio/shlink-js-sdk/node';
import type { Server } from '../entities/Server';

const apiClients = new Map<string, ShlinkApiClient>();

export const apiClientBuilder = (server: Server) => {
const key = `${server.apiKey}_${server.baseUrl}`;
const existingApiClient = apiClients.get(key);

if (existingApiClient) {
return existingApiClient;
}

const apiClient = new ShlinkApiClient(new NodeHttpClient(), server);
apiClients.set(key, apiClient);
return apiClient;
};

export type ApiClientBuilder = typeof apiClientBuilder;
18 changes: 18 additions & 0 deletions app/container/container.server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import Bottle from 'bottlejs';
import { apiClientBuilder } from '../api/apiClientBuilder.server';
import { appDataSource } from '../db/data-source.server';
import { ServersService } from '../servers/ServersService.server';
import { SettingsService } from '../settings/SettingsService.server';
import { TagsService } from '../tags/TagsService.server';

const bottle = new Bottle();

bottle.serviceFactory('em', () => appDataSource.manager);

bottle.service(TagsService.name, TagsService, 'em');
bottle.service(ServersService.name, ServersService, 'em');
bottle.service(SettingsService.name, SettingsService, 'em');

bottle.constant('apiClientBuilder', apiClientBuilder);

export const { container: serverContainer } = bottle;
5 changes: 3 additions & 2 deletions app/routes/server.$serverId.$.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@ import type { Settings } from '@shlinkio/shlink-web-component';
import type { ReactNode } from 'react';
import { useEffect, useMemo, useState } from 'react';
import { ShlinkApiProxyClient } from '../api/ShlinkApiProxyClient.client';
import { serverContainer } from '../container/container.server';
import { SettingsService } from '../settings/SettingsService.server';
import { TagsService } from '../tags/TagsService.server';
import { TagsStorage } from '../tags/TagsStorage.client';

export async function loader(
{ params }: LoaderFunctionArgs,
tagsService = new TagsService(),
settingsService = new SettingsService(),
tagsService: TagsService = serverContainer[TagsService.name],
settingsService: SettingsService = serverContainer[SettingsService.name],
): Promise<{ settings: Settings; tagColors: Record<string, string> }> {
const { serverId: serverPublicId } = params;
const userId = 1; // FIXME Get from session
Expand Down
10 changes: 5 additions & 5 deletions app/routes/server.$serverId.shlink-api.$method.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import type { ActionFunctionArgs } from '@remix-run/node';
import { json } from '@remix-run/node';
import { ShlinkApiClient } from '@shlinkio/shlink-js-sdk';
import { NodeHttpClient } from '@shlinkio/shlink-js-sdk/node';
import type { Server } from '../entities/Server';
import type { ShlinkApiClient } from '@shlinkio/shlink-js-sdk';
import type { ApiClientBuilder } from '../api/apiClientBuilder.server';
import { serverContainer } from '../container/container.server';
import { ServersService } from '../servers/ServersService.server';

type Callback = (...args: unknown[]) => unknown;
Expand All @@ -21,8 +21,8 @@ function argsAreValidForAction(args: any[], callback: Callback): args is Paramet

export async function action(
{ params, request }: ActionFunctionArgs,
serversService = new ServersService(),
createApiClient = (server: Server) => new ShlinkApiClient(new NodeHttpClient(), server),
serversService: ServersService = serverContainer[ServersService.name],
createApiClient: ApiClientBuilder = serverContainer.apiClientBuilder,
) {
try {
const { method, serverId = '' } = params;
Expand Down
6 changes: 5 additions & 1 deletion app/routes/server.$serverId.tags.colors.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import type { ActionFunctionArgs } from '@remix-run/node';
import { serverContainer } from '../container/container.server';
import { TagsService } from '../tags/TagsService.server';

export async function action({ params, request }: ActionFunctionArgs, tagsService = new TagsService()) {
export async function action(
{ params, request }: ActionFunctionArgs,
tagsService: TagsService = serverContainer[TagsService.name],
) {
const { serverId: serverPublicId } = params;
// TODO Get UserID from session
const userId = 1;
Expand Down
3 changes: 1 addition & 2 deletions app/servers/ServersService.server.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import type { EntityManager } from 'typeorm';
import { appDataSource } from '../db/data-source.server';
import type { Server } from '../entities/Server';
import { ServerEntity } from '../entities/Server';

export class ServersService {
constructor(private readonly em: EntityManager = appDataSource.manager) {}
constructor(private readonly em: EntityManager) {}

public async getByPublicId(publicId: string): Promise<Server> {
const server = await this.em.findOneBy(ServerEntity, { publicId });
Expand Down
4 changes: 1 addition & 3 deletions app/settings/SettingsService.server.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import type { Settings } from '@shlinkio/shlink-web-component';
import type { EntityManager } from 'typeorm';
import { appDataSource } from '../db/data-source.server';
import { SettingsEntity } from '../entities/Settings';
import { UserEntity } from '../entities/User';

export class SettingsService {
constructor(private readonly em: EntityManager = appDataSource.manager) {
}
constructor(private readonly em: EntityManager) {}

async userSettings(userId: number): Promise<Settings> {
const user = await this.em.findOneBy(UserEntity, { id: userId });
Expand Down
4 changes: 1 addition & 3 deletions app/tags/TagsService.server.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import type { EntityManager } from 'typeorm';
import { appDataSource } from '../db/data-source.server';
import type { Server } from '../entities/Server';
import { ServerEntity } from '../entities/Server';
import { TagEntity } from '../entities/Tag';
Expand All @@ -21,8 +20,7 @@ type ServerAndUserResult = {
};

export class TagsService {
constructor(private readonly em: EntityManager = appDataSource.manager) {
}
constructor(private readonly em: EntityManager) {}

async tagColors(param: FindTagsParam): Promise<Record<string, string>> {
const { server, user } = await this.resolveServerAndUser(param);
Expand Down
1 change: 1 addition & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"@shlinkio/shlink-js-sdk": "^1.1.0",
"@shlinkio/shlink-web-component": "^0.6.2",
"bootstrap": "5.2.3",
"bottlejs": "^2.0.1",
"express": "^4.19.2",
"isbot": "^5.1.6",
"pg": "^8.11.5",
Expand Down

0 comments on commit 2d6ffcb

Please sign in to comment.