Skip to content

Commit

Permalink
fix: type arguments passed to registerSingleton and registerTransient…
Browse files Browse the repository at this point in the history
… should themselves be allowed to receive type arguments, and these should not count towards the service/implementation name
  • Loading branch information
wessberg committed May 21, 2021
1 parent f8c388b commit 76773ab
Show file tree
Hide file tree
Showing 11 changed files with 280 additions and 129 deletions.
2 changes: 1 addition & 1 deletion LICENSE.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
The MIT License (MIT)

Copyright © 2020 [Frederik Wessberg](mailto:frederikwessberg@hotmail.com) ([@FredWessberg](https://twitter.com/FredWessberg)) ([Website](https://github.com/wessberg))
Copyright © 2021 [Frederik Wessberg](mailto:frederikwessberg@hotmail.com) ([@FredWessberg](https://twitter.com/FredWessberg)) ([Website](https://github.com/wessberg))

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
38 changes: 19 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,20 @@ This has been implemented as a TypeScript Custom Transformer in order to be so l

<!-- SHADOW_SECTION_FEATURE_IMAGE_END -->

<!-- SHADOW_SECTION_BACKERS_START -->

## Backers

| <a href="https://usebubbles.com"><img alt="Bubbles" src="https://uploads-ssl.webflow.com/5d682047c28b217055606673/5e5360be16879c1d0dca6514_icon-thin-128x128%402x.png" height="70" /></a> | <a href="https://github.com/cblanc"><img alt="Christopher Blanchard" src="https://avatars0.githubusercontent.com/u/2160685?s=400&v=4" height="70" /></a> | <a href="https://github.com/ideal-postcodes"><img alt="Ideal Postcodes" src="https://avatars.githubusercontent.com/u/4996310?s=200&v=4" height="70" /></a> | <a href="https://www.xerox.com"><img alt="Xerox" src="https://avatars.githubusercontent.com/u/9158512?s=200&v=4" height="70" /></a> |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------- |
| [Bubbles](https://usebubbles.com)<br><strong>Twitter</strong>: [@usebubbles](https://twitter.com/usebubbles) | [Christopher Blanchard](https://github.com/cblanc) | [Ideal Postcodes](https://github.com/ideal-postcodes) | [Xerox](https://www.xerox.com) |

### Patreon

<a href="https://www.patreon.com/bePatron?u=11315442"><img alt="Patrons on Patreon" src="https://img.shields.io/endpoint.svg?url=https%3A%2F%2Fshieldsio-patreon.vercel.app%2Fapi%3Fusername%3Dwessberg%26type%3Dpatrons" width="200" /></a>

<!-- SHADOW_SECTION_BACKERS_END -->

<!-- SHADOW_SECTION_TOC_START -->

## Table of Contents
Expand All @@ -70,12 +84,12 @@ This has been implemented as a TypeScript Custom Transformer in order to be so l
- [Usage with ava](#usage-with-ava)
- [Options](#options)
- [Contributing](#contributing)
- [Maintainers](#maintainers)
- [Backers](#backers)
- [Patreon](#patreon)
- [FAQ](#faq)
- [How does it work, exactly?](#how-does-it-work-exactly)
- [License](#license)
- [Backers](#backers)
- [Patreon](#patreon)
- [Maintainers](#maintainers)

<!-- SHADOW_SECTION_TOC_END -->

Expand Down Expand Up @@ -103,7 +117,7 @@ $ pnpm add @wessberg/di-compiler

### Peer Dependencies

`@wessberg/di-compiler` depends on `typescript`, so you need to manually install these as well.
`@wessberg/di-compiler` depends on `typescript`, so you need to manually install this as well.

<!-- SHADOW_SECTION_INSTALL_END -->

Expand Down Expand Up @@ -321,20 +335,6 @@ Do you want to contribute? Awesome! Please follow [these recommendations](./CONT

<!-- SHADOW_SECTION_MAINTAINERS_END -->

<!-- SHADOW_SECTION_BACKERS_START -->

## Backers

| <a href="https://usebubbles.com"><img alt="Bubbles" src="https://uploads-ssl.webflow.com/5d682047c28b217055606673/5e5360be16879c1d0dca6514_icon-thin-128x128%402x.png" height="70" /></a> |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [Bubbles](https://usebubbles.com)<br><strong>Twitter</strong>: [@use_bubbles](https://twitter.com/use_bubbles) |

### Patreon

<a href="https://www.patreon.com/bePatron?u=11315442"><img alt="Patrons on Patreon" src="https://img.shields.io/endpoint.svg?url=https://shieldsio-patreon.herokuapp.com/wessberg" width="200" /></a>

<!-- SHADOW_SECTION_BACKERS_END -->

<!-- SHADOW_SECTION_FAQ_START -->

## FAQ
Expand All @@ -361,7 +361,7 @@ Will be compiled into:
```javascript
// ...
container.registerSingleton(undefined, {
identifier: "MyInterface",
identifier: `MyInterface`,
implementation: MyImplementation,
});
```
Expand Down
9 changes: 0 additions & 9 deletions pnpm-lock.yaml

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

24 changes: 24 additions & 0 deletions src/transformer/before/util.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { TS } from "../../type/type";
import { VisitorContext } from "../visitor-context";

/**
* A TypeNode such as IFoo<string> should still yield the service name "IFoo".
* This helper generates a proper service name from a TypeNode
*/
export function pickServiceOrImplementationName(
node: TS.Expression | TS.TypeNode | TS.EntityName,
context: VisitorContext
): string {
const { typescript } = context;

if (typescript.isTypeReferenceNode(node)) {
return pickServiceOrImplementationName(node.typeName, context);
} else if (typescript.isIndexedAccessTypeNode(node)) {
return `${pickServiceOrImplementationName(
node.objectType,
context
)}[${pickServiceOrImplementationName(node.indexType, context)}]`;
} else {
return node.getFullText().trim();
}
}
14 changes: 9 additions & 5 deletions src/transformer/before/visitor/visit-call-expression.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
moduleKindSupportsImportHelpers,
updateCallExpression,
} from "../../../util/ts-util";
import { pickServiceOrImplementationName } from "../util";

export function visitCallExpression(
options: BeforeVisitorOptions<TS.CallExpression>
Expand Down Expand Up @@ -58,7 +59,7 @@ export function visitCallExpression(
case DiMethodKind.REGISTER_TRANSIENT: {
let [typeArg, implementationArg] = (node.typeArguments ??
[]) as unknown as [
TS.TypeNode | TS.Expression | undefined,
TS.TypeNode | undefined,
TS.TypeNode | TS.Expression | undefined
];

Expand All @@ -76,8 +77,11 @@ export function visitCallExpression(
return childContinuation(node);
}

const typeArgText = typeArg.getFullText().trim();
const implementationArgText = implementationArg.getFullText().trim();
const typeArgText = pickServiceOrImplementationName(typeArg, context);
const implementationArgText = pickServiceOrImplementationName(
implementationArg,
context
);

// If the Implementation is a TypeNode, and if it originates from an ImportDeclaration, it may be stripped from the file since Typescript won't Type-check the updates from
// a CustomTransformer and such a node would normally be removed from the imports.
Expand Down Expand Up @@ -190,7 +194,7 @@ export function visitCallExpression(
createObjectLiteralExpression(context, [
compatFactory.createPropertyAssignment(
"identifier",
compatFactory.createStringLiteral(typeArgText)
compatFactory.createNoSubstitutionTemplateLiteral(typeArgText)
),
...(!typescript.isTypeNode(implementationArg)
? []
Expand Down Expand Up @@ -342,7 +346,7 @@ function rewriteImplementationName(
}

default:
// TODO: Add support for SystemJS and UMD here
// TODO: Add support for SystemJS here
return name;
}
}
Expand Down
48 changes: 0 additions & 48 deletions src/util/semver-util.ts

This file was deleted.

22 changes: 11 additions & 11 deletions test/amd.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ test("Preserves Type-only imports. #1", withTypeScript, (t, { typescript }) => {
const Foo = require("./foo");
console.log(foo_1.default);
const container = new di_1.DIContainer();
container.registerSingleton(undefined, { identifier: "IFoo", implementation: Foo.default });
container.registerSingleton(undefined, { identifier: \`IFoo\`, implementation: Foo.default });
});
`)
);
Expand Down Expand Up @@ -94,7 +94,7 @@ test("Preserves type-only imports. #2", withTypeScript, (t, { typescript }) => {
Object.defineProperty(exports, "__esModule", { value: true });
const Foo = require("./foo");
const container = new di_1.DIContainer();
container.registerSingleton(undefined, { identifier: "IFoo", implementation: Foo.default });
container.registerSingleton(undefined, { identifier: \`IFoo\`, implementation: Foo.default });
});
`)
);
Expand Down Expand Up @@ -141,7 +141,7 @@ test("Preserves type-only imports. #3", withTypeScript, (t, { typescript }) => {
Object.defineProperty(exports, "__esModule", { value: true });
const Foo = require("./foo");
const container = new di_1.DIContainer();
container.registerSingleton(undefined, { identifier: "IFoo", implementation: Foo.Foo });
container.registerSingleton(undefined, { identifier: \`IFoo\`, implementation: Foo.Foo });
});
`)
);
Expand Down Expand Up @@ -189,7 +189,7 @@ test("Preserves type-only imports. #4", withTypeScript, (t, { typescript }) => {
Object.defineProperty(exports, "__esModule", { value: true });
const Foo = require("./foo");
const container = new di_1.DIContainer();
container.registerSingleton(undefined, { identifier: "IFoo", implementation: Foo });
container.registerSingleton(undefined, { identifier: \`IFoo\`, implementation: Foo });
});
`)
);
Expand Down Expand Up @@ -236,7 +236,7 @@ test("Preserves type-only imports. #5", withTypeScript, (t, { typescript }) => {
Object.defineProperty(exports, "__esModule", { value: true });
const Foo = require("./foo");
const container = new di_1.DIContainer();
container.registerSingleton(undefined, { identifier: "IFoo", implementation: Foo.Bar });
container.registerSingleton(undefined, { identifier: \`IFoo\`, implementation: Foo.Bar });
});
`)
);
Expand Down Expand Up @@ -283,7 +283,7 @@ test("Preserves type-only imports. #6", withTypeScript, (t, { typescript }) => {
Object.defineProperty(exports, "__esModule", { value: true });
const Foo = require("./foo");
const container = new di_1.DIContainer();
container.registerSingleton(undefined, { identifier: "IFoo", implementation: Foo.default });
container.registerSingleton(undefined, { identifier: \`IFoo\`, implementation: Foo.default });
});
`)
);
Expand Down Expand Up @@ -333,7 +333,7 @@ test("Preserves type-only imports. #7", withTypeScript, (t, { typescript }) => {
const Foo = require("./foo");
console.log(foo_1.Bar);
const container = new di_1.DIContainer();
container.registerSingleton(undefined, { identifier: "IFoo", implementation: Foo.Foo });
container.registerSingleton(undefined, { identifier: \`IFoo\`, implementation: Foo.Foo });
});
`)
);
Expand Down Expand Up @@ -385,7 +385,7 @@ test(
Object.defineProperty(exports, "__esModule", { value: true });
const Foo = require("tslib").__importDefault(require("./foo"));
const container = new di_1.DIContainer();
container.registerSingleton(undefined, { identifier: "IFoo", implementation: Foo.default });
container.registerSingleton(undefined, { identifier: \`IFoo\`, implementation: Foo.default });
});
`)
);
Expand Down Expand Up @@ -438,7 +438,7 @@ test(
Object.defineProperty(exports, "__esModule", { value: true });
const Foo = __importDefault(require("./foo"));
const container = new di_1.DIContainer();
container.registerSingleton(undefined, { identifier: "IFoo", implementation: Foo.default });
container.registerSingleton(undefined, { identifier: \`IFoo\`, implementation: Foo.default });
});
`)
);
Expand Down Expand Up @@ -494,7 +494,7 @@ test(
foo_1 = __importDefault(foo_1);
console.log(foo_1.default);
const container = new di_1.DIContainer();
container.registerSingleton(undefined, { identifier: "IFoo", implementation: Foo.default });
container.registerSingleton(undefined, { identifier: \`IFoo\`, implementation: Foo.default });
});
`)
);
Expand Down Expand Up @@ -548,7 +548,7 @@ test(
Object.defineProperty(exports, "__esModule", { value: true });
const Foo = __importStar(require("./foo"));
const container = new di_1.DIContainer();
container.registerSingleton(undefined, { identifier: "IFoo", implementation: Foo });
container.registerSingleton(undefined, { identifier: \`IFoo\`, implementation: Foo });
});
`)
);
Expand Down
Loading

0 comments on commit 76773ab

Please sign in to comment.