@opra/angular
Version:
Opra internationalization package
156 lines (147 loc) • 4.43 kB
text/typescript
/* eslint-disable import-x/extensions */
import { HttpClient } from '@angular/common/http';
import {
type ModuleWithProviders,
NgModule,
type Provider,
Type,
} from '@angular/core';
import { kClient } from '@opra/client';
import { OpraAngularClient } from './angular-client';
import { OPRA_CLIENT_MODULE_OPTIONS } from './constants';
import type {
OpraClientModuleAsyncOptions,
OpraClientModuleOptions,
} from './interfaces/module-options.interface';
({})
export class OpraClientModule {
public static registerClient(
options: OpraClientModuleOptions,
): ModuleWithProviders<OpraClientModule> {
const CLIENT_TOKEN = options.token || OpraAngularClient;
return {
ngModule: OpraClientModule,
providers: [
{
provide: CLIENT_TOKEN,
deps: [HttpClient],
useFactory: (httpClient: HttpClient) =>
new OpraAngularClient(httpClient, options.serviceUrl, options),
},
],
};
}
public static registerService<T>(
serviceClass: Type<T>,
options: OpraClientModuleOptions,
): ModuleWithProviders<OpraClientModule> {
const SERVICE_TOKEN = options.token || serviceClass;
return {
ngModule: OpraClientModule,
providers: [
{
provide: SERVICE_TOKEN,
deps: [HttpClient],
useFactory: (httpClient: HttpClient) => {
const opraAngularClient = new OpraAngularClient(
httpClient,
options.serviceUrl,
options,
);
const service = new serviceClass(opraAngularClient);
service[kClient] = opraAngularClient;
return service;
},
},
],
};
}
public static registerClientAsync(
options: OpraClientModuleAsyncOptions,
): ModuleWithProviders<OpraClientModule> {
const CLIENT_TOKEN = options.token || OpraAngularClient;
const asyncProviders = this._createAsyncProviders(options);
return {
ngModule: OpraClientModule,
providers: [
...asyncProviders,
{
provide: CLIENT_TOKEN,
deps: [HttpClient, OPRA_CLIENT_MODULE_OPTIONS],
useFactory: (httpClient: HttpClient, opts: OpraClientModuleOptions) =>
new OpraAngularClient(httpClient, opts.serviceUrl, opts),
},
],
};
}
public static registerServiceAsync<T>(
serviceClass: Type<T>,
options: OpraClientModuleAsyncOptions,
): ModuleWithProviders<OpraClientModule> {
const SERVICE_TOKEN = options.token || serviceClass;
const asyncProviders = this._createAsyncProviders(options);
return {
ngModule: OpraClientModule,
providers: [
...asyncProviders,
{
provide: SERVICE_TOKEN,
deps: [HttpClient, OPRA_CLIENT_MODULE_OPTIONS],
useFactory: (
httpClient: HttpClient,
opts: OpraClientModuleOptions,
) => {
const opraAngularClient = new OpraAngularClient(
httpClient,
opts.serviceUrl,
opts,
);
const service = new serviceClass(opraAngularClient);
service[kClient] = opraAngularClient;
return service;
},
},
],
};
}
private static _createAsyncProviders(
options: OpraClientModuleAsyncOptions,
): Provider[] {
if (options.useExisting || options.useFactory)
return [this._createAsyncOptionsProvider(options)];
if (options.useClass) {
return [
this._createAsyncOptionsProvider(options),
{
provide: options.useClass,
useClass: options.useClass,
},
];
}
throw new Error(
'Invalid configuration. Must provide useFactory, useClass or useExisting',
);
}
private static _createAsyncOptionsProvider(
options: OpraClientModuleAsyncOptions,
): Provider {
if (options.useFactory) {
return {
provide: OPRA_CLIENT_MODULE_OPTIONS,
useFactory: options.useFactory,
deps: options.deps || [],
};
}
const useClass = options.useClass || options.useExisting;
if (useClass) {
return {
provide: OPRA_CLIENT_MODULE_OPTIONS,
useFactory: o => o,
deps: [useClass],
};
}
throw new Error(
'Invalid configuration. Must provide useFactory, useClass or useExisting',
);
}
}