Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Delegate types on common package #1601

Merged
merged 3 commits into from
Nov 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added

### Changed
- Updated `ServiceIdentifier` to rely on `Function` instead of `Abstract<T>`.

### Fixed

Expand Down
13 changes: 13 additions & 0 deletions package-lock.json

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

3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
"url": "https://github.com/inversify/InversifyJS/issues"
},
"description": "A powerful and lightweight inversion of control container for JavaScript and Node.js apps powered by TypeScript.",
"dependencies": {
"@inversifyjs/common": "1.3.0"
},
"devDependencies": {
"@eslint/js": "9.13.0",
"@types/chai": "4.3.6",
Expand Down
6 changes: 4 additions & 2 deletions src/annotation/inject.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { LazyServiceIdentifier } from '@inversifyjs/common';

import * as METADATA_KEY from '../constants/metadata_keys';
import { interfaces } from '../interfaces/interfaces';
import { DecoratorTarget } from './decorator_utils';
import { injectBase } from './inject_base';
import { ServiceIdentifierOrFunc } from './lazy_service_identifier';

const inject: <T = unknown>(
serviceIdentifier: ServiceIdentifierOrFunc<T>,
serviceIdentifier: interfaces.ServiceIdentifier<T> | LazyServiceIdentifier<T>,
) => (
target: DecoratorTarget,
targetKey?: string | symbol,
Expand Down
12 changes: 9 additions & 3 deletions src/annotation/inject_base.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,24 @@
import { LazyServiceIdentifier } from '@inversifyjs/common';

import { UNDEFINED_INJECT_ANNOTATION } from '../constants/error_msgs';
import { interfaces } from '../interfaces/interfaces';
import { Metadata } from '../planning/metadata';
import { createTaggedDecorator, DecoratorTarget } from './decorator_utils';
import { ServiceIdentifierOrFunc } from './lazy_service_identifier';

export function injectBase(
metadataKey: string,
): <T = unknown>(
serviceIdentifier: ServiceIdentifierOrFunc<T>,
serviceIdentifier: interfaces.ServiceIdentifier<T> | LazyServiceIdentifier<T>,
) => (
target: DecoratorTarget,
targetKey?: string | symbol,
indexOrPropertyDescriptor?: number | TypedPropertyDescriptor<T>,
) => void {
return <T = unknown>(serviceIdentifier: ServiceIdentifierOrFunc<T>) => {
return <T = unknown>(
serviceIdentifier:
| interfaces.ServiceIdentifier<T>
| LazyServiceIdentifier<T>,
) => {
return (
target: DecoratorTarget,
targetKey?: string | symbol,
Expand Down
16 changes: 0 additions & 16 deletions src/annotation/lazy_service_identifier.ts

This file was deleted.

6 changes: 4 additions & 2 deletions src/annotation/multi_inject.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { LazyServiceIdentifier } from '@inversifyjs/common';

import * as METADATA_KEY from '../constants/metadata_keys';
import { interfaces } from '../interfaces/interfaces';
import { DecoratorTarget } from './decorator_utils';
import { injectBase } from './inject_base';
import { ServiceIdentifierOrFunc } from './lazy_service_identifier';

const multiInject: <T = unknown>(
serviceIdentifier: ServiceIdentifierOrFunc<T>,
serviceIdentifier: interfaces.ServiceIdentifier<T> | LazyServiceIdentifier<T>,
) => (
target: DecoratorTarget,
targetKey?: string | symbol,
Expand Down
14 changes: 7 additions & 7 deletions src/interfaces/interfaces.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
/* eslint-disable @typescript-eslint/naming-convention */
import {
Newable as CommonNewable,
ServiceIdentifier as CommonServiceIdentifier,
} from '@inversifyjs/common';

import { FactoryType } from '../utils/factory_type';

// eslint-disable-next-line @typescript-eslint/no-namespace
Expand Down Expand Up @@ -49,20 +54,15 @@ namespace interfaces {
Variable: interfaces.TargetType;
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type Newable<T> = new (...args: any[]) => T;
export type Newable<TInstance = unknown> = CommonNewable<TInstance>;

export type Instance<T> = T & Record<string, () => void>;

export interface Abstract<T> {
prototype: T;
}

export type ServiceIdentifier<T = unknown> =
| string
| symbol
| Newable<T>
| Abstract<T>;
export type ServiceIdentifier<T = unknown> = CommonServiceIdentifier<T>;

export interface Clonable<T> {
clone(): T;
Expand Down
4 changes: 2 additions & 2 deletions src/inversify.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import * as keys from './constants/metadata_keys';

export { LazyServiceIdentifier } from '@inversifyjs/common';
// eslint-disable-next-line @typescript-eslint/typedef
export const METADATA_KEY = keys;
export { Container } from './container/container';
Expand All @@ -16,8 +18,6 @@ export { injectable } from './annotation/injectable';
export { tagged } from './annotation/tagged';
export { named } from './annotation/named';
export { inject } from './annotation/inject';
export { LazyServiceIdentifier } from './annotation/lazy_service_identifier';
export { LazyServiceIdentifier as LazyServiceIdentifer } from './annotation/lazy_service_identifier';
export { optional } from './annotation/optional';
export { unmanaged } from './annotation/unmanaged';
export { multiInject } from './annotation/multi_inject';
Expand Down
5 changes: 3 additions & 2 deletions src/planning/reflection_utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { LazyServiceIdentifier } from '../annotation/lazy_service_identifier';
import { LazyServiceIdentifier } from '@inversifyjs/common';

import * as ERROR_MSGS from '../constants/error_msgs';
import { TargetTypeEnum } from '../constants/literal_types';
import * as METADATA_KEY from '../constants/metadata_keys';
Expand Down Expand Up @@ -97,7 +98,7 @@ function getConstructorArgsAsTarget(
| undefined;

// we unwrap LazyServiceIdentifier wrappers to allow circular dependencies on symbols
if (serviceIdentifier instanceof LazyServiceIdentifier) {
if (LazyServiceIdentifier.is(serviceIdentifier)) {
serviceIdentifier = serviceIdentifier.unwrap();
}

Expand Down
1 change: 0 additions & 1 deletion src/resolution/resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,6 @@ const _resolveFactoryFromBinding: <T>(
new Error(
ERROR_MSGS.CIRCULAR_DEPENDENCY_IN_FACTORY(
factoryDetails.factoryType,
// eslint-disable-next-line @typescript-eslint/no-base-to-string
context.currentRequest.serviceIdentifier.toString(),
),
),
Expand Down
8 changes: 4 additions & 4 deletions src/syntax/binding_to_syntax.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ class BindingToSyntax<T> implements interfaces.BindingToSyntax<T> {
throw new Error(ERROR_MSGS.INVALID_TO_SELF_VALUE);
}

const self: interfaces.Newable<T> = this._binding.serviceIdentifier;
const self: interfaces.Newable<T> = this._binding
.serviceIdentifier as interfaces.Newable<T>;

return this.to(self);
}

Expand Down Expand Up @@ -113,9 +115,7 @@ class BindingToSyntax<T> implements interfaces.BindingToSyntax<T> {
return new BindingWhenOnSyntax<T>(this._binding);
}

public toService(
service: string | symbol | interfaces.Newable<T> | interfaces.Abstract<T>,
): void {
public toService(service: interfaces.ServiceIdentifier<T>): void {
this.toDynamicValue((context: interfaces.Context) =>
context.container.get<T>(service),
);
Expand Down
2 changes: 1 addition & 1 deletion src/utils/serialization.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ function getServiceIdentifierAsString(
} else if (typeof serviceIdentifier === 'symbol') {
return serviceIdentifier.toString();
} else {
return serviceIdentifier as string;
return serviceIdentifier;
}
}

Expand Down
20 changes: 5 additions & 15 deletions test/annotation/inject.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,15 @@ declare function __param(
decorator: ParameterDecorator,
): ClassDecorator;

import { LazyServiceIdentifier } from '@inversifyjs/common';
import { expect } from 'chai';

import { decorate } from '../../src/annotation/decorator_utils';
import { inject } from '../../src/annotation/inject';
import {
LazyServiceIdentifier,
ServiceIdentifierOrFunc,
} from '../../src/annotation/lazy_service_identifier';
import { multiInject } from '../../src/annotation/multi_inject';
import * as ERROR_MSGS from '../../src/constants/error_msgs';
import * as METADATA_KEY from '../../src/constants/metadata_keys';
import { interfaces } from '../../src/interfaces/interfaces';
import { multiInject } from '../../src/inversify';

class Katana {}
class Shuriken {}
Expand Down Expand Up @@ -161,12 +158,7 @@ describe('@inject', () => {
// this can happen when there is circular dependency between symbols
const useDecoratorWithUndefined: () => void = function () {
__decorate(
[
__param(
0,
inject(undefined as unknown as ServiceIdentifierOrFunc<unknown>),
),
],
[__param(0, inject(undefined as unknown as symbol))],
InvalidDecoratorUsageWarrior,
);
};
Expand Down Expand Up @@ -235,7 +227,7 @@ describe('@inject', () => {
// @ts-ignore
// eslint-disable-next-line @typescript-eslint/no-unused-vars
class WithUndefinedInject {
@inject(undefined as unknown as ServiceIdentifierOrFunc<undefined>)
@inject(undefined as unknown as symbol)
public property!: string;
}
}).to.throw(ERROR_MSGS.UNDEFINED_INJECT_ANNOTATION('WithUndefinedInject'));
Expand All @@ -248,9 +240,7 @@ describe('@inject', () => {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
class WithUndefinedInject {
constructor(
@multiInject(
undefined as unknown as ServiceIdentifierOrFunc<undefined>,
)
@multiInject(undefined as unknown as symbol)
public readonly dependency: string[],
) {}
}
Expand Down
9 changes: 0 additions & 9 deletions test/middleware/middleware.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ describe('Middleware', () => {

function middleware1(planAndResolve: interfaces.Next): interfaces.Next {
return (args: interfaces.NextArgs) => {
// eslint-disable-next-line @typescript-eslint/no-base-to-string
log.push(`Middleware1: ${args.serviceIdentifier.toString()}`);
return planAndResolve(args);
};
Expand All @@ -47,15 +46,13 @@ describe('Middleware', () => {

function middleware1(planAndResolve: interfaces.Next): interfaces.Next {
return (args: interfaces.NextArgs) => {
// eslint-disable-next-line @typescript-eslint/no-base-to-string
log.push(`Middleware1: ${args.serviceIdentifier.toString()}`);
return planAndResolve(args);
};
}

function middleware2(planAndResolve: interfaces.Next): interfaces.Next {
return (args: interfaces.NextArgs) => {
// eslint-disable-next-line @typescript-eslint/no-base-to-string
log.push(`Middleware2: ${args.serviceIdentifier.toString()}`);
return planAndResolve(args);
};
Expand Down Expand Up @@ -84,15 +81,13 @@ describe('Middleware', () => {

function middleware1(planAndResolve: interfaces.Next): interfaces.Next {
return (args: interfaces.NextArgs) => {
// eslint-disable-next-line @typescript-eslint/no-base-to-string
log.push(`Middleware1: ${args.serviceIdentifier.toString()}`);
return planAndResolve(args);
};
}

function middleware2(planAndResolve: interfaces.Next): interfaces.Next {
return (args: interfaces.NextArgs) => {
// eslint-disable-next-line @typescript-eslint/no-base-to-string
log.push(`Middleware2: ${args.serviceIdentifier.toString()}`);
return planAndResolve(args);
};
Expand Down Expand Up @@ -120,15 +115,13 @@ describe('Middleware', () => {

function middleware1(planAndResolve: interfaces.Next): interfaces.Next {
return (args: interfaces.NextArgs) => {
// eslint-disable-next-line @typescript-eslint/no-base-to-string
log.push(`Middleware1: ${args.serviceIdentifier.toString()}`);
return planAndResolve(args);
};
}

function middleware2(planAndResolve: interfaces.Next): interfaces.Next {
return (args: interfaces.NextArgs) => {
// eslint-disable-next-line @typescript-eslint/no-base-to-string
log.push(`Middleware2: ${args.serviceIdentifier.toString()}`);
return planAndResolve(args);
};
Expand Down Expand Up @@ -260,7 +253,6 @@ describe('Middleware', () => {
contexts: interfaces.Context,
) => interfaces.Context = args.contextInterceptor;
args.contextInterceptor = (context: interfaces.Context) => {
// eslint-disable-next-line @typescript-eslint/no-base-to-string
log.push(`contextInterceptor1: ${args.serviceIdentifier.toString()}`);

// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
Expand All @@ -278,7 +270,6 @@ describe('Middleware', () => {
contexts: interfaces.Context,
) => interfaces.Context = args.contextInterceptor;
args.contextInterceptor = (context: interfaces.Context) => {
// eslint-disable-next-line @typescript-eslint/no-base-to-string
log.push(`contextInterceptor2: ${args.serviceIdentifier.toString()}`);
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
return nextContextInterceptor !== null
Expand Down