Compare commits
10 Commits
v0.3.0
...
v0.1.0-alp
Author | SHA1 | Date | |
---|---|---|---|
ab07e03c0f | |||
8bb153fe54 | |||
![]() |
794c1e07c3 | ||
1a67d3f4e3 | |||
042d918d00 | |||
06ae6737fd | |||
81873f3689 | |||
4aa12321e8 | |||
26b35d1e5b | |||
78564b9a76 |
47
CHANGELOG.md
47
CHANGELOG.md
@@ -9,56 +9,25 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
|
- feat: Add new `IdentifierRequiredError` class for missing identifiers.
|
||||||
### Deprecated
|
- feat: Add the option to use the decorators without passing the identifier: In this case, the identifier will be the class name (register) or the property name (inject).
|
||||||
|
|
||||||
|
|
||||||
### Removed
|
|
||||||
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
|
|
||||||
|
|
||||||
### Security
|
|
||||||
|
|
||||||
## [0.3.0]
|
|
||||||
|
|
||||||
### Added
|
|
||||||
|
|
||||||
- refactor: consolidate registration decorators
|
|
||||||
Introduced Register decorator to handle class and instance registration in the DI container.
|
|
||||||
Deprecated RegisterInstance in favor of Register, which now internally handles instance registration.
|
|
||||||
Added support for marking dependencies as deprecated with a warning logged upon first resolution.
|
|
||||||
Updated documentation with examples and notes on deprecation.
|
|
||||||
- tests: add mode parameter to RegisterInstanceDecorator
|
|
||||||
Introduced a mode parameter to the test_RegisterInstanceDecorator function allowing 'instance' or 'standalone' modes.
|
|
||||||
Updated test cases to utilize the new mode parameter when registering an instance.
|
|
||||||
Disabled specific ESLint rule in Decorators.test.ts for deprecation warnings.
|
|
||||||
Added an additional test call to test_RegisterInstanceDecorator with 'instance' mode.
|
|
||||||
- refactor: add region tags for overloads in Register.ts
|
|
||||||
|
|
||||||
## [0.2.0]
|
|
||||||
|
|
||||||
### Added
|
|
||||||
|
|
||||||
- Add pre release building to release workflow on dev/* branches an version changes.
|
- Add pre release building to release workflow on dev/* branches an version changes.
|
||||||
- feat: Introduced a new CLI command `tsinjex-generate` to automate the generation of import statements for registered dependencies.
|
|
||||||
The command scans `.ts` files for `@Register` and `@RegisterInstance` decorators and generates an `auto-imports.ts` file.
|
|
||||||
This ensures that all registered dependencies are automatically included without requiring manual imports.
|
|
||||||
The CLI can be executed via `npx tsinjex-generate` or added as a script in `package.json` for easier integration.
|
|
||||||
|
|
||||||
|
|
||||||
### Deprecated
|
### Deprecated
|
||||||
|
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
|
|
||||||
|
- feat!: Disable `experimentalDecorators` and `emitDecoratorMetadata` in the `tsconfig.json` file to reflect the change to the stable decorators api.
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
|
- feat!: Update `Register`, `RegisterInstance` and `Inject` decorators to reflect the change to the stable decorators api.
|
||||||
|
- feat!: Update `Inject` Decorator typing to reflect the correct property type.
|
||||||
|
|
||||||
### Security
|
### Security
|
||||||
|
|
||||||
|
|
||||||
## [0.0.14]
|
## [0.0.14]
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
@@ -90,6 +59,4 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
---
|
---
|
||||||
|
|
||||||
[unreleased]: https://github.com/PxaMMaxP/TSinjex/compare/0.0.14...HEAD
|
[unreleased]: https://github.com/PxaMMaxP/TSinjex/compare/0.0.14...HEAD
|
||||||
[0.0.14]: https://github.com/PxaMMaxP/TSinjex/compare/0.0.13...v0.0.14
|
[0.0.14]: https://github.com/PxaMMaxP/TSinjex/compare/0.0.13...v0.0.14
|
||||||
[0.2.00]: https://github.com/PxaMMaxP/TSinjex/compare/0.0.14...v0.2.0
|
|
||||||
[0.3.00]: https://github.com/PxaMMaxP/TSinjex/compare/0.2.0...v0.3.0
|
|
@@ -1,111 +0,0 @@
|
|||||||
#!/usr/bin/env node
|
|
||||||
|
|
||||||
const fs = require('fs');
|
|
||||||
const path = require('path');
|
|
||||||
const yargs = require('yargs');
|
|
||||||
|
|
||||||
// CLI argument parsing
|
|
||||||
const argv = yargs
|
|
||||||
.option('src', {
|
|
||||||
alias: 's',
|
|
||||||
type: 'string',
|
|
||||||
description: 'Directory to search for files',
|
|
||||||
default: 'src',
|
|
||||||
})
|
|
||||||
.option('output', {
|
|
||||||
alias: 'o',
|
|
||||||
type: 'string',
|
|
||||||
description: 'Path to the output file',
|
|
||||||
default: 'src/auto-imports.ts',
|
|
||||||
})
|
|
||||||
.option('pattern', {
|
|
||||||
alias: 'p',
|
|
||||||
type: 'string',
|
|
||||||
description: 'File pattern to search for (e.g., .ts, .js)',
|
|
||||||
default: '.ts',
|
|
||||||
})
|
|
||||||
.help()
|
|
||||||
.argv;
|
|
||||||
|
|
||||||
// Fixed RegEx patterns for decorator detection
|
|
||||||
const SEARCH_PATTERNS = [
|
|
||||||
/^@Register(?:<(.+)?>)?\(\s*["']{1}(.+)?["']{1}\s*,?\s*(true|false)?\s*\)/m, // Matches @Register(...)
|
|
||||||
/^@RegisterInstance(?:<(.+)?>)?\(\s*["']{1}(.+)?["']{1}\s*,?\s*(.+)?\s*\)/m, // Matches @RegisterInstance(...)
|
|
||||||
];
|
|
||||||
|
|
||||||
const FILE_PATTERN = argv.pattern.startsWith('.') ? argv.pattern : `.${argv.pattern}`; // Ensure the pattern starts with a dot
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Recursively searches for all files in a directory matching the specified pattern.
|
|
||||||
* @param {string} dirPath - The directory to search.
|
|
||||||
* @returns {string[]} - List of matching files.
|
|
||||||
*/
|
|
||||||
function getAllFiles(dirPath) {
|
|
||||||
let files = fs.readdirSync(dirPath);
|
|
||||||
let arrayOfFiles = [];
|
|
||||||
|
|
||||||
files.forEach((file) => {
|
|
||||||
const fullPath = path.join(dirPath, file);
|
|
||||||
if (fs.statSync(fullPath).isDirectory()) {
|
|
||||||
arrayOfFiles = arrayOfFiles.concat(getAllFiles(fullPath));
|
|
||||||
} else if (file.endsWith(FILE_PATTERN)) {
|
|
||||||
arrayOfFiles.push(fullPath);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return arrayOfFiles;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Filters files that contain at least one of the specified regex patterns.
|
|
||||||
* @param {string[]} files - List of files to check.
|
|
||||||
* @returns {string[]} - Files that contain at least one of the specified patterns.
|
|
||||||
*/
|
|
||||||
function findFilesWithPattern(files) {
|
|
||||||
return files.filter((file) => {
|
|
||||||
const content = fs.readFileSync(file, 'utf8');
|
|
||||||
return SEARCH_PATTERNS.some((pattern) => pattern.test(content));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generates an import file containing imports for all found files.
|
|
||||||
* @param {string[]} files - List of relevant files.
|
|
||||||
* @returns {string} - Generated import code.
|
|
||||||
*/
|
|
||||||
function generateImports(files) {
|
|
||||||
return files.map((file) => `import '${file.replace(/\\/g, '/')}';`).join('\n') + '\n';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Main function that executes the script.
|
|
||||||
*/
|
|
||||||
function main() {
|
|
||||||
try {
|
|
||||||
const srcDir = path.resolve(process.cwd(), argv.src);
|
|
||||||
const outputFile = path.resolve(process.cwd(), argv.output);
|
|
||||||
|
|
||||||
if (!fs.existsSync(srcDir)) {
|
|
||||||
console.error(`❌ Error: The directory '${srcDir}' does not exist.`);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
const allFiles = getAllFiles(srcDir);
|
|
||||||
const filesWithPattern = findFilesWithPattern(allFiles);
|
|
||||||
|
|
||||||
if (filesWithPattern.length === 0) {
|
|
||||||
console.log(`ℹ️ No ${FILE_PATTERN} files found matching the specified decorator patterns.`);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const importContent = generateImports(filesWithPattern);
|
|
||||||
fs.writeFileSync(outputFile, importContent);
|
|
||||||
|
|
||||||
console.log(`✅ Imports successfully generated: ${outputFile}`);
|
|
||||||
} catch (error) {
|
|
||||||
console.error('❌ An error occurred:', error.message);
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
main();
|
|
9
package-lock.json
generated
9
package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "ts-injex",
|
"name": "ts-injex",
|
||||||
"version": "0.0.9",
|
"version": "0.1.0-alpha",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "ts-injex",
|
"name": "ts-injex",
|
||||||
"version": "0.0.9",
|
"version": "0.1.0-alpha",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"eslint-plugin-prettier": "^5.2.1",
|
"eslint-plugin-prettier": "^5.2.1",
|
||||||
@@ -5958,6 +5958,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
|
||||||
"integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="
|
"integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="
|
||||||
},
|
},
|
||||||
|
"node_modules/reflect-metadata": {
|
||||||
|
"version": "0.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz",
|
||||||
|
"integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q=="
|
||||||
|
},
|
||||||
"node_modules/regexp.prototype.flags": {
|
"node_modules/regexp.prototype.flags": {
|
||||||
"version": "1.5.2",
|
"version": "1.5.2",
|
||||||
"resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz",
|
"resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz",
|
||||||
|
@@ -1,13 +1,10 @@
|
|||||||
{
|
{
|
||||||
"name": "ts-injex",
|
"name": "ts-injex",
|
||||||
"version": "0.3.0",
|
"version": "0.1.0-alpha",
|
||||||
"description": "Simple boilerplate code free dependency injection system for TypeScript.",
|
"description": "Simple boilerplate code free dependency injection system for TypeScript.",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "./dist/index.js",
|
"main": "./dist/index.js",
|
||||||
"types": "./dist/index.d.ts",
|
"types": "./dist/index.d.ts",
|
||||||
"bin": {
|
|
||||||
"tsinjex-generate": "./bin/generate-imports.cjs"
|
|
||||||
},
|
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"prepare": "npm run build",
|
"prepare": "npm run build",
|
||||||
"build": "npm run build:tsc",
|
"build": "npm run build:tsc",
|
||||||
@@ -63,4 +60,4 @@
|
|||||||
"LICENSE",
|
"LICENSE",
|
||||||
"package.json"
|
"package.json"
|
||||||
]
|
]
|
||||||
}
|
}
|
@@ -67,6 +67,29 @@ export function test_InjectDecorator(
|
|||||||
expect(instance.getDependency().value).toBe('test-value-init');
|
expect(instance.getDependency().value).toBe('test-value-init');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should inject dependency and run initializer without identifier', () => {
|
||||||
|
container.register('MockDependencyIdentifier', {
|
||||||
|
value: 'test-value',
|
||||||
|
});
|
||||||
|
|
||||||
|
class TestClass {
|
||||||
|
@Inject(undefined, (x: string) => {
|
||||||
|
(x as unknown as { value: string }).value =
|
||||||
|
'test-value-init';
|
||||||
|
|
||||||
|
return x;
|
||||||
|
})
|
||||||
|
MockDependencyIdentifier!: any;
|
||||||
|
|
||||||
|
public getDependency() {
|
||||||
|
return this.MockDependencyIdentifier;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const instance = new TestClass();
|
||||||
|
expect(instance.getDependency().value).toBe('test-value-init');
|
||||||
|
});
|
||||||
|
|
||||||
it('should throw an error when necessary is true and the initializer throws an error', () => {
|
it('should throw an error when necessary is true and the initializer throws an error', () => {
|
||||||
let _error: Error | undefined = undefined;
|
let _error: Error | undefined = undefined;
|
||||||
|
|
||||||
@@ -78,7 +101,7 @@ export function test_InjectDecorator(
|
|||||||
class TestClass {
|
class TestClass {
|
||||||
@Inject(
|
@Inject(
|
||||||
'InitThrowDependencie',
|
'InitThrowDependencie',
|
||||||
() => {
|
(): any => {
|
||||||
throw new Error('Initializer error');
|
throw new Error('Initializer error');
|
||||||
},
|
},
|
||||||
true,
|
true,
|
||||||
@@ -275,6 +298,19 @@ export function test_RegisterDecorator(
|
|||||||
TestClass,
|
TestClass,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should register a dependency without an identifier', () => {
|
||||||
|
@register()
|
||||||
|
class TestClass {
|
||||||
|
private readonly _dependency!: any;
|
||||||
|
|
||||||
|
public getDependency() {
|
||||||
|
return this._dependency;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(container.resolve('TestClass')).toBe(TestClass);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -282,7 +318,6 @@ export function test_RegisterInstanceDecorator(
|
|||||||
Container: ITSinjex_,
|
Container: ITSinjex_,
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
|
||||||
registerInstance: Function,
|
registerInstance: Function,
|
||||||
mode: 'instance' | 'standalone' = 'standalone',
|
|
||||||
): void {
|
): void {
|
||||||
describe('RegisterInstance Decorator Tests', () => {
|
describe('RegisterInstance Decorator Tests', () => {
|
||||||
let container: ITSinjex;
|
let container: ITSinjex;
|
||||||
@@ -296,10 +331,7 @@ export function test_RegisterInstanceDecorator(
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should register an instance of a dependency', () => {
|
it('should register an instance of a dependency', () => {
|
||||||
@registerInstance(
|
@registerInstance('InstanceIdentifier')
|
||||||
'InstanceIdentifier',
|
|
||||||
mode === 'instance' ? 'instance' : undefined,
|
|
||||||
)
|
|
||||||
class TestClass {
|
class TestClass {
|
||||||
private readonly _dependency!: any;
|
private readonly _dependency!: any;
|
||||||
|
|
||||||
@@ -315,6 +347,23 @@ export function test_RegisterInstanceDecorator(
|
|||||||
).toBe('instance');
|
).toBe('instance');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should register an instance of a dependency with an identifier', () => {
|
||||||
|
@registerInstance()
|
||||||
|
class TestClass {
|
||||||
|
private readonly _dependency!: any;
|
||||||
|
|
||||||
|
public getDependency() {
|
||||||
|
return this._dependency;
|
||||||
|
}
|
||||||
|
|
||||||
|
public mark: string = 'instance';
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(container.resolve<TestClass>('TestClass').mark).toBe(
|
||||||
|
'instance',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
it('should register an instance of a dependency an run the init function', () => {
|
it('should register an instance of a dependency an run the init function', () => {
|
||||||
@registerInstance(
|
@registerInstance(
|
||||||
'InstanceIdentifier',
|
'InstanceIdentifier',
|
||||||
@@ -341,10 +390,7 @@ export function test_RegisterInstanceDecorator(
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should register an instance of a dependency and get it on set', () => {
|
it('should register an instance of a dependency and get it on set', () => {
|
||||||
@registerInstance(
|
@registerInstance('InstanceIdentifier')
|
||||||
'InstanceIdentifier',
|
|
||||||
mode === 'instance' ? 'instance' : undefined,
|
|
||||||
)
|
|
||||||
class TestClass {
|
class TestClass {
|
||||||
private readonly _dependency!: any;
|
private readonly _dependency!: any;
|
||||||
|
|
||||||
|
@@ -1,4 +1,3 @@
|
|||||||
/* eslint-disable deprecation/deprecation */
|
|
||||||
import { TSinjex } from 'src/classes/TSinjex';
|
import { TSinjex } from 'src/classes/TSinjex';
|
||||||
import { Inject } from 'src/decorators/Inject';
|
import { Inject } from 'src/decorators/Inject';
|
||||||
import { Register } from 'src/decorators/Register';
|
import { Register } from 'src/decorators/Register';
|
||||||
@@ -14,5 +13,3 @@ test_InjectDecorator(TSinjex, Inject);
|
|||||||
test_RegisterDecorator(TSinjex, Register);
|
test_RegisterDecorator(TSinjex, Register);
|
||||||
|
|
||||||
test_RegisterInstanceDecorator(TSinjex, RegisterInstance);
|
test_RegisterInstanceDecorator(TSinjex, RegisterInstance);
|
||||||
|
|
||||||
test_RegisterInstanceDecorator(TSinjex, Register, 'instance');
|
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
DependencyResolutionError,
|
DependencyResolutionError,
|
||||||
|
IdentifierRequiredError,
|
||||||
InitializationError,
|
InitializationError,
|
||||||
InjectorError,
|
InjectorError,
|
||||||
NoInstantiationMethodError,
|
NoInstantiationMethodError,
|
||||||
@@ -10,17 +11,17 @@ import { InitDelegate } from '../types/InitDelegate';
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* A decorator to inject a dependency from a DI (Dependency Injection) container into a class property.
|
* A decorator to inject a dependency from a DI (Dependency Injection) container into a class property.
|
||||||
* @template T The type of the dependency to be injected.
|
* @template TargetType The type of the class to inject the dependency into.
|
||||||
* @template U The type of the property to be injected.
|
* @template DependencyType The type of the dependency to be injected.
|
||||||
* @param identifier The identifier used to resolve the class in the DI container.
|
* @template PropertyType The type of the property to be injected.
|
||||||
* @see {@link Identifier} for more information on identifiers.
|
* @param identifier The {@link Identifier|identifier} used to resolve the dependencie in the DI container or the property name if not provided.
|
||||||
* @param init Optional an initializer function to transform the dependency before injection
|
* @param init An optional initializer {@link InitDelegate|function} to transform the dependency before injection
|
||||||
* or true to instantiate the dependency if it has a constructor.
|
* or true to instantiate the dependency if it has a constructor.
|
||||||
* @see {@link InitDelegate} for more information on initializer functions.
|
|
||||||
* @param necessary If true, throws an error if the dependency is not found.
|
* @param necessary If true, throws an error if the dependency is not found.
|
||||||
* @returns The resolved dependency or undefined if the dependency is not necessary
|
* @returns The resolved dependency or undefined if the dependency is not necessary
|
||||||
* and not found, or throws an error if the dependency is necessary and not found.
|
* and not found, or throws an error if the dependency is necessary and not found.
|
||||||
* @throws **Only throws errors if the dependency is necessary.**
|
* @throws **Only throws errors if the dependency is necessary.**
|
||||||
|
* @throws An {@link IdentifierRequiredError} if the identifier is not provided and the class name is not available.
|
||||||
* @throws A {@link DependencyResolutionError} if the dependency is not found.
|
* @throws A {@link DependencyResolutionError} if the dependency is not found.
|
||||||
* @throws A {@link InjectorError} if an error occurs during the injection process.
|
* @throws A {@link InjectorError} if an error occurs during the injection process.
|
||||||
* @throws A {@link NoInstantiationMethodError} if the dependency does not have a constructor.
|
* @throws A {@link NoInstantiationMethodError} if the dependency does not have a constructor.
|
||||||
@@ -40,70 +41,86 @@ import { InitDelegate } from '../types/InitDelegate';
|
|||||||
* }
|
* }
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
export function Inject<T, U>(
|
export function Inject<TargetType, DependencyType, PropertyType>(
|
||||||
identifier: Identifier,
|
identifier?: Identifier,
|
||||||
init?: InitDelegate<T, U> | true,
|
init?: InitDelegate<DependencyType, PropertyType> | true,
|
||||||
necessary = true,
|
necessary = true,
|
||||||
) {
|
) {
|
||||||
return function (target: unknown, propertyKey: string | symbol): void {
|
return function (
|
||||||
|
constructor: undefined,
|
||||||
|
context: ClassFieldDecoratorContext<TargetType> & {
|
||||||
|
name: PropertyType;
|
||||||
|
},
|
||||||
|
): void {
|
||||||
|
const _identifier = identifier ?? context.name;
|
||||||
|
|
||||||
|
if (_identifier == null && necessary === true)
|
||||||
|
throw new IdentifierRequiredError();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function to evaluate the dependency lazily
|
* Function to evaluate the dependency lazily
|
||||||
* to avoid circular dependencies, not found dependencies, etc.
|
* to avoid circular dependencies, not found dependencies, etc.
|
||||||
* @returns The resolved dependency or undefined if the dependency is not found.
|
* @returns The resolved dependency or undefined if the dependency is not found.
|
||||||
*/
|
*/
|
||||||
const resolve = (): T | undefined => {
|
const resolve = (): DependencyType | undefined => {
|
||||||
return TSinjex.getInstance().resolve<T>(identifier, necessary);
|
return TSinjex.getInstance().resolve<DependencyType>(
|
||||||
|
_identifier,
|
||||||
|
necessary,
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
Object.defineProperty(target, propertyKey, {
|
context.addInitializer(function (this: TargetType) {
|
||||||
get() {
|
Object.defineProperty(this, context.name, {
|
||||||
let instance: T | U | undefined;
|
get() {
|
||||||
|
let instance: DependencyType | PropertyType | undefined;
|
||||||
|
|
||||||
const dependency: T | undefined = tryAndCatch(
|
const dependency: DependencyType | undefined = tryAndCatch(
|
||||||
() => resolve(),
|
() => resolve(),
|
||||||
necessary,
|
necessary,
|
||||||
identifier,
|
_identifier,
|
||||||
DependencyResolutionError,
|
DependencyResolutionError,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (dependency != null) {
|
if (dependency != null) {
|
||||||
const initFunction: (() => U) | undefined =
|
const initFunction: (() => PropertyType) | undefined =
|
||||||
typeof init === 'function' && dependency != null
|
typeof init === 'function' && dependency != null
|
||||||
? (): U => init(dependency)
|
? (): PropertyType => init(dependency)
|
||||||
: init === true && hasConstructor(dependency)
|
: init === true && hasConstructor(dependency)
|
||||||
? (): U => new dependency() as U
|
? (): PropertyType =>
|
||||||
: undefined;
|
new dependency() as PropertyType
|
||||||
|
: undefined;
|
||||||
|
|
||||||
if (init == null) instance = dependency;
|
if (init == null) instance = dependency;
|
||||||
else if (initFunction != null)
|
else if (initFunction != null)
|
||||||
instance = tryAndCatch(
|
instance = tryAndCatch(
|
||||||
initFunction,
|
initFunction,
|
||||||
necessary,
|
necessary,
|
||||||
identifier,
|
_identifier,
|
||||||
InitializationError,
|
InitializationError,
|
||||||
);
|
);
|
||||||
else if (necessary)
|
else if (necessary)
|
||||||
throw new NoInstantiationMethodError(identifier);
|
throw new NoInstantiationMethodError(_identifier);
|
||||||
} else if (necessary)
|
} else if (necessary)
|
||||||
throw new DependencyResolutionError(identifier);
|
throw new DependencyResolutionError(_identifier);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace itself with the resolved dependency
|
||||||
|
* for performance reasons.
|
||||||
|
*/
|
||||||
|
Object.defineProperty(this, context.name, {
|
||||||
|
value: instance,
|
||||||
|
writable: false,
|
||||||
|
enumerable: false,
|
||||||
|
configurable: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
return instance;
|
||||||
|
},
|
||||||
/**
|
/**
|
||||||
* Replace itself with the resolved dependency
|
* Make the property configurable to allow replacing it
|
||||||
* for performance reasons.
|
|
||||||
*/
|
*/
|
||||||
Object.defineProperty(this, propertyKey, {
|
configurable: true,
|
||||||
value: instance,
|
});
|
||||||
writable: false,
|
|
||||||
enumerable: false,
|
|
||||||
configurable: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
return instance;
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* Make the property configurable to allow replacing it
|
|
||||||
*/
|
|
||||||
configurable: true,
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@@ -1,142 +1,14 @@
|
|||||||
import { InitDelegate } from 'src/types/InitDelegate';
|
import { IdentifierRequiredError } from 'src/interfaces/Exceptions';
|
||||||
import { TSinjex } from '../classes/TSinjex';
|
import { TSinjex } from '../classes/TSinjex';
|
||||||
import { Identifier } from '../types/Identifier';
|
import { Identifier } from '../types/Identifier';
|
||||||
|
|
||||||
//#region Overloads
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A decorator to register a class in the **TSinjex** DI (Dependency Injection) container.
|
* A decorator to register a class in the **TSinjex** DI (Dependency Injection) container.
|
||||||
* @template TargetType The type of the class to be registered.
|
* @template TargetType The type of the class to be registered.
|
||||||
* @param identifier The identifier used to register the class in the DI container.
|
* @param identifier The {@link Identifier|identifier} used to register the class in the DI container or the class name if not provided.
|
||||||
* @see {@link Identifier} for more information on identifiers.
|
* @param deprecated If true, the dependency is deprecated and a warning is logged only once upon the first resolution of the dependency.
|
||||||
* @param deprecated If true, the dependency is deprecated and a warning
|
|
||||||
* is logged only once upon the first resolution of the dependency.
|
|
||||||
* @returns The decorator function to be applied on the class.
|
|
||||||
* @example
|
|
||||||
* ```ts
|
|
||||||
* \@Register('MyClassIdentifier')
|
|
||||||
* class MyClass {
|
|
||||||
* // ...
|
|
||||||
* }
|
|
||||||
* ```
|
|
||||||
* @example
|
|
||||||
* ```ts
|
|
||||||
* \@Register('MyClassIdentifier', true)
|
|
||||||
* class MyClass {
|
|
||||||
* // ...
|
|
||||||
* }
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
export function Register<
|
|
||||||
TargetType extends new (...args: unknown[]) => InstanceType<TargetType>,
|
|
||||||
>(
|
|
||||||
identifier: Identifier,
|
|
||||||
deprecated?: boolean,
|
|
||||||
): (constructor: TargetType, ...args: unknown[]) => void;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A decorator to register an instance of a class in the DI (Dependency Injection) container.
|
|
||||||
* @template TargetType The type of the class whose instance is to be registered.
|
|
||||||
* @param identifier The identifier used to register the instance in the DI container.
|
|
||||||
* @see {@link Identifier} for more information on identifiers.
|
|
||||||
* @param shouldRegister Set to 'instance' to register the instance in the DI container
|
|
||||||
* with an empty constructor.
|
|
||||||
* @param deprecated If true, the dependency is deprecated and a warning
|
|
||||||
* is logged only once upon the first resolution of the dependency.
|
|
||||||
* @returns The decorator function to be applied on the class.
|
|
||||||
* @example
|
|
||||||
* ```ts
|
|
||||||
* \@RegisterInstance('MyClassInstanceIdentifier', 'instance')
|
|
||||||
* class MyClass {
|
|
||||||
* // ...
|
|
||||||
* }
|
|
||||||
* ```
|
|
||||||
* @example
|
|
||||||
* ```ts
|
|
||||||
* \@RegisterInstance('MyClassInstanceIdentifier', 'instance', true)
|
|
||||||
* class MyClass {
|
|
||||||
* // ...
|
|
||||||
* }
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
export function Register<
|
|
||||||
TargetType extends new (..._args: unknown[]) => InstanceType<TargetType>,
|
|
||||||
>(
|
|
||||||
identifier: Identifier,
|
|
||||||
shouldRegister: 'instance',
|
|
||||||
deprecated?: boolean,
|
|
||||||
): (constructor: TargetType, ...args: unknown[]) => void;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A decorator to register an instance of a class in the DI (Dependency Injection) container.
|
|
||||||
* @template TargetType The type of the class whose instance is to be registered.
|
|
||||||
* @param identifier The identifier used to register the instance in the DI container.
|
|
||||||
* @see {@link Identifier} for more information on identifiers.
|
|
||||||
* @param init An optional initializer function which get the constructor of the class
|
|
||||||
* as input and returns an instance of the class.
|
|
||||||
* @param deprecated If true, the dependency is deprecated and a warning
|
|
||||||
* is logged only once upon the first resolution of the dependency.
|
|
||||||
* @see {@link InitDelegate} for more information on initializer functions.
|
|
||||||
* @returns The decorator function to be applied on the class.
|
|
||||||
* @example
|
|
||||||
* ```ts
|
|
||||||
* \@RegisterInstance('MyClassInstanceIdentifier', (constructor) => new constructor())
|
|
||||||
* class MyClass {
|
|
||||||
* // ...
|
|
||||||
* }
|
|
||||||
* ```
|
|
||||||
* @example
|
|
||||||
* ```ts
|
|
||||||
* \@RegisterInstance('MyClassInstanceIdentifier', (constructor) => new constructor(), true)
|
|
||||||
* class MyClass {
|
|
||||||
* // ...
|
|
||||||
* }
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
export function Register<
|
|
||||||
TargetType extends new (..._args: unknown[]) => InstanceType<TargetType>,
|
|
||||||
>(
|
|
||||||
identifier: Identifier,
|
|
||||||
init?: InitDelegate<
|
|
||||||
TargetType & { new (..._args: unknown[]): InstanceType<TargetType> },
|
|
||||||
InstanceType<TargetType>
|
|
||||||
>,
|
|
||||||
deprecated?: boolean,
|
|
||||||
): (constructor: TargetType, ...args: unknown[]) => void;
|
|
||||||
|
|
||||||
//#endregion Overloads
|
|
||||||
|
|
||||||
// eslint-disable-next-line jsdoc/require-jsdoc
|
|
||||||
export function Register<
|
|
||||||
TargetType extends new (...args: unknown[]) => InstanceType<TargetType>,
|
|
||||||
>(
|
|
||||||
identifier: Identifier,
|
|
||||||
arg1?:
|
|
||||||
| undefined
|
|
||||||
| boolean
|
|
||||||
| InitDelegate<TargetType, InstanceType<TargetType>>
|
|
||||||
| 'instance',
|
|
||||||
arg2?: boolean,
|
|
||||||
): (constructor: TargetType, ...args: unknown[]) => void {
|
|
||||||
const deprecated = typeof arg1 === 'boolean' ? arg1 : arg2;
|
|
||||||
const init = typeof arg1 === 'function' ? arg1 : undefined;
|
|
||||||
const shouldRegisterInstance = arg1 === 'instance';
|
|
||||||
|
|
||||||
if (init == undefined && shouldRegisterInstance !== true) {
|
|
||||||
return _register(identifier, deprecated);
|
|
||||||
} else {
|
|
||||||
return _registerInstance(identifier, init, deprecated);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A decorator to register a class in the **TSinjex** DI (Dependency Injection) container.
|
|
||||||
* @template TargetType The type of the class to be registered.
|
|
||||||
* @param identifier The identifier used to register the class in the DI container.
|
|
||||||
* @see {@link Identifier} for more information on identifiers.
|
|
||||||
* @param deprecated If true, the dependency is deprecated and a warning
|
|
||||||
* is logged only once upon the first resolution of the dependency.
|
|
||||||
* @returns The decorator function to be applied on the class.
|
* @returns The decorator function to be applied on the class.
|
||||||
|
* @throws An {@link IdentifierRequiredError} if the identifier is not provided and the class name is not available.
|
||||||
* @example
|
* @example
|
||||||
* ```ts
|
* ```ts
|
||||||
* \@Register('MyClassIdentifier')
|
* \@Register('MyClassIdentifier')
|
||||||
@@ -145,122 +17,18 @@ export function Register<
|
|||||||
* }
|
* }
|
||||||
* ```
|
* ```
|
||||||
*/
|
*/
|
||||||
function _register<
|
export function Register<
|
||||||
TargetType extends new (...args: unknown[]) => InstanceType<TargetType>,
|
TargetType extends new (...args: unknown[]) => InstanceType<TargetType>,
|
||||||
>(identifier: Identifier, deprecated?: boolean) {
|
>(identifier?: Identifier, deprecated?: boolean) {
|
||||||
return function (constructor: TargetType, ...args: unknown[]): void {
|
return function (
|
||||||
// Get the instance of the DI container
|
constructor: TargetType,
|
||||||
const diContainer = TSinjex.getInstance();
|
context: ClassDecoratorContext<TargetType>,
|
||||||
|
) {
|
||||||
|
const _identifier = identifier ?? context.name;
|
||||||
|
|
||||||
// Register the class in the DI container
|
if (_identifier == null) throw new IdentifierRequiredError();
|
||||||
diContainer.register(identifier, constructor, deprecated);
|
|
||||||
|
const diContainer = TSinjex.getInstance();
|
||||||
|
diContainer.register(_identifier, constructor, deprecated);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* A decorator to register an instance of a class in the DI (Dependency Injection) container.
|
|
||||||
* @template TargetType The type of the class whose instance is to be registered.
|
|
||||||
* @param identifier The identifier used to register the instance in the DI container.
|
|
||||||
* @see {@link Identifier} for more information on identifiers.
|
|
||||||
* @param init An optional initializer function which get the constructor of the class
|
|
||||||
* as input and returns an instance of the class.
|
|
||||||
* @param deprecated If true, the dependency is deprecated and a warning
|
|
||||||
* is logged only once upon the first resolution of the dependency.
|
|
||||||
* @see {@link InitDelegate} for more information on initializer functions.
|
|
||||||
* @returns The decorator function to be applied on the class.
|
|
||||||
* @example
|
|
||||||
* ```ts
|
|
||||||
* \@RegisterInstance('MyClassInstanceIdentifier', (constructor) => new constructor())
|
|
||||||
* class MyClass {
|
|
||||||
* // ...
|
|
||||||
* }
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
function _registerInstance<
|
|
||||||
TargetType extends new (..._args: unknown[]) => InstanceType<TargetType>,
|
|
||||||
>(
|
|
||||||
identifier: Identifier,
|
|
||||||
init?: InitDelegate<
|
|
||||||
TargetType & { new (..._args: unknown[]): InstanceType<TargetType> },
|
|
||||||
InstanceType<TargetType>
|
|
||||||
>,
|
|
||||||
deprecated?: boolean,
|
|
||||||
) {
|
|
||||||
return function (constructor: TargetType, ...args: unknown[]): void {
|
|
||||||
// Get the instance of the DI container
|
|
||||||
const diContainer = TSinjex.getInstance();
|
|
||||||
let instance: InstanceType<TargetType>;
|
|
||||||
|
|
||||||
// Create a proxy to instantiate the class when needed (Lazy Initialization)
|
|
||||||
let lazyProxy: unknown = new Proxy(
|
|
||||||
{},
|
|
||||||
{
|
|
||||||
get(target, prop, receiver) {
|
|
||||||
({ instance, lazyProxy } = initializeInstance<TargetType>(
|
|
||||||
instance,
|
|
||||||
init,
|
|
||||||
constructor,
|
|
||||||
args,
|
|
||||||
lazyProxy,
|
|
||||||
));
|
|
||||||
|
|
||||||
// Return the requested property of the instance
|
|
||||||
return instance[prop as keyof InstanceType<TargetType>];
|
|
||||||
},
|
|
||||||
set(target, prop, value, receiver) {
|
|
||||||
({ instance, lazyProxy } = initializeInstance<TargetType>(
|
|
||||||
instance,
|
|
||||||
init,
|
|
||||||
constructor,
|
|
||||||
args,
|
|
||||||
lazyProxy,
|
|
||||||
));
|
|
||||||
|
|
||||||
// Set the requested property of the instance
|
|
||||||
return (instance[prop as keyof InstanceType<TargetType>] =
|
|
||||||
value);
|
|
||||||
},
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
// Register the lazy proxy in the DI container
|
|
||||||
diContainer.register(identifier, lazyProxy, deprecated);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes the instance of the class.
|
|
||||||
* @template TargetType The type of the class whose instance is to be initialized.
|
|
||||||
* @param instance The instance of the class to be initialized.
|
|
||||||
* @param init The optional initializer function to initialize the instance.
|
|
||||||
* @param constructor The constructor of the class.
|
|
||||||
* @param args The arguments to be passed to the constructor of the class.
|
|
||||||
* @param lazyProxy The lazy proxy to instantiate the class when needed.
|
|
||||||
* @returns The initialized instance and the lazy proxy.
|
|
||||||
*/
|
|
||||||
function initializeInstance<
|
|
||||||
TargetType extends new (..._args: unknown[]) => InstanceType<TargetType>,
|
|
||||||
>(
|
|
||||||
instance: InstanceType<TargetType>,
|
|
||||||
init:
|
|
||||||
| InitDelegate<
|
|
||||||
TargetType &
|
|
||||||
(new (..._args: unknown[]) => InstanceType<TargetType>),
|
|
||||||
InstanceType<TargetType>
|
|
||||||
>
|
|
||||||
| undefined,
|
|
||||||
constructor: TargetType,
|
|
||||||
args: unknown[],
|
|
||||||
lazyProxy: unknown,
|
|
||||||
): { instance: InstanceType<TargetType>; lazyProxy: unknown } {
|
|
||||||
if (instance == null) {
|
|
||||||
if (init) {
|
|
||||||
instance = init(constructor);
|
|
||||||
} else {
|
|
||||||
instance = new constructor(...args);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lazyProxy = instance;
|
|
||||||
|
|
||||||
return { instance, lazyProxy };
|
|
||||||
}
|
|
||||||
|
@@ -1,18 +1,16 @@
|
|||||||
import { Register } from './Register';
|
import { IdentifierRequiredError } from 'src/interfaces/Exceptions';
|
||||||
|
import { TSinjex } from '../classes/TSinjex';
|
||||||
import { Identifier } from '../types/Identifier';
|
import { Identifier } from '../types/Identifier';
|
||||||
import { InitDelegate } from '../types/InitDelegate';
|
import { InitDelegate } from '../types/InitDelegate';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A decorator to register an instance of a class in the DI (Dependency Injection) container.
|
* A decorator to register an instance of a class in the DI (Dependency Injection) container.
|
||||||
* @template TargetType The type of the class whose instance is to be registered.
|
* @template TargetType The type of the class whose instance is to be registered.
|
||||||
* @param identifier The identifier used to register the instance in the DI container.
|
* @param identifier The {@link Identifier|identifier} used to register the class in the DI container or the class name if not provided.
|
||||||
* @see {@link Identifier} for more information on identifiers.
|
* @param init An optional initializer {@link InitDelegate|function} which get the constructor of the class
|
||||||
* @param init An optional initializer function which get the constructor of the class
|
|
||||||
* as input and returns an instance of the class.
|
* as input and returns an instance of the class.
|
||||||
* @param deprecated If true, the dependency is deprecated and a warning
|
|
||||||
* is logged only once upon the first resolution of the dependency.
|
|
||||||
* @see {@link InitDelegate} for more information on initializer functions.
|
|
||||||
* @returns The decorator function to be applied on the class.
|
* @returns The decorator function to be applied on the class.
|
||||||
|
* @throws An {@link IdentifierRequiredError} if the identifier is not provided and the class name is not available.
|
||||||
* @example
|
* @example
|
||||||
* ```ts
|
* ```ts
|
||||||
* \@RegisterInstance('MyClassInstanceIdentifier', (constructor) => new constructor())
|
* \@RegisterInstance('MyClassInstanceIdentifier', (constructor) => new constructor())
|
||||||
@@ -20,20 +18,63 @@ import { InitDelegate } from '../types/InitDelegate';
|
|||||||
* // ...
|
* // ...
|
||||||
* }
|
* }
|
||||||
* ```
|
* ```
|
||||||
* @deprecated Use {@link Register} instead. This decorator already uses the {@link Register} decorator internally.
|
|
||||||
*/
|
*/
|
||||||
export function RegisterInstance<
|
export function RegisterInstance<
|
||||||
TargetType extends new (..._args: unknown[]) => InstanceType<TargetType>,
|
TargetType extends new (..._args: unknown[]) => InstanceType<TargetType>,
|
||||||
>(
|
>(
|
||||||
identifier: Identifier,
|
identifier?: Identifier,
|
||||||
init?: InitDelegate<
|
init?: InitDelegate<
|
||||||
TargetType & { new (..._args: unknown[]): InstanceType<TargetType> },
|
TargetType & { new (..._args: unknown[]): InstanceType<TargetType> },
|
||||||
InstanceType<TargetType>
|
InstanceType<TargetType>
|
||||||
>,
|
>,
|
||||||
deprecated?: boolean,
|
) {
|
||||||
): (constructor: TargetType, ...args: unknown[]) => void {
|
return function (
|
||||||
const initDelegate = typeof init === 'function' ? init : undefined;
|
constructor: TargetType,
|
||||||
|
context: ClassDecoratorContext<TargetType>,
|
||||||
|
): void {
|
||||||
|
const _identifier = identifier ?? context.name;
|
||||||
|
|
||||||
if (initDelegate) return Register(identifier, initDelegate, deprecated);
|
if (_identifier == null) throw new IdentifierRequiredError();
|
||||||
else return Register(identifier, 'instance', deprecated);
|
|
||||||
|
const diContainer = TSinjex.getInstance();
|
||||||
|
let instance: InstanceType<TargetType>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the instance of the class
|
||||||
|
* and replace the lazy proxy with the instance
|
||||||
|
* for performance optimization.
|
||||||
|
*/
|
||||||
|
const getAndRegisterInstance = (): void => {
|
||||||
|
if (instance == null) {
|
||||||
|
if (init) {
|
||||||
|
instance = init(constructor);
|
||||||
|
} else {
|
||||||
|
instance = new constructor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
diContainer.register(_identifier, instance);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create a proxy to instantiate the class when needed (Lazy Initialization)
|
||||||
|
const lazyProxy: unknown = new Proxy(
|
||||||
|
{},
|
||||||
|
{
|
||||||
|
get(_target, prop, _receiver) {
|
||||||
|
getAndRegisterInstance();
|
||||||
|
|
||||||
|
// Return the requested property of the instance
|
||||||
|
return instance[prop as keyof InstanceType<TargetType>];
|
||||||
|
},
|
||||||
|
set(_target, prop, value, _receiver) {
|
||||||
|
getAndRegisterInstance();
|
||||||
|
|
||||||
|
// Set the requested property of the instance
|
||||||
|
return (instance[prop as keyof InstanceType<TargetType>] =
|
||||||
|
value);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
diContainer.register(_identifier, lazyProxy);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
@@ -15,6 +15,19 @@ export class TSinjexError extends Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Error class for missing identifiers in {@link ITSinjex} methods.
|
||||||
|
*/
|
||||||
|
export class IdentifierRequiredError extends TSinjexError {
|
||||||
|
/**
|
||||||
|
* Creates a new instance of {@link IdentifierRequiredError}
|
||||||
|
*/
|
||||||
|
constructor() {
|
||||||
|
super('Identifier is required.');
|
||||||
|
this.name = 'TSinjexIdentifierRequiredError';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Error class for dependency resolution errors in {@link ITSinjex}.
|
* Error class for dependency resolution errors in {@link ITSinjex}.
|
||||||
* @see {@link ITSinjex.resolve}
|
* @see {@link ITSinjex.resolve}
|
||||||
|
@@ -18,8 +18,6 @@
|
|||||||
"importHelpers": true,
|
"importHelpers": true,
|
||||||
"isolatedModules": true,
|
"isolatedModules": true,
|
||||||
"resolveJsonModule": true,
|
"resolveJsonModule": true,
|
||||||
"experimentalDecorators": true,
|
|
||||||
"emitDecoratorMetadata": true,
|
|
||||||
"strictNullChecks": true,
|
"strictNullChecks": true,
|
||||||
"strictPropertyInitialization": true,
|
"strictPropertyInitialization": true,
|
||||||
"lib": [
|
"lib": [
|
||||||
|
Reference in New Issue
Block a user