Compare commits

..

2 Commits

Author SHA1 Message Date
7feb0fc694 Add manual trigger to ValidateBranchName workflow
- Included `workflow_dispatch` event in GitHub Actions
- Allows for manual execution of the ValidateBranchName workflow
2024-08-23 21:29:14 +02:00
ea2383234f Add branch name validation configuration
- **Added** `.github/config.conf` for branch name prefixes configuration
- **Updated** `ValidateBranchName.yml` to read and utilize branch name prefixes from the config file
2024-08-23 21:28:22 +02:00
12 changed files with 144 additions and 223 deletions

2
.github/config.conf vendored Normal file
View File

@@ -0,0 +1,2 @@
[branch_validation]
valid_prefixes = feature/,fix/,refactoring/,testing/,dependabot/,gh-pages

View File

@@ -4,7 +4,6 @@ on:
push: push:
branches: branches:
- main - main
- 'dev/*'
paths: paths:
- 'package.json' - 'package.json'
workflow_dispatch: # Allows manual execution of the workflow. workflow_dispatch: # Allows manual execution of the workflow.
@@ -23,8 +22,14 @@ jobs:
with: with:
node-version: '20.8.0' node-version: '20.8.0'
- name: Install dependencies, run tests and build - name: Install Dependencies
run: npm run prepare:deploy run: npm install
- name: Run Tests
run: npm run test:verbose
- name: Build the Project
run: npm run build:tsc
- name: Get the version - name: Get the version
id: get_version id: get_version
@@ -72,9 +77,8 @@ jobs:
echo "Generating release notes from ${{ env.PREVIOUS_TAG }} to HEAD..." echo "Generating release notes from ${{ env.PREVIOUS_TAG }} to HEAD..."
repo_url=$(git config --get remote.origin.url) repo_url=$(git config --get remote.origin.url)
notes=$(git log ${{ env.PREVIOUS_TAG }}..HEAD --pretty=format:"- [\`%h\`]($repo_url/commit/%H): %s%n") notes=$(git log ${{ env.PREVIOUS_TAG }}..HEAD --pretty=format:"- [\`%h\`]($repo_url/commit/%H): %s%n")
echo "See [CHANGELOG.md](./CHANGELOG.md) for more details." echo "Release notes:"
echo "$notes" echo "$notes"
echo ""
echo "### Changes in this release" > release_notes.md echo "### Changes in this release" > release_notes.md
echo "$notes" >> release_notes.md echo "$notes" >> release_notes.md
shell: bash shell: bash
@@ -86,6 +90,17 @@ jobs:
git config --local user.email "actions@github.com" git config --local user.email "actions@github.com"
shell: bash shell: bash
# - name: Create temporary branch
# id: create_temp_branch
# if: steps.check_version.outputs.skip_release == 'false'
# run: |
# git checkout --orphan release/v${{ env.VERSION }}
# git reset
# rm -f .gitignore
# git add README.md package.json LICENSE dist/ src/ tsconfig.json
# git commit -m "Prepare files for release ${{ env.VERSION }}"
# shell: bash
- name: Create and push tag - name: Create and push tag
id: create_tag id: create_tag
if: steps.check_version.outputs.skip_release == 'false' if: steps.check_version.outputs.skip_release == 'false'
@@ -96,15 +111,6 @@ jobs:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
shell: bash shell: bash
- name: Set Release Prerelease Flag
id: set_prerelease_flag
run: |
if [[ "${{ github.ref }}" == "refs/heads/main" ]]; then
echo "PRE_RELEASE=false" >> $GITHUB_ENV
elif [[ "${{ github.ref }}" == refs/heads/dev/* ]]; then
echo "PRE_RELEASE=true" >> $GITHUB_ENV
fi
- name: Release - name: Release
if: steps.check_version.outputs.skip_release == 'false' if: steps.check_version.outputs.skip_release == 'false'
uses: softprops/action-gh-release@v2 uses: softprops/action-gh-release@v2
@@ -112,6 +118,6 @@ jobs:
tag_name: ${{ env.VERSION }} tag_name: ${{ env.VERSION }}
name: Release ${{ env.VERSION }} name: Release ${{ env.VERSION }}
body_path: release_notes.md body_path: release_notes.md
prerelease: ${{ env.PRE_RELEASE }} prerelease: true
env: env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -3,7 +3,8 @@ name: Validate Branch Name on Pull Request
on: on:
pull_request: pull_request:
branches: branches:
- UNDEFINED - main
workflow_dispatch: # Allows manual execution of the workflow.
jobs: jobs:
validate-branch-name-on-pull-request: validate-branch-name-on-pull-request:
@@ -13,11 +14,27 @@ jobs:
- name: Check out repository - name: Check out repository
uses: actions/checkout@v2 uses: actions/checkout@v2
- name: Read Config File
id: config
run: |
VALID_PREFIXES=$(grep 'valid_prefixes' .github/config.conf | cut -d '=' -f2 | tr -d ' ')
echo "VALID_PREFIXES=$VALID_PREFIXES" >> $GITHUB_ENV
- name: Validate Branch Name on Pull Request - name: Validate Branch Name on Pull Request
run: | run: |
BRANCH_NAME=${GITHUB_HEAD_REF} BRANCH_NAME=${{ github.head_ref }}
if [[ ! "$BRANCH_NAME" =~ ^(feature\/|fix\/|refactoring\/|testing\/|dependabot\/|gh-pages) ]]; then VALID_PREFIXES_ARRAY=(${VALID_PREFIXES//,/ })
VALID=false
for PREFIX in "${VALID_PREFIXES_ARRAY[@]}"; do
if [[ "$BRANCH_NAME" =~ ^$PREFIX ]]; then
VALID=true
break
fi
done
if [ "$VALID" = false ]; then
echo "Invalid branch name: $BRANCH_NAME" echo "Invalid branch name: $BRANCH_NAME"
echo "Branch name must start with 'feature/', 'fix/', 'refactoring/', 'testing/', dependabot/" or "gh-pages" echo "Branch name must start with one of the following prefixes: $VALID_PREFIXES"
exit 1 exit 1
fi fi

View File

@@ -9,21 +9,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added ### Added
- feat: Add new `IdentifierRequiredError` class for missing identifiers.
- 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).
- Add pre release building to release workflow on dev/* branches an version changes.
### 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

9
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{ {
"name": "ts-injex", "name": "ts-injex",
"version": "0.1.0-alpha", "version": "0.0.9",
"lockfileVersion": 3, "lockfileVersion": 3,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"name": "ts-injex", "name": "ts-injex",
"version": "0.1.0-alpha", "version": "0.0.9",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"eslint-plugin-prettier": "^5.2.1", "eslint-plugin-prettier": "^5.2.1",
@@ -5958,11 +5958,6 @@
"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",

View File

@@ -1,6 +1,6 @@
{ {
"name": "ts-injex", "name": "ts-injex",
"version": "0.1.0-alpha", "version": "0.1.0",
"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",
@@ -22,8 +22,7 @@
"docs:fix:coverage": "node scripts/fix-coverage-paths.cjs", "docs:fix:coverage": "node scripts/fix-coverage-paths.cjs",
"docs:generate:badge": "node scripts/generate-badge.cjs", "docs:generate:badge": "node scripts/generate-badge.cjs",
"docs:fix:escape": "node scripts/replace-doc-escaping.cjs", "docs:fix:escape": "node scripts/replace-doc-escaping.cjs",
"version:show": "node -e \"console.log(require('./package.json').version)\"", "version:show": "node -e \"console.log(require('./package.json').version)\""
"prepare:deploy": "npm install && npm run test:verbose && npm run build:tsc"
}, },
"repository": { "repository": {
"type": "git", "type": "git",

View File

@@ -67,29 +67,6 @@ 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;
@@ -101,7 +78,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,
@@ -298,19 +275,6 @@ 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);
});
}); });
} }
@@ -347,23 +311,6 @@ 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',

View File

@@ -1,6 +1,5 @@
import { import {
DependencyResolutionError, DependencyResolutionError,
IdentifierRequiredError,
InitializationError, InitializationError,
InjectorError, InjectorError,
NoInstantiationMethodError, NoInstantiationMethodError,
@@ -11,17 +10,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 TargetType The type of the class to inject the dependency into. * @template T The type of the dependency to be injected.
* @template DependencyType The type of the dependency to be injected. * @template U The type of the property to be injected.
* @template PropertyType The type of the property to be injected. * @param identifier The identifier used to resolve the class in the DI container.
* @param identifier The {@link Identifier|identifier} used to resolve the dependencie in the DI container or the property name if not provided. * @see {@link Identifier} for more information on identifiers.
* @param init An optional initializer {@link InitDelegate|function} to transform the dependency before injection * @param init Optional an initializer 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.
@@ -41,86 +40,70 @@ import { InitDelegate } from '../types/InitDelegate';
* } * }
* ``` * ```
*/ */
export function Inject<TargetType, DependencyType, PropertyType>( export function Inject<T, U>(
identifier?: Identifier, identifier: Identifier,
init?: InitDelegate<DependencyType, PropertyType> | true, init?: InitDelegate<T, U> | true,
necessary = true, necessary = true,
) { ) {
return function ( return function (target: unknown, propertyKey: string | symbol): void {
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 = (): DependencyType | undefined => { const resolve = (): T | undefined => {
return TSinjex.getInstance().resolve<DependencyType>( return TSinjex.getInstance().resolve<T>(identifier, necessary);
_identifier,
necessary,
);
}; };
context.addInitializer(function (this: TargetType) { Object.defineProperty(target, propertyKey, {
Object.defineProperty(this, context.name, { get() {
get() { let instance: T | U | undefined;
let instance: DependencyType | PropertyType | undefined;
const dependency: DependencyType | undefined = tryAndCatch( const dependency: T | undefined = tryAndCatch(
() => resolve(), () => resolve(),
necessary, necessary,
_identifier, identifier,
DependencyResolutionError, DependencyResolutionError,
); );
if (dependency != null) { if (dependency != null) {
const initFunction: (() => PropertyType) | undefined = const initFunction: (() => U) | undefined =
typeof init === 'function' && dependency != null typeof init === 'function' && dependency != null
? (): PropertyType => init(dependency) ? (): U => init(dependency)
: init === true && hasConstructor(dependency) : init === true && hasConstructor(dependency)
? (): PropertyType => ? (): U => new dependency() as U
new dependency() as PropertyType : undefined;
: 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;
},
/** /**
* Make the property configurable to allow replacing it * Replace itself with the resolved dependency
* for performance reasons.
*/ */
configurable: true, Object.defineProperty(this, propertyKey, {
}); value: instance,
writable: false,
enumerable: false,
configurable: false,
});
return instance;
},
/**
* Make the property configurable to allow replacing it
*/
configurable: true,
}); });
}; };
} }

View File

@@ -1,14 +1,14 @@
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';
/** /**
* 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 {@link Identifier|identifier} used to register the class in the DI container or the class name if not provided. * @param identifier The identifier used to register the class in the DI container.
* @param deprecated If true, the dependency is deprecated and a warning is logged only once upon the first resolution of the dependency. * @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')
@@ -19,16 +19,12 @@ import { Identifier } from '../types/Identifier';
*/ */
export 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 ( return function (constructor: TargetType, ...args: unknown[]): void {
constructor: TargetType, // Get the instance of the DI container
context: ClassDecoratorContext<TargetType>,
) {
const _identifier = identifier ?? context.name;
if (_identifier == null) throw new IdentifierRequiredError();
const diContainer = TSinjex.getInstance(); const diContainer = TSinjex.getInstance();
diContainer.register(_identifier, constructor, deprecated);
// Register the class in the DI container
diContainer.register(identifier, constructor, deprecated);
}; };
} }

View File

@@ -1,4 +1,3 @@
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';
import { InitDelegate } from '../types/InitDelegate'; import { InitDelegate } from '../types/InitDelegate';
@@ -6,11 +5,12 @@ 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 {@link Identifier|identifier} used to register the class in the DI container or the class name if not provided. * @param identifier The identifier used to register the instance in the DI container.
* @param init An optional initializer {@link InitDelegate|function} which get the constructor of the class * @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. * as input and returns an instance of the class.
* @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())
@@ -22,51 +22,43 @@ import { InitDelegate } from '../types/InitDelegate';
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>
>, >,
) { ) {
return function ( return function (constructor: TargetType, ...args: unknown[]): void {
constructor: TargetType, // Get the instance of the DI container
context: ClassDecoratorContext<TargetType>,
): void {
const _identifier = identifier ?? context.name;
if (_identifier == null) throw new IdentifierRequiredError();
const diContainer = TSinjex.getInstance(); const diContainer = TSinjex.getInstance();
let instance: InstanceType<TargetType>; 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) // Create a proxy to instantiate the class when needed (Lazy Initialization)
const lazyProxy: unknown = new Proxy( let lazyProxy: unknown = new Proxy(
{}, {},
{ {
get(_target, prop, _receiver) { get(target, prop, receiver) {
getAndRegisterInstance(); if (instance == null) {
if (init) {
instance = init(constructor);
} else {
instance = new constructor(...args);
}
}
lazyProxy = instance;
// Return the requested property of the instance // Return the requested property of the instance
return instance[prop as keyof InstanceType<TargetType>]; return instance[prop as keyof InstanceType<TargetType>];
}, },
set(_target, prop, value, _receiver) { set(target, prop, value, receiver) {
getAndRegisterInstance(); if (instance == null) {
if (init) {
instance = init(constructor);
} else {
instance = new constructor(...args);
}
}
lazyProxy = instance;
// Set the requested property of the instance // Set the requested property of the instance
return (instance[prop as keyof InstanceType<TargetType>] = return (instance[prop as keyof InstanceType<TargetType>] =
@@ -75,6 +67,7 @@ export function RegisterInstance<
}, },
); );
diContainer.register(_identifier, lazyProxy); // Register the lazy proxy in the DI container
diContainer.register(identifier, lazyProxy);
}; };
} }

View File

@@ -15,19 +15,6 @@ 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}

View File

@@ -18,6 +18,8 @@
"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": [