Skip to content

Commit f49624b

Browse files
committed
feat(*): add dependency injection utils
1 parent b99844d commit f49624b

30 files changed

Lines changed: 390 additions & 125 deletions

dist/index.js

Lines changed: 3 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/commands/init/command.ts

Lines changed: 0 additions & 15 deletions
This file was deleted.

src/commands/init/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
export * from './command.js';
1+
export * from './init.js';
Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { initConfig } from '../../config.js';
1+
import { Command, Option } from 'commander';
2+
import { CONFIG, initConfig } from '../../config.js';
23
import { TemplatesAccess, UseCaseRunner } from '../../services/index.js';
34
import {
45
hasUserInput,
@@ -7,9 +8,17 @@ import {
78
promptTextInput,
89
} from '../../shared/index.js';
910
import {
11+
inject,
12+
Injector,
1013
isExistingWorkspace,
1114
resolveWorkspacePath,
1215
} from '../../utils/index.js';
16+
import { workspacePathArgument } from '../arguments.js';
17+
18+
const templatesRepository = new Option(
19+
'--templates-repository <templatesRepository>',
20+
'use a template repository'
21+
);
1322

1423
interface InitActionOptions {
1524
templatesRepository: OptionInput;
@@ -37,7 +46,7 @@ async function promptTemplateRepository(
3746
: null;
3847
}
3948

40-
export async function init(
49+
export async function initAction(
4150
workspacePathRaw: string,
4251
options: InitActionOptions
4352
): Promise<void> {
@@ -63,11 +72,19 @@ export async function init(
6372

6473
// init config
6574
const config = initConfig(workspacePath, organization, templatesRepository);
75+
inject(Injector).register(CONFIG, () => config.store);
6676

6777
// copy templates from package/repo to workspace
68-
const templatesAccess = TemplatesAccess.create(config.store);
78+
const templatesAccess = inject(TemplatesAccess);
6979
await templatesAccess.initWorkspace();
7080

71-
const useCaseRunner = UseCaseRunner.create(templatesAccess);
81+
const useCaseRunner = inject(UseCaseRunner);
7282
await useCaseRunner.run('init');
7383
}
84+
85+
export const init = new Command()
86+
.name('init')
87+
.description('initialize the workspace')
88+
.addArgument(workspacePathArgument)
89+
.addOption(templatesRepository)
90+
.action(initAction);

src/commands/run/run.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import { Command, Option } from 'commander';
2-
import { loadWorkspaceConfig } from '../../config.js';
3-
import { TemplatesAccess, UseCaseRunner } from '../../services/index.js';
2+
import { CONFIG, loadWorkspaceConfig } from '../../config.js';
3+
import { UseCaseRunner } from '../../services/index.js';
44
import { UseCasesRepository } from '../../services/use-cases.repository.js';
55
import { promptEntitySelection } from '../../shared/entity-selection-prompt.js';
66
import { OptionInput } from '../../shared/index.js';
7+
import { inject, Injector } from '../../utils/index.js';
78
import { defaultWorkspacePathArgument } from '../arguments.js';
89

910
const useCaseOption = new Option(
@@ -22,9 +23,10 @@ export async function runAction(
2223
options: RunActionOptions
2324
) {
2425
const config = await loadWorkspaceConfig(workspacePathRaw, options.debug);
25-
const templatesAccess = TemplatesAccess.create(config);
26-
const useCaseRunner = UseCaseRunner.create(templatesAccess);
27-
const useCaseRepository = UseCasesRepository.create(templatesAccess);
26+
inject(Injector).register(CONFIG, () => config);
27+
28+
const useCaseRunner = inject(UseCaseRunner);
29+
const useCaseRepository = inject(UseCasesRepository);
2830

2931
const useCases = await useCaseRepository.loadUseCases('INITIAL');
3032
const useCase = await promptEntitySelection(

src/commands/sync/sync.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,17 @@
11
import { Command } from 'commander';
2-
import { loadWorkspaceConfig } from '../../config.js';
2+
import { CONFIG, loadWorkspaceConfig } from '../../config.js';
33
import { TemplatesAccess, UseCaseRunner } from '../../services/index.js';
4+
import { inject, Injector } from '../../utils/index.js';
45
import { defaultWorkspacePathArgument } from '../arguments.js';
56

67
async function syncAction(workspacePathRaw: string): Promise<void> {
78
const config = await loadWorkspaceConfig(workspacePathRaw);
8-
const templatesAccess = TemplatesAccess.create(config);
9-
await templatesAccess.syncTemplates();
9+
inject(Injector).register(CONFIG, () => config);
10+
11+
const templatesAccess = inject(TemplatesAccess);
12+
const useCaseRunner = inject(UseCaseRunner);
1013

11-
const useCaseRunner = UseCaseRunner.create(templatesAccess);
14+
await templatesAccess.syncTemplates();
1215
await useCaseRunner.run('sync');
1316
}
1417

src/config.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import Conf from 'conf';
22
import {
33
getWorkspacePathIdentifier,
4+
inject,
5+
InjectionToken,
46
isExistingWorkspace,
5-
logger,
7+
Logger,
68
resolveWorkspacePath,
79
} from './utils/index.js';
810

@@ -12,6 +14,8 @@ export interface Config {
1214
templatesRepository: string | null;
1315
}
1416

17+
export const CONFIG = new InjectionToken<Config>('Config');
18+
1519
export type WorkspaceConfig = Conf<Config>;
1620

1721
const schema = {
@@ -63,7 +67,7 @@ export async function loadWorkspaceConfig(
6367
): Promise<Config> {
6468
const workspacePath = workspacePathRaw.trim();
6569
if (debug) {
66-
logger.log('Running within non-workspace directory...');
70+
inject(Logger).log('Running within non-workspace directory...');
6771
return loadBlankConfig(workspacePath);
6872
}
6973

src/index.ts

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,36 @@
22
import { Command } from 'commander';
33
import packageJson from '../package.json';
44
import { init, run, sync } from './commands/index.js';
5-
import { logger } from './utils/index.js';
5+
import {
6+
TemplatesAccess,
7+
UseCaseRunner,
8+
UseCasesRepository,
9+
} from './services/index.js';
10+
import { RepositoriesRepository } from './services/repositories.repository.js';
11+
import { ScriptExecutor } from './services/script-executor.js';
12+
import { ServersRepository } from './services/servers.repository.js';
13+
import { ContextCreator } from './services/use-cases/context-creator.js';
14+
import { DefaultInjector, inject, Logger } from './utils/index.js';
615

716
const handleSigTerm = () => process.exit(0);
817
process.on('SIGINT', handleSigTerm);
918
process.on('SIGTERM', handleSigTerm);
1019
process.on('uncaughtException', err => {
11-
logger.error(err.message);
20+
inject(Logger).error(err.message);
1221
process.exit(1);
1322
});
1423

24+
DefaultInjector.getInstance([
25+
[Logger, { factory: () => new Logger() }],
26+
[ScriptExecutor, { factory: () => new ScriptExecutor() }],
27+
[TemplatesAccess, { factory: () => new TemplatesAccess() }],
28+
[RepositoriesRepository, { factory: () => new RepositoriesRepository() }],
29+
[ServersRepository, { factory: () => new ServersRepository() }],
30+
[UseCasesRepository, { factory: () => new UseCasesRepository() }],
31+
[ContextCreator, { factory: () => new ContextCreator() }],
32+
[UseCaseRunner, { factory: () => new UseCaseRunner() }],
33+
]);
34+
1535
new Command()
1636
.name(packageJson.name)
1737
.description(packageJson.description)
@@ -21,7 +41,7 @@ new Command()
2141
.addCommand(sync)
2242
.parseAsync()
2343
.catch(err => {
24-
logger.error(err.message);
44+
inject(Logger).error(err.message);
2545
process.exit(1);
2646
})
27-
.finally(() => logger.success('Finished execution.'));
47+
.finally(() => inject(Logger).success('Finished execution.'));

src/services/access/templates-access.ts

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { join } from 'node:path';
2-
import { Config } from '../../config.js';
3-
import { copyDirectory, gitUpdate, logger } from '../../utils/index.js';
2+
import { CONFIG } from '../../config.js';
3+
import { copyDirectory, gitUpdate, inject, Logger } from '../../utils/index.js';
44
import {
55
DIR_CONFIG,
66
DIR_DEVELOPMENT,
@@ -19,11 +19,8 @@ enum Location {
1919
}
2020

2121
export class TemplatesAccess {
22-
static create(config: Config): TemplatesAccess {
23-
return new TemplatesAccess(config);
24-
}
25-
26-
constructor(private readonly config: Config) {}
22+
logger = inject(Logger);
23+
config = inject(CONFIG);
2724

2825
getPackageTemplatesDir(): string {
2926
return join(this.#getBaseDir(Location.PACKAGE), DIR_TEMPLATES);
@@ -92,7 +89,7 @@ export class TemplatesAccess {
9289
async syncTemplates(): Promise<void> {
9390
// always sync the templates from the package
9491
const templatesDirPackage = this.getPackageTemplatesDir();
95-
logger.log(`Syncing templates from ${templatesDirPackage}...`);
92+
this.logger.log(`Syncing templates from ${templatesDirPackage}...`);
9693
await copyDirectory(templatesDirPackage, this.getWorkspacePath());
9794
// sync the templates from the repository
9895
await this.syncRepositoryTemplates();
@@ -103,7 +100,7 @@ export class TemplatesAccess {
103100
const templatesRepository = this.getTemplatesRepository();
104101
if (templatesRepository) {
105102
const url = this.createRepositoryUrl(templatesRepository);
106-
logger.log(`Syncing templates from repository ${url}...`);
103+
this.logger.log(`Syncing templates from repository ${url}...`);
107104

108105
await gitUpdate(url, this.getWorkspacePath(), this.getGitTemplatesDir());
109106
await copyDirectory(this.getGitTemplatesDir(), this.getConfigDir(), [

src/services/repositories.repository.test.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import { vol } from 'memfs';
22
import { temporaryDirectory } from 'tempy';
33
import { beforeEach, describe, expect, it, vi } from 'vitest';
4-
import { initConfig } from '../config.js';
4+
import { CONFIG, initConfig } from '../config.js';
5+
import { DefaultInjector, inject, Logger } from '../utils/index.js';
56
import { TemplatesAccess } from './access/templates-access.js';
67
import { RepositoriesRepository } from './repositories.repository.js';
78

@@ -15,7 +16,14 @@ describe('RepositoriesRepository', () => {
1516
beforeEach(() => {
1617
const config = initConfig(path, 'acme', null).store;
1718

18-
sut = RepositoriesRepository.create(TemplatesAccess.create(config));
19+
DefaultInjector.getInstance([
20+
[CONFIG, { factory: () => config }],
21+
[Logger, { factory: () => new Logger() }],
22+
[TemplatesAccess, { factory: () => new TemplatesAccess() }],
23+
[RepositoriesRepository, { factory: () => new RepositoriesRepository() }],
24+
]);
25+
26+
sut = inject(RepositoriesRepository);
1927
});
2028

2129
it('should load repositories; empty list', async () => {

0 commit comments

Comments
 (0)